diff --git a/Android.bp b/Android.bp index c571fa0e5cfc43e79b413676956d447eada88788..8a3f76c40e868cc3015798e0905af60ef2f42859 100644 --- a/Android.bp +++ b/Android.bp @@ -248,7 +248,6 @@ java_defaults { "core/java/android/os/ICancellationSignal.aidl", "core/java/android/os/IDeviceIdentifiersPolicyService.aidl", "core/java/android/os/IDeviceIdleController.aidl", - "core/java/android/os/IDynamicAndroidService.aidl", "core/java/android/os/IHardwarePropertiesManager.aidl", ":libincident_aidl", "core/java/android/os/IMaintenanceActivityListener.aidl", @@ -272,6 +271,7 @@ java_defaults { "core/java/android/os/IUserManager.aidl", ":libvibrator_aidl", "core/java/android/os/IVibratorService.aidl", + "core/java/android/os/image/IDynamicSystemService.aidl", "core/java/android/os/storage/IStorageManager.aidl", "core/java/android/os/storage/IStorageEventListener.aidl", "core/java/android/os/storage/IStorageShutdownObserver.aidl", @@ -318,6 +318,7 @@ java_defaults { "core/java/android/service/vr/IVrListener.aidl", "core/java/android/service/vr/IVrManager.aidl", "core/java/android/service/vr/IVrStateCallbacks.aidl", + "core/java/android/service/watchdog/IExplicitHealthCheckService.aidl", "core/java/android/print/ILayoutResultCallback.aidl", "core/java/android/print/IPrinterDiscoveryObserver.aidl", "core/java/android/print/IPrintDocumentAdapter.aidl", @@ -475,7 +476,10 @@ java_defaults { "media/java/android/media/IMediaHTTPConnection.aidl", "media/java/android/media/IMediaHTTPService.aidl", "media/java/android/media/IMediaResourceMonitor.aidl", + "media/java/android/media/IMediaRoute2Callback.aidl", + "media/java/android/media/IMediaRoute2Provider.aidl", "media/java/android/media/IMediaRouterClient.aidl", + "media/java/android/media/IMediaRouter2ManagerClient.aidl", "media/java/android/media/IMediaRouterService.aidl", "media/java/android/media/IMediaScannerListener.aidl", "media/java/android/media/IMediaScannerService.aidl", @@ -886,66 +890,6 @@ gensrcs { output_extension: "srcjar", } -// AIDL interfaces between the core system and the networking mainline module. -aidl_interface { - name: "networkstack-aidl-interfaces", - local_include_dir: "core/java", - srcs: [ - "core/java/android/net/ApfCapabilitiesParcelable.aidl", - "core/java/android/net/DhcpResultsParcelable.aidl", - "core/java/android/net/INetworkMonitor.aidl", - "core/java/android/net/INetworkMonitorCallbacks.aidl", - "core/java/android/net/INetworkStackConnector.aidl", - "core/java/android/net/INetworkStackStatusCallback.aidl", - "core/java/android/net/InitialConfigurationParcelable.aidl", - "core/java/android/net/PrivateDnsConfigParcel.aidl", - "core/java/android/net/ProvisioningConfigurationParcelable.aidl", - "core/java/android/net/StaticIpConfigurationParcelable.aidl", - "core/java/android/net/TcpKeepalivePacketDataParcelable.aidl", - "core/java/android/net/dhcp/DhcpServingParamsParcel.aidl", - "core/java/android/net/dhcp/IDhcpServer.aidl", - "core/java/android/net/dhcp/IDhcpServerCallbacks.aidl", - "core/java/android/net/ip/IIpClient.aidl", - "core/java/android/net/ip/IIpClientCallbacks.aidl", - "core/java/android/net/IIpMemoryStore.aidl", - "core/java/android/net/IIpMemoryStoreCallbacks.aidl", - "core/java/android/net/ipmemorystore/**/*.aidl", - ], - backend: { - ndk: { - enabled: false, - }, - cpp: { - enabled: false, - }, - }, - api_dir: "aidl/networkstack", -} - -aidl_interface { - name: "ipmemorystore-aidl-interfaces", - local_include_dir: "core/java", - srcs: [ - "core/java/android/net/IIpMemoryStore.aidl", - "core/java/android/net/IIpMemoryStoreCallbacks.aidl", - "core/java/android/net/ipmemorystore/**/*.aidl", - ], -} - -aidl_interface { - name: "networkstack-aidl-framework", - local_include_dir: "core/java", - srcs: [ - "core/java/android/net/TcpKeepalivePacketDataParcelable.aidl", - ], - api_dir: "aidl/networkstack", - backend: { - java: { - sdk_version: "28", - }, - }, -} - filegroup { name: "framework-annotations", srcs: [ @@ -1685,6 +1629,8 @@ droidstubs { srcs: [ ":openjdk_java_files", ":non_openjdk_java_files", + ":opt-telephony-common-srcs", + "core/java/**/*.java", ], arg_files: [ "core/res/AndroidManifest.xml", diff --git a/CleanSpec.mk b/CleanSpec.mk index 30c2c69e85729de08e9cd0d76b832ac4cbc7eec7..6160acbcf1304370020ba1e413c3f4c1f0e2ed2d 100644 --- a/CleanSpec.mk +++ b/CleanSpec.mk @@ -253,6 +253,7 @@ $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/vendor/overlay/ExperimentNav $(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/overlay/ExperimentNavigationBarSlim) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/priv-app/SystemUI) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/media/audio) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/priv-app/DynamicAndroidInstallationService) # ****************************************************************** # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST ABOVE THIS BANNER # ****************************************************************** diff --git a/api/current.txt b/api/current.txt index 793bc2fbe459ed9bc372ac9f58e5f9ff047a1374..5664d4f65cc4ff50d45889ae6a11c8178b0d67f8 100644 --- a/api/current.txt +++ b/api/current.txt @@ -5481,10 +5481,10 @@ package android.app { method public boolean getAutoExpandBubble(); method @Nullable public android.app.PendingIntent getDeleteIntent(); method public int getDesiredHeight(); + method @DimenRes public int getDesiredHeightResId(); method @NonNull public android.graphics.drawable.Icon getIcon(); method @NonNull public android.app.PendingIntent getIntent(); method public boolean getSuppressInitialNotification(); - method @Deprecated public CharSequence getTitle(); method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator CREATOR; } @@ -5495,10 +5495,10 @@ package android.app { method @NonNull public android.app.Notification.BubbleMetadata.Builder setAutoExpandBubble(boolean); method @NonNull public android.app.Notification.BubbleMetadata.Builder setDeleteIntent(@Nullable android.app.PendingIntent); method @NonNull public android.app.Notification.BubbleMetadata.Builder setDesiredHeight(int); + method @NonNull public android.app.Notification.BubbleMetadata.Builder setDesiredHeightResId(@DimenRes int); method @NonNull public android.app.Notification.BubbleMetadata.Builder setIcon(@NonNull android.graphics.drawable.Icon); method @NonNull public android.app.Notification.BubbleMetadata.Builder setIntent(@NonNull android.app.PendingIntent); method @NonNull public android.app.Notification.BubbleMetadata.Builder setSuppressInitialNotification(boolean); - method @Deprecated public android.app.Notification.BubbleMetadata.Builder setTitle(CharSequence); } public static class Notification.Builder { @@ -5848,8 +5848,8 @@ package android.app { field public static final int INTERRUPTION_FILTER_NONE = 3; // 0x3 field public static final int INTERRUPTION_FILTER_PRIORITY = 2; // 0x2 field public static final int INTERRUPTION_FILTER_UNKNOWN = 0; // 0x0 - field public static final String META_DATA_AUTOMATIC_RULE_TYPE = "android.app.automatic.ruleType"; - field public static final String META_DATA_RULE_INSTANCE_LIMIT = "android.app.zen.automatic.ruleInstanceLimit"; + field public static final String META_DATA_AUTOMATIC_RULE_TYPE = "android.service.zen.automatic.ruleType"; + field public static final String META_DATA_RULE_INSTANCE_LIMIT = "android.service.zen.automatic.ruleInstanceLimit"; } public static class NotificationManager.Policy implements android.os.Parcelable { @@ -6952,7 +6952,6 @@ package android.app.admin { field public static final int PRIVATE_DNS_SET_NO_ERROR = 0; // 0x0 field public static final int PROVISIONING_MODE_FULLY_MANAGED_DEVICE = 1; // 0x1 field public static final int PROVISIONING_MODE_MANAGED_PROFILE = 2; // 0x2 - field public static final int PROVISIONING_MODE_MANAGED_PROFILE_ON_FULLY_MANAGED_DEVICE = 3; // 0x3 field public static final int RESET_PASSWORD_DO_NOT_ASK_CREDENTIALS_ON_BOOT = 2; // 0x2 field public static final int RESET_PASSWORD_REQUIRE_ENTRY = 1; // 0x1 field public static final int SKIP_SETUP_WIZARD = 1; // 0x1 @@ -9794,6 +9793,7 @@ package android.content { field public static final int BIND_DEBUG_UNBIND = 2; // 0x2 field public static final int BIND_EXTERNAL_SERVICE = -2147483648; // 0x80000000 field public static final int BIND_IMPORTANT = 64; // 0x40 + field public static final int BIND_INCLUDE_CAPABILITIES = 4096; // 0x1000 field public static final int BIND_NOT_FOREGROUND = 4; // 0x4 field public static final int BIND_WAIVE_PRIORITY = 32; // 0x20 field public static final String BIOMETRIC_SERVICE = "biometric"; @@ -11384,6 +11384,7 @@ package android.content.pm { public class PackageInstaller { method public void abandonSession(int); method public int createSession(@NonNull android.content.pm.PackageInstaller.SessionParams) throws java.io.IOException; + method @Nullable public android.content.pm.PackageInstaller.SessionInfo getActiveStagedSession(); method @NonNull public java.util.List getAllSessions(); method @NonNull public java.util.List getMySessions(); method @Nullable public android.content.pm.PackageInstaller.SessionInfo getSessionInfo(int); @@ -11468,6 +11469,7 @@ package android.content.pm { method @NonNull public String getStagedSessionErrorMessage(); method @NonNull public android.os.UserHandle getUser(); method public boolean isActive(); + method public boolean isCommitted(); method public boolean isMultiPackage(); method public boolean isSealed(); method public boolean isStaged(); @@ -11598,6 +11600,7 @@ package android.content.pm { method public abstract android.content.pm.ServiceInfo getServiceInfo(android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException; method @NonNull public abstract java.util.List getSharedLibraries(int); method @Nullable public android.os.Bundle getSuspendedPackageAppExtras(); + method public boolean getSyntheticAppDetailsActivityEnabled(@NonNull String); method public abstract android.content.pm.FeatureInfo[] getSystemAvailableFeatures(); method public abstract String[] getSystemSharedLibraryNames(); method public abstract CharSequence getText(String, @StringRes int, android.content.pm.ApplicationInfo); @@ -12355,6 +12358,7 @@ package android.content.res { method @NonNull public android.content.res.TypedArray obtainStyledAttributes(@NonNull @StyleableRes int[]); method @NonNull public android.content.res.TypedArray obtainStyledAttributes(@StyleRes int, @NonNull @StyleableRes int[]) throws android.content.res.Resources.NotFoundException; method @NonNull public android.content.res.TypedArray obtainStyledAttributes(@Nullable android.util.AttributeSet, @NonNull @StyleableRes int[], @AttrRes int, @StyleRes int); + method public void rebase(); method public boolean resolveAttribute(int, android.util.TypedValue, boolean); method public void setTo(android.content.res.Resources.Theme); } @@ -22663,18 +22667,22 @@ package android.location { public final class GnssClock implements android.os.Parcelable { method public int describeContents(); method public double getBiasNanos(); - method public double getBiasUncertaintyNanos(); + method @FloatRange(from=0.0f) public double getBiasUncertaintyNanos(); method public double getDriftNanosPerSecond(); - method public double getDriftUncertaintyNanosPerSecond(); + method @FloatRange(from=0.0f) public double getDriftUncertaintyNanosPerSecond(); + method public long getElapsedRealtimeNanos(); + method @IntRange(from=0) public long getElapsedRealtimeUncertaintyNanos(); method public long getFullBiasNanos(); method public int getHardwareClockDiscontinuityCount(); method public int getLeapSecond(); method public long getTimeNanos(); - method public double getTimeUncertaintyNanos(); + method @FloatRange(from=0.0f) public double getTimeUncertaintyNanos(); method public boolean hasBiasNanos(); method public boolean hasBiasUncertaintyNanos(); method public boolean hasDriftNanosPerSecond(); method public boolean hasDriftUncertaintyNanosPerSecond(); + method public boolean hasElapsedRealtimeNanos(); + method public boolean hasElapsedRealtimeUncertaintyNanos(); method public boolean hasFullBiasNanos(); method public boolean hasLeapSecond(); method public boolean hasTimeUncertaintyNanos(); @@ -23248,7 +23256,7 @@ package android.media { method public static boolean isHapticPlaybackSupported(); method public boolean isMicrophoneMute(); method public boolean isMusicActive(); - method public static boolean isOffloadedPlaybackSupported(@NonNull android.media.AudioFormat); + method public static boolean isOffloadedPlaybackSupported(@NonNull android.media.AudioFormat, @NonNull android.media.AudioAttributes); method public boolean isSpeakerphoneOn(); method public boolean isStreamMute(int); method public boolean isVolumeFixed(); @@ -23401,15 +23409,16 @@ package android.media { } public final class AudioPlaybackCaptureConfiguration { + method @NonNull public android.media.projection.MediaProjection getMediaProjection(); } public static final class AudioPlaybackCaptureConfiguration.Builder { ctor public AudioPlaybackCaptureConfiguration.Builder(@NonNull android.media.projection.MediaProjection); method @NonNull public android.media.AudioPlaybackCaptureConfiguration.Builder addMatchingUid(int); - method @NonNull public android.media.AudioPlaybackCaptureConfiguration.Builder addMatchingUsage(@NonNull android.media.AudioAttributes); + method @NonNull public android.media.AudioPlaybackCaptureConfiguration.Builder addMatchingUsage(int); method @NonNull public android.media.AudioPlaybackCaptureConfiguration build(); method @NonNull public android.media.AudioPlaybackCaptureConfiguration.Builder excludeUid(int); - method @NonNull public android.media.AudioPlaybackCaptureConfiguration.Builder excludeUsage(@NonNull android.media.AudioAttributes); + method @NonNull public android.media.AudioPlaybackCaptureConfiguration.Builder excludeUsage(int); } public final class AudioPlaybackConfiguration implements android.os.Parcelable { @@ -23482,11 +23491,11 @@ package android.media { method public void release(); method public void removeOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener); method @Deprecated public void removeOnRoutingChangedListener(android.media.AudioRecord.OnRoutingChangedListener); - method public boolean setMicrophoneDirection(int); - method public boolean setMicrophoneFieldDimension(@FloatRange(from=-1.0, to=1.0) float); method public int setNotificationMarkerPosition(int); method public int setPositionNotificationPeriod(int); method public boolean setPreferredDevice(android.media.AudioDeviceInfo); + method public boolean setPreferredMicrophoneDirection(int); + method public boolean setPreferredMicrophoneFieldDimension(@FloatRange(from=-1.0, to=1.0) float); method public void setRecordPositionUpdateListener(android.media.AudioRecord.OnRecordPositionUpdateListener); method public void setRecordPositionUpdateListener(android.media.AudioRecord.OnRecordPositionUpdateListener, android.os.Handler); method public void startRecording() throws java.lang.IllegalStateException; @@ -23706,17 +23715,6 @@ package android.media { method public void onTearDown(@NonNull android.media.AudioTrack); } - public class CallbackDataSourceDesc extends android.media.DataSourceDesc { - method @NonNull public android.media.DataSourceCallback getDataSourceCallback(); - } - - public static class CallbackDataSourceDesc.Builder extends android.media.DataSourceDesc.BuilderBase { - ctor public CallbackDataSourceDesc.Builder(); - ctor public CallbackDataSourceDesc.Builder(@Nullable android.media.CallbackDataSourceDesc); - method @NonNull public android.media.CallbackDataSourceDesc build(); - method @NonNull public android.media.CallbackDataSourceDesc.Builder setDataSource(@NonNull android.media.DataSourceCallback); - } - public class CamcorderProfile { method public static android.media.CamcorderProfile get(int); method public static android.media.CamcorderProfile get(int, int); @@ -23769,12 +23767,6 @@ package android.media { field public static final int QUALITY_MEDIUM = 1; // 0x1 } - public abstract class DataSourceCallback implements java.io.Closeable { - ctor public DataSourceCallback(); - method public abstract long getSize() throws java.io.IOException; - method public abstract int readAt(long, @NonNull byte[], int, int) throws java.io.IOException; - } - public class DataSourceDesc { method public long getEndPosition(); method @Nullable public String getMediaId(); @@ -23783,10 +23775,17 @@ package android.media { field public static final long POSITION_UNKNOWN = 576460752303423L; // 0x20c49ba5e353fL } - protected static class DataSourceDesc.BuilderBase { - method @NonNull public T setEndPosition(long); - method @NonNull public T setMediaId(@Nullable String); - method @NonNull public T setStartPosition(long); + public static final class DataSourceDesc.Builder { + ctor public DataSourceDesc.Builder(); + ctor public DataSourceDesc.Builder(@Nullable android.media.DataSourceDesc); + method @NonNull public android.media.DataSourceDesc build(); + method @NonNull public android.media.DataSourceDesc.Builder setDataSource(@NonNull android.net.Uri); + method @NonNull public android.media.DataSourceDesc.Builder setDataSource(@NonNull android.net.Uri, @Nullable java.util.Map, @Nullable java.util.List); + method @NonNull public android.media.DataSourceDesc.Builder setDataSource(@NonNull android.os.ParcelFileDescriptor); + method @NonNull public android.media.DataSourceDesc.Builder setDataSource(@NonNull android.os.ParcelFileDescriptor, long, long); + method @NonNull public android.media.DataSourceDesc.Builder setEndPosition(long); + method @NonNull public android.media.DataSourceDesc.Builder setMediaId(@Nullable String); + method @NonNull public android.media.DataSourceDesc.Builder setStartPosition(long); } public final class DeniedByServerException extends android.media.MediaDrmException { @@ -23991,21 +23990,6 @@ package android.media { field public static final int EULER_Z = 2; // 0x2 } - public class FileDataSourceDesc extends android.media.DataSourceDesc { - method public long getLength(); - method public long getOffset(); - method @NonNull public android.os.ParcelFileDescriptor getParcelFileDescriptor(); - field public static final long FD_LENGTH_UNKNOWN = 576460752303423487L; // 0x7ffffffffffffffL - } - - public static class FileDataSourceDesc.Builder extends android.media.DataSourceDesc.BuilderBase { - ctor public FileDataSourceDesc.Builder(); - ctor public FileDataSourceDesc.Builder(@Nullable android.media.FileDataSourceDesc); - method @NonNull public android.media.FileDataSourceDesc build(); - method @NonNull public android.media.FileDataSourceDesc.Builder setDataSource(@NonNull android.os.ParcelFileDescriptor); - method @NonNull public android.media.FileDataSourceDesc.Builder setDataSource(@NonNull android.os.ParcelFileDescriptor, long, long); - } - public abstract class Image implements java.lang.AutoCloseable { method public abstract void close(); method public android.graphics.Rect getCropRect(); @@ -24426,9 +24410,10 @@ package android.media { field public static final int AV1Level71 = 2097152; // 0x200000 field public static final int AV1Level72 = 4194304; // 0x400000 field public static final int AV1Level73 = 8388608; // 0x800000 - field public static final int AV1Profile0 = 1; // 0x1 - field public static final int AV1Profile1 = 2; // 0x2 - field public static final int AV1Profile2 = 4; // 0x4 + field public static final int AV1ProfileMain10 = 2; // 0x2 + field public static final int AV1ProfileMain10HDR10 = 4096; // 0x1000 + field public static final int AV1ProfileMain10HDR10Plus = 8192; // 0x2000 + field public static final int AV1ProfileMain8 = 1; // 0x1 field public static final int AVCLevel1 = 1; // 0x1 field public static final int AVCLevel11 = 4; // 0x4 field public static final int AVCLevel12 = 8; // 0x8 @@ -24622,42 +24607,39 @@ package android.media { ctor public MediaCodecInfo.VideoCapabilities.PerformancePoint(int, int, int); method public boolean covers(@NonNull android.media.MediaFormat); method public boolean covers(@NonNull android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint); - field public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint FHD_100; - field public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint FHD_120; - field public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint FHD_200; - field public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint FHD_24; - field public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint FHD_240; - field public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint FHD_25; - field public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint FHD_30; - field public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint FHD_50; - field public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint FHD_60; - field public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint HD_100; - field public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint HD_120; - field public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint HD_200; - field public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint HD_24; - field public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint HD_240; - field public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint HD_25; - field public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint HD_30; - field public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint HD_50; - field public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint HD_60; - field public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint SD_24; - field public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint SD_25; - field public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint SD_30; - field public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint SD_48; - field public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint SD_50; - field public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint SD_60; - field public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint UHD_100; - field public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint UHD_120; - field public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint UHD_200; - field public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint UHD_24; - field public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint UHD_240; - field public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint UHD_25; - field public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint UHD_30; - field public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint UHD_50; - field public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint UHD_60; - field public final int frameRate; - field public final long macroBlockRate; - field public final int macroBlocks; + field @NonNull public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint FHD_100; + field @NonNull public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint FHD_120; + field @NonNull public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint FHD_200; + field @NonNull public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint FHD_24; + field @NonNull public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint FHD_240; + field @NonNull public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint FHD_25; + field @NonNull public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint FHD_30; + field @NonNull public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint FHD_50; + field @NonNull public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint FHD_60; + field @NonNull public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint HD_100; + field @NonNull public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint HD_120; + field @NonNull public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint HD_200; + field @NonNull public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint HD_24; + field @NonNull public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint HD_240; + field @NonNull public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint HD_25; + field @NonNull public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint HD_30; + field @NonNull public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint HD_50; + field @NonNull public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint HD_60; + field @NonNull public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint SD_24; + field @NonNull public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint SD_25; + field @NonNull public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint SD_30; + field @NonNull public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint SD_48; + field @NonNull public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint SD_50; + field @NonNull public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint SD_60; + field @NonNull public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint UHD_100; + field @NonNull public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint UHD_120; + field @NonNull public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint UHD_200; + field @NonNull public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint UHD_24; + field @NonNull public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint UHD_240; + field @NonNull public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint UHD_25; + field @NonNull public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint UHD_30; + field @NonNull public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint UHD_50; + field @NonNull public static final android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint UHD_60; } public final class MediaCodecList { @@ -24871,6 +24853,7 @@ package android.media { field public static final int STATUS_OUTPUT_NOT_ALLOWED = 2; // 0x2 field public static final int STATUS_PENDING = 3; // 0x3 field public static final int STATUS_USABLE = 0; // 0x0 + field public static final int STATUS_USABLE_IN_FUTURE = 5; // 0x5 } public static final class MediaDrm.MediaDrmStateException extends java.lang.IllegalStateException { @@ -24943,6 +24926,7 @@ package android.media { ctor public MediaDrm.SessionException(int, @Nullable String); method public int getErrorCode(); field public static final int ERROR_RESOURCE_CONTENTION = 1; // 0x1 + field public static final int ERROR_UNKNOWN = 0; // 0x0 } public class MediaDrmException extends java.lang.Exception { @@ -25072,6 +25056,7 @@ package android.media { field public static final String KEY_FRAME_RATE = "frame-rate"; field public static final String KEY_GRID_COLUMNS = "grid-cols"; field public static final String KEY_GRID_ROWS = "grid-rows"; + field public static final String KEY_HAPTIC_CHANNEL_COUNT = "haptic-channel-count"; field public static final String KEY_HDR10_PLUS_INFO = "hdr10-plus-info"; field public static final String KEY_HDR_STATIC_INFO = "hdr-static-info"; field public static final String KEY_HEIGHT = "height"; @@ -25094,6 +25079,7 @@ package android.media { field public static final String KEY_OPERATING_RATE = "operating-rate"; field public static final String KEY_OUTPUT_REORDER_DEPTH = "output-reorder-depth"; field public static final String KEY_PCM_ENCODING = "pcm-encoding"; + field public static final String KEY_PREPEND_HEADER_TO_SYNC_FRAMES = "prepend-sps-pps-to-idr-frames"; field public static final String KEY_PRIORITY = "priority"; field public static final String KEY_PROFILE = "profile"; field public static final String KEY_PUSH_BLANK_BUFFERS_ON_STOP = "push-blank-buffers-on-shutdown"; @@ -25569,8 +25555,8 @@ package android.media { method @NonNull public Object clearNextDataSources(); method public void clearPendingCommands(); method public void close(); - method @NonNull public Object deselectTrack(int); - method @NonNull public Object deselectTrack(@NonNull android.media.DataSourceDesc, int); + method @NonNull public Object deselectTrack(@NonNull android.media.MediaPlayer2.TrackInfo); + method @NonNull public Object deselectTrack(@NonNull android.media.DataSourceDesc, @NonNull android.media.MediaPlayer2.TrackInfo); method @NonNull public android.media.AudioAttributes getAudioAttributes(); method public int getAudioSessionId(); method public long getBufferedPosition(); @@ -25585,8 +25571,8 @@ package android.media { method public float getPlayerVolume(); method @Nullable public android.media.AudioDeviceInfo getPreferredDevice(); method @Nullable public android.media.AudioDeviceInfo getRoutedDevice(); - method public int getSelectedTrack(int); - method public int getSelectedTrack(@NonNull android.media.DataSourceDesc, int); + method @Nullable public android.media.MediaPlayer2.TrackInfo getSelectedTrack(int); + method @Nullable public android.media.MediaPlayer2.TrackInfo getSelectedTrack(@NonNull android.media.DataSourceDesc, int); method public int getState(); method @NonNull public android.media.SyncParams getSyncParams(); method @Nullable public android.media.MediaTimestamp getTimestamp(); @@ -25604,8 +25590,8 @@ package android.media { method public void reset(); method @NonNull public Object seekTo(long); method @NonNull public Object seekTo(long, int); - method @NonNull public Object selectTrack(int); - method @NonNull public Object selectTrack(@NonNull android.media.DataSourceDesc, int); + method @NonNull public Object selectTrack(@NonNull android.media.MediaPlayer2.TrackInfo); + method @NonNull public Object selectTrack(@NonNull android.media.DataSourceDesc, @NonNull android.media.MediaPlayer2.TrackInfo); method @NonNull public Object setAudioAttributes(@NonNull android.media.AudioAttributes); method @NonNull public Object setAudioSessionId(int); method @NonNull public Object setAuxEffectSendLevel(float); @@ -25698,11 +25684,11 @@ package android.media { field public static final int SEEK_PREVIOUS_SYNC = 0; // 0x0 } - public static class MediaPlayer2.DrmEventCallback { + public abstract static class MediaPlayer2.DrmEventCallback { ctor public MediaPlayer2.DrmEventCallback(); method public void onDrmConfig(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, @NonNull android.media.MediaDrm); - method @Nullable public android.media.MediaPlayer2.DrmPreparationInfo onDrmInfo(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, @NonNull android.media.MediaPlayer2.DrmInfo); - method @NonNull public byte[] onDrmKeyRequest(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, @NonNull android.media.MediaDrm.KeyRequest); + method @Nullable public abstract android.media.MediaPlayer2.DrmPreparationInfo onDrmInfo(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, @NonNull android.media.MediaPlayer2.DrmInfo); + method @NonNull public abstract byte[] onDrmKeyRequest(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, @NonNull android.media.MediaDrm.KeyRequest); method public void onDrmPrepared(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, int, @Nullable byte[]); } @@ -25712,17 +25698,22 @@ package android.media { } public static final class MediaPlayer2.DrmPreparationInfo { + method @Nullable public byte[] getInitData(); + method @Nullable public byte[] getKeySetId(); + method public int getKeyType(); + method @Nullable public String getMimeType(); + method @Nullable public java.util.Map getOptionalParameters(); + method @NonNull public java.util.UUID getUuid(); } public static final class MediaPlayer2.DrmPreparationInfo.Builder { - ctor public MediaPlayer2.DrmPreparationInfo.Builder(); + ctor public MediaPlayer2.DrmPreparationInfo.Builder(@NonNull java.util.UUID); method @NonNull public android.media.MediaPlayer2.DrmPreparationInfo build(); method @NonNull public android.media.MediaPlayer2.DrmPreparationInfo.Builder setInitData(@Nullable byte[]); method @NonNull public android.media.MediaPlayer2.DrmPreparationInfo.Builder setKeySetId(@Nullable byte[]); method @NonNull public android.media.MediaPlayer2.DrmPreparationInfo.Builder setKeyType(int); method @NonNull public android.media.MediaPlayer2.DrmPreparationInfo.Builder setMimeType(@Nullable String); method @NonNull public android.media.MediaPlayer2.DrmPreparationInfo.Builder setOptionalParameters(@Nullable java.util.Map); - method @NonNull public android.media.MediaPlayer2.DrmPreparationInfo.Builder setUuid(@NonNull java.util.UUID); } public static class MediaPlayer2.EventCallback { @@ -25732,7 +25723,7 @@ package android.media { method public void onError(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, int, int); method public void onInfo(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, int, int); method public void onMediaTimeDiscontinuity(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, @NonNull android.media.MediaTimestamp); - method public void onSubtitleData(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, @NonNull android.media.SubtitleData); + method public void onSubtitleData(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, @NonNull android.media.MediaPlayer2.SubtitleData); method public void onTimedMetaDataAvailable(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, @NonNull android.media.TimedMetaData); method public void onVideoSizeChanged(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, @NonNull android.util.Size); } @@ -25756,6 +25747,13 @@ package android.media { ctor public MediaPlayer2.NoDrmSchemeException(@Nullable String); } + public static final class MediaPlayer2.SubtitleData { + method @NonNull public byte[] getData(); + method public long getDurationUs(); + method public long getStartTimeUs(); + method @NonNull public android.media.MediaPlayer2.TrackInfo getTrackInfo(); + } + public static class MediaPlayer2.TrackInfo { method @Nullable public android.media.MediaFormat getFormat(); method @NonNull public String getLanguage(); @@ -25797,8 +25795,6 @@ package android.media { method public void setLocation(float, float); method public void setMaxDuration(int) throws java.lang.IllegalArgumentException; method public void setMaxFileSize(long) throws java.lang.IllegalArgumentException; - method public boolean setMicrophoneDirection(int); - method public boolean setMicrophoneFieldDimension(@FloatRange(from=-1.0, to=1.0) float); method public void setNextOutputFile(java.io.FileDescriptor) throws java.io.IOException; method public void setNextOutputFile(java.io.File) throws java.io.IOException; method public void setOnErrorListener(android.media.MediaRecorder.OnErrorListener); @@ -25809,6 +25805,8 @@ package android.media { method public void setOutputFile(String) throws java.lang.IllegalStateException; method public void setOutputFormat(int) throws java.lang.IllegalStateException; method public boolean setPreferredDevice(android.media.AudioDeviceInfo); + method public boolean setPreferredMicrophoneDirection(int); + method public boolean setPreferredMicrophoneFieldDimension(@FloatRange(from=-1.0, to=1.0) float); method public void setPreviewDisplay(android.view.Surface); method public void setProfile(android.media.CamcorderProfile); method public void setVideoEncoder(int) throws java.lang.IllegalStateException; @@ -26143,19 +26141,20 @@ package android.media { } public final class MediaTimestamp { + ctor public MediaTimestamp(long, long, @FloatRange(from=0.0f, to=java.lang.Float.MAX_VALUE) float); method public long getAnchorMediaTimeUs(); method public long getAnchorSystemNanoTime(); method @Deprecated public long getAnchorSytemNanoTime(); - method public float getMediaClockRate(); + method @FloatRange(from=0.0f, to=java.lang.Float.MAX_VALUE) public float getMediaClockRate(); field public static final android.media.MediaTimestamp TIMESTAMP_UNKNOWN; } public interface MicrophoneDirection { - method public boolean setMicrophoneDirection(int); - method public boolean setMicrophoneFieldDimension(@FloatRange(from=-1.0, to=1.0) float); - field public static final int MIC_DIRECTION_BACK = 2; // 0x2 + method public boolean setPreferredMicrophoneDirection(int); + method public boolean setPreferredMicrophoneFieldDimension(@FloatRange(from=-1.0, to=1.0) float); + field public static final int MIC_DIRECTION_AWAY_FROM_USER = 2; // 0x2 field public static final int MIC_DIRECTION_EXTERNAL = 3; // 0x3 - field public static final int MIC_DIRECTION_FRONT = 1; // 0x1 + field public static final int MIC_DIRECTION_TOWARDS_USER = 1; // 0x1 field public static final int MIC_DIRECTION_UNSPECIFIED = 0; // 0x0 } @@ -26360,6 +26359,8 @@ package android.media { method public android.net.Uri getRingtoneUri(int); method public boolean getStopPreviousRingtone(); method public static android.net.Uri getValidRingtoneUri(android.content.Context); + method public boolean hasHapticChannels(int); + method public static boolean hasHapticChannels(@NonNull android.net.Uri); method public int inferStreamType(); method public static boolean isDefault(android.net.Uri); method @Nullable public static android.content.res.AssetFileDescriptor openDefaultRingtoneUri(@NonNull android.content.Context, @NonNull android.net.Uri) throws java.io.FileNotFoundException; @@ -26396,15 +26397,15 @@ package android.media { method public void writeToParcel(@NonNull android.os.Parcel, int); field public static final int COMMAND_CODE_CUSTOM = 0; // 0x0 field @NonNull public static final android.os.Parcelable.Creator CREATOR; - field public static final int RESULT_ERROR_UNKNOWN_ERROR = -1; // 0xffffffff - field public static final int RESULT_INFO_SKIPPED = 1; // 0x1 - field public static final int RESULT_SUCCESS = 0; // 0x0 } public static final class Session2Command.Result { ctor public Session2Command.Result(int, @Nullable android.os.Bundle); method public int getResultCode(); method @Nullable public android.os.Bundle getResultData(); + field public static final int RESULT_ERROR_UNKNOWN_ERROR = -1; // 0xffffffff + field public static final int RESULT_INFO_SKIPPED = 1; // 0x1 + field public static final int RESULT_SUCCESS = 0; // 0x0 } public final class Session2CommandGroup implements android.os.Parcelable { @@ -26420,10 +26421,8 @@ package android.media { ctor public Session2CommandGroup.Builder(); ctor public Session2CommandGroup.Builder(@NonNull android.media.Session2CommandGroup); method @NonNull public android.media.Session2CommandGroup.Builder addCommand(@NonNull android.media.Session2Command); - method @NonNull public android.media.Session2CommandGroup.Builder addCommand(int); method @NonNull public android.media.Session2CommandGroup build(); method @NonNull public android.media.Session2CommandGroup.Builder removeCommand(@NonNull android.media.Session2Command); - method @NonNull public android.media.Session2CommandGroup.Builder removeCommand(int); } public final class Session2Token implements android.os.Parcelable { @@ -26474,6 +26473,7 @@ package android.media { } public final class SubtitleData { + ctor public SubtitleData(int, long, long, @NonNull byte[]); method @NonNull public byte[] getData(); method public long getDurationUs(); method public long getStartTimeUs(); @@ -26514,6 +26514,7 @@ package android.media { } public final class TimedMetaData { + ctor public TimedMetaData(long, @NonNull byte[]); method public byte[] getMetaData(); method public long getTimestamp(); } @@ -26638,21 +26639,6 @@ package android.media { ctor public UnsupportedSchemeException(String); } - public class UriDataSourceDesc extends android.media.DataSourceDesc { - method @NonNull public android.content.Context getContext(); - method @Nullable public java.util.List getCookies(); - method @Nullable public java.util.Map getHeaders(); - method @NonNull public android.net.Uri getUri(); - } - - public static class UriDataSourceDesc.Builder extends android.media.DataSourceDesc.BuilderBase { - ctor public UriDataSourceDesc.Builder(); - ctor public UriDataSourceDesc.Builder(@Nullable android.media.UriDataSourceDesc); - method @NonNull public android.media.UriDataSourceDesc build(); - method @NonNull public android.media.UriDataSourceDesc.Builder setDataSource(@NonNull android.content.Context, @NonNull android.net.Uri); - method @NonNull public android.media.UriDataSourceDesc.Builder setDataSource(@NonNull android.content.Context, @NonNull android.net.Uri, @Nullable java.util.Map, @Nullable java.util.List); - } - public interface VolumeAutomation { method @NonNull public android.media.VolumeShaper createVolumeShaper(@NonNull android.media.VolumeShaper.Configuration); } @@ -28649,7 +28635,7 @@ package android.net { public class ConnectivityManager { method public void addDefaultNetworkActiveListener(android.net.ConnectivityManager.OnNetworkActiveListener); method public boolean bindProcessToNetwork(@Nullable android.net.Network); - method public android.net.SocketKeepalive createSocketKeepalive(@NonNull android.net.Network, @NonNull android.net.IpSecManager.UdpEncapsulationSocket, @NonNull java.net.InetAddress, @NonNull java.net.InetAddress, @NonNull java.util.concurrent.Executor, @NonNull android.net.SocketKeepalive.Callback); + method @NonNull public android.net.SocketKeepalive createSocketKeepalive(@NonNull android.net.Network, @NonNull android.net.IpSecManager.UdpEncapsulationSocket, @NonNull java.net.InetAddress, @NonNull java.net.InetAddress, @NonNull java.util.concurrent.Executor, @NonNull android.net.SocketKeepalive.Callback); method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) @Nullable public android.net.Network getActiveNetwork(); method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.NetworkInfo getActiveNetworkInfo(); method @Deprecated @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.NetworkInfo[] getAllNetworkInfo(); @@ -28727,7 +28713,7 @@ package android.net { public static class ConnectivityManager.NetworkCallback { ctor public ConnectivityManager.NetworkCallback(); method public void onAvailable(android.net.Network); - method public void onBlockedStatusChanged(android.net.Network, boolean); + method public void onBlockedStatusChanged(@NonNull android.net.Network, boolean); method public void onCapabilitiesChanged(android.net.Network, android.net.NetworkCapabilities); method public void onLinkPropertiesChanged(android.net.Network, android.net.LinkProperties); method public void onLosing(android.net.Network, int); @@ -28761,8 +28747,8 @@ package android.net { public final class DnsResolver { method @NonNull public static android.net.DnsResolver getInstance(); - method public void query(@Nullable android.net.Network, @NonNull byte[], int, @NonNull java.util.concurrent.Executor, @NonNull android.net.DnsResolver.AnswerCallback); - method public void query(@Nullable android.net.Network, @NonNull String, int, int, int, @NonNull java.util.concurrent.Executor, @NonNull android.net.DnsResolver.AnswerCallback); + method public void query(@Nullable android.net.Network, @NonNull byte[], int, @NonNull java.util.concurrent.Executor, @Nullable android.os.CancellationSignal, @NonNull android.net.DnsResolver.AnswerCallback); + method public void query(@Nullable android.net.Network, @NonNull String, int, int, int, @NonNull java.util.concurrent.Executor, @Nullable android.os.CancellationSignal, @NonNull android.net.DnsResolver.AnswerCallback); field public static final int CLASS_IN = 1; // 0x1 field public static final int FLAG_EMPTY = 0; // 0x0 field public static final int FLAG_NO_CACHE_LOOKUP = 4; // 0x4 @@ -28881,16 +28867,25 @@ package android.net { } public final class LinkProperties implements android.os.Parcelable { + ctor public LinkProperties(); + method public boolean addRoute(@NonNull android.net.RouteInfo); + method public void clear(); method public int describeContents(); - method public java.util.List getDnsServers(); - method public String getDomains(); - method public android.net.ProxyInfo getHttpProxy(); + method @NonNull public java.util.List getDnsServers(); + method @Nullable public String getDomains(); + method @Nullable public android.net.ProxyInfo getHttpProxy(); method @Nullable public String getInterfaceName(); - method public java.util.List getLinkAddresses(); + method @NonNull public java.util.List getLinkAddresses(); method public int getMtu(); method @Nullable public String getPrivateDnsServerName(); - method public java.util.List getRoutes(); + method @NonNull public java.util.List getRoutes(); method public boolean isPrivateDnsActive(); + method public void setDnsServers(@NonNull java.util.Collection); + method public void setDomains(@Nullable String); + method public void setHttpProxy(@Nullable android.net.ProxyInfo); + method public void setInterfaceName(@Nullable String); + method public void setLinkAddresses(@NonNull java.util.Collection); + method public void setMtu(int); method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator CREATOR; } @@ -28998,6 +28993,7 @@ package android.net { method public int describeContents(); method public int getLinkDownstreamBandwidthKbps(); method public int getLinkUpstreamBandwidthKbps(); + method public int getSignalStrength(); method @Nullable public android.net.TransportInfo getTransportInfo(); method public boolean hasCapability(int); method public boolean hasTransport(int); @@ -29026,6 +29022,7 @@ package android.net { field public static final int NET_CAPABILITY_VALIDATED = 16; // 0x10 field public static final int NET_CAPABILITY_WIFI_P2P = 6; // 0x6 field public static final int NET_CAPABILITY_XCAP = 9; // 0x9 + field public static final int SIGNAL_STRENGTH_UNSPECIFIED = -2147483648; // 0x80000000 field public static final int TRANSPORT_BLUETOOTH = 2; // 0x2 field public static final int TRANSPORT_CELLULAR = 0; // 0x0 field public static final int TRANSPORT_ETHERNET = 3; // 0x3 @@ -29037,7 +29034,7 @@ package android.net { @Deprecated public class NetworkInfo implements android.os.Parcelable { method @Deprecated public int describeContents(); - method @Deprecated public android.net.NetworkInfo.DetailedState getDetailedState(); + method @Deprecated @NonNull public android.net.NetworkInfo.DetailedState getDetailedState(); method @Deprecated public String getExtraInfo(); method @Deprecated public String getReason(); method @Deprecated public android.net.NetworkInfo.State getState(); @@ -29173,7 +29170,7 @@ package android.net { method public final void start(@IntRange(from=0xa, to=0xe10) int); method public final void stop(); field public static final int ERROR_HARDWARE_ERROR = -31; // 0xffffffe1 - field public static final int ERROR_HARDWARE_UNSUPPORTED = -30; // 0xffffffe2 + field public static final int ERROR_INSUFFICIENT_RESOURCES = -32; // 0xffffffe0 field public static final int ERROR_INVALID_INTERVAL = -24; // 0xffffffe8 field public static final int ERROR_INVALID_IP_ADDRESS = -21; // 0xffffffeb field public static final int ERROR_INVALID_LENGTH = -23; // 0xffffffe9 @@ -29181,6 +29178,7 @@ package android.net { field public static final int ERROR_INVALID_PORT = -22; // 0xffffffea field public static final int ERROR_INVALID_SOCKET = -25; // 0xffffffe7 field public static final int ERROR_SOCKET_NOT_IDLE = -26; // 0xffffffe6 + field public static final int ERROR_UNSUPPORTED = -30; // 0xffffffe2 } public static class SocketKeepalive.Callback { @@ -30319,13 +30317,11 @@ package android.net.wifi.aware { } public static final class WifiAwareNetworkSpecifier.Builder { - ctor public WifiAwareNetworkSpecifier.Builder(); + ctor public WifiAwareNetworkSpecifier.Builder(@NonNull android.net.wifi.aware.DiscoverySession, @NonNull android.net.wifi.aware.PeerHandle); method @NonNull public android.net.wifi.aware.WifiAwareNetworkSpecifier build(); - method @NonNull public android.net.wifi.aware.WifiAwareNetworkSpecifier.Builder setDiscoverySession(@NonNull android.net.wifi.aware.DiscoverySession); - method @NonNull public android.net.wifi.aware.WifiAwareNetworkSpecifier.Builder setPeerHandle(@NonNull android.net.wifi.aware.PeerHandle); - method @NonNull public android.net.wifi.aware.WifiAwareNetworkSpecifier.Builder setPort(int); + method @NonNull public android.net.wifi.aware.WifiAwareNetworkSpecifier.Builder setPort(@IntRange(from=0, to=65535) int); method @NonNull public android.net.wifi.aware.WifiAwareNetworkSpecifier.Builder setPskPassphrase(@NonNull String); - method @NonNull public android.net.wifi.aware.WifiAwareNetworkSpecifier.Builder setTransportProtocol(int); + method @NonNull public android.net.wifi.aware.WifiAwareNetworkSpecifier.Builder setTransportProtocol(@IntRange(from=0, to=255) int); } public class WifiAwareSession implements java.lang.AutoCloseable { @@ -30765,7 +30761,6 @@ package android.net.wifi.rtt { method public double getAltitudeUncertainty(); method public java.util.List getColocatedBssids(); method public int getDatum(); - method public boolean getDependentStationIndication(); method public int getExpectedToMove(); method public double getFloorNumber(); method public double getHeightAboveFloorMeters(); @@ -30778,7 +30773,6 @@ package android.net.wifi.rtt { method @Nullable public String getMapImageMimeType(); method @Nullable public android.net.Uri getMapImageUri(); method public boolean getRegisteredLocationAgreementIndication(); - method public boolean getRegisteredLocationDseIndication(); method public boolean isLciSubelementValid(); method public boolean isZaxisSubelementValid(); method @Nullable public android.location.Address toCivicLocationAddress(); @@ -34622,6 +34616,7 @@ package android.os { method @RequiresPermission(allOf={android.Manifest.permission.READ_LOGS, android.Manifest.permission.PACKAGE_USAGE_STATS}) @Nullable public android.os.DropBoxManager.Entry getNextEntry(String, long); method public boolean isTagEnabled(String); field public static final String ACTION_DROPBOX_ENTRY_ADDED = "android.intent.action.DROPBOX_ENTRY_ADDED"; + field public static final String EXTRA_DROPPED_COUNT = "android.os.extra.DROPPED_COUNT"; field public static final String EXTRA_TAG = "tag"; field public static final String EXTRA_TIME = "time"; field public static final int IS_EMPTY = 1; // 0x1 @@ -35435,6 +35430,7 @@ package android.os { } public final class SystemClock { + method @NonNull public static java.time.Clock currentGnssTimeClock(); method public static long currentThreadTimeMillis(); method public static long elapsedRealtime(); method public static long elapsedRealtimeNanos(); @@ -38767,8 +38763,7 @@ package android.provider { field public static final String MIME_TYPE = "mime_type"; field public static final String ORIGINAL_DOCUMENT_ID = "original_document_id"; field public static final String OWNER_PACKAGE_NAME = "owner_package_name"; - field public static final String PRIMARY_DIRECTORY = "primary_directory"; - field public static final String SECONDARY_DIRECTORY = "secondary_directory"; + field public static final String RELATIVE_PATH = "relative_path"; field public static final String SIZE = "_size"; field public static final String TITLE = "title"; field public static final String WIDTH = "width"; @@ -41735,7 +41730,7 @@ package android.service.notification { method public void onNotificationRemoved(android.service.notification.StatusBarNotification); method public void onNotificationRemoved(android.service.notification.StatusBarNotification, android.service.notification.NotificationListenerService.RankingMap); method public void onNotificationRemoved(android.service.notification.StatusBarNotification, android.service.notification.NotificationListenerService.RankingMap, int); - method public void onStatusBarIconsBehaviorChanged(boolean); + method public void onSilentStatusBarIconsVisibilityChanged(boolean); method public final void requestInterruptionFilter(int); method public final void requestListenerHints(int); method public static void requestRebind(android.content.ComponentName); @@ -42501,12 +42496,12 @@ package android.system { method public static java.io.FileDescriptor accept(java.io.FileDescriptor, java.net.InetSocketAddress) throws android.system.ErrnoException, java.net.SocketException; method public static boolean access(String, int) throws android.system.ErrnoException; method public static void bind(java.io.FileDescriptor, java.net.InetAddress, int) throws android.system.ErrnoException, java.net.SocketException; - method public static void bind(java.io.FileDescriptor, java.net.SocketAddress) throws android.system.ErrnoException, java.net.SocketException; + method public static void bind(@NonNull java.io.FileDescriptor, @NonNull java.net.SocketAddress) throws android.system.ErrnoException, java.net.SocketException; method public static void chmod(String, int) throws android.system.ErrnoException; method public static void chown(String, int, int) throws android.system.ErrnoException; method public static void close(java.io.FileDescriptor) throws android.system.ErrnoException; method public static void connect(java.io.FileDescriptor, java.net.InetAddress, int) throws android.system.ErrnoException, java.net.SocketException; - method public static void connect(java.io.FileDescriptor, java.net.SocketAddress) throws android.system.ErrnoException, java.net.SocketException; + method public static void connect(@NonNull java.io.FileDescriptor, @NonNull java.net.SocketAddress) throws android.system.ErrnoException, java.net.SocketException; method public static java.io.FileDescriptor dup(java.io.FileDescriptor) throws android.system.ErrnoException; method public static java.io.FileDescriptor dup2(java.io.FileDescriptor, int) throws android.system.ErrnoException; method public static String[] environ(); @@ -42571,7 +42566,7 @@ package android.system { method public static long sendfile(java.io.FileDescriptor, java.io.FileDescriptor, android.system.Int64Ref, long) throws android.system.ErrnoException; method public static int sendto(java.io.FileDescriptor, java.nio.ByteBuffer, int, java.net.InetAddress, int) throws android.system.ErrnoException, java.net.SocketException; method public static int sendto(java.io.FileDescriptor, byte[], int, int, int, java.net.InetAddress, int) throws android.system.ErrnoException, java.net.SocketException; - method public static int sendto(java.io.FileDescriptor, byte[], int, int, int, java.net.SocketAddress) throws android.system.ErrnoException, java.net.SocketException; + method public static int sendto(@NonNull java.io.FileDescriptor, @NonNull byte[], int, int, int, @Nullable java.net.SocketAddress) throws android.system.ErrnoException, java.net.SocketException; method @Deprecated public static void setegid(int) throws android.system.ErrnoException; method public static void setenv(String, String, boolean) throws android.system.ErrnoException; method @Deprecated public static void seteuid(int) throws android.system.ErrnoException; @@ -44511,6 +44506,13 @@ package android.telephony { field @NonNull public static final android.os.Parcelable.Creator CREATOR; } + public final class CellInfoTdscdma extends android.telephony.CellInfo implements android.os.Parcelable { + method @NonNull public android.telephony.CellIdentityTdscdma getCellIdentity(); + method @NonNull public android.telephony.CellSignalStrengthTdscdma getCellSignalStrength(); + method public void writeToParcel(android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator CREATOR; + } + public final class CellInfoWcdma extends android.telephony.CellInfo implements android.os.Parcelable { method public android.telephony.CellIdentityWcdma getCellIdentity(); method public android.telephony.CellSignalStrengthWcdma getCellSignalStrength(); @@ -44594,6 +44596,16 @@ package android.telephony { field @NonNull public static final android.os.Parcelable.Creator CREATOR; } + public final class CellSignalStrengthTdscdma extends android.telephony.CellSignalStrength implements android.os.Parcelable { + method public int describeContents(); + method public int getAsuLevel(); + method public int getDbm(); + method public int getLevel(); + method public int getRscp(); + method public void writeToParcel(android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator CREATOR; + } + public final class CellSignalStrengthWcdma extends android.telephony.CellSignalStrength implements android.os.Parcelable { method public int describeContents(); method public int getAsuLevel(); @@ -45020,7 +45032,7 @@ package android.telephony { method public String getCountryIso(); method public int getDataRoaming(); method public CharSequence getDisplayName(); - method @Nullable public String getGroupUuid(); + method @Nullable public android.os.ParcelUuid getGroupUuid(); method public String getIccId(); method public int getIconTint(); method @Deprecated public int getMcc(); @@ -45040,7 +45052,9 @@ package android.telephony { public class SubscriptionManager { method public void addOnOpportunisticSubscriptionsChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.SubscriptionManager.OnOpportunisticSubscriptionsChangedListener); method public void addOnSubscriptionsChangedListener(android.telephony.SubscriptionManager.OnSubscriptionsChangedListener); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void addSubscriptionsIntoGroup(@NonNull java.util.List, @NonNull android.os.ParcelUuid); method public boolean canManageSubscription(android.telephony.SubscriptionInfo); + method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public android.os.ParcelUuid createSubscriptionGroup(@NonNull java.util.List); method @Deprecated public static android.telephony.SubscriptionManager from(android.content.Context); method public java.util.List getAccessibleSubscriptionInfoList(); method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public android.telephony.SubscriptionInfo getActiveSubscriptionInfo(int); @@ -45056,16 +45070,15 @@ package android.telephony { method public static int getSlotIndex(int); method @Nullable public int[] getSubscriptionIds(int); method @NonNull public java.util.List getSubscriptionPlans(int); - method @Nullable @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public java.util.List getSubscriptionsInGroup(int); + method @NonNull @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public java.util.List getSubscriptionsInGroup(@NonNull android.os.ParcelUuid); method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public boolean isActiveSubscriptionId(int); method public boolean isNetworkRoaming(int); method public static boolean isUsableSubscriptionId(int); method public static boolean isValidSubscriptionId(int); method public void removeOnOpportunisticSubscriptionsChangedListener(@NonNull android.telephony.SubscriptionManager.OnOpportunisticSubscriptionsChangedListener); method public void removeOnSubscriptionsChangedListener(android.telephony.SubscriptionManager.OnSubscriptionsChangedListener); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean removeSubscriptionsFromGroup(@NonNull int[]); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void removeSubscriptionsFromGroup(@NonNull java.util.List, @NonNull android.os.ParcelUuid); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setOpportunistic(boolean, int); - method @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String setSubscriptionGroup(@NonNull int[]); method public void setSubscriptionOverrideCongested(int, boolean, long); method public void setSubscriptionOverrideUnmetered(int, boolean, long); method public void setSubscriptionPlans(int, @NonNull java.util.List); @@ -45197,7 +45210,7 @@ package android.telephony { method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_NETWORK_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isDataRoamingEnabled(); method public boolean isEmergencyNumber(@NonNull String); method public boolean isHearingAidCompatibilitySupported(); - method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public boolean isMultisimSupported(); + method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public int isMultiSimSupported(); method public boolean isNetworkRoaming(); method public boolean isRttSupported(); method public boolean isSmsCapable(); @@ -45277,6 +45290,9 @@ package android.telephony { field public static final String EXTRA_SUBSCRIPTION_ID = "android.telephony.extra.SUBSCRIPTION_ID"; field public static final String EXTRA_VOICEMAIL_NUMBER = "android.telephony.extra.VOICEMAIL_NUMBER"; field public static final String METADATA_HIDE_VOICEMAIL_SETTINGS_MENU = "android.telephony.HIDE_VOICEMAIL_SETTINGS_MENU"; + field public static final int MULTISIM_ALLOWED = 0; // 0x0 + field public static final int MULTISIM_NOT_SUPPORTED_BY_CARRIER = 2; // 0x2 + field public static final int MULTISIM_NOT_SUPPORTED_BY_HARDWARE = 1; // 0x1 field public static final int NETWORK_TYPE_1xRTT = 7; // 0x7 field public static final int NETWORK_TYPE_CDMA = 4; // 0x4 field public static final int NETWORK_TYPE_EDGE = 2; // 0x2 @@ -45486,26 +45502,26 @@ package android.telephony.data { public static class ApnSetting.Builder { ctor public ApnSetting.Builder(); method public android.telephony.data.ApnSetting build(); - method @NonNull public android.telephony.data.ApnSetting.Builder setApnName(String); + method @NonNull public android.telephony.data.ApnSetting.Builder setApnName(@Nullable String); method @NonNull public android.telephony.data.ApnSetting.Builder setApnTypeBitmask(int); method @NonNull public android.telephony.data.ApnSetting.Builder setAuthType(int); method @NonNull public android.telephony.data.ApnSetting.Builder setCarrierEnabled(boolean); method @NonNull public android.telephony.data.ApnSetting.Builder setCarrierId(int); - method @NonNull public android.telephony.data.ApnSetting.Builder setEntryName(String); + method @NonNull public android.telephony.data.ApnSetting.Builder setEntryName(@Nullable String); method @Deprecated public android.telephony.data.ApnSetting.Builder setMmsProxyAddress(java.net.InetAddress); - method @NonNull public android.telephony.data.ApnSetting.Builder setMmsProxyAddress(String); + method @NonNull public android.telephony.data.ApnSetting.Builder setMmsProxyAddress(@Nullable String); method @NonNull public android.telephony.data.ApnSetting.Builder setMmsProxyPort(int); - method @NonNull public android.telephony.data.ApnSetting.Builder setMmsc(android.net.Uri); + method @NonNull public android.telephony.data.ApnSetting.Builder setMmsc(@Nullable android.net.Uri); method @NonNull public android.telephony.data.ApnSetting.Builder setMvnoType(int); method @NonNull public android.telephony.data.ApnSetting.Builder setNetworkTypeBitmask(int); - method @NonNull public android.telephony.data.ApnSetting.Builder setOperatorNumeric(String); - method @NonNull public android.telephony.data.ApnSetting.Builder setPassword(String); + method @NonNull public android.telephony.data.ApnSetting.Builder setOperatorNumeric(@Nullable String); + method @NonNull public android.telephony.data.ApnSetting.Builder setPassword(@Nullable String); method @NonNull public android.telephony.data.ApnSetting.Builder setProtocol(int); method @Deprecated public android.telephony.data.ApnSetting.Builder setProxyAddress(java.net.InetAddress); - method @NonNull public android.telephony.data.ApnSetting.Builder setProxyAddress(String); + method @NonNull public android.telephony.data.ApnSetting.Builder setProxyAddress(@Nullable String); method @NonNull public android.telephony.data.ApnSetting.Builder setProxyPort(int); method @NonNull public android.telephony.data.ApnSetting.Builder setRoamingProtocol(int); - method @NonNull public android.telephony.data.ApnSetting.Builder setUser(String); + method @NonNull public android.telephony.data.ApnSetting.Builder setUser(@Nullable String); } } @@ -53503,7 +53519,6 @@ package android.view.inputmethod { package android.view.inspector { public interface InspectionCompanion { - method @Nullable public default String getNodeName(); method public void mapProperties(@NonNull android.view.inspector.PropertyMapper); method public void readProperties(@NonNull T, @NonNull android.view.inspector.PropertyReader); } diff --git a/api/removed.txt b/api/removed.txt index fa07094e6b84d4ce55e145da0f2fba91d88b48f0..fe3e866de682b55a28fd7c5e999797c59c973cee 100644 --- a/api/removed.txt +++ b/api/removed.txt @@ -524,6 +524,8 @@ package android.provider { public static interface MediaStore.MediaColumns extends android.provider.BaseColumns { field @Deprecated public static final String HASH = "_hash"; field @Deprecated public static final String IS_TRASHED = "is_trashed"; + field @Deprecated public static final String PRIMARY_DIRECTORY = "primary_directory"; + field @Deprecated public static final String SECONDARY_DIRECTORY = "secondary_directory"; } @Deprecated public static class MediaStore.PendingParams { diff --git a/api/system-current.txt b/api/system-current.txt index 9548a27fc33aef62d0d2f47cda23048971f4ad59..a4cf10db3f4b7778fe138ca235aa2abf02345cff 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -12,6 +12,7 @@ package android { field public static final String ACCESS_MTP = "android.permission.ACCESS_MTP"; field public static final String ACCESS_NETWORK_CONDITIONS = "android.permission.ACCESS_NETWORK_CONDITIONS"; field public static final String ACCESS_NOTIFICATIONS = "android.permission.ACCESS_NOTIFICATIONS"; + field public static final String ACCESS_SHARED_LIBRARIES = "android.permission.ACCESS_SHARED_LIBRARIES"; field public static final String ACCESS_SHORTCUTS = "android.permission.ACCESS_SHORTCUTS"; field public static final String ACCESS_SURFACE_FLINGER = "android.permission.ACCESS_SURFACE_FLINGER"; field public static final String ACTIVITY_EMBEDDING = "android.permission.ACTIVITY_EMBEDDING"; @@ -117,6 +118,7 @@ package android { field public static final String MODIFY_QUIET_MODE = "android.permission.MODIFY_QUIET_MODE"; field public static final String MOVE_PACKAGE = "android.permission.MOVE_PACKAGE"; field public static final String NETWORK_MANAGED_PROVISIONING = "android.permission.NETWORK_MANAGED_PROVISIONING"; + field public static final String NETWORK_SCAN = "android.permission.NETWORK_SCAN"; field public static final String NETWORK_SETUP_WIZARD = "android.permission.NETWORK_SETUP_WIZARD"; field public static final String NOTIFICATION_DURING_SETUP = "android.permission.NOTIFICATION_DURING_SETUP"; field public static final String NOTIFY_TV_INPUTS = "android.permission.NOTIFY_TV_INPUTS"; @@ -186,7 +188,6 @@ package android { field public static final String SUBSTITUTE_NOTIFICATION_APP_NAME = "android.permission.SUBSTITUTE_NOTIFICATION_APP_NAME"; field public static final String SUBSTITUTE_SHARE_TARGET_APP_NAME_AND_ICON = "android.permission.SUBSTITUTE_SHARE_TARGET_APP_NAME_AND_ICON"; field public static final String SUSPEND_APPS = "android.permission.SUSPEND_APPS"; - field public static final String TEST_MANAGE_ROLLBACKS = "android.permission.TEST_MANAGE_ROLLBACKS"; field public static final String TETHER_PRIVILEGED = "android.permission.TETHER_PRIVILEGED"; field public static final String TV_INPUT_HARDWARE = "android.permission.TV_INPUT_HARDWARE"; field public static final String TV_VIRTUAL_REMOTE_CONTROLLER = "android.permission.TV_VIRTUAL_REMOTE_CONTROLLER"; @@ -547,6 +548,7 @@ package android.app { } public class NotificationManager { + method @NonNull public java.util.List getAllowedAssistantCapabilities(); method @Nullable public android.content.ComponentName getAllowedNotificationAssistant(); method public boolean isNotificationAssistantAccessGranted(@NonNull android.content.ComponentName); method public void setNotificationAssistantAccessGranted(@Nullable android.content.ComponentName, boolean); @@ -744,7 +746,8 @@ package android.app.backup { method @RequiresPermission(android.Manifest.permission.BACKUP) public String getCurrentTransport(); method @Nullable @RequiresPermission(android.Manifest.permission.BACKUP) public android.content.ComponentName getCurrentTransportComponent(); method @RequiresPermission(android.Manifest.permission.BACKUP) public android.content.Intent getDataManagementIntent(String); - method @RequiresPermission(android.Manifest.permission.BACKUP) public String getDataManagementLabel(String); + method @Nullable @RequiresPermission(android.Manifest.permission.BACKUP) public CharSequence getDataManagementIntentLabel(@NonNull String); + method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.BACKUP) public String getDataManagementLabel(@NonNull String); method @RequiresPermission(android.Manifest.permission.BACKUP) public String getDestinationString(String); method @RequiresPermission(android.Manifest.permission.BACKUP) public boolean isAppEligibleForBackup(String); method @RequiresPermission(android.Manifest.permission.BACKUP) public boolean isBackupEnabled(); @@ -758,7 +761,8 @@ package android.app.backup { method @RequiresPermission(android.Manifest.permission.BACKUP) public void setAncestralSerialNumber(long); method @RequiresPermission(android.Manifest.permission.BACKUP) public void setAutoRestore(boolean); method @RequiresPermission(android.Manifest.permission.BACKUP) public void setBackupEnabled(boolean); - method @RequiresPermission(android.Manifest.permission.BACKUP) public void updateTransportAttributes(android.content.ComponentName, String, @Nullable android.content.Intent, String, @Nullable android.content.Intent, @Nullable String); + method @Deprecated @RequiresPermission(android.Manifest.permission.BACKUP) public void updateTransportAttributes(@NonNull android.content.ComponentName, @NonNull String, @Nullable android.content.Intent, @NonNull String, @Nullable android.content.Intent, @Nullable String); + method @RequiresPermission(android.Manifest.permission.BACKUP) public void updateTransportAttributes(@NonNull android.content.ComponentName, @NonNull String, @Nullable android.content.Intent, @NonNull String, @Nullable android.content.Intent, @Nullable CharSequence); field public static final int ERROR_AGENT_FAILURE = -1003; // 0xfffffc15 field public static final int ERROR_BACKUP_CANCELLED = -2003; // 0xfffff82d field public static final int ERROR_BACKUP_NOT_ALLOWED = -2001; // 0xfffff82f @@ -863,7 +867,8 @@ package android.app.backup { method public android.content.Intent configurationIntent(); method public String currentDestinationString(); method public android.content.Intent dataManagementIntent(); - method public String dataManagementLabel(); + method @Nullable public CharSequence dataManagementIntentLabel(); + method @Deprecated @Nullable public String dataManagementLabel(); method public int finishBackup(); method public void finishRestore(); method public android.app.backup.RestoreSet[] getAvailableRestoreSets(); @@ -1059,7 +1064,7 @@ package android.app.prediction { public final class AppPredictor { method public void destroy(); method public void notifyAppTargetEvent(@NonNull android.app.prediction.AppTargetEvent); - method public void notifyLocationShown(@NonNull String, @NonNull java.util.List); + method public void notifyLaunchLocationShown(@NonNull String, @NonNull java.util.List); method public void registerPredictionUpdates(@NonNull java.util.concurrent.Executor, @NonNull android.app.prediction.AppPredictor.Callback); method public void requestPredictionUpdate(); method @Nullable public void sortTargets(@NonNull java.util.List, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer>); @@ -1071,8 +1076,6 @@ package android.app.prediction { } public final class AppTarget implements android.os.Parcelable { - ctor public AppTarget(@NonNull android.app.prediction.AppTargetId, @NonNull String, @Nullable String, @NonNull android.os.UserHandle); - ctor public AppTarget(@NonNull android.app.prediction.AppTargetId, @NonNull android.content.pm.ShortcutInfo, @Nullable String); method public int describeContents(); method @Nullable public String getClassName(); method @NonNull public android.app.prediction.AppTargetId getId(); @@ -1084,6 +1087,15 @@ package android.app.prediction { field @NonNull public static final android.os.Parcelable.Creator CREATOR; } + public static final class AppTarget.Builder { + ctor public AppTarget.Builder(@NonNull android.app.prediction.AppTargetId); + method @NonNull public android.app.prediction.AppTarget build(); + method @NonNull public android.app.prediction.AppTarget.Builder setClassName(@NonNull String); + method @NonNull public android.app.prediction.AppTarget.Builder setRank(@IntRange(from=0) int); + method @NonNull public android.app.prediction.AppTarget.Builder setTarget(@NonNull String, @NonNull android.os.UserHandle); + method @NonNull public android.app.prediction.AppTarget.Builder setTarget(@NonNull android.content.pm.ShortcutInfo); + } + public final class AppTargetEvent implements android.os.Parcelable { method public int describeContents(); method public int getAction(); @@ -1349,7 +1361,6 @@ package android.content { field public static final String BACKUP_SERVICE = "backup"; field public static final String CONTENT_SUGGESTIONS_SERVICE = "content_suggestions"; field public static final String CONTEXTHUB_SERVICE = "contexthub"; - field public static final String DYNAMIC_ANDROID_SERVICE = "dynamic_android"; field public static final String EUICC_CARD_SERVICE = "euicc_card"; field public static final String HDMI_CONTROL_SERVICE = "hdmi_control"; field public static final String NETD_SERVICE = "netd"; @@ -1376,32 +1387,6 @@ package android.content { method public void sendOrderedBroadcast(android.content.Intent, String, android.os.Bundle, android.content.BroadcastReceiver, android.os.Handler, int, String, android.os.Bundle); } - public class DynamicAndroidClient { - ctor public DynamicAndroidClient(@NonNull android.content.Context); - method public void bind(); - method public void setOnStatusChangedListener(@NonNull android.content.DynamicAndroidClient.OnStatusChangedListener, @NonNull java.util.concurrent.Executor); - method public void setOnStatusChangedListener(@NonNull android.content.DynamicAndroidClient.OnStatusChangedListener); - method public void start(String, long); - method public void start(String, long, long); - method public void unbind(); - field public static final int CAUSE_ERROR_EXCEPTION = 6; // 0x6 - field public static final int CAUSE_ERROR_INVALID_URL = 4; // 0x4 - field public static final int CAUSE_ERROR_IO = 3; // 0x3 - field public static final int CAUSE_ERROR_IPC = 5; // 0x5 - field public static final int CAUSE_INSTALL_CANCELLED = 2; // 0x2 - field public static final int CAUSE_INSTALL_COMPLETED = 1; // 0x1 - field public static final int CAUSE_NOT_SPECIFIED = 0; // 0x0 - field public static final int STATUS_IN_PROGRESS = 2; // 0x2 - field public static final int STATUS_IN_USE = 4; // 0x4 - field public static final int STATUS_NOT_STARTED = 1; // 0x1 - field public static final int STATUS_READY = 3; // 0x3 - field public static final int STATUS_UNKNOWN = 0; // 0x0 - } - - public static interface DynamicAndroidClient.OnStatusChangedListener { - method public void onStatusChanged(int, int, long); - } - public class Intent implements java.lang.Cloneable android.os.Parcelable { field public static final String ACTION_BATTERY_LEVEL_CHANGED = "android.intent.action.BATTERY_LEVEL_CHANGED"; field public static final String ACTION_CALL_EMERGENCY = "android.intent.action.CALL_EMERGENCY"; @@ -1425,14 +1410,15 @@ package android.content { field public static final String ACTION_QUERY_PACKAGE_RESTART = "android.intent.action.QUERY_PACKAGE_RESTART"; field public static final String ACTION_RESOLVE_INSTANT_APP_PACKAGE = "android.intent.action.RESOLVE_INSTANT_APP_PACKAGE"; field @RequiresPermission(android.Manifest.permission.REVIEW_ACCESSIBILITY_SERVICES) public static final String ACTION_REVIEW_ACCESSIBILITY_SERVICES = "android.intent.action.REVIEW_ACCESSIBILITY_SERVICES"; - field @RequiresPermission(android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS) public static final String ACTION_REVIEW_APP_PERMISSION_USAGE = "android.intent.action.REVIEW_APP_PERMISSION_USAGE"; + field @RequiresPermission(android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS) public static final String ACTION_REVIEW_ONGOING_PERMISSION_USAGE = "android.intent.action.REVIEW_ONGOING_PERMISSION_USAGE"; field public static final String ACTION_REVIEW_PERMISSIONS = "android.intent.action.REVIEW_PERMISSIONS"; - field public static final String ACTION_REVIEW_PERMISSION_USAGE = "android.intent.action.REVIEW_PERMISSION_USAGE"; + field @RequiresPermission(android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS) public static final String ACTION_REVIEW_PERMISSION_USAGE = "android.intent.action.REVIEW_PERMISSION_USAGE"; field public static final String ACTION_ROLLBACK_COMMITTED = "android.intent.action.ROLLBACK_COMMITTED"; field public static final String ACTION_SHOW_SUSPENDED_APP_DETAILS = "android.intent.action.SHOW_SUSPENDED_APP_DETAILS"; field @Deprecated public static final String ACTION_SIM_STATE_CHANGED = "android.intent.action.SIM_STATE_CHANGED"; field public static final String ACTION_SPLIT_CONFIGURATION_CHANGED = "android.intent.action.SPLIT_CONFIGURATION_CHANGED"; field public static final String ACTION_UPGRADE_SETUP = "android.intent.action.UPGRADE_SETUP"; + field public static final String ACTION_USER_ADDED = "android.intent.action.USER_ADDED"; field public static final String ACTION_USER_REMOVED = "android.intent.action.USER_REMOVED"; field public static final String ACTION_VOICE_ASSIST = "android.intent.action.VOICE_ASSIST"; field public static final String CATEGORY_LEANBACK_SETTINGS = "android.intent.category.LEANBACK_SETTINGS"; @@ -1475,15 +1461,16 @@ package android.content.om { field @NonNull public static final android.os.Parcelable.Creator CREATOR; field public final String category; field public final String packageName; + field public final String targetOverlayableName; field public final String targetPackageName; field public final int userId; } public class OverlayManager { method @Nullable public android.content.om.OverlayInfo getOverlayInfo(@NonNull String, @NonNull android.os.UserHandle); - method public java.util.List getOverlayInfosForTarget(@Nullable String, int); - method public boolean setEnabled(@Nullable String, boolean, int); - method public boolean setEnabledExclusiveInCategory(@Nullable String, int); + method @NonNull @RequiresPermission(anyOf={"android.permission.INTERACT_ACROSS_USERS", "android.permission.INTERACT_ACROSS_USERS_FULL"}) public java.util.List getOverlayInfosForTarget(@NonNull String, @NonNull android.os.UserHandle); + method @RequiresPermission(anyOf={"android.permission.INTERACT_ACROSS_USERS", "android.permission.INTERACT_ACROSS_USERS_FULL"}) public void setEnabled(@NonNull String, boolean, @NonNull android.os.UserHandle); + method @RequiresPermission(anyOf={"android.permission.INTERACT_ACROSS_USERS", "android.permission.INTERACT_ACROSS_USERS_FULL"}) public void setEnabledExclusiveInCategory(@NonNull String, @NonNull android.os.UserHandle); } } @@ -1609,6 +1596,7 @@ package android.content.pm { method public abstract java.util.List getAllIntentFilters(String); method @NonNull @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public android.content.pm.ApplicationInfo getApplicationInfoAsUser(@NonNull String, int, @NonNull android.os.UserHandle) throws android.content.pm.PackageManager.NameNotFoundException; method @NonNull public android.content.pm.dex.ArtManager getArtManager(); + method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_SHARED_LIBRARIES) public java.util.List getDeclaredSharedLibraries(@NonNull String, int); method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) public abstract String getDefaultBrowserPackageNameAsUser(int); method @Nullable @RequiresPermission(android.Manifest.permission.SET_HARMFUL_APP_WARNINGS) public CharSequence getHarmfulAppWarning(@NonNull String); method public String getIncidentReportApproverPackageName(); @@ -1620,7 +1608,6 @@ package android.content.pm { method public abstract java.util.List getIntentFilterVerifications(String); method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) public abstract int getIntentVerificationStatusAsUser(String, int); method @android.content.pm.PackageManager.PermissionFlags @RequiresPermission(anyOf={android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, android.Manifest.permission.GET_RUNTIME_PERMISSIONS}) public abstract int getPermissionFlags(String, String, @NonNull android.os.UserHandle); - method public boolean getSyntheticAppDetailsActivityEnabled(@NonNull String); method @NonNull @RequiresPermission(android.Manifest.permission.SUSPEND_APPS) public String[] getUnsuspendablePackages(@NonNull String[]); method @RequiresPermission(android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS) public abstract void grantRuntimePermission(@NonNull String, @NonNull String, @NonNull android.os.UserHandle); method @Deprecated public abstract int installExistingPackage(String) throws android.content.pm.PackageManager.NameNotFoundException; @@ -1753,7 +1740,7 @@ package android.content.pm { } public class ShortcutManager { - method @NonNull public java.util.List getShareTargets(@NonNull android.content.IntentFilter); + method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_APP_PREDICTIONS) public java.util.List getShareTargets(@NonNull android.content.IntentFilter); method public boolean hasShareTargets(@NonNull String); } @@ -1840,9 +1827,9 @@ package android.content.rollback { } public final class RollbackManager { - method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_ROLLBACKS, android.Manifest.permission.TEST_MANAGE_ROLLBACKS}) public void commitRollback(int, @NonNull java.util.List, @NonNull android.content.IntentSender); - method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_ROLLBACKS, android.Manifest.permission.TEST_MANAGE_ROLLBACKS}) @NonNull public java.util.List getAvailableRollbacks(); - method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_ROLLBACKS, android.Manifest.permission.TEST_MANAGE_ROLLBACKS}) @NonNull public java.util.List getRecentlyCommittedRollbacks(); + method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_ROLLBACKS, "android.permission.TEST_MANAGE_ROLLBACKS"}) public void commitRollback(int, @NonNull java.util.List, @NonNull android.content.IntentSender); + method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_ROLLBACKS, "android.permission.TEST_MANAGE_ROLLBACKS"}) @NonNull public java.util.List getAvailableRollbacks(); + method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_ROLLBACKS, "android.permission.TEST_MANAGE_ROLLBACKS"}) @NonNull public java.util.List getRecentlyCommittedRollbacks(); field public static final String EXTRA_STATUS = "android.content.rollback.extra.STATUS"; field public static final String EXTRA_STATUS_MESSAGE = "android.content.rollback.extra.STATUS_MESSAGE"; field public static final int STATUS_FAILURE = 1; // 0x1 @@ -3574,13 +3561,6 @@ package android.media { field public static final int RADIO_TUNER = 1998; // 0x7ce } - public static final class MediaTimestamp.Builder { - ctor public MediaTimestamp.Builder(); - ctor public MediaTimestamp.Builder(@NonNull android.media.MediaTimestamp); - method @NonNull public android.media.MediaTimestamp build(); - method @NonNull public android.media.MediaTimestamp.Builder setMediaTimestamp(long, long, float); - } - public class PlayerProxy { method public void pause(); method public void setPan(float); @@ -3590,20 +3570,6 @@ package android.media { method public void stop(); } - public static final class SubtitleData.Builder { - ctor public SubtitleData.Builder(); - ctor public SubtitleData.Builder(@NonNull android.media.SubtitleData); - method @NonNull public android.media.SubtitleData build(); - method @NonNull public android.media.SubtitleData.Builder setSubtitleData(int, long, long, @NonNull byte[]); - } - - public static final class TimedMetaData.Builder { - ctor public TimedMetaData.Builder(); - ctor public TimedMetaData.Builder(@NonNull android.media.TimedMetaData); - method @NonNull public android.media.TimedMetaData build(); - method @NonNull public android.media.TimedMetaData.Builder setTimedMetaData(long, @NonNull byte[]); - } - } package android.media.audiopolicy { @@ -3680,13 +3646,14 @@ package android.media.audiopolicy { public static class AudioPolicy.Builder { ctor public AudioPolicy.Builder(android.content.Context); - method public android.media.audiopolicy.AudioPolicy.Builder addMix(@NonNull android.media.audiopolicy.AudioMix) throws java.lang.IllegalArgumentException; - method public android.media.audiopolicy.AudioPolicy build(); + method @NonNull public android.media.audiopolicy.AudioPolicy.Builder addMix(@NonNull android.media.audiopolicy.AudioMix) throws java.lang.IllegalArgumentException; + method @NonNull public android.media.audiopolicy.AudioPolicy build(); method public void setAudioPolicyFocusListener(android.media.audiopolicy.AudioPolicy.AudioPolicyFocusListener); method public void setAudioPolicyStatusListener(android.media.audiopolicy.AudioPolicy.AudioPolicyStatusListener); - method public android.media.audiopolicy.AudioPolicy.Builder setAudioPolicyVolumeCallback(@NonNull android.media.audiopolicy.AudioPolicy.AudioPolicyVolumeCallback); - method public android.media.audiopolicy.AudioPolicy.Builder setIsAudioFocusPolicy(boolean); - method public android.media.audiopolicy.AudioPolicy.Builder setLooper(@NonNull android.os.Looper) throws java.lang.IllegalArgumentException; + method @NonNull public android.media.audiopolicy.AudioPolicy.Builder setAudioPolicyVolumeCallback(@NonNull android.media.audiopolicy.AudioPolicy.AudioPolicyVolumeCallback); + method @NonNull public android.media.audiopolicy.AudioPolicy.Builder setIsAudioFocusPolicy(boolean); + method @NonNull public android.media.audiopolicy.AudioPolicy.Builder setIsTestFocusPolicy(boolean); + method @NonNull public android.media.audiopolicy.AudioPolicy.Builder setLooper(@NonNull android.os.Looper) throws java.lang.IllegalArgumentException; } public final class AudioProductStrategies implements java.lang.Iterable android.os.Parcelable { @@ -4044,8 +4011,7 @@ package android.metrics { package android.net { public class CaptivePortal implements android.os.Parcelable { - ctor public CaptivePortal(android.os.IBinder); - method public void logEvent(int, String); + method public void logEvent(int, @NonNull String); method public void useNetwork(); field public static final int APP_RETURN_DISMISSED = 0; // 0x0 field public static final int APP_RETURN_UNWANTED = 1; // 0x1 @@ -4053,15 +4019,15 @@ package android.net { } public class ConnectivityManager { - method @RequiresPermission(android.Manifest.permission.PACKET_KEEPALIVE_OFFLOAD) public android.net.SocketKeepalive createNattKeepalive(@NonNull android.net.Network, @NonNull java.io.FileDescriptor, @NonNull java.net.InetAddress, @NonNull java.net.InetAddress, @NonNull java.util.concurrent.Executor, @NonNull android.net.SocketKeepalive.Callback); - method @RequiresPermission(android.Manifest.permission.PACKET_KEEPALIVE_OFFLOAD) public android.net.SocketKeepalive createSocketKeepalive(@NonNull android.net.Network, @NonNull java.net.Socket, @NonNull java.util.concurrent.Executor, @NonNull android.net.SocketKeepalive.Callback); - method public boolean getAvoidBadWifi(); + method @NonNull @RequiresPermission(android.Manifest.permission.PACKET_KEEPALIVE_OFFLOAD) public android.net.SocketKeepalive createNattKeepalive(@NonNull android.net.Network, @NonNull android.os.ParcelFileDescriptor, @NonNull java.net.InetAddress, @NonNull java.net.InetAddress, @NonNull java.util.concurrent.Executor, @NonNull android.net.SocketKeepalive.Callback); + method @NonNull @RequiresPermission(android.Manifest.permission.PACKET_KEEPALIVE_OFFLOAD) public android.net.SocketKeepalive createSocketKeepalive(@NonNull android.net.Network, @NonNull java.net.Socket, @NonNull java.util.concurrent.Executor, @NonNull android.net.SocketKeepalive.Callback); method @RequiresPermission(android.Manifest.permission.LOCAL_MAC_ADDRESS) public String getCaptivePortalServerUrl(); method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void getLatestTetheringEntitlementResult(int, boolean, @NonNull java.util.concurrent.Executor, @NonNull android.net.ConnectivityManager.OnTetheringEntitlementResultListener); method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public boolean isTetheringSupported(); method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void registerTetheringEventCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.ConnectivityManager.OnTetheringEventCallback); method @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD, "android.permission.NETWORK_STACK"}) public void setAirplaneMode(boolean); - method @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public void startCaptivePortalApp(android.net.Network, android.os.Bundle); + method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, "android.permission.NETWORK_STACK"}) public boolean shouldAvoidBadWifi(); + method @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public void startCaptivePortalApp(@NonNull android.net.Network, @NonNull android.os.Bundle); method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void startTethering(int, boolean, android.net.ConnectivityManager.OnStartTetheringCallback); method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void startTethering(int, boolean, android.net.ConnectivityManager.OnStartTetheringCallback, android.os.Handler); method @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void stopTethering(int); @@ -4092,8 +4058,8 @@ package android.net { } public final class IpPrefix implements android.os.Parcelable { - ctor public IpPrefix(java.net.InetAddress, int); - ctor public IpPrefix(String); + ctor public IpPrefix(@NonNull java.net.InetAddress, int); + ctor public IpPrefix(@NonNull String); } public final class IpSecManager { @@ -4116,57 +4082,47 @@ package android.net { ctor public LinkAddress(java.net.InetAddress, int, int, int); ctor public LinkAddress(@NonNull java.net.InetAddress, int); ctor public LinkAddress(@NonNull String); - ctor public LinkAddress(String, int, int); + ctor public LinkAddress(@NonNull String, int, int); method public boolean isGlobalPreferred(); - method public boolean isIPv4(); - method public boolean isIPv6(); - method public boolean isSameAddressAs(android.net.LinkAddress); + method public boolean isIpv4(); + method public boolean isIpv6(); + method public boolean isSameAddressAs(@Nullable android.net.LinkAddress); } public final class LinkProperties implements android.os.Parcelable { - ctor public LinkProperties(); - ctor public LinkProperties(android.net.LinkProperties); - method public boolean addDnsServer(java.net.InetAddress); - method public boolean addLinkAddress(android.net.LinkAddress); - method public boolean addRoute(android.net.RouteInfo); - method public void clear(); + ctor public LinkProperties(@Nullable android.net.LinkProperties); + method public boolean addDnsServer(@NonNull java.net.InetAddress); + method public boolean addLinkAddress(@NonNull android.net.LinkAddress); method @Nullable public android.net.IpPrefix getNat64Prefix(); - method public java.util.List getPcscfServers(); - method public String getTcpBufferSizes(); - method public java.util.List getValidatedPrivateDnsServers(); - method public boolean hasGlobalIPv6Address(); - method public boolean hasIPv4Address(); - method public boolean hasIPv6DefaultRoute(); - method public boolean isIPv4Provisioned(); - method public boolean isIPv6Provisioned(); + method @NonNull public java.util.List getPcscfServers(); + method @Nullable public String getTcpBufferSizes(); + method @NonNull public java.util.List getValidatedPrivateDnsServers(); + method public boolean hasGlobalIpv6Address(); + method public boolean hasIpv4Address(); + method public boolean hasIpv6DefaultRoute(); + method public boolean isIpv4Provisioned(); + method public boolean isIpv6Provisioned(); method public boolean isProvisioned(); - method public boolean isReachable(java.net.InetAddress); - method public boolean removeDnsServer(java.net.InetAddress); - method public boolean removeLinkAddress(android.net.LinkAddress); - method public boolean removeRoute(android.net.RouteInfo); - method public void setDnsServers(java.util.Collection); - method public void setDomains(String); - method public void setHttpProxy(android.net.ProxyInfo); - method public void setInterfaceName(String); - method public void setLinkAddresses(java.util.Collection); - method public void setMtu(int); - method public void setNat64Prefix(android.net.IpPrefix); - method public void setPcscfServers(java.util.Collection); + method public boolean isReachable(@NonNull java.net.InetAddress); + method public boolean removeDnsServer(@NonNull java.net.InetAddress); + method public boolean removeLinkAddress(@NonNull android.net.LinkAddress); + method public boolean removeRoute(@NonNull android.net.RouteInfo); + method public void setNat64Prefix(@Nullable android.net.IpPrefix); + method public void setPcscfServers(@NonNull java.util.Collection); method public void setPrivateDnsServerName(@Nullable String); - method public void setTcpBufferSizes(String); + method public void setTcpBufferSizes(@Nullable String); method public void setUsePrivateDns(boolean); - method public void setValidatedPrivateDnsServers(java.util.Collection); + method public void setValidatedPrivateDnsServers(@NonNull java.util.Collection); } public class Network implements android.os.Parcelable { - ctor public Network(android.net.Network); - method public android.net.Network getPrivateDnsBypassingCopy(); + ctor public Network(@NonNull android.net.Network); + method @NonNull public android.net.Network getPrivateDnsBypassingCopy(); } public final class NetworkCapabilities implements android.os.Parcelable { - method public int getSignalStrength(); - method public int[] getTransportTypes(); - method public boolean satisfiedByNetworkCapabilities(android.net.NetworkCapabilities); + method @NonNull public int[] getTransportTypes(); + method public boolean satisfiedByNetworkCapabilities(@Nullable android.net.NetworkCapabilities); field public static final int NET_CAPABILITY_OEM_PAID = 22; // 0x16 field public static final int NET_CAPABILITY_PARTIAL_CONNECTIVITY = 24; // 0x18 } @@ -4188,7 +4144,7 @@ package android.net { } public static class NetworkRequest.Builder { - method public android.net.NetworkRequest.Builder setSignalStrength(int); + method @NonNull public android.net.NetworkRequest.Builder setSignalStrength(int); } public class NetworkScoreManager { @@ -4212,7 +4168,7 @@ package android.net { } public final class RouteInfo implements android.os.Parcelable { - ctor public RouteInfo(android.net.IpPrefix, java.net.InetAddress, String, int); + ctor public RouteInfo(@Nullable android.net.IpPrefix, @Nullable java.net.InetAddress, @Nullable String, int); method public int getType(); field public static final int RTN_THROW = 9; // 0x9 field public static final int RTN_UNICAST = 1; // 0x1 @@ -4252,18 +4208,18 @@ package android.net { public final class StaticIpConfiguration implements android.os.Parcelable { ctor public StaticIpConfiguration(); - ctor public StaticIpConfiguration(android.net.StaticIpConfiguration); - method public void addDnsServer(java.net.InetAddress); + ctor public StaticIpConfiguration(@Nullable android.net.StaticIpConfiguration); + method public void addDnsServer(@NonNull java.net.InetAddress); method public void clear(); method public int describeContents(); - method public java.util.List getDnsServers(); - method public String getDomains(); - method public java.net.InetAddress getGateway(); - method public android.net.LinkAddress getIpAddress(); - method public java.util.List getRoutes(String); - method public void setDomains(String); - method public void setGateway(java.net.InetAddress); - method public void setIpAddress(android.net.LinkAddress); + method @NonNull public java.util.List getDnsServers(); + method @Nullable public String getDomains(); + method @Nullable public java.net.InetAddress getGateway(); + method @Nullable public android.net.LinkAddress getIpAddress(); + method @NonNull public java.util.List getRoutes(@Nullable String); + method public void setDomains(@Nullable String); + method public void setGateway(@Nullable java.net.InetAddress); + method public void setIpAddress(@Nullable android.net.LinkAddress); method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator CREATOR; } @@ -4301,8 +4257,8 @@ package android.net.apf { public final class ApfCapabilities implements android.os.Parcelable { ctor public ApfCapabilities(int, int, int); method public int describeContents(); - method public static boolean getApfDrop8023Frames(android.content.Context); - method public static int[] getApfEthTypeBlackList(android.content.Context); + method public static boolean getApfDrop8023Frames(@NonNull android.content.Context); + method @NonNull public static int[] getApfEthTypeBlackList(@NonNull android.content.Context); method public boolean hasDataAccess(); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator CREATOR; @@ -4317,28 +4273,28 @@ package android.net.captiveportal { public final class CaptivePortalProbeResult { ctor public CaptivePortalProbeResult(int); - ctor public CaptivePortalProbeResult(int, String, String); - ctor public CaptivePortalProbeResult(int, String, String, android.net.captiveportal.CaptivePortalProbeSpec); + ctor public CaptivePortalProbeResult(int, @Nullable String, @Nullable String); + ctor public CaptivePortalProbeResult(int, @Nullable String, @Nullable String, @Nullable android.net.captiveportal.CaptivePortalProbeSpec); method public boolean isFailed(); method public boolean isPartialConnectivity(); method public boolean isPortal(); method public boolean isSuccessful(); - field public static final android.net.captiveportal.CaptivePortalProbeResult FAILED; + field @NonNull public static final android.net.captiveportal.CaptivePortalProbeResult FAILED; field public static final int FAILED_CODE = 599; // 0x257 field public static final android.net.captiveportal.CaptivePortalProbeResult PARTIAL; field public static final int PORTAL_CODE = 302; // 0x12e - field public static final android.net.captiveportal.CaptivePortalProbeResult SUCCESS; + field @NonNull public static final android.net.captiveportal.CaptivePortalProbeResult SUCCESS; field public static final int SUCCESS_CODE = 204; // 0xcc - field public final String detectUrl; + field @Nullable public final String detectUrl; field @Nullable public final android.net.captiveportal.CaptivePortalProbeSpec probeSpec; - field public final String redirectUrl; + field @Nullable public final String redirectUrl; } public abstract class CaptivePortalProbeSpec { - method public String getEncodedSpec(); - method public abstract android.net.captiveportal.CaptivePortalProbeResult getResult(int, @Nullable String); - method public java.net.URL getUrl(); - method public static java.util.Collection parseCaptivePortalProbeSpecs(String); + method @NonNull public String getEncodedSpec(); + method @NonNull public abstract android.net.captiveportal.CaptivePortalProbeResult getResult(int, @Nullable String); + method @NonNull public java.net.URL getUrl(); + method @NonNull public static java.util.Collection parseCaptivePortalProbeSpecs(@NonNull String); method @Nullable public static android.net.captiveportal.CaptivePortalProbeSpec parseSpecOrNull(@Nullable String); } @@ -4349,78 +4305,78 @@ package android.net.metrics { public final class ApfProgramEvent implements android.net.metrics.IpConnectivityLog.Event { } - public static class ApfProgramEvent.Builder { + public static final class ApfProgramEvent.Builder { ctor public ApfProgramEvent.Builder(); - method public android.net.metrics.ApfProgramEvent build(); - method public android.net.metrics.ApfProgramEvent.Builder setActualLifetime(long); - method public android.net.metrics.ApfProgramEvent.Builder setCurrentRas(int); - method public android.net.metrics.ApfProgramEvent.Builder setFilteredRas(int); - method public android.net.metrics.ApfProgramEvent.Builder setFlags(boolean, boolean); - method public android.net.metrics.ApfProgramEvent.Builder setLifetime(long); - method public android.net.metrics.ApfProgramEvent.Builder setProgramLength(int); + method @NonNull public android.net.metrics.ApfProgramEvent build(); + method @NonNull public android.net.metrics.ApfProgramEvent.Builder setActualLifetime(long); + method @NonNull public android.net.metrics.ApfProgramEvent.Builder setCurrentRas(int); + method @NonNull public android.net.metrics.ApfProgramEvent.Builder setFilteredRas(int); + method @NonNull public android.net.metrics.ApfProgramEvent.Builder setFlags(boolean, boolean); + method @NonNull public android.net.metrics.ApfProgramEvent.Builder setLifetime(long); + method @NonNull public android.net.metrics.ApfProgramEvent.Builder setProgramLength(int); } public final class ApfStats implements android.net.metrics.IpConnectivityLog.Event { } - public static class ApfStats.Builder { + public static final class ApfStats.Builder { ctor public ApfStats.Builder(); - method public android.net.metrics.ApfStats build(); - method public android.net.metrics.ApfStats.Builder setDroppedRas(int); - method public android.net.metrics.ApfStats.Builder setDurationMs(long); - method public android.net.metrics.ApfStats.Builder setMatchingRas(int); - method public android.net.metrics.ApfStats.Builder setMaxProgramSize(int); - method public android.net.metrics.ApfStats.Builder setParseErrors(int); - method public android.net.metrics.ApfStats.Builder setProgramUpdates(int); - method public android.net.metrics.ApfStats.Builder setProgramUpdatesAll(int); - method public android.net.metrics.ApfStats.Builder setProgramUpdatesAllowingMulticast(int); - method public android.net.metrics.ApfStats.Builder setReceivedRas(int); - method public android.net.metrics.ApfStats.Builder setZeroLifetimeRas(int); + method @NonNull public android.net.metrics.ApfStats build(); + method @NonNull public android.net.metrics.ApfStats.Builder setDroppedRas(int); + method @NonNull public android.net.metrics.ApfStats.Builder setDurationMs(long); + method @NonNull public android.net.metrics.ApfStats.Builder setMatchingRas(int); + method @NonNull public android.net.metrics.ApfStats.Builder setMaxProgramSize(int); + method @NonNull public android.net.metrics.ApfStats.Builder setParseErrors(int); + method @NonNull public android.net.metrics.ApfStats.Builder setProgramUpdates(int); + method @NonNull public android.net.metrics.ApfStats.Builder setProgramUpdatesAll(int); + method @NonNull public android.net.metrics.ApfStats.Builder setProgramUpdatesAllowingMulticast(int); + method @NonNull public android.net.metrics.ApfStats.Builder setReceivedRas(int); + method @NonNull public android.net.metrics.ApfStats.Builder setZeroLifetimeRas(int); } public final class DhcpClientEvent implements android.net.metrics.IpConnectivityLog.Event { } - public static class DhcpClientEvent.Builder { + public static final class DhcpClientEvent.Builder { ctor public DhcpClientEvent.Builder(); - method public android.net.metrics.DhcpClientEvent build(); - method public android.net.metrics.DhcpClientEvent.Builder setDurationMs(int); - method public android.net.metrics.DhcpClientEvent.Builder setMsg(String); + method @NonNull public android.net.metrics.DhcpClientEvent build(); + method @NonNull public android.net.metrics.DhcpClientEvent.Builder setDurationMs(int); + method @NonNull public android.net.metrics.DhcpClientEvent.Builder setMsg(String); } public final class DhcpErrorEvent implements android.net.metrics.IpConnectivityLog.Event { ctor public DhcpErrorEvent(int); method public static int errorCodeWithOption(int, int); - field public static final int BOOTP_TOO_SHORT; - field public static final int BUFFER_UNDERFLOW; - field public static final int DHCP_BAD_MAGIC_COOKIE; + field public static final int BOOTP_TOO_SHORT = 67174400; // 0x4010000 + field public static final int BUFFER_UNDERFLOW = 83951616; // 0x5010000 + field public static final int DHCP_BAD_MAGIC_COOKIE = 67239936; // 0x4020000 field public static final int DHCP_ERROR = 4; // 0x4 - field public static final int DHCP_INVALID_OPTION_LENGTH; - field public static final int DHCP_NO_COOKIE; - field public static final int DHCP_NO_MSG_TYPE; - field public static final int DHCP_UNKNOWN_MSG_TYPE; + field public static final int DHCP_INVALID_OPTION_LENGTH = 67305472; // 0x4030000 + field public static final int DHCP_NO_COOKIE = 67502080; // 0x4060000 + field public static final int DHCP_NO_MSG_TYPE = 67371008; // 0x4040000 + field public static final int DHCP_UNKNOWN_MSG_TYPE = 67436544; // 0x4050000 field public static final int L2_ERROR = 1; // 0x1 - field public static final int L2_TOO_SHORT; - field public static final int L2_WRONG_ETH_TYPE; + field public static final int L2_TOO_SHORT = 16842752; // 0x1010000 + field public static final int L2_WRONG_ETH_TYPE = 16908288; // 0x1020000 field public static final int L3_ERROR = 2; // 0x2 - field public static final int L3_INVALID_IP; - field public static final int L3_NOT_IPV4; - field public static final int L3_TOO_SHORT; + field public static final int L3_INVALID_IP = 33751040; // 0x2030000 + field public static final int L3_NOT_IPV4 = 33685504; // 0x2020000 + field public static final int L3_TOO_SHORT = 33619968; // 0x2010000 field public static final int L4_ERROR = 3; // 0x3 - field public static final int L4_NOT_UDP; - field public static final int L4_WRONG_PORT; + field public static final int L4_NOT_UDP = 50397184; // 0x3010000 + field public static final int L4_WRONG_PORT = 50462720; // 0x3020000 field public static final int MISC_ERROR = 5; // 0x5 - field public static final int PARSING_ERROR; - field public static final int RECEIVE_ERROR; + field public static final int PARSING_ERROR = 84082688; // 0x5030000 + field public static final int RECEIVE_ERROR = 84017152; // 0x5020000 } public class IpConnectivityLog { ctor public IpConnectivityLog(); - method public boolean log(long, android.net.metrics.IpConnectivityLog.Event); - method public boolean log(String, android.net.metrics.IpConnectivityLog.Event); - method public boolean log(android.net.Network, int[], android.net.metrics.IpConnectivityLog.Event); - method public boolean log(int, int[], android.net.metrics.IpConnectivityLog.Event); - method public boolean log(android.net.metrics.IpConnectivityLog.Event); + method public boolean log(long, @NonNull android.net.metrics.IpConnectivityLog.Event); + method public boolean log(@NonNull String, @NonNull android.net.metrics.IpConnectivityLog.Event); + method public boolean log(@NonNull android.net.Network, @NonNull int[], @NonNull android.net.metrics.IpConnectivityLog.Event); + method public boolean log(int, @NonNull int[], @NonNull android.net.metrics.IpConnectivityLog.Event); + method public boolean log(@NonNull android.net.metrics.IpConnectivityLog.Event); } public static interface IpConnectivityLog.Event extends android.os.Parcelable { @@ -4468,19 +4424,19 @@ package android.net.metrics { public final class RaEvent implements android.net.metrics.IpConnectivityLog.Event { } - public static class RaEvent.Builder { + public static final class RaEvent.Builder { ctor public RaEvent.Builder(); - method public android.net.metrics.RaEvent build(); - method public android.net.metrics.RaEvent.Builder updateDnsslLifetime(long); - method public android.net.metrics.RaEvent.Builder updatePrefixPreferredLifetime(long); - method public android.net.metrics.RaEvent.Builder updatePrefixValidLifetime(long); - method public android.net.metrics.RaEvent.Builder updateRdnssLifetime(long); - method public android.net.metrics.RaEvent.Builder updateRouteInfoLifetime(long); - method public android.net.metrics.RaEvent.Builder updateRouterLifetime(long); + method @NonNull public android.net.metrics.RaEvent build(); + method @NonNull public android.net.metrics.RaEvent.Builder updateDnsslLifetime(long); + method @NonNull public android.net.metrics.RaEvent.Builder updatePrefixPreferredLifetime(long); + method @NonNull public android.net.metrics.RaEvent.Builder updatePrefixValidLifetime(long); + method @NonNull public android.net.metrics.RaEvent.Builder updateRdnssLifetime(long); + method @NonNull public android.net.metrics.RaEvent.Builder updateRouteInfoLifetime(long); + method @NonNull public android.net.metrics.RaEvent.Builder updateRouterLifetime(long); } public final class ValidationProbeEvent implements android.net.metrics.IpConnectivityLog.Event { - method public static String getProbeName(int); + method @NonNull public static String getProbeName(int); field public static final int DNS_FAILURE = 0; // 0x0 field public static final int DNS_SUCCESS = 1; // 0x1 field public static final int PROBE_DNS = 0; // 0x0 @@ -4491,12 +4447,12 @@ package android.net.metrics { field public static final int PROBE_PRIVDNS = 5; // 0x5 } - public static class ValidationProbeEvent.Builder { + public static final class ValidationProbeEvent.Builder { ctor public ValidationProbeEvent.Builder(); - method public android.net.metrics.ValidationProbeEvent build(); - method public android.net.metrics.ValidationProbeEvent.Builder setDurationMs(long); - method public android.net.metrics.ValidationProbeEvent.Builder setProbeType(int, boolean); - method public android.net.metrics.ValidationProbeEvent.Builder setReturnCode(int); + method @NonNull public android.net.metrics.ValidationProbeEvent build(); + method @NonNull public android.net.metrics.ValidationProbeEvent.Builder setDurationMs(long); + method @NonNull public android.net.metrics.ValidationProbeEvent.Builder setProbeType(int, boolean); + method @NonNull public android.net.metrics.ValidationProbeEvent.Builder setReturnCode(int); } } @@ -4956,7 +4912,6 @@ package android.net.wifi { method public int getCellularDataNetworkType(); method public int getCellularSignalStrengthDb(); method public int getCellularSignalStrengthDbm(); - method public boolean getIsSameRegisteredCell(); method public int getLinkSpeedMbps(); method public int getProbeElapsedTimeSinceLastUpdateMillis(); method public int getProbeMcsRateSinceLastUpdate(); @@ -4980,6 +4935,7 @@ package android.net.wifi { method public long getTotalTxBad(); method public long getTotalTxRetries(); method public long getTotalTxSuccess(); + method public boolean isSameRegisteredCell(); method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator CREATOR; field public static final int PROBE_STATUS_FAILURE = 3; // 0x3 @@ -5469,14 +5425,14 @@ package android.os { public final class PowerManager { method @RequiresPermission(allOf={android.Manifest.permission.READ_DREAM_STATE, android.Manifest.permission.WRITE_DREAM_STATE}) public void dream(long); method @RequiresPermission(android.Manifest.permission.DEVICE_POWER) public boolean forceSuspend(); - method @RequiresPermission(android.Manifest.permission.POWER_SAVER) public int getPowerSaveMode(); + method @RequiresPermission(android.Manifest.permission.POWER_SAVER) public int getPowerSaveModeTrigger(); method @RequiresPermission(anyOf={android.Manifest.permission.DEVICE_POWER, android.Manifest.permission.POWER_SAVER}) public boolean setAdaptivePowerSaveEnabled(boolean); method @RequiresPermission(anyOf={android.Manifest.permission.DEVICE_POWER, android.Manifest.permission.POWER_SAVER}) public boolean setAdaptivePowerSavePolicy(@NonNull android.os.BatterySaverPolicyConfig); - method @RequiresPermission(android.Manifest.permission.POWER_SAVER) public boolean setDynamicPowerSavings(boolean, int); + method @RequiresPermission(android.Manifest.permission.POWER_SAVER) public boolean setDynamicPowerSaveHint(boolean, int); method @RequiresPermission(anyOf={android.Manifest.permission.DEVICE_POWER, android.Manifest.permission.POWER_SAVER}) public boolean setPowerSaveModeEnabled(boolean); method @RequiresPermission(anyOf={android.Manifest.permission.DEVICE_POWER, android.Manifest.permission.USER_ACTIVITY}) public void userActivity(long, int, int); - field public static final int POWER_SAVER_MODE_DYNAMIC = 1; // 0x1 - field public static final int POWER_SAVER_MODE_PERCENTAGE = 0; // 0x0 + field public static final int POWER_SAVE_MODE_TRIGGER_DYNAMIC = 1; // 0x1 + field public static final int POWER_SAVE_MODE_TRIGGER_PERCENTAGE = 0; // 0x0 field public static final int USER_ACTIVITY_EVENT_ACCESSIBILITY = 3; // 0x3 field public static final int USER_ACTIVITY_EVENT_BUTTON = 1; // 0x1 field public static final int USER_ACTIVITY_EVENT_OTHER = 0; // 0x0 @@ -5509,7 +5465,7 @@ package android.os { } public class ServiceSpecificException extends java.lang.RuntimeException { - ctor public ServiceSpecificException(int, String); + ctor public ServiceSpecificException(int, @Nullable String); ctor public ServiceSpecificException(int); field public final int errorCode; } @@ -5683,6 +5639,36 @@ package android.os { } +package android.os.image { + + public class DynamicSystemClient { + ctor public DynamicSystemClient(@NonNull android.content.Context); + method @RequiresPermission("android.permission.MANAGE_DYNAMIC_SYSTEM") public void bind(); + method public void setOnStatusChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.os.image.DynamicSystemClient.OnStatusChangedListener); + method public void setOnStatusChangedListener(@NonNull android.os.image.DynamicSystemClient.OnStatusChangedListener); + method @RequiresPermission("android.permission.MANAGE_DYNAMIC_SYSTEM") public void start(@NonNull String, long); + method @RequiresPermission("android.permission.MANAGE_DYNAMIC_SYSTEM") public void start(@NonNull String, long, long); + method @RequiresPermission("android.permission.MANAGE_DYNAMIC_SYSTEM") public void unbind(); + field public static final int CAUSE_ERROR_EXCEPTION = 6; // 0x6 + field public static final int CAUSE_ERROR_INVALID_URL = 4; // 0x4 + field public static final int CAUSE_ERROR_IO = 3; // 0x3 + field public static final int CAUSE_ERROR_IPC = 5; // 0x5 + field public static final int CAUSE_INSTALL_CANCELLED = 2; // 0x2 + field public static final int CAUSE_INSTALL_COMPLETED = 1; // 0x1 + field public static final int CAUSE_NOT_SPECIFIED = 0; // 0x0 + field public static final int STATUS_IN_PROGRESS = 2; // 0x2 + field public static final int STATUS_IN_USE = 4; // 0x4 + field public static final int STATUS_NOT_STARTED = 1; // 0x1 + field public static final int STATUS_READY = 3; // 0x3 + field public static final int STATUS_UNKNOWN = 0; // 0x0 + } + + public static interface DynamicSystemClient.OnStatusChangedListener { + method public void onStatusChanged(int, int, long); + } + +} + package android.os.storage { public class StorageManager { @@ -5747,10 +5733,10 @@ package android.permission { } public final class RuntimePermissionUsageInfo implements android.os.Parcelable { - ctor public RuntimePermissionUsageInfo(@NonNull CharSequence, int); + ctor public RuntimePermissionUsageInfo(@NonNull String, int); method public int describeContents(); method public int getAppAccessCount(); - method @NonNull public CharSequence getName(); + method @NonNull public String getName(); method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator CREATOR; } @@ -5903,6 +5889,7 @@ package android.provider { field public static final String NAMESPACE_SCHEDULER = "scheduler"; field public static final String NAMESPACE_STORAGE = "storage"; field public static final String NAMESPACE_SYSTEMUI = "systemui"; + field public static final String NAMESPACE_TELEPHONY = "telephony"; field public static final String NAMESPACE_TEXTCLASSIFIER = "textclassifier"; } @@ -5930,13 +5917,6 @@ package android.provider { method @Nullable public String getString(@NonNull String, @Nullable String); } - public static interface DeviceConfig.Telephony { - field public static final String NAMESPACE = "telephony"; - field public static final String RAMPING_RINGER_DURATION = "ramping_ringer_duration"; - field public static final String RAMPING_RINGER_ENABLED = "ramping_ringer_enabled"; - field public static final String RAMPING_RINGER_VIBRATION_DURATION = "ramping_ringer_vibration_duration"; - } - public final class DocumentsContract { method public static boolean isManageMode(@NonNull android.net.Uri); method @NonNull public static android.net.Uri setManageMode(@NonNull android.net.Uri); @@ -6068,6 +6048,7 @@ package android.provider { field public static final String ACTION_ENTERPRISE_PRIVACY_SETTINGS = "android.settings.ENTERPRISE_PRIVACY_SETTINGS"; field public static final String ACTION_LOCATION_CONTROLLER_EXTRA_PACKAGE_SETTINGS = "android.settings.LOCATION_CONTROLLER_EXTRA_PACKAGE_SETTINGS"; field public static final String ACTION_MANAGE_DOMAIN_URLS = "android.settings.MANAGE_DOMAIN_URLS"; + field public static final String ACTION_NOTIFICATION_POLICY_ACCESS_DETAIL_SETTINGS = "android.settings.NOTIFICATION_POLICY_ACCESS_DETAIL_SETTINGS"; field public static final String ACTION_REQUEST_ENABLE_CONTENT_CAPTURE = "android.settings.REQUEST_ENABLE_CONTENT_CAPTURE"; field public static final String ACTION_SHOW_ADMIN_SUPPORT_DETAILS = "android.settings.SHOW_ADMIN_SUPPORT_DETAILS"; } @@ -6132,6 +6113,7 @@ package android.provider { field public static final String LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS = "lock_screen_allow_private_notifications"; field public static final String LOCK_SCREEN_SHOW_NOTIFICATIONS = "lock_screen_show_notifications"; field public static final String ODI_CAPTIONS_ENABLED = "odi_captions_enabled"; + field public static final String ODI_CAPTIONS_OPTED_OUT = "odi_captions_opted_out"; field public static final String THEME_CUSTOMIZATION_OVERLAY_PACKAGES = "theme_customization_overlay_packages"; field public static final String USER_SETUP_COMPLETE = "user_setup_complete"; field public static final int USER_SETUP_PERSONALIZATION_COMPLETE = 10; // 0xa @@ -6324,7 +6306,7 @@ package android.service.appprediction { method @NonNull public final android.os.IBinder onBind(@NonNull android.content.Intent); method public void onCreatePredictionSession(@NonNull android.app.prediction.AppPredictionContext, @NonNull android.app.prediction.AppPredictionSessionId); method @MainThread public void onDestroyPredictionSession(@NonNull android.app.prediction.AppPredictionSessionId); - method @MainThread public abstract void onLocationShown(@NonNull android.app.prediction.AppPredictionSessionId, @NonNull String, @NonNull java.util.List); + method @MainThread public abstract void onLaunchLocationShown(@NonNull android.app.prediction.AppPredictionSessionId, @NonNull String, @NonNull java.util.List); method @MainThread public abstract void onRequestPredictionUpdate(@NonNull android.app.prediction.AppPredictionSessionId); method @MainThread public abstract void onSortAppTargets(@NonNull android.app.prediction.AppPredictionSessionId, @NonNull java.util.List, @NonNull android.os.CancellationSignal, @NonNull java.util.function.Consumer>); method @MainThread public void onStartPredictionUpdates(); @@ -6338,20 +6320,23 @@ package android.service.attention { public abstract class AttentionService extends android.app.Service { ctor public AttentionService(); + method public final void disableSelf(); method @Nullable public final android.os.IBinder onBind(@NonNull android.content.Intent); - method public abstract void onCancelAttentionCheck(int); - method public abstract void onCheckAttention(int, @NonNull android.service.attention.AttentionService.AttentionCallback); - field public static final int ATTENTION_FAILURE_PREEMPTED = 2; // 0x2 - field public static final int ATTENTION_FAILURE_TIMED_OUT = 3; // 0x3 - field public static final int ATTENTION_FAILURE_UNKNOWN = 4; // 0x4 + method public abstract void onCancelAttentionCheck(@NonNull android.service.attention.AttentionService.AttentionCallback); + method public abstract void onCheckAttention(@NonNull android.service.attention.AttentionService.AttentionCallback); + field public static final int ATTENTION_FAILURE_CAMERA_PERMISSION_ABSENT = 6; // 0x6 + field public static final int ATTENTION_FAILURE_CANCELLED = 3; // 0x3 + field public static final int ATTENTION_FAILURE_PREEMPTED = 4; // 0x4 + field public static final int ATTENTION_FAILURE_TIMED_OUT = 5; // 0x5 + field public static final int ATTENTION_FAILURE_UNKNOWN = 2; // 0x2 field public static final int ATTENTION_SUCCESS_ABSENT = 0; // 0x0 field public static final int ATTENTION_SUCCESS_PRESENT = 1; // 0x1 field public static final String SERVICE_INTERFACE = "android.service.attention.AttentionService"; } public static final class AttentionService.AttentionCallback { - method public void onFailure(int, int); - method public void onSuccess(int, int, long); + method public void onFailure(int); + method public void onSuccess(int, long); } } @@ -6450,7 +6435,7 @@ package android.service.contentcapture { public abstract class ContentCaptureService extends android.app.Service { ctor public ContentCaptureService(); - method public final void disableContentCaptureServices(); + method public final void disableSelf(); method public void onActivityEvent(@NonNull android.service.contentcapture.ActivityEvent); method public void onActivitySnapshot(@NonNull android.view.contentcapture.ContentCaptureSessionId, @NonNull android.service.contentcapture.SnapshotData); method public void onConnected(); @@ -6662,6 +6647,7 @@ package android.service.notification { method public final void adjustNotifications(@NonNull java.util.List); method public void onActionInvoked(@NonNull String, @NonNull android.app.Notification.Action, int); method @NonNull public final android.os.IBinder onBind(@Nullable android.content.Intent); + method public void onCapabilitiesChanged(); method public void onNotificationDirectReplied(@NonNull String); method @Nullable public abstract android.service.notification.Adjustment onNotificationEnqueued(@NonNull android.service.notification.StatusBarNotification); method @Nullable public android.service.notification.Adjustment onNotificationEnqueued(@NonNull android.service.notification.StatusBarNotification, @NonNull android.app.NotificationChannel); @@ -6909,6 +6895,22 @@ package android.service.wallpaper { } +package android.service.watchdog { + + public abstract class ExplicitHealthCheckService extends android.app.Service { + ctor public ExplicitHealthCheckService(); + method public final void notifyHealthCheckPassed(@NonNull String); + method @NonNull public final android.os.IBinder onBind(@NonNull android.content.Intent); + method public abstract void onCancelHealthCheck(@NonNull String); + method @NonNull public abstract java.util.List onGetRequestedPackages(); + method @NonNull public abstract java.util.List onGetSupportedPackages(); + method public abstract void onRequestHealthCheck(@NonNull String); + field public static final String BIND_PERMISSION = "android.permission.BIND_EXPLICIT_HEALTH_CHECK_SERVICE"; + field public static final String SERVICE_INTERFACE = "android.service.watchdog.ExplicitHealthCheckService"; + } + +} + package android.telecom { @Deprecated public class AudioState implements android.os.Parcelable { @@ -7589,11 +7591,11 @@ package android.telephony { field public static final int VSNCP_TIMEOUT = 2236; // 0x8bc } - public final class DataSpecificRegistrationStates implements android.os.Parcelable { + public final class DataSpecificRegistrationInfo implements android.os.Parcelable { method public int describeContents(); method @NonNull public android.telephony.LteVopsSupportInfo getLteVopsSupportInfo(); method public void writeToParcel(android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator CREATOR; + field @NonNull public static final android.os.Parcelable.Creator CREATOR; } public final class DisconnectCause { @@ -7702,7 +7704,7 @@ package android.telephony { method public int getAccessNetworkTechnology(); method @NonNull public java.util.List getAvailableServices(); method @Nullable public android.telephony.CellIdentity getCellIdentity(); - method @Nullable public android.telephony.DataSpecificRegistrationStates getDataSpecificStates(); + method @Nullable public android.telephony.DataSpecificRegistrationInfo getDataSpecificInfo(); method public int getDomain(); method public int getRegistrationState(); method public int getRejectCause(); @@ -7745,19 +7747,19 @@ package android.telephony { ctor public NetworkService(); method public android.os.IBinder onBind(android.content.Intent); method @Nullable public abstract android.telephony.NetworkService.NetworkServiceProvider onCreateNetworkServiceProvider(int); - field public static final String NETWORK_SERVICE_INTERFACE = "android.telephony.NetworkService"; + field public static final String SERVICE_INTERFACE = "android.telephony.NetworkService"; } public abstract class NetworkService.NetworkServiceProvider implements java.lang.AutoCloseable { ctor public NetworkService.NetworkServiceProvider(int); method public abstract void close(); - method public void getNetworkRegistrationInfo(int, @NonNull android.telephony.NetworkServiceCallback); method public final int getSlotIndex(); method public final void notifyNetworkRegistrationInfoChanged(); + method public void requestNetworkRegistrationInfo(int, @NonNull android.telephony.NetworkServiceCallback); } public class NetworkServiceCallback { - method public void onGetNetworkRegistrationInfoComplete(int, @Nullable android.telephony.NetworkRegistrationInfo); + method public void onRequestNetworkRegistrationInfoComplete(int, @Nullable android.telephony.NetworkRegistrationInfo); field public static final int RESULT_ERROR_BUSY = 3; // 0x3 field public static final int RESULT_ERROR_FAILED = 5; // 0x5 field public static final int RESULT_ERROR_ILLEGAL_STATE = 4; // 0x4 @@ -8059,11 +8061,12 @@ package android.telephony { method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getVoiceActivationState(); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean handlePinMmi(String); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean handlePinMmiForSubscriber(int, String); - method @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean iccCloseLogicalChannelBySlot(int, int); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean iccCloseLogicalChannelBySlot(int, int); method @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public android.telephony.IccOpenLogicalChannelResponse iccOpenLogicalChannelBySlot(int, @Nullable String, int); method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String iccTransmitApduBasicChannelBySlot(int, int, int, int, int, int, @Nullable String); method @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String iccTransmitApduLogicalChannelBySlot(int, int, int, int, int, int, int, @Nullable String); method public boolean isDataConnectivityPossible(); + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isEmergencyAssistanceEnabled(); method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isIdle(); method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isOffhook(); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isPotentialEmergencyNumber(@NonNull String); @@ -8083,7 +8086,7 @@ package android.telephony { method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataActivationState(int); method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataEnabled(int, boolean); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataRoamingEnabled(boolean); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setMultisimCarrierRestriction(boolean); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setMultiSimCarrierRestriction(boolean); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setPreferredNetworkTypeBitmask(long); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setRadio(boolean); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setRadioPower(boolean); @@ -8190,39 +8193,55 @@ package android.telephony { package android.telephony.data { public final class DataCallResponse implements android.os.Parcelable { - ctor public DataCallResponse(int, int, int, int, int, @Nullable String, @Nullable java.util.List, @Nullable java.util.List, @Nullable java.util.List, @Nullable java.util.List, int); method public int describeContents(); - method public int getActive(); method @NonNull public java.util.List getAddresses(); - method public int getCallId(); - method @NonNull public java.util.List getDnses(); - method @NonNull public java.util.List getGateways(); - method @NonNull public String getIfname(); + method public int getCause(); + method @NonNull public java.util.List getDnsAddresses(); + method @NonNull public java.util.List getGatewayAddresses(); + method public int getId(); + method @NonNull public String getInterfaceName(); + method public int getLinkStatus(); method public int getMtu(); - method @NonNull public java.util.List getPcscfs(); + method @NonNull public java.util.List getPcscfAddresses(); method public int getProtocolType(); - method public int getStatus(); method public int getSuggestedRetryTime(); method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator CREATOR; + field public static final int LINK_STATUS_ACTIVE = 2; // 0x2 + field public static final int LINK_STATUS_DORMANT = 1; // 0x1 + field public static final int LINK_STATUS_INACTIVE = 0; // 0x0 + field public static final int LINK_STATUS_UNKNOWN = -1; // 0xffffffff + } + + public static final class DataCallResponse.Builder { + ctor public DataCallResponse.Builder(); + method @NonNull public android.telephony.data.DataCallResponse build(); + method @NonNull public android.telephony.data.DataCallResponse.Builder setAddresses(@NonNull java.util.List); + method @NonNull public android.telephony.data.DataCallResponse.Builder setCause(int); + method @NonNull public android.telephony.data.DataCallResponse.Builder setDnsAddresses(@NonNull java.util.List); + method @NonNull public android.telephony.data.DataCallResponse.Builder setGatewayAddresses(@NonNull java.util.List); + method @NonNull public android.telephony.data.DataCallResponse.Builder setId(int); + method @NonNull public android.telephony.data.DataCallResponse.Builder setInterfaceName(@NonNull String); + method @NonNull public android.telephony.data.DataCallResponse.Builder setLinkStatus(int); + method @NonNull public android.telephony.data.DataCallResponse.Builder setMtu(int); + method @NonNull public android.telephony.data.DataCallResponse.Builder setPcscfAddresses(@NonNull java.util.List); + method @NonNull public android.telephony.data.DataCallResponse.Builder setProtocolType(int); + method @NonNull public android.telephony.data.DataCallResponse.Builder setSuggestedRetryTime(int); } public final class DataProfile implements android.os.Parcelable { method public int describeContents(); method @NonNull public String getApn(); method public int getAuthType(); - method public int getBearerBitmap(); - method public int getMaxConns(); - method public int getMaxConnsTime(); + method public int getBearerBitmask(); method public int getMtu(); method @Nullable public String getPassword(); method public int getProfileId(); - method public int getProtocol(); - method public int getRoamingProtocol(); - method public int getSupportedApnTypesBitmap(); + method public int getProtocolType(); + method public int getRoamingProtocolType(); + method public int getSupportedApnTypesBitmask(); method public int getType(); method @Nullable public String getUserName(); - method public int getWaitTime(); method public boolean isEnabled(); method public boolean isPersistent(); method public boolean isPreferred(); @@ -8233,32 +8252,52 @@ package android.telephony.data { field public static final int TYPE_COMMON = 0; // 0x0 } + public static final class DataProfile.Builder { + ctor public DataProfile.Builder(); + method @NonNull public android.telephony.data.DataProfile build(); + method @NonNull public android.telephony.data.DataProfile.Builder enable(boolean); + method @NonNull public android.telephony.data.DataProfile.Builder setApn(@NonNull String); + method @NonNull public android.telephony.data.DataProfile.Builder setAuthType(int); + method @NonNull public android.telephony.data.DataProfile.Builder setBearerBitmask(int); + method @NonNull public android.telephony.data.DataProfile.Builder setMtu(int); + method @NonNull public android.telephony.data.DataProfile.Builder setPassword(@NonNull String); + method @NonNull public android.telephony.data.DataProfile.Builder setPersistent(boolean); + method @NonNull public android.telephony.data.DataProfile.Builder setPreferred(boolean); + method @NonNull public android.telephony.data.DataProfile.Builder setProfileId(int); + method @NonNull public android.telephony.data.DataProfile.Builder setProtocolType(int); + method @NonNull public android.telephony.data.DataProfile.Builder setRoamingProtocolType(int); + method @NonNull public android.telephony.data.DataProfile.Builder setSupportedApnTypesBitmask(int); + method @NonNull public android.telephony.data.DataProfile.Builder setType(int); + method @NonNull public android.telephony.data.DataProfile.Builder setUserName(@NonNull String); + } + public abstract class DataService extends android.app.Service { ctor public DataService(); method public android.os.IBinder onBind(android.content.Intent); method @Nullable public abstract android.telephony.data.DataService.DataServiceProvider onCreateDataServiceProvider(int); - field public static final String DATA_SERVICE_INTERFACE = "android.telephony.data.DataService"; field public static final int REQUEST_REASON_HANDOVER = 3; // 0x3 field public static final int REQUEST_REASON_NORMAL = 1; // 0x1 field public static final int REQUEST_REASON_SHUTDOWN = 2; // 0x2 + field public static final int REQUEST_REASON_UNKNOWN = 0; // 0x0 + field public static final String SERVICE_INTERFACE = "android.telephony.data.DataService"; } public abstract class DataService.DataServiceProvider implements java.lang.AutoCloseable { ctor public DataService.DataServiceProvider(int); method public abstract void close(); method public void deactivateDataCall(int, int, @Nullable android.telephony.data.DataServiceCallback); - method public void getDataCallList(@NonNull android.telephony.data.DataServiceCallback); method public final int getSlotIndex(); method public final void notifyDataCallListChanged(java.util.List); - method public void setDataProfile(@NonNull java.util.List, boolean, @Nullable android.telephony.data.DataServiceCallback); - method public void setInitialAttachApn(@NonNull android.telephony.data.DataProfile, boolean, @Nullable android.telephony.data.DataServiceCallback); - method public void setupDataCall(int, @NonNull android.telephony.data.DataProfile, boolean, boolean, int, @Nullable android.net.LinkProperties, @Nullable android.telephony.data.DataServiceCallback); + method public void requestDataCallList(@NonNull android.telephony.data.DataServiceCallback); + method public void setDataProfile(@NonNull java.util.List, boolean, @NonNull android.telephony.data.DataServiceCallback); + method public void setInitialAttachApn(@NonNull android.telephony.data.DataProfile, boolean, @NonNull android.telephony.data.DataServiceCallback); + method public void setupDataCall(int, @NonNull android.telephony.data.DataProfile, boolean, boolean, int, @Nullable android.net.LinkProperties, @NonNull android.telephony.data.DataServiceCallback); } public class DataServiceCallback { method public void onDataCallListChanged(@NonNull java.util.List); method public void onDeactivateDataCallComplete(int); - method public void onGetDataCallListComplete(int, @NonNull java.util.List); + method public void onRequestDataCallListComplete(int, @NonNull java.util.List); method public void onSetDataProfileComplete(int); method public void onSetInitialAttachApnComplete(int); method public void onSetupDataCallComplete(int, @Nullable android.telephony.data.DataCallResponse); @@ -8271,15 +8310,15 @@ package android.telephony.data { public abstract class QualifiedNetworksService extends android.app.Service { ctor public QualifiedNetworksService(); - method @NonNull public abstract android.telephony.data.QualifiedNetworksService.NetworkAvailabilityUpdater createNetworkAvailabilityUpdater(int); + method @NonNull public abstract android.telephony.data.QualifiedNetworksService.NetworkAvailabilityProvider onCreateNetworkAvailabilityProvider(int); field public static final String QUALIFIED_NETWORKS_SERVICE_INTERFACE = "android.telephony.data.QualifiedNetworksService"; } - public abstract class QualifiedNetworksService.NetworkAvailabilityUpdater implements java.lang.AutoCloseable { - ctor public QualifiedNetworksService.NetworkAvailabilityUpdater(int); + public abstract class QualifiedNetworksService.NetworkAvailabilityProvider implements java.lang.AutoCloseable { + ctor public QualifiedNetworksService.NetworkAvailabilityProvider(int); method public abstract void close(); method public final int getSlotIndex(); - method public final void updateQualifiedNetworkTypes(int, @Nullable int[]); + method public final void updateQualifiedNetworkTypes(int, @NonNull java.util.List); } } @@ -8371,6 +8410,7 @@ package android.telephony.euicc { field public static final String EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTIONS = "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTIONS"; field public static final String EXTRA_ENABLE_SUBSCRIPTION = "android.telephony.euicc.extra.ENABLE_SUBSCRIPTION"; field public static final String EXTRA_FORCE_PROVISION = "android.telephony.euicc.extra.FORCE_PROVISION"; + field public static final String EXTRA_FROM_SUBSCRIPTION_ID = "android.telephony.euicc.extra.FROM_SUBSCRIPTION_ID"; field public static final String EXTRA_SUBSCRIPTION_ID = "android.telephony.euicc.extra.SUBSCRIPTION_ID"; field public static final String EXTRA_SUBSCRIPTION_NICKNAME = "android.telephony.euicc.extra.SUBSCRIPTION_NICKNAME"; } @@ -9121,8 +9161,8 @@ package android.telephony.ims.feature { field public static final int STATE_UNAVAILABLE = 0; // 0x0 } - public static class ImsFeature.Capabilities { - field protected int mCapabilities; + @Deprecated public static class ImsFeature.Capabilities { + field @Deprecated protected int mCapabilities; } protected static class ImsFeature.CapabilityCallbackProxy { @@ -9471,6 +9511,10 @@ package android.util { method public int getUid(); } + public final class StatsLog { + method public static void writeRaw(@NonNull byte[], int); + } + public class StatsLogAtoms { field public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED = 170; // 0xaa field public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__AUTO_DENIED = 8; // 0x8 diff --git a/api/system-removed.txt b/api/system-removed.txt index 7e044698c72c5d484d2ac55be76c869050f791a5..9780d43624fa77a4a9ef5f49a85f4387efbf6b78 100644 --- a/api/system-removed.txt +++ b/api/system-removed.txt @@ -141,3 +141,11 @@ package android.telephony { } +package android.telephony.data { + + public final class DataCallResponse implements android.os.Parcelable { + ctor public DataCallResponse(int, int, int, int, int, @Nullable String, @Nullable java.util.List, @Nullable java.util.List, @Nullable java.util.List, @Nullable java.util.List, int); + } + +} + diff --git a/api/test-current.txt b/api/test-current.txt index 3322943256aa99a9a2ea2d80e4bbc220740159e8..9817a9747ff764071bd1850932270c72259bb0d5 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -352,6 +352,10 @@ package android.app { method public boolean isUiModeLocked(); } + public class WallpaperManager { + method @RequiresPermission("android.permission.SET_WALLPAPER_COMPONENT") public boolean setWallpaperComponent(android.content.ComponentName); + } + public class WindowConfiguration implements java.lang.Comparable android.os.Parcelable { ctor public WindowConfiguration(); method public int compareTo(android.app.WindowConfiguration); @@ -420,7 +424,8 @@ package android.app.backup { public class BackupManager { method @RequiresPermission("android.permission.BACKUP") public android.content.Intent getConfigurationIntent(String); method @RequiresPermission("android.permission.BACKUP") public android.content.Intent getDataManagementIntent(String); - method @RequiresPermission("android.permission.BACKUP") public String getDataManagementLabel(String); + method @Nullable @RequiresPermission("android.permission.BACKUP") public CharSequence getDataManagementIntentLabel(@NonNull String); + method @Deprecated @Nullable @RequiresPermission("android.permission.BACKUP") public String getDataManagementLabel(@NonNull String); method @RequiresPermission("android.permission.BACKUP") public String getDestinationString(String); } @@ -460,7 +465,7 @@ package android.app.prediction { method public void destroy(); method public android.app.prediction.AppPredictionSessionId getSessionId(); method public void notifyAppTargetEvent(@NonNull android.app.prediction.AppTargetEvent); - method public void notifyLocationShown(@NonNull String, @NonNull java.util.List); + method public void notifyLaunchLocationShown(@NonNull String, @NonNull java.util.List); method public void registerPredictionUpdates(@NonNull java.util.concurrent.Executor, @NonNull android.app.prediction.AppPredictor.Callback); method public void requestPredictionUpdate(); method @Nullable public void sortTargets(@NonNull java.util.List, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer>); @@ -472,7 +477,6 @@ package android.app.prediction { } public final class AppTarget implements android.os.Parcelable { - ctor public AppTarget(@NonNull android.app.prediction.AppTargetId, @NonNull String, @Nullable String, @NonNull android.os.UserHandle); method public int describeContents(); method @Nullable public String getClassName(); method @NonNull public android.app.prediction.AppTargetId getId(); @@ -484,6 +488,15 @@ package android.app.prediction { field @NonNull public static final android.os.Parcelable.Creator CREATOR; } + public static final class AppTarget.Builder { + ctor public AppTarget.Builder(@NonNull android.app.prediction.AppTargetId); + method @NonNull public android.app.prediction.AppTarget build(); + method @NonNull public android.app.prediction.AppTarget.Builder setClassName(@NonNull String); + method @NonNull public android.app.prediction.AppTarget.Builder setRank(@IntRange(from=0) int); + method @NonNull public android.app.prediction.AppTarget.Builder setTarget(@NonNull String, @NonNull android.os.UserHandle); + method @NonNull public android.app.prediction.AppTarget.Builder setTarget(@NonNull android.content.pm.ShortcutInfo); + } + public final class AppTargetEvent implements android.os.Parcelable { method public int describeContents(); method public int getAction(); @@ -575,12 +588,14 @@ package android.content { } public final class ContentCaptureOptions implements android.os.Parcelable { + ctor public ContentCaptureOptions(int); ctor public ContentCaptureOptions(int, int, int, int, int, @Nullable android.util.ArraySet); method public int describeContents(); method public static android.content.ContentCaptureOptions forWhitelistingItself(); method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator CREATOR; field public final int idleFlushingFrequencyMs; + field public final boolean lite; field public final int logHistorySize; field public final int loggingLevel; field public final int maxBufferSize; @@ -599,6 +614,7 @@ package android.content { public abstract class Context { method public android.content.Context createPackageContextAsUser(String, int, android.os.UserHandle) throws android.content.pm.PackageManager.NameNotFoundException; method public abstract android.view.Display getDisplay(); + method public abstract int getDisplayId(); method public android.os.UserHandle getUser(); method public int getUserId(); method public void setAutofillOptions(@Nullable android.content.AutofillOptions); @@ -609,6 +625,7 @@ package android.content { public class ContextWrapper extends android.content.Context { method public android.view.Display getDisplay(); + method public int getDisplayId(); } public class Intent implements java.lang.Cloneable android.os.Parcelable { @@ -918,19 +935,23 @@ package android.location { method public void resetBiasUncertaintyNanos(); method public void resetDriftNanosPerSecond(); method public void resetDriftUncertaintyNanosPerSecond(); + method public void resetElapsedRealtimeNanos(); + method public void resetElapsedRealtimeUncertaintyNanos(); method public void resetFullBiasNanos(); method public void resetLeapSecond(); method public void resetTimeUncertaintyNanos(); method public void set(android.location.GnssClock); method public void setBiasNanos(double); - method public void setBiasUncertaintyNanos(double); + method public void setBiasUncertaintyNanos(@FloatRange(from=0.0f) double); method public void setDriftNanosPerSecond(double); - method public void setDriftUncertaintyNanosPerSecond(double); + method public void setDriftUncertaintyNanosPerSecond(@FloatRange(from=0.0f) double); + method public void setElapsedRealtimeNanos(long); + method public void setElapsedRealtimeUncertaintyNanos(@IntRange(from=0) long); method public void setFullBiasNanos(long); method public void setHardwareClockDiscontinuityCount(int); method public void setLeapSecond(int); method public void setTimeNanos(long); - method public void setTimeUncertaintyNanos(double); + method public void setTimeUncertaintyNanos(@FloatRange(from=0.0f) double); } public final class GnssMeasurement implements android.os.Parcelable { @@ -1077,6 +1098,21 @@ package android.media { method public android.media.BufferingParams.Builder setResumePlaybackMarkMs(int); } + public class FileDataSourceDesc extends android.media.DataSourceDesc { + method public long getLength(); + method public long getOffset(); + method @NonNull public android.os.ParcelFileDescriptor getParcelFileDescriptor(); + field public static final long FD_LENGTH_UNKNOWN = 576460752303423487L; // 0x7ffffffffffffffL + } + + public static final class MediaCodecInfo.VideoCapabilities.PerformancePoint { + ctor public MediaCodecInfo.VideoCapabilities.PerformancePoint(int, int, int, int, @NonNull android.util.Size); + ctor public MediaCodecInfo.VideoCapabilities.PerformancePoint(@NonNull android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint, @NonNull android.util.Size); + method public int getMaxFrameRate(); + method public long getMaxMacroBlockRate(); + method public int getMaxMacroBlocks(); + } + public class MediaPlayer2 implements android.media.AudioRouting java.lang.AutoCloseable { method public android.media.MediaPlayer2.DrmInfo getDrmInfo(@NonNull android.media.DataSourceDesc); method public android.media.MediaDrm.KeyRequest getDrmKeyRequest(@NonNull android.media.DataSourceDesc, @Nullable byte[], @Nullable byte[], @Nullable String, int, @Nullable java.util.Map) throws android.media.MediaPlayer2.NoDrmSchemeException; @@ -1093,6 +1129,12 @@ package android.media { method public android.media.PlaybackParams setAudioStretchMode(int); } + public class UriDataSourceDesc extends android.media.DataSourceDesc { + method @Nullable public java.util.List getCookies(); + method @Nullable public java.util.Map getHeaders(); + method @NonNull public android.net.Uri getUri(); + } + public static final class VolumeShaper.Configuration.Builder { method @NonNull public android.media.VolumeShaper.Configuration.Builder setOptionFlags(int); } @@ -1181,8 +1223,7 @@ package android.metrics { package android.net { public class CaptivePortal implements android.os.Parcelable { - ctor public CaptivePortal(android.os.IBinder); - method public void logEvent(int, String); + method public void logEvent(int, @NonNull String); method public void useNetwork(); field public static final int APP_RETURN_DISMISSED = 0; // 0x0 field public static final int APP_RETURN_UNWANTED = 1; // 0x1 @@ -1190,14 +1231,14 @@ package android.net { } public class ConnectivityManager { - method @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public void startCaptivePortalApp(android.net.Network, android.os.Bundle); + method @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public void startCaptivePortalApp(@NonNull android.net.Network, @NonNull android.os.Bundle); field public static final String EXTRA_CAPTIVE_PORTAL_PROBE_SPEC = "android.net.extra.CAPTIVE_PORTAL_PROBE_SPEC"; field public static final String EXTRA_CAPTIVE_PORTAL_USER_AGENT = "android.net.extra.CAPTIVE_PORTAL_USER_AGENT"; } public final class IpPrefix implements android.os.Parcelable { - ctor public IpPrefix(java.net.InetAddress, int); - ctor public IpPrefix(String); + ctor public IpPrefix(@NonNull java.net.InetAddress, int); + ctor public IpPrefix(@NonNull String); } public final class IpSecManager { @@ -1208,48 +1249,48 @@ package android.net { ctor public LinkAddress(java.net.InetAddress, int, int, int); ctor public LinkAddress(@NonNull java.net.InetAddress, int); ctor public LinkAddress(@NonNull String); - ctor public LinkAddress(String, int, int); + ctor public LinkAddress(@NonNull String, int, int); method public boolean isGlobalPreferred(); - method public boolean isIPv4(); - method public boolean isIPv6(); - method public boolean isSameAddressAs(android.net.LinkAddress); + method public boolean isIpv4(); + method public boolean isIpv6(); + method public boolean isSameAddressAs(@Nullable android.net.LinkAddress); } public final class LinkProperties implements android.os.Parcelable { - ctor public LinkProperties(android.net.LinkProperties); - method public boolean addDnsServer(java.net.InetAddress); - method public boolean addLinkAddress(android.net.LinkAddress); + ctor public LinkProperties(@Nullable android.net.LinkProperties); + method public boolean addDnsServer(@NonNull java.net.InetAddress); + method public boolean addLinkAddress(@NonNull android.net.LinkAddress); method @Nullable public android.net.IpPrefix getNat64Prefix(); - method public java.util.List getPcscfServers(); - method public String getTcpBufferSizes(); - method public java.util.List getValidatedPrivateDnsServers(); - method public boolean hasGlobalIPv6Address(); - method public boolean hasIPv4Address(); - method public boolean hasIPv6DefaultRoute(); - method public boolean isIPv4Provisioned(); - method public boolean isIPv6Provisioned(); + method @NonNull public java.util.List getPcscfServers(); + method @Nullable public String getTcpBufferSizes(); + method @NonNull public java.util.List getValidatedPrivateDnsServers(); + method public boolean hasGlobalIpv6Address(); + method public boolean hasIpv4Address(); + method public boolean hasIpv6DefaultRoute(); + method public boolean isIpv4Provisioned(); + method public boolean isIpv6Provisioned(); method public boolean isProvisioned(); - method public boolean isReachable(java.net.InetAddress); - method public boolean removeDnsServer(java.net.InetAddress); - method public boolean removeLinkAddress(android.net.LinkAddress); - method public boolean removeRoute(android.net.RouteInfo); - method public void setNat64Prefix(android.net.IpPrefix); - method public void setPcscfServers(java.util.Collection); + method public boolean isReachable(@NonNull java.net.InetAddress); + method public boolean removeDnsServer(@NonNull java.net.InetAddress); + method public boolean removeLinkAddress(@NonNull android.net.LinkAddress); + method public boolean removeRoute(@NonNull android.net.RouteInfo); + method public void setNat64Prefix(@Nullable android.net.IpPrefix); + method public void setPcscfServers(@NonNull java.util.Collection); method public void setPrivateDnsServerName(@Nullable String); - method public void setTcpBufferSizes(String); + method public void setTcpBufferSizes(@Nullable String); method public void setUsePrivateDns(boolean); - method public void setValidatedPrivateDnsServers(java.util.Collection); + method public void setValidatedPrivateDnsServers(@NonNull java.util.Collection); } public class Network implements android.os.Parcelable { - ctor public Network(android.net.Network); - method public android.net.Network getPrivateDnsBypassingCopy(); + ctor public Network(@NonNull android.net.Network); + method @NonNull public android.net.Network getPrivateDnsBypassingCopy(); } public final class NetworkCapabilities implements android.os.Parcelable { method public int[] getCapabilities(); - method public int[] getTransportTypes(); - method public boolean satisfiedByNetworkCapabilities(android.net.NetworkCapabilities); + method @NonNull public int[] getTransportTypes(); + method public boolean satisfiedByNetworkCapabilities(@Nullable android.net.NetworkCapabilities); field public static final int TRANSPORT_TEST = 7; // 0x7 } @@ -1258,7 +1299,7 @@ package android.net { } public final class RouteInfo implements android.os.Parcelable { - ctor public RouteInfo(android.net.IpPrefix, java.net.InetAddress, String, int); + ctor public RouteInfo(@Nullable android.net.IpPrefix, @Nullable java.net.InetAddress, @Nullable String, int); method public int getType(); field public static final int RTN_THROW = 9; // 0x9 field public static final int RTN_UNICAST = 1; // 0x1 @@ -1267,18 +1308,18 @@ package android.net { public final class StaticIpConfiguration implements android.os.Parcelable { ctor public StaticIpConfiguration(); - ctor public StaticIpConfiguration(android.net.StaticIpConfiguration); - method public void addDnsServer(java.net.InetAddress); + ctor public StaticIpConfiguration(@Nullable android.net.StaticIpConfiguration); + method public void addDnsServer(@NonNull java.net.InetAddress); method public void clear(); method public int describeContents(); - method public java.util.List getDnsServers(); - method public String getDomains(); - method public java.net.InetAddress getGateway(); - method public android.net.LinkAddress getIpAddress(); - method public java.util.List getRoutes(String); - method public void setDomains(String); - method public void setGateway(java.net.InetAddress); - method public void setIpAddress(android.net.LinkAddress); + method @NonNull public java.util.List getDnsServers(); + method @Nullable public String getDomains(); + method @Nullable public java.net.InetAddress getGateway(); + method @Nullable public android.net.LinkAddress getIpAddress(); + method @NonNull public java.util.List getRoutes(@Nullable String); + method public void setDomains(@Nullable String); + method public void setGateway(@Nullable java.net.InetAddress); + method public void setIpAddress(@Nullable android.net.LinkAddress); method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator CREATOR; } @@ -1315,8 +1356,8 @@ package android.net.apf { public final class ApfCapabilities implements android.os.Parcelable { ctor public ApfCapabilities(int, int, int); method public int describeContents(); - method public static boolean getApfDrop8023Frames(android.content.Context); - method public static int[] getApfEthTypeBlackList(android.content.Context); + method public static boolean getApfDrop8023Frames(@NonNull android.content.Context); + method @NonNull public static int[] getApfEthTypeBlackList(@NonNull android.content.Context); method public boolean hasDataAccess(); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator CREATOR; @@ -1331,28 +1372,28 @@ package android.net.captiveportal { public final class CaptivePortalProbeResult { ctor public CaptivePortalProbeResult(int); - ctor public CaptivePortalProbeResult(int, String, String); - ctor public CaptivePortalProbeResult(int, String, String, android.net.captiveportal.CaptivePortalProbeSpec); + ctor public CaptivePortalProbeResult(int, @Nullable String, @Nullable String); + ctor public CaptivePortalProbeResult(int, @Nullable String, @Nullable String, @Nullable android.net.captiveportal.CaptivePortalProbeSpec); method public boolean isFailed(); method public boolean isPartialConnectivity(); method public boolean isPortal(); method public boolean isSuccessful(); - field public static final android.net.captiveportal.CaptivePortalProbeResult FAILED; + field @NonNull public static final android.net.captiveportal.CaptivePortalProbeResult FAILED; field public static final int FAILED_CODE = 599; // 0x257 field public static final android.net.captiveportal.CaptivePortalProbeResult PARTIAL; field public static final int PORTAL_CODE = 302; // 0x12e - field public static final android.net.captiveportal.CaptivePortalProbeResult SUCCESS; + field @NonNull public static final android.net.captiveportal.CaptivePortalProbeResult SUCCESS; field public static final int SUCCESS_CODE = 204; // 0xcc - field public final String detectUrl; + field @Nullable public final String detectUrl; field @Nullable public final android.net.captiveportal.CaptivePortalProbeSpec probeSpec; - field public final String redirectUrl; + field @Nullable public final String redirectUrl; } public abstract class CaptivePortalProbeSpec { - method public String getEncodedSpec(); - method public abstract android.net.captiveportal.CaptivePortalProbeResult getResult(int, @Nullable String); - method public java.net.URL getUrl(); - method public static java.util.Collection parseCaptivePortalProbeSpecs(String); + method @NonNull public String getEncodedSpec(); + method @NonNull public abstract android.net.captiveportal.CaptivePortalProbeResult getResult(int, @Nullable String); + method @NonNull public java.net.URL getUrl(); + method @NonNull public static java.util.Collection parseCaptivePortalProbeSpecs(@NonNull String); method @Nullable public static android.net.captiveportal.CaptivePortalProbeSpec parseSpecOrNull(@Nullable String); } @@ -1363,78 +1404,78 @@ package android.net.metrics { public final class ApfProgramEvent implements android.net.metrics.IpConnectivityLog.Event { } - public static class ApfProgramEvent.Builder { + public static final class ApfProgramEvent.Builder { ctor public ApfProgramEvent.Builder(); - method public android.net.metrics.ApfProgramEvent build(); - method public android.net.metrics.ApfProgramEvent.Builder setActualLifetime(long); - method public android.net.metrics.ApfProgramEvent.Builder setCurrentRas(int); - method public android.net.metrics.ApfProgramEvent.Builder setFilteredRas(int); - method public android.net.metrics.ApfProgramEvent.Builder setFlags(boolean, boolean); - method public android.net.metrics.ApfProgramEvent.Builder setLifetime(long); - method public android.net.metrics.ApfProgramEvent.Builder setProgramLength(int); + method @NonNull public android.net.metrics.ApfProgramEvent build(); + method @NonNull public android.net.metrics.ApfProgramEvent.Builder setActualLifetime(long); + method @NonNull public android.net.metrics.ApfProgramEvent.Builder setCurrentRas(int); + method @NonNull public android.net.metrics.ApfProgramEvent.Builder setFilteredRas(int); + method @NonNull public android.net.metrics.ApfProgramEvent.Builder setFlags(boolean, boolean); + method @NonNull public android.net.metrics.ApfProgramEvent.Builder setLifetime(long); + method @NonNull public android.net.metrics.ApfProgramEvent.Builder setProgramLength(int); } public final class ApfStats implements android.net.metrics.IpConnectivityLog.Event { } - public static class ApfStats.Builder { + public static final class ApfStats.Builder { ctor public ApfStats.Builder(); - method public android.net.metrics.ApfStats build(); - method public android.net.metrics.ApfStats.Builder setDroppedRas(int); - method public android.net.metrics.ApfStats.Builder setDurationMs(long); - method public android.net.metrics.ApfStats.Builder setMatchingRas(int); - method public android.net.metrics.ApfStats.Builder setMaxProgramSize(int); - method public android.net.metrics.ApfStats.Builder setParseErrors(int); - method public android.net.metrics.ApfStats.Builder setProgramUpdates(int); - method public android.net.metrics.ApfStats.Builder setProgramUpdatesAll(int); - method public android.net.metrics.ApfStats.Builder setProgramUpdatesAllowingMulticast(int); - method public android.net.metrics.ApfStats.Builder setReceivedRas(int); - method public android.net.metrics.ApfStats.Builder setZeroLifetimeRas(int); + method @NonNull public android.net.metrics.ApfStats build(); + method @NonNull public android.net.metrics.ApfStats.Builder setDroppedRas(int); + method @NonNull public android.net.metrics.ApfStats.Builder setDurationMs(long); + method @NonNull public android.net.metrics.ApfStats.Builder setMatchingRas(int); + method @NonNull public android.net.metrics.ApfStats.Builder setMaxProgramSize(int); + method @NonNull public android.net.metrics.ApfStats.Builder setParseErrors(int); + method @NonNull public android.net.metrics.ApfStats.Builder setProgramUpdates(int); + method @NonNull public android.net.metrics.ApfStats.Builder setProgramUpdatesAll(int); + method @NonNull public android.net.metrics.ApfStats.Builder setProgramUpdatesAllowingMulticast(int); + method @NonNull public android.net.metrics.ApfStats.Builder setReceivedRas(int); + method @NonNull public android.net.metrics.ApfStats.Builder setZeroLifetimeRas(int); } public final class DhcpClientEvent implements android.net.metrics.IpConnectivityLog.Event { } - public static class DhcpClientEvent.Builder { + public static final class DhcpClientEvent.Builder { ctor public DhcpClientEvent.Builder(); - method public android.net.metrics.DhcpClientEvent build(); - method public android.net.metrics.DhcpClientEvent.Builder setDurationMs(int); - method public android.net.metrics.DhcpClientEvent.Builder setMsg(String); + method @NonNull public android.net.metrics.DhcpClientEvent build(); + method @NonNull public android.net.metrics.DhcpClientEvent.Builder setDurationMs(int); + method @NonNull public android.net.metrics.DhcpClientEvent.Builder setMsg(String); } public final class DhcpErrorEvent implements android.net.metrics.IpConnectivityLog.Event { ctor public DhcpErrorEvent(int); method public static int errorCodeWithOption(int, int); - field public static final int BOOTP_TOO_SHORT; - field public static final int BUFFER_UNDERFLOW; - field public static final int DHCP_BAD_MAGIC_COOKIE; + field public static final int BOOTP_TOO_SHORT = 67174400; // 0x4010000 + field public static final int BUFFER_UNDERFLOW = 83951616; // 0x5010000 + field public static final int DHCP_BAD_MAGIC_COOKIE = 67239936; // 0x4020000 field public static final int DHCP_ERROR = 4; // 0x4 - field public static final int DHCP_INVALID_OPTION_LENGTH; - field public static final int DHCP_NO_COOKIE; - field public static final int DHCP_NO_MSG_TYPE; - field public static final int DHCP_UNKNOWN_MSG_TYPE; + field public static final int DHCP_INVALID_OPTION_LENGTH = 67305472; // 0x4030000 + field public static final int DHCP_NO_COOKIE = 67502080; // 0x4060000 + field public static final int DHCP_NO_MSG_TYPE = 67371008; // 0x4040000 + field public static final int DHCP_UNKNOWN_MSG_TYPE = 67436544; // 0x4050000 field public static final int L2_ERROR = 1; // 0x1 - field public static final int L2_TOO_SHORT; - field public static final int L2_WRONG_ETH_TYPE; + field public static final int L2_TOO_SHORT = 16842752; // 0x1010000 + field public static final int L2_WRONG_ETH_TYPE = 16908288; // 0x1020000 field public static final int L3_ERROR = 2; // 0x2 - field public static final int L3_INVALID_IP; - field public static final int L3_NOT_IPV4; - field public static final int L3_TOO_SHORT; + field public static final int L3_INVALID_IP = 33751040; // 0x2030000 + field public static final int L3_NOT_IPV4 = 33685504; // 0x2020000 + field public static final int L3_TOO_SHORT = 33619968; // 0x2010000 field public static final int L4_ERROR = 3; // 0x3 - field public static final int L4_NOT_UDP; - field public static final int L4_WRONG_PORT; + field public static final int L4_NOT_UDP = 50397184; // 0x3010000 + field public static final int L4_WRONG_PORT = 50462720; // 0x3020000 field public static final int MISC_ERROR = 5; // 0x5 - field public static final int PARSING_ERROR; - field public static final int RECEIVE_ERROR; + field public static final int PARSING_ERROR = 84082688; // 0x5030000 + field public static final int RECEIVE_ERROR = 84017152; // 0x5020000 } public class IpConnectivityLog { ctor public IpConnectivityLog(); - method public boolean log(long, android.net.metrics.IpConnectivityLog.Event); - method public boolean log(String, android.net.metrics.IpConnectivityLog.Event); - method public boolean log(android.net.Network, int[], android.net.metrics.IpConnectivityLog.Event); - method public boolean log(int, int[], android.net.metrics.IpConnectivityLog.Event); - method public boolean log(android.net.metrics.IpConnectivityLog.Event); + method public boolean log(long, @NonNull android.net.metrics.IpConnectivityLog.Event); + method public boolean log(@NonNull String, @NonNull android.net.metrics.IpConnectivityLog.Event); + method public boolean log(@NonNull android.net.Network, @NonNull int[], @NonNull android.net.metrics.IpConnectivityLog.Event); + method public boolean log(int, @NonNull int[], @NonNull android.net.metrics.IpConnectivityLog.Event); + method public boolean log(@NonNull android.net.metrics.IpConnectivityLog.Event); } public static interface IpConnectivityLog.Event extends android.os.Parcelable { @@ -1482,19 +1523,19 @@ package android.net.metrics { public final class RaEvent implements android.net.metrics.IpConnectivityLog.Event { } - public static class RaEvent.Builder { + public static final class RaEvent.Builder { ctor public RaEvent.Builder(); - method public android.net.metrics.RaEvent build(); - method public android.net.metrics.RaEvent.Builder updateDnsslLifetime(long); - method public android.net.metrics.RaEvent.Builder updatePrefixPreferredLifetime(long); - method public android.net.metrics.RaEvent.Builder updatePrefixValidLifetime(long); - method public android.net.metrics.RaEvent.Builder updateRdnssLifetime(long); - method public android.net.metrics.RaEvent.Builder updateRouteInfoLifetime(long); - method public android.net.metrics.RaEvent.Builder updateRouterLifetime(long); + method @NonNull public android.net.metrics.RaEvent build(); + method @NonNull public android.net.metrics.RaEvent.Builder updateDnsslLifetime(long); + method @NonNull public android.net.metrics.RaEvent.Builder updatePrefixPreferredLifetime(long); + method @NonNull public android.net.metrics.RaEvent.Builder updatePrefixValidLifetime(long); + method @NonNull public android.net.metrics.RaEvent.Builder updateRdnssLifetime(long); + method @NonNull public android.net.metrics.RaEvent.Builder updateRouteInfoLifetime(long); + method @NonNull public android.net.metrics.RaEvent.Builder updateRouterLifetime(long); } public final class ValidationProbeEvent implements android.net.metrics.IpConnectivityLog.Event { - method public static String getProbeName(int); + method @NonNull public static String getProbeName(int); field public static final int DNS_FAILURE = 0; // 0x0 field public static final int DNS_SUCCESS = 1; // 0x1 field public static final int PROBE_DNS = 0; // 0x0 @@ -1505,12 +1546,12 @@ package android.net.metrics { field public static final int PROBE_PRIVDNS = 5; // 0x5 } - public static class ValidationProbeEvent.Builder { + public static final class ValidationProbeEvent.Builder { ctor public ValidationProbeEvent.Builder(); - method public android.net.metrics.ValidationProbeEvent build(); - method public android.net.metrics.ValidationProbeEvent.Builder setDurationMs(long); - method public android.net.metrics.ValidationProbeEvent.Builder setProbeType(int, boolean); - method public android.net.metrics.ValidationProbeEvent.Builder setReturnCode(int); + method @NonNull public android.net.metrics.ValidationProbeEvent build(); + method @NonNull public android.net.metrics.ValidationProbeEvent.Builder setDurationMs(long); + method @NonNull public android.net.metrics.ValidationProbeEvent.Builder setProbeType(int, boolean); + method @NonNull public android.net.metrics.ValidationProbeEvent.Builder setReturnCode(int); } } @@ -1770,11 +1811,11 @@ package android.os { } public final class PowerManager { - method @RequiresPermission("android.permission.POWER_SAVER") public int getPowerSaveMode(); - method @RequiresPermission("android.permission.POWER_SAVER") public boolean setDynamicPowerSavings(boolean, int); + method @RequiresPermission("android.permission.POWER_SAVER") public int getPowerSaveModeTrigger(); + method @RequiresPermission("android.permission.POWER_SAVER") public boolean setDynamicPowerSaveHint(boolean, int); method @RequiresPermission(anyOf={"android.permission.DEVICE_POWER", "android.permission.POWER_SAVER"}) public boolean setPowerSaveModeEnabled(boolean); - field public static final int POWER_SAVER_MODE_DYNAMIC = 1; // 0x1 - field public static final int POWER_SAVER_MODE_PERCENTAGE = 0; // 0x0 + field public static final int POWER_SAVE_MODE_TRIGGER_DYNAMIC = 1; // 0x1 + field public static final int POWER_SAVE_MODE_TRIGGER_PERCENTAGE = 0; // 0x0 } public class Process { @@ -2109,9 +2150,9 @@ package android.provider { method @RequiresPermission(android.Manifest.permission.CLEAR_APP_USER_DATA) public static long getContributedMediaSize(android.content.Context, String, android.os.UserHandle) throws java.io.IOException; method @NonNull public static java.io.File getVolumePath(@NonNull String) throws java.io.FileNotFoundException; method @NonNull public static java.util.Collection getVolumeScanPaths(@NonNull String) throws java.io.FileNotFoundException; - field public static final String EXTRA_ORIGINATED_FROM_SHELL = "android.intent.extra.originated_from_shell"; - field public static final String SCAN_FILE_CALL = "scan_file"; - field public static final String SCAN_VOLUME_CALL = "scan_volume"; + method public static android.net.Uri scanFile(android.content.Context, java.io.File); + method public static android.net.Uri scanFileFromShell(android.content.Context, java.io.File); + method public static void scanVolume(android.content.Context, java.io.File); } public final class Settings { @@ -2122,7 +2163,7 @@ package android.provider { public static final class Settings.Global extends android.provider.Settings.NameValueTable { field public static final String AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES = "autofill_compat_mode_allowed_packages"; - field public static final String AUTOMATIC_POWER_SAVER_MODE = "automatic_power_saver_mode"; + field public static final String AUTOMATIC_POWER_SAVE_MODE = "automatic_power_save_mode"; field public static final String BATTERY_SAVER_CONSTANTS = "battery_saver_constants"; field public static final String CAPTIVE_PORTAL_FALLBACK_PROBE_SPECS = "captive_portal_fallback_probe_specs"; field public static final String CAPTIVE_PORTAL_FALLBACK_URL = "captive_portal_fallback_url"; @@ -2232,7 +2273,7 @@ package android.service.appprediction { method @NonNull public final android.os.IBinder onBind(@NonNull android.content.Intent); method public void onCreatePredictionSession(@NonNull android.app.prediction.AppPredictionContext, @NonNull android.app.prediction.AppPredictionSessionId); method @MainThread public void onDestroyPredictionSession(@NonNull android.app.prediction.AppPredictionSessionId); - method @MainThread public abstract void onLocationShown(@NonNull android.app.prediction.AppPredictionSessionId, @NonNull String, @NonNull java.util.List); + method @MainThread public abstract void onLaunchLocationShown(@NonNull android.app.prediction.AppPredictionSessionId, @NonNull String, @NonNull java.util.List); method @MainThread public abstract void onRequestPredictionUpdate(@NonNull android.app.prediction.AppPredictionSessionId); method @MainThread public abstract void onSortAppTargets(@NonNull android.app.prediction.AppPredictionSessionId, @NonNull java.util.List, @NonNull android.os.CancellationSignal, @NonNull java.util.function.Consumer>); method @MainThread public void onStartPredictionUpdates(); @@ -2407,7 +2448,7 @@ package android.service.contentcapture { public abstract class ContentCaptureService extends android.app.Service { ctor public ContentCaptureService(); - method public final void disableContentCaptureServices(); + method public final void disableSelf(); method public void onActivityEvent(@NonNull android.service.contentcapture.ActivityEvent); method public void onActivitySnapshot(@NonNull android.view.contentcapture.ContentCaptureSessionId, @NonNull android.service.contentcapture.SnapshotData); method public void onConnected(); @@ -2526,10 +2567,34 @@ package android.telecom { package android.telephony { + public final class AccessNetworkConstants { + field public static final int TRANSPORT_TYPE_WLAN = 2; // 0x2 + field public static final int TRANSPORT_TYPE_WWAN = 1; // 0x1 + } + public class CarrierConfigManager { method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void overrideConfig(int, @Nullable android.os.PersistableBundle); } + public final class DataSpecificRegistrationInfo implements android.os.Parcelable { + method public int describeContents(); + method @NonNull public android.telephony.LteVopsSupportInfo getLteVopsSupportInfo(); + method public void writeToParcel(android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator CREATOR; + } + + public final class LteVopsSupportInfo implements android.os.Parcelable { + ctor public LteVopsSupportInfo(int, int); + method public int describeContents(); + method public int getEmcBearerSupport(); + method public int getVopsSupport(); + method public void writeToParcel(android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator CREATOR; + field public static final int LTE_STATUS_NOT_AVAILABLE = 1; // 0x1 + field public static final int LTE_STATUS_NOT_SUPPORTED = 3; // 0x3 + field public static final int LTE_STATUS_SUPPORTED = 2; // 0x2 + } + public class MbmsDownloadSession implements java.lang.AutoCloseable { field public static final String MBMS_DOWNLOAD_SERVICE_OVERRIDE_METADATA = "mbms-download-service-override"; } @@ -2542,12 +2607,59 @@ package android.telephony { field public static final String MBMS_STREAMING_SERVICE_OVERRIDE_METADATA = "mbms-streaming-service-override"; } + public final class NetworkRegistrationInfo implements android.os.Parcelable { + method public int describeContents(); + method public int getAccessNetworkTechnology(); + method @NonNull public java.util.List getAvailableServices(); + method @Nullable public android.telephony.CellIdentity getCellIdentity(); + method @Nullable public android.telephony.DataSpecificRegistrationInfo getDataSpecificInfo(); + method public int getDomain(); + method public int getRegistrationState(); + method public int getRejectCause(); + method public int getRoamingType(); + method public int getTransportType(); + method public boolean isEmergencyEnabled(); + method public boolean isRoaming(); + method public void writeToParcel(android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator CREATOR; + field public static final int DOMAIN_CS = 1; // 0x1 + field public static final int DOMAIN_PS = 2; // 0x2 + field public static final int REGISTRATION_STATE_DENIED = 3; // 0x3 + field public static final int REGISTRATION_STATE_HOME = 1; // 0x1 + field public static final int REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING = 0; // 0x0 + field public static final int REGISTRATION_STATE_NOT_REGISTERED_SEARCHING = 2; // 0x2 + field public static final int REGISTRATION_STATE_ROAMING = 5; // 0x5 + field public static final int REGISTRATION_STATE_UNKNOWN = 4; // 0x4 + field public static final int SERVICE_TYPE_DATA = 2; // 0x2 + field public static final int SERVICE_TYPE_EMERGENCY = 5; // 0x5 + field public static final int SERVICE_TYPE_SMS = 3; // 0x3 + field public static final int SERVICE_TYPE_UNKNOWN = 0; // 0x0 + field public static final int SERVICE_TYPE_VIDEO = 4; // 0x4 + field public static final int SERVICE_TYPE_VOICE = 1; // 0x1 + } + + public static final class NetworkRegistrationInfo.Builder { + ctor public NetworkRegistrationInfo.Builder(); + method @NonNull public android.telephony.NetworkRegistrationInfo build(); + method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setAccessNetworkTechnology(int); + method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setAvailableServices(@NonNull java.util.List); + method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setCellIdentity(@Nullable android.telephony.CellIdentity); + method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setDomain(int); + method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setEmergencyOnly(boolean); + method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRegistrationState(int); + method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRejectCause(int); + method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setTransportType(int); + } + public class ServiceState implements android.os.Parcelable { + method public void addNetworkRegistrationInfo(android.telephony.NetworkRegistrationInfo); method public void setCdmaSystemAndNetworkId(int, int); method public void setCellBandwidths(int[]); method public void setChannelNumber(int); + method public void setDataRoamingType(int); method public void setRilDataRadioTechnology(int); method public void setRilVoiceRadioTechnology(int); + method public void setVoiceRoamingType(int); } public class TelephonyManager { @@ -3177,10 +3289,6 @@ package android.view.inputmethod { package android.view.inspector { - @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) @java.lang.annotation.Target({java.lang.annotation.ElementType.TYPE}) public @interface InspectableNodeName { - method public abstract String value(); - } - @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.FIELD}) public @interface InspectableProperty { method public abstract int attributeId() default android.content.res.Resources.ID_NULL; method public abstract android.view.inspector.InspectableProperty.EnumEntry[] enumMapping() default {}; diff --git a/cmds/idmap2/idmap2/Create.cpp b/cmds/idmap2/idmap2/Create.cpp index fdbb210441766673ad62a5e48ca1eb61e84eabe5..47617e045c12eb835f16257b74de23c24db3ea01 100644 --- a/cmds/idmap2/idmap2/Create.cpp +++ b/cmds/idmap2/idmap2/Create.cpp @@ -98,12 +98,10 @@ Result Create(const std::vector& args) { return Error("failed to load apk %s", overlay_apk_path.c_str()); } - std::stringstream stream; - const std::unique_ptr idmap = - Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk, - fulfilled_policies, !ignore_overlayable, stream); + const auto idmap = Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, + *overlay_apk, fulfilled_policies, !ignore_overlayable); if (!idmap) { - return Error("failed to create idmap: %s", stream.str().c_str()); + return Error(idmap.GetError(), "failed to create idmap"); } umask(kIdmapFilePermissionMask); @@ -112,7 +110,7 @@ Result Create(const std::vector& args) { return Error("failed to open idmap path %s", idmap_path.c_str()); } BinaryStreamVisitor visitor(fout); - idmap->accept(&visitor); + (*idmap)->accept(&visitor); fout.close(); if (fout.fail()) { return Error("failed to write to idmap path %s", idmap_path.c_str()); diff --git a/cmds/idmap2/idmap2/Dump.cpp b/cmds/idmap2/idmap2/Dump.cpp index fd5822251188607cdd2d216208c1f724a36c823c..8716bf313ed007e79c2161881bed4455879d9b73 100644 --- a/cmds/idmap2/idmap2/Dump.cpp +++ b/cmds/idmap2/idmap2/Dump.cpp @@ -49,20 +49,19 @@ Result Dump(const std::vector& args) { if (!opts_ok) { return opts_ok.GetError(); } - std::stringstream stream; std::ifstream fin(idmap_path); - const std::unique_ptr idmap = Idmap::FromBinaryStream(fin, stream); + const auto idmap = Idmap::FromBinaryStream(fin); fin.close(); if (!idmap) { - return Error("failed to load idmap: %s", stream.str().c_str()); + return Error(idmap.GetError(), "failed to load idmap"); } if (verbose) { RawPrintVisitor visitor(std::cout); - idmap->accept(&visitor); + (*idmap)->accept(&visitor); } else { PrettyPrintVisitor visitor(std::cout); - idmap->accept(&visitor); + (*idmap)->accept(&visitor); } return Unit{}; diff --git a/cmds/idmap2/idmap2/Scan.cpp b/cmds/idmap2/idmap2/Scan.cpp index 24331af9fd6d68e5c3b136a1a3c504ab15f31b31..55b1003c38af99731d6367708f9ced858829060a 100644 --- a/cmds/idmap2/idmap2/Scan.cpp +++ b/cmds/idmap2/idmap2/Scan.cpp @@ -196,13 +196,7 @@ Result Scan(const std::vector& args) { std::stringstream stream; for (const auto& overlay : interesting_apks) { - std::vector verify_args = {"--idmap-path", overlay.idmap_path}; - for (const std::string& policy : overlay.policies) { - verify_args.emplace_back("--policy"); - verify_args.emplace_back(policy); - } - - if (!Verify(std::vector(verify_args))) { + if (!Verify(std::vector({"--idmap-path", overlay.idmap_path}))) { std::vector create_args = {"--target-apk-path", target_apk_path, "--overlay-apk-path", overlay.apk_path, "--idmap-path", overlay.idmap_path}; diff --git a/cmds/idmap2/idmap2d/Idmap2Service.cpp b/cmds/idmap2/idmap2d/Idmap2Service.cpp index e03a9cc1032e0afbd5ecb17f9de3732f4368ffd5..4f653796ce3f0a81af95a40ba1de840103740497 100644 --- a/cmds/idmap2/idmap2d/Idmap2Service.cpp +++ b/cmds/idmap2/idmap2d/Idmap2Service.cpp @@ -138,12 +138,10 @@ Status Idmap2Service::createIdmap(const std::string& target_apk_path, return error("failed to load apk " + overlay_apk_path); } - std::stringstream err; - const std::unique_ptr idmap = - Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk, - policy_bitmask, enforce_overlayable, err); + const auto idmap = Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, + *overlay_apk, policy_bitmask, enforce_overlayable); if (!idmap) { - return error(err.str()); + return error(idmap.GetErrorMessage()); } umask(kIdmapFilePermissionMask); @@ -152,7 +150,7 @@ Status Idmap2Service::createIdmap(const std::string& target_apk_path, return error("failed to open idmap path " + idmap_path); } BinaryStreamVisitor visitor(fout); - idmap->accept(&visitor); + (*idmap)->accept(&visitor); fout.close(); if (fout.fail()) { return error("failed to write to idmap path " + idmap_path); diff --git a/cmds/idmap2/include/idmap2/Idmap.h b/cmds/idmap2/include/idmap2/Idmap.h index 673d18d25907afab68ce67940eb598ca1a29f1d0..5cc0664b2bedae3f6c72fbe0db032871441c8efe 100644 --- a/cmds/idmap2/include/idmap2/Idmap.h +++ b/cmds/idmap2/include/idmap2/Idmap.h @@ -228,17 +228,18 @@ class Idmap { static std::string CanonicalIdmapPathFor(const std::string& absolute_dir, const std::string& absolute_apk_path); - static std::unique_ptr FromBinaryStream(std::istream& stream, - std::ostream& out_error); + static Result> FromBinaryStream(std::istream& stream); // In the current version of idmap, the first package in each resources.arsc // file is used; change this in the next version of idmap to use a named // package instead; also update FromApkAssets to take additional parameters: // the target and overlay package names - static std::unique_ptr FromApkAssets( - const std::string& target_apk_path, const ApkAssets& target_apk_assets, - const std::string& overlay_apk_path, const ApkAssets& overlay_apk_assets, - const PolicyBitmask& fulfilled_policies, bool enforce_overlayable, std::ostream& out_error); + static Result> FromApkAssets(const std::string& target_apk_path, + const ApkAssets& target_apk_assets, + const std::string& overlay_apk_path, + const ApkAssets& overlay_apk_assets, + const PolicyBitmask& fulfilled_policies, + bool enforce_overlayable); inline const std::unique_ptr& GetHeader() const { return header_; diff --git a/cmds/idmap2/libidmap2/Idmap.cpp b/cmds/idmap2/libidmap2/Idmap.cpp index 9afdd437491fd1c12f51ccc25f7055c771807714..6d5fe7b3446afc5ba4630ca5070f876ff609aaba 100644 --- a/cmds/idmap2/libidmap2/Idmap.cpp +++ b/cmds/idmap2/libidmap2/Idmap.cpp @@ -56,7 +56,7 @@ class MatchingResources { } inline const std::map>>& WARN_UNUSED - Map() const { + Map() const { return map_; } @@ -124,7 +124,7 @@ Result GetCrc(const ZipFile& zip) { const Result b = zip.Crc("AndroidManifest.xml"); return a && b ? Result(*a ^ *b) - : Error("Couldn't get CRC for \"%s\"", a ? "AndroidManifest.xml" : "resources.arsc"); + : Error("failed to get CRC for \"%s\"", a ? "AndroidManifest.xml" : "resources.arsc"); } } // namespace @@ -244,15 +244,13 @@ std::string Idmap::CanonicalIdmapPathFor(const std::string& absolute_dir, return absolute_dir + "/" + copy + "@idmap"; } -std::unique_ptr Idmap::FromBinaryStream(std::istream& stream, - std::ostream& out_error) { +Result> Idmap::FromBinaryStream(std::istream& stream) { SYSTRACE << "Idmap::FromBinaryStream"; std::unique_ptr idmap(new Idmap()); idmap->header_ = IdmapHeader::FromBinaryStream(stream); if (!idmap->header_) { - out_error << "error: failed to parse idmap header" << std::endl; - return nullptr; + return Error("failed to parse idmap header"); } // idmap version 0x01 does not specify the number of data blocks that follow @@ -260,13 +258,12 @@ std::unique_ptr Idmap::FromBinaryStream(std::istream& stream, for (int i = 0; i < 1; i++) { std::unique_ptr data = IdmapData::FromBinaryStream(stream); if (!data) { - out_error << "error: failed to parse data block " << i << std::endl; - return nullptr; + return Error("failed to parse data block %d", i); } idmap->data_.push_back(std::move(data)); } - return std::move(idmap); + return {std::move(idmap)}; } std::string ConcatPolicies(const std::vector& policies) { @@ -323,63 +320,56 @@ Result CheckOverlayable(const LoadedPackage& target_package, return Result({}); } -std::unique_ptr Idmap::FromApkAssets( - const std::string& target_apk_path, const ApkAssets& target_apk_assets, - const std::string& overlay_apk_path, const ApkAssets& overlay_apk_assets, - const PolicyBitmask& fulfilled_policies, bool enforce_overlayable, std::ostream& out_error) { +Result> Idmap::FromApkAssets(const std::string& target_apk_path, + const ApkAssets& target_apk_assets, + const std::string& overlay_apk_path, + const ApkAssets& overlay_apk_assets, + const PolicyBitmask& fulfilled_policies, + bool enforce_overlayable) { SYSTRACE << "Idmap::FromApkAssets"; AssetManager2 target_asset_manager; if (!target_asset_manager.SetApkAssets({&target_apk_assets}, true, false)) { - out_error << "error: failed to create target asset manager" << std::endl; - return nullptr; + return Error("failed to create target asset manager"); } AssetManager2 overlay_asset_manager; if (!overlay_asset_manager.SetApkAssets({&overlay_apk_assets}, true, false)) { - out_error << "error: failed to create overlay asset manager" << std::endl; - return nullptr; + return Error("failed to create overlay asset manager"); } const LoadedArsc* target_arsc = target_apk_assets.GetLoadedArsc(); if (target_arsc == nullptr) { - out_error << "error: failed to load target resources.arsc" << std::endl; - return nullptr; + return Error("failed to load target resources.arsc"); } const LoadedArsc* overlay_arsc = overlay_apk_assets.GetLoadedArsc(); if (overlay_arsc == nullptr) { - out_error << "error: failed to load overlay resources.arsc" << std::endl; - return nullptr; + return Error("failed to load overlay resources.arsc"); } const LoadedPackage* target_pkg = GetPackageAtIndex0(*target_arsc); if (target_pkg == nullptr) { - out_error << "error: failed to load target package from resources.arsc" << std::endl; - return nullptr; + return Error("failed to load target package from resources.arsc"); } const LoadedPackage* overlay_pkg = GetPackageAtIndex0(*overlay_arsc); if (overlay_pkg == nullptr) { - out_error << "error: failed to load overlay package from resources.arsc" << std::endl; - return nullptr; + return Error("failed to load overlay package from resources.arsc"); } const std::unique_ptr target_zip = ZipFile::Open(target_apk_path); if (!target_zip) { - out_error << "error: failed to open target as zip" << std::endl; - return nullptr; + return Error("failed to open target as zip"); } const std::unique_ptr overlay_zip = ZipFile::Open(overlay_apk_path); if (!overlay_zip) { - out_error << "error: failed to open overlay as zip" << std::endl; - return nullptr; + return Error("failed to open overlay as zip"); } auto overlay_info = utils::ExtractOverlayManifestInfo(overlay_apk_path); if (!overlay_info) { - out_error << "error: " << overlay_info.GetErrorMessage() << std::endl; - return nullptr; + return overlay_info.GetError(); } std::unique_ptr header(new IdmapHeader()); @@ -388,30 +378,26 @@ std::unique_ptr Idmap::FromApkAssets( Result crc = GetCrc(*target_zip); if (!crc) { - out_error << "error: failed to get zip crc for target" << std::endl; - return nullptr; + return Error(crc.GetError(), "failed to get zip CRC for target"); } header->target_crc_ = *crc; crc = GetCrc(*overlay_zip); if (!crc) { - out_error << "error: failed to get zip crc for overlay" << std::endl; - return nullptr; + return Error(crc.GetError(), "failed to get zip CRC for overlay"); } header->overlay_crc_ = *crc; if (target_apk_path.size() > sizeof(header->target_path_)) { - out_error << "error: target apk path \"" << target_apk_path << "\" longer that maximum size " - << sizeof(header->target_path_) << std::endl; - return nullptr; + return Error("target apk path \"%s\" longer than maximum size %zu", target_apk_path.c_str(), + sizeof(header->target_path_)); } memset(header->target_path_, 0, sizeof(header->target_path_)); memcpy(header->target_path_, target_apk_path.data(), target_apk_path.size()); if (overlay_apk_path.size() > sizeof(header->overlay_path_)) { - out_error << "error: overlay apk path \"" << overlay_apk_path << "\" longer that maximum size " - << sizeof(header->overlay_path_) << std::endl; - return nullptr; + return Error("overlay apk path \"%s\" longer than maximum size %zu", target_apk_path.c_str(), + sizeof(header->target_path_)); } memset(header->overlay_path_, 0, sizeof(header->overlay_path_)); memcpy(header->overlay_path_, overlay_apk_path.data(), overlay_apk_path.size()); @@ -451,9 +437,8 @@ std::unique_ptr Idmap::FromApkAssets( } if (matching_resources.Map().empty()) { - out_error << "overlay \"" << overlay_apk_path << "\" does not successfully overlay any resource" - << std::endl; - return nullptr; + return Error("overlay \"%s\" does not successfully overlay any resource", + overlay_apk_path.c_str()); } // encode idmap data @@ -484,7 +469,7 @@ std::unique_ptr Idmap::FromApkAssets( idmap->data_.push_back(std::move(data)); - return std::move(idmap); + return {std::move(idmap)}; } void IdmapHeader::accept(Visitor* v) const { diff --git a/cmds/idmap2/tests/BinaryStreamVisitorTests.cpp b/cmds/idmap2/tests/BinaryStreamVisitorTests.cpp index 9a0412efbde44f1e1463b208ff472c102577dc0e..9a5b6331cb209c04fd28c0d57d4da9c77918dfcf 100644 --- a/cmds/idmap2/tests/BinaryStreamVisitorTests.cpp +++ b/cmds/idmap2/tests/BinaryStreamVisitorTests.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -37,16 +38,17 @@ TEST(BinaryStreamVisitorTests, CreateBinaryStreamViaBinaryStreamVisitor) { std::string raw(reinterpret_cast(idmap_raw_data), idmap_raw_data_len); std::istringstream raw_stream(raw); - std::stringstream error; - std::unique_ptr idmap1 = Idmap::FromBinaryStream(raw_stream, error); - ASSERT_THAT(idmap1, NotNull()); + auto result1 = Idmap::FromBinaryStream(raw_stream); + ASSERT_TRUE(result1); + const auto idmap1 = std::move(*result1); std::stringstream stream; BinaryStreamVisitor visitor(stream); idmap1->accept(&visitor); - std::unique_ptr idmap2 = Idmap::FromBinaryStream(stream, error); - ASSERT_THAT(idmap2, NotNull()); + auto result2 = Idmap::FromBinaryStream(stream); + ASSERT_TRUE(result2); + const auto idmap2 = std::move(*result2); ASSERT_EQ(idmap1->GetHeader()->GetTargetCrc(), idmap2->GetHeader()->GetTargetCrc()); ASSERT_EQ(idmap1->GetHeader()->GetTargetPath(), idmap2->GetHeader()->GetTargetPath()); @@ -76,15 +78,14 @@ TEST(BinaryStreamVisitorTests, CreateIdmapFromApkAssetsInteropWithLoadedIdmap) { std::unique_ptr overlay_apk = ApkAssets::Load(overlay_apk_path); ASSERT_THAT(overlay_apk, NotNull()); - std::stringstream error; - std::unique_ptr idmap = + const auto idmap = Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk, - PolicyFlags::POLICY_PUBLIC, /* enforce_overlayable */ true, error); - ASSERT_THAT(idmap, NotNull()); + PolicyFlags::POLICY_PUBLIC, /* enforce_overlayable */ true); + ASSERT_TRUE(idmap); std::stringstream stream; BinaryStreamVisitor visitor(stream); - idmap->accept(&visitor); + (*idmap)->accept(&visitor); const std::string str = stream.str(); const StringPiece data(str); std::unique_ptr loaded_idmap = LoadedIdmap::Load(data); diff --git a/cmds/idmap2/tests/Idmap2BinaryTests.cpp b/cmds/idmap2/tests/Idmap2BinaryTests.cpp index a6a2ada767127c46efc940182ad57328cd66adc0..91bc4ddb397fefff57c610dc1fbd9d76f49add9e 100644 --- a/cmds/idmap2/tests/Idmap2BinaryTests.cpp +++ b/cmds/idmap2/tests/Idmap2BinaryTests.cpp @@ -100,13 +100,12 @@ TEST_F(Idmap2BinaryTests, Create) { struct stat st; ASSERT_EQ(stat(GetIdmapPath().c_str(), &st), 0); - std::stringstream error; std::ifstream fin(GetIdmapPath()); - std::unique_ptr idmap = Idmap::FromBinaryStream(fin, error); + const auto idmap = Idmap::FromBinaryStream(fin); fin.close(); - ASSERT_THAT(idmap, NotNull()); - ASSERT_IDMAP(*idmap, GetTargetApkPath(), GetOverlayApkPath()); + ASSERT_TRUE(idmap); + ASSERT_IDMAP(**idmap, GetTargetApkPath(), GetOverlayApkPath()); unlink(GetIdmapPath().c_str()); } @@ -193,24 +192,23 @@ TEST_F(Idmap2BinaryTests, Scan) { expected << idmap_static_2_path << std::endl; ASSERT_EQ(result->stdout, expected.str()); - std::stringstream error; auto idmap_static_no_name_raw_string = utils::ReadFile(idmap_static_no_name_path); auto idmap_static_no_name_raw_stream = std::istringstream(*idmap_static_no_name_raw_string); - auto idmap_static_no_name = Idmap::FromBinaryStream(idmap_static_no_name_raw_stream, error); - ASSERT_THAT(idmap_static_no_name, NotNull()); - ASSERT_IDMAP(*idmap_static_no_name, GetTargetApkPath(), overlay_static_no_name_apk_path); + auto idmap_static_no_name = Idmap::FromBinaryStream(idmap_static_no_name_raw_stream); + ASSERT_TRUE(idmap_static_no_name); + ASSERT_IDMAP(**idmap_static_no_name, GetTargetApkPath(), overlay_static_no_name_apk_path); auto idmap_static_1_raw_string = utils::ReadFile(idmap_static_1_path); auto idmap_static_1_raw_stream = std::istringstream(*idmap_static_1_raw_string); - auto idmap_static_1 = Idmap::FromBinaryStream(idmap_static_1_raw_stream, error); - ASSERT_THAT(idmap_static_1, NotNull()); - ASSERT_IDMAP(*idmap_static_1, GetTargetApkPath(), overlay_static_1_apk_path); + auto idmap_static_1 = Idmap::FromBinaryStream(idmap_static_1_raw_stream); + ASSERT_TRUE(idmap_static_1); + ASSERT_IDMAP(**idmap_static_1, GetTargetApkPath(), overlay_static_1_apk_path); auto idmap_static_2_raw_string = utils::ReadFile(idmap_static_2_path); auto idmap_static_2_raw_stream = std::istringstream(*idmap_static_2_raw_string); - auto idmap_static_2 = Idmap::FromBinaryStream(idmap_static_2_raw_stream, error); - ASSERT_THAT(idmap_static_2, NotNull()); - ASSERT_IDMAP(*idmap_static_2, GetTargetApkPath(), overlay_static_2_apk_path); + auto idmap_static_2 = Idmap::FromBinaryStream(idmap_static_2_raw_stream); + ASSERT_TRUE(idmap_static_2); + ASSERT_IDMAP(**idmap_static_2, GetTargetApkPath(), overlay_static_2_apk_path); unlink(idmap_static_no_name_path.c_str()); unlink(idmap_static_2_path.c_str()); diff --git a/cmds/idmap2/tests/IdmapTests.cpp b/cmds/idmap2/tests/IdmapTests.cpp index c20ae7b798a3e659940794fd51cad68bd1e05431..621f50337aa3ce557c53af9321fcbc87a19f2751 100644 --- a/cmds/idmap2/tests/IdmapTests.cpp +++ b/cmds/idmap2/tests/IdmapTests.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include "gmock/gmock.h" @@ -127,9 +128,9 @@ TEST(IdmapTests, CreateIdmapFromBinaryStream) { std::string raw(reinterpret_cast(idmap_raw_data), idmap_raw_data_len); std::istringstream stream(raw); - std::stringstream error; - std::unique_ptr idmap = Idmap::FromBinaryStream(stream, error); - ASSERT_THAT(idmap, NotNull()); + auto result = Idmap::FromBinaryStream(stream); + ASSERT_TRUE(result); + const auto idmap = std::move(*result); ASSERT_THAT(idmap->GetHeader(), NotNull()); ASSERT_EQ(idmap->GetHeader()->GetMagic(), 0x504d4449U); @@ -168,9 +169,8 @@ TEST(IdmapTests, GracefullyFailToCreateIdmapFromCorruptBinaryStream) { 10); // data too small std::istringstream stream(raw); - std::stringstream error; - std::unique_ptr idmap = Idmap::FromBinaryStream(stream, error); - ASSERT_THAT(idmap, IsNull()); + const auto result = Idmap::FromBinaryStream(stream); + ASSERT_FALSE(result); } void CreateIdmap(const StringPiece& target_apk_path, const StringPiece& overlay_apk_path, @@ -182,10 +182,10 @@ void CreateIdmap(const StringPiece& target_apk_path, const StringPiece& overlay_ std::unique_ptr overlay_apk = ApkAssets::Load(overlay_apk_path.to_string()); ASSERT_THAT(overlay_apk, NotNull()); - std::stringstream error; - *out_idmap = + auto result = Idmap::FromApkAssets(target_apk_path.to_string(), *target_apk, overlay_apk_path.to_string(), - *overlay_apk, fulfilled_policies, enforce_overlayable, error); + *overlay_apk, fulfilled_policies, enforce_overlayable); + *out_idmap = result ? std::move(*result) : nullptr; } TEST(IdmapTests, CreateIdmapFromApkAssets) { @@ -471,11 +471,10 @@ TEST(IdmapTests, FailToCreateIdmapFromApkAssetsIfPathTooLong) { std::unique_ptr overlay_apk = ApkAssets::Load(overlay_apk_path); ASSERT_THAT(overlay_apk, NotNull()); - std::stringstream error; - std::unique_ptr idmap = + const auto result = Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk, - PolicyFlags::POLICY_PUBLIC, /* enforce_overlayable */ true, error); - ASSERT_THAT(idmap, IsNull()); + PolicyFlags::POLICY_PUBLIC, /* enforce_overlayable */ true); + ASSERT_FALSE(result); } TEST(IdmapTests, IdmapHeaderIsUpToDate) { @@ -489,11 +488,11 @@ TEST(IdmapTests, IdmapHeaderIsUpToDate) { std::unique_ptr overlay_apk = ApkAssets::Load(overlay_apk_path); ASSERT_THAT(overlay_apk, NotNull()); - std::stringstream error; - std::unique_ptr idmap = Idmap::FromApkAssets( - target_apk_path, *target_apk, overlay_apk_path, *overlay_apk, PolicyFlags::POLICY_PUBLIC, - /* enforce_overlayable */ true, error); - ASSERT_THAT(idmap, NotNull()); + auto result = Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk, + PolicyFlags::POLICY_PUBLIC, + /* enforce_overlayable */ true); + ASSERT_TRUE(result); + const auto idmap = std::move(*result); std::stringstream stream; BinaryStreamVisitor visitor(stream); @@ -609,13 +608,12 @@ TEST(IdmapTests, TestVisitor) { std::string raw(reinterpret_cast(idmap_raw_data), idmap_raw_data_len); std::istringstream stream(raw); - std::stringstream error; - std::unique_ptr idmap = Idmap::FromBinaryStream(stream, error); - ASSERT_THAT(idmap, NotNull()); + const auto idmap = Idmap::FromBinaryStream(stream); + ASSERT_TRUE(idmap); std::stringstream test_stream; TestVisitor visitor(test_stream); - idmap->accept(&visitor); + (*idmap)->accept(&visitor); ASSERT_EQ(test_stream.str(), "TestVisitor::visit(Idmap)\n" diff --git a/cmds/idmap2/tests/PrettyPrintVisitorTests.cpp b/cmds/idmap2/tests/PrettyPrintVisitorTests.cpp index eaa47cd7953339e44efaa5412703cefbbe9f6b12..27a3880f67b6a9ba36ec5a7e7f65f2db80984c8b 100644 --- a/cmds/idmap2/tests/PrettyPrintVisitorTests.cpp +++ b/cmds/idmap2/tests/PrettyPrintVisitorTests.cpp @@ -46,15 +46,14 @@ TEST(PrettyPrintVisitorTests, CreatePrettyPrintVisitor) { std::unique_ptr overlay_apk = ApkAssets::Load(overlay_apk_path); ASSERT_THAT(overlay_apk, NotNull()); - std::stringstream error; - std::unique_ptr idmap = + const auto idmap = Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk, - PolicyFlags::POLICY_PUBLIC, /* enforce_overlayable */ true, error); - ASSERT_THAT(idmap, NotNull()); + PolicyFlags::POLICY_PUBLIC, /* enforce_overlayable */ true); + ASSERT_TRUE(idmap); std::stringstream stream; PrettyPrintVisitor visitor(stream); - idmap->accept(&visitor); + (*idmap)->accept(&visitor); ASSERT_NE(stream.str().find("target apk path : "), std::string::npos); ASSERT_NE(stream.str().find("overlay apk path : "), std::string::npos); @@ -67,13 +66,12 @@ TEST(PrettyPrintVisitorTests, CreatePrettyPrintVisitorWithoutAccessToApks) { std::string raw(reinterpret_cast(idmap_raw_data), idmap_raw_data_len); std::istringstream raw_stream(raw); - std::stringstream error; - std::unique_ptr idmap = Idmap::FromBinaryStream(raw_stream, error); - ASSERT_THAT(idmap, NotNull()); + const auto idmap = Idmap::FromBinaryStream(raw_stream); + ASSERT_TRUE(idmap); std::stringstream stream; PrettyPrintVisitor visitor(stream); - idmap->accept(&visitor); + (*idmap)->accept(&visitor); ASSERT_NE(stream.str().find("target apk path : "), std::string::npos); ASSERT_NE(stream.str().find("overlay apk path : "), std::string::npos); diff --git a/cmds/idmap2/tests/RawPrintVisitorTests.cpp b/cmds/idmap2/tests/RawPrintVisitorTests.cpp index 7ec13ed0ade751f7f29bf400bf67803f8d8aa5f1..7372148f0f0ec3c523f076b3c747f6a460679852 100644 --- a/cmds/idmap2/tests/RawPrintVisitorTests.cpp +++ b/cmds/idmap2/tests/RawPrintVisitorTests.cpp @@ -40,15 +40,14 @@ TEST(RawPrintVisitorTests, CreateRawPrintVisitor) { std::unique_ptr overlay_apk = ApkAssets::Load(overlay_apk_path); ASSERT_THAT(overlay_apk, NotNull()); - std::stringstream error; - std::unique_ptr idmap = + const auto idmap = Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk, - PolicyFlags::POLICY_PUBLIC, /* enforce_overlayable */ true, error); - ASSERT_THAT(idmap, NotNull()); + PolicyFlags::POLICY_PUBLIC, /* enforce_overlayable */ true); + ASSERT_TRUE(idmap); std::stringstream stream; RawPrintVisitor visitor(stream); - idmap->accept(&visitor); + (*idmap)->accept(&visitor); ASSERT_NE(stream.str().find("00000000: 504d4449 magic\n"), std::string::npos); ASSERT_NE(stream.str().find("00000004: 00000001 version\n"), std::string::npos); @@ -64,13 +63,12 @@ TEST(RawPrintVisitorTests, CreateRawPrintVisitorWithoutAccessToApks) { std::string raw(reinterpret_cast(idmap_raw_data), idmap_raw_data_len); std::istringstream raw_stream(raw); - std::stringstream error; - std::unique_ptr idmap = Idmap::FromBinaryStream(raw_stream, error); - ASSERT_THAT(idmap, NotNull()); + const auto idmap = Idmap::FromBinaryStream(raw_stream); + ASSERT_TRUE(idmap); std::stringstream stream; RawPrintVisitor visitor(stream); - idmap->accept(&visitor); + (*idmap)->accept(&visitor); ASSERT_NE(stream.str().find("00000000: 504d4449 magic\n"), std::string::npos); ASSERT_NE(stream.str().find("00000004: 00000001 version\n"), std::string::npos); diff --git a/cmds/idmap2/tests/data/overlay/AndroidManifest.xml b/cmds/idmap2/tests/data/overlay/AndroidManifest.xml index a7767a6d35e6c58d174b0ba34b518c23ebabf108..619bb6ce0f25132f805463758b8ba3618deb3a21 100644 --- a/cmds/idmap2/tests/data/overlay/AndroidManifest.xml +++ b/cmds/idmap2/tests/data/overlay/AndroidManifest.xml @@ -16,6 +16,7 @@ + diff --git a/cmds/idmap2/tests/data/signature-overlay/AndroidManifest.xml b/cmds/idmap2/tests/data/signature-overlay/AndroidManifest.xml index 5dacebded5297521c0e523fb3e480acf13714d0e..9e6a4536cb51cd42ee35249abce637dcc640d5a3 100644 --- a/cmds/idmap2/tests/data/signature-overlay/AndroidManifest.xml +++ b/cmds/idmap2/tests/data/signature-overlay/AndroidManifest.xml @@ -16,6 +16,7 @@ + diff --git a/cmds/idmap2/tests/data/system-overlay-invalid/AndroidManifest.xml b/cmds/idmap2/tests/data/system-overlay-invalid/AndroidManifest.xml index ae687d375e7f8e0a31f6f37af154fa263009f053..c7b652cdb287426411f894d7b4e8c1eadc2ca571 100644 --- a/cmds/idmap2/tests/data/system-overlay-invalid/AndroidManifest.xml +++ b/cmds/idmap2/tests/data/system-overlay-invalid/AndroidManifest.xml @@ -16,6 +16,7 @@ + diff --git a/cmds/idmap2/tests/data/system-overlay/AndroidManifest.xml b/cmds/idmap2/tests/data/system-overlay/AndroidManifest.xml index 5dacebded5297521c0e523fb3e480acf13714d0e..9e6a4536cb51cd42ee35249abce637dcc640d5a3 100644 --- a/cmds/idmap2/tests/data/system-overlay/AndroidManifest.xml +++ b/cmds/idmap2/tests/data/system-overlay/AndroidManifest.xml @@ -16,6 +16,7 @@ + diff --git a/cmds/statsd/src/atom_field_options.proto b/cmds/statsd/src/atom_field_options.proto index 2a3eee2a7e1803ea077df6fea564212c0f28530e..16c936c41559cb16dc8c98e2134ea4a0737b89e3 100644 --- a/cmds/statsd/src/atom_field_options.proto +++ b/cmds/statsd/src/atom_field_options.proto @@ -84,4 +84,6 @@ extend google.protobuf.FieldOptions { optional LogMode log_mode = 50002 [default = MODE_AUTOMATIC]; optional bool allow_from_any_uid = 50003 [default = false]; + + optional string log_from_module = 50004; } \ No newline at end of file diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto index 1dbbbc5595ba42ccbdf700c99d332f96e35a0e9c..c2b81e44e5d92754d0af258cac4408dfc90fd3da 100644 --- a/cmds/statsd/src/atoms.proto +++ b/cmds/statsd/src/atoms.proto @@ -40,6 +40,7 @@ import "frameworks/base/core/proto/android/server/job/enums.proto"; import "frameworks/base/core/proto/android/server/location/enums.proto"; import "frameworks/base/core/proto/android/service/procstats_enum.proto"; import "frameworks/base/core/proto/android/service/usb.proto"; +import "frameworks/base/core/proto/android/stats/connectivity/network_stack.proto"; import "frameworks/base/core/proto/android/stats/enums.proto"; import "frameworks/base/core/proto/android/stats/docsui/docsui_enums.proto"; import "frameworks/base/core/proto/android/stats/devicepolicy/device_policy.proto"; @@ -252,6 +253,7 @@ message Atom { StyleUIChanged style_ui_changed = 179; PrivacyIndicatorsInteracted privacy_indicators_interacted = 180; AppInstallOnExternalStorageReported app_install_on_external_storage_reported = 181; + NetworkStackReported network_stack_reported = 182; } // Pulled events will start at field 10000. @@ -2065,6 +2067,9 @@ message BluetoothClassicPairingEventReported { // HCI reason code associated with this event // Default: STATUS_UNKNOWN optional android.bluetooth.hci.StatusEnum reason_code = 6; + // A status value related to this specific event + // Default: 0 + optional int64 event_value = 7; } /** @@ -2428,6 +2433,8 @@ message TouchEventReported { optional float latency_mean_micros = 3; // Standard deviation optional float latency_stdev_micros = 4; + // Number of touch events (input_event) in this report + optional int32 count = 5; } /** @@ -3419,7 +3426,6 @@ message HiddenApiUsed { * - When user clicks privacy chip * - How does the user exit the Privacy Dialog * Logged from: - * packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyDialog.kt * packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java */ message PrivacyIndicatorsInteracted { @@ -5849,3 +5855,14 @@ message SystemIonHeapSize { // Size of the system ion heap in bytes. optional int64 size_in_bytes = 1; } + +/** + * Push network stack events. + * + * Log from: + * frameworks/base/packages/NetworkStack/ + */ +message NetworkStackReported { + optional int32 eventId = 1; + optional android.stats.connectivity.NetworkStackEventData network_stack_event = 2 [(log_mode) = MODE_BYTES]; +} diff --git a/config/boot-image-profile.txt b/config/boot-image-profile.txt index d740961cac2a8b08016ba001e1301fe67816d3d0..a3776c4b4d32e39e039c09a151be4ad082a57274 100644 --- a/config/boot-image-profile.txt +++ b/config/boot-image-profile.txt @@ -4759,7 +4759,6 @@ HPLandroid/os/IDeviceIdleController$Stub$Proxy;->addPowerSaveTempWhitelistAppFor HPLandroid/os/IDeviceIdleController$Stub$Proxy;->addPowerSaveTempWhitelistAppForSms(Ljava/lang/String;ILjava/lang/String;)J HPLandroid/os/IDeviceIdleController$Stub;->getDefaultTransactionName(I)Ljava/lang/String; HPLandroid/os/IDeviceIdleController$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z -HPLandroid/os/IDynamicAndroidService$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z HPLandroid/os/IHardwarePropertiesManager$Stub;->getDefaultTransactionName(I)Ljava/lang/String; HPLandroid/os/IHardwarePropertiesManager$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z HPLandroid/os/IInstalld$Stub$Proxy;->clearAppData(Ljava/lang/String;Ljava/lang/String;IIJ)V @@ -5081,6 +5080,7 @@ HPLandroid/os/health/HealthStatsWriter;->writeLongsMap(Landroid/os/Parcel;Landro HPLandroid/os/health/HealthStatsWriter;->writeParcelableMap(Landroid/os/Parcel;Landroid/util/ArrayMap;)V HPLandroid/os/health/TimerStat;->(IJ)V HPLandroid/os/health/TimerStat;->writeToParcel(Landroid/os/Parcel;I)V +HPLandroid/os/image/IDynamicSystemService$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z HPLandroid/os/storage/IStorageEventListener$Stub$Proxy;->onStorageStateChanged(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V HPLandroid/os/storage/IStorageManager$Stub$Proxy;->allocateBytes(Ljava/lang/String;JILjava/lang/String;)V HPLandroid/os/storage/IStorageManager$Stub$Proxy;->changeEncryptionPassword(ILjava/lang/String;)I @@ -24027,7 +24027,6 @@ HSPLandroid/os/IDeviceIdleController$Stub$Proxy;->isPowerSaveWhitelistApp(Ljava/ HSPLandroid/os/IDeviceIdleController$Stub;->()V HSPLandroid/os/IDeviceIdleController$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IDeviceIdleController; HSPLandroid/os/IDumpstate$Stub;->()V -HSPLandroid/os/IDynamicAndroidService$Stub;->()V HSPLandroid/os/IExternalVibratorService$Stub;->()V HSPLandroid/os/IHardwarePropertiesManager$Stub;->()V HSPLandroid/os/IIncidentCompanion$Stub;->()V @@ -24837,6 +24836,7 @@ HSPLandroid/os/ZygoteProcess;->waitForConnectionToZygote(Ljava/lang/String;)V HSPLandroid/os/ZygoteProcess;->zygoteSendArgsAndGetResult(Landroid/os/ZygoteProcess$ZygoteState;ZLjava/util/ArrayList;)Landroid/os/Process$ProcessStartResult; HSPLandroid/os/health/HealthStatsParceler$1;->()V HSPLandroid/os/health/TimerStat$1;->()V +HSPLandroid/os/image/IDynamicSystemService$Stub;->()V HSPLandroid/os/storage/IStorageEventListener$Stub$Proxy;->asBinder()Landroid/os/IBinder; HSPLandroid/os/storage/IStorageEventListener$Stub;->asBinder()Landroid/os/IBinder; HSPLandroid/os/storage/IStorageManager$Stub$Proxy;->getVolumeList(ILjava/lang/String;I)[Landroid/os/storage/StorageVolume; @@ -47386,7 +47386,6 @@ Landroid/os/DeviceIdleManager; Landroid/os/DropBoxManager$Entry$1; Landroid/os/DropBoxManager$Entry; Landroid/os/DropBoxManager; -Landroid/os/DynamicAndroidManager; Landroid/os/Environment$UserEnvironment; Landroid/os/Environment; Landroid/os/EventLogTags; @@ -47428,8 +47427,6 @@ Landroid/os/IDeviceIdleController$Stub; Landroid/os/IDeviceIdleController; Landroid/os/IDumpstate$Stub; Landroid/os/IDumpstate; -Landroid/os/IDynamicAndroidService$Stub; -Landroid/os/IDynamicAndroidService; Landroid/os/IExternalVibratorService$Stub; Landroid/os/IExternalVibratorService; Landroid/os/IHardwarePropertiesManager$Stub; @@ -47689,6 +47686,10 @@ Landroid/os/health/HealthStatsWriter; Landroid/os/health/SystemHealthManager; Landroid/os/health/TimerStat$1; Landroid/os/health/TimerStat; +Landroid/os/image/DynamicSystemClient; +Landroid/os/image/DynamicSystemManager; +Landroid/os/image/IDynamicSystemService$Stub; +Landroid/os/image/IDynamicSystemService; Landroid/os/storage/DiskInfo; Landroid/os/storage/IObbActionListener$Stub; Landroid/os/storage/IObbActionListener; diff --git a/config/hiddenapi-greylist.txt b/config/hiddenapi-greylist.txt index b3f003730c53d3a933507c0223c47dafd29f56c6..95bdc364998f65748db14411f9d0bbcfcd105b59 100644 --- a/config/hiddenapi-greylist.txt +++ b/config/hiddenapi-greylist.txt @@ -123,7 +123,6 @@ Landroid/bluetooth/IBluetoothStateChangeCallback$Stub;->()V Landroid/companion/ICompanionDeviceDiscoveryService$Stub;->()V Landroid/companion/ICompanionDeviceDiscoveryServiceCallback;->onDeviceSelected(Ljava/lang/String;ILjava/lang/String;)V Landroid/companion/ICompanionDeviceDiscoveryServiceCallback;->onDeviceSelectionCancel()V -Landroid/companion/IFindDeviceCallback;->onSuccess(Landroid/app/PendingIntent;)V Landroid/content/IClipboard$Stub$Proxy;->(Landroid/os/IBinder;)V Landroid/content/IClipboard$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/IClipboard; Landroid/content/IContentService$Stub$Proxy;->(Landroid/os/IBinder;)V @@ -198,8 +197,6 @@ Landroid/database/IContentObserver$Stub;->asInterface(Landroid/os/IBinder;)Landr Landroid/database/IContentObserver;->onChange(ZLandroid/net/Uri;I)V Landroid/database/sqlite/SQLiteConnectionPool;->$assertionsDisabled:Z Landroid/database/sqlite/SQLiteDatabase;->$assertionsDisabled:Z -Landroid/filterfw/GraphEnvironment;->addReferences([Ljava/lang/Object;)V -Landroid/hardware/camera2/utils/HashCodeHelpers;->hashCode([I)I Landroid/hardware/display/IDisplayManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/hardware/display/IDisplayManager; Landroid/hardware/fingerprint/IFingerprintService$Stub$Proxy;->(Landroid/os/IBinder;)V Landroid/hardware/fingerprint/IFingerprintService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/hardware/fingerprint/IFingerprintService; @@ -211,8 +208,6 @@ Landroid/hardware/location/IActivityRecognitionHardwareClient$Stub;->()V Landroid/hardware/location/IContextHubService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/hardware/location/IContextHubService; Landroid/hardware/usb/IUsbManager$Stub$Proxy;->(Landroid/os/IBinder;)V Landroid/hardware/usb/IUsbManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/hardware/usb/IUsbManager; -Landroid/inputmethodservice/IInputMethodSessionWrapper;->mCaller:Lcom/android/internal/os/HandlerCaller; -Landroid/inputmethodservice/IInputMethodWrapper;->mCaller:Lcom/android/internal/os/HandlerCaller; Landroid/location/ICountryDetector$Stub;->asInterface(Landroid/os/IBinder;)Landroid/location/ICountryDetector; Landroid/location/ICountryListener$Stub;->()V Landroid/location/IGeocodeProvider$Stub;->()V @@ -230,7 +225,6 @@ Landroid/location/LocationManager$ListenerTransport;->(Landroid/location/L Landroid/Manifest$permission;->CAPTURE_SECURE_VIDEO_OUTPUT:Ljava/lang/String; Landroid/Manifest$permission;->CAPTURE_VIDEO_OUTPUT:Ljava/lang/String; Landroid/Manifest$permission;->READ_FRAME_BUFFER:Ljava/lang/String; -Landroid/media/effect/SingleFilterEffect;->(Landroid/media/effect/EffectContext;Ljava/lang/String;Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/Object;)V Landroid/media/IAudioRoutesObserver$Stub;->()V Landroid/media/IAudioService$Stub$Proxy;->(Landroid/os/IBinder;)V Landroid/media/IAudioService$Stub;->()V @@ -266,7 +260,6 @@ Landroid/net/InterfaceConfiguration;->()V Landroid/net/LinkProperties$ProvisioningChange;->values()[Landroid/net/LinkProperties$ProvisioningChange; Landroid/net/MobileLinkQualityInfo;->()V Landroid/net/nsd/INsdManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/nsd/INsdManager; -Landroid/net/nsd/INsdManager;->getMessenger()Landroid/os/Messenger; Landroid/net/sip/ISipSession$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/sip/ISipSession; Landroid/net/SntpClient;->()V Landroid/net/wifi/IWifiManager$Stub$Proxy;->(Landroid/os/IBinder;)V @@ -295,7 +288,6 @@ Landroid/os/IPowerManager$Stub$Proxy;->isLightDeviceIdleMode()Z Landroid/os/IPowerManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IPowerManager; Landroid/os/IPowerManager$Stub;->TRANSACTION_acquireWakeLock:I Landroid/os/IPowerManager$Stub;->TRANSACTION_goToSleep:I -Landroid/os/IPowerManager;->releaseWakeLock(Landroid/os/IBinder;I)V Landroid/os/IRecoverySystem$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IRecoverySystem; Landroid/os/IRemoteCallback$Stub;->()V Landroid/os/IUpdateEngine$Stub;->()V @@ -310,7 +302,6 @@ Landroid/os/storage/IObbActionListener$Stub;->()V Landroid/os/storage/IStorageManager$Stub$Proxy;->(Landroid/os/IBinder;)V Landroid/os/storage/IStorageManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/storage/IStorageManager; Landroid/os/storage/StorageEventListener;->()V -Landroid/preference/PreferenceGroupAdapter;->getItem(I)Landroid/preference/Preference; Landroid/R$styleable;->ActionBar:[I Landroid/R$styleable;->ActionBar_background:I Landroid/R$styleable;->ActionBar_backgroundSplit:I @@ -576,17 +567,6 @@ Landroid/R$styleable;->Window:[I Landroid/R$styleable;->Window_windowBackground:I Landroid/R$styleable;->Window_windowFrame:I Landroid/security/IKeyChainService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/security/IKeyChainService; -Landroid/security/keymaster/KeymasterBlobArgument;->(ILandroid/os/Parcel;)V -Landroid/security/keymaster/KeymasterBlobArgument;->(I[B)V -Landroid/security/keymaster/KeymasterBlobArgument;->blob:[B -Landroid/security/keymaster/KeymasterBooleanArgument;->(ILandroid/os/Parcel;)V -Landroid/security/keymaster/KeymasterDateArgument;->(ILandroid/os/Parcel;)V -Landroid/security/keymaster/KeymasterIntArgument;->(II)V -Landroid/security/keymaster/KeymasterIntArgument;->(ILandroid/os/Parcel;)V -Landroid/security/keymaster/KeymasterIntArgument;->value:I -Landroid/security/keymaster/KeymasterLongArgument;->(IJ)V -Landroid/security/keymaster/KeymasterLongArgument;->(ILandroid/os/Parcel;)V -Landroid/security/keymaster/KeymasterLongArgument;->value:J Landroid/security/keystore/IKeystoreService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/security/keystore/IKeystoreService; Landroid/security/keystore/IKeystoreService;->clear_uid(J)I Landroid/security/keystore/IKeystoreService;->del(Ljava/lang/String;I)I @@ -599,24 +579,17 @@ Landroid/security/keystore/IKeystoreService;->list(Ljava/lang/String;I)[Ljava/la Landroid/security/keystore/IKeystoreService;->reset()I Landroid/security/keystore/IKeystoreService;->ungrant(Ljava/lang/String;I)I Landroid/service/dreams/IDreamManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/service/dreams/IDreamManager; -Landroid/service/dreams/IDreamManager;->awaken()V -Landroid/service/dreams/IDreamManager;->dream()V Landroid/service/dreams/IDreamManager;->getDreamComponents()[Landroid/content/ComponentName; -Landroid/service/dreams/IDreamManager;->isDreaming()Z -Landroid/service/dreams/IDreamManager;->setDreamComponents([Landroid/content/ComponentName;)V Landroid/service/euicc/IEuiccService$Stub;->()V Landroid/service/notification/INotificationListener$Stub;->()V Landroid/service/persistentdata/IPersistentDataBlockService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/service/persistentdata/IPersistentDataBlockService; Landroid/service/vr/IVrManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/service/vr/IVrManager; Landroid/service/wallpaper/IWallpaperConnection$Stub;->()V Landroid/service/wallpaper/IWallpaperService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/service/wallpaper/IWallpaperService; -Landroid/telecom/Log;->i(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/Object;)V -Landroid/telecom/Log;->w(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/Object;)V Landroid/telephony/ims/compat/feature/MMTelFeature;->()V Landroid/telephony/ims/compat/ImsService;->()V Landroid/telephony/ims/compat/stub/ImsCallSessionImplBase;->()V Landroid/telephony/ims/compat/stub/ImsUtListenerImplBase;->()V -Landroid/telephony/JapanesePhoneNumberFormatter;->format(Landroid/text/Editable;)V Landroid/telephony/mbms/IMbmsStreamingSessionCallback$Stub;->()V Landroid/telephony/mbms/IStreamingServiceCallback$Stub;->()V Landroid/telephony/mbms/vendor/IMbmsStreamingService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/telephony/mbms/vendor/IMbmsStreamingService; @@ -646,14 +619,8 @@ Landroid/telephony/SmsCbMessage;->isCmasMessage()Z Landroid/telephony/SmsCbMessage;->isEmergencyMessage()Z Landroid/telephony/TelephonyManager$MultiSimVariants;->values()[Landroid/telephony/TelephonyManager$MultiSimVariants; Landroid/util/Singleton;->()V -Landroid/util/XmlPullAttributes;->(Lorg/xmlpull/v1/XmlPullParser;)V -Landroid/util/XmlPullAttributes;->mParser:Lorg/xmlpull/v1/XmlPullParser; -Landroid/view/accessibility/IAccessibilityInteractionConnectionCallback;->setFindAccessibilityNodeInfoResult(Landroid/view/accessibility/AccessibilityNodeInfo;I)V -Landroid/view/accessibility/IAccessibilityInteractionConnectionCallback;->setFindAccessibilityNodeInfosResult(Ljava/util/List;I)V -Landroid/view/accessibility/IAccessibilityInteractionConnectionCallback;->setPerformAccessibilityActionResult(ZI)V Landroid/view/accessibility/IAccessibilityManager$Stub$Proxy;->(Landroid/os/IBinder;)V Landroid/view/accessibility/IAccessibilityManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/view/accessibility/IAccessibilityManager; -Landroid/view/accessibility/IAccessibilityManager;->getEnabledAccessibilityServiceList(II)Ljava/util/List; Landroid/view/AccessibilityIterators$AbstractTextSegmentIterator;->()V Landroid/view/autofill/IAutoFillManager$Stub$Proxy;->(Landroid/os/IBinder;)V Landroid/view/autofill/IAutoFillManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/view/autofill/IAutoFillManager; @@ -711,11 +678,6 @@ Lcom/android/ims/internal/uce/presence/IPresenceService$Stub;->()V Lcom/android/ims/internal/uce/uceservice/IUceListener$Stub;->()V Lcom/android/ims/internal/uce/uceservice/IUceService$Stub;->()V Lcom/android/internal/app/AlertActivity;->()V -Lcom/android/internal/app/AlertActivity;->mAlert:Lcom/android/internal/app/AlertController; -Lcom/android/internal/app/AlertActivity;->mAlertParams:Lcom/android/internal/app/AlertController$AlertParams; -Lcom/android/internal/app/AlertActivity;->setupAlert()V -Lcom/android/internal/app/AssistUtils;->(Landroid/content/Context;)V -Lcom/android/internal/app/AssistUtils;->getAssistComponentForUser(I)Landroid/content/ComponentName; Lcom/android/internal/app/ChooserActivity;->()V Lcom/android/internal/app/IAppOpsCallback$Stub;->()V Lcom/android/internal/app/IAppOpsService$Stub$Proxy;->(Landroid/os/IBinder;)V @@ -743,42 +705,13 @@ Lcom/android/internal/app/IAppOpsService$Stub;->TRANSACTION_stopWatchingMode:I Lcom/android/internal/app/IBatteryStats$Stub$Proxy;->(Landroid/os/IBinder;)V Lcom/android/internal/app/IBatteryStats$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/app/IBatteryStats; Lcom/android/internal/app/IMediaContainerService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/app/IMediaContainerService; -Lcom/android/internal/app/IntentForwarderActivity;->TAG:Ljava/lang/String; Lcom/android/internal/app/IVoiceInteractionManagerService$Stub$Proxy;->showSessionFromSession(Landroid/os/IBinder;Landroid/os/Bundle;I)Z Lcom/android/internal/app/IVoiceInteractionManagerService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/app/IVoiceInteractionManagerService; -Lcom/android/internal/app/LocaleHelper$LocaleInfoComparator;->(Ljava/util/Locale;Z)V -Lcom/android/internal/app/LocaleHelper$LocaleInfoComparator;->compare(Lcom/android/internal/app/LocaleStore$LocaleInfo;Lcom/android/internal/app/LocaleStore$LocaleInfo;)I -Lcom/android/internal/app/LocaleHelper;->getDisplayCountry(Ljava/util/Locale;Ljava/util/Locale;)Ljava/lang/String; -Lcom/android/internal/app/LocaleHelper;->getDisplayName(Ljava/util/Locale;Ljava/util/Locale;Z)Ljava/lang/String; -Lcom/android/internal/app/LocaleHelper;->normalizeForSearch(Ljava/lang/String;Ljava/util/Locale;)Ljava/lang/String; -Lcom/android/internal/app/LocalePicker$LocaleInfo;->getLocale()Ljava/util/Locale; -Lcom/android/internal/app/LocalePicker;->getLocales()Landroid/os/LocaleList; -Lcom/android/internal/app/LocalePicker;->updateLocale(Ljava/util/Locale;)V -Lcom/android/internal/app/LocalePicker;->updateLocales(Landroid/os/LocaleList;)V -Lcom/android/internal/app/LocaleStore$LocaleInfo;->getFullNameInUiLanguage()Ljava/lang/String; -Lcom/android/internal/app/LocaleStore$LocaleInfo;->getFullNameNative()Ljava/lang/String; -Lcom/android/internal/app/LocaleStore$LocaleInfo;->getId()Ljava/lang/String; -Lcom/android/internal/app/LocaleStore$LocaleInfo;->getLocale()Ljava/util/Locale; -Lcom/android/internal/app/LocaleStore$LocaleInfo;->getParent()Ljava/util/Locale; -Lcom/android/internal/app/LocaleStore;->fillCache(Landroid/content/Context;)V -Lcom/android/internal/app/LocaleStore;->getLevelLocales(Landroid/content/Context;Ljava/util/Set;Lcom/android/internal/app/LocaleStore$LocaleInfo;Z)Ljava/util/Set; -Lcom/android/internal/app/LocaleStore;->getLocaleInfo(Ljava/util/Locale;)Lcom/android/internal/app/LocaleStore$LocaleInfo; -Lcom/android/internal/app/NetInitiatedActivity;->handleNIVerify(Landroid/content/Intent;)V Lcom/android/internal/app/ResolverActivity;->()V -Lcom/android/internal/app/ResolverActivity;->mAdapter:Lcom/android/internal/app/ResolverActivity$ResolveListAdapter; -Lcom/android/internal/app/ResolverActivity;->mPm:Landroid/content/pm/PackageManager; -Lcom/android/internal/app/ResolverActivity;->onCreate(Landroid/os/Bundle;Landroid/content/Intent;Ljava/lang/CharSequence;[Landroid/content/Intent;Ljava/util/List;Z)V -Lcom/android/internal/app/WindowDecorActionBar$TabImpl;->mCallback:Landroid/app/ActionBar$TabListener; -Lcom/android/internal/app/WindowDecorActionBar;->mTabScrollView:Lcom/android/internal/widget/ScrollingTabContainerView; -Lcom/android/internal/app/WindowDecorActionBar;->setShowHideAnimationEnabled(Z)V Lcom/android/internal/appwidget/IAppWidgetService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/appwidget/IAppWidgetService; Lcom/android/internal/appwidget/IAppWidgetService$Stub;->TRANSACTION_bindAppWidgetId:I Lcom/android/internal/backup/IBackupTransport$Stub;->()V Lcom/android/internal/content/PackageMonitor;->()V -Lcom/android/internal/database/SortCursor;->([Landroid/database/Cursor;Ljava/lang/String;)V -Lcom/android/internal/database/SortCursor;->mCursor:Landroid/database/Cursor; -Lcom/android/internal/database/SortCursor;->mCursors:[Landroid/database/Cursor; -Lcom/android/internal/http/HttpDateTime;->parse(Ljava/lang/String;)J Lcom/android/internal/location/GpsNetInitiatedHandler$GpsNiNotification;->()V Lcom/android/internal/location/GpsNetInitiatedHandler$GpsNiNotification;->requestorId:Ljava/lang/String; Lcom/android/internal/location/GpsNetInitiatedHandler$GpsNiNotification;->requestorIdEncoding:I @@ -797,48 +730,11 @@ Lcom/android/internal/location/ILocationProviderManager$Stub;->asInterface(Landr Lcom/android/internal/logging/MetricsLogger;->()V Lcom/android/internal/net/LegacyVpnInfo;->()V Lcom/android/internal/net/VpnConfig;->()V -Lcom/android/internal/os/AndroidPrintStream;->(ILjava/lang/String;)V Lcom/android/internal/os/BaseCommand;->()V -Lcom/android/internal/os/BaseCommand;->mArgs:Landroid/os/ShellCommand; Lcom/android/internal/os/BatterySipper$DrainType;->values()[Lcom/android/internal/os/BatterySipper$DrainType; -Lcom/android/internal/os/BinderInternal;->getContextObject()Landroid/os/IBinder; -Lcom/android/internal/os/BinderInternal;->handleGc()V -Lcom/android/internal/os/ClassLoaderFactory;->createClassloaderNamespace(Ljava/lang/ClassLoader;ILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;)Ljava/lang/String; Lcom/android/internal/os/IDropBoxManagerService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/os/IDropBoxManagerService; -Lcom/android/internal/os/ProcessCpuTracker$Stats;->name:Ljava/lang/String; -Lcom/android/internal/os/ProcessCpuTracker$Stats;->rel_stime:I -Lcom/android/internal/os/ProcessCpuTracker$Stats;->rel_uptime:J -Lcom/android/internal/os/ProcessCpuTracker$Stats;->rel_utime:I -Lcom/android/internal/os/ProcessCpuTracker;->(Z)V -Lcom/android/internal/os/ProcessCpuTracker;->countWorkingStats()I -Lcom/android/internal/os/ProcessCpuTracker;->getWorkingStats(I)Lcom/android/internal/os/ProcessCpuTracker$Stats; -Lcom/android/internal/os/ProcessCpuTracker;->update()V -Lcom/android/internal/os/RuntimeInit;->commonInit()V -Lcom/android/internal/os/RuntimeInit;->getApplicationObject()Landroid/os/IBinder; -Lcom/android/internal/os/RuntimeInit;->initialized:Z -Lcom/android/internal/os/RuntimeInit;->main([Ljava/lang/String;)V -Lcom/android/internal/os/RuntimeInit;->mApplicationObject:Landroid/os/IBinder; -Lcom/android/internal/os/ZygoteConnection;->closeSocket()V -Lcom/android/internal/os/ZygoteConnection;->mSocket:Landroid/net/LocalSocket; -Lcom/android/internal/os/ZygoteConnection;->mSocketOutStream:Ljava/io/DataOutputStream; -Lcom/android/internal/os/ZygoteConnection;->peer:Landroid/net/Credentials; -Lcom/android/internal/os/ZygoteInit;->main([Ljava/lang/String;)V -Lcom/android/internal/os/ZygoteInit;->mResources:Landroid/content/res/Resources; -Lcom/android/internal/os/ZygoteSecurityException;->(Ljava/lang/String;)V -Lcom/android/internal/policy/DecorView;->mLastBottomInset:I -Lcom/android/internal/policy/DecorView;->mLastLeftInset:I -Lcom/android/internal/policy/DecorView;->mLastRightInset:I -Lcom/android/internal/policy/DecorView;->mWindow:Lcom/android/internal/policy/PhoneWindow; Lcom/android/internal/policy/IKeyguardService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/policy/IKeyguardService; Lcom/android/internal/policy/IKeyguardStateCallback$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/policy/IKeyguardStateCallback; -Lcom/android/internal/policy/PhoneFallbackEventHandler;->(Landroid/content/Context;)V -Lcom/android/internal/policy/PhoneFallbackEventHandler;->mContext:Landroid/content/Context; -Lcom/android/internal/policy/PhoneFallbackEventHandler;->mView:Landroid/view/View; -Lcom/android/internal/policy/PhoneFallbackEventHandler;->onKeyDown(ILandroid/view/KeyEvent;)Z -Lcom/android/internal/policy/PhoneFallbackEventHandler;->onKeyUp(ILandroid/view/KeyEvent;)Z -Lcom/android/internal/policy/PhoneFallbackEventHandler;->startCallActivity()V -Lcom/android/internal/policy/PhoneWindow;->(Landroid/content/Context;)V -Lcom/android/internal/policy/PhoneWindow;->mTitle:Ljava/lang/CharSequence; Lcom/android/internal/preference/YesNoPreference;->(Landroid/content/Context;Landroid/util/AttributeSet;)V Lcom/android/internal/R$anim;->fade_in:I Lcom/android/internal/R$array;->config_autoBrightnessLcdBacklightValues:I @@ -1589,203 +1485,15 @@ Lcom/android/internal/telephony/uicc/IccUtils;->parseToBnW([BI)Landroid/graphics Lcom/android/internal/telephony/uicc/IccUtils;->parseToRGB([BIZ)Landroid/graphics/Bitmap; Lcom/android/internal/telephony/uicc/SIMRecords$GetSpnFsmState;->values()[Lcom/android/internal/telephony/uicc/SIMRecords$GetSpnFsmState; Lcom/android/internal/textservice/ITextServicesManager$Stub$Proxy;->(Landroid/os/IBinder;)V -Lcom/android/internal/util/ArrayUtils;->appendElement(Ljava/lang/Class;[Ljava/lang/Object;Ljava/lang/Object;)[Ljava/lang/Object; -Lcom/android/internal/util/ArrayUtils;->appendInt([II)[I -Lcom/android/internal/util/ArrayUtils;->contains([II)Z -Lcom/android/internal/util/ArrayUtils;->contains([Ljava/lang/Object;Ljava/lang/Object;)Z -Lcom/android/internal/util/ArrayUtils;->emptyArray(Ljava/lang/Class;)[Ljava/lang/Object; -Lcom/android/internal/util/ArrayUtils;->indexOf([Ljava/lang/Object;Ljava/lang/Object;)I -Lcom/android/internal/util/ArrayUtils;->isEmpty([Ljava/lang/Object;)Z -Lcom/android/internal/util/ArrayUtils;->newUnpaddedArray(Ljava/lang/Class;I)[Ljava/lang/Object; -Lcom/android/internal/util/ArrayUtils;->newUnpaddedIntArray(I)[I -Lcom/android/internal/util/ArrayUtils;->removeElement(Ljava/lang/Class;[Ljava/lang/Object;Ljava/lang/Object;)[Ljava/lang/Object; -Lcom/android/internal/util/BitwiseInputStream;->([B)V -Lcom/android/internal/util/BitwiseInputStream;->available()I -Lcom/android/internal/util/BitwiseInputStream;->read(I)I -Lcom/android/internal/util/BitwiseInputStream;->readByteArray(I)[B -Lcom/android/internal/util/BitwiseInputStream;->skip(I)V -Lcom/android/internal/util/BitwiseOutputStream;->(I)V -Lcom/android/internal/util/BitwiseOutputStream;->toByteArray()[B -Lcom/android/internal/util/BitwiseOutputStream;->write(II)V -Lcom/android/internal/util/BitwiseOutputStream;->writeByteArray(I[B)V -Lcom/android/internal/util/CharSequences;->compareToIgnoreCase(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)I -Lcom/android/internal/util/CharSequences;->equals(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)Z -Lcom/android/internal/util/FastMath;->round(F)I -Lcom/android/internal/util/FastXmlSerializer;->()V -Lcom/android/internal/util/GrowingArrayUtils;->append([III)[I -Lcom/android/internal/util/GrowingArrayUtils;->append([Ljava/lang/Object;ILjava/lang/Object;)[Ljava/lang/Object; -Lcom/android/internal/util/HexDump;->hexStringToByteArray(Ljava/lang/String;)[B -Lcom/android/internal/util/HexDump;->toHexString(I)Ljava/lang/String; -Lcom/android/internal/util/HexDump;->toHexString([B)Ljava/lang/String; -Lcom/android/internal/util/HexDump;->toHexString([BII)Ljava/lang/String; -Lcom/android/internal/util/HexDump;->toHexString([BZ)Ljava/lang/String; -Lcom/android/internal/util/IState;->getName()Ljava/lang/String; Lcom/android/internal/util/MemInfoReader;->()V -Lcom/android/internal/util/MemInfoReader;->getCachedSize()J -Lcom/android/internal/util/MemInfoReader;->getFreeSize()J -Lcom/android/internal/util/MemInfoReader;->getRawInfo()[J -Lcom/android/internal/util/MemInfoReader;->getTotalSize()J -Lcom/android/internal/util/MemInfoReader;->readMemInfo()V -Lcom/android/internal/util/Preconditions;->checkArgument(Z)V -Lcom/android/internal/util/Preconditions;->checkArgument(ZLjava/lang/Object;)V -Lcom/android/internal/util/Preconditions;->checkArgumentInRange(IIILjava/lang/String;)I -Lcom/android/internal/util/Preconditions;->checkNotNull(Ljava/lang/Object;)Ljava/lang/Object; -Lcom/android/internal/util/Preconditions;->checkNotNull(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; -Lcom/android/internal/util/Preconditions;->checkState(Z)V -Lcom/android/internal/util/Preconditions;->checkState(ZLjava/lang/String;)V -Lcom/android/internal/util/State;->()V -Lcom/android/internal/util/State;->enter()V -Lcom/android/internal/util/State;->exit()V -Lcom/android/internal/util/State;->getName()Ljava/lang/String; -Lcom/android/internal/util/State;->processMessage(Landroid/os/Message;)Z -Lcom/android/internal/util/StateMachine;->(Ljava/lang/String;)V -Lcom/android/internal/util/StateMachine;->(Ljava/lang/String;Landroid/os/Handler;)V -Lcom/android/internal/util/StateMachine;->(Ljava/lang/String;Landroid/os/Looper;)V -Lcom/android/internal/util/StateMachine;->dump(Ljava/io/FileDescriptor;Ljava/io/PrintWriter;[Ljava/lang/String;)V -Lcom/android/internal/util/StateMachine;->obtainMessage(III)Landroid/os/Message; -Lcom/android/internal/util/StateMachine;->obtainMessage(IIILjava/lang/Object;)Landroid/os/Message; -Lcom/android/internal/util/StateMachine;->sendMessage(I)V -Lcom/android/internal/util/StateMachine;->sendMessage(II)V -Lcom/android/internal/util/StateMachine;->sendMessage(IIILjava/lang/Object;)V -Lcom/android/internal/util/StateMachine;->sendMessage(ILjava/lang/Object;)V -Lcom/android/internal/util/StateMachine;->sendMessage(Landroid/os/Message;)V -Lcom/android/internal/view/ActionBarPolicy;->(Landroid/content/Context;)V -Lcom/android/internal/view/ActionBarPolicy;->get(Landroid/content/Context;)Lcom/android/internal/view/ActionBarPolicy; -Lcom/android/internal/view/ActionBarPolicy;->getEmbeddedMenuWidthLimit()I -Lcom/android/internal/view/ActionBarPolicy;->getMaxActionButtons()I -Lcom/android/internal/view/ActionBarPolicy;->getStackedTabMaxWidth()I -Lcom/android/internal/view/ActionBarPolicy;->getTabContainerHeight()I -Lcom/android/internal/view/ActionBarPolicy;->hasEmbeddedTabs()Z -Lcom/android/internal/view/ActionBarPolicy;->mContext:Landroid/content/Context; -Lcom/android/internal/view/ActionBarPolicy;->showsOverflowMenuButton()Z Lcom/android/internal/view/IInputMethodManager$Stub$Proxy;->(Landroid/os/IBinder;)V Lcom/android/internal/view/IInputMethodManager$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/view/IInputMethodManager; Lcom/android/internal/view/IInputMethodSession$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/view/IInputMethodSession; -Lcom/android/internal/view/InputConnectionWrapper$InputContextCallback;->dispose()V -Lcom/android/internal/view/InputConnectionWrapper$InputContextCallback;->getInstance()Lcom/android/internal/view/InputConnectionWrapper$InputContextCallback; -Lcom/android/internal/view/menu/ActionMenu;->(Landroid/content/Context;)V -Lcom/android/internal/view/menu/ActionMenuItem;->(Landroid/content/Context;IIIILjava/lang/CharSequence;)V -Lcom/android/internal/view/menu/ContextMenuBuilder;->(Landroid/content/Context;)V -Lcom/android/internal/view/menu/IconMenuItemView;->getTextAppropriateLayoutParams()Lcom/android/internal/view/menu/IconMenuView$LayoutParams; -Lcom/android/internal/view/menu/IconMenuItemView;->setIconMenuView(Lcom/android/internal/view/menu/IconMenuView;)V -Lcom/android/internal/view/menu/IconMenuItemView;->setItemInvoker(Lcom/android/internal/view/menu/MenuBuilder$ItemInvoker;)V -Lcom/android/internal/view/menu/IconMenuView$SavedState;->(Landroid/os/Parcel;)V -Lcom/android/internal/view/menu/IconMenuView;->createMoreItemView()Lcom/android/internal/view/menu/IconMenuItemView; -Lcom/android/internal/view/menu/IconMenuView;->getNumActualItemsShown()I -Lcom/android/internal/view/menu/IconMenuView;->mItemBackground:Landroid/graphics/drawable/Drawable; -Lcom/android/internal/view/menu/IconMenuView;->mMaxItems:I -Lcom/android/internal/view/menu/IconMenuView;->mMenu:Lcom/android/internal/view/menu/MenuBuilder; -Lcom/android/internal/view/menu/MenuDialogHelper;->(Lcom/android/internal/view/menu/MenuBuilder;)V -Lcom/android/internal/view/menu/MenuDialogHelper;->dismiss()V -Lcom/android/internal/view/menu/MenuDialogHelper;->show(Landroid/os/IBinder;)V -Lcom/android/internal/view/WindowManagerPolicyThread;->getLooper()Landroid/os/Looper; -Lcom/android/internal/widget/AbsActionBarView;->dismissPopupMenus()V -Lcom/android/internal/widget/ActionBarContextView;->(Landroid/content/Context;Landroid/util/AttributeSet;)V -Lcom/android/internal/widget/ActionBarOverlayLayout;->(Landroid/content/Context;Landroid/util/AttributeSet;)V -Lcom/android/internal/widget/ActionBarOverlayLayout;->setWindowCallback(Landroid/view/Window$Callback;)V -Lcom/android/internal/widget/EditableInputConnection;->(Landroid/widget/TextView;)V Lcom/android/internal/widget/ILockSettings$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/widget/ILockSettings; Lcom/android/internal/widget/IRemoteViewsFactory$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/widget/IRemoteViewsFactory; -Lcom/android/internal/widget/LinearLayoutWithDefaultTouchRecepient;->(Landroid/content/Context;)V -Lcom/android/internal/widget/LinearLayoutWithDefaultTouchRecepient;->setDefaultTouchRecepient(Landroid/view/View;)V -Lcom/android/internal/widget/LockPatternChecker;->checkPassword(Lcom/android/internal/widget/LockPatternUtils;Ljava/lang/String;ILcom/android/internal/widget/LockPatternChecker$OnCheckCallback;)Landroid/os/AsyncTask; -Lcom/android/internal/widget/LockPatternUtils$RequestThrottledException;->(I)V -Lcom/android/internal/widget/LockPatternUtils$RequestThrottledException;->getTimeoutMs()I -Lcom/android/internal/widget/LockPatternUtils;->(Landroid/content/Context;)V -Lcom/android/internal/widget/LockPatternUtils;->checkPassword(Ljava/lang/String;I)Z -Lcom/android/internal/widget/LockPatternUtils;->getActivePasswordQuality(I)I -Lcom/android/internal/widget/LockPatternUtils;->getDevicePolicyManager()Landroid/app/admin/DevicePolicyManager; -Lcom/android/internal/widget/LockPatternUtils;->getKeyguardStoredPasswordQuality(I)I -Lcom/android/internal/widget/LockPatternUtils;->getLockSettings()Lcom/android/internal/widget/ILockSettings; -Lcom/android/internal/widget/LockPatternUtils;->getOwnerInfo(I)Ljava/lang/String; -Lcom/android/internal/widget/LockPatternUtils;->getPowerButtonInstantlyLocks(I)Z -Lcom/android/internal/widget/LockPatternUtils;->getString(Ljava/lang/String;I)Ljava/lang/String; -Lcom/android/internal/widget/LockPatternUtils;->isDeviceEncryptionEnabled()Z -Lcom/android/internal/widget/LockPatternUtils;->isLockPasswordEnabled(I)Z -Lcom/android/internal/widget/LockPatternUtils;->isLockPatternEnabled(I)Z -Lcom/android/internal/widget/LockPatternUtils;->isLockScreenDisabled(I)Z -Lcom/android/internal/widget/LockPatternUtils;->isSecure(I)Z -Lcom/android/internal/widget/LockPatternUtils;->isTactileFeedbackEnabled()Z -Lcom/android/internal/widget/LockPatternUtils;->isVisiblePatternEnabled(I)Z -Lcom/android/internal/widget/LockPatternUtils;->mContentResolver:Landroid/content/ContentResolver; -Lcom/android/internal/widget/LockPatternUtils;->mContext:Landroid/content/Context; -Lcom/android/internal/widget/LockPatternUtils;->patternToHash(Ljava/util/List;)[B -Lcom/android/internal/widget/LockPatternUtils;->patternToString(Ljava/util/List;)Ljava/lang/String; -Lcom/android/internal/widget/LockPatternUtils;->reportFailedPasswordAttempt(I)V -Lcom/android/internal/widget/LockPatternUtils;->reportSuccessfulPasswordAttempt(I)V -Lcom/android/internal/widget/LockPatternUtils;->saveLockPassword(Ljava/lang/String;Ljava/lang/String;II)V -Lcom/android/internal/widget/LockPatternUtils;->setLockoutAttemptDeadline(II)J -Lcom/android/internal/widget/LockPatternUtils;->setLong(Ljava/lang/String;JI)V -Lcom/android/internal/widget/LockPatternUtils;->setOwnerInfo(Ljava/lang/String;I)V -Lcom/android/internal/widget/LockPatternUtils;->setOwnerInfoEnabled(ZI)V -Lcom/android/internal/widget/LockPatternUtils;->setString(Ljava/lang/String;Ljava/lang/String;I)V -Lcom/android/internal/widget/LockPatternView$Cell;->column:I -Lcom/android/internal/widget/LockPatternView$Cell;->row:I -Lcom/android/internal/widget/LockPatternView$DisplayMode;->Animate:Lcom/android/internal/widget/LockPatternView$DisplayMode; -Lcom/android/internal/widget/LockPatternView$DisplayMode;->Correct:Lcom/android/internal/widget/LockPatternView$DisplayMode; -Lcom/android/internal/widget/LockPatternView$DisplayMode;->Wrong:Lcom/android/internal/widget/LockPatternView$DisplayMode; -Lcom/android/internal/widget/LockPatternView$SavedState;->(Landroid/os/Parcel;)V -Lcom/android/internal/widget/LockPatternView$SavedState;->(Landroid/os/Parcelable;Ljava/lang/String;IZZZ)V -Lcom/android/internal/widget/LockPatternView;->(Landroid/content/Context;Landroid/util/AttributeSet;)V -Lcom/android/internal/widget/LockPatternView;->clearPattern()V -Lcom/android/internal/widget/LockPatternView;->disableInput()V -Lcom/android/internal/widget/LockPatternView;->enableInput()V -Lcom/android/internal/widget/LockPatternView;->getCellStates()[[Lcom/android/internal/widget/LockPatternView$CellState; -Lcom/android/internal/widget/LockPatternView;->mInStealthMode:Z -Lcom/android/internal/widget/LockPatternView;->mPaint:Landroid/graphics/Paint; -Lcom/android/internal/widget/LockPatternView;->mPathPaint:Landroid/graphics/Paint; -Lcom/android/internal/widget/LockPatternView;->mPattern:Ljava/util/ArrayList; -Lcom/android/internal/widget/LockPatternView;->mPatternDisplayMode:Lcom/android/internal/widget/LockPatternView$DisplayMode; -Lcom/android/internal/widget/LockPatternView;->mPatternInProgress:Z -Lcom/android/internal/widget/LockPatternView;->mSquareHeight:F -Lcom/android/internal/widget/LockPatternView;->mSquareWidth:F -Lcom/android/internal/widget/LockPatternView;->notifyPatternDetected()V -Lcom/android/internal/widget/LockPatternView;->setDisplayMode(Lcom/android/internal/widget/LockPatternView$DisplayMode;)V -Lcom/android/internal/widget/LockPatternView;->setInStealthMode(Z)V -Lcom/android/internal/widget/LockPatternView;->setOnPatternListener(Lcom/android/internal/widget/LockPatternView$OnPatternListener;)V -Lcom/android/internal/widget/LockPatternView;->setTactileFeedbackEnabled(Z)V Lcom/android/internal/widget/PointerLocationView$PointerState;->()V -Lcom/android/internal/widget/PointerLocationView$PointerState;->mCurDown:Z -Lcom/android/internal/widget/PointerLocationView;->mCurDown:Z -Lcom/android/internal/widget/PointerLocationView;->mCurNumPointers:I -Lcom/android/internal/widget/PointerLocationView;->mMaxNumPointers:I -Lcom/android/internal/widget/PointerLocationView;->mPointers:Ljava/util/ArrayList; -Lcom/android/internal/widget/PointerLocationView;->mPrintCoords:Z -Lcom/android/internal/widget/PreferenceImageView;->(Landroid/content/Context;Landroid/util/AttributeSet;)V -Lcom/android/internal/widget/RecyclerView$RecycledViewPool$ScrapData;->mScrapHeap:Ljava/util/ArrayList; -Lcom/android/internal/widget/ScrollBarUtils;->getThumbLength(IIII)I -Lcom/android/internal/widget/SlidingTab$Slider;->tab:Landroid/widget/ImageView; -Lcom/android/internal/widget/SlidingTab$Slider;->text:Landroid/widget/TextView; -Lcom/android/internal/widget/SlidingTab;->mAnimationDoneListener:Landroid/view/animation/Animation$AnimationListener; -Lcom/android/internal/widget/SlidingTab;->mLeftSlider:Lcom/android/internal/widget/SlidingTab$Slider; -Lcom/android/internal/widget/SlidingTab;->mRightSlider:Lcom/android/internal/widget/SlidingTab$Slider; -Lcom/android/internal/widget/SlidingTab;->onAnimationDone()V -Lcom/android/internal/widget/SlidingTab;->resetView()V -Lcom/android/internal/widget/SlidingTab;->setHoldAfterTrigger(ZZ)V -Lcom/android/internal/widget/SlidingTab;->setLeftHintText(I)V -Lcom/android/internal/widget/SlidingTab;->setLeftTabResources(IIII)V -Lcom/android/internal/widget/SlidingTab;->setOnTriggerListener(Lcom/android/internal/widget/SlidingTab$OnTriggerListener;)V -Lcom/android/internal/widget/SlidingTab;->setRightHintText(I)V -Lcom/android/internal/widget/SlidingTab;->setRightTabResources(IIII)V -Lcom/android/internal/widget/TextViewInputDisabler;->(Landroid/widget/TextView;)V -Lcom/android/internal/widget/TextViewInputDisabler;->setInputEnabled(Z)V -Lcom/android/internal/widget/ViewPager$OnPageChangeListener;->onPageScrolled(IFI)V -Lcom/android/internal/widget/ViewPager$OnPageChangeListener;->onPageScrollStateChanged(I)V -Lcom/android/internal/widget/ViewPager$OnPageChangeListener;->onPageSelected(I)V -Lcom/android/internal/widget/ViewPager;->getCurrentItem()I Lcom/android/server/net/BaseNetworkObserver;->()V -Lcom/android/server/net/NetlinkTracker;->(Ljava/lang/String;Lcom/android/server/net/NetlinkTracker$Callback;)V -Lcom/android/server/net/NetlinkTracker;->clearLinkProperties()V -Lcom/android/server/net/NetlinkTracker;->getLinkProperties()Landroid/net/LinkProperties; Lcom/android/server/ResettableTimeout$T;->(Lcom/android/server/ResettableTimeout;)V -Lcom/android/server/ResettableTimeout;->mLock:Landroid/os/ConditionVariable; -Lcom/android/server/ResettableTimeout;->mOffAt:J -Lcom/google/android/collect/Lists;->newArrayList([Ljava/lang/Object;)Ljava/util/ArrayList; -Lcom/google/android/collect/Sets;->newArraySet()Landroid/util/ArraySet; -Lcom/google/android/collect/Sets;->newArraySet([Ljava/lang/Object;)Landroid/util/ArraySet; -Lcom/google/android/collect/Sets;->newHashSet()Ljava/util/HashSet; -Lcom/google/android/collect/Sets;->newHashSet([Ljava/lang/Object;)Ljava/util/HashSet; -Lcom/google/android/collect/Sets;->newSortedSet()Ljava/util/SortedSet; Lcom/google/android/gles_jni/EGLImpl;->()V Lcom/google/android/gles_jni/GLImpl;->()V Lcom/google/android/mms/ContentType;->getAudioTypes()Ljava/util/ArrayList; @@ -2067,17 +1775,7 @@ Lcom/google/android/mms/util/SqliteWrapper;->insert(Landroid/content/Context;Lan Lcom/google/android/mms/util/SqliteWrapper;->query(Landroid/content/Context;Landroid/content/ContentResolver;Landroid/net/Uri;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)Landroid/database/Cursor; Lcom/google/android/mms/util/SqliteWrapper;->requery(Landroid/content/Context;Landroid/database/Cursor;)Z Lcom/google/android/mms/util/SqliteWrapper;->update(Landroid/content/Context;Landroid/content/ContentResolver;Landroid/net/Uri;Landroid/content/ContentValues;Ljava/lang/String;[Ljava/lang/String;)I -Lcom/google/android/util/AbstractMessageParser$Token$Type;->ACRONYM:Lcom/google/android/util/AbstractMessageParser$Token$Type; -Lcom/google/android/util/AbstractMessageParser$Token$Type;->FLICKR:Lcom/google/android/util/AbstractMessageParser$Token$Type; -Lcom/google/android/util/AbstractMessageParser$Token$Type;->FORMAT:Lcom/google/android/util/AbstractMessageParser$Token$Type; -Lcom/google/android/util/AbstractMessageParser$Token$Type;->GOOGLE_VIDEO:Lcom/google/android/util/AbstractMessageParser$Token$Type; -Lcom/google/android/util/AbstractMessageParser$Token$Type;->HTML:Lcom/google/android/util/AbstractMessageParser$Token$Type; -Lcom/google/android/util/AbstractMessageParser$Token$Type;->LINK:Lcom/google/android/util/AbstractMessageParser$Token$Type; -Lcom/google/android/util/AbstractMessageParser$Token$Type;->MUSIC:Lcom/google/android/util/AbstractMessageParser$Token$Type; -Lcom/google/android/util/AbstractMessageParser$Token$Type;->PHOTO:Lcom/google/android/util/AbstractMessageParser$Token$Type; -Lcom/google/android/util/AbstractMessageParser$Token$Type;->SMILEY:Lcom/google/android/util/AbstractMessageParser$Token$Type; Lcom/google/android/util/AbstractMessageParser$Token$Type;->values()[Lcom/google/android/util/AbstractMessageParser$Token$Type; -Lcom/google/android/util/AbstractMessageParser$Token$Type;->YOUTUBE_VIDEO:Lcom/google/android/util/AbstractMessageParser$Token$Type; Lgov/nist/core/Debug;->printStackTrace(Ljava/lang/Exception;)V Lgov/nist/core/GenericObject;->()V Lgov/nist/core/GenericObject;->dbgPrint()V diff --git a/config/preloaded-classes b/config/preloaded-classes index fda028de33f36536f44f09bd75813876ac5bc235..abdbab2a29eb1b0ab4d61689c3c4d445e765b5c1 100644 --- a/config/preloaded-classes +++ b/config/preloaded-classes @@ -2724,7 +2724,6 @@ android.os.DeviceIdleManager android.os.DropBoxManager$Entry$1 android.os.DropBoxManager$Entry android.os.DropBoxManager -android.os.DynamicAndroidManager android.os.Environment$UserEnvironment android.os.Environment android.os.EventLogTags @@ -2909,6 +2908,8 @@ android.os.health.HealthStatsParceler android.os.health.SystemHealthManager android.os.health.TimerStat$1 android.os.health.TimerStat +android.os.image.DynamicSystemClient +android.os.image.DynamicSystemManager android.os.storage.IObbActionListener$Stub android.os.storage.IObbActionListener android.os.storage.IStorageManager$Stub$Proxy diff --git a/core/java/android/accessibilityservice/AccessibilityButtonController.java b/core/java/android/accessibilityservice/AccessibilityButtonController.java index a70085cbde4f132d3c16e1cf35e3b896f09e670f..af5af9cb9b172a4efd30a8f475db0821a903c13f 100644 --- a/core/java/android/accessibilityservice/AccessibilityButtonController.java +++ b/core/java/android/accessibilityservice/AccessibilityButtonController.java @@ -17,7 +17,6 @@ package android.accessibilityservice; import android.annotation.NonNull; -import android.annotation.Nullable; import android.os.Handler; import android.os.Looper; import android.os.RemoteException; @@ -76,13 +75,16 @@ public final class AccessibilityButtonController { * available to the calling service, {@code false} otherwise */ public boolean isAccessibilityButtonAvailable() { - try { - return mServiceConnection.isAccessibilityButtonAvailable(); - } catch (RemoteException re) { - Slog.w(LOG_TAG, "Failed to get accessibility button availability.", re); - re.rethrowFromSystemServer(); - return false; + if (mServiceConnection != null) { + try { + return mServiceConnection.isAccessibilityButtonAvailable(); + } catch (RemoteException re) { + Slog.w(LOG_TAG, "Failed to get accessibility button availability.", re); + re.rethrowFromSystemServer(); + return false; + } } + return false; } /** diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java index 7a0639eef8cc428327e50eb66537c79404d87433..404e52011c39dfc55244f037a931b3b4e95969e3 100644 --- a/core/java/android/app/ApplicationPackageManager.java +++ b/core/java/android/app/ApplicationPackageManager.java @@ -536,6 +536,19 @@ public class ApplicationPackageManager extends PackageManager { } } + @NonNull + @Override + public List getDeclaredSharedLibraries(@NonNull String packageName, + @InstallFlags int flags) { + try { + ParceledListSlice sharedLibraries = mPM.getDeclaredSharedLibraries( + packageName, flags, mContext.getUserId()); + return sharedLibraries != null ? sharedLibraries.getList() : Collections.emptyList(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + /** @hide */ @Override public @NonNull String getServicesSystemSharedLibraryPackageName() { diff --git a/core/java/android/app/AutomaticZenRule.java b/core/java/android/app/AutomaticZenRule.java index ec2825edebe64caf1c0073be8fc8d259b496df8e..7180c01143a5a0d39ede82d91f0f501feccaebf1 100644 --- a/core/java/android/app/AutomaticZenRule.java +++ b/core/java/android/app/AutomaticZenRule.java @@ -231,7 +231,7 @@ public final class AutomaticZenRule implements Parcelable { * Sets the zen policy. */ public void setZenPolicy(ZenPolicy zenPolicy) { - this.mZenPolicy = zenPolicy; + this.mZenPolicy = (zenPolicy == null ? null : zenPolicy.copy()); } /** diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index 5945eef52b2ce6fc606e6a27d1b918965f5ad6b5..11000df5b9936f515cc42ed6f6807cc07091bdbc 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -1090,7 +1090,6 @@ class ContextImpl extends Context { @Override public void sendBroadcastAsUserMultiplePermissions(Intent intent, UserHandle user, String[] receiverPermissions) { - warnIfCallingFromSystemProcess(); String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); try { intent.prepareToLeaveProcess(this); diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl index 15084de0d7dd5fbdea279912075369cd631af997..7884872a7ef30f028fa6737fd21b415405a90767 100644 --- a/core/java/android/app/INotificationManager.aidl +++ b/core/java/android/app/INotificationManager.aidl @@ -70,6 +70,10 @@ interface INotificationManager boolean areNotificationsEnabled(String pkg); int getPackageImportance(String pkg); + List getAllowedAssistantCapabilities(String pkg); + void allowAssistantCapability(String adjustmentType); + void disallowAssistantCapability(String adjustmentType); + boolean shouldHideSilentStatusIcons(String callingPkg); void setHideSilentStatusIcons(boolean hide); @@ -86,10 +90,10 @@ interface INotificationManager NotificationChannelGroup getPopulatedNotificationChannelGroupForPackage(String pkg, int uid, String groupId, boolean includeDeleted); void updateNotificationChannelGroupForPackage(String pkg, int uid, in NotificationChannelGroup group); void updateNotificationChannelForPackage(String pkg, int uid, in NotificationChannel channel); - NotificationChannel getNotificationChannel(String pkg, String channelId); + NotificationChannel getNotificationChannel(String callingPkg, int userId, String pkg, String channelId); NotificationChannel getNotificationChannelForPackage(String pkg, int uid, String channelId, boolean includeDeleted); void deleteNotificationChannel(String pkg, String channelId); - ParceledListSlice getNotificationChannels(String pkg); + ParceledListSlice getNotificationChannels(String callingPkg, String targetPkg, int userId); ParceledListSlice getNotificationChannelsForPackage(String pkg, int uid, boolean includeDeleted); int getNumNotificationChannelsForPackage(String pkg, int uid, boolean includeDeleted); int getDeletedChannelCount(String pkg, int uid); diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 523b2005fb7206f807eb64ad067120cbe31c6b80..d634aa5784292d8baa5c6ea3f8a11b2dfe8c03af 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -16,9 +16,12 @@ package android.app; +import static android.graphics.drawable.Icon.TYPE_BITMAP; + import static com.android.internal.util.ContrastColorUtil.satisfiesTextContrast; import android.annotation.ColorInt; +import android.annotation.DimenRes; import android.annotation.DrawableRes; import android.annotation.IdRes; import android.annotation.IntDef; @@ -8519,6 +8522,7 @@ public class Notification implements Parcelable private PendingIntent mDeleteIntent; private Icon mIcon; private int mDesiredHeight; + @DimenRes private int mDesiredHeightResId; private int mFlags; /** @@ -8545,10 +8549,11 @@ public class Notification implements Parcelable private static final int FLAG_SUPPRESS_INITIAL_NOTIFICATION = 0x00000002; private BubbleMetadata(PendingIntent expandIntent, PendingIntent deleteIntent, - Icon icon, int height) { + Icon icon, int height, @DimenRes int heightResId) { mPendingIntent = expandIntent; mIcon = icon; mDesiredHeight = height; + mDesiredHeightResId = heightResId; mDeleteIntent = deleteIntent; } @@ -8560,6 +8565,7 @@ public class Notification implements Parcelable if (in.readInt() != 0) { mDeleteIntent = PendingIntent.CREATOR.createFromParcel(in); } + mDesiredHeightResId = in.readInt(); } /** @@ -8578,17 +8584,6 @@ public class Notification implements Parcelable return mDeleteIntent; } - /** - * @return the title that will appear along with the app content defined by - * {@link #getIntent()} for this bubble. - * - * @deprecated titles are no longer required or shown. - */ - @Deprecated - public CharSequence getTitle() { - return ""; - } - /** * @return the icon that will be displayed for this bubble when it is collapsed. */ @@ -8598,13 +8593,22 @@ public class Notification implements Parcelable } /** - * @return the ideal height for the floating window that app content defined by + * @return the ideal height, in DPs, for the floating window that app content defined by * {@link #getIntent()} for this bubble. */ public int getDesiredHeight() { return mDesiredHeight; } + /** + * @return the resId of ideal height for the floating window that app content defined by + * {@link #getIntent()} for this bubble. + */ + @DimenRes + public int getDesiredHeightResId() { + return mDesiredHeightResId; + } + /** * @return whether this bubble should auto expand when it is posted. * @@ -8652,6 +8656,7 @@ public class Notification implements Parcelable if (mDeleteIntent != null) { mDeleteIntent.writeToParcel(out, 0); } + out.writeInt(mDesiredHeightResId); } private void setFlags(int flags) { @@ -8666,6 +8671,7 @@ public class Notification implements Parcelable private PendingIntent mPendingIntent; private Icon mIcon; private int mDesiredHeight; + @DimenRes private int mDesiredHeightResId; private int mFlags; private PendingIntent mDeleteIntent; @@ -8688,43 +8694,65 @@ public class Notification implements Parcelable return this; } - /** - * Sets the title that will appear along with the app content for this bubble. - * - *

A title is required and should expect to fit on a single line and make sense when - * shown with the content defined by {@link #setIntent(PendingIntent)}.

- * - * @deprecated titles are no longer required or shown. - */ - @Deprecated - public BubbleMetadata.Builder setTitle(CharSequence title) { - return this; - } - /** * Sets the icon that will represent the bubble when it is collapsed. * *

An icon is required and should be representative of the content within the bubble. * If your app produces multiple bubbles, the image should be unique for each of them. *

+ * + *

The shape of a bubble icon is adaptive and can match the device theme. + * + * If your icon is bitmap-based, you should create it using + * {@link Icon#createWithAdaptiveBitmap(Bitmap)}, otherwise this method will throw. + * + * If your icon is not bitmap-based, you should expect that the icon will be tinted. + *

*/ @NonNull public BubbleMetadata.Builder setIcon(@NonNull Icon icon) { if (icon == null) { throw new IllegalArgumentException("Bubbles require non-null icon"); } + if (icon.getType() == TYPE_BITMAP) { + throw new IllegalArgumentException("When using bitmap based icons, Bubbles " + + "require TYPE_ADAPTIVE_BITMAP, please use" + + " Icon#createWithAdaptiveBitmap instead"); + } mIcon = icon; return this; } /** - * Sets the desired height for the app content defined by + * Sets the desired height in DPs for the app content defined by * {@link #setIntent(PendingIntent)}, this height may not be respected if there is not * enough space on the screen or if the provided height is too small to be useful. + *

+ * If {@link #setDesiredHeightResId(int)} was previously called on this builder, the + * previous value set will be cleared after calling this method, and this value will + * be used instead. */ @NonNull public BubbleMetadata.Builder setDesiredHeight(int height) { mDesiredHeight = Math.max(height, 0); + mDesiredHeightResId = 0; + return this; + } + + + /** + * Sets the desired height via resId for the app content defined by + * {@link #setIntent(PendingIntent)}, this height may not be respected if there is not + * enough space on the screen or if the provided height is too small to be useful. + *

+ * If {@link #setDesiredHeight(int)} was previously called on this builder, the + * previous value set will be cleared after calling this method, and this value will + * be used instead. + */ + @NonNull + public BubbleMetadata.Builder setDesiredHeightResId(@DimenRes int heightResId) { + mDesiredHeightResId = heightResId; + mDesiredHeight = 0; return this; } @@ -8786,7 +8814,7 @@ public class Notification implements Parcelable throw new IllegalStateException("Must supply an icon for the bubble"); } BubbleMetadata data = new BubbleMetadata(mPendingIntent, mDeleteIntent, - mIcon, mDesiredHeight); + mIcon, mDesiredHeight, mDesiredHeightResId); data.setFlags(mFlags); return data; } diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java index 6a301c91bb06258d04a92dafbaa839870e4bea6c..0bec21fcda900ccaadf8c538e865c1ed2b6f2110 100644 --- a/core/java/android/app/NotificationManager.java +++ b/core/java/android/app/NotificationManager.java @@ -42,6 +42,7 @@ import android.os.ServiceManager; import android.os.StrictMode; import android.os.UserHandle; import android.provider.Settings.Global; +import android.service.notification.Adjustment; import android.service.notification.Condition; import android.service.notification.StatusBarNotification; import android.service.notification.ZenModeConfig; @@ -314,7 +315,8 @@ public class NotificationManager { * This tag should contain a localized name of the type of the zen rule provided by the * activity. */ - public static final String META_DATA_AUTOMATIC_RULE_TYPE = "android.app.automatic.ruleType"; + public static final String META_DATA_AUTOMATIC_RULE_TYPE = + "android.service.zen.automatic.ruleType"; /** * An optional {@code meta-data} tag for activities that handle @@ -324,7 +326,7 @@ public class NotificationManager { * can be created for this rule type. Omit or enter a value <= 0 to allow unlimited instances. */ public static final String META_DATA_RULE_INSTANCE_LIMIT = - "android.app.zen.automatic.ruleInstanceLimit"; + "android.service.zen.automatic.ruleInstanceLimit"; /** Value signifying that the user has not expressed a per-app visibility override value. * @hide */ @@ -715,12 +717,16 @@ public class NotificationManager { /** * Returns the notification channel settings for a given channel id. * - * The channel must belong to your package, or it will not be returned. + *

The channel must belong to your package, or to a package you are an approved notification + * delegate for (see {@link #canNotifyAsPackage(String)}), or it will not be returned. To query + * a channel as a notification delegate, call this method from a context created for that + * package (see {@link Context#createPackageContext(String, int)}).

*/ public NotificationChannel getNotificationChannel(String channelId) { INotificationManager service = getService(); try { - return service.getNotificationChannel(mContext.getPackageName(), channelId); + return service.getNotificationChannel(mContext.getOpPackageName(), + mContext.getUserId(), mContext.getPackageName(), channelId); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -728,11 +734,17 @@ public class NotificationManager { /** * Returns all notification channels belonging to the calling package. + * + *

Approved notification delegates (see {@link #canNotifyAsPackage(String)}) can query + * notification channels belonging to packages they are the delegate for. To do so, call this + * method from a context created for that package (see + * {@link Context#createPackageContext(String, int)}).

*/ public List getNotificationChannels() { INotificationManager service = getService(); try { - return service.getNotificationChannels(mContext.getPackageName()).getList(); + return service.getNotificationChannels(mContext.getOpPackageName(), + mContext.getPackageName(), mContext.getUserId()).getList(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1182,6 +1194,25 @@ public class NotificationManager { } } + /** + * Returns the list of {@link android.service.notification.Adjustment adjustment keys} that can + * be modified by the current {@link android.service.notification.NotificationAssistantService}. + * + *

Only callable by the current + * {@link android.service.notification.NotificationAssistantService}. + * See {@link #isNotificationAssistantAccessGranted(ComponentName)}

+ * @hide + */ + @SystemApi + public @NonNull @Adjustment.Keys List getAllowedAssistantCapabilities() { + INotificationManager service = getService(); + try { + return service.getAllowedAssistantCapabilities(mContext.getOpPackageName()); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + /** @hide */ public boolean isNotificationPolicyAccessGrantedForPackage(String pkg) { INotificationManager service = getService(); diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java index 4d280b76b3fa981d98a0bc03d66c3113a0b674e8..d67bfb6c9c84fb564e4fe0e0fd484c1b25cca948 100644 --- a/core/java/android/app/SystemServiceRegistry.java +++ b/core/java/android/app/SystemServiceRegistry.java @@ -131,13 +131,11 @@ import android.os.BugreportManager; import android.os.Build; import android.os.DeviceIdleManager; import android.os.DropBoxManager; -import android.os.DynamicAndroidManager; import android.os.HardwarePropertiesManager; import android.os.IBatteryPropertiesRegistrar; import android.os.IBinder; import android.os.IDeviceIdleController; import android.os.IDumpstate; -import android.os.IDynamicAndroidService; import android.os.IHardwarePropertiesManager; import android.os.IPowerManager; import android.os.IRecoverySystem; @@ -155,6 +153,8 @@ import android.os.UserHandle; import android.os.UserManager; import android.os.Vibrator; import android.os.health.SystemHealthManager; +import android.os.image.DynamicSystemManager; +import android.os.image.IDynamicSystemService; import android.os.storage.StorageManager; import android.permission.PermissionControllerManager; import android.permission.PermissionManager; @@ -1275,15 +1275,15 @@ final class SystemServiceRegistry { IRollbackManager.Stub.asInterface(b)); }}); - registerService(Context.DYNAMIC_ANDROID_SERVICE, DynamicAndroidManager.class, - new CachedServiceFetcher() { + registerService(Context.DYNAMIC_SYSTEM_SERVICE, DynamicSystemManager.class, + new CachedServiceFetcher() { @Override - public DynamicAndroidManager createService(ContextImpl ctx) + public DynamicSystemManager createService(ContextImpl ctx) throws ServiceNotFoundException { IBinder b = ServiceManager.getServiceOrThrow( - Context.DYNAMIC_ANDROID_SERVICE); - return new DynamicAndroidManager( - IDynamicAndroidService.Stub.asInterface(b)); + Context.DYNAMIC_SYSTEM_SERVICE); + return new DynamicSystemManager( + IDynamicSystemService.Stub.asInterface(b)); }}); //CHECKSTYLE:ON IndentationCheck } diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java index a929fe0f688e11e57e08ce64690a482f6f6ac88a..325a54bffbfbcf5afc7ffe5b920153c9162f8db7 100644 --- a/core/java/android/app/WallpaperManager.java +++ b/core/java/android/app/WallpaperManager.java @@ -25,6 +25,7 @@ import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SystemApi; import android.annotation.SystemService; +import android.annotation.TestApi; import android.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.ContentResolver; @@ -1666,6 +1667,7 @@ public class WallpaperManager { * * @hide */ + @TestApi @SystemApi @RequiresPermission(android.Manifest.permission.SET_WALLPAPER_COMPONENT) public boolean setWallpaperComponent(ComponentName name) { diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index 20e85e6793f15752107d5cdbaba7575591d7a386..4c05497479c05601ba7b4478c2289c2c28eb89b1 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -2226,7 +2226,6 @@ public class DevicePolicyManager { *
    *
  • {@link #PROVISIONING_MODE_FULLY_MANAGED_DEVICE}
  • *
  • {@link #PROVISIONING_MODE_MANAGED_PROFILE}
  • - *
  • {@link #PROVISIONING_MODE_MANAGED_PROFILE_ON_FULLY_MANAGED_DEVICE}
  • *
* *

The target activity may also return the account that needs to be migrated from primary @@ -2253,7 +2252,6 @@ public class DevicePolicyManager { *

    *
  • {@link #PROVISIONING_MODE_FULLY_MANAGED_DEVICE}
  • *
  • {@link #PROVISIONING_MODE_MANAGED_PROFILE}
  • - *
  • {@link #PROVISIONING_MODE_MANAGED_PROFILE_ON_FULLY_MANAGED_DEVICE}
  • *
*/ public static final String EXTRA_PROVISIONING_MODE = @@ -2269,11 +2267,6 @@ public class DevicePolicyManager { */ public static final int PROVISIONING_MODE_MANAGED_PROFILE = 2; - /** - * The provisioning mode for managed profile on a fully managed device. - */ - public static final int PROVISIONING_MODE_MANAGED_PROFILE_ON_FULLY_MANAGED_DEVICE = 3; - /** * Activity action: Starts the administrator to show policy compliance for the provisioning. */ @@ -4358,6 +4351,7 @@ public class DevicePolicyManager { /** * Disable text entry into notifications on secure keyguard screens (e.g. PIN/Pattern/Password). + * This flag has no effect starting from version {@link android.os.Build.VERSION_CODES#N} */ public static final int KEYGUARD_DISABLE_REMOTE_INPUT = 1 << 6; diff --git a/core/java/android/app/admin/PasswordMetrics.java b/core/java/android/app/admin/PasswordMetrics.java index d71d3553db7e3c195e420efaefe2f3df248f6e40..992985528fca5f435b69e1bb6983866a59b7e5bd 100644 --- a/core/java/android/app/admin/PasswordMetrics.java +++ b/core/java/android/app/admin/PasswordMetrics.java @@ -24,8 +24,12 @@ import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC; import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC; import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_COMPLEX; import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC; +import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_SOMETHING; import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; +import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD; +import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PATTERN; + import android.annotation.IntDef; import android.annotation.NonNull; import android.app.admin.DevicePolicyManager.PasswordComplexity; @@ -33,13 +37,15 @@ import android.os.Parcel; import android.os.Parcelable; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.util.Preconditions; +import com.android.internal.widget.LockPatternUtils.CredentialType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** - * A class that represents the metrics of a password that are used to decide whether or not a - * password meets the requirements. + * A class that represents the metrics of a credential that are used to decide whether or not a + * credential meets the requirements. If the credential is a pattern, only quality matters. * * {@hide} */ @@ -48,8 +54,6 @@ public class PasswordMetrics implements Parcelable { // consider it a complex PIN/password. public static final int MAX_ALLOWED_SEQUENCE = 3; - // TODO(b/120536847): refactor isActivePasswordSufficient logic so that the actual password - // quality is not overwritten public int quality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; public int length = 0; public int letters = 0; @@ -221,6 +225,25 @@ public class PasswordMetrics implements Parcelable { } }; + /** + * Returnsthe {@code PasswordMetrics} for a given credential. + * + * If the credential is a pin or a password, equivalent to {@link #computeForPassword(byte[])}. + * {@code credential} cannot be null when {@code type} is + * {@link com.android.internal.widget.LockPatternUtils#CREDENTIAL_TYPE_PASSWORD}. + */ + public static PasswordMetrics computeForCredential( + @CredentialType int type, byte[] credential) { + if (type == CREDENTIAL_TYPE_PASSWORD) { + Preconditions.checkNotNull(credential, "credential cannot be null"); + return PasswordMetrics.computeForPassword(credential); + } else if (type == CREDENTIAL_TYPE_PATTERN) { + return new PasswordMetrics(PASSWORD_QUALITY_SOMETHING); + } else /* if (type == CREDENTIAL_TYPE_NONE) */ { + return new PasswordMetrics(PASSWORD_QUALITY_UNSPECIFIED); + } + } + /** * Returns the {@code PasswordMetrics} for a given password */ @@ -233,8 +256,8 @@ public class PasswordMetrics implements Parcelable { int symbols = 0; int nonLetter = 0; final int length = password.length; - for (int i = 0; i < length; i++) { - switch (categoryChar((char) password[i])) { + for (byte b : password) { + switch (categoryChar((char) b)) { case CHAR_LOWER_CASE: letters++; lowerCase++; diff --git a/core/java/android/app/admin/SecurityLog.java b/core/java/android/app/admin/SecurityLog.java index 638657342066336f1481bdc06b2d6022f79686d5..19f4335893cbe03effbf1ba91feb4c2c34bd89fb 100644 --- a/core/java/android/app/admin/SecurityLog.java +++ b/core/java/android/app/admin/SecurityLog.java @@ -136,8 +136,11 @@ public class SecurityLog { public static final int TAG_APP_PROCESS_START = SecurityLogTags.SECURITY_APP_PROCESS_START; /** - * Indicates that keyguard has been dismissed. + * Indicates that keyguard has been dismissed. This event is only logged if the device + * has a secure keyguard. It is logged regardless of how keyguard is dismissed, including + * via PIN/pattern/password, biometrics or via a trust agent. * There is no extra payload in the log event. + * @see #TAG_KEYGUARD_DISMISS_AUTH_ATTEMPT */ public static final int TAG_KEYGUARD_DISMISSED = SecurityLogTags.SECURITY_KEYGUARD_DISMISSED; diff --git a/core/java/android/app/backup/BackupManager.java b/core/java/android/app/backup/BackupManager.java index bcc4974e4e64e40075a23f89c1d536552026ef59..25caaaa6e5ad1e6757086e758da96ea700df360c 100644 --- a/core/java/android/app/backup/BackupManager.java +++ b/core/java/android/app/backup/BackupManager.java @@ -16,6 +16,7 @@ package android.app.backup; +import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SystemApi; @@ -502,32 +503,76 @@ public class BackupManager { * @param transportComponent The identity of the transport being described. * @param name A {@link String} with the new name for the transport. This is NOT for * identification. MUST NOT be {@code null}. - * @param configurationIntent An {@link Intent} that can be passed to - * {@link Context#startActivity} in order to launch the transport's configuration UI. It may - * be {@code null} if the transport does not offer any user-facing configuration UI. + * @param configurationIntent An {@link Intent} that can be passed to {@link + * Context#startActivity} in order to launch the transport's configuration UI. It may be + * {@code null} if the transport does not offer any user-facing configuration UI. * @param currentDestinationString A {@link String} describing the destination to which the * transport is currently sending data. MUST NOT be {@code null}. - * @param dataManagementIntent An {@link Intent} that can be passed to - * {@link Context#startActivity} in order to launch the transport's data-management UI. It - * may be {@code null} if the transport does not offer any user-facing data - * management UI. + * @param dataManagementIntent An {@link Intent} that can be passed to {@link + * Context#startActivity} in order to launch the transport's data-management UI. It may be + * {@code null} if the transport does not offer any user-facing data management UI. * @param dataManagementLabel A {@link String} to be used as the label for the transport's data - * management affordance. This MUST be {@code null} when dataManagementIntent is - * {@code null} and MUST NOT be {@code null} when dataManagementIntent is not {@code null}. + * management affordance. This MUST be {@code null} when dataManagementIntent is {@code + * null} and MUST NOT be {@code null} when dataManagementIntent is not {@code null}. * @throws SecurityException If the UID of the calling process differs from the package UID of * {@code transportComponent} or if the caller does NOT have BACKUP permission. - * + * @deprecated Since Android Q, please use the variant {@link + * #updateTransportAttributes(ComponentName, String, Intent, String, Intent, CharSequence)} + * instead. * @hide */ + @Deprecated @SystemApi @RequiresPermission(android.Manifest.permission.BACKUP) public void updateTransportAttributes( - ComponentName transportComponent, - String name, + @NonNull ComponentName transportComponent, + @NonNull String name, @Nullable Intent configurationIntent, - String currentDestinationString, + @NonNull String currentDestinationString, @Nullable Intent dataManagementIntent, @Nullable String dataManagementLabel) { + updateTransportAttributes( + transportComponent, + name, + configurationIntent, + currentDestinationString, + dataManagementIntent, + (CharSequence) dataManagementLabel); + } + + /** + * Update the attributes of the transport identified by {@code transportComponent}. If the + * specified transport has not been bound at least once (for registration), this call will be + * ignored. Only the host process of the transport can change its description, otherwise a + * {@link SecurityException} will be thrown. + * + * @param transportComponent The identity of the transport being described. + * @param name A {@link String} with the new name for the transport. This is NOT for + * identification. MUST NOT be {@code null}. + * @param configurationIntent An {@link Intent} that can be passed to {@link + * Context#startActivity} in order to launch the transport's configuration UI. It may be + * {@code null} if the transport does not offer any user-facing configuration UI. + * @param currentDestinationString A {@link String} describing the destination to which the + * transport is currently sending data. MUST NOT be {@code null}. + * @param dataManagementIntent An {@link Intent} that can be passed to {@link + * Context#startActivity} in order to launch the transport's data-management UI. It may be + * {@code null} if the transport does not offer any user-facing data management UI. + * @param dataManagementLabel A {@link CharSequence} to be used as the label for the transport's + * data management affordance. This MUST be {@code null} when dataManagementIntent is {@code + * null} and MUST NOT be {@code null} when dataManagementIntent is not {@code null}. + * @throws SecurityException If the UID of the calling process differs from the package UID of + * {@code transportComponent} or if the caller does NOT have BACKUP permission. + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.BACKUP) + public void updateTransportAttributes( + @NonNull ComponentName transportComponent, + @NonNull String name, + @Nullable Intent configurationIntent, + @NonNull String currentDestinationString, + @Nullable Intent dataManagementIntent, + @Nullable CharSequence dataManagementLabel) { checkServiceBinder(); if (sService != null) { try { @@ -796,7 +841,7 @@ public class BackupManager { /** * Returns an {@link Intent} for the specified transport's configuration UI. * This value is set by {@link #updateTransportAttributes(ComponentName, String, Intent, String, - * Intent, String)}. + * Intent, CharSequence)}. * @param transportName The name of the registered transport. * @hide */ @@ -818,7 +863,7 @@ public class BackupManager { /** * Returns a {@link String} describing where the specified transport is sending data. * This value is set by {@link #updateTransportAttributes(ComponentName, String, Intent, String, - * Intent, String)}. + * Intent, CharSequence)}. * @param transportName The name of the registered transport. * @hide */ @@ -840,7 +885,7 @@ public class BackupManager { /** * Returns an {@link Intent} for the specified transport's data management UI. * This value is set by {@link #updateTransportAttributes(ComponentName, String, Intent, String, - * Intent, String)}. + * Intent, CharSequence)}. * @param transportName The name of the registered transport. * @hide */ @@ -861,23 +906,43 @@ public class BackupManager { /** * Returns a {@link String} describing what the specified transport's data management intent is - * used for. - * This value is set by {@link #updateTransportAttributes(ComponentName, String, Intent, String, - * Intent, String)}. + * used for. This value is set by {@link #updateTransportAttributes(ComponentName, String, + * Intent, String, Intent, CharSequence)}. * * @param transportName The name of the registered transport. + * @deprecated Since Android Q, please use the variant {@link + * #getDataManagementIntentLabel(String)} instead. * @hide */ + @Deprecated @SystemApi @TestApi @RequiresPermission(android.Manifest.permission.BACKUP) - public String getDataManagementLabel(String transportName) { + @Nullable + public String getDataManagementLabel(@NonNull String transportName) { + CharSequence label = getDataManagementIntentLabel(transportName); + return label == null ? null : label.toString(); + } + + /** + * Returns a {@link CharSequence} describing what the specified transport's data management + * intent is used for. This value is set by {@link #updateTransportAttributes(ComponentName, + * String, Intent, String, Intent, CharSequence)}. + * + * @param transportName The name of the registered transport. + * @hide + */ + @SystemApi + @TestApi + @RequiresPermission(android.Manifest.permission.BACKUP) + @Nullable + public CharSequence getDataManagementIntentLabel(@NonNull String transportName) { checkServiceBinder(); if (sService != null) { try { return sService.getDataManagementLabelForUser(mContext.getUserId(), transportName); } catch (RemoteException e) { - Log.e(TAG, "getDataManagementLabel() couldn't connect"); + Log.e(TAG, "getDataManagementIntentLabel() couldn't connect"); } } return null; diff --git a/core/java/android/app/backup/BackupTransport.java b/core/java/android/app/backup/BackupTransport.java index 0963594bc00e0ae817b23900656a94f2d9e807b9..c8f2ff34a70c9bb95bb61c4f2dd10dbb2325da54 100644 --- a/core/java/android/app/backup/BackupTransport.java +++ b/core/java/android/app/backup/BackupTransport.java @@ -16,6 +16,7 @@ package android.app.backup; +import android.annotation.Nullable; import android.annotation.SystemApi; import android.content.Intent; import android.content.pm.PackageInfo; @@ -164,18 +165,35 @@ public class BackupTransport { } /** - * On demand, supply a short string that can be shown to the user as the label - * on an overflow menu item used to invoked the data management UI. + * On demand, supply a short string that can be shown to the user as the label on an overflow + * menu item used to invoke the data management UI. * - * @return A string to be used as the label for the transport's data management - * affordance. If the transport supplies a data management intent, this - * method must not return {@code null}. + * @return A string to be used as the label for the transport's data management affordance. If + * the transport supplies a data management intent, this method must not return {@code + * null}. + * @deprecated Since Android Q, please use the variant {@link #dataManagementIntentLabel()} + * instead. */ + @Deprecated + @Nullable public String dataManagementLabel() { throw new UnsupportedOperationException( "Transport dataManagementLabel() not implemented"); } + /** + * On demand, supply a short CharSequence that can be shown to the user as the label on an + * overflow menu item used to invoke the data management UI. + * + * @return A CharSequence to be used as the label for the transport's data management + * affordance. If the transport supplies a data management intent, this method must not + * return {@code null}. + */ + @Nullable + public CharSequence dataManagementIntentLabel() { + return dataManagementLabel(); + } + /** * Ask the transport where, on local device storage, to keep backup state blobs. * This is per-transport so that mock transports used for testing can coexist with @@ -651,8 +669,8 @@ public class BackupTransport { } @Override - public String dataManagementLabel() { - return BackupTransport.this.dataManagementLabel(); + public CharSequence dataManagementIntentLabel() { + return BackupTransport.this.dataManagementIntentLabel(); } @Override diff --git a/core/java/android/app/backup/IBackupManager.aidl b/core/java/android/app/backup/IBackupManager.aidl index 70ecdae92652d747c87818f1dc33c3e5f5ea1a95..2dfaad759d3f2ce401a732653b3947671458283b 100644 --- a/core/java/android/app/backup/IBackupManager.aidl +++ b/core/java/android/app/backup/IBackupManager.aidl @@ -353,16 +353,16 @@ interface IBackupManager { * {@link Context#startActivity} in order to launch the transport's data-management UI. It * may be {@code null} if the transport does not offer any user-facing data * management UI. - * @param dataManagementLabel A {@link String} to be used as the label for the transport's data - * management affordance. This MUST be {@code null} when dataManagementIntent is - * {@code null} and MUST NOT be {@code null} when dataManagementIntent is not {@code null}. + * @param dataManagementLabel A {@link CharSequence} to be used as the label for the transport's + * data management affordance. This MUST be {@code null} when dataManagementIntent is {@code + * null} and MUST NOT be {@code null} when dataManagementIntent is not {@code null}. * @throws SecurityException If the UID of the calling process differs from the package UID of * {@code transportComponent} or if the caller does NOT have BACKUP permission. */ void updateTransportAttributesForUser(int userId, in ComponentName transportComponent, in String name, in Intent configurationIntent, in String currentDestinationString, - in Intent dataManagementIntent, in String dataManagementLabel); + in Intent dataManagementIntent, in CharSequence dataManagementLabel); /** * Identify the currently selected transport. Callers must hold the @@ -525,13 +525,7 @@ interface IBackupManager { * * @param userId User id for which the manage-data menu label should be reported. */ - String getDataManagementLabelForUser(int userId, String transport); - - /** - * {@link android.app.backup.IBackupManager.getDataManagementLabelForUser} for the calling user - * id. - */ - String getDataManagementLabel(String transport); + CharSequence getDataManagementLabelForUser(int userId, String transport); /** * Begin a restore session. Either or both of packageName and transportID diff --git a/core/java/android/app/prediction/AppPredictor.java b/core/java/android/app/prediction/AppPredictor.java index 3e4e8dc2db72139d7ac834f3d9829d89b8af4ca6..3f2f2090bf33deb2ecfb6f8de6515dd4e52e1526 100644 --- a/core/java/android/app/prediction/AppPredictor.java +++ b/core/java/android/app/prediction/AppPredictor.java @@ -131,14 +131,14 @@ public final class AppPredictor { * @param launchLocation The launch location where the targets are shown to the user. * @param targetIds List of {@link AppTargetId}s that are shown to the user. */ - public void notifyLocationShown(@NonNull String launchLocation, + public void notifyLaunchLocationShown(@NonNull String launchLocation, @NonNull List targetIds) { if (mIsClosed.get()) { throw new IllegalStateException("This client has already been destroyed."); } try { - mPredictionManager.notifyLocationShown(mSessionId, launchLocation, + mPredictionManager.notifyLaunchLocationShown(mSessionId, launchLocation, new ParceledListSlice<>(targetIds)); } catch (RemoteException e) { Log.e(TAG, "Failed to notify location shown event", e); diff --git a/core/java/android/app/prediction/AppTarget.java b/core/java/android/app/prediction/AppTarget.java index bb1b96ce5f00f41597fd16f75bf161b2d78a1857..826c149b2e05f729adc0ebb10bd082b5755827e1 100644 --- a/core/java/android/app/prediction/AppTarget.java +++ b/core/java/android/app/prediction/AppTarget.java @@ -43,20 +43,13 @@ public final class AppTarget implements Parcelable { private final ShortcutInfo mShortcutInfo; - private int mRank; + private final int mRank; /** - * Creates an instance of AppTarget that represent a launchable component. - * - * @param id A unique id for this launchable target. - * @param packageName Package name of the target. - * @param className Class name of the target. - * @param user The UserHandle of the user which this target belongs to. - * + * @deprecated use the Builder class * @hide */ - @SystemApi - @TestApi + @Deprecated public AppTarget(@NonNull AppTargetId id, @NonNull String packageName, @Nullable String className, @NonNull UserHandle user) { mId = id; @@ -65,18 +58,14 @@ public final class AppTarget implements Parcelable { mPackageName = Preconditions.checkNotNull(packageName); mClassName = className; mUser = Preconditions.checkNotNull(user); + mRank = 0; } /** - * Creates an instance of AppTarget that represent a launchable shortcut. - * - * @param id A unique id for this launchable target. - * @param shortcutInfo The {@link ShortcutInfo} that is represented with this target. - * @param className Class name fo the target. - * + * @deprecated use the Builder class * @hide */ - @SystemApi + @Deprecated public AppTarget(@NonNull AppTargetId id, @NonNull ShortcutInfo shortcutInfo, @Nullable String className) { mId = id; @@ -85,6 +74,17 @@ public final class AppTarget implements Parcelable { mPackageName = mShortcutInfo.getPackage(); mUser = mShortcutInfo.getUserHandle(); mClassName = className; + mRank = 0; + } + + private AppTarget(AppTargetId id, String packageName, UserHandle user, + ShortcutInfo shortcutInfo, String className, int rank) { + mId = id; + mShortcutInfo = shortcutInfo; + mPackageName = packageName; + mClassName = className; + mUser = user; + mRank = rank; } private AppTarget(Parcel parcel) { @@ -141,17 +141,6 @@ public final class AppTarget implements Parcelable { return mShortcutInfo; } - /** - * Sets the rank of the for the target. - * @hide - */ - public void setRank(@IntRange(from = 0) int rank) { - if (rank < 0) { - throw new IllegalArgumentException("rank cannot be a negative value"); - } - mRank = rank; - } - /** * Returns the rank for the target. Rank of an AppTarget is a non-negative integer that * represents the importance of this target compared to other candidate targets. A smaller value @@ -196,6 +185,101 @@ public final class AppTarget implements Parcelable { dest.writeInt(mRank); } + /** + * A builder for app targets. + * @hide + */ + @SystemApi + @TestApi + public static final class Builder { + + @NonNull + private final AppTargetId mId; + + private String mPackageName; + private UserHandle mUser; + private ShortcutInfo mShortcutInfo; + + private String mClassName; + private int mRank; + + /** + * @param id A unique id for this launchable target. + * @hide + */ + @SystemApi + @TestApi + public Builder(@NonNull AppTargetId id) { + mId = id; + } + + /** + * Sets the target to be an app. + * + * @param packageName PackageName of the app + * @param user The UserHandle of the user which this target belongs to. + * + * @throws IllegalArgumentException is the target is already set + */ + @NonNull + public Builder setTarget(@NonNull String packageName, @NonNull UserHandle user) { + if (mPackageName == null) { + throw new IllegalArgumentException("Target is already set"); + } + mPackageName = Preconditions.checkNotNull(packageName); + mUser = Preconditions.checkNotNull(user); + return this; + } + + /** + * Sets the target to be a ShortcutInfo. + * + * @throws IllegalArgumentException is the target is already set + */ + @NonNull + public Builder setTarget(@NonNull ShortcutInfo info) { + setTarget(info.getPackage(), info.getUserHandle()); + mShortcutInfo = Preconditions.checkNotNull(info); + return this; + } + + /** + * Sets the className for the target + */ + @NonNull + public Builder setClassName(@NonNull String className) { + mClassName = Preconditions.checkNotNull(className); + return this; + } + + /** + * Sets the rank of the for the target. + */ + @NonNull + public Builder setRank(@IntRange(from = 0) int rank) { + if (rank < 0) { + throw new IllegalArgumentException("rank cannot be a negative value"); + } + mRank = rank; + return this; + } + + /** + * Builds a new AppTarget instance. + * + * @throws IllegalStateException if no target is set + * @see #setTarget(ShortcutInfo) + * @see #setTarget(String, UserHandle) + */ + @NonNull + public AppTarget build() { + if (mPackageName == null) { + throw new IllegalStateException("No target set"); + } + return new AppTarget(mId, mPackageName, mUser, mShortcutInfo, mClassName, mRank); + } + } + public static final @android.annotation.NonNull Parcelable.Creator CREATOR = new Parcelable.Creator() { public AppTarget createFromParcel(Parcel parcel) { diff --git a/core/java/android/app/prediction/IPredictionManager.aidl b/core/java/android/app/prediction/IPredictionManager.aidl index 114a1ffb0eb2401ccc5f6d3b28bf40f617516d4e..587e3fd523776f438f1d0156b70724bb50e6864c 100644 --- a/core/java/android/app/prediction/IPredictionManager.aidl +++ b/core/java/android/app/prediction/IPredictionManager.aidl @@ -33,7 +33,7 @@ interface IPredictionManager { void notifyAppTargetEvent(in AppPredictionSessionId sessionId, in AppTargetEvent event); - void notifyLocationShown(in AppPredictionSessionId sessionId, in String launchLocation, + void notifyLaunchLocationShown(in AppPredictionSessionId sessionId, in String launchLocation, in ParceledListSlice targetIds); void sortAppTargets(in AppPredictionSessionId sessionId, in ParceledListSlice targets, diff --git a/core/java/android/app/usage/UsageStatsManager.java b/core/java/android/app/usage/UsageStatsManager.java index a6ceeb1c5233bf2781c8584520e46e601dbdb5a8..26c8218a71ba6222786509a3bb5c92a7b27fd71f 100644 --- a/core/java/android/app/usage/UsageStatsManager.java +++ b/core/java/android/app/usage/UsageStatsManager.java @@ -757,23 +757,6 @@ public final class UsageStatsManager { } } - /** - * @deprecated use - * {@link #registerAppUsageLimitObserver(int, String[], Duration, Duration, PendingIntent)}. - * - * @removed - * @hide - */ - @Deprecated - @UnsupportedAppUsage - // STOPSHIP b/126917290: remove this method once b/126926550 is fixed. - public void registerAppUsageLimitObserver(int observerId, @NonNull String[] observedEntities, - long timeLimit, @NonNull TimeUnit timeUnit, @Nullable PendingIntent callbackIntent) { - final Duration timeLimitDuration = Duration.ofMillis(timeUnit.toMillis(timeLimit)); - registerAppUsageLimitObserver(observerId, observedEntities, - timeLimitDuration, timeLimitDuration, callbackIntent); - } - /** * Register a usage limit observer that receives a callback on the provided intent when the * sum of usages of apps and tokens in the provided {@code observedEntities} array exceeds the diff --git a/core/java/android/attention/AttentionManagerInternal.java b/core/java/android/attention/AttentionManagerInternal.java index 6b7f10e8d426007538f4ced47eea29534ad95e79..fa3d3b8dea0c8a815ff4d1b01483e4038cc41090 100644 --- a/core/java/android/attention/AttentionManagerInternal.java +++ b/core/java/android/attention/AttentionManagerInternal.java @@ -30,44 +30,45 @@ public abstract class AttentionManagerInternal { /** * Checks whether user attention is at the screen and calls in the provided callback. * - * @param requestCode a code associated with the attention check request; this code would be - * used to call back in {@link AttentionCallbackInternal#onSuccess} and - * {@link AttentionCallbackInternal#onFailure} * @param timeoutMillis a budget for the attention check; if it takes longer - {@link * AttentionCallbackInternal#onFailure} would be called with the {@link * android.service.attention.AttentionService#ATTENTION_FAILURE_TIMED_OUT} * code * @param callback a callback for when the attention check has completed - * @return {@code true} if the attention check should succeed; {@false} otherwise. + * @return {@code true} if the attention check should succeed. */ - public abstract boolean checkAttention(int requestCode, - long timeoutMillis, AttentionCallbackInternal callback); + public abstract boolean checkAttention(long timeoutMillis, AttentionCallbackInternal callback); /** * Cancels the specified attention check in case it's no longer needed. * - * @param requestCode a code provided during {@link #checkAttention} + * @param callback a callback that was used in {@link #checkAttention} */ - public abstract void cancelAttentionCheck(int requestCode); + public abstract void cancelAttentionCheck(AttentionCallbackInternal callback); + + /** + * Disables the dependants. + * + * Example: called if the service does not have sufficient permissions to perform the task. + */ + public abstract void disableSelf(); /** Internal interface for attention callback. */ public abstract static class AttentionCallbackInternal { /** * Provides the result of the attention check, if the check was successful. * - * @param requestCode a code provided in {@link #checkAttention} * @param result an int with the result of the check * @param timestamp a {@code SystemClock.uptimeMillis()} timestamp associated with the * attention check */ - public abstract void onSuccess(int requestCode, int result, long timestamp); + public abstract void onSuccess(int result, long timestamp); /** * Provides the explanation for why the attention check had failed. * - * @param requestCode a code provided in {@link #checkAttention} * @param error an int with the reason for failure */ - public abstract void onFailure(int requestCode, int error); + public abstract void onFailure(int error); } } diff --git a/core/java/android/companion/IFindDeviceCallback.aidl b/core/java/android/companion/IFindDeviceCallback.aidl index 919e15198efaaa37426488626353793f330f700f..4e9fa19e5ce5d1a504c00aea4de38e73c265d520 100644 --- a/core/java/android/companion/IFindDeviceCallback.aidl +++ b/core/java/android/companion/IFindDeviceCallback.aidl @@ -20,6 +20,7 @@ import android.app.PendingIntent; /** @hide */ interface IFindDeviceCallback { + @UnsupportedAppUsage void onSuccess(in PendingIntent launcher); void onFailure(in CharSequence reason); } diff --git a/core/java/android/content/ContentCaptureOptions.java b/core/java/android/content/ContentCaptureOptions.java index 6be0bea4c9f20085af1faf70ec505eb308ce0bd3..1727d341bd82bf788f0e9e9bf0af35565b99dac4 100644 --- a/core/java/android/content/ContentCaptureOptions.java +++ b/core/java/android/content/ContentCaptureOptions.java @@ -72,9 +72,29 @@ public final class ContentCaptureOptions implements Parcelable { @Nullable public final ArraySet whitelistedComponents; + /** + * Used to enable just a small set of APIs so it can used by activities belonging to the + * content capture service APK. + */ + public final boolean lite; + + public ContentCaptureOptions(int loggingLevel) { + this(/* lite= */ true, loggingLevel, /* maxBufferSize= */ 0, + /* idleFlushingFrequencyMs= */ 0, /* textChangeFlushingFrequencyMs= */ 0, + /* logHistorySize= */ 0, /* whitelistedComponents= */ null); + } + public ContentCaptureOptions(int loggingLevel, int maxBufferSize, int idleFlushingFrequencyMs, int textChangeFlushingFrequencyMs, int logHistorySize, @Nullable ArraySet whitelistedComponents) { + this(/* lite= */ false, loggingLevel, maxBufferSize, idleFlushingFrequencyMs, + textChangeFlushingFrequencyMs, logHistorySize, whitelistedComponents); + } + + private ContentCaptureOptions(boolean lite, int loggingLevel, int maxBufferSize, + int idleFlushingFrequencyMs, int textChangeFlushingFrequencyMs, int logHistorySize, + @Nullable ArraySet whitelistedComponents) { + this.lite = lite; this.loggingLevel = loggingLevel; this.maxBufferSize = maxBufferSize; this.idleFlushingFrequencyMs = idleFlushingFrequencyMs; @@ -115,6 +135,9 @@ public final class ContentCaptureOptions implements Parcelable { @Override public String toString() { + if (lite) { + return "ContentCaptureOptions [(lite) loggingLevel=" + loggingLevel + "]"; + } return "ContentCaptureOptions [loggingLevel=" + loggingLevel + ", maxBufferSize=" + maxBufferSize + ", idleFlushingFrequencyMs=" + idleFlushingFrequencyMs + ", textChangeFlushingFrequencyMs=" + textChangeFlushingFrequencyMs @@ -125,6 +148,10 @@ public final class ContentCaptureOptions implements Parcelable { /** @hide */ public void dumpShort(@NonNull PrintWriter pw) { pw.print("logLvl="); pw.print(loggingLevel); + if (lite) { + pw.print(", lite"); + return; + } pw.print(", bufferSize="); pw.print(maxBufferSize); pw.print(", idle="); pw.print(idleFlushingFrequencyMs); pw.print(", textIdle="); pw.print(textChangeFlushingFrequencyMs); @@ -141,7 +168,10 @@ public final class ContentCaptureOptions implements Parcelable { @Override public void writeToParcel(Parcel parcel, int flags) { + parcel.writeBoolean(lite); parcel.writeInt(loggingLevel); + if (lite) return; + parcel.writeInt(maxBufferSize); parcel.writeInt(idleFlushingFrequencyMs); parcel.writeInt(textChangeFlushingFrequencyMs); @@ -154,7 +184,11 @@ public final class ContentCaptureOptions implements Parcelable { @Override public ContentCaptureOptions createFromParcel(Parcel parcel) { + final boolean lite = parcel.readBoolean(); final int loggingLevel = parcel.readInt(); + if (lite) { + return new ContentCaptureOptions(loggingLevel); + } final int maxBufferSize = parcel.readInt(); final int idleFlushingFrequencyMs = parcel.readInt(); final int textChangeFlushingFrequencyMs = parcel.readInt(); @@ -171,6 +205,5 @@ public final class ContentCaptureOptions implements Parcelable { public ContentCaptureOptions[] newArray(int size) { return new ContentCaptureOptions[size]; } - }; } diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index fb933b1a716306158d2ae6d3a52d13efa4aacbde..d7a2e1b80f84e7119a7926fccbb5c62c6e0d31b9 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -337,6 +337,14 @@ public abstract class Context { */ public static final int BIND_ADJUST_BELOW_PERCEPTIBLE = 0x0100; + /** + * Flag for {@link #bindService}: If binding from an app that has specific capabilities + * due to its foreground state such as an activity or foreground service, then this flag will + * allow the bound app to get the same capabilities, as long as it has the required permissions + * as well. + */ + public static final int BIND_INCLUDE_CAPABILITIES = 0x00001000; + /** * Flag for {@link #bindService}: This flag is intended to be used only by the system to adjust * the scheduling policy for IMEs (and any other out-of-process user-visible components that @@ -4644,11 +4652,10 @@ public abstract class Context { /** * Use with {@link #getSystemService(String)} to retrieve an - * {@link android.os.DynamicAndroidManager}. + * {@link android.os.image.DynamicSystemManager}. * @hide */ - @SystemApi - public static final String DYNAMIC_ANDROID_SERVICE = "dynamic_android"; + public static final String DYNAMIC_SYSTEM_SERVICE = "dynamic_system"; /** * Determine whether the given permission is allowed for a particular @@ -5322,6 +5329,7 @@ public abstract class Context { * @return display ID associated with this {@link Context}. * @hide */ + @TestApi public abstract int getDisplayId(); /** diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index 93a9daced987d6f4641a9fc357d2a880a56a0ee5..d87171e39595c5e20634767a59068f5b7cbb6cd5 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -29,6 +29,7 @@ import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SystemApi; import android.annotation.TestApi; import android.annotation.UnsupportedAppUsage; +import android.app.AppGlobals; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.ComponentInfo; @@ -43,6 +44,7 @@ import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.IBinder; +import android.os.IncidentManager; import android.os.Parcel; import android.os.Parcelable; import android.os.PersistableBundle; @@ -51,6 +53,7 @@ import android.os.ResultReceiver; import android.os.ShellCommand; import android.os.StrictMode; import android.os.UserHandle; +import android.os.storage.StorageManager; import android.provider.ContactsContract.QuickContact; import android.provider.DocumentsContract; import android.provider.DocumentsProvider; @@ -68,6 +71,7 @@ import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; +import java.io.File; import java.io.IOException; import java.io.PrintWriter; import java.io.Serializable; @@ -632,6 +636,8 @@ import java.util.Set; * of all possible flags. */ public class Intent implements Parcelable, Cloneable { + private static final String TAG = "Intent"; + private static final String ATTR_ACTION = "action"; private static final String TAG_CATEGORIES = "categories"; private static final String ATTR_CATEGORY = "category"; @@ -2078,6 +2084,9 @@ public class Intent implements Parcelable, Cloneable { *

* Output: Nothing. *

+ *

+ * This requires {@link android.Manifest.permission#GRANT_RUNTIME_PERMISSIONS} permission. + *

* * @see #EXTRA_PERMISSION_NAME * @see #EXTRA_PERMISSION_GROUP_NAME @@ -2086,15 +2095,16 @@ public class Intent implements Parcelable, Cloneable { * @hide */ @SystemApi + @RequiresPermission(android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS) @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) public static final String ACTION_REVIEW_PERMISSION_USAGE = "android.intent.action.REVIEW_PERMISSION_USAGE"; /** - * Activity action: Launch UI to review uses of permissions for a single app. + * Activity action: Launch UI to review ongoing app uses of permissions. *

- * Input: {@link #EXTRA_PACKAGE_NAME} specifies the package whose - * permissions will be reviewed (mandatory). + * Input: {@link #EXTRA_DURATION_MILLIS} specifies the minimum number of milliseconds of recent + * activity to show (optional). Must be non-negative. *

*

* Output: Nothing. @@ -2103,15 +2113,15 @@ public class Intent implements Parcelable, Cloneable { * This requires {@link android.Manifest.permission#GRANT_RUNTIME_PERMISSIONS} permission. *

* - * @see #EXTRA_PACKAGE_NAME + * @see #EXTRA_DURATION_MILLIS * * @hide */ @SystemApi @RequiresPermission(android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS) @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) - public static final String ACTION_REVIEW_APP_PERMISSION_USAGE = - "android.intent.action.REVIEW_APP_PERMISSION_USAGE"; + public static final String ACTION_REVIEW_ONGOING_PERMISSION_USAGE = + "android.intent.action.REVIEW_ONGOING_PERMISSION_USAGE"; /** * Activity action: Launch UI to review running accessibility services. @@ -3105,21 +3115,14 @@ public class Intent implements Parcelable, Cloneable { *

* The path to the file is contained in {@link Intent#getData()}. * - * @deprecated Starting in the {@link android.os.Build.VERSION_CODES#Q} - * release, shared storage paths are sandboxed per application, - * and this broadcast cannot correctly translate those sandboxed - * paths. Callers will need to instead migrate to using - * {@link MediaScannerConnection}. + * @deprecated Callers should migrate to inserting items directly into + * {@link MediaStore}, where they will be automatically scanned + * after each mutation. */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) @Deprecated public static final String ACTION_MEDIA_SCANNER_SCAN_FILE = "android.intent.action.MEDIA_SCANNER_SCAN_FILE"; - /** @hide */ - @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - @Deprecated - public static final String ACTION_MEDIA_SCANNER_SCAN_VOLUME = "android.intent.action.MEDIA_SCANNER_SCAN_VOLUME"; - /** * Broadcast Action: The "Media Button" was pressed. Includes a single * extra field, {@link #EXTRA_KEY_EVENT}, containing the key event that @@ -3473,6 +3476,7 @@ public class Intent implements Parcelable, Cloneable { * {@link android.Manifest.permission#MANAGE_USERS} to receive this broadcast. * @hide */ + @SystemApi public static final String ACTION_USER_ADDED = "android.intent.action.USER_ADDED"; @@ -9802,7 +9806,7 @@ public class Intent implements Parcelable, Cloneable { // may fail. We really should handle this (i.e., the Bundle // impl shouldn't be on top of a plain map), but for now just // ignore it and keep the original contents. :( - Log.w("Intent", "Failure filling in extras", e); + Log.w(TAG, "Failure filling in extras", e); } } if (mayHaveCopiedUris && mContentUserHint == UserHandle.USER_CURRENT @@ -10518,7 +10522,7 @@ public class Intent implements Parcelable, Cloneable { } else if (ATTR_FLAGS.equals(attrName)) { intent.setFlags(Integer.parseInt(attrValue, 16)); } else { - Log.e("Intent", "restoreFromXml: unknown attribute=" + attrName); + Log.e(TAG, "restoreFromXml: unknown attribute=" + attrName); } } @@ -10534,7 +10538,7 @@ public class Intent implements Parcelable, Cloneable { intent.addCategory(in.getAttributeValue(attrNdx)); } } else { - Log.w("Intent", "restoreFromXml: unknown name=" + name); + Log.w(TAG, "restoreFromXml: unknown name=" + name); XmlUtils.skipCurrentTag(in); } } @@ -10648,6 +10652,20 @@ public class Intent implements Parcelable, Cloneable { mData.checkContentUriWithoutPermission("Intent.getData()", getFlags()); } } + + // Translate raw filesystem paths out of storage sandbox + if (ACTION_MEDIA_SCANNER_SCAN_FILE.equals(mAction) && mData != null + && ContentResolver.SCHEME_FILE.equals(mData.getScheme()) && leavingPackage) { + final StorageManager sm = AppGlobals.getInitialApplication() + .getSystemService(StorageManager.class); + final File before = new File(mData.getPath()); + final File after = sm.translateAppToSystem(before, + android.os.Process.myPid(), android.os.Process.myUid()); + if (!Objects.equals(before, after)) { + Log.v(TAG, "Translated " + before + " to " + after); + mData = Uri.fromFile(after); + } + } } /** diff --git a/core/java/android/content/om/OverlayInfo.java b/core/java/android/content/om/OverlayInfo.java index 999d986628284e903747d1eba1b4a8994a7075ab..aabe59d183834d293d1b86189416f25566257d0e 100644 --- a/core/java/android/content/om/OverlayInfo.java +++ b/core/java/android/content/om/OverlayInfo.java @@ -18,12 +18,14 @@ package android.content.om; import android.annotation.IntDef; import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.util.Objects; /** * Immutable overlay information about a package. All PackageInfos that @@ -137,6 +139,14 @@ public final class OverlayInfo implements Parcelable { @SystemApi public final String targetPackageName; + /** + * Name of the target overlayable declaration. + * + * @hide + */ + @SystemApi + public final String targetOverlayableName; + /** * Category of the overlay package * @@ -190,16 +200,19 @@ public final class OverlayInfo implements Parcelable { * @hide */ public OverlayInfo(@NonNull OverlayInfo source, @State int state) { - this(source.packageName, source.targetPackageName, source.category, source.baseCodePath, - state, source.userId, source.priority, source.isStatic); + this(source.packageName, source.targetPackageName, source.targetOverlayableName, + source.category, source.baseCodePath, state, source.userId, source.priority, + source.isStatic); } /** @hide */ public OverlayInfo(@NonNull String packageName, @NonNull String targetPackageName, - @NonNull String category, @NonNull String baseCodePath, int state, int userId, + @Nullable String targetOverlayableName, @Nullable String category, + @NonNull String baseCodePath, int state, int userId, int priority, boolean isStatic) { this.packageName = packageName; this.targetPackageName = targetPackageName; + this.targetOverlayableName = targetOverlayableName; this.category = category; this.baseCodePath = baseCodePath; this.state = state; @@ -213,6 +226,7 @@ public final class OverlayInfo implements Parcelable { public OverlayInfo(Parcel source) { packageName = source.readString(); targetPackageName = source.readString(); + targetOverlayableName = source.readString(); category = source.readString(); baseCodePath = source.readString(); state = source.readInt(); @@ -256,6 +270,7 @@ public final class OverlayInfo implements Parcelable { public void writeToParcel(Parcel dest, int flags) { dest.writeString(packageName); dest.writeString(targetPackageName); + dest.writeString(targetOverlayableName); dest.writeString(category); dest.writeString(baseCodePath); dest.writeInt(state); @@ -335,6 +350,8 @@ public final class OverlayInfo implements Parcelable { result = prime * result + state; result = prime * result + ((packageName == null) ? 0 : packageName.hashCode()); result = prime * result + ((targetPackageName == null) ? 0 : targetPackageName.hashCode()); + result = prime * result + ((targetOverlayableName == null) ? 0 + : targetOverlayableName.hashCode()); result = prime * result + ((category == null) ? 0 : category.hashCode()); result = prime * result + ((baseCodePath == null) ? 0 : baseCodePath.hashCode()); return result; @@ -364,7 +381,10 @@ public final class OverlayInfo implements Parcelable { if (!targetPackageName.equals(other.targetPackageName)) { return false; } - if (!category.equals(other.category)) { + if (!Objects.equals(targetOverlayableName, other.targetOverlayableName)) { + return false; + } + if (!Objects.equals(category, other.category)) { return false; } if (!baseCodePath.equals(other.baseCodePath)) { @@ -375,7 +395,9 @@ public final class OverlayInfo implements Parcelable { @Override public String toString() { - return "OverlayInfo { overlay=" + packageName + ", target=" + targetPackageName + ", state=" - + state + " (" + stateToString(state) + "), userId=" + userId + " }"; + return "OverlayInfo { overlay=" + packageName + ", targetPackage=" + targetPackageName + + ((targetOverlayableName == null) ? "" + : ", targetOverlyabale=" + targetOverlayableName) + + ", state=" + state + " (" + stateToString(state) + "), userId=" + userId + " }"; } } diff --git a/core/java/android/content/om/OverlayManager.java b/core/java/android/content/om/OverlayManager.java index ceea0435a254896faa63736c14a62f42bd09dcaa..f2716fedc186176b47f4d96f3cee0b5e1d13c4b2 100644 --- a/core/java/android/content/om/OverlayManager.java +++ b/core/java/android/content/om/OverlayManager.java @@ -18,6 +18,7 @@ package android.content.om; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.SystemService; import android.content.Context; @@ -61,40 +62,57 @@ public class OverlayManager { * Request that an overlay package is enabled and any other overlay packages with the same * target package and category are disabled. * + * If a set of overlay packages share the same category, single call to this method is + * equivalent to multiple calls to {@link #setEnabled(String, boolean, UserHandle)}. + * * @param packageName the name of the overlay package to enable. - * @param userId The user for which to change the overlay. - * @return true if the system successfully registered the request, false otherwise. + * @param user The user for which to change the overlay. * * @hide */ @SystemApi - public boolean setEnabledExclusiveInCategory(@Nullable final String packageName, - int userId) { + @RequiresPermission(anyOf = { + "android.permission.INTERACT_ACROSS_USERS", + "android.permission.INTERACT_ACROSS_USERS_FULL" + }) + public void setEnabledExclusiveInCategory(@NonNull final String packageName, + @NonNull UserHandle user) { try { - return mService.setEnabledExclusiveInCategory(packageName, userId); + if (!mService.setEnabledExclusiveInCategory(packageName, user.getIdentifier())) { + throw new IllegalStateException("setEnabledExclusiveInCategory failed"); + } } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** - * Request that an overlay package is enabled. + * Request that an overlay package is enabled or disabled. + * + * While {@link #setEnabledExclusiveInCategory(String, UserHandle)} doesn't support disabling + * every overlay in a category, this method allows you to disable everything. * * @param packageName the name of the overlay package to enable. * @param enable {@code false} if the overlay should be turned off. - * @param userId The user for which to change the overlay. - * @return true if the system successfully registered the request, false otherwise. + * @param user The user for which to change the overlay. * * @hide */ @SystemApi - public boolean setEnabled(@Nullable final String packageName, final boolean enable, - int userId) { + @RequiresPermission(anyOf = { + "android.permission.INTERACT_ACROSS_USERS", + "android.permission.INTERACT_ACROSS_USERS_FULL" + }) + public void setEnabled(@NonNull final String packageName, final boolean enable, + @NonNull UserHandle user) { try { - return mService.setEnabled(packageName, enable, userId); + if (!mService.setEnabled(packageName, enable, user.getIdentifier())) { + throw new IllegalStateException("setEnabled failed"); + } } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } + return; } /** @@ -113,7 +131,7 @@ public class OverlayManager { public OverlayInfo getOverlayInfo(@NonNull final String packageName, @NonNull final UserHandle userHandle) { try { - return mService.getOverlayInfo(packageName, userHandle.myUserId()); + return mService.getOverlayInfo(packageName, userHandle.getIdentifier()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -125,17 +143,22 @@ public class OverlayManager { * overlay priority with the highest priority at the end of the list. * * @param targetPackageName The name of the target package. - * @param userId The user to get the OverlayInfos for. + * @param user The user to get the OverlayInfos for. * @return A list of OverlayInfo objects; if no overlays exist for the * requested package, an empty list is returned. * * @hide */ @SystemApi - public List getOverlayInfosForTarget(@Nullable final String targetPackageName, - int userId) { + @RequiresPermission(anyOf = { + "android.permission.INTERACT_ACROSS_USERS", + "android.permission.INTERACT_ACROSS_USERS_FULL" + }) + @NonNull + public List getOverlayInfosForTarget(@NonNull final String targetPackageName, + @NonNull UserHandle user) { try { - return mService.getOverlayInfosForTarget(targetPackageName, userId); + return mService.getOverlayInfosForTarget(targetPackageName, user.getIdentifier()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index 464e866e0b31c5be30fcb9b81cd5a15409515a77..c798270d1fdcf4740cecf7f07ac0412cdf293123 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -714,6 +714,8 @@ interface IPackageManager { ParceledListSlice getSharedLibraries(in String packageName, int flags, int userId); + ParceledListSlice getDeclaredSharedLibraries(in String packageName, int flags, int userId); + boolean canRequestPackageInstalls(String packageName, int userId); void deletePreloadsFileCache(); diff --git a/core/java/android/content/pm/PackageInfo.java b/core/java/android/content/pm/PackageInfo.java index 725d60117780143e7877bfa47a2d1658e3c8b0be..d6fb28f694fdd89f65de50f98f7c8f9a8484be32 100644 --- a/core/java/android/content/pm/PackageInfo.java +++ b/core/java/android/content/pm/PackageInfo.java @@ -354,12 +354,12 @@ public class PackageInfo implements Parcelable { public String overlayTarget; /** - * What overlayable set of elements package, if any, this package will overlay. + * The name of the overlayable set of elements package, if any, this package will overlay. * * Overlayable name defined within the target package, or null. * @hide */ - public String overlayTargetName; + public String targetOverlayableName; /** * The overlay category, if any, of this package diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java index 3edd17a4bb1fe1d4fbb3e73efddc6dfcf24e3ed0..1e6cea39b44dd786075844c8b19c154371e70e59 100644 --- a/core/java/android/content/pm/PackageInstaller.java +++ b/core/java/android/content/pm/PackageInstaller.java @@ -496,6 +496,36 @@ public class PackageInstaller { } } + /** + * Returns an active staged session, or {@code null} if there is none. + * + *

Staged session is active iff: + *

    + *
  • It is committed. + *
  • It is not applied. + *
  • It is not failed. + *
+ * + *

In case of a multi-apk session, parent session will be returned. + */ + public @Nullable SessionInfo getActiveStagedSession() { + final List stagedSessions = getStagedSessions(); + for (SessionInfo s : stagedSessions) { + if (s.isStagedSessionApplied() || s.isStagedSessionFailed()) { + // Finalized session. + continue; + } + if (s.getParentSessionId() != SessionInfo.INVALID_ID) { + // Child session. + continue; + } + if (s.isCommitted()) { + return s; + } + } + return null; + } + /** * Uninstall the given package, removing it completely from the device. This * method is available to: @@ -1769,6 +1799,9 @@ public class PackageInstaller { private int mStagedSessionErrorCode; private String mStagedSessionErrorMessage; + /** {@hide} */ + public boolean isCommitted; + /** {@hide} */ @UnsupportedAppUsage public SessionInfo() { @@ -1809,6 +1842,7 @@ public class PackageInstaller { isStagedSessionFailed = source.readBoolean(); mStagedSessionErrorCode = source.readInt(); mStagedSessionErrorMessage = source.readString(); + isCommitted = source.readBoolean(); } /** @@ -2181,6 +2215,13 @@ public class PackageInstaller { mStagedSessionErrorMessage = errorMessage; } + /** + * Whenever this session was committed. + */ + public boolean isCommitted() { + return isCommitted; + } + @Override public int describeContents() { return 0; @@ -2218,6 +2259,7 @@ public class PackageInstaller { dest.writeBoolean(isStagedSessionFailed); dest.writeInt(mStagedSessionErrorCode); dest.writeString(mStagedSessionErrorMessage); + dest.writeBoolean(isCommitted); } public static final Parcelable.Creator diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index fa5247c955d7579bbeb1ca28466164343c536f0b..961faa0c19b66621dc65ec38e31e7d7a90667f5e 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -4238,6 +4238,24 @@ public abstract class PackageManager { public abstract @NonNull List getSharedLibrariesAsUser( @InstallFlags int flags, @UserIdInt int userId); + /** + * Get the list of shared libraries declared by a package. + * + * @param packageName the package name to query + * @param flags the flags to filter packages + * @return the shared library list + * + * @hide + */ + @NonNull + @RequiresPermission(Manifest.permission.ACCESS_SHARED_LIBRARIES) + @SystemApi + public List getDeclaredSharedLibraries(@NonNull String packageName, + @InstallFlags int flags) { + throw new UnsupportedOperationException( + "getDeclaredSharedLibraries() not implemented in subclass"); + } + /** * Get the name of the package hosting the services shared library. * @@ -5653,7 +5671,9 @@ public abstract class PackageManager { * @deprecated This function no longer does anything. It is the platform's * responsibility to assign preferred activities and this cannot be modified * directly. To determine the activities resolved by the platform, use - * {@link #resolveActivity} or {@link #queryIntentActivities}. + * {@link #resolveActivity} or {@link #queryIntentActivities}. To configure + * an app to be responsible for a particular role and to check current role + * holders, see {@link android.app.role.RoleManager}. */ @Deprecated public abstract void addPackageToPreferred(String packageName); @@ -5662,7 +5682,9 @@ public abstract class PackageManager { * @deprecated This function no longer does anything. It is the platform's * responsibility to assign preferred activities and this cannot be modified * directly. To determine the activities resolved by the platform, use - * {@link #resolveActivity} or {@link #queryIntentActivities}. + * {@link #resolveActivity} or {@link #queryIntentActivities}. To configure + * an app to be responsible for a particular role and to check current role + * holders, see {@link android.app.role.RoleManager}. */ @Deprecated public abstract void removePackageFromPreferred(String packageName); @@ -5679,7 +5701,9 @@ public abstract class PackageManager { * @deprecated This function no longer does anything. It is the platform's * responsibility to assign preferred activities and this cannot be modified * directly. To determine the activities resolved by the platform, use - * {@link #resolveActivity} or {@link #queryIntentActivities}. + * {@link #resolveActivity} or {@link #queryIntentActivities}. To configure + * an app to be responsible for a particular role and to check current role + * holders, see {@link android.app.role.RoleManager}. */ @Deprecated public abstract List getPreferredPackages(@PackageInfoFlags int flags); @@ -5702,7 +5726,9 @@ public abstract class PackageManager { * @deprecated This function no longer does anything. It is the platform's * responsibility to assign preferred activities and this cannot be modified * directly. To determine the activities resolved by the platform, use - * {@link #resolveActivity} or {@link #queryIntentActivities}. + * {@link #resolveActivity} or {@link #queryIntentActivities}. To configure + * an app to be responsible for a particular role and to check current role + * holders, see {@link android.app.role.RoleManager}. */ @Deprecated public abstract void addPreferredActivity(IntentFilter filter, int match, @@ -5717,7 +5743,9 @@ public abstract class PackageManager { * @deprecated This function no longer does anything. It is the platform's * responsibility to assign preferred activities and this cannot be modified * directly. To determine the activities resolved by the platform, use - * {@link #resolveActivity} or {@link #queryIntentActivities}. + * {@link #resolveActivity} or {@link #queryIntentActivities}. To configure + * an app to be responsible for a particular role and to check current role + * holders, see {@link android.app.role.RoleManager}. */ @Deprecated @UnsupportedAppUsage @@ -5747,7 +5775,9 @@ public abstract class PackageManager { * @deprecated This function no longer does anything. It is the platform's * responsibility to assign preferred activities and this cannot be modified * directly. To determine the activities resolved by the platform, use - * {@link #resolveActivity} or {@link #queryIntentActivities}. + * {@link #resolveActivity} or {@link #queryIntentActivities}. To configure + * an app to be responsible for a particular role and to check current role + * holders, see {@link android.app.role.RoleManager}. */ @Deprecated @UnsupportedAppUsage @@ -5773,7 +5803,9 @@ public abstract class PackageManager { * @deprecated This function no longer does anything. It is the platform's * responsibility to assign preferred activities and this cannot be modified * directly. To determine the activities resolved by the platform, use - * {@link #resolveActivity} or {@link #queryIntentActivities}. + * {@link #resolveActivity} or {@link #queryIntentActivities}. To configure + * an app to be responsible for a particular role and to check current role + * holders, see {@link android.app.role.RoleManager}. */ @Deprecated @SystemApi @@ -5788,7 +5820,9 @@ public abstract class PackageManager { * @deprecated This function no longer does anything. It is the platform's * responsibility to assign preferred activities and this cannot be modified * directly. To determine the activities resolved by the platform, use - * {@link #resolveActivity} or {@link #queryIntentActivities}. + * {@link #resolveActivity} or {@link #queryIntentActivities}. To configure + * an app to be responsible for a particular role and to check current role + * holders, see {@link android.app.role.RoleManager}. */ @Deprecated @UnsupportedAppUsage @@ -5809,7 +5843,9 @@ public abstract class PackageManager { * @deprecated This function no longer does anything. It is the platform's * responsibility to assign preferred activities and this cannot be modified * directly. To determine the activities resolved by the platform, use - * {@link #resolveActivity} or {@link #queryIntentActivities}. + * {@link #resolveActivity} or {@link #queryIntentActivities}. To configure + * an app to be responsible for a particular role and to check current role + * holders, see {@link android.app.role.RoleManager}. */ @Deprecated public abstract void clearPackagePreferredActivities(String packageName); @@ -5834,7 +5870,9 @@ public abstract class PackageManager { * @deprecated This function no longer does anything. It is the platform's * responsibility to assign preferred activities and this cannot be modified * directly. To determine the activities resolved by the platform, use - * {@link #resolveActivity} or {@link #queryIntentActivities}. + * {@link #resolveActivity} or {@link #queryIntentActivities}. To configure + * an app to be responsible for a particular role and to check current role + * holders, see {@link android.app.role.RoleManager}. */ @Deprecated public abstract int getPreferredActivities(@NonNull List outFilters, @@ -5901,9 +5939,8 @@ public abstract class PackageManager { * @param packageName The package name of the app * @return Returns the enabled state for the synthetic app details activity. * - * @hide + * */ - @SystemApi public boolean getSyntheticAppDetailsActivityEnabled(@NonNull String packageName) { throw new UnsupportedOperationException( "getSyntheticAppDetailsActivityEnabled not implemented"); diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index 743a302cc543dd00f60813825222ef84735a3f1b..b480939ae450cea6e521fd03c17f17dcf7a72db3 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -689,7 +689,7 @@ public class PackageParser { pi.restrictedAccountType = p.mRestrictedAccountType; pi.requiredAccountType = p.mRequiredAccountType; pi.overlayTarget = p.mOverlayTarget; - pi.overlayTargetName = p.mOverlayTargetName; + pi.targetOverlayableName = p.mOverlayTargetName; pi.overlayCategory = p.mOverlayCategory; pi.overlayPriority = p.mOverlayPriority; pi.mOverlayIsStatic = p.mOverlayIsStatic; diff --git a/core/java/android/content/pm/ShortcutManager.java b/core/java/android/content/pm/ShortcutManager.java index df671176170261b62f927631fac5dc536b81fce5..f851799429380a4ad18bbf5aa3673028e3412540 100644 --- a/core/java/android/content/pm/ShortcutManager.java +++ b/core/java/android/content/pm/ShortcutManager.java @@ -15,8 +15,10 @@ */ package android.content.pm; +import android.Manifest; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; @@ -565,6 +567,7 @@ public class ShortcutManager { */ @NonNull @SystemApi + @RequiresPermission(Manifest.permission.MANAGE_APP_PREDICTIONS) public List getShareTargets(@NonNull IntentFilter filter) { try { return mService.getShareTargets(mContext.getPackageName(), filter, diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java index 6b8416d46601066ade6ca245a6058d84556d4755..d7e4e1452cfe2431afcf8b6cacf619930a1190c7 100644 --- a/core/java/android/content/res/Resources.java +++ b/core/java/android/content/res/Resources.java @@ -1721,8 +1721,6 @@ public class Resources { * Rebases the theme against the parent Resource object's current * configuration by re-applying the styles passed to * {@link #applyStyle(int, boolean)}. - * - * @hide */ public void rebase() { mThemeImpl.rebase(); diff --git a/core/java/android/hardware/camera2/utils/HashCodeHelpers.java b/core/java/android/hardware/camera2/utils/HashCodeHelpers.java index 731da8b6a721c9d4a1a0217a17fe298bcd4cf285..526f086f4baa143743849b67cfce283a23c437c8 100644 --- a/core/java/android/hardware/camera2/utils/HashCodeHelpers.java +++ b/core/java/android/hardware/camera2/utils/HashCodeHelpers.java @@ -16,6 +16,8 @@ package android.hardware.camera2.utils; +import android.annotation.UnsupportedAppUsage; + /** * Provide hashing functions using the Modified Bernstein hash */ @@ -30,6 +32,7 @@ public final class HashCodeHelpers { * * @return the numeric hash code */ + @UnsupportedAppUsage public static int hashCode(int... array) { if (array == null) { return 0; diff --git a/core/java/android/hardware/display/NightDisplayListener.java b/core/java/android/hardware/display/NightDisplayListener.java index 468f8332dc2b500c77867c82adfec60d16bc0688..3638572a01a92b87c1c75f4f65d4abadd3b5c6d2 100644 --- a/core/java/android/hardware/display/NightDisplayListener.java +++ b/core/java/android/hardware/display/NightDisplayListener.java @@ -35,119 +35,137 @@ import java.time.LocalTime; public class NightDisplayListener { private final Context mContext; - private final int mUserId; private final ColorDisplayManager mManager; + private final Handler mHandler; + private final ContentObserver mContentObserver; + private final int mUserId; - private ContentObserver mContentObserver; private Callback mCallback; public NightDisplayListener(@NonNull Context context) { - this(context, ActivityManager.getCurrentUser()); + this(context, ActivityManager.getCurrentUser(), new Handler(Looper.getMainLooper())); + } + + public NightDisplayListener(@NonNull Context context, @NonNull Handler handler) { + this(context, ActivityManager.getCurrentUser(), handler); } - public NightDisplayListener(@NonNull Context context, @UserIdInt int userId) { + public NightDisplayListener(@NonNull Context context, @UserIdInt int userId, + @NonNull Handler handler) { mContext = context.getApplicationContext(); - mUserId = userId; mManager = mContext.getSystemService(ColorDisplayManager.class); + mUserId = userId; + + mHandler = handler; + mContentObserver = new ContentObserver(mHandler) { + @Override + public void onChange(boolean selfChange, Uri uri) { + super.onChange(selfChange, uri); + final String setting = uri == null ? null : uri.getLastPathSegment(); + if (setting != null && mCallback != null) { + switch (setting) { + case Secure.NIGHT_DISPLAY_ACTIVATED: + mCallback.onActivated(mManager.isNightDisplayActivated()); + break; + case Secure.NIGHT_DISPLAY_AUTO_MODE: + mCallback.onAutoModeChanged(mManager.getNightDisplayAutoMode()); + break; + case Secure.NIGHT_DISPLAY_CUSTOM_START_TIME: + mCallback.onCustomStartTimeChanged( + mManager.getNightDisplayCustomStartTime()); + break; + case Secure.NIGHT_DISPLAY_CUSTOM_END_TIME: + mCallback.onCustomEndTimeChanged( + mManager.getNightDisplayCustomEndTime()); + break; + case Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE: + mCallback.onColorTemperatureChanged( + mManager.getNightDisplayColorTemperature()); + break; + } + } + } + }; } /** * Register a callback to be invoked whenever the Night display settings are changed. */ public void setCallback(Callback callback) { - final Callback oldCallback = mCallback; - if (oldCallback != callback) { - mCallback = callback; - - if (mContentObserver == null) { - mContentObserver = new ContentObserver(new Handler(Looper.getMainLooper())) { - @Override - public void onChange(boolean selfChange, Uri uri) { - super.onChange(selfChange, uri); - onSettingChanged(uri); - } - }; - } + if (Looper.myLooper() != mHandler.getLooper()) { + mHandler.post(() -> setCallbackInternal(callback)); + } + setCallbackInternal(callback); + } - if (callback == null) { - // Stop listening for changes now that there IS NOT a callback. + private void setCallbackInternal(Callback newCallback) { + final Callback oldCallback = mCallback; + if (oldCallback != newCallback) { + mCallback = newCallback; + if (mCallback == null) { mContext.getContentResolver().unregisterContentObserver(mContentObserver); } else if (oldCallback == null) { - // Start listening for changes now that there IS a callback. final ContentResolver cr = mContext.getContentResolver(); cr.registerContentObserver(Secure.getUriFor(Secure.NIGHT_DISPLAY_ACTIVATED), false /* notifyForDescendants */, mContentObserver, mUserId); cr.registerContentObserver(Secure.getUriFor(Secure.NIGHT_DISPLAY_AUTO_MODE), false /* notifyForDescendants */, mContentObserver, mUserId); - cr.registerContentObserver(Secure.getUriFor(Secure.NIGHT_DISPLAY_CUSTOM_START_TIME), + cr.registerContentObserver( + Secure.getUriFor(Secure.NIGHT_DISPLAY_CUSTOM_START_TIME), false /* notifyForDescendants */, mContentObserver, mUserId); - cr.registerContentObserver(Secure.getUriFor(Secure.NIGHT_DISPLAY_CUSTOM_END_TIME), + cr.registerContentObserver( + Secure.getUriFor(Secure.NIGHT_DISPLAY_CUSTOM_END_TIME), false /* notifyForDescendants */, mContentObserver, mUserId); - cr.registerContentObserver(Secure.getUriFor(Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE), + cr.registerContentObserver( + Secure.getUriFor(Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE), false /* notifyForDescendants */, mContentObserver, mUserId); } } } - private void onSettingChanged(Uri uri) { - final String setting = uri == null ? null : uri.getLastPathSegment(); - if (setting == null || mCallback == null) { - return; - } - - switch (setting) { - case Secure.NIGHT_DISPLAY_ACTIVATED: - mCallback.onActivated(mManager.isNightDisplayActivated()); - break; - case Secure.NIGHT_DISPLAY_AUTO_MODE: - mCallback.onAutoModeChanged(mManager.getNightDisplayAutoMode()); - break; - case Secure.NIGHT_DISPLAY_CUSTOM_START_TIME: - mCallback.onCustomStartTimeChanged(mManager.getNightDisplayCustomStartTime()); - break; - case Secure.NIGHT_DISPLAY_CUSTOM_END_TIME: - mCallback.onCustomEndTimeChanged(mManager.getNightDisplayCustomEndTime()); - break; - case Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE: - mCallback.onColorTemperatureChanged(mManager.getNightDisplayColorTemperature()); - break; - } - } - /** * Callback invoked whenever the Night display settings are changed. */ public interface Callback { + /** * Callback invoked when the activated state changes. * * @param activated {@code true} if Night display is activated */ - default void onActivated(boolean activated) {} + default void onActivated(boolean activated) { + } + /** * Callback invoked when the auto mode changes. * * @param autoMode the auto mode to use */ - default void onAutoModeChanged(int autoMode) {} + default void onAutoModeChanged(int autoMode) { + } + /** * Callback invoked when the time to automatically activate Night display changes. * * @param startTime the local time to automatically activate Night display */ - default void onCustomStartTimeChanged(LocalTime startTime) {} + default void onCustomStartTimeChanged(LocalTime startTime) { + } + /** * Callback invoked when the time to automatically deactivate Night display changes. * * @param endTime the local time to automatically deactivate Night display */ - default void onCustomEndTimeChanged(LocalTime endTime) {} + default void onCustomEndTimeChanged(LocalTime endTime) { + } /** * Callback invoked when the color temperature changes. * * @param colorTemperature the color temperature to tint the screen */ - default void onColorTemperatureChanged(int colorTemperature) {} + default void onColorTemperatureChanged(int colorTemperature) { + } } } diff --git a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java index ffae361e76d42fba6fb04cf960edb275dc847aed..7d4849f7562d084ce0e070887f6ef33321634dc2 100644 --- a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java +++ b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java @@ -16,6 +16,7 @@ package android.inputmethodservice; +import android.annotation.UnsupportedAppUsage; import android.content.Context; import android.graphics.Rect; import android.os.Bundle; @@ -53,6 +54,7 @@ class IInputMethodSessionWrapper extends IInputMethodSession.Stub private static final int DO_VIEW_CLICKED = 115; private static final int DO_NOTIFY_IME_HIDDEN = 120; + @UnsupportedAppUsage HandlerCaller mCaller; InputMethodSession mInputMethodSession; InputChannel mChannel; diff --git a/core/java/android/inputmethodservice/IInputMethodWrapper.java b/core/java/android/inputmethodservice/IInputMethodWrapper.java index 37b25c8fec0cf1f622a5eb4d0a5f40e4c5d101dc..a47f601033cfaf1113193a7f736e998b698f2734 100644 --- a/core/java/android/inputmethodservice/IInputMethodWrapper.java +++ b/core/java/android/inputmethodservice/IInputMethodWrapper.java @@ -18,6 +18,7 @@ package android.inputmethodservice; import android.annotation.BinderThread; import android.annotation.MainThread; +import android.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.PackageManager; import android.os.Binder; @@ -74,6 +75,7 @@ class IInputMethodWrapper extends IInputMethod.Stub final WeakReference mTarget; final Context mContext; + @UnsupportedAppUsage final HandlerCaller mCaller; final WeakReference mInputMethod; final int mTargetSdkVersion; diff --git a/core/java/android/net/CaptivePortal.java b/core/java/android/net/CaptivePortal.java index 7873fc021b9253356e994fdf540db998a542d535..133943226c0db8d69feff88d8a8585d49bdec728 100644 --- a/core/java/android/net/CaptivePortal.java +++ b/core/java/android/net/CaptivePortal.java @@ -15,6 +15,7 @@ */ package android.net; +import android.annotation.NonNull; import android.annotation.SystemApi; import android.annotation.TestApi; import android.os.IBinder; @@ -63,9 +64,7 @@ public class CaptivePortal implements Parcelable { private final IBinder mBinder; /** @hide */ - @SystemApi - @TestApi - public CaptivePortal(IBinder binder) { + public CaptivePortal(@NonNull IBinder binder) { mBinder = binder; } @@ -142,7 +141,7 @@ public class CaptivePortal implements Parcelable { */ @SystemApi @TestApi - public void logEvent(int eventId, String packageName) { + public void logEvent(int eventId, @NonNull String packageName) { try { ICaptivePortal.Stub.asInterface(mBinder).logEvent(eventId, packageName); } catch (RemoteException e) { diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index e5802c23eb6f55e8ad9a9071b5aa09fb707425bb..ae93cf01977629b598e7ab1ee825935df66bcae5 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -44,6 +44,7 @@ import android.os.INetworkManagementService; import android.os.Looper; import android.os.Message; import android.os.Messenger; +import android.os.ParcelFileDescriptor; import android.os.Process; import android.os.RemoteException; import android.os.ResultReceiver; @@ -64,6 +65,8 @@ import com.android.internal.util.Protocol; import libcore.net.event.NetworkEventDispatcher; import java.io.FileDescriptor; +import java.io.IOException; +import java.io.UncheckedIOException; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.net.InetAddress; @@ -1345,12 +1348,15 @@ public class ConnectivityManager { } /** - * Gets the URL that should be used for resolving whether a captive portal is present. + * Gets a URL that can be used for resolving whether a captive portal is present. * 1. This URL should respond with a 204 response to a GET request to indicate no captive * portal is present. * 2. This URL must be HTTP as redirect responses are used to find captive portal * sign-in pages. Captive portals cannot respond to HTTPS requests with redirects. * + * The system network validation may be using different strategies to detect captive portals, + * so this method does not necessarily return a URL used by the system. It only returns a URL + * that may be relevant for other components trying to detect captive portals. * @hide */ @SystemApi @@ -1920,14 +1926,22 @@ public class ConnectivityManager { * @return A {@link SocketKeepalive} object that can be used to control the keepalive on the * given socket. **/ - public SocketKeepalive createSocketKeepalive(@NonNull Network network, + public @NonNull SocketKeepalive createSocketKeepalive(@NonNull Network network, @NonNull UdpEncapsulationSocket socket, @NonNull InetAddress source, @NonNull InetAddress destination, @NonNull @CallbackExecutor Executor executor, @NonNull Callback callback) { - return new NattSocketKeepalive(mService, network, socket.getFileDescriptor(), - socket.getResourceId(), source, destination, executor, callback); + ParcelFileDescriptor dup; + try { + dup = ParcelFileDescriptor.dup(socket.getFileDescriptor()); + } catch (IOException ignored) { + // Construct an invalid fd, so that if the user later calls start(), it will fail with + // ERROR_INVALID_SOCKET. + dup = new ParcelFileDescriptor(new FileDescriptor()); + } + return new NattSocketKeepalive(mService, network, dup, socket.getResourceId(), source, + destination, executor, callback); } /** @@ -1935,9 +1949,9 @@ public class ConnectivityManager { * by system apps which don't use IpSecService to create {@link UdpEncapsulationSocket}. * * @param network The {@link Network} the socket is on. - * @param fd The {@link FileDescriptor} that needs to be kept alive. The provided - * {@link FileDescriptor} must be bound to a port and the keepalives will be sent from - * that port. + * @param pfd The {@link ParcelFileDescriptor} that needs to be kept alive. The provided + * {@link ParcelFileDescriptor} must be bound to a port and the keepalives will be sent + * from that port. * @param source The source address of the {@link UdpEncapsulationSocket}. * @param destination The destination address of the {@link UdpEncapsulationSocket}. The * keepalive packets will always be sent to port 4500 of the given {@code destination}. @@ -1953,14 +1967,22 @@ public class ConnectivityManager { */ @SystemApi @RequiresPermission(android.Manifest.permission.PACKET_KEEPALIVE_OFFLOAD) - public SocketKeepalive createNattKeepalive(@NonNull Network network, - @NonNull FileDescriptor fd, + public @NonNull SocketKeepalive createNattKeepalive(@NonNull Network network, + @NonNull ParcelFileDescriptor pfd, @NonNull InetAddress source, @NonNull InetAddress destination, @NonNull @CallbackExecutor Executor executor, @NonNull Callback callback) { - return new NattSocketKeepalive(mService, network, fd, INVALID_RESOURCE_ID /* Unused */, - source, destination, executor, callback); + ParcelFileDescriptor dup; + try { + dup = pfd.dup(); + } catch (IOException ignored) { + // Construct an invalid fd, so that if the user later calls start(), it will fail with + // ERROR_INVALID_SOCKET. + dup = new ParcelFileDescriptor(new FileDescriptor()); + } + return new NattSocketKeepalive(mService, network, dup, + INVALID_RESOURCE_ID /* Unused */, source, destination, executor, callback); } /** @@ -1984,11 +2006,19 @@ public class ConnectivityManager { */ @SystemApi @RequiresPermission(android.Manifest.permission.PACKET_KEEPALIVE_OFFLOAD) - public SocketKeepalive createSocketKeepalive(@NonNull Network network, + public @NonNull SocketKeepalive createSocketKeepalive(@NonNull Network network, @NonNull Socket socket, @NonNull Executor executor, @NonNull Callback callback) { - return new TcpSocketKeepalive(mService, network, socket, executor, callback); + ParcelFileDescriptor dup; + try { + dup = ParcelFileDescriptor.fromSocket(socket); + } catch (UncheckedIOException ignored) { + // Construct an invalid fd, so that if the user later calls start(), it will fail with + // ERROR_INVALID_SOCKET. + dup = new ParcelFileDescriptor(new FileDescriptor()); + } + return new TcpSocketKeepalive(mService, network, dup, executor, callback); } /** @@ -3320,7 +3350,7 @@ public class ConnectivityManager { * @param network The {@link Network} whose blocked status has changed. * @param blocked The blocked status of this {@link Network}. */ - public void onBlockedStatusChanged(Network network, boolean blocked) {} + public void onBlockedStatusChanged(@NonNull Network network, boolean blocked) {} private NetworkRequest networkRequest; } @@ -4088,7 +4118,7 @@ public class ConnectivityManager { @SystemApi @TestApi @RequiresPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) - public void startCaptivePortalApp(Network network, Bundle appExtras) { + public void startCaptivePortalApp(@NonNull Network network, @NonNull Bundle appExtras) { try { mService.startCaptivePortalAppInternal(network, appExtras); } catch (RemoteException e) { @@ -4101,9 +4131,12 @@ public class ConnectivityManager { * @hide */ @SystemApi - public boolean getAvoidBadWifi() { + @RequiresPermission(anyOf = { + NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, + android.Manifest.permission.NETWORK_STACK}) + public boolean shouldAvoidBadWifi() { try { - return mService.getAvoidBadWifi(); + return mService.shouldAvoidBadWifi(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/android/net/DnsResolver.java b/core/java/android/net/DnsResolver.java index 93b8cf801d4562fae0164805cd264b993d12720b..59802514c7a3c33a027332072a5d2f5531fe2bf6 100644 --- a/core/java/android/net/DnsResolver.java +++ b/core/java/android/net/DnsResolver.java @@ -16,6 +16,7 @@ package android.net; +import static android.net.NetworkUtils.resNetworkCancel; import static android.net.NetworkUtils.resNetworkQuery; import static android.net.NetworkUtils.resNetworkResult; import static android.net.NetworkUtils.resNetworkSend; @@ -26,6 +27,7 @@ import android.annotation.CallbackExecutor; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; +import android.os.CancellationSignal; import android.os.Looper; import android.system.ErrnoException; import android.util.Log; @@ -191,11 +193,18 @@ public final class DnsResolver { * @param query blob message * @param flags flags as a combination of the FLAGS_* constants * @param executor The {@link Executor} that the callback should be executed on. + * @param cancellationSignal used by the caller to signal if the query should be + * cancelled. May be {@code null}. * @param callback an {@link AnswerCallback} which will be called to notify the caller - * of the result of dns query. + * of the result of dns query. */ public void query(@Nullable Network network, @NonNull byte[] query, @QueryFlag int flags, - @NonNull @CallbackExecutor Executor executor, @NonNull AnswerCallback callback) { + @NonNull @CallbackExecutor Executor executor, + @Nullable CancellationSignal cancellationSignal, + @NonNull AnswerCallback callback) { + if (cancellationSignal != null && cancellationSignal.isCanceled()) { + return; + } final FileDescriptor queryfd; try { queryfd = resNetworkSend((network != null @@ -205,6 +214,7 @@ public final class DnsResolver { return; } + maybeAddCancellationSignal(cancellationSignal, queryfd); registerFDListener(executor, queryfd, callback); } @@ -219,12 +229,19 @@ public final class DnsResolver { * @param nsType dns resource record (RR) type as one of the TYPE_* constants * @param flags flags as a combination of the FLAGS_* constants * @param executor The {@link Executor} that the callback should be executed on. + * @param cancellationSignal used by the caller to signal if the query should be + * cancelled. May be {@code null}. * @param callback an {@link AnswerCallback} which will be called to notify the caller - * of the result of dns query. + * of the result of dns query. */ public void query(@Nullable Network network, @NonNull String domain, @QueryClass int nsClass, @QueryType int nsType, @QueryFlag int flags, - @NonNull @CallbackExecutor Executor executor, @NonNull AnswerCallback callback) { + @NonNull @CallbackExecutor Executor executor, + @Nullable CancellationSignal cancellationSignal, + @NonNull AnswerCallback callback) { + if (cancellationSignal != null && cancellationSignal.isCanceled()) { + return; + } final FileDescriptor queryfd; try { queryfd = resNetworkQuery((network != null @@ -233,6 +250,8 @@ public final class DnsResolver { callback.onQueryException(e); return; } + + maybeAddCancellationSignal(cancellationSignal, queryfd); registerFDListener(executor, queryfd, callback); } @@ -264,6 +283,17 @@ public final class DnsResolver { }); } + private void maybeAddCancellationSignal(@Nullable CancellationSignal cancellationSignal, + @NonNull FileDescriptor queryfd) { + if (cancellationSignal == null) return; + cancellationSignal.setOnCancelListener( + () -> { + Looper.getMainLooper().getQueue() + .removeOnFileDescriptorEventListener(queryfd); + resNetworkCancel(queryfd); + }); + } + private static class DnsAddressAnswer extends DnsPacket { private static final String TAG = "DnsResolver.DnsAddressAnswer"; private static final boolean DBG = false; diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl index 24e6a855ffe8e4d35b640878d959e2ad547b2dc9..61648dc7f1d8083e1b4730e41a2230ab2eb1ec98 100644 --- a/core/java/android/net/IConnectivityManager.aidl +++ b/core/java/android/net/IConnectivityManager.aidl @@ -182,7 +182,7 @@ interface IConnectivityManager void startCaptivePortalApp(in Network network); void startCaptivePortalAppInternal(in Network network, in Bundle appExtras); - boolean getAvoidBadWifi(); + boolean shouldAvoidBadWifi(); int getMultipathPreference(in Network Network); NetworkRequest getDefaultRequest(); diff --git a/core/java/android/net/IpPrefix.java b/core/java/android/net/IpPrefix.java index 21bbd304a81ba7b7c75230df055ea2d49e827857..402bffdc2a97b8b6478c05a65bee7a42bd4820e7 100644 --- a/core/java/android/net/IpPrefix.java +++ b/core/java/android/net/IpPrefix.java @@ -16,6 +16,7 @@ package android.net; +import android.annotation.NonNull; import android.annotation.SystemApi; import android.annotation.TestApi; import android.os.Parcel; @@ -70,7 +71,7 @@ public final class IpPrefix implements Parcelable { * * @hide */ - public IpPrefix(byte[] address, int prefixLength) { + public IpPrefix(@NonNull byte[] address, int prefixLength) { this.address = address.clone(); this.prefixLength = prefixLength; checkAndMaskAddressAndPrefixLength(); @@ -87,7 +88,7 @@ public final class IpPrefix implements Parcelable { */ @SystemApi @TestApi - public IpPrefix(InetAddress address, int prefixLength) { + public IpPrefix(@NonNull InetAddress address, int prefixLength) { // We don't reuse the (byte[], int) constructor because it calls clone() on the byte array, // which is unnecessary because getAddress() already returns a clone. this.address = address.getAddress(); @@ -106,7 +107,7 @@ public final class IpPrefix implements Parcelable { */ @SystemApi @TestApi - public IpPrefix(String prefix) { + public IpPrefix(@NonNull String prefix) { // We don't reuse the (InetAddress, int) constructor because "error: call to this must be // first statement in constructor". We could factor out setting the member variables to an // init() method, but if we did, then we'd have to make the members non-final, or "error: diff --git a/core/java/android/net/LinkAddress.java b/core/java/android/net/LinkAddress.java index 78a4e7293947958abce41cbafd6b1c10290957fb..333603f3a0f24d36b4f0fb4107bce2dcf6c64fe5 100644 --- a/core/java/android/net/LinkAddress.java +++ b/core/java/android/net/LinkAddress.java @@ -26,6 +26,7 @@ import static android.system.OsConstants.RT_SCOPE_SITE; import static android.system.OsConstants.RT_SCOPE_UNIVERSE; import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.TestApi; import android.annotation.UnsupportedAppUsage; @@ -107,8 +108,8 @@ public class LinkAddress implements Parcelable { * * Per RFC 4193 section 8, fc00::/7 identifies these addresses. */ - private boolean isIPv6ULA() { - if (isIPv6()) { + private boolean isIpv6ULA() { + if (isIpv6()) { byte[] bytes = address.getAddress(); return ((bytes[0] & (byte)0xfe) == (byte)0xfc); } @@ -121,17 +122,29 @@ public class LinkAddress implements Parcelable { */ @TestApi @SystemApi - public boolean isIPv6() { + public boolean isIpv6() { return address instanceof Inet6Address; } + /** + * For backward compatibility. + * This was annotated with @UnsupportedAppUsage in P, so we can't remove the method completely + * just yet. + * @return true if the address is IPv6. + * @hide + */ + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) + public boolean isIPv6() { + return isIpv6(); + } + /** * @return true if the address is IPv4 or is a mapped IPv4 address. * @hide */ @TestApi @SystemApi - public boolean isIPv4() { + public boolean isIpv4() { return address instanceof Inet4Address; } @@ -217,7 +230,7 @@ public class LinkAddress implements Parcelable { */ @SystemApi @TestApi - public LinkAddress(String address, int flags, int scope) { + public LinkAddress(@NonNull String address, int flags, int scope) { // This may throw an IllegalArgumentException; catching it is the caller's responsibility. // TODO: consider rejecting mapped IPv4 addresses such as "::ffff:192.0.2.5/24". Pair ipAndMask = NetworkUtils.parseIpAndMask(address); @@ -276,7 +289,10 @@ public class LinkAddress implements Parcelable { */ @TestApi @SystemApi - public boolean isSameAddressAs(LinkAddress other) { + public boolean isSameAddressAs(@Nullable LinkAddress other) { + if (other == null) { + return false; + } return address.equals(other.address) && prefixLength == other.prefixLength; } @@ -331,10 +347,10 @@ public class LinkAddress implements Parcelable { * state has cleared either DAD has succeeded or failed, and both * flags are cleared regardless). */ - return (scope == RT_SCOPE_UNIVERSE && - !isIPv6ULA() && - (flags & (IFA_F_DADFAILED | IFA_F_DEPRECATED)) == 0L && - ((flags & IFA_F_TENTATIVE) == 0L || (flags & IFA_F_OPTIMISTIC) != 0L)); + return (scope == RT_SCOPE_UNIVERSE + && !isIpv6ULA() + && (flags & (IFA_F_DADFAILED | IFA_F_DEPRECATED)) == 0L + && ((flags & IFA_F_TENTATIVE) == 0L || (flags & IFA_F_OPTIMISTIC) != 0L)); } /** diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java index b52b15e6dd51a2d14c0bbb4e1c1266d1caad5d92..d5ca6642a3c378a509e0a67028dde11304fc39db 100644 --- a/core/java/android/net/LinkProperties.java +++ b/core/java/android/net/LinkProperties.java @@ -54,11 +54,11 @@ public final class LinkProperties implements Parcelable { // The interface described by the network link. @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private String mIfaceName; - private ArrayList mLinkAddresses = new ArrayList<>(); - private ArrayList mDnses = new ArrayList<>(); + private final ArrayList mLinkAddresses = new ArrayList<>(); + private final ArrayList mDnses = new ArrayList<>(); // PCSCF addresses are addresses of SIP proxies that only exist for the IMS core service. - private ArrayList mPcscfs = new ArrayList(); - private ArrayList mValidatedPrivateDnses = new ArrayList<>(); + private final ArrayList mPcscfs = new ArrayList(); + private final ArrayList mValidatedPrivateDnses = new ArrayList<>(); private boolean mUsePrivateDns; private String mPrivateDnsServerName; private String mDomains; @@ -150,8 +150,8 @@ public final class LinkProperties implements Parcelable { // connections getting stuck until timeouts fire and other // baffling failures. Therefore, loss of either IPv4 or IPv6 on a // previously dual-stack network is deemed a lost of provisioning. - if ((before.isIPv4Provisioned() && !after.isIPv4Provisioned()) || - (before.isIPv6Provisioned() && !after.isIPv6Provisioned())) { + if ((before.isIpv4Provisioned() && !after.isIpv4Provisioned()) + || (before.isIpv6Provisioned() && !after.isIpv6Provisioned())) { return ProvisioningChange.LOST_PROVISIONING; } return ProvisioningChange.STILL_PROVISIONED; @@ -165,9 +165,8 @@ public final class LinkProperties implements Parcelable { } /** - * @hide + * Constructs a new {@code LinkProperties} with default values. */ - @SystemApi public LinkProperties() { } @@ -176,7 +175,7 @@ public final class LinkProperties implements Parcelable { */ @SystemApi @TestApi - public LinkProperties(LinkProperties source) { + public LinkProperties(@Nullable LinkProperties source) { if (source != null) { mIfaceName = source.mIfaceName; mLinkAddresses.addAll(source.mLinkAddresses); @@ -202,10 +201,8 @@ public final class LinkProperties implements Parcelable { * will have their interface changed to match this new value. * * @param iface The name of the network interface used for this link. - * @hide */ - @SystemApi - public void setInterfaceName(String iface) { + public void setInterfaceName(@Nullable String iface) { mIfaceName = iface; ArrayList newRoutes = new ArrayList<>(mRoutes.size()); for (RouteInfo route : mRoutes) { @@ -227,7 +224,7 @@ public final class LinkProperties implements Parcelable { * @hide */ @UnsupportedAppUsage - public List getAllInterfaceNames() { + public @NonNull List getAllInterfaceNames() { List interfaceNames = new ArrayList<>(mStackedLinks.size() + 1); if (mIfaceName != null) interfaceNames.add(mIfaceName); for (LinkProperties stacked: mStackedLinks.values()) { @@ -247,8 +244,8 @@ public final class LinkProperties implements Parcelable { * @hide */ @UnsupportedAppUsage - public List getAddresses() { - List addresses = new ArrayList<>(); + public @NonNull List getAddresses() { + final List addresses = new ArrayList<>(); for (LinkAddress linkAddress : mLinkAddresses) { addresses.add(linkAddress.getAddress()); } @@ -260,7 +257,7 @@ public final class LinkProperties implements Parcelable { * @hide */ @UnsupportedAppUsage - public List getAllAddresses() { + public @NonNull List getAllAddresses() { List addresses = new ArrayList<>(); for (LinkAddress linkAddress : mLinkAddresses) { addresses.add(linkAddress.getAddress()); @@ -289,7 +286,7 @@ public final class LinkProperties implements Parcelable { */ @SystemApi @TestApi - public boolean addLinkAddress(LinkAddress address) { + public boolean addLinkAddress(@NonNull LinkAddress address) { if (address == null) { return false; } @@ -318,7 +315,10 @@ public final class LinkProperties implements Parcelable { */ @SystemApi @TestApi - public boolean removeLinkAddress(LinkAddress toRemove) { + public boolean removeLinkAddress(@NonNull LinkAddress toRemove) { + if (toRemove == null) { + return false; + } int i = findLinkAddressIndex(toRemove); if (i >= 0) { mLinkAddresses.remove(i); @@ -333,7 +333,7 @@ public final class LinkProperties implements Parcelable { * * @return An unmodifiable {@link List} of {@link LinkAddress} for this link. */ - public List getLinkAddresses() { + public @NonNull List getLinkAddresses() { return Collections.unmodifiableList(mLinkAddresses); } @@ -356,10 +356,8 @@ public final class LinkProperties implements Parcelable { * * @param addresses The {@link Collection} of {@link LinkAddress} to set in this * object. - * @hide */ - @SystemApi - public void setLinkAddresses(Collection addresses) { + public void setLinkAddresses(@NonNull Collection addresses) { mLinkAddresses.clear(); for (LinkAddress address: addresses) { addLinkAddress(address); @@ -375,7 +373,7 @@ public final class LinkProperties implements Parcelable { */ @TestApi @SystemApi - public boolean addDnsServer(InetAddress dnsServer) { + public boolean addDnsServer(@NonNull InetAddress dnsServer) { if (dnsServer != null && !mDnses.contains(dnsServer)) { mDnses.add(dnsServer); return true; @@ -392,7 +390,7 @@ public final class LinkProperties implements Parcelable { */ @TestApi @SystemApi - public boolean removeDnsServer(InetAddress dnsServer) { + public boolean removeDnsServer(@NonNull InetAddress dnsServer) { if (dnsServer != null) { return mDnses.remove(dnsServer); } @@ -404,10 +402,8 @@ public final class LinkProperties implements Parcelable { * the given {@link Collection} of {@link InetAddress} objects. * * @param dnsServers The {@link Collection} of DNS servers to set in this object. - * @hide */ - @SystemApi - public void setDnsServers(Collection dnsServers) { + public void setDnsServers(@NonNull Collection dnsServers) { mDnses.clear(); for (InetAddress dnsServer: dnsServers) { addDnsServer(dnsServer); @@ -420,7 +416,7 @@ public final class LinkProperties implements Parcelable { * @return An unmodifiable {@link List} of {@link InetAddress} for DNS servers on * this link. */ - public List getDnsServers() { + public @NonNull List getDnsServers() { return Collections.unmodifiableList(mDnses); } @@ -490,7 +486,7 @@ public final class LinkProperties implements Parcelable { * @return true if the DNS server was added, false if it was already present. * @hide */ - public boolean addValidatedPrivateDnsServer(InetAddress dnsServer) { + public boolean addValidatedPrivateDnsServer(@NonNull InetAddress dnsServer) { if (dnsServer != null && !mValidatedPrivateDnses.contains(dnsServer)) { mValidatedPrivateDnses.add(dnsServer); return true; @@ -506,11 +502,8 @@ public final class LinkProperties implements Parcelable { * @return true if the DNS server was removed, false if it did not exist. * @hide */ - public boolean removeValidatedPrivateDnsServer(InetAddress dnsServer) { - if (dnsServer != null) { - return mValidatedPrivateDnses.remove(dnsServer); - } - return false; + public boolean removeValidatedPrivateDnsServer(@NonNull InetAddress dnsServer) { + return mValidatedPrivateDnses.remove(dnsServer); } /** @@ -523,7 +516,7 @@ public final class LinkProperties implements Parcelable { */ @TestApi @SystemApi - public void setValidatedPrivateDnsServers(Collection dnsServers) { + public void setValidatedPrivateDnsServers(@NonNull Collection dnsServers) { mValidatedPrivateDnses.clear(); for (InetAddress dnsServer: dnsServers) { addValidatedPrivateDnsServer(dnsServer); @@ -534,13 +527,13 @@ public final class LinkProperties implements Parcelable { * Returns all the {@link InetAddress} for validated private DNS servers on this link. * These are resolved from the private DNS server name. * - * @return An umodifiable {@link List} of {@link InetAddress} for validated private + * @return An unmodifiable {@link List} of {@link InetAddress} for validated private * DNS servers on this link. * @hide */ @TestApi @SystemApi - public List getValidatedPrivateDnsServers() { + public @NonNull List getValidatedPrivateDnsServers() { return Collections.unmodifiableList(mValidatedPrivateDnses); } @@ -551,7 +544,7 @@ public final class LinkProperties implements Parcelable { * @return true if the PCSCF server was added, false otherwise. * @hide */ - public boolean addPcscfServer(InetAddress pcscfServer) { + public boolean addPcscfServer(@NonNull InetAddress pcscfServer) { if (pcscfServer != null && !mPcscfs.contains(pcscfServer)) { mPcscfs.add(pcscfServer); return true; @@ -562,27 +555,24 @@ public final class LinkProperties implements Parcelable { /** * Removes the given {@link InetAddress} from the list of PCSCF servers. * - * @param pcscf Server The {@link InetAddress} to remove from the list of PCSCF servers. + * @param pcscfServer The {@link InetAddress} to remove from the list of PCSCF servers. * @return true if the PCSCF server was removed, false otherwise. * @hide */ - public boolean removePcscfServer(InetAddress pcscfServer) { - if (pcscfServer != null) { - return mPcscfs.remove(pcscfServer); - } - return false; + public boolean removePcscfServer(@NonNull InetAddress pcscfServer) { + return mPcscfs.remove(pcscfServer); } /** * Replaces the PCSCF servers in this {@code LinkProperties} with * the given {@link Collection} of {@link InetAddress} objects. * - * @param addresses The {@link Collection} of PCSCF servers to set in this object. + * @param pcscfServers The {@link Collection} of PCSCF servers to set in this object. * @hide */ @SystemApi @TestApi - public void setPcscfServers(Collection pcscfServers) { + public void setPcscfServers(@NonNull Collection pcscfServers) { mPcscfs.clear(); for (InetAddress pcscfServer: pcscfServers) { addPcscfServer(pcscfServer); @@ -598,7 +588,7 @@ public final class LinkProperties implements Parcelable { */ @SystemApi @TestApi - public List getPcscfServers() { + public @NonNull List getPcscfServers() { return Collections.unmodifiableList(mPcscfs); } @@ -607,20 +597,18 @@ public final class LinkProperties implements Parcelable { * * @param domains A {@link String} listing in priority order the comma separated * domains to search when resolving host names on this link. - * @hide */ - @SystemApi - public void setDomains(String domains) { + public void setDomains(@Nullable String domains) { mDomains = domains; } /** - * Get the DNS domains search path set for this link. + * Get the DNS domains search path set for this link. May be {@code null} if not set. * - * @return A {@link String} containing the comma separated domains to search when resolving - * host names on this link. + * @return A {@link String} containing the comma separated domains to search when resolving host + * names on this link or {@code null}. */ - public String getDomains() { + public @Nullable String getDomains() { return mDomains; } @@ -630,9 +618,7 @@ public final class LinkProperties implements Parcelable { * 10000 will be ignored. * * @param mtu The MTU to use for this link. - * @hide */ - @SystemApi public void setMtu(int mtu) { mMtu = mtu; } @@ -657,20 +643,20 @@ public final class LinkProperties implements Parcelable { */ @TestApi @SystemApi - public void setTcpBufferSizes(String tcpBufferSizes) { + public void setTcpBufferSizes(@Nullable String tcpBufferSizes) { mTcpBufferSizes = tcpBufferSizes; } /** - * Gets the tcp buffer sizes. + * Gets the tcp buffer sizes. May be {@code null} if not set. * - * @return the tcp buffer sizes to use when this link is the system default. + * @return the tcp buffer sizes to use when this link is the system default or {@code null}. * * @hide */ @TestApi @SystemApi - public String getTcpBufferSizes() { + public @Nullable String getTcpBufferSizes() { return mTcpBufferSizes; } @@ -690,23 +676,18 @@ public final class LinkProperties implements Parcelable { * * @param route A {@link RouteInfo} to add to this object. * @return {@code false} if the route was already present, {@code true} if it was added. - * - * @hide */ - @SystemApi - public boolean addRoute(RouteInfo route) { - if (route != null) { - String routeIface = route.getInterface(); - if (routeIface != null && !routeIface.equals(mIfaceName)) { - throw new IllegalArgumentException( - "Route added with non-matching interface: " + routeIface + - " vs. " + mIfaceName); - } - route = routeWithInterface(route); - if (!mRoutes.contains(route)) { - mRoutes.add(route); - return true; - } + public boolean addRoute(@NonNull RouteInfo route) { + String routeIface = route.getInterface(); + if (routeIface != null && !routeIface.equals(mIfaceName)) { + throw new IllegalArgumentException( + "Route added with non-matching interface: " + routeIface + + " vs. " + mIfaceName); + } + route = routeWithInterface(route); + if (!mRoutes.contains(route)) { + mRoutes.add(route); + return true; } return false; } @@ -722,10 +703,8 @@ public final class LinkProperties implements Parcelable { */ @TestApi @SystemApi - public boolean removeRoute(RouteInfo route) { - return route != null && - Objects.equals(mIfaceName, route.getInterface()) && - mRoutes.remove(route); + public boolean removeRoute(@NonNull RouteInfo route) { + return Objects.equals(mIfaceName, route.getInterface()) && mRoutes.remove(route); } /** @@ -733,7 +712,7 @@ public final class LinkProperties implements Parcelable { * * @return An unmodifiable {@link List} of {@link RouteInfo} for this link. */ - public List getRoutes() { + public @NonNull List getRoutes() { return Collections.unmodifiableList(mRoutes); } @@ -753,7 +732,7 @@ public final class LinkProperties implements Parcelable { * @hide */ @UnsupportedAppUsage - public List getAllRoutes() { + public @NonNull List getAllRoutes() { List routes = new ArrayList<>(mRoutes); for (LinkProperties stacked: mStackedLinks.values()) { routes.addAll(stacked.getAllRoutes()); @@ -767,26 +746,24 @@ public final class LinkProperties implements Parcelable { * not enforce it and applications may ignore them. * * @param proxy A {@link ProxyInfo} defining the HTTP Proxy to use on this link. - * @hide */ - @SystemApi - public void setHttpProxy(ProxyInfo proxy) { + public void setHttpProxy(@Nullable ProxyInfo proxy) { mHttpProxy = proxy; } /** * Gets the recommended {@link ProxyInfo} (or {@code null}) set on this link. * - * @return The {@link ProxyInfo} set on this link + * @return The {@link ProxyInfo} set on this link or {@code null}. */ - public ProxyInfo getHttpProxy() { + public @Nullable ProxyInfo getHttpProxy() { return mHttpProxy; } /** * Returns the NAT64 prefix in use on this link, if any. * - * @return the NAT64 prefix. + * @return the NAT64 prefix or {@code null}. * @hide */ @SystemApi @@ -799,14 +776,14 @@ public final class LinkProperties implements Parcelable { * Sets the NAT64 prefix in use on this link. * * Currently, only 96-bit prefixes (i.e., where the 32-bit IPv4 address is at the end of the - * 128-bit IPv6 address) are supported. + * 128-bit IPv6 address) are supported or {@code null} for no prefix. * * @param prefix the NAT64 prefix. * @hide */ @SystemApi @TestApi - public void setNat64Prefix(IpPrefix prefix) { + public void setNat64Prefix(@Nullable IpPrefix prefix) { if (prefix != null && prefix.getPrefixLength() != 96) { throw new IllegalArgumentException("Only 96-bit prefixes are supported: " + prefix); } @@ -818,15 +795,15 @@ public final class LinkProperties implements Parcelable { * * If there is already a stacked link with the same interface name as link, * that link is replaced with link. Otherwise, link is added to the list - * of stacked links. If link is null, nothing changes. + * of stacked links. * * @param link The link to add. * @return true if the link was stacked, false otherwise. * @hide */ @UnsupportedAppUsage - public boolean addStackedLink(LinkProperties link) { - if (link != null && link.getInterfaceName() != null) { + public boolean addStackedLink(@NonNull LinkProperties link) { + if (link.getInterfaceName() != null) { mStackedLinks.put(link.getInterfaceName(), link); return true; } @@ -843,12 +820,9 @@ public final class LinkProperties implements Parcelable { * @return true if the link was removed, false otherwise. * @hide */ - public boolean removeStackedLink(String iface) { - if (iface != null) { - LinkProperties removed = mStackedLinks.remove(iface); - return removed != null; - } - return false; + public boolean removeStackedLink(@NonNull String iface) { + LinkProperties removed = mStackedLinks.remove(iface); + return removed != null; } /** @@ -860,7 +834,7 @@ public final class LinkProperties implements Parcelable { if (mStackedLinks.isEmpty()) { return Collections.emptyList(); } - List stacked = new ArrayList<>(); + final List stacked = new ArrayList<>(); for (LinkProperties link : mStackedLinks.values()) { stacked.add(new LinkProperties(link)); } @@ -869,9 +843,7 @@ public final class LinkProperties implements Parcelable { /** * Clears this object to its initial state. - * @hide */ - @SystemApi public void clear() { mIfaceName = null; mLinkAddresses.clear(); @@ -988,7 +960,7 @@ public final class LinkProperties implements Parcelable { */ @TestApi @SystemApi - public boolean hasIPv4Address() { + public boolean hasIpv4Address() { for (LinkAddress address : mLinkAddresses) { if (address.getAddress() instanceof Inet4Address) { return true; @@ -997,16 +969,28 @@ public final class LinkProperties implements Parcelable { return false; } + /** + * For backward compatibility. + * This was annotated with @UnsupportedAppUsage in P, so we can't remove the method completely + * just yet. + * @return {@code true} if there is an IPv4 address, {@code false} otherwise. + * @hide + */ + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) + public boolean hasIPv4Address() { + return hasIpv4Address(); + } + /** * Returns true if this link or any of its stacked interfaces has an IPv4 address. * * @return {@code true} if there is an IPv4 address, {@code false} otherwise. */ - private boolean hasIPv4AddressOnInterface(String iface) { + private boolean hasIpv4AddressOnInterface(String iface) { // mIfaceName can be null. - return (Objects.equals(iface, mIfaceName) && hasIPv4Address()) || - (iface != null && mStackedLinks.containsKey(iface) && - mStackedLinks.get(iface).hasIPv4Address()); + return (Objects.equals(iface, mIfaceName) && hasIpv4Address()) + || (iface != null && mStackedLinks.containsKey(iface) + && mStackedLinks.get(iface).hasIpv4Address()); } /** @@ -1017,7 +1001,7 @@ public final class LinkProperties implements Parcelable { */ @TestApi @SystemApi - public boolean hasGlobalIPv6Address() { + public boolean hasGlobalIpv6Address() { for (LinkAddress address : mLinkAddresses) { if (address.getAddress() instanceof Inet6Address && address.isGlobalPreferred()) { return true; @@ -1026,6 +1010,18 @@ public final class LinkProperties implements Parcelable { return false; } + /** + * For backward compatibility. + * This was annotated with @UnsupportedAppUsage in P, so we can't remove the method completely + * just yet. + * @return {@code true} if there is a global preferred IPv6 address, {@code false} otherwise. + * @hide + */ + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) + public boolean hasGlobalIPv6Address() { + return hasGlobalIpv6Address(); + } + /** * Returns true if this link has an IPv4 default route. * @@ -1033,7 +1029,7 @@ public final class LinkProperties implements Parcelable { * @hide */ @UnsupportedAppUsage - public boolean hasIPv4DefaultRoute() { + public boolean hasIpv4DefaultRoute() { for (RouteInfo r : mRoutes) { if (r.isIPv4Default()) { return true; @@ -1042,6 +1038,18 @@ public final class LinkProperties implements Parcelable { return false; } + /** + * For backward compatibility. + * This was annotated with @UnsupportedAppUsage in P, so we can't remove the method completely + * just yet. + * @return {@code true} if there is an IPv4 default route, {@code false} otherwise. + * @hide + */ + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) + public boolean hasIPv4DefaultRoute() { + return hasIpv4DefaultRoute(); + } + /** * Returns true if this link has an IPv6 default route. * @@ -1050,7 +1058,7 @@ public final class LinkProperties implements Parcelable { */ @TestApi @SystemApi - public boolean hasIPv6DefaultRoute() { + public boolean hasIpv6DefaultRoute() { for (RouteInfo r : mRoutes) { if (r.isIPv6Default()) { return true; @@ -1059,6 +1067,18 @@ public final class LinkProperties implements Parcelable { return false; } + /** + * For backward compatibility. + * This was annotated with @UnsupportedAppUsage in P, so we can't remove the method completely + * just yet. + * @return {@code true} if there is an IPv6 default route, {@code false} otherwise. + * @hide + */ + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) + public boolean hasIPv6DefaultRoute() { + return hasIpv6DefaultRoute(); + } + /** * Returns true if this link has an IPv4 DNS server. * @@ -1066,7 +1086,7 @@ public final class LinkProperties implements Parcelable { * @hide */ @UnsupportedAppUsage - public boolean hasIPv4DnsServer() { + public boolean hasIpv4DnsServer() { for (InetAddress ia : mDnses) { if (ia instanceof Inet4Address) { return true; @@ -1075,6 +1095,18 @@ public final class LinkProperties implements Parcelable { return false; } + /** + * For backward compatibility. + * This was annotated with @UnsupportedAppUsage in P, so we can't remove the method completely + * just yet. + * @return {@code true} if there is an IPv4 DNS server, {@code false} otherwise. + * @hide + */ + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) + public boolean hasIPv4DnsServer() { + return hasIpv4DnsServer(); + } + /** * Returns true if this link has an IPv6 DNS server. * @@ -1082,7 +1114,7 @@ public final class LinkProperties implements Parcelable { * @hide */ @UnsupportedAppUsage - public boolean hasIPv6DnsServer() { + public boolean hasIpv6DnsServer() { for (InetAddress ia : mDnses) { if (ia instanceof Inet6Address) { return true; @@ -1091,13 +1123,25 @@ public final class LinkProperties implements Parcelable { return false; } + /** + * For backward compatibility. + * This was annotated with @UnsupportedAppUsage in P, so we can't remove the method completely + * just yet. + * @return {@code true} if there is an IPv6 DNS server, {@code false} otherwise. + * @hide + */ + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) + public boolean hasIPv6DnsServer() { + return hasIpv6DnsServer(); + } + /** * Returns true if this link has an IPv4 PCSCF server. * * @return {@code true} if there is an IPv4 PCSCF server, {@code false} otherwise. * @hide */ - public boolean hasIPv4PcscfServer() { + public boolean hasIpv4PcscfServer() { for (InetAddress ia : mPcscfs) { if (ia instanceof Inet4Address) { return true; @@ -1112,7 +1156,7 @@ public final class LinkProperties implements Parcelable { * @return {@code true} if there is an IPv6 PCSCF server, {@code false} otherwise. * @hide */ - public boolean hasIPv6PcscfServer() { + public boolean hasIpv6PcscfServer() { for (InetAddress ia : mPcscfs) { if (ia instanceof Inet6Address) { return true; @@ -1130,10 +1174,10 @@ public final class LinkProperties implements Parcelable { */ @TestApi @SystemApi - public boolean isIPv4Provisioned() { - return (hasIPv4Address() && - hasIPv4DefaultRoute() && - hasIPv4DnsServer()); + public boolean isIpv4Provisioned() { + return (hasIpv4Address() + && hasIpv4DefaultRoute() + && hasIpv4DnsServer()); } /** @@ -1145,12 +1189,25 @@ public final class LinkProperties implements Parcelable { */ @TestApi @SystemApi + public boolean isIpv6Provisioned() { + return (hasGlobalIpv6Address() + && hasIpv6DefaultRoute() + && hasIpv6DnsServer()); + } + + /** + * For backward compatibility. + * This was annotated with @UnsupportedAppUsage in P, so we can't remove the method completely + * just yet. + * @return {@code true} if the link is provisioned, {@code false} otherwise. + * @hide + */ + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) public boolean isIPv6Provisioned() { - return (hasGlobalIPv6Address() && - hasIPv6DefaultRoute() && - hasIPv6DnsServer()); + return isIpv6Provisioned(); } + /** * Returns true if this link is provisioned for global connectivity, * for at least one Internet Protocol family. @@ -1161,7 +1218,7 @@ public final class LinkProperties implements Parcelable { @TestApi @SystemApi public boolean isProvisioned() { - return (isIPv4Provisioned() || isIPv6Provisioned()); + return (isIpv4Provisioned() || isIpv6Provisioned()); } /** @@ -1173,7 +1230,7 @@ public final class LinkProperties implements Parcelable { */ @TestApi @SystemApi - public boolean isReachable(InetAddress ip) { + public boolean isReachable(@NonNull InetAddress ip) { final List allRoutes = getAllRoutes(); // If we don't have a route to this IP address, it's not reachable. final RouteInfo bestRoute = RouteInfo.selectBestRoute(allRoutes, ip); @@ -1185,7 +1242,7 @@ public final class LinkProperties implements Parcelable { if (ip instanceof Inet4Address) { // For IPv4, it suffices for now to simply have any address. - return hasIPv4AddressOnInterface(bestRoute.getInterface()); + return hasIpv4AddressOnInterface(bestRoute.getInterface()); } else if (ip instanceof Inet6Address) { if (ip.isLinkLocalAddress()) { // For now, just make sure link-local destinations have @@ -1196,7 +1253,7 @@ public final class LinkProperties implements Parcelable { // For non-link-local destinations check that either the best route // is directly connected or that some global preferred address exists. // TODO: reconsider all cases (disconnected ULA networks, ...). - return (!bestRoute.hasGateway() || hasGlobalIPv6Address()); + return (!bestRoute.hasGateway() || hasGlobalIpv6Address()); } } @@ -1211,7 +1268,7 @@ public final class LinkProperties implements Parcelable { * @hide */ @UnsupportedAppUsage - public boolean isIdenticalInterfaceName(LinkProperties target) { + public boolean isIdenticalInterfaceName(@NonNull LinkProperties target) { return TextUtils.equals(getInterfaceName(), target.getInterfaceName()); } @@ -1223,7 +1280,7 @@ public final class LinkProperties implements Parcelable { * @hide */ @UnsupportedAppUsage - public boolean isIdenticalAddresses(LinkProperties target) { + public boolean isIdenticalAddresses(@NonNull LinkProperties target) { Collection targetAddresses = target.getAddresses(); Collection sourceAddresses = getAddresses(); return (sourceAddresses.size() == targetAddresses.size()) ? @@ -1238,7 +1295,7 @@ public final class LinkProperties implements Parcelable { * @hide */ @UnsupportedAppUsage - public boolean isIdenticalDnses(LinkProperties target) { + public boolean isIdenticalDnses(@NonNull LinkProperties target) { Collection targetDnses = target.getDnsServers(); String targetDomains = target.getDomains(); if (mDomains == null) { @@ -1258,7 +1315,7 @@ public final class LinkProperties implements Parcelable { * @return {@code true} if both are identical, {@code false} otherwise. * @hide */ - public boolean isIdenticalPrivateDns(LinkProperties target) { + public boolean isIdenticalPrivateDns(@NonNull LinkProperties target) { return (isPrivateDnsActive() == target.isPrivateDnsActive() && TextUtils.equals(getPrivateDnsServerName(), target.getPrivateDnsServerName())); @@ -1272,7 +1329,7 @@ public final class LinkProperties implements Parcelable { * @return {@code true} if both are identical, {@code false} otherwise. * @hide */ - public boolean isIdenticalValidatedPrivateDnses(LinkProperties target) { + public boolean isIdenticalValidatedPrivateDnses(@NonNull LinkProperties target) { Collection targetDnses = target.getValidatedPrivateDnsServers(); return (mValidatedPrivateDnses.size() == targetDnses.size()) ? mValidatedPrivateDnses.containsAll(targetDnses) : false; @@ -1285,7 +1342,7 @@ public final class LinkProperties implements Parcelable { * @return {@code true} if both are identical, {@code false} otherwise. * @hide */ - public boolean isIdenticalPcscfs(LinkProperties target) { + public boolean isIdenticalPcscfs(@NonNull LinkProperties target) { Collection targetPcscfs = target.getPcscfServers(); return (mPcscfs.size() == targetPcscfs.size()) ? mPcscfs.containsAll(targetPcscfs) : false; @@ -1299,7 +1356,7 @@ public final class LinkProperties implements Parcelable { * @hide */ @UnsupportedAppUsage - public boolean isIdenticalRoutes(LinkProperties target) { + public boolean isIdenticalRoutes(@NonNull LinkProperties target) { Collection targetRoutes = target.getRoutes(); return (mRoutes.size() == targetRoutes.size()) ? mRoutes.containsAll(targetRoutes) : false; @@ -1313,7 +1370,7 @@ public final class LinkProperties implements Parcelable { * @hide */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) - public boolean isIdenticalHttpProxy(LinkProperties target) { + public boolean isIdenticalHttpProxy(@NonNull LinkProperties target) { return getHttpProxy() == null ? target.getHttpProxy() == null : getHttpProxy().equals(target.getHttpProxy()); } @@ -1326,7 +1383,7 @@ public final class LinkProperties implements Parcelable { * @hide */ @UnsupportedAppUsage - public boolean isIdenticalStackedLinks(LinkProperties target) { + public boolean isIdenticalStackedLinks(@NonNull LinkProperties target) { if (!mStackedLinks.keySet().equals(target.mStackedLinks.keySet())) { return false; } @@ -1347,7 +1404,7 @@ public final class LinkProperties implements Parcelable { * @return {@code true} if both are identical, {@code false} otherwise. * @hide */ - public boolean isIdenticalMtu(LinkProperties target) { + public boolean isIdenticalMtu(@NonNull LinkProperties target) { return getMtu() == target.getMtu(); } @@ -1358,7 +1415,7 @@ public final class LinkProperties implements Parcelable { * @return {@code true} if both are identical, {@code false} otherwise. * @hide */ - public boolean isIdenticalTcpBufferSizes(LinkProperties target) { + public boolean isIdenticalTcpBufferSizes(@NonNull LinkProperties target) { return Objects.equals(mTcpBufferSizes, target.mTcpBufferSizes); } @@ -1369,7 +1426,7 @@ public final class LinkProperties implements Parcelable { * @return {@code true} if both are identical, {@code false} otherwise. * @hide */ - public boolean isIdenticalNat64Prefix(LinkProperties target) { + public boolean isIdenticalNat64Prefix(@NonNull LinkProperties target) { return Objects.equals(mNat64Prefix, target.mNat64Prefix); } @@ -1421,7 +1478,7 @@ public final class LinkProperties implements Parcelable { * @return the differences between the addresses. * @hide */ - public CompareResult compareAddresses(LinkProperties target) { + public @NonNull CompareResult compareAddresses(@Nullable LinkProperties target) { /* * Duplicate the LinkAddresses into removed, we will be removing * address which are common between mLinkAddresses and target @@ -1441,7 +1498,7 @@ public final class LinkProperties implements Parcelable { * @return the differences between the DNS addresses. * @hide */ - public CompareResult compareDnses(LinkProperties target) { + public @NonNull CompareResult compareDnses(@Nullable LinkProperties target) { /* * Duplicate the InetAddresses into removed, we will be removing * dns address which are common between mDnses and target @@ -1460,7 +1517,8 @@ public final class LinkProperties implements Parcelable { * @return the differences between the DNS addresses. * @hide */ - public CompareResult compareValidatedPrivateDnses(LinkProperties target) { + public @NonNull CompareResult compareValidatedPrivateDnses( + @Nullable LinkProperties target) { return new CompareResult<>(mValidatedPrivateDnses, target != null ? target.getValidatedPrivateDnsServers() : null); } @@ -1473,7 +1531,7 @@ public final class LinkProperties implements Parcelable { * @return the differences between the routes. * @hide */ - public CompareResult compareAllRoutes(LinkProperties target) { + public @NonNull CompareResult compareAllRoutes(@Nullable LinkProperties target) { /* * Duplicate the RouteInfos into removed, we will be removing * routes which are common between mRoutes and target @@ -1491,7 +1549,8 @@ public final class LinkProperties implements Parcelable { * @return the differences between the interface names. * @hide */ - public CompareResult compareAllInterfaceNames(LinkProperties target) { + public @NonNull CompareResult compareAllInterfaceNames( + @Nullable LinkProperties target) { /* * Duplicate the interface names into removed, we will be removing * interface names which are common between this and target diff --git a/core/java/android/net/NattSocketKeepalive.java b/core/java/android/net/NattSocketKeepalive.java index 84da294f8940d1718dcb6eed4dc46077b8008337..b0ce0c71fbeb8da7279f4dda74cdfd526e3cf944 100644 --- a/core/java/android/net/NattSocketKeepalive.java +++ b/core/java/android/net/NattSocketKeepalive.java @@ -17,10 +17,10 @@ package android.net; import android.annotation.NonNull; +import android.os.ParcelFileDescriptor; import android.os.RemoteException; import android.util.Log; -import java.io.FileDescriptor; import java.net.InetAddress; import java.util.concurrent.Executor; @@ -31,21 +31,19 @@ public final class NattSocketKeepalive extends SocketKeepalive { @NonNull private final InetAddress mSource; @NonNull private final InetAddress mDestination; - @NonNull private final FileDescriptor mFd; private final int mResourceId; NattSocketKeepalive(@NonNull IConnectivityManager service, @NonNull Network network, - @NonNull FileDescriptor fd, + @NonNull ParcelFileDescriptor pfd, int resourceId, @NonNull InetAddress source, @NonNull InetAddress destination, @NonNull Executor executor, @NonNull Callback callback) { - super(service, network, executor, callback); + super(service, network, pfd, executor, callback); mSource = source; mDestination = destination; - mFd = fd; mResourceId = resourceId; } @@ -53,8 +51,8 @@ public final class NattSocketKeepalive extends SocketKeepalive { void startImpl(int intervalSec) { mExecutor.execute(() -> { try { - mService.startNattKeepaliveWithFd(mNetwork, mFd, mResourceId, intervalSec, - mCallback, + mService.startNattKeepaliveWithFd(mNetwork, mPfd.getFileDescriptor(), mResourceId, + intervalSec, mCallback, mSource.getHostAddress(), mDestination.getHostAddress()); } catch (RemoteException e) { Log.e(TAG, "Error starting socket keepalive: ", e); @@ -75,6 +73,5 @@ public final class NattSocketKeepalive extends SocketKeepalive { throw e.rethrowFromSystemServer(); } }); - } } diff --git a/core/java/android/net/Network.java b/core/java/android/net/Network.java index 0fafdf76b491ae2617c09cea8e45dd70533027ba..3f56def6d7d588546914ab2d12cb4a5f3ed41a31 100644 --- a/core/java/android/net/Network.java +++ b/core/java/android/net/Network.java @@ -16,6 +16,7 @@ package android.net; +import android.annotation.NonNull; import android.annotation.SystemApi; import android.annotation.TestApi; import android.annotation.UnsupportedAppUsage; @@ -125,7 +126,7 @@ public class Network implements Parcelable { */ @SystemApi @TestApi - public Network(Network that) { + public Network(@NonNull Network that) { this(that.netId, that.mPrivateDnsBypass); } @@ -163,7 +164,7 @@ public class Network implements Parcelable { */ @TestApi @SystemApi - public Network getPrivateDnsBypassingCopy() { + public @NonNull Network getPrivateDnsBypassingCopy() { return new Network(netId, true); } diff --git a/core/java/android/net/NetworkAgent.java b/core/java/android/net/NetworkAgent.java index 273f8cd4f21dc9c303d3835ee2bbaf2375fcbc06..419fa7a61de557fbb1aba1df266dd823a03b58b1 100644 --- a/core/java/android/net/NetworkAgent.java +++ b/core/java/android/net/NetworkAgent.java @@ -488,14 +488,14 @@ public abstract class NetworkAgent extends Handler { * Requests that the network hardware send the specified packet at the specified interval. */ protected void startSocketKeepalive(Message msg) { - onSocketKeepaliveEvent(msg.arg1, SocketKeepalive.ERROR_HARDWARE_UNSUPPORTED); + onSocketKeepaliveEvent(msg.arg1, SocketKeepalive.ERROR_UNSUPPORTED); } /** * Requests that the network hardware send the specified packet at the specified interval. */ protected void stopSocketKeepalive(Message msg) { - onSocketKeepaliveEvent(msg.arg1, SocketKeepalive.ERROR_HARDWARE_UNSUPPORTED); + onSocketKeepaliveEvent(msg.arg1, SocketKeepalive.ERROR_UNSUPPORTED); } /** @@ -511,7 +511,7 @@ public abstract class NetworkAgent extends Handler { * override this method. */ protected void addKeepalivePacketFilter(Message msg) { - onSocketKeepaliveEvent(msg.arg1, SocketKeepalive.ERROR_HARDWARE_UNSUPPORTED); + onSocketKeepaliveEvent(msg.arg1, SocketKeepalive.ERROR_UNSUPPORTED); } /** @@ -520,7 +520,7 @@ public abstract class NetworkAgent extends Handler { * must override this method. */ protected void removeKeepalivePacketFilter(Message msg) { - onSocketKeepaliveEvent(msg.arg1, SocketKeepalive.ERROR_HARDWARE_UNSUPPORTED); + onSocketKeepaliveEvent(msg.arg1, SocketKeepalive.ERROR_UNSUPPORTED); } /** diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java index c57ae0c9fc3212ce2ad39be10d39925ce055b8ed..02145f2705c78f9d7cc947b085fb02f7b11829fc 100644 --- a/core/java/android/net/NetworkCapabilities.java +++ b/core/java/android/net/NetworkCapabilities.java @@ -17,6 +17,7 @@ package android.net; import android.annotation.IntDef; +import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.TestApi; @@ -91,7 +92,7 @@ public final class NetworkCapabilities implements Parcelable { * Set all contents of this object to the contents of a NetworkCapabilities. * @hide */ - public void set(NetworkCapabilities nc) { + public void set(@NonNull NetworkCapabilities nc) { mNetworkCapabilities = nc.mNetworkCapabilities; mTransportTypes = nc.mTransportTypes; mLinkUpBandwidthKbps = nc.mLinkUpBandwidthKbps; @@ -405,7 +406,7 @@ public final class NetworkCapabilities implements Parcelable { * @hide */ @UnsupportedAppUsage - public NetworkCapabilities addCapability(@NetCapability int capability) { + public @NonNull NetworkCapabilities addCapability(@NetCapability int capability) { checkValidCapability(capability); mNetworkCapabilities |= 1 << capability; mUnwantedNetworkCapabilities &= ~(1 << capability); // remove from unwanted capability list @@ -442,7 +443,7 @@ public final class NetworkCapabilities implements Parcelable { * @hide */ @UnsupportedAppUsage - public NetworkCapabilities removeCapability(@NetCapability int capability) { + public @NonNull NetworkCapabilities removeCapability(@NetCapability int capability) { checkValidCapability(capability); final long mask = ~(1 << capability); mNetworkCapabilities &= mask; @@ -456,7 +457,8 @@ public final class NetworkCapabilities implements Parcelable { * * @hide */ - public NetworkCapabilities setCapability(@NetCapability int capability, boolean value) { + public @NonNull NetworkCapabilities setCapability(@NetCapability int capability, + boolean value) { if (value) { addCapability(capability); } else { @@ -534,7 +536,7 @@ public final class NetworkCapabilities implements Parcelable { } /** Note this method may result in having the same capability in wanted and unwanted lists. */ - private void combineNetCapabilities(NetworkCapabilities nc) { + private void combineNetCapabilities(@NonNull NetworkCapabilities nc) { this.mNetworkCapabilities |= nc.mNetworkCapabilities; this.mUnwantedNetworkCapabilities |= nc.mUnwantedNetworkCapabilities; } @@ -546,7 +548,7 @@ public final class NetworkCapabilities implements Parcelable { * * @hide */ - public String describeFirstNonRequestableCapability() { + public @Nullable String describeFirstNonRequestableCapability() { final long nonRequestable = (mNetworkCapabilities | mUnwantedNetworkCapabilities) & NON_REQUESTABLE_CAPABILITIES; @@ -558,7 +560,8 @@ public final class NetworkCapabilities implements Parcelable { return null; } - private boolean satisfiedByNetCapabilities(NetworkCapabilities nc, boolean onlyImmutable) { + private boolean satisfiedByNetCapabilities(@NonNull NetworkCapabilities nc, + boolean onlyImmutable) { long requestedCapabilities = mNetworkCapabilities; long requestedUnwantedCapabilities = mUnwantedNetworkCapabilities; long providedCapabilities = nc.mNetworkCapabilities; @@ -572,12 +575,12 @@ public final class NetworkCapabilities implements Parcelable { } /** @hide */ - public boolean equalsNetCapabilities(NetworkCapabilities nc) { + public boolean equalsNetCapabilities(@NonNull NetworkCapabilities nc) { return (nc.mNetworkCapabilities == this.mNetworkCapabilities) && (nc.mUnwantedNetworkCapabilities == this.mUnwantedNetworkCapabilities); } - private boolean equalsNetCapabilitiesRequestable(NetworkCapabilities that) { + private boolean equalsNetCapabilitiesRequestable(@NonNull NetworkCapabilities that) { return ((this.mNetworkCapabilities & ~NON_REQUESTABLE_CAPABILITIES) == (that.mNetworkCapabilities & ~NON_REQUESTABLE_CAPABILITIES)) && ((this.mUnwantedNetworkCapabilities & ~NON_REQUESTABLE_CAPABILITIES) == @@ -713,7 +716,7 @@ public final class NetworkCapabilities implements Parcelable { * @hide */ @UnsupportedAppUsage - public NetworkCapabilities addTransportType(@Transport int transportType) { + public @NonNull NetworkCapabilities addTransportType(@Transport int transportType) { checkValidTransportType(transportType); mTransportTypes |= 1 << transportType; setNetworkSpecifier(mNetworkSpecifier); // used for exception checking @@ -727,7 +730,7 @@ public final class NetworkCapabilities implements Parcelable { * @return This NetworkCapabilities instance, to facilitate chaining. * @hide */ - public NetworkCapabilities removeTransportType(@Transport int transportType) { + public @NonNull NetworkCapabilities removeTransportType(@Transport int transportType) { checkValidTransportType(transportType); mTransportTypes &= ~(1 << transportType); setNetworkSpecifier(mNetworkSpecifier); // used for exception checking @@ -740,7 +743,8 @@ public final class NetworkCapabilities implements Parcelable { * * @hide */ - public NetworkCapabilities setTransportType(@Transport int transportType, boolean value) { + public @NonNull NetworkCapabilities setTransportType(@Transport int transportType, + boolean value) { if (value) { addTransportType(transportType); } else { @@ -757,7 +761,7 @@ public final class NetworkCapabilities implements Parcelable { */ @TestApi @SystemApi - public @Transport int[] getTransportTypes() { + @NonNull public @Transport int[] getTransportTypes() { return BitUtils.unpackBits(mTransportTypes); } @@ -847,7 +851,7 @@ public final class NetworkCapabilities implements Parcelable { * @param upKbps the estimated first hop upstream (device to network) bandwidth. * @hide */ - public NetworkCapabilities setLinkUpstreamBandwidthKbps(int upKbps) { + public @NonNull NetworkCapabilities setLinkUpstreamBandwidthKbps(int upKbps) { mLinkUpBandwidthKbps = upKbps; return this; } @@ -877,7 +881,7 @@ public final class NetworkCapabilities implements Parcelable { * @param downKbps the estimated first hop downstream (network to device) bandwidth. * @hide */ - public NetworkCapabilities setLinkDownstreamBandwidthKbps(int downKbps) { + public @NonNull NetworkCapabilities setLinkDownstreamBandwidthKbps(int downKbps) { mLinkDownBandwidthKbps = downKbps; return this; } @@ -936,7 +940,7 @@ public final class NetworkCapabilities implements Parcelable { * @return This NetworkCapabilities instance, to facilitate chaining. * @hide */ - public NetworkCapabilities setNetworkSpecifier(NetworkSpecifier networkSpecifier) { + public @NonNull NetworkCapabilities setNetworkSpecifier(NetworkSpecifier networkSpecifier) { if (networkSpecifier != null && Long.bitCount(mTransportTypes) != 1) { throw new IllegalStateException("Must have a single transport specified to use " + "setNetworkSpecifier"); @@ -955,20 +959,20 @@ public final class NetworkCapabilities implements Parcelable { * @return This NetworkCapabilities instance, to facilitate chaining. * @hide */ - public NetworkCapabilities setTransportInfo(TransportInfo transportInfo) { + public @NonNull NetworkCapabilities setTransportInfo(TransportInfo transportInfo) { mTransportInfo = transportInfo; return this; } /** - * Gets the optional bearer specific network specifier. + * Gets the optional bearer specific network specifier. May be {@code null} if not set. * * @return The optional {@link NetworkSpecifier} specifying the bearer specific network - * specifier. See {@link #setNetworkSpecifier}. + * specifier or {@code null}. See {@link #setNetworkSpecifier}. * @hide */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) - public NetworkSpecifier getNetworkSpecifier() { + public @Nullable NetworkSpecifier getNetworkSpecifier() { return mNetworkSpecifier; } @@ -1015,8 +1019,6 @@ public final class NetworkCapabilities implements Parcelable { /** * Magic value that indicates no signal strength provided. A request specifying this value is * always satisfied. - * - * @hide */ public static final int SIGNAL_STRENGTH_UNSPECIFIED = Integer.MIN_VALUE; @@ -1024,7 +1026,7 @@ public final class NetworkCapabilities implements Parcelable { * Signal strength. This is a signed integer, and higher values indicate better signal. * The exact units are bearer-dependent. For example, Wi-Fi uses RSSI. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) private int mSignalStrength = SIGNAL_STRENGTH_UNSPECIFIED; /** @@ -1041,7 +1043,7 @@ public final class NetworkCapabilities implements Parcelable { * @hide */ @UnsupportedAppUsage - public NetworkCapabilities setSignalStrength(int signalStrength) { + public @NonNull NetworkCapabilities setSignalStrength(int signalStrength) { mSignalStrength = signalStrength; return this; } @@ -1060,9 +1062,7 @@ public final class NetworkCapabilities implements Parcelable { * Retrieves the signal strength. * * @return The bearer-specific signal strength. - * @hide */ - @SystemApi public int getSignalStrength() { return mSignalStrength; } @@ -1120,7 +1120,7 @@ public final class NetworkCapabilities implements Parcelable { * Convenience method to set the UIDs this network applies to to a single UID. * @hide */ - public NetworkCapabilities setSingleUid(int uid) { + public @NonNull NetworkCapabilities setSingleUid(int uid) { final ArraySet identity = new ArraySet<>(1); identity.add(new UidRange(uid, uid)); setUids(identity); @@ -1132,7 +1132,7 @@ public final class NetworkCapabilities implements Parcelable { * This makes a copy of the set so that callers can't modify it after the call. * @hide */ - public NetworkCapabilities setUids(Set uids) { + public @NonNull NetworkCapabilities setUids(Set uids) { if (null == uids) { mUids = null; } else { @@ -1146,7 +1146,7 @@ public final class NetworkCapabilities implements Parcelable { * This returns a copy of the set so that callers can't modify the original object. * @hide */ - public Set getUids() { + public @Nullable Set getUids() { return null == mUids ? null : new ArraySet<>(mUids); } @@ -1179,7 +1179,7 @@ public final class NetworkCapabilities implements Parcelable { * @hide */ @VisibleForTesting - public boolean equalsUids(NetworkCapabilities nc) { + public boolean equalsUids(@NonNull NetworkCapabilities nc) { Set comparedUids = nc.mUids; if (null == comparedUids) return null == mUids; if (null == mUids) return false; @@ -1212,7 +1212,7 @@ public final class NetworkCapabilities implements Parcelable { * @see #appliesToUid * @hide */ - public boolean satisfiedByUids(NetworkCapabilities nc) { + public boolean satisfiedByUids(@NonNull NetworkCapabilities nc) { if (null == nc.mUids || null == mUids) return true; // The network satisfies everything. for (UidRange requiredRange : mUids) { if (requiredRange.contains(nc.mEstablishingVpnAppUid)) return true; @@ -1232,7 +1232,7 @@ public final class NetworkCapabilities implements Parcelable { * @hide */ @VisibleForTesting - public boolean appliesToUidRange(UidRange requiredRange) { + public boolean appliesToUidRange(@Nullable UidRange requiredRange) { if (null == mUids) return true; for (UidRange uidRange : mUids) { if (uidRange.containsRange(requiredRange)) { @@ -1247,7 +1247,7 @@ public final class NetworkCapabilities implements Parcelable { * NetworkCapabilities apply to. * nc is assumed nonnull. */ - private void combineUids(NetworkCapabilities nc) { + private void combineUids(@NonNull NetworkCapabilities nc) { if (null == nc.mUids || null == mUids) { mUids = null; return; @@ -1268,7 +1268,7 @@ public final class NetworkCapabilities implements Parcelable { * Sets the SSID of this network. * @hide */ - public NetworkCapabilities setSSID(String ssid) { + public @NonNull NetworkCapabilities setSSID(@Nullable String ssid) { mSSID = ssid; return this; } @@ -1277,7 +1277,7 @@ public final class NetworkCapabilities implements Parcelable { * Gets the SSID of this network, or null if none or unknown. * @hide */ - public String getSSID() { + public @Nullable String getSSID() { return mSSID; } @@ -1285,7 +1285,7 @@ public final class NetworkCapabilities implements Parcelable { * Tests if the SSID of this network is the same as the SSID of the passed network. * @hide */ - public boolean equalsSSID(NetworkCapabilities nc) { + public boolean equalsSSID(@NonNull NetworkCapabilities nc) { return Objects.equals(mSSID, nc.mSSID); } @@ -1293,7 +1293,7 @@ public final class NetworkCapabilities implements Parcelable { * Check if the SSID requirements of this object are matched by the passed object. * @hide */ - public boolean satisfiedBySSID(NetworkCapabilities nc) { + public boolean satisfiedBySSID(@NonNull NetworkCapabilities nc) { return mSSID == null || mSSID.equals(nc.mSSID); } @@ -1304,7 +1304,7 @@ public final class NetworkCapabilities implements Parcelable { * equal. * @hide */ - private void combineSSIDs(NetworkCapabilities nc) { + private void combineSSIDs(@NonNull NetworkCapabilities nc) { if (mSSID != null && !mSSID.equals(nc.mSSID)) { throw new IllegalStateException("Can't combine two SSIDs"); } @@ -1319,7 +1319,7 @@ public final class NetworkCapabilities implements Parcelable { * both lists will never be satisfied. * @hide */ - public void combineCapabilities(NetworkCapabilities nc) { + public void combineCapabilities(@NonNull NetworkCapabilities nc) { combineNetCapabilities(nc); combineTransportTypes(nc); combineLinkBandwidths(nc); @@ -1359,7 +1359,7 @@ public final class NetworkCapabilities implements Parcelable { */ @TestApi @SystemApi - public boolean satisfiedByNetworkCapabilities(NetworkCapabilities nc) { + public boolean satisfiedByNetworkCapabilities(@Nullable NetworkCapabilities nc) { return satisfiedByNetworkCapabilities(nc, false); } @@ -1370,7 +1370,7 @@ public final class NetworkCapabilities implements Parcelable { * * @hide */ - public boolean satisfiedByImmutableNetworkCapabilities(NetworkCapabilities nc) { + public boolean satisfiedByImmutableNetworkCapabilities(@Nullable NetworkCapabilities nc) { return satisfiedByNetworkCapabilities(nc, true); } @@ -1381,7 +1381,7 @@ public final class NetworkCapabilities implements Parcelable { * * @hide */ - public String describeImmutableDifferences(NetworkCapabilities that) { + public String describeImmutableDifferences(@Nullable NetworkCapabilities that) { if (that == null) { return "other NetworkCapabilities was null"; } @@ -1420,7 +1420,7 @@ public final class NetworkCapabilities implements Parcelable { * * @hide */ - public boolean equalRequestableCapabilities(NetworkCapabilities nc) { + public boolean equalRequestableCapabilities(@Nullable NetworkCapabilities nc) { if (nc == null) return false; return (equalsNetCapabilitiesRequestable(nc) && equalsTransportTypes(nc) && @@ -1428,7 +1428,7 @@ public final class NetworkCapabilities implements Parcelable { } @Override - public boolean equals(Object obj) { + public boolean equals(@Nullable Object obj) { if (obj == null || (obj instanceof NetworkCapabilities == false)) return false; NetworkCapabilities that = (NetworkCapabilities) obj; return (equalsNetCapabilities(that) @@ -1502,7 +1502,7 @@ public final class NetworkCapabilities implements Parcelable { }; @Override - public String toString() { + public @NonNull String toString() { final StringBuilder sb = new StringBuilder("["); if (0 != mTransportTypes) { sb.append(" Transports: "); @@ -1561,8 +1561,8 @@ public final class NetworkCapabilities implements Parcelable { /** * @hide */ - public static void appendStringRepresentationOfBitMaskToStringBuilder(StringBuilder sb, - long bitMask, NameOf nameFetcher, String separator) { + public static void appendStringRepresentationOfBitMaskToStringBuilder(@NonNull StringBuilder sb, + long bitMask, @NonNull NameOf nameFetcher, @NonNull String separator) { int bitPos = 0; boolean firstElementAdded = false; while (bitMask != 0) { @@ -1580,7 +1580,7 @@ public final class NetworkCapabilities implements Parcelable { } /** @hide */ - public void writeToProto(ProtoOutputStream proto, long fieldId) { + public void writeToProto(@NonNull ProtoOutputStream proto, long fieldId) { final long token = proto.start(fieldId); for (int transport : getTransportTypes()) { @@ -1610,7 +1610,7 @@ public final class NetworkCapabilities implements Parcelable { /** * @hide */ - public static String capabilityNamesOf(@NetCapability int[] capabilities) { + public static @NonNull String capabilityNamesOf(@Nullable @NetCapability int[] capabilities) { StringJoiner joiner = new StringJoiner("|"); if (capabilities != null) { for (int c : capabilities) { @@ -1623,7 +1623,7 @@ public final class NetworkCapabilities implements Parcelable { /** * @hide */ - public static String capabilityNameOf(@NetCapability int capability) { + public static @NonNull String capabilityNameOf(@NetCapability int capability) { switch (capability) { case NET_CAPABILITY_MMS: return "MMS"; case NET_CAPABILITY_SUPL: return "SUPL"; @@ -1658,7 +1658,7 @@ public final class NetworkCapabilities implements Parcelable { * @hide */ @UnsupportedAppUsage - public static String transportNamesOf(@Transport int[] types) { + public static @NonNull String transportNamesOf(@Nullable @Transport int[] types) { StringJoiner joiner = new StringJoiner("|"); if (types != null) { for (int t : types) { @@ -1671,7 +1671,7 @@ public final class NetworkCapabilities implements Parcelable { /** * @hide */ - public static String transportNameOf(@Transport int transport) { + public static @NonNull String transportNameOf(@Transport int transport) { if (!isValidTransport(transport)) { return "UNKNOWN"; } diff --git a/core/java/android/net/NetworkInfo.java b/core/java/android/net/NetworkInfo.java index cd835317a3a28dd776f0ada7e483e28f76212f49..92f105f7717222191815ccb0a386c5fcc43cd836 100644 --- a/core/java/android/net/NetworkInfo.java +++ b/core/java/android/net/NetworkInfo.java @@ -16,6 +16,7 @@ package android.net; +import android.annotation.NonNull; import android.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; @@ -138,7 +139,9 @@ public class NetworkInfo implements Parcelable { private int mSubtype; private String mTypeName; private String mSubtypeName; + @NonNull private State mState; + @NonNull private DetailedState mDetailedState; private String mReason; private String mExtraInfo; @@ -451,7 +454,7 @@ public class NetworkInfo implements Parcelable { * the device and let apps react more easily and quickly to changes. */ @Deprecated - public DetailedState getDetailedState() { + public @NonNull DetailedState getDetailedState() { synchronized (this) { return mDetailedState; } diff --git a/core/java/android/net/NetworkRequest.java b/core/java/android/net/NetworkRequest.java index dcb027d187b3239644ed937aaefa4bcf306f32eb..51cbed48e02175baec847a0a11e345fc7528430f 100644 --- a/core/java/android/net/NetworkRequest.java +++ b/core/java/android/net/NetworkRequest.java @@ -347,7 +347,7 @@ public class NetworkRequest implements Parcelable { * @hide */ @SystemApi - public Builder setSignalStrength(int signalStrength) { + public @NonNull Builder setSignalStrength(int signalStrength) { mNetworkCapabilities.setSignalStrength(signalStrength); return this; } diff --git a/core/java/android/net/NetworkUtils.java b/core/java/android/net/NetworkUtils.java index ed410e277a4229b658e0a3191f4406ed72cf36a1..5188866fe49dcc28d88fa7adac13aaca42cc9c84 100644 --- a/core/java/android/net/NetworkUtils.java +++ b/core/java/android/net/NetworkUtils.java @@ -176,6 +176,12 @@ public class NetworkUtils { */ public static native byte[] resNetworkResult(FileDescriptor fd) throws ErrnoException; + /** + * DNS resolver series jni method. + * Attempts to cancel the in-progress query associated with the {@code fd}. + */ + public static native void resNetworkCancel(FileDescriptor fd); + /** * Add an entry into the ARP cache. */ diff --git a/core/java/android/net/RouteInfo.java b/core/java/android/net/RouteInfo.java index c1c8f6eaf3c05f5125cf4a317c06ab8571fcece4..b0239c839348d8a3913e76387227e12f1be664c3 100644 --- a/core/java/android/net/RouteInfo.java +++ b/core/java/android/net/RouteInfo.java @@ -16,6 +16,7 @@ package android.net; +import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.TestApi; import android.annotation.UnsupportedAppUsage; @@ -112,7 +113,8 @@ public final class RouteInfo implements Parcelable { */ @SystemApi @TestApi - public RouteInfo(IpPrefix destination, InetAddress gateway, String iface, int type) { + public RouteInfo(@Nullable IpPrefix destination, @Nullable InetAddress gateway, + @Nullable String iface, int type) { switch (type) { case RTN_UNICAST: case RTN_UNREACHABLE: diff --git a/core/java/android/net/SocketKeepalive.java b/core/java/android/net/SocketKeepalive.java index 0e768dfc8eb9b2ed39c2d10aee9e8ee978ff1101..9d91620bdf96ed9491874842f0a2d4c87ce7f240 100644 --- a/core/java/android/net/SocketKeepalive.java +++ b/core/java/android/net/SocketKeepalive.java @@ -21,8 +21,10 @@ import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Binder; +import android.os.ParcelFileDescriptor; import android.os.RemoteException; +import java.io.IOException; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.concurrent.Executor; @@ -73,10 +75,15 @@ public abstract class SocketKeepalive implements AutoCloseable { /** The target socket is not idle. */ public static final int ERROR_SOCKET_NOT_IDLE = -26; - /** The hardware does not support this request. */ - public static final int ERROR_HARDWARE_UNSUPPORTED = -30; + /** The device does not support this request. */ + public static final int ERROR_UNSUPPORTED = -30; + /** @hide TODO: delete when telephony code has been updated. */ + public static final int ERROR_HARDWARE_UNSUPPORTED = ERROR_UNSUPPORTED; /** The hardware returned an error. */ public static final int ERROR_HARDWARE_ERROR = -31; + /** The limitation of resource is reached. */ + public static final int ERROR_INSUFFICIENT_RESOURCES = -32; + /** @hide */ @Retention(RetentionPolicy.SOURCE) @@ -147,15 +154,18 @@ public abstract class SocketKeepalive implements AutoCloseable { @NonNull final IConnectivityManager mService; @NonNull final Network mNetwork; + @NonNull final ParcelFileDescriptor mPfd; @NonNull final Executor mExecutor; @NonNull final ISocketKeepaliveCallback mCallback; // TODO: remove slot since mCallback could be used to identify which keepalive to stop. @Nullable Integer mSlot; SocketKeepalive(@NonNull IConnectivityManager service, @NonNull Network network, + @NonNull ParcelFileDescriptor pfd, @NonNull Executor executor, @NonNull Callback callback) { mService = service; mNetwork = network; + mPfd = pfd; mExecutor = executor; mCallback = new ISocketKeepaliveCallback.Stub() { @Override @@ -233,6 +243,11 @@ public abstract class SocketKeepalive implements AutoCloseable { @Override public final void close() { stop(); + try { + mPfd.close(); + } catch (IOException e) { + // Nothing much can be done. + } } /** diff --git a/core/java/android/net/StaticIpConfiguration.java b/core/java/android/net/StaticIpConfiguration.java index 8b264eeee3c9201b7507452e103b6c956ca24354..565f36f1420859bf8b5fb925cad64c07b7a287f5 100644 --- a/core/java/android/net/StaticIpConfiguration.java +++ b/core/java/android/net/StaticIpConfiguration.java @@ -16,6 +16,8 @@ package android.net; +import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.TestApi; import android.annotation.UnsupportedAppUsage; @@ -53,22 +55,26 @@ import java.util.Objects; public final class StaticIpConfiguration implements Parcelable { /** @hide */ @UnsupportedAppUsage + @Nullable public LinkAddress ipAddress; /** @hide */ @UnsupportedAppUsage + @Nullable public InetAddress gateway; /** @hide */ @UnsupportedAppUsage + @NonNull public final ArrayList dnsServers; /** @hide */ @UnsupportedAppUsage + @Nullable public String domains; public StaticIpConfiguration() { dnsServers = new ArrayList(); } - public StaticIpConfiguration(StaticIpConfiguration source) { + public StaticIpConfiguration(@Nullable StaticIpConfiguration source) { this(); if (source != null) { // All of these except dnsServers are immutable, so no need to make copies. @@ -86,38 +92,38 @@ public final class StaticIpConfiguration implements Parcelable { domains = null; } - public LinkAddress getIpAddress() { + public @Nullable LinkAddress getIpAddress() { return ipAddress; } - public void setIpAddress(LinkAddress ipAddress) { + public void setIpAddress(@Nullable LinkAddress ipAddress) { this.ipAddress = ipAddress; } - public InetAddress getGateway() { + public @Nullable InetAddress getGateway() { return gateway; } - public void setGateway(InetAddress gateway) { + public void setGateway(@Nullable InetAddress gateway) { this.gateway = gateway; } - public List getDnsServers() { + public @NonNull List getDnsServers() { return dnsServers; } - public String getDomains() { + public @Nullable String getDomains() { return domains; } - public void setDomains(String newDomains) { + public void setDomains(@Nullable String newDomains) { domains = newDomains; } /** * Add a DNS server to this configuration. */ - public void addDnsServer(InetAddress server) { + public void addDnsServer(@NonNull InetAddress server) { dnsServers.add(server); } @@ -128,7 +134,7 @@ public final class StaticIpConfiguration implements Parcelable { * route to the gateway as well. This configuration is arguably invalid, but it used to work * in K and earlier, and other OSes appear to accept it. */ - public List getRoutes(String iface) { + public @NonNull List getRoutes(@Nullable String iface) { List routes = new ArrayList(3); if (ipAddress != null) { RouteInfo connectedRoute = new RouteInfo(ipAddress, null, iface); @@ -150,7 +156,7 @@ public final class StaticIpConfiguration implements Parcelable { * IPv6 configuration) will not be included. * @hide */ - public LinkProperties toLinkProperties(String iface) { + public @NonNull LinkProperties toLinkProperties(String iface) { LinkProperties lp = new LinkProperties(); lp.setInterfaceName(iface); if (ipAddress != null) { diff --git a/core/java/android/net/TcpSocketKeepalive.java b/core/java/android/net/TcpSocketKeepalive.java index 26cc8ff181b2af3a2644253b53d16e64b074f44d..436397ea7754c5de57c5ae4dced3645039d0067f 100644 --- a/core/java/android/net/TcpSocketKeepalive.java +++ b/core/java/android/net/TcpSocketKeepalive.java @@ -17,25 +17,22 @@ package android.net; import android.annotation.NonNull; +import android.os.ParcelFileDescriptor; import android.os.RemoteException; import android.util.Log; import java.io.FileDescriptor; -import java.net.Socket; import java.util.concurrent.Executor; /** @hide */ final class TcpSocketKeepalive extends SocketKeepalive { - private final Socket mSocket; - TcpSocketKeepalive(@NonNull IConnectivityManager service, @NonNull Network network, - @NonNull Socket socket, + @NonNull ParcelFileDescriptor pfd, @NonNull Executor executor, @NonNull Callback callback) { - super(service, network, executor, callback); - mSocket = socket; + super(service, network, pfd, executor, callback); } /** @@ -57,7 +54,7 @@ final class TcpSocketKeepalive extends SocketKeepalive { void startImpl(int intervalSec) { mExecutor.execute(() -> { try { - final FileDescriptor fd = mSocket.getFileDescriptor$(); + final FileDescriptor fd = mPfd.getFileDescriptor(); mService.startTcpKeepalive(mNetwork, fd, intervalSec, mCallback); } catch (RemoteException e) { Log.e(TAG, "Error starting packet keepalive: ", e); diff --git a/core/java/android/net/apf/ApfCapabilities.java b/core/java/android/net/apf/ApfCapabilities.java index d6023d701762badea25f0b9291c0c5cde35a1127..17a03c7c8933743ef68ce3b474032babba53ac77 100644 --- a/core/java/android/net/apf/ApfCapabilities.java +++ b/core/java/android/net/apf/ApfCapabilities.java @@ -16,6 +16,7 @@ package android.net.apf; +import android.annotation.NonNull; import android.annotation.SystemApi; import android.annotation.TestApi; import android.content.Context; @@ -115,14 +116,14 @@ public final class ApfCapabilities implements Parcelable { /** * @return Whether the APF Filter in the device should filter out IEEE 802.3 Frames. */ - public static boolean getApfDrop8023Frames(Context context) { + public static boolean getApfDrop8023Frames(@NonNull Context context) { return context.getResources().getBoolean(R.bool.config_apfDrop802_3Frames); } /** * @return An array of blacklisted EtherType, packets with EtherTypes within it will be dropped. */ - public static int[] getApfEthTypeBlackList(Context context) { + public static @NonNull int[] getApfEthTypeBlackList(@NonNull Context context) { return context.getResources().getIntArray(R.array.config_apfEthTypeBlackList); } } diff --git a/core/java/android/net/captiveportal/CaptivePortalProbeResult.java b/core/java/android/net/captiveportal/CaptivePortalProbeResult.java index 3930344e5d27b8ac76dcf497d70248b64542f47e..a1d3de248a96b659fce32cddcb6c1e5699849bfb 100644 --- a/core/java/android/net/captiveportal/CaptivePortalProbeResult.java +++ b/core/java/android/net/captiveportal/CaptivePortalProbeResult.java @@ -16,6 +16,7 @@ package android.net.captiveportal; +import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.TestApi; @@ -39,14 +40,18 @@ public final class CaptivePortalProbeResult { */ public static final int PARTIAL_CODE = -1; + @NonNull public static final CaptivePortalProbeResult FAILED = new CaptivePortalProbeResult(FAILED_CODE); + @NonNull public static final CaptivePortalProbeResult SUCCESS = new CaptivePortalProbeResult(SUCCESS_CODE); public static final CaptivePortalProbeResult PARTIAL = new CaptivePortalProbeResult(PARTIAL_CODE); private final int mHttpResponseCode; // HTTP response code returned from Internet probe. + @Nullable public final String redirectUrl; // Redirect destination returned from Internet probe. + @Nullable public final String detectUrl; // URL where a 204 response code indicates // captive portal has been appeased. @Nullable @@ -56,12 +61,13 @@ public final class CaptivePortalProbeResult { this(httpResponseCode, null, null); } - public CaptivePortalProbeResult(int httpResponseCode, String redirectUrl, String detectUrl) { + public CaptivePortalProbeResult(int httpResponseCode, @Nullable String redirectUrl, + @Nullable String detectUrl) { this(httpResponseCode, redirectUrl, detectUrl, null); } - public CaptivePortalProbeResult(int httpResponseCode, String redirectUrl, String detectUrl, - CaptivePortalProbeSpec probeSpec) { + public CaptivePortalProbeResult(int httpResponseCode, @Nullable String redirectUrl, + @Nullable String detectUrl, @Nullable CaptivePortalProbeSpec probeSpec) { mHttpResponseCode = httpResponseCode; this.redirectUrl = redirectUrl; this.detectUrl = detectUrl; diff --git a/core/java/android/net/captiveportal/CaptivePortalProbeSpec.java b/core/java/android/net/captiveportal/CaptivePortalProbeSpec.java index 7ad4ecf2264c929d32298a7a1680f1abb21e7814..6c6a16c4534eab9cd4a7fdd3f3dc5a6c1710b571 100644 --- a/core/java/android/net/captiveportal/CaptivePortalProbeSpec.java +++ b/core/java/android/net/captiveportal/CaptivePortalProbeSpec.java @@ -19,6 +19,8 @@ package android.net.captiveportal; import static android.net.captiveportal.CaptivePortalProbeResult.PORTAL_CODE; import static android.net.captiveportal.CaptivePortalProbeResult.SUCCESS_CODE; +import static com.android.internal.util.Preconditions.checkNotNull; + import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; @@ -48,9 +50,10 @@ public abstract class CaptivePortalProbeSpec { private final String mEncodedSpec; private final URL mUrl; - CaptivePortalProbeSpec(String encodedSpec, URL url) { - mEncodedSpec = encodedSpec; - mUrl = url; + CaptivePortalProbeSpec(@NonNull String encodedSpec, @NonNull URL url) + throws NullPointerException { + mEncodedSpec = checkNotNull(encodedSpec); + mUrl = checkNotNull(url); } /** @@ -64,7 +67,7 @@ public abstract class CaptivePortalProbeSpec { */ @VisibleForTesting @NonNull - public static CaptivePortalProbeSpec parseSpec(String spec) throws ParseException, + public static CaptivePortalProbeSpec parseSpec(@NonNull String spec) throws ParseException, MalformedURLException { if (TextUtils.isEmpty(spec)) { throw new ParseException("Empty probe spec", 0 /* errorOffset */); @@ -84,7 +87,8 @@ public abstract class CaptivePortalProbeSpec { } @Nullable - private static Pattern parsePatternIfNonEmpty(String pattern, int pos) throws ParseException { + private static Pattern parsePatternIfNonEmpty(@Nullable String pattern, int pos) + throws ParseException { if (TextUtils.isEmpty(pattern)) { return null; } @@ -120,8 +124,9 @@ public abstract class CaptivePortalProbeSpec { *

Each spec is separated by @@,@@ and follows the format for {@link #parseSpec(String)}. *

This method does not throw but ignores any entry that could not be parsed. */ + @NonNull public static Collection parseCaptivePortalProbeSpecs( - String settingsVal) { + @NonNull String settingsVal) { List specs = new ArrayList<>(); if (settingsVal != null) { for (String spec : TextUtils.split(settingsVal, SPEC_SEPARATOR)) { @@ -142,12 +147,15 @@ public abstract class CaptivePortalProbeSpec { /** * Get the probe result from HTTP status and location header. */ + @NonNull public abstract CaptivePortalProbeResult getResult(int status, @Nullable String locationHeader); + @NonNull public String getEncodedSpec() { return mEncodedSpec; } + @NonNull public URL getUrl() { return mUrl; } diff --git a/core/java/android/net/metrics/ApfProgramEvent.java b/core/java/android/net/metrics/ApfProgramEvent.java index b30d8cb04f4cc67b1213a008a1a82cc41118854a..2bd43782d523e4cd56bc6dd1e047dc128d3deb42 100644 --- a/core/java/android/net/metrics/ApfProgramEvent.java +++ b/core/java/android/net/metrics/ApfProgramEvent.java @@ -17,6 +17,7 @@ package android.net.metrics; import android.annotation.IntDef; +import android.annotation.NonNull; import android.annotation.SystemApi; import android.annotation.TestApi; import android.annotation.UnsupportedAppUsage; @@ -95,7 +96,7 @@ public final class ApfProgramEvent implements IpConnectivityLog.Event { /** * Utility to create an instance of {@link ApfProgramEvent}. */ - public static class Builder { + public static final class Builder { private long mLifetime; private long mActualLifetime; private int mFilteredRas; @@ -106,6 +107,7 @@ public final class ApfProgramEvent implements IpConnectivityLog.Event { /** * Set the maximum computed lifetime of the program in seconds. */ + @NonNull public Builder setLifetime(long lifetime) { mLifetime = lifetime; return this; @@ -114,6 +116,7 @@ public final class ApfProgramEvent implements IpConnectivityLog.Event { /** * Set the effective program lifetime in seconds. */ + @NonNull public Builder setActualLifetime(long lifetime) { mActualLifetime = lifetime; return this; @@ -122,6 +125,7 @@ public final class ApfProgramEvent implements IpConnectivityLog.Event { /** * Set the number of RAs filtered by the APF program. */ + @NonNull public Builder setFilteredRas(int filteredRas) { mFilteredRas = filteredRas; return this; @@ -130,6 +134,7 @@ public final class ApfProgramEvent implements IpConnectivityLog.Event { /** * Set the total number of current RAs at generation time. */ + @NonNull public Builder setCurrentRas(int currentRas) { mCurrentRas = currentRas; return this; @@ -138,6 +143,7 @@ public final class ApfProgramEvent implements IpConnectivityLog.Event { /** * Set the length of the APF program in bytes. */ + @NonNull public Builder setProgramLength(int programLength) { mProgramLength = programLength; return this; @@ -146,6 +152,7 @@ public final class ApfProgramEvent implements IpConnectivityLog.Event { /** * Set the flags describing what an Apf program filters. */ + @NonNull public Builder setFlags(boolean hasIPv4, boolean multicastFilterOn) { mFlags = flagsFor(hasIPv4, multicastFilterOn); return this; @@ -154,6 +161,7 @@ public final class ApfProgramEvent implements IpConnectivityLog.Event { /** * Build a new {@link ApfProgramEvent}. */ + @NonNull public ApfProgramEvent build() { return new ApfProgramEvent(mLifetime, mActualLifetime, mFilteredRas, mCurrentRas, mProgramLength, mFlags); diff --git a/core/java/android/net/metrics/ApfStats.java b/core/java/android/net/metrics/ApfStats.java index e1c8888deff736af416f55dca4f5961d56ef32c9..6c3b7af6b88836eece57945e198ea60c56fb9f6e 100644 --- a/core/java/android/net/metrics/ApfStats.java +++ b/core/java/android/net/metrics/ApfStats.java @@ -16,6 +16,7 @@ package android.net.metrics; +import android.annotation.NonNull; import android.annotation.SystemApi; import android.annotation.TestApi; import android.annotation.UnsupportedAppUsage; @@ -125,7 +126,7 @@ public final class ApfStats implements IpConnectivityLog.Event { */ @SystemApi @TestApi - public static class Builder { + public static final class Builder { private long mDurationMs; private int mReceivedRas; private int mMatchingRas; @@ -140,6 +141,7 @@ public final class ApfStats implements IpConnectivityLog.Event { /** * Set the time interval in milliseconds these statistics covers. */ + @NonNull public Builder setDurationMs(long durationMs) { mDurationMs = durationMs; return this; @@ -148,6 +150,7 @@ public final class ApfStats implements IpConnectivityLog.Event { /** * Set the number of received RAs. */ + @NonNull public Builder setReceivedRas(int receivedRas) { mReceivedRas = receivedRas; return this; @@ -156,6 +159,7 @@ public final class ApfStats implements IpConnectivityLog.Event { /** * Set the number of received RAs matching a known RA. */ + @NonNull public Builder setMatchingRas(int matchingRas) { mMatchingRas = matchingRas; return this; @@ -164,6 +168,7 @@ public final class ApfStats implements IpConnectivityLog.Event { /** * Set the number of received RAs ignored due to the MAX_RAS limit. */ + @NonNull public Builder setDroppedRas(int droppedRas) { mDroppedRas = droppedRas; return this; @@ -172,6 +177,7 @@ public final class ApfStats implements IpConnectivityLog.Event { /** * Set the number of received RAs with a minimum lifetime of 0. */ + @NonNull public Builder setZeroLifetimeRas(int zeroLifetimeRas) { mZeroLifetimeRas = zeroLifetimeRas; return this; @@ -180,6 +186,7 @@ public final class ApfStats implements IpConnectivityLog.Event { /** * Set the number of received RAs that could not be parsed. */ + @NonNull public Builder setParseErrors(int parseErrors) { mParseErrors = parseErrors; return this; @@ -188,6 +195,7 @@ public final class ApfStats implements IpConnectivityLog.Event { /** * Set the number of APF program updates from receiving RAs. */ + @NonNull public Builder setProgramUpdates(int programUpdates) { mProgramUpdates = programUpdates; return this; @@ -196,6 +204,7 @@ public final class ApfStats implements IpConnectivityLog.Event { /** * Set the total number of APF program updates. */ + @NonNull public Builder setProgramUpdatesAll(int programUpdatesAll) { mProgramUpdatesAll = programUpdatesAll; return this; @@ -204,6 +213,7 @@ public final class ApfStats implements IpConnectivityLog.Event { /** * Set the number of APF program updates from allowing multicast traffic. */ + @NonNull public Builder setProgramUpdatesAllowingMulticast(int programUpdatesAllowingMulticast) { mProgramUpdatesAllowingMulticast = programUpdatesAllowingMulticast; return this; @@ -212,6 +222,7 @@ public final class ApfStats implements IpConnectivityLog.Event { /** * Set the maximum APF program size advertised by hardware. */ + @NonNull public Builder setMaxProgramSize(int maxProgramSize) { mMaxProgramSize = maxProgramSize; return this; @@ -220,6 +231,7 @@ public final class ApfStats implements IpConnectivityLog.Event { /** * Create a new {@link ApfStats}. */ + @NonNull public ApfStats build() { return new ApfStats(mDurationMs, mReceivedRas, mMatchingRas, mDroppedRas, mZeroLifetimeRas, mParseErrors, mProgramUpdates, mProgramUpdatesAll, diff --git a/core/java/android/net/metrics/DhcpClientEvent.java b/core/java/android/net/metrics/DhcpClientEvent.java index e4faea9247d7b18db298b561d029ee409023cdb3..a3d0a20194f2998091433c92036643d68eae8371 100644 --- a/core/java/android/net/metrics/DhcpClientEvent.java +++ b/core/java/android/net/metrics/DhcpClientEvent.java @@ -16,6 +16,7 @@ package android.net.metrics; +import android.annotation.NonNull; import android.annotation.SystemApi; import android.annotation.TestApi; import android.annotation.UnsupportedAppUsage; @@ -51,13 +52,14 @@ public final class DhcpClientEvent implements IpConnectivityLog.Event { /** * Utility to create an instance of {@link ApfProgramEvent}. */ - public static class Builder { + public static final class Builder { private String mMsg; private int mDurationMs; /** * Set the message of the event. */ + @NonNull public Builder setMsg(String msg) { mMsg = msg; return this; @@ -66,6 +68,7 @@ public final class DhcpClientEvent implements IpConnectivityLog.Event { /** * Set the duration of the event in milliseconds. */ + @NonNull public Builder setDurationMs(int durationMs) { mDurationMs = durationMs; return this; @@ -74,6 +77,7 @@ public final class DhcpClientEvent implements IpConnectivityLog.Event { /** * Create a new {@link DhcpClientEvent}. */ + @NonNull public DhcpClientEvent build() { return new DhcpClientEvent(mMsg, mDurationMs); } diff --git a/core/java/android/net/metrics/DhcpErrorEvent.java b/core/java/android/net/metrics/DhcpErrorEvent.java index 91318a2459d2449e5eabe18ffc9d7cea8d0ac83c..876000463cb17347b178332acb1fbbc0db6e9e06 100644 --- a/core/java/android/net/metrics/DhcpErrorEvent.java +++ b/core/java/android/net/metrics/DhcpErrorEvent.java @@ -37,27 +37,6 @@ public final class DhcpErrorEvent implements IpConnectivityLog.Event { public static final int DHCP_ERROR = 4; public static final int MISC_ERROR = 5; - public static final int L2_TOO_SHORT = makeErrorCode(L2_ERROR, 1); - public static final int L2_WRONG_ETH_TYPE = makeErrorCode(L2_ERROR, 2); - - public static final int L3_TOO_SHORT = makeErrorCode(L3_ERROR, 1); - public static final int L3_NOT_IPV4 = makeErrorCode(L3_ERROR, 2); - public static final int L3_INVALID_IP = makeErrorCode(L3_ERROR, 3); - - public static final int L4_NOT_UDP = makeErrorCode(L4_ERROR, 1); - public static final int L4_WRONG_PORT = makeErrorCode(L4_ERROR, 2); - - public static final int BOOTP_TOO_SHORT = makeErrorCode(DHCP_ERROR, 1); - public static final int DHCP_BAD_MAGIC_COOKIE = makeErrorCode(DHCP_ERROR, 2); - public static final int DHCP_INVALID_OPTION_LENGTH = makeErrorCode(DHCP_ERROR, 3); - public static final int DHCP_NO_MSG_TYPE = makeErrorCode(DHCP_ERROR, 4); - public static final int DHCP_UNKNOWN_MSG_TYPE = makeErrorCode(DHCP_ERROR, 5); - public static final int DHCP_NO_COOKIE = makeErrorCode(DHCP_ERROR, 6); - - public static final int BUFFER_UNDERFLOW = makeErrorCode(MISC_ERROR, 1); - public static final int RECEIVE_ERROR = makeErrorCode(MISC_ERROR, 2); - public static final int PARSING_ERROR = makeErrorCode(MISC_ERROR, 3); - // error code byte format (MSB to LSB): // byte 0: error type // byte 1: error subtype @@ -66,6 +45,33 @@ public final class DhcpErrorEvent implements IpConnectivityLog.Event { /** @hide */ public final int errorCode; + private static final int L2_ERROR_TYPE = L2_ERROR << 8; + private static final int L3_ERROR_TYPE = L3_ERROR << 8; + private static final int L4_ERROR_TYPE = L4_ERROR << 8; + private static final int DHCP_ERROR_TYPE = DHCP_ERROR << 8; + private static final int MISC_ERROR_TYPE = MISC_ERROR << 8; + + public static final int L2_TOO_SHORT = (L2_ERROR_TYPE | 0x1) << 16; + public static final int L2_WRONG_ETH_TYPE = (L2_ERROR_TYPE | 0x2) << 16; + + public static final int L3_TOO_SHORT = (L3_ERROR_TYPE | 0x1) << 16; + public static final int L3_NOT_IPV4 = (L3_ERROR_TYPE | 0x2) << 16; + public static final int L3_INVALID_IP = (L3_ERROR_TYPE | 0x3) << 16; + + public static final int L4_NOT_UDP = (L4_ERROR_TYPE | 0x1) << 16; + public static final int L4_WRONG_PORT = (L4_ERROR_TYPE | 0x2) << 16; + + public static final int BOOTP_TOO_SHORT = (DHCP_ERROR_TYPE | 0x1) << 16; + public static final int DHCP_BAD_MAGIC_COOKIE = (DHCP_ERROR_TYPE | 0x2) << 16; + public static final int DHCP_INVALID_OPTION_LENGTH = (DHCP_ERROR_TYPE | 0x3) << 16; + public static final int DHCP_NO_MSG_TYPE = (DHCP_ERROR_TYPE | 0x4) << 16; + public static final int DHCP_UNKNOWN_MSG_TYPE = (DHCP_ERROR_TYPE | 0x5) << 16; + public static final int DHCP_NO_COOKIE = (DHCP_ERROR_TYPE | 0x6) << 16; + + public static final int BUFFER_UNDERFLOW = (MISC_ERROR_TYPE | 0x1) << 16; + public static final int RECEIVE_ERROR = (MISC_ERROR_TYPE | 0x2) << 16; + public static final int PARSING_ERROR = (MISC_ERROR_TYPE | 0x3) << 16; + public DhcpErrorEvent(int errorCode) { this.errorCode = errorCode; } @@ -102,10 +108,6 @@ public final class DhcpErrorEvent implements IpConnectivityLog.Event { return (0xFFFF0000 & errorCode) | (0xFF & option); } - private static int makeErrorCode(int type, int subtype) { - return (type << 24) | ((0xFF & subtype) << 16); - } - @Override public String toString() { return String.format("DhcpErrorEvent(%s)", Decoder.constants.get(errorCode)); diff --git a/core/java/android/net/metrics/IpConnectivityLog.java b/core/java/android/net/metrics/IpConnectivityLog.java index 5b5a23578954c42413ae60622df8f384116a985f..680c01573f98bbb8cf89ca8e85798d27ea5f6dd6 100644 --- a/core/java/android/net/metrics/IpConnectivityLog.java +++ b/core/java/android/net/metrics/IpConnectivityLog.java @@ -16,6 +16,7 @@ package android.net.metrics; +import android.annotation.NonNull; import android.annotation.SystemApi; import android.annotation.TestApi; import android.net.ConnectivityMetricsEvent; @@ -41,7 +42,7 @@ public class IpConnectivityLog { /** @hide */ public static final String SERVICE_NAME = "connmetrics"; - + @NonNull private IIpConnectivityMetrics mService; /** @@ -57,7 +58,7 @@ public class IpConnectivityLog { /** @hide */ @VisibleForTesting - public IpConnectivityLog(IIpConnectivityMetrics service) { + public IpConnectivityLog(@NonNull IIpConnectivityMetrics service) { mService = service; } @@ -83,7 +84,7 @@ public class IpConnectivityLog { * @return true if the event was successfully logged. * @hide */ - public boolean log(ConnectivityMetricsEvent ev) { + public boolean log(@NonNull ConnectivityMetricsEvent ev) { if (!checkLoggerService()) { if (DBG) { Log.d(TAG, SERVICE_NAME + " service was not ready"); @@ -109,7 +110,7 @@ public class IpConnectivityLog { * @param data is a Parcelable instance representing the event. * @return true if the event was successfully logged. */ - public boolean log(long timestamp, Event data) { + public boolean log(long timestamp, @NonNull Event data) { ConnectivityMetricsEvent ev = makeEv(data); ev.timestamp = timestamp; return log(ev); @@ -121,7 +122,7 @@ public class IpConnectivityLog { * @param data is a Parcelable instance representing the event. * @return true if the event was successfully logged. */ - public boolean log(String ifname, Event data) { + public boolean log(@NonNull String ifname, @NonNull Event data) { ConnectivityMetricsEvent ev = makeEv(data); ev.ifname = ifname; return log(ev); @@ -135,7 +136,7 @@ public class IpConnectivityLog { * @param data is a Parcelable instance representing the event. * @return true if the event was successfully logged. */ - public boolean log(Network network, int[] transports, Event data) { + public boolean log(@NonNull Network network, @NonNull int[] transports, @NonNull Event data) { return log(network.netId, transports, data); } @@ -147,7 +148,7 @@ public class IpConnectivityLog { * @param data is a Parcelable instance representing the event. * @return true if the event was successfully logged. */ - public boolean log(int netid, int[] transports, Event data) { + public boolean log(int netid, @NonNull int[] transports, @NonNull Event data) { ConnectivityMetricsEvent ev = makeEv(data); ev.netId = netid; ev.transports = BitUtils.packBits(transports); @@ -159,7 +160,7 @@ public class IpConnectivityLog { * @param data is a Parcelable instance representing the event. * @return true if the event was successfully logged. */ - public boolean log(Event data) { + public boolean log(@NonNull Event data) { return log(makeEv(data)); } diff --git a/core/java/android/net/metrics/RaEvent.java b/core/java/android/net/metrics/RaEvent.java index 0d43f12e6537235d6962ac443ccd00d4de7f070d..b2f6585cc2fc93ab0cdde21efe56fe77cc68d1ca 100644 --- a/core/java/android/net/metrics/RaEvent.java +++ b/core/java/android/net/metrics/RaEvent.java @@ -16,6 +16,7 @@ package android.net.metrics; +import android.annotation.NonNull; import android.annotation.SystemApi; import android.annotation.TestApi; import android.os.Parcel; @@ -107,7 +108,7 @@ public final class RaEvent implements IpConnectivityLog.Event { } }; - public static class Builder { + public static final class Builder { long routerLifetime = NO_LIFETIME; long prefixValidLifetime = NO_LIFETIME; @@ -119,37 +120,37 @@ public final class RaEvent implements IpConnectivityLog.Event { public Builder() { } - public RaEvent build() { + public @NonNull RaEvent build() { return new RaEvent(routerLifetime, prefixValidLifetime, prefixPreferredLifetime, routeInfoLifetime, rdnssLifetime, dnsslLifetime); } - public Builder updateRouterLifetime(long lifetime) { + public @NonNull Builder updateRouterLifetime(long lifetime) { routerLifetime = updateLifetime(routerLifetime, lifetime); return this; } - public Builder updatePrefixValidLifetime(long lifetime) { + public @NonNull Builder updatePrefixValidLifetime(long lifetime) { prefixValidLifetime = updateLifetime(prefixValidLifetime, lifetime); return this; } - public Builder updatePrefixPreferredLifetime(long lifetime) { + public @NonNull Builder updatePrefixPreferredLifetime(long lifetime) { prefixPreferredLifetime = updateLifetime(prefixPreferredLifetime, lifetime); return this; } - public Builder updateRouteInfoLifetime(long lifetime) { + public @NonNull Builder updateRouteInfoLifetime(long lifetime) { routeInfoLifetime = updateLifetime(routeInfoLifetime, lifetime); return this; } - public Builder updateRdnssLifetime(long lifetime) { + public @NonNull Builder updateRdnssLifetime(long lifetime) { rdnssLifetime = updateLifetime(rdnssLifetime, lifetime); return this; } - public Builder updateDnsslLifetime(long lifetime) { + public @NonNull Builder updateDnsslLifetime(long lifetime) { dnsslLifetime = updateLifetime(dnsslLifetime, lifetime); return this; } diff --git a/core/java/android/net/metrics/ValidationProbeEvent.java b/core/java/android/net/metrics/ValidationProbeEvent.java index 052758da7aba040481d8aeccd651afb867cc1e18..c9d7b1b8f7d90d38925991ca40c6ee91d310ed6d 100644 --- a/core/java/android/net/metrics/ValidationProbeEvent.java +++ b/core/java/android/net/metrics/ValidationProbeEvent.java @@ -17,6 +17,7 @@ package android.net.metrics; import android.annotation.IntDef; +import android.annotation.NonNull; import android.annotation.SystemApi; import android.annotation.TestApi; import android.os.Parcel; @@ -81,7 +82,7 @@ public final class ValidationProbeEvent implements IpConnectivityLog.Event { /** * Utility to create an instance of {@link ValidationProbeEvent}. */ - public static class Builder { + public static final class Builder { private long mDurationMs; private int mProbeType; private int mReturnCode; @@ -89,6 +90,7 @@ public final class ValidationProbeEvent implements IpConnectivityLog.Event { /** * Set the duration of the probe in milliseconds. */ + @NonNull public Builder setDurationMs(long durationMs) { mDurationMs = durationMs; return this; @@ -97,6 +99,7 @@ public final class ValidationProbeEvent implements IpConnectivityLog.Event { /** * Set the probe type based on whether it was the first validation. */ + @NonNull public Builder setProbeType(int probeType, boolean firstValidation) { mProbeType = makeProbeType(probeType, firstValidation); return this; @@ -105,6 +108,7 @@ public final class ValidationProbeEvent implements IpConnectivityLog.Event { /** * Set the return code of the probe. */ + @NonNull public Builder setReturnCode(int returnCode) { mReturnCode = returnCode; return this; @@ -113,6 +117,7 @@ public final class ValidationProbeEvent implements IpConnectivityLog.Event { /** * Create a new {@link ValidationProbeEvent}. */ + @NonNull public ValidationProbeEvent build() { return new ValidationProbeEvent(mDurationMs, mProbeType, mReturnCode); } @@ -148,11 +153,14 @@ public final class ValidationProbeEvent implements IpConnectivityLog.Event { return (probeType & 0xff) | (firstValidation ? FIRST_VALIDATION : REVALIDATION); } - public static String getProbeName(int probeType) { + /** + * Get the name of a probe specified by its probe type. + */ + public static @NonNull String getProbeName(int probeType) { return Decoder.constants.get(probeType & 0xff, "PROBE_???"); } - private static String getValidationStage(int probeType) { + private static @NonNull String getValidationStage(int probeType) { return Decoder.constants.get(probeType & 0xff00, "UNKNOWN"); } diff --git a/core/java/android/net/nsd/INsdManager.aidl b/core/java/android/net/nsd/INsdManager.aidl index 3361a7b84b5379869fc54f8c9b5664f060595851..9484c74bcb23ed444a8a121fa3a7ee95dd9fdf58 100644 --- a/core/java/android/net/nsd/INsdManager.aidl +++ b/core/java/android/net/nsd/INsdManager.aidl @@ -25,6 +25,7 @@ import android.os.Messenger; */ interface INsdManager { + @UnsupportedAppUsage Messenger getMessenger(); void setEnabled(boolean enable); } diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java index 4fae3a8d52a8c7ea8f7dd410a2f7beae358474ab..b64fe007bcd9560f2a556f019f83dd435dc82ba9 100644 --- a/core/java/android/os/BatteryStats.java +++ b/core/java/android/os/BatteryStats.java @@ -200,13 +200,21 @@ public abstract class BatteryStats implements Parcelable { /** * Include only the current run in the stats. + * + * @deprecated As of {@link android.os.Build.VERSION_CODES#Q}, only {@link #STATS_SINCE_CHARGED} + * is supported. */ @UnsupportedAppUsage + @Deprecated public static final int STATS_CURRENT = 1; /** * Include only the run since the last time the device was unplugged in the stats. + * + * @deprecated As of {@link android.os.Build.VERSION_CODES#Q}, only {@link #STATS_SINCE_CHARGED} + * is supported. */ + @Deprecated public static final int STATS_SINCE_UNPLUGGED = 2; // NOTE: Update this list if you add/change any stats above. @@ -255,8 +263,10 @@ public abstract class BatteryStats implements Parcelable { * - Ambient display properly output in data dump. * New in version 33: * - Fixed bug in min learned capacity updating process. + * New in version 34: + * - Deprecated STATS_SINCE_UNPLUGGED and STATS_CURRENT. */ - static final int CHECKIN_VERSION = 33; + static final int CHECKIN_VERSION = 34; /** * Old version, we hit 9 and ran out of room, need to remove. @@ -3651,6 +3661,14 @@ public abstract class BatteryStats implements Parcelable { */ public final void dumpCheckinLocked(Context context, PrintWriter pw, int which, int reqUid, boolean wifiOnly) { + + if (which != BatteryStats.STATS_SINCE_CHARGED) { + dumpLine(pw, 0, STAT_NAMES[which], "err", + "ERROR: BatteryStats.dumpCheckin called for which type " + which + + " but only STATS_SINCE_CHARGED is supported."); + return; + } + final long rawUptime = SystemClock.uptimeMillis() * 1000; final long rawRealtimeMs = SystemClock.elapsedRealtime(); final long rawRealtime = rawRealtimeMs * 1000; @@ -3848,28 +3866,13 @@ public abstract class BatteryStats implements Parcelable { multicastWakeLockTimeTotalMicros / 1000, multicastWakeLockCountTotal); - if (which == STATS_SINCE_UNPLUGGED) { - dumpLine(pw, 0 /* uid */, category, BATTERY_LEVEL_DATA, getDischargeStartLevel(), - getDischargeCurrentLevel()); - } - - if (which == STATS_SINCE_UNPLUGGED) { - dumpLine(pw, 0 /* uid */, category, BATTERY_DISCHARGE_DATA, - getDischargeStartLevel()-getDischargeCurrentLevel(), - getDischargeStartLevel()-getDischargeCurrentLevel(), - getDischargeAmountScreenOn(), getDischargeAmountScreenOff(), - dischargeCount / 1000, dischargeScreenOffCount / 1000, - getDischargeAmountScreenDoze(), dischargeScreenDozeCount / 1000, - dischargeLightDozeCount / 1000, dischargeDeepDozeCount / 1000); - } else { - dumpLine(pw, 0 /* uid */, category, BATTERY_DISCHARGE_DATA, - getLowDischargeAmountSinceCharge(), getHighDischargeAmountSinceCharge(), - getDischargeAmountScreenOnSinceCharge(), - getDischargeAmountScreenOffSinceCharge(), - dischargeCount / 1000, dischargeScreenOffCount / 1000, - getDischargeAmountScreenDozeSinceCharge(), dischargeScreenDozeCount / 1000, - dischargeLightDozeCount / 1000, dischargeDeepDozeCount / 1000); - } + dumpLine(pw, 0 /* uid */, category, BATTERY_DISCHARGE_DATA, + getLowDischargeAmountSinceCharge(), getHighDischargeAmountSinceCharge(), + getDischargeAmountScreenOnSinceCharge(), + getDischargeAmountScreenOffSinceCharge(), + dischargeCount / 1000, dischargeScreenOffCount / 1000, + getDischargeAmountScreenDozeSinceCharge(), dischargeScreenDozeCount / 1000, + dischargeLightDozeCount / 1000, dischargeDeepDozeCount / 1000); if (reqUid < 0) { final Map kernelWakelocks = getKernelWakelockStats(); @@ -4432,6 +4435,13 @@ public abstract class BatteryStats implements Parcelable { @SuppressWarnings("unused") public final void dumpLocked(Context context, PrintWriter pw, String prefix, final int which, int reqUid, boolean wifiOnly) { + + if (which != BatteryStats.STATS_SINCE_CHARGED) { + pw.println("ERROR: BatteryStats.dump called for which type " + which + + " but only STATS_SINCE_CHARGED is supported"); + return; + } + final long rawUptime = SystemClock.uptimeMillis() * 1000; final long rawRealtime = SystemClock.elapsedRealtime() * 1000; final long rawRealtimeMs = (rawRealtime + 500) / 1000; @@ -5044,41 +5054,18 @@ public abstract class BatteryStats implements Parcelable { pw.println(); - if (which == STATS_SINCE_UNPLUGGED) { - if (getIsOnBattery()) { - pw.print(prefix); pw.println(" Device is currently unplugged"); - pw.print(prefix); pw.print(" Discharge cycle start level: "); - pw.println(getDischargeStartLevel()); - pw.print(prefix); pw.print(" Discharge cycle current level: "); - pw.println(getDischargeCurrentLevel()); - } else { - pw.print(prefix); pw.println(" Device is currently plugged into power"); - pw.print(prefix); pw.print(" Last discharge cycle start level: "); - pw.println(getDischargeStartLevel()); - pw.print(prefix); pw.print(" Last discharge cycle end level: "); - pw.println(getDischargeCurrentLevel()); - } - pw.print(prefix); pw.print(" Amount discharged while screen on: "); - pw.println(getDischargeAmountScreenOn()); - pw.print(prefix); pw.print(" Amount discharged while screen off: "); - pw.println(getDischargeAmountScreenOff()); - pw.print(prefix); pw.print(" Amount discharged while screen doze: "); - pw.println(getDischargeAmountScreenDoze()); - pw.println(" "); - } else { - pw.print(prefix); pw.println(" Device battery use since last full charge"); - pw.print(prefix); pw.print(" Amount discharged (lower bound): "); - pw.println(getLowDischargeAmountSinceCharge()); - pw.print(prefix); pw.print(" Amount discharged (upper bound): "); - pw.println(getHighDischargeAmountSinceCharge()); - pw.print(prefix); pw.print(" Amount discharged while screen on: "); - pw.println(getDischargeAmountScreenOnSinceCharge()); - pw.print(prefix); pw.print(" Amount discharged while screen off: "); - pw.println(getDischargeAmountScreenOffSinceCharge()); - pw.print(prefix); pw.print(" Amount discharged while screen doze: "); - pw.println(getDischargeAmountScreenDozeSinceCharge()); - pw.println(); - } + pw.print(prefix); pw.println(" Device battery use since last full charge"); + pw.print(prefix); pw.print(" Amount discharged (lower bound): "); + pw.println(getLowDischargeAmountSinceCharge()); + pw.print(prefix); pw.print(" Amount discharged (upper bound): "); + pw.println(getHighDischargeAmountSinceCharge()); + pw.print(prefix); pw.print(" Amount discharged while screen on: "); + pw.println(getDischargeAmountScreenOnSinceCharge()); + pw.print(prefix); pw.print(" Amount discharged while screen off: "); + pw.println(getDischargeAmountScreenOffSinceCharge()); + pw.print(prefix); pw.print(" Amount discharged while screen doze: "); + pw.println(getDischargeAmountScreenDozeSinceCharge()); + pw.println(); final BatteryStatsHelper helper = new BatteryStatsHelper(context, false, wifiOnly); helper.create(this); diff --git a/core/java/android/os/DropBoxManager.java b/core/java/android/os/DropBoxManager.java index 320f471e4b3f48c9c3c4aaffc336017e5628a2b5..b92e7135750334e4b635a7530a1444d11458284a 100644 --- a/core/java/android/os/DropBoxManager.java +++ b/core/java/android/os/DropBoxManager.java @@ -91,6 +91,13 @@ public class DropBoxManager { */ public static final String EXTRA_TIME = "time"; + /** + * Extra for {@link android.os.DropBoxManager#ACTION_DROPBOX_ENTRY_ADDED}: + * integer value containing number of broadcasts dropped due to rate limiting on + * this {@link android.os.DropBoxManager#EXTRA_TAG} + */ + public static final String EXTRA_DROPPED_COUNT = "android.os.extra.DROPPED_COUNT"; + /** * A single entry retrieved from the drop box. * This may include a reference to a stream, so you must call diff --git a/core/java/android/os/GraphicsEnvironment.java b/core/java/android/os/GraphicsEnvironment.java index 707a404da4ed57924556305530c736f7d62d37c3..41691d763673831968a11676715d11e38fc37697 100644 --- a/core/java/android/os/GraphicsEnvironment.java +++ b/core/java/android/os/GraphicsEnvironment.java @@ -63,7 +63,7 @@ public class GraphicsEnvironment { private static final long SYSTEM_DRIVER_VERSION_CODE = 0; private static final String PROPERTY_GFX_DRIVER = "ro.gfx.driver.0"; private static final String PROPERTY_GFX_DRIVER_BUILD_TIME = "ro.gfx.driver_build_time"; - private static final String METADATA_DRIVER_BUILD_TIME = "driver_build_time"; + private static final String METADATA_DRIVER_BUILD_TIME = "com.android.gamedriver.build_time"; private static final String ANGLE_RULES_FILE = "a4a_rules.json"; private static final String ANGLE_TEMP_RULES = "debug.angle.rules"; private static final String ACTION_ANGLE_FOR_ANDROID = "android.app.action.ANGLE_FOR_ANDROID"; @@ -702,7 +702,7 @@ public class GraphicsEnvironment { final String driverBuildTime = driverAppInfo.metaData.getString(METADATA_DRIVER_BUILD_TIME); if (driverBuildTime == null || driverBuildTime.isEmpty()) { - throw new IllegalArgumentException("driver_build_time meta-data is not set"); + throw new IllegalArgumentException("com.android.gamedriver.build_time is not set"); } // driver_build_time in the meta-data is in "L" format. e.g. L123456. // Long.parseLong will throw if the meta-data "driver_build_time" is not set properly. diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl index f62a999a7d390328003c61446dff4a229c2858ed..6536fc991b30caa148515faf34d2ec7f7923132f 100644 --- a/core/java/android/os/INetworkManagementService.aidl +++ b/core/java/android/os/INetworkManagementService.aidl @@ -241,27 +241,6 @@ interface INetworkManagementService */ void tetherLimitReached(ITetheringStatsProvider provider); - /** - ** PPPD - **/ - - /** - * Returns the list of currently known TTY devices on the system - */ - String[] listTtys(); - - /** - * Attaches a PPP server daemon to the specified TTY with the specified - * local/remote addresses. - */ - void attachPppd(String tty, String localAddr, String remoteAddr, String dns1Addr, - String dns2Addr); - - /** - * Detaches a PPP server daemon from the specified TTY. - */ - void detachPppd(String tty); - /** ** DATA USAGE RELATED **/ diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl index 423334008818c4ec6b31f6c14dcc36f9a769eb2f..e1d605e1c99da3ca2eb306c357a3de26654a13cd 100644 --- a/core/java/android/os/IPowerManager.aidl +++ b/core/java/android/os/IPowerManager.aidl @@ -34,6 +34,7 @@ interface IPowerManager String historyTag); void acquireWakeLockWithUid(IBinder lock, int flags, String tag, String packageName, int uidtoblame); + @UnsupportedAppUsage void releaseWakeLock(IBinder lock, int flags); void updateWakeLockUids(IBinder lock, in int[] uids); oneway void powerHint(int hintId, int data); @@ -52,10 +53,10 @@ interface IPowerManager boolean isPowerSaveMode(); PowerSaveState getPowerSaveState(int serviceType); boolean setPowerSaveModeEnabled(boolean mode); - boolean setDynamicPowerSavings(boolean dynamicPowerSavingsEnabled, int disableThreshold); + boolean setDynamicPowerSaveHint(boolean powerSaveHint, int disableThreshold); boolean setAdaptivePowerSavePolicy(in BatterySaverPolicyConfig config); boolean setAdaptivePowerSaveEnabled(boolean enabled); - int getPowerSaveMode(); + int getPowerSaveModeTrigger(); boolean isDeviceIdleMode(); boolean isLightDeviceIdleMode(); diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java index 36bae2daf9bddddb0ec33a55a83521fa77708b29..64e2f890ee479a9a5fa0ff11b751c6ec11fa521a 100644 --- a/core/java/android/os/PowerManager.java +++ b/core/java/android/os/PowerManager.java @@ -1460,7 +1460,7 @@ public final class PowerManager { * an on/off switch for a subset of features. * @hide * - * @param dynamicPowerSavingsEnabled A signal indicating to the system if it believes the + * @param powerSaveHint A signal indicating to the system if it believes the * dynamic power savings behaviors should be activated. * @param disableThreshold When the suggesting app believes it would be safe to disable dynamic * power savings behaviors. @@ -1471,10 +1471,9 @@ public final class PowerManager { @SystemApi @TestApi @RequiresPermission(permission.POWER_SAVER) - public boolean setDynamicPowerSavings(boolean dynamicPowerSavingsEnabled, - int disableThreshold) { + public boolean setDynamicPowerSaveHint(boolean powerSaveHint, int disableThreshold) { try { - return mService.setDynamicPowerSavings(dynamicPowerSavingsEnabled, disableThreshold); + return mService.setDynamicPowerSaveHint(powerSaveHint, disableThreshold); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1525,54 +1524,54 @@ public final class PowerManager { /** * Indicates automatic battery saver toggling by the system will be based on percentage. * - * @see PowerManager#getPowerSaveMode() + * @see PowerManager#getPowerSaveModeTrigger() * * @hide */ @SystemApi @TestApi - public static final int POWER_SAVER_MODE_PERCENTAGE = 0; + public static final int POWER_SAVE_MODE_TRIGGER_PERCENTAGE = 0; /** * Indicates automatic battery saver toggling by the system will be based on the state * of the dynamic power savings signal. * - * @see PowerManager#setDynamicPowerSavings(boolean, int) - * @see PowerManager#getPowerSaveMode() + * @see PowerManager#setDynamicPowerSaveHint(boolean, int) + * @see PowerManager#getPowerSaveModeTrigger() * * @hide */ @SystemApi @TestApi - public static final int POWER_SAVER_MODE_DYNAMIC = 1; + public static final int POWER_SAVE_MODE_TRIGGER_DYNAMIC = 1; /** @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef(value = { - POWER_SAVER_MODE_PERCENTAGE, - POWER_SAVER_MODE_DYNAMIC + POWER_SAVE_MODE_TRIGGER_PERCENTAGE, + POWER_SAVE_MODE_TRIGGER_DYNAMIC }) - public @interface AutoPowerSaverMode{} + public @interface AutoPowerSaveModeTriggers {} /** * Returns the current battery saver control mode. Values it may return are defined in - * AutoPowerSaverMode. Note that this is a global device state, not a per user setting. + * AutoPowerSaveModeTriggers. Note that this is a global device state, not a per user setting. * * @return The current value power saver mode for the system. * - * @see AutoPowerSaverMode - * @see PowerManager#getPowerSaveMode() + * @see AutoPowerSaveModeTriggers + * @see PowerManager#getPowerSaveModeTrigger() * @hide */ - @AutoPowerSaverMode + @AutoPowerSaveModeTriggers @SystemApi @TestApi @RequiresPermission(android.Manifest.permission.POWER_SAVER) - public int getPowerSaveMode() { + public int getPowerSaveModeTrigger() { try { - return mService.getPowerSaveMode(); + return mService.getPowerSaveModeTrigger(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java index 6a01e56cdf52e44e4a8d26790da0d11842a7bfa4..7cc7ccd2ad1695f3dd8dfc4448dd6e92ecad44d9 100644 --- a/core/java/android/os/RecoverySystem.java +++ b/core/java/android/os/RecoverySystem.java @@ -30,6 +30,7 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; +import android.os.storage.IStorageManager; import android.provider.Settings; import android.telephony.euicc.EuiccManager; import android.text.TextUtils; @@ -38,6 +39,8 @@ import android.util.Log; import android.view.Display; import android.view.WindowManager; +import com.android.internal.content.PackageHelper; + import libcore.io.Streams; import java.io.ByteArrayInputStream; @@ -854,6 +857,21 @@ public class RecoverySystem { /** {@hide} */ public static void rebootPromptAndWipeUserData(Context context, String reason) throws IOException { + boolean checkpointing = false; + + // If we are running in checkpointing mode, we should not prompt a wipe. + // Checkpointing may save us. If it doesn't, we will wind up here again. + try { + IStorageManager storageManager = PackageHelper.getStorageManager(); + if (storageManager.needsCheckpoint()) { + Log.i(TAG, "Rescue Party requested wipe. Aborting update instead."); + storageManager.abortChanges("rescueparty", false); + } + return; + } catch (RemoteException e) { + Log.i(TAG, "Failed to handle with checkpointing. Continuing with wipe."); + } + String reasonArg = null; if (!TextUtils.isEmpty(reason)) { reasonArg = "--reason=" + sanitizeArg(reason); diff --git a/core/java/android/os/ServiceSpecificException.java b/core/java/android/os/ServiceSpecificException.java index 3b0f26ae88677af3a7071093bb611fdcbfacf6f3..03d5d3e195e0fe99df9c0f9e2c385564f044fe7d 100644 --- a/core/java/android/os/ServiceSpecificException.java +++ b/core/java/android/os/ServiceSpecificException.java @@ -15,6 +15,7 @@ */ package android.os; +import android.annotation.Nullable; import android.annotation.SystemApi; /** @@ -34,7 +35,7 @@ import android.annotation.SystemApi; public class ServiceSpecificException extends RuntimeException { public final int errorCode; - public ServiceSpecificException(int errorCode, String message) { + public ServiceSpecificException(int errorCode, @Nullable String message) { super(message); this.errorCode = errorCode; } diff --git a/core/java/android/os/SystemClock.java b/core/java/android/os/SystemClock.java index e695a1b21593f9942ead7ece35e1d2e6a66d9e24..64effb8fa0ccacdc4641ac78e149082dc8d3d3d7 100644 --- a/core/java/android/os/SystemClock.java +++ b/core/java/android/os/SystemClock.java @@ -20,6 +20,8 @@ import android.annotation.NonNull; import android.annotation.UnsupportedAppUsage; import android.app.IAlarmManager; import android.content.Context; +import android.location.ILocationManager; +import android.location.LocationTime; import android.util.Slog; import dalvik.annotation.optimization.CriticalNative; @@ -317,4 +319,33 @@ public final class SystemClock { } }; } + + /** + * Returns a {@link Clock} that starts at January 1, 1970 00:00:00.0 UTC, + * synchronized using the device's location provider. + * + * @throws DateTimeException when the location provider has not had a location fix since boot. + */ + public static @NonNull Clock currentGnssTimeClock() { + return new SimpleClock(ZoneOffset.UTC) { + private final ILocationManager mMgr = ILocationManager.Stub + .asInterface(ServiceManager.getService(Context.LOCATION_SERVICE)); + @Override + public long millis() { + LocationTime time; + try { + time = mMgr.getGnssTimeMillis(); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + return 0; + } + if (time == null) { + throw new DateTimeException("Gnss based time is not available."); + } + long currentNanos = elapsedRealtimeNanos(); + long deltaMs = (currentNanos - time.getElapsedRealtimeNanos()) / 1000000L; + return time.getTime() + deltaMs; + } + }; + } } diff --git a/core/java/android/os/VibrationEffect.java b/core/java/android/os/VibrationEffect.java index c74cbff567c515d33f0b9b21a21e1685ef959ffa..7958ddd29c70f8f4bf796026671024eec7a74551 100644 --- a/core/java/android/os/VibrationEffect.java +++ b/core/java/android/os/VibrationEffect.java @@ -23,7 +23,7 @@ import android.annotation.TestApi; import android.content.ContentResolver; import android.content.Context; import android.hardware.vibrator.V1_0.EffectStrength; -import android.hardware.vibrator.V1_2.Effect; +import android.hardware.vibrator.V1_3.Effect; import android.net.Uri; import android.util.MathUtils; @@ -94,6 +94,18 @@ public abstract class VibrationEffect implements Parcelable { */ public static final int EFFECT_HEAVY_CLICK = Effect.HEAVY_CLICK; + /** + * A texture effect meant to replicate soft ticks. + * + * Unlike normal effects, texture effects are meant to be called repeatedly, generally in + * response to some motion, in order to replicate the feeling of some texture underneath the + * user's fingers. + * + * @see #get(int) + * @hide + */ + public static final int EFFECT_TEXTURE_TICK = Effect.TEXTURE_TICK; + /** {@hide} */ @TestApi public static final int EFFECT_STRENGTH_LIGHT = EffectStrength.LIGHT; @@ -746,6 +758,7 @@ public abstract class VibrationEffect implements Parcelable { case EFFECT_CLICK: case EFFECT_DOUBLE_CLICK: case EFFECT_TICK: + case EFFECT_TEXTURE_TICK: case EFFECT_THUD: case EFFECT_POP: case EFFECT_HEAVY_CLICK: @@ -798,7 +811,7 @@ public abstract class VibrationEffect implements Parcelable { out.writeInt(mEffectStrength); } - public static final @android.annotation.NonNull Parcelable.Creator CREATOR = + public static final @NonNull Parcelable.Creator CREATOR = new Parcelable.Creator() { @Override public Prebaked createFromParcel(Parcel in) { @@ -813,7 +826,7 @@ public abstract class VibrationEffect implements Parcelable { }; } - public static final @android.annotation.NonNull Parcelable.Creator CREATOR = + public static final @NonNull Parcelable.Creator CREATOR = new Parcelable.Creator() { @Override public VibrationEffect createFromParcel(Parcel in) { diff --git a/core/java/android/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java index 40238d2a9f2759f61144c4b1e57fba345ed75dc1..34200077044df8901cc78df58cecb3864cafc10e 100644 --- a/core/java/android/os/ZygoteProcess.java +++ b/core/java/android/os/ZygoteProcess.java @@ -66,22 +66,14 @@ import java.util.UUID; */ public class ZygoteProcess { - /** - * @hide for internal use only. - */ - public static final int ZYGOTE_CONNECT_TIMEOUT_MS = 20000; + private static final int ZYGOTE_CONNECT_TIMEOUT_MS = 20000; /** - * @hide for internal use only. - * * Use a relatively short delay, because for app zygote, this is in the critical path of * service launch. */ - public static final int ZYGOTE_CONNECT_RETRY_DELAY_MS = 50; + private static final int ZYGOTE_CONNECT_RETRY_DELAY_MS = 50; - /** - * @hide for internal use only - */ private static final String LOG_TAG = "ZygoteProcess"; /** @@ -141,7 +133,7 @@ public class ZygoteProcess { /** * State for communicating with the zygote process. */ - public static class ZygoteState { + private static class ZygoteState implements AutoCloseable { final LocalSocketAddress mZygoteSocketAddress; final LocalSocketAddress mUsapSocketAddress; @@ -178,12 +170,12 @@ public class ZygoteProcess { * address * @throws IOException */ - public static ZygoteState connect(@NonNull LocalSocketAddress zygoteSocketAddress, - @Nullable LocalSocketAddress usapSocketAddress) + static ZygoteState connect(@NonNull LocalSocketAddress zygoteSocketAddress, + @Nullable LocalSocketAddress usapSocketAddress) throws IOException { - DataInputStream zygoteInputStream = null; - BufferedWriter zygoteOutputWriter = null; + DataInputStream zygoteInputStream; + BufferedWriter zygoteOutputWriter; final LocalSocket zygoteSessionSocket = new LocalSocket(); if (zygoteSocketAddress == null) { @@ -357,8 +349,6 @@ public class ZygoteProcess { /** * Queries the zygote for the list of ABIS it supports. - * - * @throws ZygoteStartFailedEx if the query failed. */ @GuardedBy("mLock") private static List getAbiList(BufferedWriter writer, DataInputStream inputStream) @@ -411,52 +401,24 @@ public class ZygoteProcess { * the child or -1 on failure, followed by boolean to * indicate whether a wrapper process was used. */ - String msgStr = Integer.toString(args.size()) + "\n" - + String.join("\n", args) + "\n"; - - // Should there be a timeout on this? - Process.ProcessStartResult result = new Process.ProcessStartResult(); + String msgStr = args.size() + "\n" + String.join("\n", args) + "\n"; - // TODO (chriswailes): Move branch body into separate function. if (useUsapPool && mUsapPoolEnabled && isValidUsapCommand(args)) { - LocalSocket usapSessionSocket = null; - try { - usapSessionSocket = zygoteState.getUsapSessionSocket(); - - final BufferedWriter usapWriter = - new BufferedWriter( - new OutputStreamWriter(usapSessionSocket.getOutputStream()), - Zygote.SOCKET_BUFFER_SIZE); - final DataInputStream usapReader = - new DataInputStream(usapSessionSocket.getInputStream()); - - usapWriter.write(msgStr); - usapWriter.flush(); - - result.pid = usapReader.readInt(); - // USAPs can't be used to spawn processes that need wrappers. - result.usingWrapper = false; - - if (result.pid < 0) { - throw new ZygoteStartFailedEx("USAP specialization failed"); - } - - return result; + return attemptUsapSendArgsAndGetResult(zygoteState, msgStr); } catch (IOException ex) { // If there was an IOException using the USAP pool we will log the error and // attempt to start the process through the Zygote. Log.e(LOG_TAG, "IO Exception while communicating with USAP pool - " - + ex.getMessage()); - } finally { - try { - usapSessionSocket.close(); - } catch (IOException ex) { - Log.e(LOG_TAG, "Failed to close USAP session socket: " + ex.getMessage()); - } + + ex.getMessage()); } } + return attemptZygoteSendArgsAndGetResult(zygoteState, msgStr); + } + + private Process.ProcessStartResult attemptZygoteSendArgsAndGetResult( + ZygoteState zygoteState, String msgStr) throws ZygoteStartFailedEx { try { final BufferedWriter zygoteWriter = zygoteState.mZygoteOutputWriter; final DataInputStream zygoteInputStream = zygoteState.mZygoteInputStream; @@ -467,20 +429,48 @@ public class ZygoteProcess { // Always read the entire result from the input stream to avoid leaving // bytes in the stream for future process starts to accidentally stumble // upon. + Process.ProcessStartResult result = new Process.ProcessStartResult(); result.pid = zygoteInputStream.readInt(); result.usingWrapper = zygoteInputStream.readBoolean(); + + if (result.pid < 0) { + throw new ZygoteStartFailedEx("fork() failed"); + } + + return result; } catch (IOException ex) { zygoteState.close(); Log.e(LOG_TAG, "IO Exception while communicating with Zygote - " + ex.toString()); throw new ZygoteStartFailedEx(ex); } + } - if (result.pid < 0) { - throw new ZygoteStartFailedEx("fork() failed"); + private Process.ProcessStartResult attemptUsapSendArgsAndGetResult( + ZygoteState zygoteState, String msgStr) + throws ZygoteStartFailedEx, IOException { + try (LocalSocket usapSessionSocket = zygoteState.getUsapSessionSocket()) { + final BufferedWriter usapWriter = + new BufferedWriter( + new OutputStreamWriter(usapSessionSocket.getOutputStream()), + Zygote.SOCKET_BUFFER_SIZE); + final DataInputStream usapReader = + new DataInputStream(usapSessionSocket.getInputStream()); + + usapWriter.write(msgStr); + usapWriter.flush(); + + Process.ProcessStartResult result = new Process.ProcessStartResult(); + result.pid = usapReader.readInt(); + // USAPs can't be used to spawn processes that need wrappers. + result.usingWrapper = false; + + if (result.pid >= 0) { + return result; + } else { + throw new ZygoteStartFailedEx("USAP specialization failed"); + } } - - return result; } /** @@ -557,7 +547,7 @@ public class ZygoteProcess { boolean useUnspecializedAppProcessPool, @Nullable String[] extraArgs) throws ZygoteStartFailedEx { - ArrayList argsForZygote = new ArrayList(); + ArrayList argsForZygote = new ArrayList<>(); // --runtime-args, --setuid=, --setgid=, // and --setgroups= must go first @@ -627,17 +617,7 @@ public class ZygoteProcess { } if (packagesForUid != null && packagesForUid.length > 0) { - final StringBuilder sb = new StringBuilder(); - sb.append("--packages-for-uid="); - - // TODO (chriswailes): Replace with String.join - for (int i = 0; i < packagesForUid.length; ++i) { - if (i != 0) { - sb.append(','); - } - sb.append(packagesForUid[i]); - } - argsForZygote.add(sb.toString()); + argsForZygote.add("--packages-for-uid=" + String.join(",", packagesForUid)); } if (sandboxId != null) { @@ -647,9 +627,7 @@ public class ZygoteProcess { argsForZygote.add(processClass); if (extraArgs != null) { - for (String arg : extraArgs) { - argsForZygote.add(arg); - } + Collections.addAll(argsForZygote, extraArgs); } synchronized(mLock) { @@ -671,11 +649,13 @@ public class ZygoteProcess { Boolean.parseBoolean(USAP_POOL_ENABLED_DEFAULT)); } - if (origVal != mUsapPoolEnabled) { + boolean valueChanged = origVal != mUsapPoolEnabled; + + if (valueChanged) { Log.i(LOG_TAG, "usapPoolEnabled = " + mUsapPoolEnabled); } - return origVal != mUsapPoolEnabled; + return valueChanged; } private boolean mIsFirstPropCheck = true; @@ -805,10 +785,10 @@ public class ZygoteProcess { if (state == null || state.isClosed()) { Slog.e(LOG_TAG, "Can't set API blacklist exemptions: no zygote connection"); return false; - } - if (!sendIfEmpty && mApiBlacklistExemptions.isEmpty()) { + } else if (!sendIfEmpty && mApiBlacklistExemptions.isEmpty()) { return true; } + try { state.mZygoteOutputWriter.write(Integer.toString(mApiBlacklistExemptions.size() + 1)); state.mZygoteOutputWriter.newLine(); @@ -832,17 +812,15 @@ public class ZygoteProcess { } private void maybeSetHiddenApiAccessLogSampleRate(ZygoteState state) { - if (state == null || state.isClosed()) { - return; - } - if (mHiddenApiAccessLogSampleRate == -1) { + if (state == null || state.isClosed() || mHiddenApiAccessLogSampleRate == -1) { return; } + try { state.mZygoteOutputWriter.write(Integer.toString(1)); state.mZygoteOutputWriter.newLine(); state.mZygoteOutputWriter.write("--hidden-api-log-sampling-rate=" - + Integer.toString(mHiddenApiAccessLogSampleRate)); + + mHiddenApiAccessLogSampleRate); state.mZygoteOutputWriter.newLine(); state.mZygoteOutputWriter.flush(); int status = state.mZygoteInputStream.readInt(); @@ -855,17 +833,15 @@ public class ZygoteProcess { } private void maybeSetHiddenApiAccessStatslogSampleRate(ZygoteState state) { - if (state == null || state.isClosed()) { - return; - } - if (mHiddenApiAccessStatslogSampleRate == -1) { + if (state == null || state.isClosed() || mHiddenApiAccessStatslogSampleRate == -1) { return; } + try { state.mZygoteOutputWriter.write(Integer.toString(1)); state.mZygoteOutputWriter.newLine(); state.mZygoteOutputWriter.write("--hidden-api-statslog-sampling-rate=" - + Integer.toString(mHiddenApiAccessStatslogSampleRate)); + + mHiddenApiAccessStatslogSampleRate); state.mZygoteOutputWriter.newLine(); state.mZygoteOutputWriter.flush(); int status = state.mZygoteInputStream.readInt(); @@ -942,8 +918,8 @@ public class ZygoteProcess { * Only the app zygote supports this function. * TODO preloadPackageForAbi() can probably be removed and the callers an use this instead. */ - public boolean preloadApp(ApplicationInfo appInfo, String abi) throws ZygoteStartFailedEx, - IOException { + public boolean preloadApp(ApplicationInfo appInfo, String abi) + throws ZygoteStartFailedEx, IOException { synchronized (mLock) { ZygoteState state = openZygoteSocketIfNeeded(abi); state.mZygoteOutputWriter.write("2"); @@ -971,10 +947,10 @@ public class ZygoteProcess { * Instructs the zygote to pre-load the classes and native libraries at the given paths * for the specified abi. Not all zygotes support this function. */ - public boolean preloadPackageForAbi(String packagePath, String libsPath, String libFileName, - String cacheKey, String abi) throws ZygoteStartFailedEx, - IOException { - synchronized(mLock) { + public boolean preloadPackageForAbi( + String packagePath, String libsPath, String libFileName, String cacheKey, String abi) + throws ZygoteStartFailedEx, IOException { + synchronized (mLock) { ZygoteState state = openZygoteSocketIfNeeded(abi); state.mZygoteOutputWriter.write("5"); state.mZygoteOutputWriter.newLine(); @@ -1049,8 +1025,7 @@ public class ZygoteProcess { try { Thread.sleep(ZYGOTE_CONNECT_RETRY_DELAY_MS); - } catch (InterruptedException ie) { - } + } catch (InterruptedException ignored) { } } Slog.wtf(LOG_TAG, "Failed to connect to Zygote through socket " + zygoteSocketAddress.getName()); diff --git a/core/java/android/os/health/SystemHealthManager.java b/core/java/android/os/health/SystemHealthManager.java index 71eda19e165b714953b4217bdf362aebb0164f1f..a92e28a47660c914a9e4e77902993ad650288894 100644 --- a/core/java/android/os/health/SystemHealthManager.java +++ b/core/java/android/os/health/SystemHealthManager.java @@ -37,11 +37,13 @@ import com.android.internal.app.IBatteryStats; * by the logging itself. It can be substantial. *

* Battery Usage
- * The statistics related to power (battery) usage are recorded since the device - * was last unplugged. It is expected that applications schedule more work to do - * while the device is plugged in (e.g. using {@link android.app.job.JobScheduler - * JobScheduler}), and while that can affect charging rates, it is still preferable - * to actually draining the battery. + * Since Android version {@link android.os.Build.VERSION_CODES#Q}, the statistics related to power + * (battery) usage are recorded since the device was last considered fully charged (for previous + * versions, it is instead since the device was last unplugged). + * It is expected that applications schedule more work to do while the device is + * plugged in (e.g. using {@link android.app.job.JobScheduler JobScheduler}), and + * while that can affect charging rates, it is still preferable to actually draining + * the battery. */ @SystemService(Context.SYSTEM_HEALTH_SERVICE) public class SystemHealthManager { diff --git a/core/java/android/content/DynamicAndroidClient.java b/core/java/android/os/image/DynamicSystemClient.java similarity index 65% rename from core/java/android/content/DynamicAndroidClient.java rename to core/java/android/os/image/DynamicSystemClient.java index 571cba429ea9bb670870603af5af506a56467074..33a6ee888d0a72dadd349106b48cd9e7374bd6c0 100644 --- a/core/java/android/content/DynamicAndroidClient.java +++ b/core/java/android/os/image/DynamicSystemClient.java @@ -13,12 +13,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package android.content; +package android.os.image; +import android.annotation.BytesLong; import android.annotation.CallbackExecutor; import android.annotation.IntDef; import android.annotation.NonNull; +import android.annotation.RequiresPermission; import android.annotation.SystemApi; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.ServiceConnection; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; @@ -34,12 +40,28 @@ import java.lang.ref.WeakReference; import java.util.concurrent.Executor; /** - * This class contains methods and constants used to start DynamicAndroid - * installation, and a listener for progress update. + *

This class contains methods and constants used to start a {@code DynamicSystem} installation, + * and a listener for status updates.

+ * + *

{@code DynamicSystem} allows user to run certified system images in a non destructive manner + * without needing to prior OEM unlock. While running in {@code DynamicSystem}, persitent storage + * for factory reset protection (FRP) remains unchanged. The new system is installed in a + * temporarily allocated partition. After the installation is completed, the device will be running + * in the new system on next reboot. Then, when the user reboots the device again, it will leave + * {@code DynamicSystem} and go back into the original system. Since the userdata for + * {@code DynamicSystem} is also newly created during the installation, running in + * {@code DynamicSystem} doesn't change user's app data.

+ * + *

With {@link #setOnStatusChangedListener}, API users can register an + * {@link #OnStatusChangedListener} and get status updates and cause when the installation is + * started, stopped, or cancelled. It also sends progress updates during the installation. With + * {@link #start}, API users can start an installation with the {@link Uri} to a gzipped system + * image. The {@link Uri} can be a web URL or a content Uri to a local path.

+ * * @hide */ @SystemApi -public class DynamicAndroidClient { +public class DynamicSystemClient { /** @hide */ @IntDef(prefix = { "STATUS_" }, value = { STATUS_UNKNOWN, @@ -64,23 +86,23 @@ public class DynamicAndroidClient { @Retention(RetentionPolicy.SOURCE) public @interface StatusChangedCause {} - private static final String TAG = "DynAndroidClient"; + private static final String TAG = "DynSystemClient"; private static final long DEFAULT_USERDATA_SIZE = (10L << 30); - /** Listener for installation status update. */ + /** Listener for installation status updates. */ public interface OnStatusChangedListener { /** * This callback is called when installation status is changed, and when the - * client is {@link #bind} to DynamicAndroid installation service. + * client is {@link #bind} to {@code DynamicSystem} installation service. * - * @param status status code, also defined in {@code DynamicAndroidClient}. - * @param cause cause code, also defined in {@code DynamicAndroidClient}. + * @param status status code, also defined in {@code DynamicSystemClient}. + * @param cause cause code, also defined in {@code DynamicSystemClient}. * @param progress number of bytes installed. */ void onStatusChanged(@InstallationStatus int status, @StatusChangedCause int cause, - long progress); + @BytesLong long progress); } /* @@ -98,7 +120,7 @@ public class DynamicAndroidClient { /** Installation is finished but the user has not launched it. */ public static final int STATUS_READY = 3; - /** Device is running in Dynamic Android. */ + /** Device is running in {@code DynamicSystem}. */ public static final int STATUS_IN_USE = 4; /* @@ -113,7 +135,7 @@ public class DynamicAndroidClient { /** Status changed because installation is cancelled. */ public static final int CAUSE_INSTALL_CANCELLED = 2; - /** Installation failed due to IOException. */ + /** Installation failed due to {@code IOException}. */ public static final int CAUSE_ERROR_IO = 3; /** Installation failed because the image URL source is not supported. */ @@ -141,7 +163,7 @@ public class DynamicAndroidClient { public static final int MSG_UNREGISTER_LISTENER = 2; /** - * Message for status update. + * Message for status updates. * @hide */ public static final int MSG_POST_STATUS = 3; @@ -150,7 +172,7 @@ public class DynamicAndroidClient { * Messages keys */ /** - * Message key, for progress update. + * Message key, for progress updates. * @hide */ public static final String KEY_INSTALLED_SIZE = "KEY_INSTALLED_SIZE"; @@ -163,14 +185,14 @@ public class DynamicAndroidClient { * @hide */ public static final String ACTION_START_INSTALL = - "android.content.action.START_INSTALL"; + "android.os.image.action.START_INSTALL"; /** - * Intent action: notify user if we are currently running in Dynamic Android. + * Intent action: notify user if we are currently running in {@code DynamicSystem}. * @hide */ public static final String ACTION_NOTIFY_IF_IN_USE = - "android.content.action.NOTIFY_IF_IN_USE"; + "android.os.image.action.NOTIFY_IF_IN_USE"; /* * Intent Keys @@ -195,16 +217,16 @@ public class DynamicAndroidClient { private static class IncomingHandler extends Handler { - private final WeakReference mWeakClient; + private final WeakReference mWeakClient; - IncomingHandler(DynamicAndroidClient service) { + IncomingHandler(DynamicSystemClient service) { super(Looper.getMainLooper()); mWeakClient = new WeakReference<>(service); } @Override public void handleMessage(Message msg) { - DynamicAndroidClient service = mWeakClient.get(); + DynamicSystemClient service = mWeakClient.get(); if (service != null) { service.handleMessage(msg); @@ -212,9 +234,9 @@ public class DynamicAndroidClient { } } - private class DynAndroidServiceConnection implements ServiceConnection { + private class DynSystemServiceConnection implements ServiceConnection { public void onServiceConnected(ComponentName className, IBinder service) { - Slog.v(TAG, "DynAndroidService connected"); + Slog.v(TAG, "DynSystemService connected"); mService = new Messenger(service); @@ -232,13 +254,13 @@ public class DynamicAndroidClient { } public void onServiceDisconnected(ComponentName className) { - Slog.v(TAG, "DynAndroidService disconnected"); + Slog.v(TAG, "DynSystemService disconnected"); mService = null; } } private final Context mContext; - private final DynAndroidServiceConnection mConnection; + private final DynSystemServiceConnection mConnection; private final Messenger mMessenger; private boolean mBound; @@ -247,12 +269,16 @@ public class DynamicAndroidClient { private Messenger mService; /** + * Create a new {@code DynamicSystem} client. + * + * @param context a {@link Context} will be used to bind the installation service. + * * @hide */ @SystemApi - public DynamicAndroidClient(@NonNull Context context) { + public DynamicSystemClient(@NonNull Context context) { mContext = context; - mConnection = new DynAndroidServiceConnection(); + mConnection = new DynSystemServiceConnection(); mMessenger = new Messenger(new IncomingHandler(this)); } @@ -261,8 +287,8 @@ public class DynamicAndroidClient { * the executor. */ public void setOnStatusChangedListener( - @NonNull OnStatusChangedListener listener, - @NonNull @CallbackExecutor Executor executor) { + @NonNull @CallbackExecutor Executor executor, + @NonNull OnStatusChangedListener listener) { mListener = listener; mExecutor = executor; } @@ -278,12 +304,15 @@ public class DynamicAndroidClient { } /** - * Bind to DynamicAndroidInstallationService. + * Bind to {@code DynamicSystem} installation service. Binding to the installation service + * allows it to send status updates to {@link #OnStatusChangedListener}. It is recommanded + * to bind before calling {@link #start} and get status updates. */ + @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM) public void bind() { Intent intent = new Intent(); - intent.setClassName("com.android.dynandroid", - "com.android.dynandroid.DynamicAndroidInstallationService"); + intent.setClassName("com.android.dynsystem", + "com.android.dynsystem.DynamicSystemInstallationService"); mContext.bindService(intent, mConnection, Context.BIND_AUTO_CREATE); @@ -291,8 +320,10 @@ public class DynamicAndroidClient { } /** - * Unbind from DynamicAndroidInstallationService. + * Unbind from {@code DynamicSystem} installation service. Unbinding from the installation + * service stops it from sending following status updates. */ + @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM) public void unbind() { if (!mBound) { return; @@ -315,27 +346,40 @@ public class DynamicAndroidClient { } /** - * Start installing DynamicAndroid from URL with default userdata size. + * Start installing {@code DynamicSystem} from URL with default userdata size. + * + * Calling this function will first start an Activity to confirm device credential, using + * {@link KeyguardManager}. If it's confirmed, the installation service will be started. + * + * This function doesn't require prior calling {@link #bind}. * * @param systemUrl A network URL or a file URL to system image. * @param systemSize size of system image. */ - public void start(String systemUrl, long systemSize) { + @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM) + public void start(@NonNull String systemUrl, @BytesLong long systemSize) { start(systemUrl, systemSize, DEFAULT_USERDATA_SIZE); } /** - * Start installing DynamicAndroid from URL. + * Start installing {@code DynamicSystem} from URL. + * + * Calling this function will first start an Activity to confirm device credential, using + * {@link KeyguardManager}. If it's confirmed, the installation service will be started. + * + * This function doesn't require prior calling {@link #bind}. * * @param systemUrl A network URL or a file URL to system image. * @param systemSize size of system image. * @param userdataSize bytes reserved for userdata. */ - public void start(String systemUrl, long systemSize, long userdataSize) { + @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM) + public void start(@NonNull String systemUrl, @BytesLong long systemSize, + @BytesLong long userdataSize) { Intent intent = new Intent(); - intent.setClassName("com.android.dynandroid", - "com.android.dynandroid.VerificationActivity"); + intent.setClassName("com.android.dynsystem", + "com.android.dynsystem.VerificationActivity"); intent.setAction(ACTION_START_INSTALL); diff --git a/core/java/android/os/DynamicAndroidManager.java b/core/java/android/os/image/DynamicSystemManager.java similarity index 81% rename from core/java/android/os/DynamicAndroidManager.java rename to core/java/android/os/image/DynamicSystemManager.java index 5238896016eecaaac009b1d5213545d7bb170ee8..0458c2a8b735435815da9299c58c21d94a25d6e6 100644 --- a/core/java/android/os/DynamicAndroidManager.java +++ b/core/java/android/os/image/DynamicSystemManager.java @@ -14,50 +14,51 @@ * limitations under the License. */ -package android.os; +package android.os.image; import android.annotation.RequiresPermission; import android.annotation.SystemService; import android.content.Context; import android.gsi.GsiProgress; +import android.os.RemoteException; /** - * The DynamicAndroidManager offers a mechanism to use a new Android image temporarily. After the + * The DynamicSystemManager offers a mechanism to use a new system image temporarily. After the * installation, the device can reboot into this image with a new created /data. This image will * last until the next reboot and then the device will go back to the original image. However the * installed image and the new created /data are not deleted but disabled. Thus the application can * either re-enable the installed image by calling {@link #toggle} or use the {@link #remove} to * delete it completely. In other words, there are three device states: no installation, installed - * and running. The procedure to install a DynamicAndroid starts with a {@link #startInstallation}, + * and running. The procedure to install a DynamicSystem starts with a {@link #startInstallation}, * followed by a series of {@link #write} and ends with a {@link commit}. Once the installation is * complete, the device state changes from no installation to the installed state and a followed - * reboot will change its state to running. Note one instance of dynamic android can exist on a - * given device thus the {@link #startInstallation} will fail if the device is currently running a - * DynamicAndroid. + * reboot will change its state to running. Note one instance of DynamicSystem can exist on a given + * device thus the {@link #startInstallation} will fail if the device is currently running a + * DynamicSystem. * * @hide */ -@SystemService(Context.DYNAMIC_ANDROID_SERVICE) -public class DynamicAndroidManager { - private static final String TAG = "DynamicAndroidManager"; +@SystemService(Context.DYNAMIC_SYSTEM_SERVICE) +public class DynamicSystemManager { + private static final String TAG = "DynamicSystemManager"; - private final IDynamicAndroidService mService; + private final IDynamicSystemService mService; /** {@hide} */ - public DynamicAndroidManager(IDynamicAndroidService service) { + public DynamicSystemManager(IDynamicSystemService service) { mService = service; } - /** The DynamicAndroidManager.Session represents a started session for the installation. */ + /** The DynamicSystemManager.Session represents a started session for the installation. */ public class Session { private Session() {} /** - * Write a chunk of the DynamicAndroid system image + * Write a chunk of the DynamicSystem system image * * @return {@code true} if the call succeeds. {@code false} if there is any native runtime * error. */ - @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_ANDROID) + @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM) public boolean write(byte[] buf) { try { return mService.write(buf); @@ -72,7 +73,7 @@ public class DynamicAndroidManager { * @return {@code true} if the call succeeds. {@code false} if there is any native runtime * error. */ - @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_ANDROID) + @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM) public boolean commit() { try { return mService.commit(); @@ -82,16 +83,16 @@ public class DynamicAndroidManager { } } /** - * Start DynamicAndroid installation. This call may take an unbounded amount of time. The caller + * Start DynamicSystem installation. This call may take an unbounded amount of time. The caller * may use another thread to call the getStartProgress() to get the progress. * * @param systemSize system size in bytes * @param userdataSize userdata size in bytes * @return {@code true} if the call succeeds. {@code false} either the device does not contain - * enough space or a DynamicAndroid is currently in use where the {@link #isInUse} would be + * enough space or a DynamicSystem is currently in use where the {@link #isInUse} would be * true. */ - @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_ANDROID) + @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM) public Session startInstallation(long systemSize, long userdataSize) { try { if (mService.startInstallation(systemSize, userdataSize)) { @@ -112,7 +113,7 @@ public class DynamicAndroidManager { * status field can be IGsiService.STATUS_NO_OPERATION, IGsiService.STATUS_WORKING or * IGsiService.STATUS_COMPLETE. */ - @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_ANDROID) + @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM) public GsiProgress getInstallationProgress() { try { return mService.getInstallationProgress(); @@ -129,7 +130,7 @@ public class DynamicAndroidManager { * @return {@code true} if the call succeeds. {@code false} if there is no installation * currently. */ - @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_ANDROID) + @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM) public boolean abort() { try { return mService.abort(); @@ -138,8 +139,8 @@ public class DynamicAndroidManager { } } - /** @return {@code true} if the device is running a dynamic android */ - @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_ANDROID) + /** @return {@code true} if the device is running a dynamic system */ + @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM) public boolean isInUse() { try { return mService.isInUse(); @@ -148,8 +149,8 @@ public class DynamicAndroidManager { } } - /** @return {@code true} if the device has a dynamic android installed */ - @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_ANDROID) + /** @return {@code true} if the device has a dynamic system installed */ + @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM) public boolean isInstalled() { try { return mService.isInstalled(); @@ -159,11 +160,11 @@ public class DynamicAndroidManager { } /** - * Remove DynamicAndroid installation if present + * Remove DynamicSystem installation if present * * @return {@code true} if the call succeeds. {@code false} if there is no installed image. */ - @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_ANDROID) + @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM) public boolean remove() { try { return mService.remove(); @@ -173,11 +174,11 @@ public class DynamicAndroidManager { } /** - * Enable DynamicAndroid when it's not enabled, otherwise, disable it. + * Enable DynamicSystem when it's not enabled, otherwise, disable it. * * @return {@code true} if the call succeeds. {@code false} if there is no installed image. */ - @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_ANDROID) + @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM) public boolean toggle() { try { return mService.toggle(); diff --git a/core/java/android/os/IDynamicAndroidService.aidl b/core/java/android/os/image/IDynamicSystemService.aidl similarity index 84% rename from core/java/android/os/IDynamicAndroidService.aidl rename to core/java/android/os/image/IDynamicSystemService.aidl index 0b28799c8dd005117c2be98ce56eb74e1a20e5f4..15f5b68e354b7cebe24f39cea93ccb354d773e3b 100644 --- a/core/java/android/os/IDynamicAndroidService.aidl +++ b/core/java/android/os/image/IDynamicSystemService.aidl @@ -13,15 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package android.os; +package android.os.image; import android.gsi.GsiProgress; /** {@hide} */ -interface IDynamicAndroidService +interface IDynamicSystemService { /** - * Start DynamicAndroid installation. This call may take 60~90 seconds. The caller + * Start DynamicSystem installation. This call may take 60~90 seconds. The caller * may use another thread to call the getStartProgress() to get the progress. * * @param systemSize system size in bytes @@ -53,26 +53,26 @@ interface IDynamicAndroidService boolean isInUse(); /** - * @return true if the device has an DynamicAndroid image installed + * @return true if the device has an DynamicSystem image installed */ boolean isInstalled(); /** - * Remove DynamicAndroid installation if present + * Remove DynamicSystem installation if present * * @return true if the call succeeds */ boolean remove(); /** - * Enable DynamicAndroid when it's not enabled, otherwise, disable it. + * Enable DynamicSystem when it's not enabled, otherwise, disable it. * * @return true if the call succeeds */ boolean toggle(); /** - * Write a chunk of the DynamicAndroid system image + * Write a chunk of the DynamicSystem system image * * @return true if the call succeeds */ diff --git a/core/java/android/os/storage/IStorageManager.aidl b/core/java/android/os/storage/IStorageManager.aidl index 25f67f81b70a68a6f5558aff79ed0941d63d247e..9db41116d20af54a6b968a96f7a455c5ba0d2dc7 100644 --- a/core/java/android/os/storage/IStorageManager.aidl +++ b/core/java/android/os/storage/IStorageManager.aidl @@ -193,4 +193,6 @@ interface IStorageManager { void commitChanges() = 83; boolean supportsCheckpoint() = 84; void startCheckpoint(int numTries) = 85; + boolean needsCheckpoint() = 86; + void abortChanges(in String message, boolean retry) = 87; } diff --git a/core/java/android/permission/RuntimePermissionUsageInfo.java b/core/java/android/permission/RuntimePermissionUsageInfo.java index 9f954f7dcbe92bb81010333e8e48717104da00af..863b0ad9c3d4ae0ff6fd03097f9e6da06095d21d 100644 --- a/core/java/android/permission/RuntimePermissionUsageInfo.java +++ b/core/java/android/permission/RuntimePermissionUsageInfo.java @@ -35,7 +35,7 @@ import android.os.Parcelable; */ @SystemApi public final class RuntimePermissionUsageInfo implements Parcelable { - private final @NonNull CharSequence mName; + private final @NonNull String mName; private final int mNumUsers; /** @@ -44,7 +44,7 @@ public final class RuntimePermissionUsageInfo implements Parcelable { * @param name The permission group name. * @param numUsers The number of apps that have used this permission. */ - public RuntimePermissionUsageInfo(@NonNull CharSequence name, int numUsers) { + public RuntimePermissionUsageInfo(@NonNull String name, int numUsers) { checkNotNull(name); checkArgumentNonnegative(numUsers); @@ -53,7 +53,7 @@ public final class RuntimePermissionUsageInfo implements Parcelable { } private RuntimePermissionUsageInfo(Parcel parcel) { - this(parcel.readCharSequence(), parcel.readInt()); + this(parcel.readString(), parcel.readInt()); } /** @@ -68,7 +68,7 @@ public final class RuntimePermissionUsageInfo implements Parcelable { * * @return The name. */ - public @NonNull CharSequence getName() { + public @NonNull String getName() { return mName; } @@ -79,7 +79,7 @@ public final class RuntimePermissionUsageInfo implements Parcelable { @Override public void writeToParcel(Parcel parcel, int flags) { - parcel.writeCharSequence(mName); + parcel.writeString(mName); parcel.writeInt(mNumUsers); } diff --git a/core/java/android/preference/PreferenceGroupAdapter.java b/core/java/android/preference/PreferenceGroupAdapter.java index fb41ea8218b7b4e8359a5f3e012947e5ac249c13..dcc5d4c587846d4ddd43fb334757581ffea7de7c 100644 --- a/core/java/android/preference/PreferenceGroupAdapter.java +++ b/core/java/android/preference/PreferenceGroupAdapter.java @@ -16,6 +16,7 @@ package android.preference; +import android.annotation.UnsupportedAppUsage; import android.graphics.drawable.Drawable; import android.os.Handler; import android.preference.Preference.OnPreferenceChangeInternalListener; @@ -215,6 +216,7 @@ public class PreferenceGroupAdapter extends BaseAdapter return mPreferenceList.size(); } + @UnsupportedAppUsage public Preference getItem(int position) { if (position < 0 || position >= getCount()) return null; return mPreferenceList.get(position); diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java index 7fc07b05771cb3b8ad83ab10b43a31f98caca0fb..728d77ef941ea941cae96856df72d83541cc8e56 100644 --- a/core/java/android/provider/DeviceConfig.java +++ b/core/java/android/provider/DeviceConfig.java @@ -27,6 +27,8 @@ import android.annotation.SystemApi; import android.annotation.TestApi; import android.app.ActivityThread; import android.content.ContentResolver; +import android.content.Context; +import android.content.pm.PackageManager; import android.database.ContentObserver; import android.net.Uri; import android.provider.Settings.ResetMode; @@ -37,6 +39,7 @@ import android.util.Pair; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.Preconditions; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -240,6 +243,14 @@ public final class DeviceConfig { @SystemApi public static final String NAMESPACE_SYSTEMUI = "systemui"; + /** + * Telephony related properties. + * + * @hide + */ + @SystemApi + public static final String NAMESPACE_TELEPHONY = "telephony"; + /** * Namespace for TextClassifier related features. * @@ -248,6 +259,14 @@ public final class DeviceConfig { @SystemApi public static final String NAMESPACE_TEXTCLASSIFIER = "textclassifier"; + /** + * List of namespaces which can be read without READ_DEVICE_CONFIG permission + * + * @hide + */ + @NonNull + private static final List PUBLIC_NAMESPACES = + Arrays.asList(NAMESPACE_TEXTCLASSIFIER, NAMESPACE_RUNTIME); /** * Privacy related properties definitions. * @@ -285,7 +304,6 @@ public final class DeviceConfig { * * @hide */ - @SystemApi public interface Telephony { String NAMESPACE = "telephony"; /** @@ -520,6 +538,8 @@ public final class DeviceConfig { @NonNull String namespace, @NonNull @CallbackExecutor Executor executor, @NonNull OnPropertyChangedListener onPropertyChangedListener) { + enforceReadPermission(ActivityThread.currentApplication().getApplicationContext(), + namespace); synchronized (sLock) { Pair oldNamespace = sSingleListeners.get(onPropertyChangedListener); if (oldNamespace == null) { @@ -559,6 +579,8 @@ public final class DeviceConfig { @NonNull String namespace, @NonNull @CallbackExecutor Executor executor, @NonNull OnPropertiesChangedListener onPropertiesChangedListener) { + enforceReadPermission(ActivityThread.currentApplication().getApplicationContext(), + namespace); synchronized (sLock) { Pair oldNamespace = sListeners.get(onPropertiesChangedListener); if (oldNamespace == null) { @@ -660,7 +682,7 @@ public final class DeviceConfig { } /** - * Decrement the count used to represent th enumber of listeners subscribed to the given + * Decrement the count used to represent the number of listeners subscribed to the given * namespace. If this is the final decrement call (i.e. decrementing from 1 to 0) for the given * namespace, the ContentObserver that had been tracking it will be removed. * @@ -689,7 +711,14 @@ public final class DeviceConfig { // pathSegments(0) is "config" final String namespace = pathSegments.get(1); final String name = pathSegments.get(2); - final String value = getProperty(namespace, name); + final String value; + try { + value = getProperty(namespace, name); + } catch (SecurityException e) { + // Silently failing to not crash binder or listener threads. + Log.e(TAG, "OnPropertyChangedListener update failed: permission violation."); + return; + } synchronized (sLock) { // OnPropertiesChangedListeners for (int i = 0; i < sListeners.size(); i++) { @@ -723,6 +752,22 @@ public final class DeviceConfig { } } + + /** + * Enforces READ_DEVICE_CONFIG permission if namespace is not one of public namespaces. + * @hide + */ + public static void enforceReadPermission(Context context, String namespace) { + if (context.checkCallingOrSelfPermission(READ_DEVICE_CONFIG) + != PackageManager.PERMISSION_GRANTED) { + if (!PUBLIC_NAMESPACES.contains(namespace)) { + throw new SecurityException("Permission denial: reading from settings requires:" + + READ_DEVICE_CONFIG); + } + } + } + + /** * Interface for monitoring single property changes. *

diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java index 14863338f182d80ae5d3e105aa3d342c64247656..7feeeee0f790f7d22a05d532b24fdad1e839cefd 100644 --- a/core/java/android/provider/MediaStore.java +++ b/core/java/android/provider/MediaStore.java @@ -115,9 +115,9 @@ public final class MediaStore { */ public static final String VOLUME_EXTERNAL = "external"; - /** {@hide} */ @TestApi + /** {@hide} */ public static final String SCAN_FILE_CALL = "scan_file"; - /** {@hide} */ @TestApi + /** {@hide} */ public static final String SCAN_VOLUME_CALL = "scan_volume"; /** @@ -126,7 +126,6 @@ public final class MediaStore { * * {@hide} */ - @TestApi public static final String EXTRA_ORIGINATED_FROM_SHELL = "android.intent.extra.originated_from_shell"; @@ -136,6 +135,7 @@ public final class MediaStore { * removing nomedia files * @hide */ + @Deprecated public static final String UNHIDE_CALL = "unhide"; /** @@ -873,7 +873,7 @@ public final class MediaStore { */ public interface MediaColumns extends BaseColumns { /** - * Path to the media item on disk. + * Absolute filesystem path to the media item on disk. *

* Note that apps may not have filesystem permissions to directly access * this path. Instead of trying to open this path directly, apps should @@ -920,6 +920,10 @@ public final class MediaStore { /** * The display name of the media item. + *

+ * For example, an item stored at + * {@code /storage/0000-0000/DCIM/Vacation/IMG1024.JPG} would have a + * display name of {@code IMG1024.JPG}. */ @Column(Cursor.FIELD_TYPE_STRING) public static final String DISPLAY_NAME = "_display_name"; @@ -985,7 +989,8 @@ public final class MediaStore { /** * Flag indicating if a media item is pending, and still being inserted - * by its owner. + * by its owner. While this flag is set, only the owner of the item can + * open the underlying file; requests from other apps will be rejected. * * @see MediaStore#setIncludePending(Uri) */ @@ -1032,18 +1037,54 @@ public final class MediaStore { @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true) public static final String OWNER_PACKAGE_NAME = "owner_package_name"; + /** + * Relative path of this media item within the storage device where it + * is persisted. For example, an item stored at + * {@code /storage/0000-0000/DCIM/Vacation/IMG1024.JPG} would have a + * path of {@code DCIM/Vacation}. + *

+ * This value should only be used for organizational purposes, and you + * should not attempt to construct or access a raw filesystem path using + * this value. If you need to open a media item, use an API like + * {@link ContentResolver#openFileDescriptor(Uri, String)}. + *

+ * When this value is set to {@code NULL} during an + * {@link ContentResolver#insert} operation, the newly created item will + * be placed in a relevant default location based on the type of media + * being inserted. For example, a {@code image/jpeg} item will be placed + * under {@link Environment#DIRECTORY_PICTURES}. + *

+ * You can modify this column during an {@link ContentResolver#update} + * call, which will move the underlying file on disk. + *

+ * In both cases above, content must be placed under a top-level + * directory that is relevant to the media type. For example, attempting + * to place a {@code audio/mpeg} file under + * {@link Environment#DIRECTORY_PICTURES} will be rejected. + */ + @Column(Cursor.FIELD_TYPE_STRING) + public static final String RELATIVE_PATH = "relative_path"; + /** * The primary directory name this media exists under. The value may be * {@code NULL} if the media doesn't have a primary directory name. + * + * @removed + * @deprecated Replaced by {@link #RELATIVE_PATH}. */ @Column(Cursor.FIELD_TYPE_STRING) + @Deprecated public static final String PRIMARY_DIRECTORY = "primary_directory"; /** * The secondary directory name this media exists under. The value may * be {@code NULL} if the media doesn't have a secondary directory name. + * + * @removed + * @deprecated Replaced by {@link #RELATIVE_PATH}. */ @Column(Cursor.FIELD_TYPE_STRING) + @Deprecated public static final String SECONDARY_DIRECTORY = "secondary_directory"; /** @@ -1339,6 +1380,11 @@ public final class MediaStore { .appendPath("downloads").build(); } + /** @hide */ + public static @NonNull Uri getContentUri(@NonNull String volumeName, long id) { + return ContentUris.withAppendedId(getContentUri(volumeName), id); + } + /** @hide */ public static @NonNull Uri getContentUriForPath(@NonNull String path) { return getContentUri(getVolumeName(new File(path))); @@ -1711,6 +1757,11 @@ public final class MediaStore { .appendPath("media").build(); } + /** @hide */ + public static @NonNull Uri getContentUri(@NonNull String volumeName, long id) { + return ContentUris.withAppendedId(getContentUri(volumeName), id); + } + /** * The content:// style URI for the internal storage. */ @@ -2199,6 +2250,11 @@ public final class MediaStore { .appendPath("media").build(); } + /** @hide */ + public static @NonNull Uri getContentUri(@NonNull String volumeName, long id) { + return ContentUris.withAppendedId(getContentUri(volumeName), id); + } + /** * Get the content:// style URI for the given audio media file. * @@ -2977,6 +3033,11 @@ public final class MediaStore { .appendPath("media").build(); } + /** @hide */ + public static @NonNull Uri getContentUri(@NonNull String volumeName, long id) { + return ContentUris.withAppendedId(getContentUri(volumeName), id); + } + /** * The content:// style URI for the internal storage. */ @@ -3344,6 +3405,10 @@ public final class MediaStore { * substantial changes, and that data should be rescanned. *

* No other assumptions should be made about the meaning of the version. + * + * @param volumeName specific volume to obtain an opaque version string for. + * Must be one of the values returned from + * {@link #getAllVolumeNames(Context)}. */ public static @NonNull String getVersion(@NonNull Context context, @NonNull String volumeName) { final ContentResolver resolver = context.getContentResolver(); @@ -3471,4 +3536,37 @@ public final class MediaStore { throw new IOException("User " + user + " must be unlocked and running"); } } + + /** @hide */ + @TestApi + public static Uri scanFile(Context context, File file) { + return scan(context, SCAN_FILE_CALL, file, false); + } + + /** @hide */ + @TestApi + public static Uri scanFileFromShell(Context context, File file) { + return scan(context, SCAN_FILE_CALL, file, true); + } + + /** @hide */ + @TestApi + public static void scanVolume(Context context, File file) { + scan(context, SCAN_VOLUME_CALL, file, false); + } + + /** @hide */ + private static Uri scan(Context context, String method, File file, + boolean originatedFromShell) { + final ContentResolver resolver = context.getContentResolver(); + try (ContentProviderClient client = resolver.acquireContentProviderClient(AUTHORITY)) { + final Bundle in = new Bundle(); + in.putParcelable(Intent.EXTRA_STREAM, Uri.fromFile(file)); + in.putBoolean(EXTRA_ORIGINATED_FROM_SHELL, originatedFromShell); + final Bundle out = client.call(method, null, in); + return out.getParcelable(Intent.EXTRA_STREAM); + } catch (RemoteException e) { + throw e.rethrowAsRuntimeException(); + } + } } diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 63235a1c17e7a4de28d025ca5c13a869cd04d0f6..702dc74f774803f84afda8ec131f90a686025950 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -73,6 +73,7 @@ import android.os.Bundle; import android.os.DropBoxManager; import android.os.IBinder; import android.os.LocaleList; +import android.os.PowerManager.AutoPowerSaveModeTriggers; import android.os.Process; import android.os.RemoteException; import android.os.ResultReceiver; @@ -875,7 +876,8 @@ public final class Settings { /** * Activity Action: Show screen for controlling app usage properties for an app. - * Input: Intent's extra EXTRA_PACKAGE_NAME must specify the application package name. + * Input: Intent's extra {@link android.content.Intent#EXTRA_PACKAGE_NAME} must specify the + * application package name. * Output: Nothing. */ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) @@ -1260,6 +1262,25 @@ public final class Settings { public static final String ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS = "android.settings.NOTIFICATION_POLICY_ACCESS_SETTINGS"; + /** + * Activity Action: Show do not disturb setting page for app. + *

+ * Users can grant and deny access to Do Not Disturb configuration for an app from here. + * See {@link android.app.NotificationManager#isNotificationPolicyAccessGranted()} for more + * details. + *

+ * Input: Intent's data URI set with an application name, using the + * "package" schema (like "package:com.my.app"). + *

+ * Output: Nothing. + * + * @hide + */ + @SystemApi + @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) + public static final String ACTION_NOTIFICATION_POLICY_ACCESS_DETAIL_SETTINGS = + "android.settings.NOTIFICATION_POLICY_ACCESS_DETAIL_SETTINGS"; + /** * @hide */ @@ -5612,6 +5633,17 @@ public final class Settings { private static final Validator ODI_CAPTIONS_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR; + /** + * Setting to indicate that on device captions cannot be shown because the app + * which is currently playing media had opted out. + * + * @hide + */ + @SystemApi + public static final String ODI_CAPTIONS_OPTED_OUT = "odi_captions_opted_out"; + + private static final Validator ODI_CAPTIONS_OPTED_OUT_VALIDATOR = BOOLEAN_VALIDATOR; + /** * On Android 8.0 (API level 26) and higher versions of the platform, * a 64-bit number (expressed as a hexadecimal string), unique to @@ -8012,17 +8044,6 @@ public final class Settings { private static final Validator CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR; - /** - * Whether the swipe up gesture to switch apps should be enabled. - * - * @hide - */ - public static final String SWIPE_UP_TO_SWITCH_APPS_ENABLED = - "swipe_up_to_switch_apps_enabled"; - - private static final Validator SWIPE_UP_TO_SWITCH_APPS_ENABLED_VALIDATOR = - BOOLEAN_VALIDATOR; - /** * Whether or not the smart camera lift trigger that launches the camera when the user moves * the phone into a position for taking photos should be enabled. @@ -8575,38 +8596,6 @@ public final class Settings { public static final String PACKAGES_TO_CLEAR_DATA_BEFORE_FULL_RESTORE = "packages_to_clear_data_before_full_restore"; - /** - * Indicates the location state should be maintained after sensor privacy is disabled. - * @hide - */ - public static final String MAINTAIN_LOCATION_AFTER_SP_DISABLED = "0"; - - /** - * Indicates location should be reenabled after sensor privacy is disabled. - * @hide - */ - public static final String REENABLE_LOCATION_AFTER_SP_DISABLED = "1"; - - /** - * Indicates the state of airplane mode should be maintained after sensor privacy is - * disabled. - * @hide - */ - public static final String MAINTAIN_AIRPLANE_MODE_AFTER_SP_DISABLED = "0"; - - /** - * Indicates airplane mode should be disabled after sensor privacy is disabled. - * @hide - */ - public static final String DISABLE_AIRPLANE_MODE_AFTER_SP_DISABLED = "1"; - - /** - * The state of all sensors managed by SensorPrivacyService when sensor privacy is enabled. - * @hide - */ - public static final String SENSOR_PRIVACY_SENSOR_STATE = - "sensor_privacy_sensor_state"; - /** * Setting to determine whether to use the new notification priority handling features. * @hide @@ -8739,7 +8728,6 @@ public final class Settings { DISPLAY_WHITE_BALANCE_ENABLED, SYNC_PARENT_SOUNDS, CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED, - SWIPE_UP_TO_SWITCH_APPS_ENABLED, CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, SYSTEM_NAVIGATION_KEYS_ENABLED, QS_TILES, @@ -8902,8 +8890,6 @@ public final class Settings { VALIDATORS.put(SYNC_PARENT_SOUNDS, SYNC_PARENT_SOUNDS_VALIDATOR); VALIDATORS.put(CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED, CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED_VALIDATOR); - VALIDATORS.put(SWIPE_UP_TO_SWITCH_APPS_ENABLED, - SWIPE_UP_TO_SWITCH_APPS_ENABLED_VALIDATOR); VALIDATORS.put(CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED_VALIDATOR); VALIDATORS.put(SYSTEM_NAVIGATION_KEYS_ENABLED, @@ -8979,6 +8965,7 @@ public final class Settings { VALIDATORS.put(SILENCE_CALL_GESTURE_COUNT, SILENCE_GESTURE_COUNT_VALIDATOR); VALIDATORS.put(SILENCE_NOTIFICATION_GESTURE_COUNT, SILENCE_GESTURE_COUNT_VALIDATOR); VALIDATORS.put(ODI_CAPTIONS_ENABLED, ODI_CAPTIONS_ENABLED_VALIDATOR); + VALIDATORS.put(ODI_CAPTIONS_OPTED_OUT, ODI_CAPTIONS_OPTED_OUT_VALIDATOR); } /** @@ -12600,12 +12587,11 @@ public final class Settings { /** * Battery level [1-100] at which low power mode automatically turns on. * If 0, it will not automatically turn on. For Q and newer, it will only automatically - * turn on if the value is greater than 0 and the {@link #AUTOMATIC_POWER_SAVER_MODE} + * turn on if the value is greater than 0 and the {@link #AUTOMATIC_POWER_SAVE_MODE} * setting is also set to - * {@link android.os.PowerManager.AutoPowerSaverMode#POWER_SAVER_MODE_PERCENTAGE}. - * - * @see #AUTOMATIC_POWER_SAVER_MODE - * @see android.os.PowerManager#getPowerSaveMode() + * {@link android.os.PowerManager.AutoPowerSaveMode#POWER_SAVE_MODE_TRIGGER_PERCENTAGE}. + * @see #AUTOMATIC_POWER_SAVE_MODE + * @see android.os.PowerManager#getPowerSaveModeTrigger() * @hide */ public static final String LOW_POWER_MODE_TRIGGER_LEVEL = "low_power_trigger_level"; @@ -12615,22 +12601,22 @@ public final class Settings { /** * Whether battery saver is currently set to trigger based on percentage, dynamic power - * savings trigger, or none. See {@link android.os.PowerManager.AutoPowerSaverMode} for + * savings trigger, or none. See {@link AutoPowerSaveModeTriggers} for * accepted values. * * @hide */ @TestApi - public static final String AUTOMATIC_POWER_SAVER_MODE = "automatic_power_saver_mode"; + public static final String AUTOMATIC_POWER_SAVE_MODE = "automatic_power_save_mode"; - private static final Validator AUTOMATIC_POWER_SAVER_MODE_VALIDATOR = + private static final Validator AUTOMATIC_POWER_SAVE_MODE_VALIDATOR = new SettingsValidators.DiscreteValueValidator(new String[] {"0", "1"}); /** * The setting that backs the disable threshold for the setPowerSavingsWarning api in * PowerManager * - * @see android.os.PowerManager#setDynamicPowerSavings(boolean, int) + * @see android.os.PowerManager#setDynamicPowerSaveHint(boolean, int) * @hide */ @TestApi @@ -12640,9 +12626,9 @@ public final class Settings { new SettingsValidators.InclusiveIntegerRangeValidator(0, 100); /** - * The setting which backs the setDynamicPowerSavings api in PowerManager. + * The setting which backs the setDynamicPowerSaveHint api in PowerManager. * - * @see android.os.PowerManager#setDynamicPowerSavings(boolean, int) + * @see android.os.PowerManager#setDynamicPowerSaveHint(boolean, int) * @hide */ @TestApi @@ -13631,7 +13617,7 @@ public final class Settings { VALIDATORS.put(LOW_POWER_MODE_TRIGGER_LEVEL, LOW_POWER_MODE_TRIGGER_LEVEL_VALIDATOR); VALIDATORS.put(LOW_POWER_MODE_TRIGGER_LEVEL_MAX, LOW_POWER_MODE_TRIGGER_LEVEL_VALIDATOR); - VALIDATORS.put(AUTOMATIC_POWER_SAVER_MODE, AUTOMATIC_POWER_SAVER_MODE_VALIDATOR); + VALIDATORS.put(AUTOMATIC_POWER_SAVE_MODE, AUTOMATIC_POWER_SAVE_MODE_VALIDATOR); VALIDATORS.put(DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD, DYNAMIC_POWER_SAVINGS_VALIDATOR); VALIDATORS.put(BLUETOOTH_ON, BLUETOOTH_ON_VALIDATOR); diff --git a/core/java/android/security/keymaster/KeymasterBlobArgument.java b/core/java/android/security/keymaster/KeymasterBlobArgument.java index 541d33ef614f5791baf19029f4990603dab6eff7..fc562bd2174e4ec2dcbedf513ab2638688691103 100644 --- a/core/java/android/security/keymaster/KeymasterBlobArgument.java +++ b/core/java/android/security/keymaster/KeymasterBlobArgument.java @@ -16,14 +16,17 @@ package android.security.keymaster; +import android.annotation.UnsupportedAppUsage; import android.os.Parcel; /** * @hide */ class KeymasterBlobArgument extends KeymasterArgument { + @UnsupportedAppUsage public final byte[] blob; + @UnsupportedAppUsage public KeymasterBlobArgument(int tag, byte[] blob) { super(tag); switch (KeymasterDefs.getTagType(tag)) { @@ -36,6 +39,7 @@ class KeymasterBlobArgument extends KeymasterArgument { this.blob = blob; } + @UnsupportedAppUsage public KeymasterBlobArgument(int tag, Parcel in) { super(tag); blob = in.createByteArray(); diff --git a/core/java/android/security/keymaster/KeymasterBooleanArgument.java b/core/java/android/security/keymaster/KeymasterBooleanArgument.java index 67b3281a8a64025f98dbc13e416919d92f0fd66d..4286aa0d4ae3202161393e1a6d8cb97738eaabf3 100644 --- a/core/java/android/security/keymaster/KeymasterBooleanArgument.java +++ b/core/java/android/security/keymaster/KeymasterBooleanArgument.java @@ -16,6 +16,7 @@ package android.security.keymaster; +import android.annotation.UnsupportedAppUsage; import android.os.Parcel; /** @@ -36,6 +37,7 @@ class KeymasterBooleanArgument extends KeymasterArgument { } } + @UnsupportedAppUsage public KeymasterBooleanArgument(int tag, Parcel in) { super(tag); } diff --git a/core/java/android/security/keymaster/KeymasterDateArgument.java b/core/java/android/security/keymaster/KeymasterDateArgument.java index aa15e34e3e86c42ebe11b8f90d46b948eb9cafb7..3e04c1543117b8f0c2d9b8a57df47d5790038a27 100644 --- a/core/java/android/security/keymaster/KeymasterDateArgument.java +++ b/core/java/android/security/keymaster/KeymasterDateArgument.java @@ -16,6 +16,7 @@ package android.security.keymaster; +import android.annotation.UnsupportedAppUsage; import android.os.Parcel; import java.util.Date; @@ -36,6 +37,7 @@ class KeymasterDateArgument extends KeymasterArgument { this.date = date; } + @UnsupportedAppUsage public KeymasterDateArgument(int tag, Parcel in) { super(tag); date = new Date(in.readLong()); diff --git a/core/java/android/security/keymaster/KeymasterIntArgument.java b/core/java/android/security/keymaster/KeymasterIntArgument.java index 578d2498612d270114943733a967ec1fceb7070b..4aadce4583951cfe7a33117fedd7da33871b0cf7 100644 --- a/core/java/android/security/keymaster/KeymasterIntArgument.java +++ b/core/java/android/security/keymaster/KeymasterIntArgument.java @@ -16,14 +16,17 @@ package android.security.keymaster; +import android.annotation.UnsupportedAppUsage; import android.os.Parcel; /** * @hide */ class KeymasterIntArgument extends KeymasterArgument { + @UnsupportedAppUsage public final int value; + @UnsupportedAppUsage public KeymasterIntArgument(int tag, int value) { super(tag); switch (KeymasterDefs.getTagType(tag)) { @@ -38,6 +41,7 @@ class KeymasterIntArgument extends KeymasterArgument { this.value = value; } + @UnsupportedAppUsage public KeymasterIntArgument(int tag, Parcel in) { super(tag); value = in.readInt(); diff --git a/core/java/android/security/keymaster/KeymasterLongArgument.java b/core/java/android/security/keymaster/KeymasterLongArgument.java index d3d40ba0cb9d2157db5a01f4067eff40a7d9caea..bc2255e22a69a397384c19c3cbcd899f6fab81cb 100644 --- a/core/java/android/security/keymaster/KeymasterLongArgument.java +++ b/core/java/android/security/keymaster/KeymasterLongArgument.java @@ -16,14 +16,17 @@ package android.security.keymaster; +import android.annotation.UnsupportedAppUsage; import android.os.Parcel; /** * @hide */ class KeymasterLongArgument extends KeymasterArgument { + @UnsupportedAppUsage public final long value; + @UnsupportedAppUsage public KeymasterLongArgument(int tag, long value) { super(tag); switch (KeymasterDefs.getTagType(tag)) { @@ -36,6 +39,7 @@ class KeymasterLongArgument extends KeymasterArgument { this.value = value; } + @UnsupportedAppUsage public KeymasterLongArgument(int tag, Parcel in) { super(tag); value = in.readLong(); diff --git a/core/java/android/service/appprediction/AppPredictionService.java b/core/java/android/service/appprediction/AppPredictionService.java index ff13e0361ab896b91f3940af4579496d5110a72d..c1323bc8fd4c4ad79c5788e72875bcef79826e20 100644 --- a/core/java/android/service/appprediction/AppPredictionService.java +++ b/core/java/android/service/appprediction/AppPredictionService.java @@ -86,11 +86,12 @@ public abstract class AppPredictionService extends Service { } @Override - public void notifyLocationShown(AppPredictionSessionId sessionId, String launchLocation, - ParceledListSlice targetIds) { + public void notifyLaunchLocationShown(AppPredictionSessionId sessionId, + String launchLocation, ParceledListSlice targetIds) { mHandler.sendMessage( - obtainMessage(AppPredictionService::onLocationShown, AppPredictionService.this, - sessionId, launchLocation, targetIds.getList())); + obtainMessage(AppPredictionService::onLaunchLocationShown, + AppPredictionService.this, sessionId, launchLocation, + targetIds.getList())); } @Override @@ -158,7 +159,7 @@ public abstract class AppPredictionService extends Service { * Called by a client app to indication a particular location has been shown to the user. */ @MainThread - public abstract void onLocationShown(@NonNull AppPredictionSessionId sessionId, + public abstract void onLaunchLocationShown(@NonNull AppPredictionSessionId sessionId, @NonNull String launchLocation, @NonNull List targetIds); private void doCreatePredictionSession(@NonNull AppPredictionContext context, diff --git a/core/java/android/service/appprediction/IPredictionService.aidl b/core/java/android/service/appprediction/IPredictionService.aidl index 3a6d1666f4b95a14fe12a9d180d69b82125752b6..0f3df8561743dae5d31ead934d8b942d4b72e8cb 100644 --- a/core/java/android/service/appprediction/IPredictionService.aidl +++ b/core/java/android/service/appprediction/IPredictionService.aidl @@ -35,7 +35,7 @@ oneway interface IPredictionService { void notifyAppTargetEvent(in AppPredictionSessionId sessionId, in AppTargetEvent event); - void notifyLocationShown(in AppPredictionSessionId sessionId, in String launchLocation, + void notifyLaunchLocationShown(in AppPredictionSessionId sessionId, in String launchLocation, in ParceledListSlice targetIds); void sortAppTargets(in AppPredictionSessionId sessionId, in ParceledListSlice targets, diff --git a/core/java/android/service/attention/AttentionService.java b/core/java/android/service/attention/AttentionService.java index 32f4ea9a23ed2ef80c5243fdae48be1bdfd5c0e0..6172ce5015909fb944fae853fdd5856cd7dbebb0 100644 --- a/core/java/android/service/attention/AttentionService.java +++ b/core/java/android/service/attention/AttentionService.java @@ -21,11 +21,13 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.app.Service; +import android.attention.AttentionManagerInternal; import android.content.Intent; import android.os.IBinder; import android.os.RemoteException; import com.android.internal.util.Preconditions; +import com.android.server.LocalServices; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -38,7 +40,7 @@ import java.lang.annotation.RetentionPolicy; * The system's default AttentionService implementation is configured in * {@code config_AttentionComponent}. If this config has no value, a stub is returned. * - * See: {@link AttentionManagerService}. + * See: {@link com.android.server.attention.AttentionManagerService}. * *

  * {@literal
@@ -65,14 +67,20 @@ public abstract class AttentionService extends Service {
     /** Attention is present. */
     public static final int ATTENTION_SUCCESS_PRESENT = 1;
 
+    /** Unknown reasons for failing to determine the attention. */
+    public static final int ATTENTION_FAILURE_UNKNOWN = 2;
+
+    /** Request has been cancelled. */
+    public static final int ATTENTION_FAILURE_CANCELLED = 3;
+
     /** Preempted by other client. */
-    public static final int ATTENTION_FAILURE_PREEMPTED = 2;
+    public static final int ATTENTION_FAILURE_PREEMPTED = 4;
 
     /** Request timed out. */
-    public static final int ATTENTION_FAILURE_TIMED_OUT = 3;
+    public static final int ATTENTION_FAILURE_TIMED_OUT = 5;
 
-    /** Unknown reasons for failing to determine the attention. */
-    public static final int ATTENTION_FAILURE_UNKNOWN = 4;
+    /** Camera permission is not granted. */
+    public static final int ATTENTION_FAILURE_CAMERA_PERMISSION_ABSENT = 6;
 
     /**
      * Result codes for when attention check was successful.
@@ -90,8 +98,9 @@ public abstract class AttentionService extends Service {
      *
      * @hide
      */
-    @IntDef(prefix = {"ATTENTION_FAILURE_"}, value = {ATTENTION_FAILURE_PREEMPTED,
-            ATTENTION_FAILURE_TIMED_OUT, ATTENTION_FAILURE_UNKNOWN})
+    @IntDef(prefix = {"ATTENTION_FAILURE_"}, value = {ATTENTION_FAILURE_UNKNOWN,
+            ATTENTION_FAILURE_CANCELLED, ATTENTION_FAILURE_PREEMPTED, ATTENTION_FAILURE_TIMED_OUT,
+            ATTENTION_FAILURE_CAMERA_PERMISSION_ABSENT})
     @Retention(RetentionPolicy.SOURCE)
     public @interface AttentionFailureCodes {
     }
@@ -100,15 +109,16 @@ public abstract class AttentionService extends Service {
 
         /** {@inheritDoc} */
         @Override
-        public void checkAttention(int requestCode, IAttentionCallback callback) {
+        public void checkAttention(IAttentionCallback callback) {
             Preconditions.checkNotNull(callback);
-            AttentionService.this.onCheckAttention(requestCode, new AttentionCallback(callback));
+            AttentionService.this.onCheckAttention(new AttentionCallback(callback));
         }
 
         /** {@inheritDoc} */
         @Override
-        public void cancelAttentionCheck(int requestCode) {
-            AttentionService.this.onCancelAttentionCheck(requestCode);
+        public void cancelAttentionCheck(IAttentionCallback callback) {
+            Preconditions.checkNotNull(callback);
+            AttentionService.this.onCancelAttentionCheck(new AttentionCallback(callback));
         }
     };
 
@@ -122,38 +132,58 @@ public abstract class AttentionService extends Service {
     }
 
     /**
-     * Checks the user attention and calls into the provided callback.
+     * Disables the dependants.
      *
-     * @param requestCode an identifier that could be used to cancel the request
-     * @param callback    the callback to return the result to
+     * Example: called if the service does not have sufficient permissions to perform the task.
      */
-    public abstract void onCheckAttention(int requestCode, @NonNull AttentionCallback callback);
+    public final void disableSelf() {
+        AttentionManagerInternal attentionManager = LocalServices.getService(
+                AttentionManagerInternal.class);
+        if (attentionManager != null) {
+            attentionManager.disableSelf();
+        }
+    }
 
-    /** Cancels the attention check for a given request code. */
-    public abstract void onCancelAttentionCheck(int requestCode);
+    /**
+     * Checks the user attention and calls into the provided callback.
+     *
+     * @param callback the callback to return the result to
+     */
+    public abstract void onCheckAttention(@NonNull AttentionCallback callback);
 
+    /**
+     * Cancels pending work for a given callback.
+     *
+     * Implementation must call back with a failure code of {@link #ATTENTION_FAILURE_CANCELLED}.
+     */
+    public abstract void onCancelAttentionCheck(@NonNull AttentionCallback callback);
 
     /** Callbacks for AttentionService results. */
     public static final class AttentionCallback {
-        private final IAttentionCallback mCallback;
+        @NonNull private final IAttentionCallback mCallback;
 
-        private AttentionCallback(IAttentionCallback callback) {
+        private AttentionCallback(@NonNull IAttentionCallback callback) {
             mCallback = callback;
         }
 
-        /** Returns the result. */
-        public void onSuccess(int requestCode, @AttentionSuccessCodes int result, long timestamp) {
+        /**
+         * Signals a success and provides the result code.
+         *
+         * @param timestamp of when the attention signal was computed; system throttles the requests
+         *                  so this is useful to know how fresh the result is.
+         */
+        public void onSuccess(@AttentionSuccessCodes int result, long timestamp) {
             try {
-                mCallback.onSuccess(requestCode, result, timestamp);
+                mCallback.onSuccess(result, timestamp);
             } catch (RemoteException e) {
                 e.rethrowFromSystemServer();
             }
         }
 
-        /** Signals a failure. */
-        public void onFailure(int requestCode, @AttentionFailureCodes int error) {
+        /** Signals a failure and provides the error code. */
+        public void onFailure(@AttentionFailureCodes int error) {
             try {
-                mCallback.onFailure(requestCode, error);
+                mCallback.onFailure(error);
             } catch (RemoteException e) {
                 e.rethrowFromSystemServer();
             }
diff --git a/core/java/android/service/attention/IAttentionCallback.aidl b/core/java/android/service/attention/IAttentionCallback.aidl
index 0e8a1e75c14b43ea617e8fbe1f94de923d5e66ed..f65b9c095428c8bae579c5860279246b9c542f89 100644
--- a/core/java/android/service/attention/IAttentionCallback.aidl
+++ b/core/java/android/service/attention/IAttentionCallback.aidl
@@ -22,6 +22,6 @@ package android.service.attention;
  * @hide
  */
 oneway interface IAttentionCallback {
-    void onSuccess(int requestCode, int result, long timestamp);
-    void onFailure(int requestCode, int error);
+    void onSuccess(int result, long timestamp);
+    void onFailure(int error);
 }
diff --git a/core/java/android/service/attention/IAttentionService.aidl b/core/java/android/service/attention/IAttentionService.aidl
index c3b6f48a5b2e011b4ebf757b3bf9ad77a5b1efae..99e79973cfd2485b1ef151ec482986e630f1ed03 100644
--- a/core/java/android/service/attention/IAttentionService.aidl
+++ b/core/java/android/service/attention/IAttentionService.aidl
@@ -24,6 +24,6 @@ import android.service.attention.IAttentionCallback;
  * @hide
  */
 oneway interface IAttentionService {
-    void checkAttention(int requestCode, IAttentionCallback callback);
-    void cancelAttentionCheck(int requestCode);
+    void checkAttention(IAttentionCallback callback);
+    void cancelAttentionCheck(IAttentionCallback callback);
 }
\ No newline at end of file
diff --git a/core/java/android/service/contentcapture/ContentCaptureService.java b/core/java/android/service/contentcapture/ContentCaptureService.java
index df113979bacf4af23ac48a363a1c93a12833a980..fb07abaa34a13a6b5f7d3c17f70713843872cb8a 100644
--- a/core/java/android/service/contentcapture/ContentCaptureService.java
+++ b/core/java/android/service/contentcapture/ContentCaptureService.java
@@ -298,12 +298,12 @@ public abstract class ContentCaptureService extends Service {
     /**
      * Disables the Content Capture service for the given user.
      */
-    public final void disableContentCaptureServices() {
-        if (sDebug) Log.d(TAG, "disableContentCaptureServices()");
+    public final void disableSelf() {
+        if (sDebug) Log.d(TAG, "disableSelf()");
 
         final IContentCaptureServiceCallback callback = mCallback;
         if (callback == null) {
-            Log.w(TAG, "disableContentCaptureServices(): no server callback");
+            Log.w(TAG, "disableSelf(): no server callback");
             return;
         }
         try {
@@ -367,7 +367,6 @@ public abstract class ContentCaptureService extends Service {
             stateFlags = initialState;
         } else {
             stateFlags |= ContentCaptureSession.STATE_DISABLED;
-
         }
         setClientState(clientReceiver, stateFlags, mClientInterface.asBinder());
     }
diff --git a/core/java/android/service/contentcapture/ContentCaptureServiceInfo.java b/core/java/android/service/contentcapture/ContentCaptureServiceInfo.java
index 6ecd82f50fdbf2f924c91ae3e33a866f308bb7e9..fb6061916d99d1df4c2cdae42e9e09f83a305c34 100644
--- a/core/java/android/service/contentcapture/ContentCaptureServiceInfo.java
+++ b/core/java/android/service/contentcapture/ContentCaptureServiceInfo.java
@@ -139,6 +139,7 @@ public final class ContentCaptureServiceInfo {
         mSettingsActivity = settingsActivity;
     }
 
+    @NonNull
     public ServiceInfo getServiceInfo() {
         return mServiceInfo;
     }
diff --git a/core/java/android/service/dreams/IDreamManager.aidl b/core/java/android/service/dreams/IDreamManager.aidl
index b84e6c9bc9624a02850278bb48d7c99033524ab6..d3f2a70029f79440384863fe87a795be12902477 100644
--- a/core/java/android/service/dreams/IDreamManager.aidl
+++ b/core/java/android/service/dreams/IDreamManager.aidl
@@ -23,12 +23,16 @@ import android.os.IBinder;
 
 /** @hide */
 interface IDreamManager {
+    @UnsupportedAppUsage
     void dream();
+    @UnsupportedAppUsage
     void awaken();
+    @UnsupportedAppUsage
     void setDreamComponents(in ComponentName[] componentNames);
     ComponentName[] getDreamComponents();
     ComponentName getDefaultDreamComponent();
     void testDream(in ComponentName componentName);
+    @UnsupportedAppUsage
     boolean isDreaming();
     void finishSelf(in IBinder token, boolean immediate);
     void startDozing(in IBinder token, int screenState, int screenBrightness);
diff --git a/core/java/android/service/euicc/GetEuiccProfileInfoListResult.java b/core/java/android/service/euicc/GetEuiccProfileInfoListResult.java
index 7a9d8a05ab4715a566128c11f171a97b3f52d88b..9add38e40d9be0cc82eadd6c3fd70d6287bfa552 100644
--- a/core/java/android/service/euicc/GetEuiccProfileInfoListResult.java
+++ b/core/java/android/service/euicc/GetEuiccProfileInfoListResult.java
@@ -97,9 +97,10 @@ public final class GetEuiccProfileInfoListResult implements Parcelable {
         if (this.result == EuiccService.RESULT_OK) {
             this.mProfiles = profiles;
         } else {
-            if (profiles != null) {
+            // For error case, profiles is either null or 0 size.
+            if (profiles != null && profiles.length > 0) {
                 throw new IllegalArgumentException(
-                        "Error result with non-null profiles: " + result);
+                        "Error result with non-empty profiles: " + result);
             }
             this.mProfiles = null;
         }
diff --git a/core/java/android/service/notification/Adjustment.java b/core/java/android/service/notification/Adjustment.java
index 1cdb62fe89349565f5176ab929391872fba0efce..8ba9a8357c65085349fb2e6e4f7b77db073ec7f8 100644
--- a/core/java/android/service/notification/Adjustment.java
+++ b/core/java/android/service/notification/Adjustment.java
@@ -16,6 +16,7 @@
 package android.service.notification;
 
 import android.annotation.NonNull;
+import android.annotation.StringDef;
 import android.annotation.SystemApi;
 import android.app.Notification;
 import android.os.Bundle;
@@ -23,6 +24,9 @@ import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.UserHandle;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * Ranking updates from the Assistant.
  *
@@ -43,6 +47,14 @@ public final class Adjustment implements Parcelable {
     private final Bundle mSignals;
     private final int mUser;
 
+    /** @hide */
+    @StringDef (prefix = { "KEY_" }, value = {
+            KEY_CONTEXTUAL_ACTIONS, KEY_GROUP_KEY, KEY_IMPORTANCE, KEY_PEOPLE, KEY_SNOOZE_CRITERIA,
+            KEY_TEXT_REPLIES, KEY_USER_SENTIMENT
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Keys {}
+
     /**
      * Data type: ArrayList of {@code String}, where each is a representation of a
      * {@link android.provider.ContactsContract.Contacts#CONTENT_LOOKUP_URI}.
diff --git a/core/java/android/service/notification/NotificationAssistantService.java b/core/java/android/service/notification/NotificationAssistantService.java
index 780b576d71f39fac73fc9ea493e14b73d76b75fa..b81725d99d2bb1700dd76bf4eaa31a47a3a270fb 100644
--- a/core/java/android/service/notification/NotificationAssistantService.java
+++ b/core/java/android/service/notification/NotificationAssistantService.java
@@ -25,6 +25,7 @@ import android.annotation.SdkConstant;
 import android.annotation.SystemApi;
 import android.app.Notification;
 import android.app.NotificationChannel;
+import android.app.NotificationManager;
 import android.app.admin.DevicePolicyManager;
 import android.content.ComponentName;
 import android.content.Context;
@@ -141,7 +142,6 @@ public abstract class NotificationAssistantService extends NotificationListenerS
         return onNotificationEnqueued(sbn);
     }
 
-
     /**
      * Implement this method to learn when notifications are removed, how they were interacted with
      * before removal, and why they were removed.
@@ -215,6 +215,15 @@ public abstract class NotificationAssistantService extends NotificationListenerS
             @Source int source) {
     }
 
+    /**
+     * Implement this to know when a user has changed which features of
+     * their notifications the assistant can modify.
+     * 

Query {@link NotificationManager#getAllowedAssistantCapabilities()} to see what + * {@link Adjustment adjustments} you are currently allowed to make.

+ */ + public void onCapabilitiesChanged() { + } + /** * Updates a notification. N.B. this won’t cause * an existing notification to alert, but might allow a future update to @@ -225,7 +234,7 @@ public abstract class NotificationAssistantService extends NotificationListenerS public final void adjustNotification(@NonNull Adjustment adjustment) { if (!isBound()) return; try { - getNotificationInterface().applyAdjustmentFromAssistant(mWrapper, adjustment); + getNotificationInterface().applyEnqueuedAdjustmentFromAssistant(mWrapper, adjustment); } catch (android.os.RemoteException ex) { Log.v(TAG, "Unable to contact notification manager", ex); throw ex.rethrowFromSystemServer(); diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java index 23607ebe78fe0cbd0853e3165195fba344b6c996..333868a2f08accbc20b5677d6efbd73fa3f7fea5 100644 --- a/core/java/android/service/notification/NotificationListenerService.java +++ b/core/java/android/service/notification/NotificationListenerService.java @@ -476,7 +476,7 @@ public abstract class NotificationListenerService extends Service { * @param hideSilentStatusIcons whether or not status bar icons should be hidden for silent * notifications */ - public void onStatusBarIconsBehaviorChanged(boolean hideSilentStatusIcons) { + public void onSilentStatusBarIconsVisibilityChanged(boolean hideSilentStatusIcons) { // optional } @@ -2255,7 +2255,7 @@ public abstract class NotificationListenerService extends Service { } break; case MSG_ON_STATUS_BAR_ICON_BEHAVIOR_CHANGED: { - onStatusBarIconsBehaviorChanged((Boolean) msg.obj); + onSilentStatusBarIconsVisibilityChanged((Boolean) msg.obj); } break; } } diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java index c042a8c8ae1c54a8282e4bc0569a644eae3f5bf1..e1762dffeef59449d9d2d268775ffe8fca2263c7 100644 --- a/core/java/android/service/wallpaper/WallpaperService.java +++ b/core/java/android/service/wallpaper/WallpaperService.java @@ -320,7 +320,7 @@ public abstract class WallpaperService extends Service { public void resized(Rect frame, Rect overscanInsets, Rect contentInsets, Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw, MergedConfiguration mergedConfiguration, Rect backDropRect, boolean forceLayout, - boolean alwaysConsumeNavBar, int displayId, + boolean alwaysConsumeSystemBars, int displayId, DisplayCutout.ParcelableWrapper displayCutout) { Message msg = mCaller.obtainMessageIO(MSG_WINDOW_RESIZED, reportDraw ? 1 : 0, outsets); diff --git a/core/java/android/service/watchdog/ExplicitHealthCheckService.java b/core/java/android/service/watchdog/ExplicitHealthCheckService.java new file mode 100644 index 0000000000000000000000000000000000000000..015fba19d785162b48ea24feb2d18a71bba3c348 --- /dev/null +++ b/core/java/android/service/watchdog/ExplicitHealthCheckService.java @@ -0,0 +1,208 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.service.watchdog; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.SdkConstant; +import android.annotation.SystemApi; +import android.app.Service; +import android.content.Intent; +import android.os.Bundle; +import android.os.Handler; +import android.os.IBinder; +import android.os.Looper; +import android.os.RemoteCallback; +import android.os.RemoteException; +import android.util.Log; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * A service to provide packages supporting explicit health checks and route checks to these + * packages on behalf of the package watchdog. + * + *

To extend this class, you must declare the service in your manifest file with the + * {@link android.Manifest.permission#BIND_EXPLICIT_HEALTH_CHECK_SERVICE} permission, + * and include an intent filter with the {@link #SERVICE_INTERFACE} action. In adddition, + * your implementation must live in {@link PackageManger#SYSTEM_SHARED_LIBRARY_SERVICES}. + * For example:

+ *
+ *     <service android:name=".FooExplicitHealthCheckService"
+ *             android:exported="true"
+ *             android:priority="100"
+ *             android:permission="android.permission.BIND_EXPLICIT_HEALTH_CHECK_SERVICE">
+ *         <intent-filter>
+ *             <action android:name="android.service.watchdog.ExplicitHealthCheckService" />
+ *         </intent-filter>
+ *     </service>
+ * 
+ * @hide + */ +@SystemApi +public abstract class ExplicitHealthCheckService extends Service { + + private static final String TAG = "ExplicitHealthCheckService"; + + /** + * {@link Bundle} key for a {@link List} of {@link String} value. + * + * {@hide} + */ + public static final String EXTRA_SUPPORTED_PACKAGES = + "android.service.watchdog.extra.supported_packages"; + + /** + * {@link Bundle} key for a {@link List} of {@link String} value. + * + * {@hide} + */ + public static final String EXTRA_REQUESTED_PACKAGES = + "android.service.watchdog.extra.requested_packages"; + + /** + * {@link Bundle} key for a {@link String} value. + * + * {@hide} + */ + public static final String EXTRA_HEALTH_CHECK_PASSED_PACKAGE = + "android.service.watchdog.extra.health_check_passed_package"; + + /** + * The Intent action that a service must respond to. Add it to the intent filter of the service + * in its manifest. + */ + @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION) + public static final String SERVICE_INTERFACE = + "android.service.watchdog.ExplicitHealthCheckService"; + + /** + * The permission that a service must require to ensure that only Android system can bind to it. + * If this permission is not enforced in the AndroidManifest of the service, the system will + * skip that service. + */ + public static final String BIND_PERMISSION = + "android.permission.BIND_EXPLICIT_HEALTH_CHECK_SERVICE"; + + private final ExplicitHealthCheckServiceWrapper mWrapper = + new ExplicitHealthCheckServiceWrapper(); + + /** + * Called when the system requests an explicit health check for {@code packageName}. + * + *

When {@code packageName} passes the check, implementors should call + * {@link #notifyHealthCheckPassed} to inform the system. + * + *

It could take many hours before a {@code packageName} passes a check and implementors + * should never drop requests unless {@link onCancel} is called or the service dies. + * + *

Requests should not be queued and additional calls while expecting a result for + * {@code packageName} should have no effect. + */ + public abstract void onRequestHealthCheck(@NonNull String packageName); + + /** + * Called when the system cancels the explicit health check request for {@code packageName}. + * Should do nothing if there are is no active request for {@code packageName}. + */ + public abstract void onCancelHealthCheck(@NonNull String packageName); + + /** + * Called when the system requests for all the packages supporting explicit health checks. The + * system may request an explicit health check for any of these packages with + * {@link #onRequestHealthCheck}. + * + * @return all packages supporting explicit health checks + */ + @NonNull public abstract List onGetSupportedPackages(); + + /** + * Called when the system requests for all the packages that it has currently requested + * an explicit health check for. + * + * @return all packages expecting an explicit health check result + */ + @NonNull public abstract List onGetRequestedPackages(); + + private final Handler mHandler = new Handler(Looper.getMainLooper(), null, true); + @Nullable private RemoteCallback mCallback; + + @Override + @NonNull + public final IBinder onBind(@NonNull Intent intent) { + return mWrapper; + } + + /** + * Implementors should call this to notify the system when explicit health check passes + * for {@code packageName}; + */ + public final void notifyHealthCheckPassed(@NonNull String packageName) { + mHandler.post(() -> { + if (mCallback != null) { + Objects.requireNonNull(packageName, + "Package passing explicit health check must be non-null"); + Bundle bundle = new Bundle(); + bundle.putString(EXTRA_HEALTH_CHECK_PASSED_PACKAGE, packageName); + mCallback.sendResult(bundle); + } else { + Log.wtf(TAG, "System missed explicit health check result for " + packageName); + } + }); + } + + private class ExplicitHealthCheckServiceWrapper extends IExplicitHealthCheckService.Stub { + @Override + public void setCallback(RemoteCallback callback) throws RemoteException { + mHandler.post(() -> { + mCallback = callback; + }); + } + + @Override + public void request(String packageName) throws RemoteException { + mHandler.post(() -> ExplicitHealthCheckService.this.onRequestHealthCheck(packageName)); + } + + @Override + public void cancel(String packageName) throws RemoteException { + mHandler.post(() -> ExplicitHealthCheckService.this.onCancelHealthCheck(packageName)); + } + + @Override + public void getSupportedPackages(RemoteCallback callback) throws RemoteException { + mHandler.post(() -> sendPackages(callback, EXTRA_SUPPORTED_PACKAGES, + ExplicitHealthCheckService.this.onGetSupportedPackages())); + } + + @Override + public void getRequestedPackages(RemoteCallback callback) throws RemoteException { + mHandler.post(() -> sendPackages(callback, EXTRA_REQUESTED_PACKAGES, + ExplicitHealthCheckService.this.onGetRequestedPackages())); + } + + private void sendPackages(RemoteCallback callback, String key, List packages) { + Objects.requireNonNull(packages, + "Supported and requested package list must be non-null"); + Bundle bundle = new Bundle(); + bundle.putStringArrayList(key, new ArrayList<>(packages)); + callback.sendResult(bundle); + } + } +} diff --git a/core/java/android/service/watchdog/IExplicitHealthCheckService.aidl b/core/java/android/service/watchdog/IExplicitHealthCheckService.aidl new file mode 100644 index 0000000000000000000000000000000000000000..78c0328d36f03ea05c3e805d1d0e5883410e8fef --- /dev/null +++ b/core/java/android/service/watchdog/IExplicitHealthCheckService.aidl @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.service.watchdog; + +import android.os.RemoteCallback; + +/** + * @hide + */ +oneway interface IExplicitHealthCheckService +{ + void setCallback(in @nullable RemoteCallback callback); + void request(String packageName); + void cancel(String packageName); + void getSupportedPackages(in RemoteCallback callback); + void getRequestedPackages(in RemoteCallback callback); +} diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java index c1504ae2a2690b39f79689f40cd82b8b43b9b2b4..da6ef4cb591edc09c903a4e854d3c65d437a8867 100644 --- a/core/java/android/util/FeatureFlagUtils.java +++ b/core/java/android/util/FeatureFlagUtils.java @@ -51,15 +51,15 @@ public class FeatureFlagUtils { DEFAULT_FLAGS.put("settings_network_and_internet_v2", "true"); DEFAULT_FLAGS.put("settings_slice_injection", "true"); DEFAULT_FLAGS.put("settings_systemui_theme", "true"); - DEFAULT_FLAGS.put("settings_mainline_module", "false"); - DEFAULT_FLAGS.put("settings_dynamic_android", "false"); + DEFAULT_FLAGS.put("settings_mainline_module", "true"); + DEFAULT_FLAGS.put("settings_dynamic_system", "false"); DEFAULT_FLAGS.put(SEAMLESS_TRANSFER, "false"); DEFAULT_FLAGS.put(HEARING_AID_SETTINGS, "false"); DEFAULT_FLAGS.put(SAFETY_HUB, "false"); DEFAULT_FLAGS.put(SCREENRECORD_LONG_PRESS, "false"); DEFAULT_FLAGS.put(GLOBAL_ACTIONS_GRID_ENABLED, "true"); DEFAULT_FLAGS.put(GLOBAL_ACTIONS_PANEL_ENABLED, "true"); - DEFAULT_FLAGS.put("settings_wifi_details_saved_screen", "false"); + DEFAULT_FLAGS.put("settings_wifi_details_saved_screen", "true"); DEFAULT_FLAGS.put("settings_wifi_details_datausage_header", "false"); } diff --git a/core/java/android/util/StatsLog.java b/core/java/android/util/StatsLog.java index bf46e95c7b091a31c7845a5c72122b714a09774f..30d3d7d069b5d88c3c40f9ffa145f8f93bdc7de7 100644 --- a/core/java/android/util/StatsLog.java +++ b/core/java/android/util/StatsLog.java @@ -22,6 +22,7 @@ import static android.Manifest.permission.PACKAGE_USAGE_STATS; import android.Manifest; import android.annotation.NonNull; import android.annotation.RequiresPermission; +import android.annotation.SystemApi; import android.app.IActivityManager; import android.content.Context; import android.os.IStatsManager; @@ -199,6 +200,16 @@ public final class StatsLog extends StatsLogInternal { } } + /** + * Write an event to stats log using the raw format. + * + * @param buffer The encoded buffer of data to write.. + * @param size The number of bytes from the buffer to write. + * @hide + */ + @SystemApi + public static native void writeRaw(@NonNull byte[] buffer, int size); + private static void enforceDumpCallingPermission(Context context) { context.enforceCallingPermission(android.Manifest.permission.DUMP, "Need DUMP permission."); } diff --git a/core/java/android/util/XmlPullAttributes.java b/core/java/android/util/XmlPullAttributes.java index cb35eb5c12a334a934e5cdeff0d2bfd758fec740..32fe16fcb2b19658cd182367fa8db964d3c852ec 100644 --- a/core/java/android/util/XmlPullAttributes.java +++ b/core/java/android/util/XmlPullAttributes.java @@ -18,6 +18,7 @@ package android.util; import org.xmlpull.v1.XmlPullParser; +import android.annotation.UnsupportedAppUsage; import android.util.AttributeSet; import com.android.internal.util.XmlUtils; @@ -26,6 +27,7 @@ import com.android.internal.util.XmlUtils; * Provides an implementation of AttributeSet on top of an XmlPullParser. */ class XmlPullAttributes implements AttributeSet { + @UnsupportedAppUsage public XmlPullAttributes(XmlPullParser parser) { mParser = parser; } @@ -147,5 +149,6 @@ class XmlPullAttributes implements AttributeSet { return getAttributeResourceValue(null, "style", 0); } + @UnsupportedAppUsage /*package*/ XmlPullParser mParser; } diff --git a/core/java/android/view/AccessibilityInteractionController.java b/core/java/android/view/AccessibilityInteractionController.java index f37c9162d98a4dc93ceeaa58db20f1b0757ededa..0051d01eec130bf14c6f249b56e580f87899d3c4 100644 --- a/core/java/android/view/AccessibilityInteractionController.java +++ b/core/java/android/view/AccessibilityInteractionController.java @@ -16,6 +16,7 @@ package android.view; +import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; import static android.view.accessibility.AccessibilityNodeInfo.ACTION_ARGUMENT_ACCESSIBLE_CLICKABLE_SPAN; import static android.view.accessibility.AccessibilityNodeInfo.EXTRA_DATA_REQUESTED_KEY; import static android.view.accessibility.AccessibilityNodeInfo.EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY; @@ -797,11 +798,19 @@ public final class AccessibilityInteractionController { } Rect boundsInScreen = mTempRect; info.getBoundsInScreen(boundsInScreen); - if (interactiveRegion.quickReject(boundsInScreen)) { + if (interactiveRegion.quickReject(boundsInScreen) && !shouldBypassAdjustIsVisible()) { info.setVisibleToUser(false); } } + private boolean shouldBypassAdjustIsVisible() { + final int windowType = mViewRootImpl.mOrigWindowType; + if (windowType == TYPE_INPUT_METHOD) { + return true; + } + return false; + } + private void applyAppScaleAndMagnificationSpecIfNeeded(AccessibilityNodeInfo info, MagnificationSpec spec) { if (info == null) { diff --git a/core/java/android/view/GestureDetector.java b/core/java/android/view/GestureDetector.java index c1d122a1f9b16960d524701c033d1593cac6505b..c794a69d36808ff22868629b83706e0c4b89ffac 100644 --- a/core/java/android/view/GestureDetector.java +++ b/core/java/android/view/GestureDetector.java @@ -16,20 +16,11 @@ package android.view; -import static android.util.StatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__DEEP_PRESS; -import static android.util.StatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__DOUBLE_TAP; -import static android.util.StatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__LONG_PRESS; -import static android.util.StatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__SCROLL; -import static android.util.StatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__SINGLE_TAP; -import static android.util.StatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__UNKNOWN_CLASSIFICATION; - import android.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.Build; import android.os.Handler; import android.os.Message; -import android.os.SystemClock; -import android.util.StatsLog; /** * Detects various gestures and events using the supplied {@link MotionEvent}s. @@ -260,12 +251,8 @@ public class GestureDetector { private boolean mAlwaysInTapRegion; private boolean mAlwaysInBiggerTapRegion; private boolean mIgnoreNextUpEvent; - // Whether a classification has been recorded by statsd for the current event stream. Reset on - // ACTION_DOWN. - private boolean mHasRecordedClassification; private MotionEvent mCurrentDownEvent; - private MotionEvent mCurrentMotionEvent; private MotionEvent mPreviousUpEvent; /** @@ -310,7 +297,6 @@ public class GestureDetector { break; case LONG_PRESS: - recordGestureClassification(msg.arg1); dispatchLongPress(); break; @@ -318,8 +304,6 @@ public class GestureDetector { // If the user's finger is still down, do not count it as a tap if (mDoubleTapListener != null) { if (!mStillDown) { - recordGestureClassification( - TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__SINGLE_TAP); mDoubleTapListener.onSingleTapConfirmed(mCurrentDownEvent); } else { mDeferConfirmSingleTap = true; @@ -517,11 +501,6 @@ public class GestureDetector { final int action = ev.getAction(); - if (mCurrentMotionEvent != null) { - mCurrentMotionEvent.recycle(); - } - mCurrentMotionEvent = MotionEvent.obtain(ev); - if (mVelocityTracker == null) { mVelocityTracker = VelocityTracker.obtain(); } @@ -590,8 +569,6 @@ public class GestureDetector { && isConsideredDoubleTap(mCurrentDownEvent, mPreviousUpEvent, ev)) { // This is a second tap mIsDoubleTapping = true; - recordGestureClassification( - TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__DOUBLE_TAP); // Give a callback with the first tap of the double-tap handled |= mDoubleTapListener.onDoubleTap(mCurrentDownEvent); // Give a callback with down event of the double-tap @@ -613,17 +590,11 @@ public class GestureDetector { mStillDown = true; mInLongPress = false; mDeferConfirmSingleTap = false; - mHasRecordedClassification = false; if (mIsLongpressEnabled) { mHandler.removeMessages(LONG_PRESS); - mHandler.sendMessageAtTime( - mHandler.obtainMessage( - LONG_PRESS, - TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__LONG_PRESS, - 0 /* arg2 */), - mCurrentDownEvent.getDownTime() - + ViewConfiguration.getLongPressTimeout()); + mHandler.sendEmptyMessageAtTime(LONG_PRESS, mCurrentDownEvent.getDownTime() + + ViewConfiguration.getLongPressTimeout()); } mHandler.sendEmptyMessageAtTime(SHOW_PRESS, mCurrentDownEvent.getDownTime() + TAP_TIMEOUT); @@ -642,8 +613,6 @@ public class GestureDetector { final float scrollY = mLastFocusY - focusY; if (mIsDoubleTapping) { // Give the move events of the double-tap - recordGestureClassification( - TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__DOUBLE_TAP); handled |= mDoubleTapListener.onDoubleTapEvent(ev); } else if (mAlwaysInTapRegion) { final int deltaX = (int) (focusX - mDownFocusX); @@ -666,12 +635,8 @@ public class GestureDetector { // reschedule long press with a modified timeout. mHandler.removeMessages(LONG_PRESS); final long longPressTimeout = ViewConfiguration.getLongPressTimeout(); - mHandler.sendMessageAtTime( - mHandler.obtainMessage( - LONG_PRESS, - TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__LONG_PRESS, - 0 /* arg2 */), - ev.getDownTime() + (long) (longPressTimeout * multiplier)); + mHandler.sendEmptyMessageAtTime(LONG_PRESS, ev.getDownTime() + + (long) (longPressTimeout * multiplier)); } // Inhibit default scroll. If a gesture is ambiguous, we prevent scroll // until the gesture is resolved. @@ -681,8 +646,6 @@ public class GestureDetector { } if (distance > slopSquare) { - recordGestureClassification( - TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__SCROLL); handled = mListener.onScroll(mCurrentDownEvent, ev, scrollX, scrollY); mLastFocusX = focusX; mLastFocusY = focusY; @@ -696,7 +659,6 @@ public class GestureDetector { mAlwaysInBiggerTapRegion = false; } } else if ((Math.abs(scrollX) >= 1) || (Math.abs(scrollY) >= 1)) { - recordGestureClassification(TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__SCROLL); handled = mListener.onScroll(mCurrentDownEvent, ev, scrollX, scrollY); mLastFocusX = focusX; mLastFocusY = focusY; @@ -705,11 +667,7 @@ public class GestureDetector { motionClassification == MotionEvent.CLASSIFICATION_DEEP_PRESS; if (deepPress && hasPendingLongPress) { mHandler.removeMessages(LONG_PRESS); - mHandler.sendMessage( - mHandler.obtainMessage( - LONG_PRESS, - TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__DEEP_PRESS, - 0 /* arg2 */)); + mHandler.sendEmptyMessage(LONG_PRESS); } break; @@ -718,15 +676,11 @@ public class GestureDetector { MotionEvent currentUpEvent = MotionEvent.obtain(ev); if (mIsDoubleTapping) { // Finally, give the up event of the double-tap - recordGestureClassification( - TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__DOUBLE_TAP); handled |= mDoubleTapListener.onDoubleTapEvent(ev); } else if (mInLongPress) { mHandler.removeMessages(TAP); mInLongPress = false; } else if (mAlwaysInTapRegion && !mIgnoreNextUpEvent) { - recordGestureClassification( - TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__SINGLE_TAP); handled = mListener.onSingleTapUp(ev); if (mDeferConfirmSingleTap && mDoubleTapListener != null) { mDoubleTapListener.onSingleTapConfirmed(ev); @@ -867,21 +821,4 @@ public class GestureDetector { mInLongPress = true; mListener.onLongPress(mCurrentDownEvent); } - - private void recordGestureClassification(int classification) { - if (mHasRecordedClassification - || classification - == TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__UNKNOWN_CLASSIFICATION) { - // Only record the first classification for an event stream. - return; - } - StatsLog.write( - StatsLog.TOUCH_GESTURE_CLASSIFIED, - getClass().getName(), - classification, - (int) (SystemClock.uptimeMillis() - mCurrentMotionEvent.getDownTime()), - (float) Math.hypot(mCurrentMotionEvent.getRawX() - mCurrentDownEvent.getRawX(), - mCurrentMotionEvent.getRawY() - mCurrentDownEvent.getRawY())); - mHasRecordedClassification = true; - } } diff --git a/core/java/android/view/IRecentsAnimationController.aidl b/core/java/android/view/IRecentsAnimationController.aidl index b1f934a44cdb32754cf8a865b2e72ba9392e560c..597b34bf8554951cf17402c0d543cde3bd4d2c8c 100644 --- a/core/java/android/view/IRecentsAnimationController.aidl +++ b/core/java/android/view/IRecentsAnimationController.aidl @@ -73,4 +73,33 @@ interface IRecentsAnimationController { * Hides the current input method if one is showing. */ void hideCurrentInputMethod(); + + /** + * Set a state for controller whether would like to cancel recents animations with deferred + * task screenshot presentation. + * + * When we cancel the recents animation due to a stack order change, we can't just cancel it + * immediately as it would lead to a flicker in Launcher if we just remove the task from the + * leash. Instead we screenshot the previous task and replace the child of the leash with the + * screenshot, so that Launcher can still control the leash lifecycle & make the next app + * transition animate smoothly without flickering. + * + * @param screenshot When set {@code true}, means recents animation will be canceled when the + * next app launch. System will take previous task's screenshot when the next + * app transition starting, and skip previous task's animation. + * Set {@code false} means will not take screenshot & skip animation + * for previous task. + * + * @see #cleanupScreenshot() + * @see IRecentsAnimationRunner#onCancelled + */ + void setCancelWithDeferredScreenshot(boolean screenshot); + + /** + * Clean up the screenshot of previous task which was created during recents animation that + * was cancelled by a stack order change. + * + * @see {@link IRecentsAnimationRunner#onAnimationCanceled} + */ + void cleanupScreenshot(); } diff --git a/core/java/android/view/IRecentsAnimationRunner.aidl b/core/java/android/view/IRecentsAnimationRunner.aidl index 6e382f416b62f5ed147988cb00a59fe059d01761..9c652a8d990ba62362c13aefae635012e02a3368 100644 --- a/core/java/android/view/IRecentsAnimationRunner.aidl +++ b/core/java/android/view/IRecentsAnimationRunner.aidl @@ -32,9 +32,17 @@ oneway interface IRecentsAnimationRunner { * Called when the system needs to cancel the current animation. This can be due to the * wallpaper not drawing in time, or the handler not finishing the animation within a predefined * amount of time. + * + * @param deferredWithScreenshot If set to {@code true}, the contents of the task will be + * replaced with a screenshot, such that the runner's leash is + * still active. As soon as the runner doesn't need the leash + * anymore, it can call + * {@link IRecentsAnimationController#cleanupScreenshot). + * + * @see {@link RecentsAnimationController#cleanupScreenshot} */ @UnsupportedAppUsage - void onAnimationCanceled() = 1; + void onAnimationCanceled(boolean deferredWithScreenshot) = 1; /** * Called when the system is ready for the handler to start animating all the visible tasks. diff --git a/core/java/android/view/IWindow.aidl b/core/java/android/view/IWindow.aidl index c06a1fe0a257de9c978312636c549c0cbe705ef8..699e795be9803b5e0b7e639c46853d05b2e25e51 100644 --- a/core/java/android/view/IWindow.aidl +++ b/core/java/android/view/IWindow.aidl @@ -53,7 +53,7 @@ oneway interface IWindow { void resized(in Rect frame, in Rect overscanInsets, in Rect contentInsets, in Rect visibleInsets, in Rect stableInsets, in Rect outsets, boolean reportDraw, in MergedConfiguration newMergedConfiguration, in Rect backDropFrame, - boolean forceLayout, boolean alwaysConsumeNavBar, int displayId, + boolean forceLayout, boolean alwaysConsumeSystemBars, int displayId, in DisplayCutout.ParcelableWrapper displayCutout); /** diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl index b91b93f7e09c58f3f40e73d2ac1b165f815f4e0e..6c37319c63033247b70ebdde620b4d57af4d854e 100644 --- a/core/java/android/view/IWindowManager.aidl +++ b/core/java/android/view/IWindowManager.aidl @@ -303,6 +303,16 @@ interface IWindowManager */ oneway void statusBarVisibilityChanged(int displayId, int visibility); + /** + * When set to {@code true} the system bars will always be shown. This is true even if an app + * requests to be fullscreen by setting the system ui visibility flags. The + * functionality was added for the automotive case as a way to guarantee required content stays + * on screen at all times. + * + * @hide + */ + oneway void setForceShowSystemBars(boolean show); + /** * Called by System UI to notify of changes to the visibility of Recents. */ diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java index 08f2e8d873523982f6285cca08c96a8e1cff78c4..bf16e3dedd499827aa9cf09be59af70cc0e938ee 100644 --- a/core/java/android/view/InsetsController.java +++ b/core/java/android/view/InsetsController.java @@ -134,7 +134,7 @@ public class InsetsController implements WindowInsetsController { } WindowInsets insets = state.calculateInsets(mFrame, mLastInsets.isRound(), - mLastInsets.shouldAlwaysConsumeNavBar(), mLastInsets.getDisplayCutout(), + mLastInsets.shouldAlwaysConsumeSystemBars(), mLastInsets.getDisplayCutout(), mLastLegacyContentInsets, mLastLegacyStableInsets, mLastLegacySoftInputMode, null /* typeSideMap */); mViewRoot.mView.dispatchWindowInsetsAnimationProgress(insets); @@ -177,12 +177,12 @@ public class InsetsController implements WindowInsetsController { */ @VisibleForTesting public WindowInsets calculateInsets(boolean isScreenRound, - boolean alwaysConsumeNavBar, DisplayCutout cutout, Rect legacyContentInsets, + boolean alwaysConsumeSystemBars, DisplayCutout cutout, Rect legacyContentInsets, Rect legacyStableInsets, int legacySoftInputMode) { mLastLegacyContentInsets.set(legacyContentInsets); mLastLegacyStableInsets.set(legacyStableInsets); mLastLegacySoftInputMode = legacySoftInputMode; - mLastInsets = mState.calculateInsets(mFrame, isScreenRound, alwaysConsumeNavBar, cutout, + mLastInsets = mState.calculateInsets(mFrame, isScreenRound, alwaysConsumeSystemBars, cutout, legacyContentInsets, legacyStableInsets, legacySoftInputMode, null /* typeSideMap */); return mLastInsets; diff --git a/core/java/android/view/InsetsState.java b/core/java/android/view/InsetsState.java index 6129b38104af14dd6d7afa7d5e5ed5b0a92f6559..13b0cc038fcea313132b7fb39514fa5101842fcd 100644 --- a/core/java/android/view/InsetsState.java +++ b/core/java/android/view/InsetsState.java @@ -17,9 +17,6 @@ package android.view; import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL; -import static android.view.ViewRootImpl.NEW_INSETS_MODE_IME; -import static android.view.ViewRootImpl.NEW_INSETS_MODE_NONE; -import static android.view.WindowInsets.Type.IME; import static android.view.WindowInsets.Type.SIZE; import static android.view.WindowInsets.Type.indexOf; @@ -31,7 +28,6 @@ import android.os.Parcel; import android.os.Parcelable; import android.util.ArrayMap; import android.util.ArraySet; -import android.util.SparseArray; import android.util.SparseIntArray; import android.view.WindowInsets.Type; import android.view.WindowInsets.Type.InsetType; @@ -40,7 +36,6 @@ import android.view.WindowManager.LayoutParams; import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -import java.util.ArrayList; import java.util.Objects; /** @@ -130,7 +125,7 @@ public class InsetsState implements Parcelable { * @return The calculated insets. */ public WindowInsets calculateInsets(Rect frame, boolean isScreenRound, - boolean alwaysConsumeNavBar, DisplayCutout cutout, + boolean alwaysConsumeSystemBars, DisplayCutout cutout, @Nullable Rect legacyContentInsets, @Nullable Rect legacyStableInsets, int legacySoftInputMode, @Nullable @InsetSide SparseIntArray typeSideMap) { Insets[] typeInsetsMap = new Insets[Type.SIZE]; @@ -180,7 +175,7 @@ public class InsetsState implements Parcelable { } } return new WindowInsets(typeInsetsMap, typeMaxInsetsMap, typeVisibilityMap, isScreenRound, - alwaysConsumeNavBar, cutout); + alwaysConsumeSystemBars, cutout); } private void processSource(InsetsSource source, Rect relativeFrame, boolean ignoreVisibility, diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index cd075bf65e4aeb3044b5f99f2e34dc365b0218ae..0043d32587725aa07f7b9f2e2d7428b2c65a3c9c 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -88,10 +88,10 @@ public final class SurfaceControl implements Parcelable { private static native void nativeDestroy(long nativeObject); private static native void nativeDisconnect(long nativeObject); - private static native GraphicBuffer nativeScreenshot(IBinder displayToken, + private static native ScreenshotGraphicBuffer nativeScreenshot(IBinder displayToken, Rect sourceCrop, int width, int height, boolean useIdentityTransform, int rotation, boolean captureSecureLayers); - private static native GraphicBuffer nativeCaptureLayers(IBinder layerHandleToken, + private static native ScreenshotGraphicBuffer nativeCaptureLayers(IBinder layerHandleToken, Rect sourceCrop, float frameScale); private static native long nativeCreateTransaction(); @@ -430,8 +430,53 @@ public final class SurfaceControl implements Parcelable { */ public static final int METADATA_TASK_ID = 3; + /** + * A wrapper around GraphicBuffer that contains extra information about how to + * interpret the screenshot GraphicBuffer. + * @hide + */ + public static class ScreenshotGraphicBuffer { + private final GraphicBuffer mGraphicBuffer; + private final ColorSpace mColorSpace; + + public ScreenshotGraphicBuffer(GraphicBuffer graphicBuffer, ColorSpace colorSpace) { + mGraphicBuffer = graphicBuffer; + mColorSpace = colorSpace; + } + + /** + * Create ScreenshotGraphicBuffer from existing native GraphicBuffer object. + * @param width The width in pixels of the buffer + * @param height The height in pixels of the buffer + * @param format The format of each pixel as specified in {@link PixelFormat} + * @param usage Hint indicating how the buffer will be used + * @param unwrappedNativeObject The native object of GraphicBuffer + * @param namedColorSpace Integer value of a named color space {@link ColorSpace.Named} + */ + private static ScreenshotGraphicBuffer createFromNative(int width, int height, int format, + int usage, long unwrappedNativeObject, int namedColorSpace) { + GraphicBuffer graphicBuffer = GraphicBuffer.createFromExisting(width, height, format, + usage, unwrappedNativeObject); + ColorSpace colorSpace = ColorSpace.get(ColorSpace.Named.values()[namedColorSpace]); + return new ScreenshotGraphicBuffer(graphicBuffer, colorSpace); + } + + public ColorSpace getColorSpace() { + return mColorSpace; + } + + public GraphicBuffer getGraphicBuffer() { + return mGraphicBuffer; + } + } + /** * Builder class for {@link SurfaceControl} objects. + * + * By default the surface will be hidden, and have "unset" bounds, meaning it can + * be as large as the bounds of its parent if a buffer or child so requires. + * + * It is necessary to set at least a name via {@link Builder#setName} */ public static class Builder { private SurfaceSession mSession; @@ -466,11 +511,11 @@ public final class SurfaceControl implements Parcelable { @NonNull public SurfaceControl build() { if (mWidth < 0 || mHeight < 0) { - throw new IllegalArgumentException( + throw new IllegalStateException( "width and height must be positive or unset"); } if ((mWidth > 0 || mHeight > 0) && (isColorLayerSet() || isContainerLayerSet())) { - throw new IllegalArgumentException( + throw new IllegalStateException( "Only buffer layers can set a valid buffer size."); } return new SurfaceControl( @@ -860,7 +905,9 @@ public final class SurfaceControl implements Parcelable { * Release the local reference to the server-side surface. The surface * may continue to exist on-screen as long as its parent continues * to exist. To explicitly remove a surface from the screen use - * {@link Transaction#reparent} with a null-parent. + * {@link Transaction#reparent} with a null-parent. After release, + * {@link #isValid} will return false and other methods will throw + * an exception. * * Always call release() when you're done with a SurfaceControl. */ @@ -902,7 +949,8 @@ public final class SurfaceControl implements Parcelable { /** * Check whether this instance points to a valid layer with the system-compositor. For - * example this may be false if construction failed, or the layer was released. + * example this may be false if construction failed, or the layer was released + * ({@link #release}). * * @return Whether this SurfaceControl is valid. */ @@ -1815,10 +1863,10 @@ public final class SurfaceControl implements Parcelable { throw new IllegalArgumentException("consumer must not be null"); } - final GraphicBuffer buffer = screenshotToBuffer(display, sourceCrop, width, height, - useIdentityTransform, rotation); + final ScreenshotGraphicBuffer buffer = screenshotToBuffer(display, sourceCrop, width, + height, useIdentityTransform, rotation); try { - consumer.attachAndQueueBuffer(buffer); + consumer.attachAndQueueBuffer(buffer.getGraphicBuffer()); } catch (RuntimeException e) { Log.w(TAG, "Failed to take screenshot - " + e.getMessage()); } @@ -1861,17 +1909,16 @@ public final class SurfaceControl implements Parcelable { } SurfaceControl.rotateCropForSF(sourceCrop, rotation); - final GraphicBuffer buffer = screenshotToBuffer(displayToken, sourceCrop, width, height, - useIdentityTransform, rotation); + final ScreenshotGraphicBuffer buffer = screenshotToBuffer(displayToken, sourceCrop, width, + height, useIdentityTransform, rotation); if (buffer == null) { Log.w(TAG, "Failed to take screenshot"); return null; } - // TODO(b/116112787) Now that hardware bitmap creation can take color space, we - // should continue to fix screenshot. - return Bitmap.wrapHardwareBuffer(HardwareBuffer.createFromGraphicBuffer(buffer), - ColorSpace.get(ColorSpace.Named.SRGB)); + return Bitmap.wrapHardwareBuffer( + HardwareBuffer.createFromGraphicBuffer(buffer.getGraphicBuffer()), + buffer.getColorSpace()); } /** @@ -1897,8 +1944,8 @@ public final class SurfaceControl implements Parcelable { * @return Returns a GraphicBuffer that contains the captured content. * @hide */ - public static GraphicBuffer screenshotToBuffer(IBinder display, Rect sourceCrop, int width, - int height, boolean useIdentityTransform, int rotation) { + public static ScreenshotGraphicBuffer screenshotToBuffer(IBinder display, Rect sourceCrop, + int width, int height, boolean useIdentityTransform, int rotation) { if (display == null) { throw new IllegalArgumentException("displayToken must not be null"); } @@ -1917,7 +1964,7 @@ public final class SurfaceControl implements Parcelable { * * @hide */ - public static GraphicBuffer screenshotToBufferWithSecureLayersUnsafe(IBinder display, + public static ScreenshotGraphicBuffer screenshotToBufferWithSecureLayersUnsafe(IBinder display, Rect sourceCrop, int width, int height, boolean useIdentityTransform, int rotation) { if (display == null) { @@ -1951,7 +1998,7 @@ public final class SurfaceControl implements Parcelable { * @return Returns a GraphicBuffer that contains the layer capture. * @hide */ - public static GraphicBuffer captureLayers(IBinder layerHandleToken, Rect sourceCrop, + public static ScreenshotGraphicBuffer captureLayers(IBinder layerHandleToken, Rect sourceCrop, float frameScale) { return nativeCaptureLayers(layerHandleToken, sourceCrop, frameScale); } @@ -2042,8 +2089,7 @@ public final class SurfaceControl implements Parcelable { } /** - * Close the transaction, if the transaction was not already applied this will cancel the - * transaction. + * Release the native transaction object, without applying it. */ @Override public void close() { @@ -2128,8 +2174,8 @@ public final class SurfaceControl implements Parcelable { } /** - * Set the default buffer size for the SurfaceControl, if there is an - * {@link Surface} assosciated with the control, then + * Set the default buffer size for the SurfaceControl, if there is a + * {@link Surface} associated with the control, then * this will be the default size for buffers dequeued from it. * @param sc The surface to set the buffer size for. * @param w The default width diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index ee8d66313ea2aa90a4699621d0ae95905ded78de..e931448652c0efac18ab4b07a8481d57b191cf5e 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -491,7 +491,7 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb if (mBackgroundControl == null) { return; } - if ((mSurfaceFlags & SurfaceControl.OPAQUE) != 0) { + if ((mSubLayer > 0) && ((mSurfaceFlags & SurfaceControl.OPAQUE) != 0)) { mBackgroundControl.show(); mBackgroundControl.setLayer(Integer.MIN_VALUE); } else { diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index bf0f4e29a4f3971818fb8369ba4716c0d3e67115..2357db46771a3669661cd7dca57b9aadcea78833 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -17,10 +17,6 @@ package android.view; import static android.content.res.Resources.ID_NULL; -import static android.util.StatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__DEEP_PRESS; -import static android.util.StatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__LONG_PRESS; -import static android.util.StatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__SINGLE_TAP; -import static android.util.StatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__UNKNOWN_CLASSIFICATION; import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL; import static android.view.accessibility.AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED; @@ -100,7 +96,6 @@ import android.util.Property; import android.util.SparseArray; import android.util.SparseIntArray; import android.util.StateSet; -import android.util.StatsLog; import android.util.SuperNotCalledException; import android.util.TypedValue; import android.view.AccessibilityIterators.CharacterTextSegmentIterator; @@ -14546,12 +14541,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (clickable) { setPressed(true, x, y); } - checkForLongClick( - ViewConfiguration.getLongPressTimeout(), - x, - y, - // This is not a touch gesture -- do not classify it as one. - TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__UNKNOWN_CLASSIFICATION); + checkForLongClick(ViewConfiguration.getLongPressTimeout(), x, y); return true; } } @@ -15292,11 +15282,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, mHasPerformedLongPress = false; if (!clickable) { - checkForLongClick( - ViewConfiguration.getLongPressTimeout(), - x, - y, - TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__LONG_PRESS); + checkForLongClick(ViewConfiguration.getLongPressTimeout(), x, y); break; } @@ -15320,11 +15306,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } else { // Not inside a scrolling container, so show the feedback right away setPressed(true, x, y); - checkForLongClick( - ViewConfiguration.getLongPressTimeout(), - x, - y, - TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__LONG_PRESS); + checkForLongClick(ViewConfiguration.getLongPressTimeout(), x, y); } break; @@ -15361,11 +15343,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * ambiguousMultiplier); // Subtract the time already spent delay -= event.getEventTime() - event.getDownTime(); - checkForLongClick( - delay, - x, - y, - TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__LONG_PRESS); + checkForLongClick(delay, x, y); } touchSlop *= ambiguousMultiplier; } @@ -15387,11 +15365,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (deepPress && hasPendingLongPressCallback()) { // process the long click action immediately removeLongPressCallback(); - checkForLongClick( - 0 /* send immediately */, - x, - y, - TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__DEEP_PRESS); + checkForLongClick(0 /* send immediately */, x, y); } break; @@ -26056,7 +26030,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } } - private void checkForLongClick(long delay, float x, float y, int classification) { + private void checkForLongClick(long delay, float x, float y) { if ((mViewFlags & LONG_CLICKABLE) == LONG_CLICKABLE || (mViewFlags & TOOLTIP) == TOOLTIP) { mHasPerformedLongPress = false; @@ -26066,7 +26040,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, mPendingCheckForLongPress.setAnchor(x, y); mPendingCheckForLongPress.rememberWindowAttachCount(); mPendingCheckForLongPress.rememberPressedState(); - mPendingCheckForLongPress.setClassification(classification); postDelayed(mPendingCheckForLongPress, delay); } } @@ -27624,17 +27597,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, private float mX; private float mY; private boolean mOriginalPressedState; - /** - * The classification of the long click being checked: one of the - * StatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__* constants. - */ - private int mClassification; @Override public void run() { if ((mOriginalPressedState == isPressed()) && (mParent != null) && mOriginalWindowAttachCount == mWindowAttachCount) { - recordGestureClassification(mClassification); if (performLongClick(mX, mY)) { mHasPerformedLongPress = true; } @@ -27653,10 +27620,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, public void rememberPressedState() { mOriginalPressedState = isPressed(); } - - public void setClassification(int classification) { - mClassification = classification; - } } private final class CheckForTap implements Runnable { @@ -27669,28 +27632,17 @@ public class View implements Drawable.Callback, KeyEvent.Callback, setPressed(true, x, y); final long delay = ViewConfiguration.getLongPressTimeout() - ViewConfiguration.getTapTimeout(); - checkForLongClick(delay, x, y, TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__LONG_PRESS); + checkForLongClick(delay, x, y); } } private final class PerformClick implements Runnable { @Override public void run() { - recordGestureClassification(TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__SINGLE_TAP); performClickInternal(); } } - /** Records a classification for the current event stream. */ - private void recordGestureClassification(int classification) { - if (classification == TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__UNKNOWN_CLASSIFICATION) { - return; - } - // To avoid negatively impacting View performance, the latency and displacement metrics - // are omitted. - StatsLog.write(StatsLog.TOUCH_GESTURE_CLASSIFIED, getClass().getName(), classification); - } - /** * This method returns a ViewPropertyAnimator object, which can be used to animate * specific properties on this View. @@ -28248,11 +28200,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, final Rect mOutsets = new Rect(); /** - * In multi-window we force show the navigation bar. Because we don't want that the surface - * size changes in this mode, we instead have a flag whether the navigation bar size should - * always be consumed, so the app is treated like there is no virtual navigation bar at all. + * In multi-window we force show the system bars. Because we don't want that the surface + * size changes in this mode, we instead have a flag whether the system bars sizes should + * always be consumed, so the app is treated like there are no virtual system bars at all. */ - boolean mAlwaysConsumeNavBar; + boolean mAlwaysConsumeSystemBars; /** * The internal insets given by this window. This value is diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index a4d80dcfe7d29e711843ec4b6cd4a12f57cf2910..4851476e3d70849e87c76e4b120c039290aa5a7c 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -142,7 +142,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager * This field should be made private, so it is hidden from the SDK. * {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123768704) protected OnHierarchyChangeListener mOnHierarchyChangeListener; // The view contained within this ViewGroup that has or contains focus. @@ -239,7 +239,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager @ViewDebug.FlagToString(mask = FLAG_PADDING_NOT_NULL, equals = FLAG_PADDING_NOT_NULL, name = "PADDING_NOT_NULL") }, formatToHexString = true) - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123769411) protected int mGroupFlags; /** @@ -300,7 +300,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123769377) protected static final int FLAG_USE_CHILD_DRAWING_ORDER = 0x400; /** @@ -314,7 +314,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager * * {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123769647) protected static final int FLAG_SUPPORT_STATIC_TRANSFORMATIONS = 0x800; // UNUSED FLAG VALUE: 0x1000; @@ -368,7 +368,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager * When set, this ViewGroup should not intercept touch events. * {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123983692) protected static final int FLAG_DISALLOW_INTERCEPT = 0x80000; /** diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 6d04cd3187ef3e2a5fd2f8786ad2ba11ced57267..2880e7f135456689b458d14012852220b99c746e 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -512,7 +512,7 @@ public final class ViewRootImpl implements ViewParent, final Rect mPendingBackDropFrame = new Rect(); final DisplayCutout.ParcelableWrapper mPendingDisplayCutout = new DisplayCutout.ParcelableWrapper(DisplayCutout.NO_CUTOUT); - boolean mPendingAlwaysConsumeNavBar; + boolean mPendingAlwaysConsumeSystemBars; private InsetsState mTempInsets = new InsetsState(); final ViewTreeObserver.InternalInsetsInfo mLastGivenInsets = new ViewTreeObserver.InternalInsetsInfo(); @@ -921,9 +921,9 @@ public final class ViewRootImpl implements ViewParent, mPendingStableInsets.set(mAttachInfo.mStableInsets); mPendingDisplayCutout.set(mAttachInfo.mDisplayCutout); mPendingVisibleInsets.set(0, 0, 0, 0); - mAttachInfo.mAlwaysConsumeNavBar = - (res & WindowManagerGlobal.ADD_FLAG_ALWAYS_CONSUME_NAV_BAR) != 0; - mPendingAlwaysConsumeNavBar = mAttachInfo.mAlwaysConsumeNavBar; + mAttachInfo.mAlwaysConsumeSystemBars = + (res & WindowManagerGlobal.ADD_FLAG_ALWAYS_CONSUME_SYSTEM_BARS) != 0; + mPendingAlwaysConsumeSystemBars = mAttachInfo.mAlwaysConsumeSystemBars; mInsetsController.onStateChanged(mTempInsets); if (DEBUG_LAYOUT) Log.v(mTag, "Added window " + mWindow); if (res < WindowManagerGlobal.ADD_OKAY) { @@ -1918,12 +1918,12 @@ public final class ViewRootImpl implements ViewParent, if (sNewInsetsMode != NEW_INSETS_MODE_NONE) { mLastWindowInsets = mInsetsController.calculateInsets( mContext.getResources().getConfiguration().isScreenRound(), - mAttachInfo.mAlwaysConsumeNavBar, displayCutout, + mAttachInfo.mAlwaysConsumeSystemBars, displayCutout, contentInsets, stableInsets, mWindowAttributes.softInputMode); } else { mLastWindowInsets = new WindowInsets(contentInsets, stableInsets, mContext.getResources().getConfiguration().isScreenRound(), - mAttachInfo.mAlwaysConsumeNavBar, displayCutout); + mAttachInfo.mAlwaysConsumeSystemBars, displayCutout); } } return mLastWindowInsets; @@ -2126,7 +2126,7 @@ public final class ViewRootImpl implements ViewParent, if (!mPendingOutsets.equals(mAttachInfo.mOutsets)) { insetsChanged = true; } - if (mPendingAlwaysConsumeNavBar != mAttachInfo.mAlwaysConsumeNavBar) { + if (mPendingAlwaysConsumeSystemBars != mAttachInfo.mAlwaysConsumeSystemBars) { insetsChanged = true; } if (lp.width == ViewGroup.LayoutParams.WRAP_CONTENT @@ -2326,8 +2326,8 @@ public final class ViewRootImpl implements ViewParent, final boolean surfaceSizeChanged = (relayoutResult & WindowManagerGlobal.RELAYOUT_RES_SURFACE_RESIZED) != 0; surfaceChanged |= surfaceSizeChanged; - final boolean alwaysConsumeNavBarChanged = - mPendingAlwaysConsumeNavBar != mAttachInfo.mAlwaysConsumeNavBar; + final boolean alwaysConsumeSystemBarsChanged = + mPendingAlwaysConsumeSystemBars != mAttachInfo.mAlwaysConsumeSystemBars; final boolean colorModeChanged = hasColorModeChanged(lp.getColorMode()); if (contentInsetsChanged) { mAttachInfo.mContentInsets.set(mPendingContentInsets); @@ -2356,8 +2356,8 @@ public final class ViewRootImpl implements ViewParent, // Need to relayout with content insets. contentInsetsChanged = true; } - if (alwaysConsumeNavBarChanged) { - mAttachInfo.mAlwaysConsumeNavBar = mPendingAlwaysConsumeNavBar; + if (alwaysConsumeSystemBarsChanged) { + mAttachInfo.mAlwaysConsumeSystemBars = mPendingAlwaysConsumeSystemBars; contentInsetsChanged = true; } if (contentInsetsChanged || mLastSystemUiVisibility != @@ -4633,7 +4633,7 @@ public final class ViewRootImpl implements ViewParent, mPendingOutsets.set((Rect) args.arg7); mPendingBackDropFrame.set((Rect) args.arg8); mForceNextWindowRelayout = args.argi1 != 0; - mPendingAlwaysConsumeNavBar = args.argi2 != 0; + mPendingAlwaysConsumeSystemBars = args.argi2 != 0; args.recycle(); @@ -7084,8 +7084,8 @@ public final class ViewRootImpl implements ViewParent, destroySurface(); } - mPendingAlwaysConsumeNavBar = - (relayoutResult & WindowManagerGlobal.RELAYOUT_RES_CONSUME_ALWAYS_NAV_BAR) != 0; + mPendingAlwaysConsumeSystemBars = + (relayoutResult & WindowManagerGlobal.RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS) != 0; if (restore) { params.restore(); @@ -7374,7 +7374,7 @@ public final class ViewRootImpl implements ViewParent, private void dispatchResized(Rect frame, Rect overscanInsets, Rect contentInsets, Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw, MergedConfiguration mergedConfiguration, Rect backDropFrame, boolean forceLayout, - boolean alwaysConsumeNavBar, int displayId, + boolean alwaysConsumeSystemBars, int displayId, DisplayCutout.ParcelableWrapper displayCutout) { if (DEBUG_LAYOUT) Log.v(mTag, "Resizing " + this + ": frame=" + frame.toShortString() + " contentInsets=" + contentInsets.toShortString() @@ -7414,7 +7414,7 @@ public final class ViewRootImpl implements ViewParent, args.arg8 = sameProcessCall ? new Rect(backDropFrame) : backDropFrame; args.arg9 = displayCutout.get(); // DisplayCutout is immutable. args.argi1 = forceLayout ? 1 : 0; - args.argi2 = alwaysConsumeNavBar ? 1 : 0; + args.argi2 = alwaysConsumeSystemBars ? 1 : 0; args.argi3 = displayId; msg.obj = args; mHandler.sendMessage(msg); @@ -8498,13 +8498,14 @@ public final class ViewRootImpl implements ViewParent, public void resized(Rect frame, Rect overscanInsets, Rect contentInsets, Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw, MergedConfiguration mergedConfiguration, Rect backDropFrame, boolean forceLayout, - boolean alwaysConsumeNavBar, int displayId, + boolean alwaysConsumeSystemBars, int displayId, DisplayCutout.ParcelableWrapper displayCutout) { final ViewRootImpl viewAncestor = mViewAncestor.get(); if (viewAncestor != null) { viewAncestor.dispatchResized(frame, overscanInsets, contentInsets, visibleInsets, stableInsets, outsets, reportDraw, mergedConfiguration, - backDropFrame, forceLayout, alwaysConsumeNavBar, displayId, displayCutout); + backDropFrame, forceLayout, alwaysConsumeSystemBars, displayId, + displayCutout); } } diff --git a/core/java/android/view/WindowInsets.java b/core/java/android/view/WindowInsets.java index aac0e34de0da0f8b91684fd66f70536b8eec506e..ffa769a424a999d2a580dd17a7e533ca6bbe8667 100644 --- a/core/java/android/view/WindowInsets.java +++ b/core/java/android/view/WindowInsets.java @@ -83,7 +83,7 @@ public final class WindowInsets { * changes in this mode, we instead have a flag whether the navigation bar size should always * be consumed, so the app is treated like there is no virtual navigation bar at all. */ - private final boolean mAlwaysConsumeNavBar; + private final boolean mAlwaysConsumeSystemBars; private final boolean mSystemWindowInsetsConsumed; private final boolean mStableInsetsConsumed; @@ -111,10 +111,10 @@ public final class WindowInsets { * @deprecated Use {@link WindowInsets(SparseArray, SparseArray, boolean, boolean, DisplayCutout)} */ public WindowInsets(Rect systemWindowInsetsRect, Rect stableInsetsRect, - boolean isRound, boolean alwaysConsumeNavBar, DisplayCutout displayCutout) { + boolean isRound, boolean alwaysConsumeSystemBars, DisplayCutout displayCutout) { this(createCompatTypeMap(systemWindowInsetsRect), createCompatTypeMap(stableInsetsRect), createCompatVisibilityMap(createCompatTypeMap(systemWindowInsetsRect)), - isRound, alwaysConsumeNavBar, displayCutout); + isRound, alwaysConsumeSystemBars, displayCutout); } /** @@ -133,7 +133,7 @@ public final class WindowInsets { @Nullable Insets[] typeMaxInsetsMap, boolean[] typeVisibilityMap, boolean isRound, - boolean alwaysConsumeNavBar, DisplayCutout displayCutout) { + boolean alwaysConsumeSystemBars, DisplayCutout displayCutout) { mSystemWindowInsetsConsumed = typeInsetsMap == null; mTypeInsetsMap = mSystemWindowInsetsConsumed ? new Insets[SIZE] @@ -146,7 +146,7 @@ public final class WindowInsets { mTypeVisibilityMap = typeVisibilityMap; mIsRound = isRound; - mAlwaysConsumeNavBar = alwaysConsumeNavBar; + mAlwaysConsumeSystemBars = alwaysConsumeSystemBars; mDisplayCutoutConsumed = displayCutout == null; mDisplayCutout = (mDisplayCutoutConsumed || displayCutout.isEmpty()) @@ -160,7 +160,7 @@ public final class WindowInsets { */ public WindowInsets(WindowInsets src) { this(src.mTypeInsetsMap, src.mTypeMaxInsetsMap, src.mTypeVisibilityMap, src.mIsRound, - src.mAlwaysConsumeNavBar, displayCutoutCopyConstructorArgument(src)); + src.mAlwaysConsumeSystemBars, displayCutoutCopyConstructorArgument(src)); } private static DisplayCutout displayCutoutCopyConstructorArgument(WindowInsets w) { @@ -443,7 +443,7 @@ public final class WindowInsets { return new WindowInsets(mSystemWindowInsetsConsumed ? null : mTypeInsetsMap, mStableInsetsConsumed ? null : mTypeMaxInsetsMap, mTypeVisibilityMap, - mIsRound, mAlwaysConsumeNavBar, + mIsRound, mAlwaysConsumeSystemBars, null /* displayCutout */); } @@ -489,7 +489,7 @@ public final class WindowInsets { public WindowInsets consumeSystemWindowInsets() { return new WindowInsets(null, mStableInsetsConsumed ? null : mTypeMaxInsetsMap, mTypeVisibilityMap, - mIsRound, mAlwaysConsumeNavBar, + mIsRound, mAlwaysConsumeSystemBars, displayCutoutCopyConstructorArgument(this)); } @@ -729,15 +729,15 @@ public final class WindowInsets { @NonNull public WindowInsets consumeStableInsets() { return new WindowInsets(mSystemWindowInsetsConsumed ? null : mTypeInsetsMap, null, - mTypeVisibilityMap, mIsRound, mAlwaysConsumeNavBar, + mTypeVisibilityMap, mIsRound, mAlwaysConsumeSystemBars, displayCutoutCopyConstructorArgument(this)); } /** * @hide */ - public boolean shouldAlwaysConsumeNavBar() { - return mAlwaysConsumeNavBar; + public boolean shouldAlwaysConsumeSystemBars() { + return mAlwaysConsumeSystemBars; } @Override @@ -809,7 +809,7 @@ public final class WindowInsets { ? null : insetInsets(mTypeMaxInsetsMap, left, top, right, bottom), mTypeVisibilityMap, - mIsRound, mAlwaysConsumeNavBar, + mIsRound, mAlwaysConsumeSystemBars, mDisplayCutoutConsumed ? null : mDisplayCutout == null @@ -824,7 +824,7 @@ public final class WindowInsets { WindowInsets that = (WindowInsets) o; return mIsRound == that.mIsRound - && mAlwaysConsumeNavBar == that.mAlwaysConsumeNavBar + && mAlwaysConsumeSystemBars == that.mAlwaysConsumeSystemBars && mSystemWindowInsetsConsumed == that.mSystemWindowInsetsConsumed && mStableInsetsConsumed == that.mStableInsetsConsumed && mDisplayCutoutConsumed == that.mDisplayCutoutConsumed @@ -837,8 +837,9 @@ public final class WindowInsets { @Override public int hashCode() { return Objects.hash(Arrays.hashCode(mTypeInsetsMap), Arrays.hashCode(mTypeMaxInsetsMap), - Arrays.hashCode(mTypeVisibilityMap), mIsRound, mDisplayCutout, mAlwaysConsumeNavBar, - mSystemWindowInsetsConsumed, mStableInsetsConsumed, mDisplayCutoutConsumed); + Arrays.hashCode(mTypeVisibilityMap), mIsRound, mDisplayCutout, + mAlwaysConsumeSystemBars, mSystemWindowInsetsConsumed, mStableInsetsConsumed, + mDisplayCutoutConsumed); } @@ -900,7 +901,7 @@ public final class WindowInsets { private DisplayCutout mDisplayCutout; private boolean mIsRound; - private boolean mAlwaysConsumeNavBar; + private boolean mAlwaysConsumeSystemBars; /** * Creates a builder where all insets are initially consumed. @@ -924,7 +925,7 @@ public final class WindowInsets { mStableInsetsConsumed = insets.mStableInsetsConsumed; mDisplayCutout = displayCutoutCopyConstructorArgument(insets); mIsRound = insets.mIsRound; - mAlwaysConsumeNavBar = insets.mAlwaysConsumeNavBar; + mAlwaysConsumeSystemBars = insets.mAlwaysConsumeSystemBars; } /** @@ -1119,8 +1120,8 @@ public final class WindowInsets { /** @hide */ @NonNull - public Builder setAlwaysConsumeNavBar(boolean alwaysConsumeNavBar) { - mAlwaysConsumeNavBar = alwaysConsumeNavBar; + public Builder setAlwaysConsumeSystemBars(boolean alwaysConsumeSystemBars) { + mAlwaysConsumeSystemBars = alwaysConsumeSystemBars; return this; } @@ -1133,7 +1134,7 @@ public final class WindowInsets { public WindowInsets build() { return new WindowInsets(mSystemInsetsConsumed ? null : mTypeInsetsMap, mStableInsetsConsumed ? null : mTypeMaxInsetsMap, mTypeVisibilityMap, - mIsRound, mAlwaysConsumeNavBar, mDisplayCutout); + mIsRound, mAlwaysConsumeSystemBars, mDisplayCutout); } } diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java index 453c5e32a178b959cc3c2c6ca52f45462ecf1f01..8a111cf866583b1387ca255e43b4bdefe328f857 100644 --- a/core/java/android/view/WindowManagerGlobal.java +++ b/core/java/android/view/WindowManagerGlobal.java @@ -93,11 +93,11 @@ public final class WindowManagerGlobal { public static final int RELAYOUT_RES_SURFACE_RESIZED = 0x20; /** - * In multi-window we force show the navigation bar. Because we don't want that the surface size - * changes in this mode, we instead have a flag whether the navigation bar size should always be - * consumed, so the app is treated like there is no virtual navigation bar at all. + * In multi-window we force show the system bars. Because we don't want that the surface size + * changes in this mode, we instead have a flag whether the system bar sizes should always be + * consumed, so the app is treated like there is no virtual system bars at all. */ - public static final int RELAYOUT_RES_CONSUME_ALWAYS_NAV_BAR = 0x40; + public static final int RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS = 0x40; /** * Flag for relayout: the client will be later giving @@ -118,9 +118,10 @@ public final class WindowManagerGlobal { public static final int ADD_FLAG_IN_TOUCH_MODE = RELAYOUT_RES_IN_TOUCH_MODE; /** - * Like {@link #RELAYOUT_RES_CONSUME_ALWAYS_NAV_BAR}, but as a "hint" when adding the window. + * Like {@link #RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS}, but as a "hint" when adding the + * window. */ - public static final int ADD_FLAG_ALWAYS_CONSUME_NAV_BAR = 0x4; + public static final int ADD_FLAG_ALWAYS_CONSUME_SYSTEM_BARS = 0x4; public static final int ADD_OKAY = 0; public static final int ADD_BAD_APP_TOKEN = -1; diff --git a/core/java/android/view/WindowManagerPolicyConstants.java b/core/java/android/view/WindowManagerPolicyConstants.java index 35ed7bfa2ce69c6736c68ad0d9b61c5fa120e2db..46a59f09eca7886728aabea9dc094474b33cca97 100644 --- a/core/java/android/view/WindowManagerPolicyConstants.java +++ b/core/java/android/view/WindowManagerPolicyConstants.java @@ -54,6 +54,16 @@ public interface WindowManagerPolicyConstants { int NAV_BAR_RIGHT = 1 << 1; int NAV_BAR_BOTTOM = 1 << 2; + // Navigation bar interaction modes + int NAV_BAR_MODE_3BUTTON = 0; + int NAV_BAR_MODE_2BUTTON = 1; + int NAV_BAR_MODE_GESTURAL = 2; + + // Associated overlays for each nav bar mode + String NAV_BAR_MODE_3BUTTON_OVERLAY = "com.android.internal.systemui.navbar.threebutton"; + String NAV_BAR_MODE_2BUTTON_OVERLAY = "com.android.internal.systemui.navbar.twobutton"; + String NAV_BAR_MODE_GESTURAL_OVERLAY = "com.android.internal.systemui.navbar.gestural"; + /** * Broadcast sent when a user activity is detected. */ diff --git a/core/java/android/view/accessibility/AccessibilityManager.java b/core/java/android/view/accessibility/AccessibilityManager.java index 384cdbb3831c43c213b317dd7a402da2dfce07e3..d12777fe908eff092cce9c2c9bb6d0f219d483d8 100644 --- a/core/java/android/view/accessibility/AccessibilityManager.java +++ b/core/java/android/view/accessibility/AccessibilityManager.java @@ -848,7 +848,7 @@ public final class AccessibilityManager { if (mRequestPreparerLists == null) { mRequestPreparerLists = new SparseArray<>(1); } - int id = preparer.getView().getAccessibilityViewId(); + int id = preparer.getAccessibilityViewId(); List requestPreparerList = mRequestPreparerLists.get(id); if (requestPreparerList == null) { requestPreparerList = new ArrayList<>(1); @@ -864,7 +864,7 @@ public final class AccessibilityManager { if (mRequestPreparerLists == null) { return; } - int viewId = preparer.getView().getAccessibilityViewId(); + int viewId = preparer.getAccessibilityViewId(); List requestPreparerList = mRequestPreparerLists.get(viewId); if (requestPreparerList != null) { requestPreparerList.remove(preparer); diff --git a/core/java/android/view/accessibility/AccessibilityRequestPreparer.java b/core/java/android/view/accessibility/AccessibilityRequestPreparer.java index 4dcb18766347260f2c7025bd71b22a3d7c8b6791..8108d37a8814c3719e72f2fe3d333e5fec1f1466 100644 --- a/core/java/android/view/accessibility/AccessibilityRequestPreparer.java +++ b/core/java/android/view/accessibility/AccessibilityRequestPreparer.java @@ -51,6 +51,7 @@ public abstract class AccessibilityRequestPreparer { public @interface RequestTypes {} private final WeakReference mViewRef; + private final int mAccessibilityViewId; private final int mRequestTypes; /** @@ -68,6 +69,7 @@ public abstract class AccessibilityRequestPreparer { throw new IllegalStateException("View must be attached to a window"); } mViewRef = new WeakReference<>(view); + mAccessibilityViewId = view.getAccessibilityViewId(); mRequestTypes = requestTypes; view.addOnAttachStateChangeListener(new ViewAttachStateListener()); } @@ -118,4 +120,8 @@ public abstract class AccessibilityRequestPreparer { v.removeOnAttachStateChangeListener(this); } } + + int getAccessibilityViewId() { + return mAccessibilityViewId; + } } diff --git a/core/java/android/view/accessibility/IAccessibilityInteractionConnectionCallback.aidl b/core/java/android/view/accessibility/IAccessibilityInteractionConnectionCallback.aidl index c1a3ab77098950ac0ab249b1b658bdac868527c0..f96f0acd60825ed56555d8abcf9f2a1b66368aa3 100644 --- a/core/java/android/view/accessibility/IAccessibilityInteractionConnectionCallback.aidl +++ b/core/java/android/view/accessibility/IAccessibilityInteractionConnectionCallback.aidl @@ -33,6 +33,7 @@ oneway interface IAccessibilityInteractionConnectionCallback { * @param infos The result {@link AccessibilityNodeInfo}. * @param interactionId The interaction id to match the result with the request. */ + @UnsupportedAppUsage void setFindAccessibilityNodeInfoResult(in AccessibilityNodeInfo info, int interactionId); /** @@ -41,6 +42,7 @@ oneway interface IAccessibilityInteractionConnectionCallback { * @param infos The result {@link AccessibilityNodeInfo}s. * @param interactionId The interaction id to match the result with the request. */ + @UnsupportedAppUsage void setFindAccessibilityNodeInfosResult(in List infos, int interactionId); @@ -50,5 +52,6 @@ oneway interface IAccessibilityInteractionConnectionCallback { * @param Whether the action was performed. * @param interactionId The interaction id to match the result with the request. */ + @UnsupportedAppUsage void setPerformAccessibilityActionResult(boolean succeeded, int interactionId); } diff --git a/core/java/android/view/accessibility/IAccessibilityManager.aidl b/core/java/android/view/accessibility/IAccessibilityManager.aidl index 486b35d9cc0fc56d7ed3875ad631817f3c8a125d..0d5c7c941a56ff396f0fd8d0dffc863e2aa2d6d5 100644 --- a/core/java/android/view/accessibility/IAccessibilityManager.aidl +++ b/core/java/android/view/accessibility/IAccessibilityManager.aidl @@ -42,6 +42,7 @@ interface IAccessibilityManager { List getInstalledAccessibilityServiceList(int userId); + @UnsupportedAppUsage List getEnabledAccessibilityServiceList(int feedbackType, int userId); int addAccessibilityInteractionConnection(IWindow windowToken, diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java index 8cb04cbdc994fad948c2687fe167444599cda852..77a0c4c5f4eef2231d5cd41c85ea30719de8d711 100644 --- a/core/java/android/view/autofill/AutofillManager.java +++ b/core/java/android/view/autofill/AutofillManager.java @@ -16,7 +16,6 @@ package android.view.autofill; -import static android.service.autofill.FillRequest.FLAG_AUGMENTED_AUTOFILL_REQUEST; import static android.service.autofill.FillRequest.FLAG_MANUAL_REQUEST; import static android.view.autofill.Helper.sDebug; import static android.view.autofill.Helper.sVerbose; @@ -228,6 +227,7 @@ public final class AutofillManager { /** @hide */ public static final int FLAG_ADD_CLIENT_ENABLED = 0x1; /** @hide */ public static final int FLAG_ADD_CLIENT_DEBUG = 0x2; /** @hide */ public static final int FLAG_ADD_CLIENT_VERBOSE = 0x4; + /** @hide */ public static final int FLAG_ADD_CLIENT_ENABLED_FOR_AUGMENTED_AUTOFILL_ONLY = 0x8; /** @hide */ public static final int FLAG_SESSION_FOR_AUGMENTED_AUTOFILL_ONLY = 0x1; @@ -520,6 +520,13 @@ public final class AutofillManager { @GuardedBy("mLock") private boolean mForAugmentedAutofillOnly; + /** + * When set, standard autofill is enabled, but sessions can still be created for augmented + * autofill only. + */ + @GuardedBy("mLock") + private boolean mEnabledForAugmentedAutofillOnly; + /** @hide */ public interface AutofillClient { /** @@ -946,7 +953,7 @@ public final class AutofillManager { ensureServiceClientAddedIfNeededLocked(); - if (!mEnabled) { + if (!mEnabled && !mEnabledForAugmentedAutofillOnly) { if (sVerbose) Log.v(TAG, "ignoring notifyViewEntered(" + id + "): disabled"); if (mCallback != null) { @@ -988,7 +995,7 @@ public final class AutofillManager { void notifyViewExitedLocked(@NonNull View view) { ensureServiceClientAddedIfNeededLocked(); - if (mEnabled && isActiveLocked()) { + if ((mEnabled || mEnabledForAugmentedAutofillOnly) && isActiveLocked()) { // dont notify exited when Activity is already in background if (!isClientDisablingEnterExitEvent()) { final AutofillId id = view.getAutofillId(); @@ -1104,7 +1111,7 @@ public final class AutofillManager { ensureServiceClientAddedIfNeededLocked(); - if (!mEnabled) { + if (!mEnabled && !mEnabledForAugmentedAutofillOnly) { if (sVerbose) { Log.v(TAG, "ignoring notifyViewEntered(" + id + "): disabled"); } @@ -1155,7 +1162,7 @@ public final class AutofillManager { private void notifyViewExitedLocked(@NonNull View view, int virtualId) { ensureServiceClientAddedIfNeededLocked(); - if (mEnabled && isActiveLocked()) { + if ((mEnabled || mEnabledForAugmentedAutofillOnly) && isActiveLocked()) { // don't notify exited when Activity is already in background if (!isClientDisablingEnterExitEvent()) { final AutofillId id = getAutofillId(view, virtualId); @@ -1674,14 +1681,17 @@ public final class AutofillManager { private void startSessionLocked(@NonNull AutofillId id, @NonNull Rect bounds, @NonNull AutofillValue value, int flags) { if (mEnteredForAugmentedAutofillIds != null - && mEnteredForAugmentedAutofillIds.contains(id)) { + && mEnteredForAugmentedAutofillIds.contains(id) + || mEnabledForAugmentedAutofillOnly) { if (sVerbose) Log.v(TAG, "Starting session for augmented autofill on " + id); - flags |= FLAG_AUGMENTED_AUTOFILL_REQUEST; + flags |= FLAG_ADD_CLIENT_ENABLED_FOR_AUGMENTED_AUTOFILL_ONLY; } if (sVerbose) { Log.v(TAG, "startSessionLocked(): id=" + id + ", bounds=" + bounds + ", value=" + value + ", flags=" + flags + ", state=" + getStateAsStringLocked() + ", compatMode=" + isCompatibilityModeEnabledLocked() + + ", augmentedOnly=" + mForAugmentedAutofillOnly + + ", enabledAugmentedOnly=" + mEnabledForAugmentedAutofillOnly + ", enteredIds=" + mEnteredIds); } if (mState != STATE_UNKNOWN && !isFinishedLocked() && (flags & FLAG_MANUAL_REQUEST) == 0) { @@ -1776,7 +1786,8 @@ public final class AutofillManager { @GuardedBy("mLock") private void ensureServiceClientAddedIfNeededLocked() { - if (getClient() == null) { + final AutofillClient client = getClient(); + if (client == null) { return; } @@ -1785,11 +1796,18 @@ public final class AutofillManager { try { final int userId = mContext.getUserId(); final SyncResultReceiver receiver = new SyncResultReceiver(SYNC_CALLS_TIMEOUT_MS); - mService.addClient(mServiceClient, userId, receiver); + mService.addClient(mServiceClient, client.autofillClientGetComponentName(), + userId, receiver); final int flags = receiver.getIntResult(); mEnabled = (flags & FLAG_ADD_CLIENT_ENABLED) != 0; sDebug = (flags & FLAG_ADD_CLIENT_DEBUG) != 0; sVerbose = (flags & FLAG_ADD_CLIENT_VERBOSE) != 0; + mEnabledForAugmentedAutofillOnly = (flags + & FLAG_ADD_CLIENT_ENABLED_FOR_AUGMENTED_AUTOFILL_ONLY) != 0; + if (sVerbose) { + Log.v(TAG, "receiver results: flags=" + flags + " enabled=" + mEnabled + + ", enabledForAugmentedOnly: " + mEnabledForAugmentedAutofillOnly); + } final IAutoFillManager service = mService; final IAutoFillManagerClient serviceClient = mServiceClient; mServiceClientCleaner = Cleaner.create(this, () -> { @@ -2406,6 +2424,7 @@ public final class AutofillManager { pw.print(" ("); pw.print(client.autofillClientGetActivityToken()); pw.println(')'); } pw.print(pfx); pw.print("enabled: "); pw.println(mEnabled); + pw.print(pfx); pw.print("enabledAugmentedOnly: "); pw.println(mForAugmentedAutofillOnly); pw.print(pfx); pw.print("hasService: "); pw.println(mService != null); pw.print(pfx); pw.print("hasCallback: "); pw.println(mCallback != null); pw.print(pfx); pw.print("onInvisibleCalled "); pw.println(mOnInvisibleCalled); diff --git a/core/java/android/view/autofill/IAutoFillManager.aidl b/core/java/android/view/autofill/IAutoFillManager.aidl index 9e6a4afe54149f8945be478f8e10ebdb899328b4..a507e74c30ab8c361fd71e9c92b3681617427760 100644 --- a/core/java/android/view/autofill/IAutoFillManager.aidl +++ b/core/java/android/view/autofill/IAutoFillManager.aidl @@ -37,7 +37,8 @@ import com.android.internal.os.IResultReceiver; */ oneway interface IAutoFillManager { // Returns flags: FLAG_ADD_CLIENT_ENABLED | FLAG_ADD_CLIENT_DEBUG | FLAG_ADD_CLIENT_VERBOSE - void addClient(in IAutoFillManagerClient client, int userId, in IResultReceiver result); + void addClient(in IAutoFillManagerClient client, in ComponentName componentName, int userId, + in IResultReceiver result); void removeClient(in IAutoFillManagerClient client, int userId); void startSession(IBinder activityToken, in IBinder appCallback, in AutofillId autoFillId, in Rect bounds, in AutofillValue value, int userId, boolean hasCallback, int flags, diff --git a/core/java/android/view/contentcapture/ContentCaptureManager.java b/core/java/android/view/contentcapture/ContentCaptureManager.java index a3e65496bcd01dc7a2e28c0c8fec9d4f3e25ce87..9e546a80dfd346194fa3b076334587f7fda5d9fc 100644 --- a/core/java/android/view/contentcapture/ContentCaptureManager.java +++ b/core/java/android/view/contentcapture/ContentCaptureManager.java @@ -32,6 +32,7 @@ import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.RemoteException; +import android.os.ServiceManager; import android.util.Log; import android.view.contentcapture.ContentCaptureSession.FlushReason; @@ -51,12 +52,14 @@ public final class ContentCaptureManager { private static final String TAG = ContentCaptureManager.class.getSimpleName(); + /** @hide */ + public static final int RESULT_CODE_OK = 0; /** @hide */ public static final int RESULT_CODE_TRUE = 1; /** @hide */ public static final int RESULT_CODE_FALSE = 2; /** @hide */ - public static final int RESULT_CODE_NOT_SERVICE = -1; + public static final int RESULT_CODE_SECURITY_EXCEPTION = -1; /** * Timeout for calls to system_server. @@ -243,6 +246,7 @@ public final class ContentCaptureManager { @UiThread public void onActivityCreated(@NonNull IBinder applicationToken, @NonNull ComponentName activityComponent, int flags) { + if (mOptions.lite) return; synchronized (mLock) { mFlags |= flags; getMainContentCaptureSession().start(applicationToken, activityComponent, mFlags); @@ -252,18 +256,21 @@ public final class ContentCaptureManager { /** @hide */ @UiThread public void onActivityResumed() { + if (mOptions.lite) return; getMainContentCaptureSession().notifySessionLifecycle(/* started= */ true); } /** @hide */ @UiThread public void onActivityPaused() { + if (mOptions.lite) return; getMainContentCaptureSession().notifySessionLifecycle(/* started= */ false); } /** @hide */ @UiThread public void onActivityDestroyed() { + if (mOptions.lite) return; getMainContentCaptureSession().destroy(); } @@ -276,6 +283,7 @@ public final class ContentCaptureManager { */ @UiThread public void flush(@FlushReason int reason) { + if (mOptions.lite) return; getMainContentCaptureSession().flush(reason); } @@ -285,7 +293,7 @@ public final class ContentCaptureManager { */ @Nullable public ComponentName getServiceComponentName() { - if (!isContentCaptureEnabled()) return null; + if (!isContentCaptureEnabled() && !mOptions.lite) return null; final SyncResultReceiver resultReceiver = new SyncResultReceiver(SYNC_CALLS_TIMEOUT_MS); try { @@ -296,6 +304,35 @@ public final class ContentCaptureManager { } } + /** + * Gets the (optional) intent used to launch the service-specific settings. + * + *

This method is static because it's called by Settings, which might not be whitelisted + * for content capture (in which case the ContentCaptureManager on its context would be null). + * + * @hide + */ + // TODO: use "lite" options as it's done by activities from the content capture service + @Nullable + public static ComponentName getServiceSettingsComponentName() { + final IBinder binder = ServiceManager + .checkService(Context.CONTENT_CAPTURE_MANAGER_SERVICE); + if (binder == null) return null; + + final IContentCaptureManager service = IContentCaptureManager.Stub.asInterface(binder); + final SyncResultReceiver resultReceiver = new SyncResultReceiver(SYNC_CALLS_TIMEOUT_MS); + try { + service.getServiceSettingsActivity(resultReceiver); + final int resultCode = resultReceiver.getIntResult(); + if (resultCode == RESULT_CODE_SECURITY_EXCEPTION) { + throw new SecurityException(resultReceiver.getStringResult()); + } + return resultReceiver.getParcelableResult(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + /** * Checks whether content capture is enabled for this activity. * @@ -311,6 +348,8 @@ public final class ContentCaptureManager { * */ public boolean isContentCaptureEnabled() { + if (mOptions.lite) return false; + final MainContentCaptureSession mainSession; synchronized (mLock) { mainSession = mMainSession; @@ -365,7 +404,7 @@ public final class ContentCaptureManager { return true; case RESULT_CODE_FALSE: return false; - case RESULT_CODE_NOT_SERVICE: + case RESULT_CODE_SECURITY_EXCEPTION: throw new SecurityException("caller is not user's ContentCapture service"); default: Log.wtf(TAG, "received invalid result: " + resultCode); diff --git a/core/java/android/view/contentcapture/ContentCaptureSession.java b/core/java/android/view/contentcapture/ContentCaptureSession.java index 6d41b289460a25dc587ee856aa019641e43efc1a..ed1ca2a48850207e9221b818d90ef9d2268ed1e6 100644 --- a/core/java/android/view/contentcapture/ContentCaptureSession.java +++ b/core/java/android/view/contentcapture/ContentCaptureSession.java @@ -134,12 +134,19 @@ public abstract class ContentCaptureSession implements AutoCloseable { */ public static final int STATE_SERVICE_DIED = 0x400; + /** + * Session is disabled because the service package is being udpated. + * + * @hide + */ + public static final int STATE_SERVICE_UPDATING = 0x800; + /** * Session is enabled, after the service died and came back to live. * * @hide */ - public static final int STATE_SERVICE_RESURRECTED = 0x800; + public static final int STATE_SERVICE_RESURRECTED = 0x1000; private static final int INITIAL_CHILDREN_CAPACITY = 5; diff --git a/core/java/android/view/contentcapture/IContentCaptureManager.aidl b/core/java/android/view/contentcapture/IContentCaptureManager.aidl index e3b0372a8cc7f6f05a95a1618a512e75847bc320..15fbaa2d7dabf8f06d35827035068ca0c68440f4 100644 --- a/core/java/android/view/contentcapture/IContentCaptureManager.aidl +++ b/core/java/android/view/contentcapture/IContentCaptureManager.aidl @@ -67,4 +67,9 @@ oneway interface IContentCaptureManager { * Returns whether the content capture feature is enabled for the calling user. */ void isContentCaptureFeatureEnabled(in IResultReceiver result); + + /** + * Returns a ComponentName with the name of custom service activity, if defined. + */ + void getServiceSettingsActivity(in IResultReceiver result); } diff --git a/core/java/android/view/contentcapture/MainContentCaptureSession.java b/core/java/android/view/contentcapture/MainContentCaptureSession.java index 666af5968f69fe70ac436319400146a8232d8af9..790b8f9dde460b9b984651ff4efd66b72e62f8d9 100644 --- a/core/java/android/view/contentcapture/MainContentCaptureSession.java +++ b/core/java/android/view/contentcapture/MainContentCaptureSession.java @@ -230,7 +230,8 @@ public final class MainContentCaptureSession extends ContentCaptureSession { /** * Callback from {@code system_server} after call to - * {@link IContentCaptureManager#startSession(IBinder, ComponentName, String, int, IBinder)} + * {@link IContentCaptureManager#startSession(IBinder, ComponentName, String, int, + * IResultReceiver)}. * * @param resultCode session state * @param binder handle to {@code IContentCaptureDirectManager} diff --git a/core/java/android/view/inspector/InspectableNodeName.java b/core/java/android/view/inspector/InspectableNodeName.java deleted file mode 100644 index 7b9a507ee45d011ea3d4cc7544dbdccbb17757c4..0000000000000000000000000000000000000000 --- a/core/java/android/view/inspector/InspectableNodeName.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.view.inspector; - -import static java.lang.annotation.ElementType.TYPE; -import static java.lang.annotation.RetentionPolicy.SOURCE; - -import android.annotation.TestApi; - -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - -/** - * Marks the node name to display to a developer in the inspection tree. - * - * This annotation is optional to marking a class as inspectable. If it is omitted, the node name - * will be inferred using the semantics of {@link Class#getSimpleName()}. The fully qualified class - * name is always available in the tree, this is for display purposes only. If a class is inflated - * from XML and the tag it inflates from does not match its simple name, this annotation should be - * used to inform the inspector to display the XML tag name in the inspection tree view. - * - * This annotation does not inherit. If a class extends an annotated parent class, but does not - * annotate itself, its node name will be inferred from its Java name. - * - * @see InspectionCompanion#getNodeName() - * @hide - */ -@Target({TYPE}) -@Retention(SOURCE) -@TestApi -public @interface InspectableNodeName { - /** - * The display name for nodes of this type. - * - * @return The name for nodes of this type - */ - String value(); -} diff --git a/core/java/android/view/inspector/InspectionCompanion.java b/core/java/android/view/inspector/InspectionCompanion.java index 62d769b6d963a2b524d02136cfc5e15d3c64d466..a633a58065a0968d0734ee0a8fa81976754ea65c 100644 --- a/core/java/android/view/inspector/InspectionCompanion.java +++ b/core/java/android/view/inspector/InspectionCompanion.java @@ -17,7 +17,6 @@ package android.view.inspector; import android.annotation.NonNull; -import android.annotation.Nullable; /** * An interface for companion objects used to inspect views. @@ -33,11 +32,6 @@ import android.annotation.Nullable; * parent class via the parent's inspection companion, and the child companion will only read * properties added or changed since the parent was defined. * - * Only one child traversal is considered for each class. If a descendant class defines a - * different child traversal than its parent, only the bottom traversal is used. If a class does - * not define its own child traversal, but one of its ancestors does, the bottom-most ancestor's - * traversal will be used. - * * @param The type of inspectable this is the companion to */ public interface InspectionCompanion { @@ -67,22 +61,6 @@ public interface InspectionCompanion { */ void readProperties(@NonNull T inspectable, @NonNull PropertyReader propertyReader); - /** - * Get an optional name to display to developers for inspection nodes of this companion's type. - * - * The default implementation returns null, which will cause the runtime to use the class's - * simple name as defined by {@link Class#getSimpleName()} as the node name. - * - * If the type of this companion is inflated from XML, this method should be overridden to - * return the string used as the tag name for this type in XML. - * - * @return A string to use as the node name, or null to use the simple class name fallback. - */ - @Nullable - default String getNodeName() { - return null; - } - /** * Thrown by {@link #readProperties(Object, PropertyReader)} if called before * {@link #mapProperties(PropertyMapper)}. diff --git a/core/java/android/view/textclassifier/TextClassifierImpl.java b/core/java/android/view/textclassifier/TextClassifierImpl.java index 8f5f0a376c3567f78ac7a0eb612272d58ecc2fce..0f2e702ecd0d9bb71640657531eaca271e54302d 100644 --- a/core/java/android/view/textclassifier/TextClassifierImpl.java +++ b/core/java/android/view/textclassifier/TextClassifierImpl.java @@ -86,7 +86,8 @@ public final class TextClassifierImpl implements TextClassifier { new File("/data/misc/textclassifier/lang_id.model"); // Actions - private static final String ACTIONS_FACTORY_MODEL_FILENAME_REGEX = "actions_suggestions.model"; + private static final String ACTIONS_FACTORY_MODEL_FILENAME_REGEX = + "actions_suggestions\\.(.*)\\.model"; private static final File UPDATED_ACTIONS_MODEL = new File("/data/misc/textclassifier/actions_suggestions.model"); @@ -177,8 +178,7 @@ public final class TextClassifierImpl implements TextClassifier { final String localesString = concatenateLocales(request.getDefaultLocales()); final String detectLanguageTags = detectLanguageTagsFromText(request.getText()); final ZonedDateTime refTime = ZonedDateTime.now(); - final AnnotatorModel annotatorImpl = - getAnnotatorImpl(request.getDefaultLocales()); + final AnnotatorModel annotatorImpl = getAnnotatorImpl(request.getDefaultLocales()); final int start; final int end; if (mSettings.isModelDarkLaunchEnabled() && !request.isDarkLaunchAllowed()) { @@ -417,7 +417,8 @@ public final class TextClassifierImpl implements TextClassifier { nativeConversation, null, mContext, - getResourceLocalesString()); + getResourceLocalesString(), + getAnnotatorImpl(LocaleList.getDefault())); return createConversationActionResult(request, nativeSuggestions); } catch (Throwable t) { // Avoid throwing from this method. Log the error. @@ -583,8 +584,7 @@ public final class TextClassifierImpl implements TextClassifier { new File(bestModel.getPath()), ParcelFileDescriptor.MODE_READ_ONLY); try { if (pfd != null) { - mActionsImpl = new ActionsSuggestionsModel( - pfd.getFd(), getAnnotatorImpl(LocaleList.getDefault())); + mActionsImpl = new ActionsSuggestionsModel(pfd.getFd()); mActionModelInUse = bestModel; } } finally { diff --git a/core/java/com/android/internal/annotations/VisibleForNative.java b/core/java/com/android/internal/annotations/VisibleForNative.java new file mode 100644 index 0000000000000000000000000000000000000000..e6a3fc67b7d39e3588c3d4b5b9da74840864546e --- /dev/null +++ b/core/java/com/android/internal/annotations/VisibleForNative.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.annotations; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Denotes that the class, method or field has its visibility relaxed so + * that native code can access it. + */ +@Retention(RetentionPolicy.CLASS) +public @interface VisibleForNative { +} diff --git a/core/java/com/android/internal/app/AbstractResolverComparator.java b/core/java/com/android/internal/app/AbstractResolverComparator.java new file mode 100644 index 0000000000000000000000000000000000000000..3576b6bb42368ef7de5274193af15c82546550a1 --- /dev/null +++ b/core/java/com/android/internal/app/AbstractResolverComparator.java @@ -0,0 +1,63 @@ +package com.android.internal.app; + +import android.content.ComponentName; +import com.android.internal.app.ResolverActivity.ResolvedComponentInfo; +import java.util.Comparator; +import java.util.List; + +/** + * Used to sort resolved activities in {@link ResolverListController}. + */ +abstract class AbstractResolverComparator implements Comparator { + + protected AfterCompute mAfterCompute; + + /** + * Callback to be called when {@link #compute(List)} finishes. This signals to stop waiting. + */ + public interface AfterCompute { + + public void afterCompute(); + } + + public void setCallBack(AfterCompute afterCompute) { + mAfterCompute = afterCompute; + } + + /** + * Computes features for each target. This will be called before calls to {@link + * #getScore(ComponentName)} or {@link #compare(Object, Object)}, in order to prepare the + * comparator for those calls. Note that {@link #getScore(ComponentName)} uses {@link + * ComponentName}, so the implementation will have to be prepared to identify a {@link + * ResolvedComponentInfo} by {@link ComponentName}. + */ + public abstract void compute(List targets); + + /** + * Returns the score that was calculated for the corresponding {@link ResolvedComponentInfo} + * when {@link #compute(List)} was called before this. + */ + public abstract float getScore(ComponentName name); + + /** + * Reports to UsageStats what was chosen. + */ + // TODO(b/129014961) Move implemetation here and make final. + public abstract void updateChooserCounts(String packageName, int userId, String action); + + /** + * Updates the model used to rank the componentNames. + * + *

Default implementation does nothing, as we could have simple model that does not train + * online. + * + * @param componentName the component that the user clicked + */ + public void updateModel(ComponentName componentName) { + } + + /** + * Called when the {@link ResolverActivity} is destroyed. + */ + public abstract void destroy(); +} diff --git a/core/java/com/android/internal/app/AlertActivity.java b/core/java/com/android/internal/app/AlertActivity.java index 999a908251dd668c7c3a4cbf2bc11af4025ce08f..0b08099b51edd619a3e1f5e577f264f825b96fcc 100644 --- a/core/java/com/android/internal/app/AlertActivity.java +++ b/core/java/com/android/internal/app/AlertActivity.java @@ -16,6 +16,7 @@ package com.android.internal.app; +import android.annotation.UnsupportedAppUsage; import android.app.Activity; import android.app.Dialog; import android.content.DialogInterface; @@ -38,11 +39,13 @@ public abstract class AlertActivity extends Activity implements DialogInterface * * @see #mAlertParams */ + @UnsupportedAppUsage protected AlertController mAlert; /** * The parameters for the alert. */ + @UnsupportedAppUsage protected AlertController.AlertParams mAlertParams; @Override @@ -90,6 +93,7 @@ public abstract class AlertActivity extends Activity implements DialogInterface * @see #mAlert * @see #mAlertParams */ + @UnsupportedAppUsage protected void setupAlert() { mAlert.installContent(mAlertParams); } diff --git a/core/java/com/android/internal/app/AssistUtils.java b/core/java/com/android/internal/app/AssistUtils.java index d0102a72e703c437c1f288da2c2af417b7264062..efcdb9a29dd89a44e5cd8d147e03f9d81e5e8341 100644 --- a/core/java/com/android/internal/app/AssistUtils.java +++ b/core/java/com/android/internal/app/AssistUtils.java @@ -17,6 +17,7 @@ package com.android.internal.app; import android.annotation.NonNull; +import android.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.pm.ApplicationInfo; @@ -42,6 +43,7 @@ public class AssistUtils { private final Context mContext; private final IVoiceInteractionManagerService mVoiceInteractionManagerService; + @UnsupportedAppUsage public AssistUtils(Context context) { mContext = context; mVoiceInteractionManagerService = IVoiceInteractionManagerService.Stub.asInterface( @@ -168,6 +170,7 @@ public class AssistUtils { } } + @UnsupportedAppUsage public ComponentName getAssistComponentForUser(int userId) { final String setting = Settings.Secure.getStringForUser(mContext.getContentResolver(), Settings.Secure.ASSISTANT, userId); diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java index faf0c7dbed375623d9a9ac0646bffd44ce266824..4f5678a5ff24da119cbc5cb1a37cb00854e51549 100644 --- a/core/java/com/android/internal/app/ChooserActivity.java +++ b/core/java/com/android/internal/app/ChooserActivity.java @@ -24,6 +24,7 @@ import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.animation.ValueAnimator; import android.annotation.IntDef; +import android.annotation.UnsupportedAppUsage; import android.app.Activity; import android.app.ActivityManager; import android.app.prediction.AppPredictionContext; @@ -58,6 +59,7 @@ import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; +import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.Icon; import android.metrics.LogMaker; @@ -236,7 +238,7 @@ public class ChooserActivity extends ResolverActivity { if (DEBUG) { Log.d(TAG, "CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT; unbinding services"); } - if (isDestroyed()) { + if (mChooserListAdapter == null || isDestroyed()) { break; } unbindRemainingServices(); @@ -821,6 +823,7 @@ public class ChooserActivity extends ResolverActivity { mRefinementResultReceiver = null; } unbindRemainingServices(); + mChooserHandler.removeMessages(CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT); mChooserHandler.removeMessages(CHOOSER_TARGET_SERVICE_RESULT); if (USE_PREDICTION_MANAGER_FOR_DIRECT_TARGETS) { mAppPredictor.unregisterPredictionUpdates(mAppPredictorCallback); @@ -876,10 +879,17 @@ public class ChooserActivity extends ResolverActivity { } mChooserRowAdapter = new ChooserRowAdapter(mChooserListAdapter); mChooserRowAdapter.registerDataSetObserver(new OffsetDataSetObserver(adapterView)); - adapterView.setAdapter(mChooserRowAdapter); if (listView != null) { listView.setItemsCanFocus(true); + listView.addOnLayoutChangeListener( + (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> { + if (mChooserRowAdapter.calculateMaxTargetsPerRow(right - left)) { + adapterView.setAdapter(mChooserRowAdapter); + } + }); } + + adapterView.setAdapter(mChooserRowAdapter); } @Override @@ -1269,11 +1279,10 @@ public class ChooserActivity extends ResolverActivity { } mAppPredictor.notifyAppTargetEvent( new AppTargetEvent.Builder( - new AppTarget( - new AppTargetId(shortcutId), - componentName.getPackageName(), - componentName.getClassName(), - getUser()), + new AppTarget.Builder(new AppTargetId(shortcutId)) + .setTarget(componentName.getPackageName(), getUser()) + .setClassName(componentName.getClassName()) + .build(), AppTargetEvent.ACTION_LAUNCH ).setLaunchLocation(LAUNCH_LOCATON_DIRECT_SHARE) .build()); @@ -1465,14 +1474,6 @@ public class ChooserActivity extends ResolverActivity { return null; } - public Drawable getBadgeIcon() { - return null; - } - - public CharSequence getBadgeContentDescription() { - return null; - } - public TargetInfo cloneFilledIn(Intent fillInIntent, int flags) { return null; } @@ -1561,31 +1562,49 @@ public class ChooserActivity extends ResolverActivity { */ // TODO(121287224): Refactor code to apply the suggestion above private Drawable getChooserTargetIconDrawable(ChooserTarget target) { + Drawable directShareIcon = null; + + // First get the target drawable and associated activity info final Icon icon = target.getIcon(); if (icon != null) { - return icon.loadDrawable(ChooserActivity.this); - } - if (!USE_SHORTCUT_MANAGER_FOR_DIRECT_TARGETS) { - return null; + directShareIcon = icon.loadDrawable(ChooserActivity.this); + } else if (USE_SHORTCUT_MANAGER_FOR_DIRECT_TARGETS) { + Bundle extras = target.getIntentExtras(); + if (extras != null && extras.containsKey(Intent.EXTRA_SHORTCUT_ID)) { + CharSequence shortcutId = extras.getCharSequence(Intent.EXTRA_SHORTCUT_ID); + LauncherApps launcherApps = (LauncherApps) getSystemService( + Context.LAUNCHER_APPS_SERVICE); + final LauncherApps.ShortcutQuery q = new LauncherApps.ShortcutQuery(); + q.setPackage(target.getComponentName().getPackageName()); + q.setShortcutIds(Arrays.asList(shortcutId.toString())); + q.setQueryFlags(LauncherApps.ShortcutQuery.FLAG_MATCH_DYNAMIC); + final List shortcuts = launcherApps.getShortcuts(q, getUser()); + if (shortcuts != null && shortcuts.size() > 0) { + directShareIcon = launcherApps.getShortcutIconDrawable(shortcuts.get(0), 0); + } + } } - Bundle extras = target.getIntentExtras(); - if (extras == null || !extras.containsKey(Intent.EXTRA_SHORTCUT_ID)) { - return null; - } - CharSequence shortcutId = extras.getCharSequence(Intent.EXTRA_SHORTCUT_ID); - LauncherApps launcherApps = (LauncherApps) getSystemService( - Context.LAUNCHER_APPS_SERVICE); - final LauncherApps.ShortcutQuery q = new LauncherApps.ShortcutQuery(); - q.setPackage(target.getComponentName().getPackageName()); - q.setShortcutIds(Arrays.asList(shortcutId.toString())); - q.setQueryFlags(LauncherApps.ShortcutQuery.FLAG_MATCH_DYNAMIC); - final List shortcuts = launcherApps.getShortcuts(q, getUser()); - if (shortcuts != null && shortcuts.size() > 0) { - return launcherApps.getShortcutIconDrawable(shortcuts.get(0), 0); + if (directShareIcon == null) return null; + + ActivityInfo info = null; + try { + info = mPm.getActivityInfo(target.getComponentName(), 0); + } catch (NameNotFoundException error) { + Log.e(TAG, "Could not find activity associated with ChooserTarget"); } - return null; + if (info == null) return null; + + // Now fetch app icon and raster with no badging even in work profile + Bitmap appIcon = (new ActivityInfoPresentationGetter(info)).getIconBitmap(); + + // Raster target drawable with appIcon as a badge + SimpleIconFactory sif = SimpleIconFactory.obtain(ChooserActivity.this); + Bitmap directShareBadgedIcon = sif.createAppBadgedIconBitmap(directShareIcon, appIcon); + sif.recycle(); + + return new BitmapDrawable(getResources(), directShareBadgedIcon); } public float getModifiedScore() { @@ -1683,16 +1702,6 @@ public class ChooserActivity extends ResolverActivity { return mDisplayIcon; } - @Override - public Drawable getBadgeIcon() { - return mBadgeIcon; - } - - @Override - public CharSequence getBadgeContentDescription() { - return mBadgeContentDescription; - } - public ChooserTarget getChooserTarget() { return mChooserTarget; } @@ -2062,7 +2071,7 @@ public class ChooserActivity extends ResolverActivity { class ChooserRowAdapter extends BaseAdapter { private ChooserListAdapter mChooserListAdapter; private final LayoutInflater mLayoutInflater; - private int mAnimationCount = 0; + private int mCalculatedMaxTargetsPerRow = MAX_TARGETS_PER_ROW_LANDSCAPE; private DirectShareViewHolder mDirectShareViewHolder; @@ -2070,6 +2079,9 @@ public class ChooserActivity extends ResolverActivity { private static final int VIEW_TYPE_NORMAL = 1; private static final int VIEW_TYPE_CONTENT_PREVIEW = 2; + private static final int MAX_TARGETS_PER_ROW_PORTRAIT = 4; + private static final int MAX_TARGETS_PER_ROW_LANDSCAPE = 8; + public ChooserRowAdapter(ChooserListAdapter wrappedAdapter) { mChooserListAdapter = wrappedAdapter; mLayoutInflater = LayoutInflater.from(ChooserActivity.this); @@ -2089,9 +2101,40 @@ public class ChooserActivity extends ResolverActivity { }); } + /** + * Determine how many targets can comfortably fit in a single row. + * + * @param width The new row width to use for recalculation + * @return true if the numbers of targets per row has changed + */ + public boolean calculateMaxTargetsPerRow(int width) { + int targetWidth = getResources().getDimensionPixelSize( + R.dimen.chooser_target_width); + + if (targetWidth == 0 || width == 0) { + return false; + } + + int margin = getResources().getDimensionPixelSize( + R.dimen.chooser_edge_margin_normal); + + int newCount = (width - margin * 2) / targetWidth; + if (newCount != mCalculatedMaxTargetsPerRow) { + mCalculatedMaxTargetsPerRow = newCount; + return true; + } + + return false; + } + private int getMaxTargetsPerRow() { - // this will soon hold logic for portrait/landscape - return 4; + int maxTargets = MAX_TARGETS_PER_ROW_PORTRAIT; + if (getResources().getConfiguration().orientation + == Configuration.ORIENTATION_LANDSCAPE) { + maxTargets = MAX_TARGETS_PER_ROW_LANDSCAPE; + } + + return Math.min(maxTargets, mCalculatedMaxTargetsPerRow); } @Override @@ -2158,9 +2201,7 @@ public class ChooserActivity extends ResolverActivity { holder = (RowViewHolder) convertView.getTag(); } - bindViewHolder(position, holder, - viewType == VIEW_TYPE_DIRECT_SHARE - ? ChooserListAdapter.MAX_SERVICE_TARGETS : getMaxTargetsPerRow()); + bindViewHolder(position, holder); return holder.getViewGroup(); } @@ -2277,7 +2318,7 @@ public class ChooserActivity extends ResolverActivity { } } - void bindViewHolder(int rowPosition, RowViewHolder holder, int columnCount) { + void bindViewHolder(int rowPosition, RowViewHolder holder) { final int start = getFirstRowPosition(rowPosition); final int startType = mChooserListAdapter.getPositionTargetType(start); @@ -2294,6 +2335,7 @@ public class ChooserActivity extends ResolverActivity { setVertPadding(row, 0, 0); } + int columnCount = holder.getColumnCount(); int end = start + columnCount - 1; while (mChooserListAdapter.getPositionTargetType(end) != startType && end >= start) { end--; @@ -2328,36 +2370,15 @@ public class ChooserActivity extends ResolverActivity { for (int i = 0; i < columnCount; i++) { final View v = holder.getView(i); if (start + i <= end) { - setCellVisibility(holder, i, View.VISIBLE); + holder.setViewVisibility(i, View.VISIBLE); holder.setItemIndex(i, start + i); mChooserListAdapter.bindView(holder.getItemIndex(i), v); } else { - setCellVisibility(holder, i, View.INVISIBLE); + holder.setViewVisibility(i, View.INVISIBLE); } } } - private void setCellVisibility(RowViewHolder holder, int i, int visibility) { - final View v = holder.getView(i); - if (visibility == View.VISIBLE) { - holder.setViewVisibility(i, true); - v.setVisibility(visibility); - v.setAlpha(1.0f); - } else if (visibility == View.INVISIBLE && holder.getViewVisibility(i)) { - holder.setViewVisibility(i, false); - - ValueAnimator fadeAnim = ObjectAnimator.ofFloat(v, "alpha", 1.0f, 0f); - fadeAnim.setDuration(NO_DIRECT_SHARE_ANIM_IN_MILLIS); - fadeAnim.setInterpolator(new AccelerateInterpolator(1.0f)); - fadeAnim.addListener(new AnimatorListenerAdapter() { - public void onAnimationEnd(Animator animation) { - v.setVisibility(View.INVISIBLE); - } - }); - fadeAnim.start(); - } - } - private void setVertPadding(ViewGroup row, int top, int bottom) { row.setPadding(row.getPaddingLeft(), top, row.getPaddingRight(), bottom); } @@ -2393,13 +2414,11 @@ public class ChooserActivity extends ResolverActivity { protected int mMeasuredRowHeight; private int[] mItemIndices; protected final View[] mCells; - private final boolean[] mCellVisibility; private final int mColumnCount; RowViewHolder(int cellCount) { this.mCells = new View[cellCount]; this.mItemIndices = new int[cellCount]; - this.mCellVisibility = new boolean[cellCount]; this.mColumnCount = cellCount; } @@ -2409,18 +2428,12 @@ public class ChooserActivity extends ResolverActivity { abstract ViewGroup getRow(int index); + abstract void setViewVisibility(int i, int visibility); + public int getColumnCount() { return mColumnCount; } - public void setViewVisibility(int index, boolean visibility) { - mCellVisibility[index] = visibility; - } - - public boolean getViewVisibility(int index) { - return mCellVisibility[index]; - } - public void measure() { final int spec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); getViewGroup().measure(spec, spec); @@ -2476,6 +2489,10 @@ public class ChooserActivity extends ResolverActivity { return mRow; } + + public void setViewVisibility(int i, int visibility) { + getView(i).setVisibility(visibility); + } } class DirectShareViewHolder extends RowViewHolder { @@ -2488,12 +2505,15 @@ public class ChooserActivity extends ResolverActivity { private int mDirectShareCurrHeight = 0; private int mDirectShareMaxHeight = 0; + private final boolean[] mCellVisibility; + DirectShareViewHolder(ViewGroup parent, List rows, int cellCountPerRow) { super(rows.size() * cellCountPerRow); this.mParent = parent; this.mRows = rows; this.mCellCountPerRow = cellCountPerRow; + this.mCellVisibility = new boolean[rows.size() * cellCountPerRow]; } public ViewGroup addView(int index, View v) { @@ -2532,6 +2552,27 @@ public class ChooserActivity extends ResolverActivity { return mDirectShareCurrHeight; } + public void setViewVisibility(int i, int visibility) { + final View v = getView(i); + if (visibility == View.VISIBLE) { + mCellVisibility[i] = true; + v.setVisibility(visibility); + v.setAlpha(1.0f); + } else if (visibility == View.INVISIBLE && mCellVisibility[i]) { + mCellVisibility[i] = false; + + ValueAnimator fadeAnim = ObjectAnimator.ofFloat(v, "alpha", 1.0f, 0f); + fadeAnim.setDuration(NO_DIRECT_SHARE_ANIM_IN_MILLIS); + fadeAnim.setInterpolator(new AccelerateInterpolator(1.0f)); + fadeAnim.addListener(new AnimatorListenerAdapter() { + public void onAnimationEnd(Animator animation) { + v.setVisibility(View.INVISIBLE); + } + }); + fadeAnim.start(); + } + } + public void handleScroll(AbsListView view, int y, int oldy, int maxTargetsPerRow) { // only expand if we have more than 4 targets, and delay that decision until // they start to scroll diff --git a/core/java/com/android/internal/app/IntentForwarderActivity.java b/core/java/com/android/internal/app/IntentForwarderActivity.java index 64f00103eb4bf5efd75065128f93e1671d258f13..3811fe44255db6bee76d070e554e689870fe465b 100644 --- a/core/java/com/android/internal/app/IntentForwarderActivity.java +++ b/core/java/com/android/internal/app/IntentForwarderActivity.java @@ -20,6 +20,7 @@ import static android.content.pm.PackageManager.MATCH_DEFAULT_ONLY; import android.annotation.Nullable; import android.annotation.StringRes; +import android.annotation.UnsupportedAppUsage; import android.app.Activity; import android.app.ActivityTaskManager; import android.app.ActivityThread; @@ -54,6 +55,7 @@ import java.util.Set; * be passed in and out of a managed profile. */ public class IntentForwarderActivity extends Activity { + @UnsupportedAppUsage public static String TAG = "IntentForwarderActivity"; public static String FORWARD_INTENT_TO_PARENT diff --git a/core/java/com/android/internal/app/LocaleHelper.java b/core/java/com/android/internal/app/LocaleHelper.java index 0a230a90a7356ae91fc9be792e90e4e7947c68a0..aef4dbf41d350cdc1144d64b5a5a83200f6118a0 100644 --- a/core/java/com/android/internal/app/LocaleHelper.java +++ b/core/java/com/android/internal/app/LocaleHelper.java @@ -17,6 +17,7 @@ package com.android.internal.app; import android.annotation.IntRange; +import android.annotation.UnsupportedAppUsage; import android.icu.text.ListFormatter; import android.icu.util.ULocale; import android.os.LocaleList; @@ -84,6 +85,7 @@ public class LocaleHelper { * @param locale the locale that might be used for certain operations (i.e. case conversion) * @return the string normalized for search */ + @UnsupportedAppUsage public static String normalizeForSearch(String str, Locale locale) { // TODO: tbd if it needs to be smarter (real normalization, remove accents, etc.) // If needed we might use case folding and ICU/CLDR's collation-based loose searching. @@ -109,6 +111,7 @@ public class LocaleHelper { * @param sentenceCase true if the result should be sentence-cased * @return the localized name of the locale. */ + @UnsupportedAppUsage public static String getDisplayName(Locale locale, Locale displayLocale, boolean sentenceCase) { final ULocale displayULocale = ULocale.forLocale(displayLocale); String result = shouldUseDialectName(locale) @@ -135,6 +138,7 @@ public class LocaleHelper { * @param displayLocale the locale in which to display the name. * @return the localized country name. */ + @UnsupportedAppUsage public static String getDisplayCountry(Locale locale, Locale displayLocale) { final String languageTag = locale.toLanguageTag(); final ULocale uDisplayLocale = ULocale.forLocale(displayLocale); @@ -226,6 +230,7 @@ public class LocaleHelper { * * @param sortLocale the locale to be used for sorting. */ + @UnsupportedAppUsage public LocaleInfoComparator(Locale sortLocale, boolean countryMode) { mCollator = Collator.getInstance(sortLocale); mCountryMode = countryMode; @@ -253,6 +258,7 @@ public class LocaleHelper { * @return a negative integer, zero, or a positive integer as the first * argument is less than, equal to, or greater than the second. */ + @UnsupportedAppUsage @Override public int compare(LocaleStore.LocaleInfo lhs, LocaleStore.LocaleInfo rhs) { // We don't care about the various suggestion types, just "suggested" (!= 0) diff --git a/core/java/com/android/internal/app/LocalePicker.java b/core/java/com/android/internal/app/LocalePicker.java index c8c2fcf60d1ff983008b89fdd0a9b0dec6e8f46f..75174246cd99ba4c8fa1030b7332f55a2bf82424 100644 --- a/core/java/com/android/internal/app/LocalePicker.java +++ b/core/java/com/android/internal/app/LocalePicker.java @@ -18,6 +18,7 @@ package com.android.internal.app; import com.android.internal.R; +import android.annotation.UnsupportedAppUsage; import android.app.ActivityManager; import android.app.IActivityManager; import android.app.ListFragment; @@ -70,6 +71,7 @@ public class LocalePicker extends ListFragment { return label; } + @UnsupportedAppUsage public Locale getLocale() { return locale; } @@ -251,6 +253,7 @@ public class LocalePicker extends ListFragment { * * @see #updateLocales(LocaleList) */ + @UnsupportedAppUsage public static void updateLocale(Locale locale) { updateLocales(new LocaleList(locale)); } @@ -260,6 +263,7 @@ public class LocalePicker extends ListFragment { * Note that the system looks halted for a while during the Locale migration, * so the caller need to take care of it. */ + @UnsupportedAppUsage public static void updateLocales(LocaleList locales) { try { final IActivityManager am = ActivityManager.getService(); @@ -281,6 +285,7 @@ public class LocalePicker extends ListFragment { * * @return The locale list. */ + @UnsupportedAppUsage public static LocaleList getLocales() { try { return ActivityManager.getService() diff --git a/core/java/com/android/internal/app/LocaleStore.java b/core/java/com/android/internal/app/LocaleStore.java index 1d997f5767d380fb150627fa297207d7e6faca1d..c11089ba19bd5b6327855eb1f70853bdf06a44c5 100644 --- a/core/java/com/android/internal/app/LocaleStore.java +++ b/core/java/com/android/internal/app/LocaleStore.java @@ -16,6 +16,7 @@ package com.android.internal.app; +import android.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.LocaleList; import android.provider.Settings; @@ -81,14 +82,17 @@ public class LocaleStore { return mId; } + @UnsupportedAppUsage public Locale getLocale() { return mLocale; } + @UnsupportedAppUsage public Locale getParent() { return mParent; } + @UnsupportedAppUsage public String getId() { return mId; } @@ -115,6 +119,7 @@ public class LocaleStore { return (mSuggestionFlags & suggestionMask) == suggestionMask; } + @UnsupportedAppUsage public String getFullNameNative() { if (mFullNameNative == null) { mFullNameNative = @@ -140,6 +145,7 @@ public class LocaleStore { * For instance German will show as "Deutsch" in the list, but we will also search for * "allemand" if the system UI is in French. */ + @UnsupportedAppUsage public String getFullNameInUiLanguage() { // We don't cache the UI name because the default locale keeps changing return LocaleHelper.getDisplayName(mLocale, true /* sentence case */); @@ -254,6 +260,7 @@ public class LocaleStore { } } + @UnsupportedAppUsage public static void fillCache(Context context) { if (sFullyInitialized) { return; @@ -340,6 +347,7 @@ public class LocaleStore { * Example: if the parent is "ar", then the region list will contain all Arabic locales. * (this is not language based, but language-script, so that it works for zh-Hant and so on. */ + @UnsupportedAppUsage public static Set getLevelLocales(Context context, Set ignorables, LocaleInfo parent, boolean translatedOnly) { fillCache(context); @@ -365,6 +373,7 @@ public class LocaleStore { return result; } + @UnsupportedAppUsage public static LocaleInfo getLocaleInfo(Locale locale) { String id = locale.toLanguageTag(); LocaleInfo result; diff --git a/core/java/com/android/internal/app/NetInitiatedActivity.java b/core/java/com/android/internal/app/NetInitiatedActivity.java index d3bae16d03a7b3eefb21de02abcc389f61ad7b8e..9a802a9c0fa9efe81802a134dc74e17516bf3842 100644 --- a/core/java/com/android/internal/app/NetInitiatedActivity.java +++ b/core/java/com/android/internal/app/NetInitiatedActivity.java @@ -16,6 +16,7 @@ package com.android.internal.app; +import android.annotation.UnsupportedAppUsage; import android.app.AlertDialog; import android.content.BroadcastReceiver; import android.content.Context; @@ -141,6 +142,7 @@ public class NetInitiatedActivity extends AlertActivity implements DialogInterfa locationManager.sendNiResponse(notificationId, response); } + @UnsupportedAppUsage private void handleNIVerify(Intent intent) { int notifId = intent.getIntExtra(GpsNetInitiatedHandler.NI_INTENT_KEY_NOTIF_ID, -1); notificationId = notifId; diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java index 12942abc81597196faee02f404d39404016233ad..84a1bed36e553017ff6ff94de1147aa377cb9335 100644 --- a/core/java/com/android/internal/app/ResolverActivity.java +++ b/core/java/com/android/internal/app/ResolverActivity.java @@ -21,6 +21,7 @@ import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import android.annotation.Nullable; import android.annotation.StringRes; import android.annotation.UiThread; +import android.annotation.UnsupportedAppUsage; import android.app.Activity; import android.app.ActivityManager; import android.app.ActivityTaskManager; @@ -42,7 +43,7 @@ import android.content.pm.ResolveInfo; import android.content.pm.UserInfo; import android.content.res.Configuration; import android.content.res.Resources; -import android.graphics.Color; +import android.graphics.Bitmap; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.net.Uri; @@ -99,6 +100,7 @@ public class ResolverActivity extends Activity { // Temporary flag for new chooser delegate behavior. boolean mEnableChooserDelegate = true; + @UnsupportedAppUsage protected ResolveListAdapter mAdapter; private boolean mSafeForwardingMode; protected AbsListView mAdapterView; @@ -121,6 +123,7 @@ public class ResolverActivity extends Activity { // Whether or not this activity supports choosing a default handler for the intent. private boolean mSupportsAlwaysUseOption; protected ResolverDrawerLayout mResolverDrawerLayout; + @UnsupportedAppUsage protected PackageManager mPm; protected int mLaunchedFromUid; @@ -133,8 +136,6 @@ public class ResolverActivity extends Activity { /** See {@link #setRetainInOnStop}. */ private boolean mRetainInOnStop; - SimpleIconFactory mSimpleIconFactory; - private final PackageMonitor mPackageMonitor = new PackageMonitor() { @Override public void onSomePackagesChanged() { mAdapter.handlePackagesChanged(); @@ -259,6 +260,7 @@ public class ResolverActivity extends Activity { * Compatibility version for other bundled services that use this overload without * a default title resource */ + @UnsupportedAppUsage protected void onCreate(Bundle savedInstanceState, Intent intent, CharSequence title, Intent[] initialIntents, List rList, boolean supportsAlwaysUseOption) { @@ -311,11 +313,6 @@ public class ResolverActivity extends Activity { // as to mitigate Intent Capturing vulnerability mSupportsAlwaysUseOption = supportsAlwaysUseOption && !mUseLayoutForBrowsables; - final int iconSize = getResources().getDimensionPixelSize(R.dimen.resolver_icon_size); - final int badgeSize = getResources().getDimensionPixelSize(R.dimen.resolver_badge_size); - mSimpleIconFactory = new SimpleIconFactory(this, mIconDpi, iconSize, badgeSize); - mSimpleIconFactory.setWrapperBackgroundColor(Color.WHITE); - if (configureContentView(mIntents, initialIntents, rList)) { return; } @@ -500,64 +497,150 @@ public class ResolverActivity extends Activity { } } - @Nullable - Drawable getIcon(Resources res, int resId) { - Drawable result; - try { - result = res.getDrawableForDensity(resId, mIconDpi); - } catch (Resources.NotFoundException e) { - result = null; - } - - return result; - } /** - * Loads the icon for the provided ResolveInfo. Defaults to using the application icon over + * Loads the icon for the provided ApplicationInfo. Defaults to using the application icon over * any IntentFilter or Activity icon to increase user understanding, with an exception for * applications that hold the right permission. Always attempts to use icon resources over * PackageManager loading mechanisms so badging can be done by iconloader. */ - Drawable loadIconForResolveInfo(ResolveInfo ri) { - Drawable dr = null; + private abstract class TargetPresentationGetter { + @Nullable abstract Drawable getIconSubstitute(); + @Nullable abstract String getAppSubLabel(); - // Allow for app icon override given the right permission - if (PackageManager.PERMISSION_GRANTED == mPm.checkPermission( - android.Manifest.permission.SUBSTITUTE_SHARE_TARGET_APP_NAME_AND_ICON, - ri.activityInfo.applicationInfo.packageName)) { - try { - if (ri.resolvePackageName != null && ri.icon != 0) { - dr = getIcon(mPm.getResourcesForApplication(ri.resolvePackageName), ri.icon); - } - if (dr == null) { - final int iconRes = ri.getIconResource(); - if (iconRes != 0) { - dr = getIcon(mPm.getResourcesForApplication(ri.activityInfo.packageName), - iconRes); + private final ApplicationInfo mAi; + private final boolean mHasSubstitutePermission; + + TargetPresentationGetter(ApplicationInfo ai) { + mAi = ai; + mHasSubstitutePermission = PackageManager.PERMISSION_GRANTED == mPm.checkPermission( + android.Manifest.permission.SUBSTITUTE_SHARE_TARGET_APP_NAME_AND_ICON, + mAi.packageName); + } + + Drawable getIcon() { + return new BitmapDrawable(getResources(), getIconBitmap()); + } + + Bitmap getIconBitmap() { + Drawable dr = null; + if (mHasSubstitutePermission) { + dr = getIconSubstitute(); + } + + if (dr == null) { + try { + if (mAi.icon != 0) { + dr = loadIconFromResource(mPm.getResourcesForApplication(mAi), mAi.icon); } + } catch (NameNotFoundException ignore) { + } + } + + // Fall back to ApplicationInfo#loadIcon if nothing has been loaded + if (dr == null) { + dr = mAi.loadIcon(mPm); + } + + SimpleIconFactory sif = SimpleIconFactory.obtain(ResolverActivity.this); + Bitmap icon = sif.createUserBadgedIconBitmap(dr, Process.myUserHandle()); + sif.recycle(); + + return icon; + } + + String getLabel() { + String label = null; + // Apps with the substitute permission will always show the sublabel as their label + if (mHasSubstitutePermission) { + label = getAppSubLabel(); + } + + if (label == null) { + label = (String) mAi.loadLabel(mPm); + } + + return label; + } + + String getSubLabel() { + // Apps with the substitute permission will never have a sublabel + if (mHasSubstitutePermission) return null; + return getAppSubLabel(); + } + + @Nullable + protected Drawable loadIconFromResource(Resources res, int resId) { + return res.getDrawableForDensity(resId, mIconDpi); + } + + } + + protected class ResolveInfoPresentationGetter extends TargetPresentationGetter { + + private final ResolveInfo mRi; + + ResolveInfoPresentationGetter(ResolveInfo ri) { + super(ri.activityInfo.applicationInfo); + mRi = ri; + } + + @Override + Drawable getIconSubstitute() { + Drawable dr = null; + try { + // Do not use ResolveInfo#getIconResource() as it defaults to the app + if (mRi.resolvePackageName != null && mRi.icon != 0) { + dr = loadIconFromResource( + mPm.getResourcesForApplication(mRi.resolvePackageName), mRi.icon); } } catch (NameNotFoundException e) { Log.e(TAG, "SUBSTITUTE_SHARE_TARGET_APP_NAME_AND_ICON permission granted but " + "couldn't find resources for package", e); } + + return dr; + } + + @Override + String getAppSubLabel() { + return (String) mRi.loadLabel(mPm); + } + } + + protected class ActivityInfoPresentationGetter extends TargetPresentationGetter { + private final ActivityInfo mActivityInfo; + protected ActivityInfoPresentationGetter(ActivityInfo activityInfo) { + super(activityInfo.applicationInfo); + mActivityInfo = activityInfo; } - // Use app icons for better user association - if (dr == null) { + @Override + Drawable getIconSubstitute() { + Drawable dr = null; try { - dr = getIcon(mPm.getResourcesForApplication(ri.activityInfo.applicationInfo), - ri.activityInfo.applicationInfo.icon); - } catch (NameNotFoundException ignore) { + // Do not use ActivityInfo#getIconResource() as it defaults to the app + if (mActivityInfo.icon != 0) { + dr = loadIconFromResource( + mPm.getResourcesForApplication(mActivityInfo.applicationInfo), + mActivityInfo.icon); + } + } catch (NameNotFoundException e) { + Log.e(TAG, "SUBSTITUTE_SHARE_TARGET_APP_NAME_AND_ICON permission granted but " + + "couldn't find resources for package", e); } + + return dr; } - // Fall back to ApplicationInfo#loadIcon if nothing has been loaded - if (dr == null) { - dr = ri.activityInfo.applicationInfo.loadIcon(mPm); + @Override + String getAppSubLabel() { + return (String) mActivityInfo.loadLabel(mPm); } + } - return new BitmapDrawable(this.getResources(), - mSimpleIconFactory.createUserBadgedIconBitmap(dr, Process.myUserHandle())); + Drawable loadIconForResolveInfo(ResolveInfo ri) { + return (new ResolveInfoPresentationGetter(ri)).getIcon(); } @Override @@ -1250,33 +1333,6 @@ public class ResolverActivity extends Activity { return mDisplayIcon; } - public Drawable getBadgeIcon() { - // We only expose a badge if we have extended info. - // The badge is a higher-priority disambiguation signal - // but we don't need one if we wouldn't show extended info at all. - if (TextUtils.isEmpty(getExtendedInfo())) { - return null; - } - - if (mBadge == null && mResolveInfo != null && mResolveInfo.activityInfo != null - && mResolveInfo.activityInfo.applicationInfo != null) { - if (mResolveInfo.activityInfo.icon == 0 || mResolveInfo.activityInfo.icon - == mResolveInfo.activityInfo.applicationInfo.icon) { - // Badging an icon with exactly the same icon is silly. - // If the activityInfo icon resid is 0 it will fall back - // to the application's icon, making it a match. - return null; - } - mBadge = mResolveInfo.activityInfo.applicationInfo.loadIcon(mPm); - } - return mBadge; - } - - @Override - public CharSequence getBadgeContentDescription() { - return null; - } - @Override public TargetInfo cloneFilledIn(Intent fillInIntent, int flags) { return new DisplayResolveInfo(this, fillInIntent, flags); @@ -1413,20 +1469,10 @@ public class ResolverActivity extends Activity { CharSequence getExtendedInfo(); /** - * @return The drawable that should be used to represent this target + * @return The drawable that should be used to represent this target including badge */ Drawable getDisplayIcon(); - /** - * @return The (small) icon to badge the target with - */ - Drawable getBadgeIcon(); - - /** - * @return The content description for the badge icon - */ - CharSequence getBadgeContentDescription(); - /** * Clone this target with the given fill-in information. */ @@ -1963,16 +2009,6 @@ public class ResolverActivity extends Activity { new LoadAdapterIconTask((DisplayResolveInfo) info).execute(); } holder.icon.setImageDrawable(info.getDisplayIcon()); - if (holder.badge != null) { - final Drawable badge = info.getBadgeIcon(); - if (badge != null) { - holder.badge.setImageDrawable(badge); - holder.badge.setContentDescription(info.getBadgeContentDescription()); - holder.badge.setVisibility(View.VISIBLE); - } else { - holder.badge.setVisibility(View.GONE); - } - } } } @@ -2027,13 +2063,11 @@ public class ResolverActivity extends Activity { public TextView text; public TextView text2; public ImageView icon; - public ImageView badge; public ViewHolder(View view) { text = (TextView) view.findViewById(com.android.internal.R.id.text1); text2 = (TextView) view.findViewById(com.android.internal.R.id.text2); icon = (ImageView) view.findViewById(R.id.icon); - badge = (ImageView) view.findViewById(R.id.target_badge); } } diff --git a/core/java/com/android/internal/app/ResolverListController.java b/core/java/com/android/internal/app/ResolverListController.java index f48102a9fcd4121efab02a34d7ba47dc84e77d39..156baf03f5636cf3664a878a9e767552770a132d 100644 --- a/core/java/com/android/internal/app/ResolverListController.java +++ b/core/java/com/android/internal/app/ResolverListController.java @@ -55,7 +55,7 @@ public class ResolverListController { private static final String TAG = "ResolverListController"; private static final boolean DEBUG = false; - private ResolverComparator mResolverComparator; + private AbstractResolverComparator mResolverComparator; private boolean isComputed = false; public ResolverListController( @@ -70,7 +70,8 @@ public class ResolverListController { mTargetIntent = targetIntent; mReferrerPackage = referrerPackage; mResolverComparator = - new ResolverComparator(mContext, mTargetIntent, mReferrerPackage, null); + new ResolverRankerServiceResolverComparator( + mContext, mTargetIntent, mReferrerPackage, null); } @VisibleForTesting @@ -221,7 +222,7 @@ public class ResolverListController { return listToReturn; } - private class ComputeCallback implements ResolverComparator.AfterCompute { + private class ComputeCallback implements AbstractResolverComparator.AfterCompute { private CountDownLatch mFinishComputeSignal; diff --git a/core/java/com/android/internal/app/ResolverComparator.java b/core/java/com/android/internal/app/ResolverRankerServiceResolverComparator.java similarity index 97% rename from core/java/com/android/internal/app/ResolverComparator.java rename to core/java/com/android/internal/app/ResolverRankerServiceResolverComparator.java index b9f67e6e0521100c71af92fbd0aff8864bb33c9f..a88a80f199a472ff7b326db9375ceeb12221a4e0 100644 --- a/core/java/com/android/internal/app/ResolverComparator.java +++ b/core/java/com/android/internal/app/ResolverRankerServiceResolverComparator.java @@ -46,7 +46,6 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import java.text.Collator; import java.util.ArrayList; -import java.util.Comparator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -54,10 +53,10 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; /** - * Ranks and compares packages based on usage stats. + * Ranks and compares packages based on usage stats and uses the {@link ResolverRankerService}. */ -class ResolverComparator implements Comparator { - private static final String TAG = "ResolverComparator"; +class ResolverRankerServiceResolverComparator extends AbstractResolverComparator { + private static final String TAG = "RRSResolverComparator"; private static final boolean DEBUG = false; @@ -100,7 +99,6 @@ class ResolverComparator implements Comparator { private ComponentName mRankerServiceName; private IResolverRankerService mRanker; private ResolverRankerServiceConnection mConnection; - private AfterCompute mAfterCompute; private Context mContext; private CountDownLatch mConnectSignal; @@ -155,12 +153,8 @@ class ResolverComparator implements Comparator { } }; - public interface AfterCompute { - public void afterCompute (); - } - - public ResolverComparator(Context context, Intent intent, String referrerPackage, - AfterCompute afterCompute) { + public ResolverRankerServiceResolverComparator(Context context, Intent intent, + String referrerPackage, AfterCompute afterCompute) { mCollator = Collator.getInstance(context.getResources().getConfiguration().locale); String scheme = intent.getScheme(); mHttp = "http".equals(scheme) || "https".equals(scheme); @@ -185,7 +179,7 @@ class ResolverComparator implements Comparator { } // get annotations of content from intent. - public void getContentAnnotations(Intent intent) { + private void getContentAnnotations(Intent intent) { ArrayList annotations = intent.getStringArrayListExtra( Intent.EXTRA_CONTENT_ANNOTATIONS); if (annotations != null) { @@ -200,11 +194,8 @@ class ResolverComparator implements Comparator { } } - public void setCallBack(AfterCompute afterCompute) { - mAfterCompute = afterCompute; - } - // compute features for each target according to usage stats of targets. + @Override public void compute(List targets) { reset(); @@ -349,6 +340,7 @@ class ResolverComparator implements Comparator { return mCollator.compare(sa.toString().trim(), sb.toString().trim()); } + @Override public float getScore(ComponentName name) { final ResolverTarget target = mTargetsDict.get(name); if (target != null) { @@ -357,6 +349,7 @@ class ResolverComparator implements Comparator { return 0; } + @Override public void updateChooserCounts(String packageName, int userId, String action) { if (mUsm != null) { mUsm.reportChooserSelection(packageName, userId, mContentType, mAnnotations, action); @@ -364,6 +357,7 @@ class ResolverComparator implements Comparator { } // update ranking model when the connection to it is valid. + @Override public void updateModel(ComponentName componentName) { synchronized (mLock) { if (mRanker != null) { @@ -397,6 +391,7 @@ class ResolverComparator implements Comparator { } // unbind the service and clear unhandled messges. + @Override public void destroy() { mHandler.removeMessages(RESOLVER_RANKER_SERVICE_RESULT); mHandler.removeMessages(RESOLVER_RANKER_RESULT_TIMEOUT); @@ -478,8 +473,8 @@ class ResolverComparator implements Comparator { if (!ResolverRankerService.BIND_PERMISSION.equals(perm)) { Log.w(TAG, "ResolverRankerService " + componentName + " does not require" + " permission " + ResolverRankerService.BIND_PERMISSION - + " - this service will not be queried for ResolverComparator." - + " add android:permission=\"" + + " - this service will not be queried for " + + "ResolverRankerServiceResolverComparator. add android:permission=\"" + ResolverRankerService.BIND_PERMISSION + "\"" + " to the tag for " + componentName + " in the manifest."); @@ -490,7 +485,8 @@ class ResolverComparator implements Comparator { resolveInfo.serviceInfo.packageName)) { Log.w(TAG, "ResolverRankerService " + componentName + " does not hold" + " permission " + ResolverRankerService.HOLD_PERMISSION - + " - this service will not be queried for ResolverComparator."); + + " - this service will not be queried for " + + "ResolverRankerServiceResolverComparator."); continue; } } catch (NameNotFoundException e) { diff --git a/core/java/com/android/internal/app/SimpleIconFactory.java b/core/java/com/android/internal/app/SimpleIconFactory.java index eb1530e97b7f17550732da6137bab41d1546754b..a85485d3969bbe4522150512cb7b2ec4efb6b958 100644 --- a/core/java/com/android/internal/app/SimpleIconFactory.java +++ b/core/java/com/android/internal/app/SimpleIconFactory.java @@ -16,11 +16,13 @@ package com.android.internal.app; +import static android.content.Context.ACTIVITY_SERVICE; import static android.graphics.Paint.DITHER_FLAG; import static android.graphics.Paint.FILTER_BITMAP_FLAG; import android.annotation.NonNull; import android.annotation.Nullable; +import android.app.ActivityManager; import android.content.Context; import android.content.pm.PackageManager; import android.content.res.Resources; @@ -42,6 +44,7 @@ import android.graphics.drawable.DrawableWrapper; import android.os.Process; import android.os.UserHandle; import android.util.AttributeSet; +import android.util.Pools.SynchronizedPool; import com.android.internal.R; @@ -58,6 +61,9 @@ import java.nio.ByteBuffer; @Deprecated public class SimpleIconFactory { + private static final SynchronizedPool sPool = + new SynchronizedPool<>(Runtime.getRuntime().availableProcessors()); + private static final int DEFAULT_WRAPPER_BACKGROUND = Color.WHITE; private static final float BLUR_FACTOR = 0.5f / 48; @@ -73,11 +79,46 @@ public class SimpleIconFactory { private Drawable mWrapperIcon; private final Rect mOldBounds = new Rect(); + /** + * Obtain a SimpleIconFactory from a pool objects. + * + * @deprecated Do not use, functionality will be replaced by iconloader lib eventually. + */ + @Deprecated + public static SimpleIconFactory obtain(Context ctx) { + SimpleIconFactory instance = sPool.acquire(); + if (instance == null) { + final ActivityManager am = (ActivityManager) ctx.getSystemService(ACTIVITY_SERVICE); + final int iconDpi = (am == null) ? 0 : am.getLauncherLargeIconDensity(); + + final Resources r = ctx.getResources(); + final int iconSize = r.getDimensionPixelSize(R.dimen.resolver_icon_size); + final int badgeSize = r.getDimensionPixelSize(R.dimen.resolver_badge_size); + + instance = new SimpleIconFactory(ctx, iconDpi, iconSize, badgeSize); + instance.setWrapperBackgroundColor(Color.WHITE); + } + + return instance; + } + + /** + * Recycles the SimpleIconFactory so others may use it. + * + * @deprecated Do not use, functionality will be replaced by iconloader lib eventually. + */ + @Deprecated + public void recycle() { + // Return to default background color + setWrapperBackgroundColor(Color.WHITE); + sPool.release(this); + } + /** * @deprecated Do not use, functionality will be replaced by iconloader lib eventually. */ @Deprecated - SimpleIconFactory(Context context, int fillResIconDpi, int iconBitmapSize, + private SimpleIconFactory(Context context, int fillResIconDpi, int iconBitmapSize, int badgeBitmapSize) { mContext = context.getApplicationContext(); mPm = mContext.getPackageManager(); @@ -170,7 +211,7 @@ public class SimpleIconFactory { * @deprecated Do not use, functionality will be replaced by iconloader lib eventually. */ @Deprecated - public Bitmap createAppBadgedIconBitmap(@Nullable Drawable icon, Bitmap renderedAppIcon) { + Bitmap createAppBadgedIconBitmap(@Nullable Drawable icon, Bitmap renderedAppIcon) { // Flatten the passed in icon float [] scale = new float[1]; diff --git a/core/java/com/android/internal/app/WindowDecorActionBar.java b/core/java/com/android/internal/app/WindowDecorActionBar.java index 119f30df894606a02e5bfdcae2f67f58a380b334..e71ee66c677cdca4b4673f45e56536e34e529fe2 100644 --- a/core/java/com/android/internal/app/WindowDecorActionBar.java +++ b/core/java/com/android/internal/app/WindowDecorActionBar.java @@ -84,6 +84,7 @@ public class WindowDecorActionBar extends ActionBar implements private ActionBarContextView mContextView; private ActionBarContainer mSplitView; private View mContentView; + @UnsupportedAppUsage private ScrollingTabContainerView mTabScrollView; private ArrayList mTabs = new ArrayList(); @@ -331,6 +332,7 @@ public class WindowDecorActionBar extends ActionBar implements * * @param enabled true to animate, false to not animate. */ + @UnsupportedAppUsage public void setShowHideAnimationEnabled(boolean enabled) { mShowHideAnimationEnabled = enabled; if (!enabled && mCurrentShowAnim != null) { @@ -1147,6 +1149,7 @@ public class WindowDecorActionBar extends ActionBar implements * @hide */ public class TabImpl extends ActionBar.Tab { + @UnsupportedAppUsage private ActionBar.TabListener mCallback; private Object mTag; private Drawable mIcon; diff --git a/core/java/com/android/internal/backup/IBackupTransport.aidl b/core/java/com/android/internal/backup/IBackupTransport.aidl index f8117a7e92608145afed6907c138c2f64468a619..c9baf004d798e7d81978acb382c3d8ea234d4ff5 100644 --- a/core/java/com/android/internal/backup/IBackupTransport.aidl +++ b/core/java/com/android/internal/backup/IBackupTransport.aidl @@ -79,14 +79,14 @@ interface IBackupTransport { Intent dataManagementIntent(); /** - * On demand, supply a short string that can be shown to the user as the label - * on an overflow menu item used to invoked the data management UI. + * On demand, supply a short {@link CharSequence} that can be shown to the user as the label on + * an overflow menu item used to invoke the data management UI. * - * @return A string to be used as the label for the transport's data management + * @return A {@link CharSequence} to be used as the label for the transport's data management * affordance. If the transport supplies a data management intent, this * method must not return {@code null}. */ - String dataManagementLabel(); + CharSequence dataManagementIntentLabel(); /** * Ask the transport where, on local device storage, to keep backup state blobs. diff --git a/core/java/com/android/internal/database/SortCursor.java b/core/java/com/android/internal/database/SortCursor.java index 00255128972c1d75ed77e568dff0e4180fb84ef5..7fe809ee319b7b070050022efd1f985e1e3dd1ee 100644 --- a/core/java/com/android/internal/database/SortCursor.java +++ b/core/java/com/android/internal/database/SortCursor.java @@ -16,6 +16,7 @@ package com.android.internal.database; +import android.annotation.UnsupportedAppUsage; import android.database.AbstractCursor; import android.database.Cursor; import android.database.DataSetObserver; @@ -28,7 +29,9 @@ import android.util.Log; public class SortCursor extends AbstractCursor { private static final String TAG = "SortCursor"; + @UnsupportedAppUsage private Cursor mCursor; // updated in onMove + @UnsupportedAppUsage private Cursor[] mCursors; private int [] mSortColumns; private final int ROWCACHESIZE = 64; @@ -52,6 +55,7 @@ public class SortCursor extends AbstractCursor } }; + @UnsupportedAppUsage public SortCursor(Cursor[] cursors, String sortcolumn) { mCursors = cursors; diff --git a/core/java/com/android/internal/http/HttpDateTime.java b/core/java/com/android/internal/http/HttpDateTime.java index 8ebd4aaf1ac0d10a55a9a789c9b44eb32160c7b8..f7706e310952bfe8d6acf6c36d25523db28ec792 100644 --- a/core/java/com/android/internal/http/HttpDateTime.java +++ b/core/java/com/android/internal/http/HttpDateTime.java @@ -16,6 +16,7 @@ package com.android.internal.http; +import android.annotation.UnsupportedAppUsage; import android.text.format.Time; import java.util.Calendar; @@ -82,6 +83,7 @@ public final class HttpDateTime { int second; } + @UnsupportedAppUsage public static long parse(String timeString) throws IllegalArgumentException { diff --git a/core/java/com/android/internal/infra/AbstractRemoteService.java b/core/java/com/android/internal/infra/AbstractRemoteService.java index 5c144d3b5752a4c897ac6ec0db1ecf7d845c633a..0a83fcc6db61dfd0880ae7b8ec4f77139794ba5f 100644 --- a/core/java/com/android/internal/infra/AbstractRemoteService.java +++ b/core/java/com/android/internal/infra/AbstractRemoteService.java @@ -481,7 +481,11 @@ public abstract class AbstractRemoteService asUsers, long rawRealtimeUs, long rawUptimeUs) { + if (statsType != BatteryStats.STATS_SINCE_CHARGED) { + Log.w(TAG, "refreshStats called for statsType " + statsType + " but only " + + "STATS_SINCE_CHARGED is supported. Using STATS_SINCE_CHARGED instead."); + } + // Initialize mStats if necessary. getStats(); diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index 8679dcba2f80397164d13f3718bb203a1193d5fc..1fc76351254be437a7ddf83faca2f96b015aa68e 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -145,7 +145,7 @@ public class BatteryStatsImpl extends BatteryStats { private static final int MAGIC = 0xBA757475; // 'BATSTATS' // Current on-disk Parcel version - static final int VERSION = 185 + (USE_OLD_HISTORY ? 1000 : 0); + static final int VERSION = 186 + (USE_OLD_HISTORY ? 1000 : 0); // The maximum number of names wakelocks we will keep track of // per uid; once the limit is reached, we batch the remaining wakelocks @@ -991,8 +991,6 @@ public class BatteryStatsImpl extends BatteryStats { private int mPhoneSimStateRaw = -1; private int mNumConnectivityChange; - private int mLoadedNumConnectivityChange; - private int mUnpluggedNumConnectivityChange; private int mEstimatedBatteryCapacity = -1; @@ -1225,27 +1223,11 @@ public class BatteryStatsImpl extends BatteryStats { } public long computeUptime(long curTime, int which) { - switch (which) { - case STATS_SINCE_CHARGED: - return mUptime + getUptime(curTime); - case STATS_CURRENT: - return getUptime(curTime); - case STATS_SINCE_UNPLUGGED: - return getUptime(curTime) - mUnpluggedUptime; - } - return 0; + return mUptime + getUptime(curTime); } public long computeRealtime(long curTime, int which) { - switch (which) { - case STATS_SINCE_CHARGED: - return mRealtime + getRealtime(curTime); - case STATS_CURRENT: - return getRealtime(curTime); - case STATS_SINCE_UNPLUGGED: - return getRealtime(curTime) - mUnpluggedRealtime; - } - return 0; + return mRealtime + getRealtime(curTime); } public long getUptime(long curTime) { @@ -1352,16 +1334,10 @@ public class BatteryStatsImpl extends BatteryStats { @UnsupportedAppUsage final AtomicInteger mCount = new AtomicInteger(); final TimeBase mTimeBase; - int mLoadedCount; - int mUnpluggedCount; - int mPluggedCount; public Counter(TimeBase timeBase, Parcel in) { mTimeBase = timeBase; - mPluggedCount = in.readInt(); - mCount.set(mPluggedCount); - mLoadedCount = in.readInt(); - mUnpluggedCount = in.readInt(); + mCount.set(in.readInt()); timeBase.add(this); } @@ -1372,18 +1348,14 @@ public class BatteryStatsImpl extends BatteryStats { public void writeToParcel(Parcel out) { out.writeInt(mCount.get()); - out.writeInt(mLoadedCount); - out.writeInt(mUnpluggedCount); } @Override public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) { - mUnpluggedCount = mPluggedCount; } @Override public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { - mPluggedCount = mCount.get(); } /** @@ -1417,21 +1389,11 @@ public class BatteryStatsImpl extends BatteryStats { @Override public int getCountLocked(int which) { - int val = mCount.get(); - if (which == STATS_SINCE_UNPLUGGED) { - val -= mUnpluggedCount; - } else if (which != STATS_SINCE_CHARGED) { - val -= mLoadedCount; - } - - return val; + return mCount.get(); } public void logState(Printer pw, String prefix) { - pw.println(prefix + "mCount=" + mCount.get() - + " mLoadedCount=" + mLoadedCount - + " mUnpluggedCount=" + mUnpluggedCount - + " mPluggedCount=" + mPluggedCount); + pw.println(prefix + "mCount=" + mCount.get()); } @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) @@ -1453,7 +1415,6 @@ public class BatteryStatsImpl extends BatteryStats { @Override public boolean reset(boolean detachIfReset) { mCount.set(0); - mLoadedCount = mPluggedCount = mUnpluggedCount = 0; if (detachIfReset) { detach(); } @@ -1467,15 +1428,12 @@ public class BatteryStatsImpl extends BatteryStats { @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public void writeSummaryFromParcelLocked(Parcel out) { - int count = mCount.get(); - out.writeInt(count); + out.writeInt(mCount.get()); } @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public void readSummaryFromParcelLocked(Parcel in) { - mLoadedCount = in.readInt(); - mCount.set(mLoadedCount); - mUnpluggedCount = mPluggedCount = mLoadedCount; + mCount.set(in.readInt()); } } @@ -1483,14 +1441,10 @@ public class BatteryStatsImpl extends BatteryStats { public static class LongSamplingCounterArray extends LongCounterArray implements TimeBaseObs { final TimeBase mTimeBase; public long[] mCounts; - public long[] mLoadedCounts; - public long[] mUnpluggedCounts; private LongSamplingCounterArray(TimeBase timeBase, Parcel in) { mTimeBase = timeBase; mCounts = in.createLongArray(); - mLoadedCounts = in.createLongArray(); - mUnpluggedCounts = in.createLongArray(); timeBase.add(this); } @@ -1501,13 +1455,10 @@ public class BatteryStatsImpl extends BatteryStats { private void writeToParcel(Parcel out) { out.writeLongArray(mCounts); - out.writeLongArray(mLoadedCounts); - out.writeLongArray(mUnpluggedCounts); } @Override public void onTimeStarted(long elapsedRealTime, long baseUptime, long baseRealtime) { - mUnpluggedCounts = copyArray(mCounts, mUnpluggedCounts); } @Override @@ -1516,20 +1467,12 @@ public class BatteryStatsImpl extends BatteryStats { @Override public long[] getCountsLocked(int which) { - long[] val = copyArray(mCounts, null); - if (which == STATS_SINCE_UNPLUGGED) { - subtract(val, mUnpluggedCounts); - } else if (which != STATS_SINCE_CHARGED) { - subtract(val, mLoadedCounts); - } - return val; + return mCounts == null ? null : Arrays.copyOf(mCounts, mCounts.length); } @Override public void logState(Printer pw, String prefix) { - pw.println(prefix + "mCounts=" + Arrays.toString(mCounts) - + " mLoadedCounts=" + Arrays.toString(mLoadedCounts) - + " mUnpluggedCounts=" + Arrays.toString(mUnpluggedCounts)); + pw.println(prefix + "mCounts=" + Arrays.toString(mCounts)); } public void addCountLocked(long[] counts) { @@ -1559,9 +1502,9 @@ public class BatteryStatsImpl extends BatteryStats { */ @Override public boolean reset(boolean detachIfReset) { - fillArray(mCounts, 0); - fillArray(mLoadedCounts, 0); - fillArray(mUnpluggedCounts, 0); + if (mCounts != null) { + Arrays.fill(mCounts, 0); + } if (detachIfReset) { detach(); } @@ -1579,8 +1522,6 @@ public class BatteryStatsImpl extends BatteryStats { private void readSummaryFromParcelLocked(Parcel in) { mCounts = in.createLongArray(); - mLoadedCounts = copyArray(mCounts, mLoadedCounts); - mUnpluggedCounts = copyArray(mCounts, mUnpluggedCounts); } public static void writeToParcel(Parcel out, LongSamplingCounterArray counterArray) { @@ -1621,49 +1562,16 @@ public class BatteryStatsImpl extends BatteryStats { return null; } } - - private static void fillArray(long[] a, long val) { - if (a != null) { - Arrays.fill(a, val); - } - } - - private static void subtract(@NonNull long[] val, long[] toSubtract) { - if (toSubtract == null) { - return; - } - for (int i = 0; i < val.length; i++) { - val[i] -= toSubtract[i]; - } - } - - private static long[] copyArray(long[] src, long[] dest) { - if (src == null) { - return null; - } else { - if (dest == null) { - dest = new long[src.length]; - } - System.arraycopy(src, 0, dest, 0, src.length); - return dest; - } - } } @VisibleForTesting public static class LongSamplingCounter extends LongCounter implements TimeBaseObs { final TimeBase mTimeBase; - public long mCount; - public long mCurrentCount; - public long mLoadedCount; - public long mUnpluggedCount; + private long mCount; public LongSamplingCounter(TimeBase timeBase, Parcel in) { mTimeBase = timeBase; mCount = in.readLong(); - mCurrentCount = in.readLong(); - mLoadedCount = in.readLong(); - mUnpluggedCount = in.readLong(); timeBase.add(this); } @@ -1674,14 +1582,10 @@ public class BatteryStatsImpl extends BatteryStats { public void writeToParcel(Parcel out) { out.writeLong(mCount); - out.writeLong(mCurrentCount); - out.writeLong(mLoadedCount); - out.writeLong(mUnpluggedCount); } @Override public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) { - mUnpluggedCount = mCount; } @Override @@ -1689,43 +1593,22 @@ public class BatteryStatsImpl extends BatteryStats { } public long getCountLocked(int which) { - long val = mCount; - if (which == STATS_SINCE_UNPLUGGED) { - val -= mUnpluggedCount; - } else if (which != STATS_SINCE_CHARGED) { - val -= mLoadedCount; - } - return val; + return mCount; } @Override public void logState(Printer pw, String prefix) { - pw.println(prefix + "mCount=" + mCount - + " mCurrentCount=" + mCurrentCount - + " mLoadedCount=" + mLoadedCount - + " mUnpluggedCount=" + mUnpluggedCount); + pw.println(prefix + "mCount=" + mCount); } public void addCountLocked(long count) { - update(mCurrentCount + count, mTimeBase.isRunning()); + addCountLocked(count, mTimeBase.isRunning()); } public void addCountLocked(long count, boolean isRunning) { - update(mCurrentCount + count, isRunning); - } - - public void update(long count) { - update(count, mTimeBase.isRunning()); - } - - public void update(long count, boolean isRunning) { - if (count < mCurrentCount) { - mCurrentCount = 0; - } if (isRunning) { - mCount += count - mCurrentCount; + mCount += count; } - mCurrentCount = count; } /** @@ -1734,7 +1617,6 @@ public class BatteryStatsImpl extends BatteryStats { @Override public boolean reset(boolean detachIfReset) { mCount = 0; - mLoadedCount = mUnpluggedCount = 0; if (detachIfReset) { detach(); } @@ -1751,7 +1633,7 @@ public class BatteryStatsImpl extends BatteryStats { } public void readSummaryFromParcelLocked(Parcel in) { - mCount = mUnpluggedCount= mLoadedCount = in.readLong(); + mCount = in.readLong(); } } @@ -1764,9 +1646,6 @@ public class BatteryStatsImpl extends BatteryStats { protected final TimeBase mTimeBase; protected int mCount; - protected int mLoadedCount; - protected int mLastCount; - protected int mUnpluggedCount; // Times are in microseconds for better accuracy when dividing by the // lock count, and are in "battery realtime" units. @@ -1778,25 +1657,6 @@ public class BatteryStatsImpl extends BatteryStats { */ protected long mTotalTime; - /** - * The total time we loaded for the previous runs. Subtract this from - * mTotalTime to find the time for the current run of the system. - */ - protected long mLoadedTime; - - /** - * The run time of the last run of the system, as loaded from the - * saved data. - */ - protected long mLastTime; - - /** - * The value of mTotalTime when unplug() was last called. Subtract - * this from mTotalTime to find the time since the last unplug from - * power. - */ - protected long mUnpluggedTime; - /** * The total time this timer has been running until the latest mark has been set. * Subtract this from mTotalTime to get the time spent running since the mark was set. @@ -1815,13 +1675,7 @@ public class BatteryStatsImpl extends BatteryStats { mTimeBase = timeBase; mCount = in.readInt(); - mLoadedCount = in.readInt(); - mLastCount = 0; - mUnpluggedCount = in.readInt(); mTotalTime = in.readLong(); - mLoadedTime = in.readLong(); - mLastTime = 0; - mUnpluggedTime = in.readLong(); mTimeBeforeMark = in.readLong(); timeBase.add(this); if (DEBUG) Log.i(TAG, "**** READ TIMER #" + mType + ": mTotalTime=" + mTotalTime); @@ -1834,6 +1688,16 @@ public class BatteryStatsImpl extends BatteryStats { timeBase.add(this); } + public void writeToParcel(Parcel out, long elapsedRealtimeUs) { + if (DEBUG) { + Log.i(TAG, "**** WRITING TIMER #" + mType + ": mTotalTime=" + + computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs))); + } + out.writeInt(computeCurrentCountLocked()); + out.writeLong(computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs))); + out.writeLong(mTimeBeforeMark); + } + protected abstract long computeRunTimeLocked(long curBatteryRealtime); protected abstract int computeCurrentCountLocked(); @@ -1844,8 +1708,8 @@ public class BatteryStatsImpl extends BatteryStats { */ @Override public boolean reset(boolean detachIfReset) { - mTotalTime = mLoadedTime = mLastTime = mTimeBeforeMark = 0; - mCount = mLoadedCount = mLastCount = 0; + mTotalTime = mTimeBeforeMark = 0; + mCount = 0; if (detachIfReset) { detach(); } @@ -1857,32 +1721,8 @@ public class BatteryStatsImpl extends BatteryStats { mTimeBase.remove(this); } - public void writeToParcel(Parcel out, long elapsedRealtimeUs) { - if (DEBUG) Log.i(TAG, "**** WRITING TIMER #" + mType + ": mTotalTime=" - + computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs))); - out.writeInt(computeCurrentCountLocked()); - out.writeInt(mLoadedCount); - out.writeInt(mUnpluggedCount); - out.writeLong(computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs))); - out.writeLong(mLoadedTime); - out.writeLong(mUnpluggedTime); - out.writeLong(mTimeBeforeMark); - } - @Override public void onTimeStarted(long elapsedRealtime, long timeBaseUptime, long baseRealtime) { - if (DEBUG && mType < 0) { - Log.v(TAG, "unplug #" + mType + ": realtime=" + baseRealtime - + " old mUnpluggedTime=" + mUnpluggedTime - + " old mUnpluggedCount=" + mUnpluggedCount); - } - mUnpluggedTime = computeRunTimeLocked(baseRealtime); - mUnpluggedCount = computeCurrentCountLocked(); - if (DEBUG && mType < 0) { - Log.v(TAG, "unplug #" + mType - + ": new mUnpluggedTime=" + mUnpluggedTime - + " new mUnpluggedCount=" + mUnpluggedCount); - } } @Override @@ -1894,8 +1734,7 @@ public class BatteryStatsImpl extends BatteryStats { mTotalTime = computeRunTimeLocked(baseRealtime); mCount = computeCurrentCountLocked(); if (DEBUG && mType < 0) { - Log.v(TAG, "plug #" + mType - + ": new mTotalTime=" + mTotalTime); + Log.v(TAG, "plug #" + mType + ": new mTotalTime=" + mTotalTime); } } @@ -1912,34 +1751,19 @@ public class BatteryStatsImpl extends BatteryStats { return; } out.writeInt(1); // indicates non-null - timer.writeToParcel(out, elapsedRealtimeUs); } @Override @UnsupportedAppUsage public long getTotalTimeLocked(long elapsedRealtimeUs, int which) { - long val = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs)); - if (which == STATS_SINCE_UNPLUGGED) { - val -= mUnpluggedTime; - } else if (which != STATS_SINCE_CHARGED) { - val -= mLoadedTime; - } - - return val; + return computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs)); } @Override @UnsupportedAppUsage public int getCountLocked(int which) { - int val = computeCurrentCountLocked(); - if (which == STATS_SINCE_UNPLUGGED) { - val -= mUnpluggedCount; - } else if (which != STATS_SINCE_CHARGED) { - val -= mLoadedCount; - } - - return val; + return computeCurrentCountLocked(); } @Override @@ -1950,13 +1774,8 @@ public class BatteryStatsImpl extends BatteryStats { @Override public void logState(Printer pw, String prefix) { - pw.println(prefix + "mCount=" + mCount - + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount - + " mUnpluggedCount=" + mUnpluggedCount); - pw.println(prefix + "mTotalTime=" + mTotalTime - + " mLoadedTime=" + mLoadedTime); - pw.println(prefix + "mLastTime=" + mLastTime - + " mUnpluggedTime=" + mUnpluggedTime); + pw.println(prefix + "mCount=" + mCount); + pw.println(prefix + "mTotalTime=" + mTotalTime); } @@ -1968,13 +1787,8 @@ public class BatteryStatsImpl extends BatteryStats { public void readSummaryFromParcelLocked(Parcel in) { // Multiply by 1000 for backwards compatibility - mTotalTime = mLoadedTime = in.readLong(); - mLastTime = 0; - mUnpluggedTime = mTotalTime; - mCount = mLoadedCount = in.readInt(); - mLastCount = 0; - mUnpluggedCount = mCount; - + mTotalTime = in.readLong(); + mCount = in.readInt(); // When reading the summary, we set the mark to be the latest information. mTimeBeforeMark = mTotalTime; } @@ -2233,7 +2047,7 @@ public class BatteryStatsImpl extends BatteryStats { private long computeOverage(long curTime) { if (mLastAddedTime > 0) { - return mLastTime + mLastAddedDuration - curTime; + return mLastAddedDuration - curTime; } return 0; } @@ -2452,7 +2266,7 @@ public class BatteryStatsImpl extends BatteryStats { mTotalDurationMs = 0; mCurrentDurationMs = 0; if (mNesting > 0) { - mStartTimeMs = mTimeBase.getRealtime(mClocks.elapsedRealtime()*1000) / 1000; + mStartTimeMs = mTimeBase.getRealtime(mClocks.elapsedRealtime() * 1000) / 1000; } else { mStartTimeMs = -1; } @@ -2491,7 +2305,7 @@ public class BatteryStatsImpl extends BatteryStats { public long getCurrentDurationMsLocked(long elapsedRealtimeMs) { long durationMs = mCurrentDurationMs; if (mNesting > 0 && mTimeBase.isRunning()) { - durationMs += (mTimeBase.getRealtime(elapsedRealtimeMs*1000)/1000) + durationMs += (mTimeBase.getRealtime(elapsedRealtimeMs * 1000) / 1000) - mStartTimeMs; } return durationMs; @@ -6401,13 +6215,7 @@ public class BatteryStatsImpl extends BatteryStats { } @Override public int getNumConnectivityChange(int which) { - int val = mNumConnectivityChange; - if (which == STATS_CURRENT) { - val -= mLoadedNumConnectivityChange; - } else if (which == STATS_SINCE_UNPLUGGED) { - val -= mUnpluggedNumConnectivityChange; - } - return val; + return mNumConnectivityChange; } @Override public long getGpsSignalQualityTime(int strengthBin, @@ -9122,66 +8930,6 @@ public class BatteryStatsImpl extends BatteryStats { */ int mNumAnrs; - /** - * The amount of user time loaded from a previous save. - */ - long mLoadedUserTime; - - /** - * The amount of system time loaded from a previous save. - */ - long mLoadedSystemTime; - - /** - * The amount of foreground time loaded from a previous save. - */ - long mLoadedForegroundTime; - - /** - * The number of times the process has started from a previous save. - */ - int mLoadedStarts; - - /** - * Number of times the process has crashed from a previous save. - */ - int mLoadedNumCrashes; - - /** - * Number of times the process has had an ANR from a previous save. - */ - int mLoadedNumAnrs; - - /** - * The amount of user time when last unplugged. - */ - long mUnpluggedUserTime; - - /** - * The amount of system time when last unplugged. - */ - long mUnpluggedSystemTime; - - /** - * The amount of foreground time since unplugged. - */ - long mUnpluggedForegroundTime; - - /** - * The number of times the process has started before unplugged. - */ - int mUnpluggedStarts; - - /** - * Number of times the process has crashed before unplugged. - */ - int mUnpluggedNumCrashes; - - /** - * Number of times the process has had an ANR before unplugged. - */ - int mUnpluggedNumAnrs; - ArrayList mExcessivePower; public Proc(BatteryStatsImpl bsi, String name) { @@ -9191,12 +8939,6 @@ public class BatteryStatsImpl extends BatteryStats { } public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) { - mUnpluggedUserTime = mUserTime; - mUnpluggedSystemTime = mSystemTime; - mUnpluggedForegroundTime = mForegroundTime; - mUnpluggedStarts = mStarts; - mUnpluggedNumCrashes = mNumCrashes; - mUnpluggedNumAnrs = mNumAnrs; } public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { @@ -9283,18 +9025,6 @@ public class BatteryStatsImpl extends BatteryStats { out.writeInt(mStarts); out.writeInt(mNumCrashes); out.writeInt(mNumAnrs); - out.writeLong(mLoadedUserTime); - out.writeLong(mLoadedSystemTime); - out.writeLong(mLoadedForegroundTime); - out.writeInt(mLoadedStarts); - out.writeInt(mLoadedNumCrashes); - out.writeInt(mLoadedNumAnrs); - out.writeLong(mUnpluggedUserTime); - out.writeLong(mUnpluggedSystemTime); - out.writeLong(mUnpluggedForegroundTime); - out.writeInt(mUnpluggedStarts); - out.writeInt(mUnpluggedNumCrashes); - out.writeInt(mUnpluggedNumAnrs); writeExcessivePowerToParcelLocked(out); } @@ -9305,18 +9035,6 @@ public class BatteryStatsImpl extends BatteryStats { mStarts = in.readInt(); mNumCrashes = in.readInt(); mNumAnrs = in.readInt(); - mLoadedUserTime = in.readLong(); - mLoadedSystemTime = in.readLong(); - mLoadedForegroundTime = in.readLong(); - mLoadedStarts = in.readInt(); - mLoadedNumCrashes = in.readInt(); - mLoadedNumAnrs = in.readInt(); - mUnpluggedUserTime = in.readLong(); - mUnpluggedSystemTime = in.readLong(); - mUnpluggedForegroundTime = in.readLong(); - mUnpluggedStarts = in.readInt(); - mUnpluggedNumCrashes = in.readInt(); - mUnpluggedNumAnrs = in.readInt(); readExcessivePowerFromParcelLocked(in); } @@ -9358,71 +9076,35 @@ public class BatteryStatsImpl extends BatteryStats { @Override @UnsupportedAppUsage public long getUserTime(int which) { - long val = mUserTime; - if (which == STATS_CURRENT) { - val -= mLoadedUserTime; - } else if (which == STATS_SINCE_UNPLUGGED) { - val -= mUnpluggedUserTime; - } - return val; + return mUserTime; } @Override @UnsupportedAppUsage public long getSystemTime(int which) { - long val = mSystemTime; - if (which == STATS_CURRENT) { - val -= mLoadedSystemTime; - } else if (which == STATS_SINCE_UNPLUGGED) { - val -= mUnpluggedSystemTime; - } - return val; + return mSystemTime; } @Override @UnsupportedAppUsage public long getForegroundTime(int which) { - long val = mForegroundTime; - if (which == STATS_CURRENT) { - val -= mLoadedForegroundTime; - } else if (which == STATS_SINCE_UNPLUGGED) { - val -= mUnpluggedForegroundTime; - } - return val; + return mForegroundTime; } @Override @UnsupportedAppUsage public int getStarts(int which) { - int val = mStarts; - if (which == STATS_CURRENT) { - val -= mLoadedStarts; - } else if (which == STATS_SINCE_UNPLUGGED) { - val -= mUnpluggedStarts; - } - return val; + return mStarts; } @Override public int getNumCrashes(int which) { - int val = mNumCrashes; - if (which == STATS_CURRENT) { - val -= mLoadedNumCrashes; - } else if (which == STATS_SINCE_UNPLUGGED) { - val -= mUnpluggedNumCrashes; - } - return val; + return mNumCrashes; } @Override public int getNumAnrs(int which) { - int val = mNumAnrs; - if (which == STATS_CURRENT) { - val -= mLoadedNumAnrs; - } else if (which == STATS_SINCE_UNPLUGGED) { - val -= mUnpluggedNumAnrs; - } - return val; + return mNumAnrs; } } @@ -9587,54 +9269,6 @@ public class BatteryStatsImpl extends BatteryStats { */ protected int mLaunches; - /** - * The amount of time spent started loaded from a previous save - * (ms in battery uptime). - */ - protected long mLoadedStartTime; - - /** - * The number of starts loaded from a previous save. - */ - protected int mLoadedStarts; - - /** - * The number of launches loaded from a previous save. - */ - protected int mLoadedLaunches; - - /** - * The amount of time spent started as of the last run (ms - * in battery uptime). - */ - protected long mLastStartTime; - - /** - * The number of starts as of the last run. - */ - protected int mLastStarts; - - /** - * The number of launches as of the last run. - */ - protected int mLastLaunches; - - /** - * The amount of time spent started when last unplugged (ms - * in battery uptime). - */ - protected long mUnpluggedStartTime; - - /** - * The number of starts when last unplugged. - */ - protected int mUnpluggedStarts; - - /** - * The number of launches when last unplugged. - */ - protected int mUnpluggedLaunches; - /** * Construct a Serv. Also adds it to the on-battery time base as a listener. */ @@ -9645,9 +9279,6 @@ public class BatteryStatsImpl extends BatteryStats { public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) { - mUnpluggedStartTime = getStartTimeToNowLocked(baseUptime); - mUnpluggedStarts = mStarts; - mUnpluggedLaunches = mLaunches; } public void onTimeStopped(long elapsedRealtime, long baseUptime, @@ -9679,15 +9310,6 @@ public class BatteryStatsImpl extends BatteryStats { mLaunchedSince = in.readLong(); mLaunched = in.readInt() != 0; mLaunches = in.readInt(); - mLoadedStartTime = in.readLong(); - mLoadedStarts = in.readInt(); - mLoadedLaunches = in.readInt(); - mLastStartTime = 0; - mLastStarts = 0; - mLastLaunches = 0; - mUnpluggedStartTime = in.readLong(); - mUnpluggedStarts = in.readInt(); - mUnpluggedLaunches = in.readInt(); } public void writeToParcelLocked(Parcel out) { @@ -9699,12 +9321,6 @@ public class BatteryStatsImpl extends BatteryStats { out.writeLong(mLaunchedSince); out.writeInt(mLaunched ? 1 : 0); out.writeInt(mLaunches); - out.writeLong(mLoadedStartTime); - out.writeInt(mLoadedStarts); - out.writeInt(mLoadedLaunches); - out.writeLong(mUnpluggedStartTime); - out.writeInt(mUnpluggedStarts); - out.writeInt(mUnpluggedLaunches); } public long getLaunchTimeToNowLocked(long batteryUptime) { @@ -9768,36 +9384,17 @@ public class BatteryStatsImpl extends BatteryStats { @Override public int getLaunches(int which) { - int val = mLaunches; - if (which == STATS_CURRENT) { - val -= mLoadedLaunches; - } else if (which == STATS_SINCE_UNPLUGGED) { - val -= mUnpluggedLaunches; - } - return val; + return mLaunches; } @Override public long getStartTime(long now, int which) { - long val = getStartTimeToNowLocked(now); - if (which == STATS_CURRENT) { - val -= mLoadedStartTime; - } else if (which == STATS_SINCE_UNPLUGGED) { - val -= mUnpluggedStartTime; - } - return val; + return getStartTimeToNowLocked(now); } @Override public int getStarts(int which) { - int val = mStarts; - if (which == STATS_CURRENT) { - val -= mLoadedStarts; - } else if (which == STATS_SINCE_UNPLUGGED) { - val -= mUnpluggedStarts; - } - - return val; + return mStarts; } } @@ -10932,7 +10529,7 @@ public class BatteryStatsImpl extends BatteryStats { } mBluetoothActivity.reset(false); mModemActivity.reset(false); - mNumConnectivityChange = mLoadedNumConnectivityChange = mUnpluggedNumConnectivityChange = 0; + mNumConnectivityChange = 0; for (int i=0; i T[] newUnpaddedArray(Class clazz, int minLen) { return (T[])VMRuntime.getRuntime().newUnpaddedArray(clazz, minLen); @@ -112,6 +115,7 @@ public class ArrayUtils { * it will return the same empty array every time to avoid reallocation, * although this is not guaranteed. */ + @UnsupportedAppUsage @SuppressWarnings("unchecked") public static T[] emptyArray(Class kind) { if (kind == Object.class) { @@ -148,6 +152,7 @@ public class ArrayUtils { /** * Checks if given array is null or has zero elements. */ + @UnsupportedAppUsage public static boolean isEmpty(@Nullable T[] array) { return array == null || array.length == 0; } @@ -200,6 +205,7 @@ public class ArrayUtils { * @param value the value to check for * @return true if the value is present in the array */ + @UnsupportedAppUsage public static boolean contains(@Nullable T[] array, T value) { return indexOf(array, value) != -1; } @@ -208,6 +214,7 @@ public class ArrayUtils { * Return first index of {@code value} in {@code array}, or {@code -1} if * not found. */ + @UnsupportedAppUsage public static int indexOf(@Nullable T[] array, T value) { if (array == null) return -1; for (int i = 0; i < array.length; i++) { @@ -242,6 +249,7 @@ public class ArrayUtils { return false; } + @UnsupportedAppUsage public static boolean contains(@Nullable int[] array, int value) { if (array == null) return false; for (int element : array) { @@ -333,6 +341,7 @@ public class ArrayUtils { * Adds value to given array if not already present, providing set-like * behavior. */ + @UnsupportedAppUsage @SuppressWarnings("unchecked") public static @NonNull T[] appendElement(Class kind, @Nullable T[] array, T element) { return appendElement(kind, array, element, false); @@ -362,6 +371,7 @@ public class ArrayUtils { /** * Removes value from given array if present, providing set-like behavior. */ + @UnsupportedAppUsage @SuppressWarnings("unchecked") public static @Nullable T[] removeElement(Class kind, @Nullable T[] array, T element) { if (array != null) { @@ -408,6 +418,7 @@ public class ArrayUtils { * Adds value to given array if not already present, providing set-like * behavior. */ + @UnsupportedAppUsage public static @NonNull int[] appendInt(@Nullable int[] cur, int val) { return appendInt(cur, val, false); } diff --git a/core/java/com/android/internal/util/BitwiseInputStream.java b/core/java/com/android/internal/util/BitwiseInputStream.java index 86f74f30251815f1b60bf0fdeb7bcf65772636aa..6ff67e9b9718e551fb782a4d550c718144c802b5 100644 --- a/core/java/com/android/internal/util/BitwiseInputStream.java +++ b/core/java/com/android/internal/util/BitwiseInputStream.java @@ -16,6 +16,8 @@ package com.android.internal.util; +import android.annotation.UnsupportedAppUsage; + /** * An object that provides bitwise incremental read access to a byte array. * @@ -49,6 +51,7 @@ public class BitwiseInputStream { * * @param buf a byte array containing data */ + @UnsupportedAppUsage public BitwiseInputStream(byte buf[]) { mBuf = buf; mEnd = buf.length << 3; @@ -58,6 +61,7 @@ public class BitwiseInputStream { /** * Return the number of bit still available for reading. */ + @UnsupportedAppUsage public int available() { return mEnd - mPos; } @@ -71,6 +75,7 @@ public class BitwiseInputStream { * @param bits the amount of data to read (gte 0, lte 8) * @return byte of read data (possibly partially filled, from lsb) */ + @UnsupportedAppUsage public int read(int bits) throws AccessException { int index = mPos >>> 3; int offset = 16 - (mPos & 0x07) - bits; // &7==%8 @@ -92,6 +97,7 @@ public class BitwiseInputStream { * @param bits the amount of data to read * @return newly allocated byte array of read data */ + @UnsupportedAppUsage public byte[] readByteArray(int bits) throws AccessException { int bytes = (bits >>> 3) + ((bits & 0x07) > 0 ? 1 : 0); // &7==%8 byte[] arr = new byte[bytes]; @@ -107,6 +113,7 @@ public class BitwiseInputStream { * * @param bits the amount by which to increment the position */ + @UnsupportedAppUsage public void skip(int bits) throws AccessException { if ((mPos + bits) > mEnd) { throw new AccessException("illegal skip " + diff --git a/core/java/com/android/internal/util/BitwiseOutputStream.java b/core/java/com/android/internal/util/BitwiseOutputStream.java index ddecbed1d97c0e0c2c2fb059a41e784ea756876a..cdd6f173484c0c69028dea72b66954239b7ef63d 100644 --- a/core/java/com/android/internal/util/BitwiseOutputStream.java +++ b/core/java/com/android/internal/util/BitwiseOutputStream.java @@ -16,6 +16,8 @@ package com.android.internal.util; +import android.annotation.UnsupportedAppUsage; + /** * An object that provides bitwise incremental write access to a byte array. * @@ -49,6 +51,7 @@ public class BitwiseOutputStream { * * @param startingLength initial internal byte array length in bytes */ + @UnsupportedAppUsage public BitwiseOutputStream(int startingLength) { mBuf = new byte[startingLength]; mEnd = startingLength << 3; @@ -60,6 +63,7 @@ public class BitwiseOutputStream { * * @return newly allocated byte array */ + @UnsupportedAppUsage public byte[] toByteArray() { int len = (mPos >>> 3) + ((mPos & 0x07) > 0 ? 1 : 0); // &7==%8 byte[] newBuf = new byte[len]; @@ -89,6 +93,7 @@ public class BitwiseOutputStream { * @param bits the amount of data to write (gte 0, lte 8) * @param data to write, will be masked to expose only bits param from lsb */ + @UnsupportedAppUsage public void write(int bits, int data) throws AccessException { if ((bits < 0) || (bits > 8)) { throw new AccessException("illegal write (" + bits + " bits)"); @@ -109,6 +114,7 @@ public class BitwiseOutputStream { * @param bits the amount of data to write * @param arr the byte array containing data to be written */ + @UnsupportedAppUsage public void writeByteArray(int bits, byte[] arr) throws AccessException { for (int i = 0; i < arr.length; i++) { int increment = Math.min(8, bits - (i << 3)); diff --git a/core/java/com/android/internal/util/CharSequences.java b/core/java/com/android/internal/util/CharSequences.java index fdaa4bce25dbe8e2b87defa22f8a08f0a05081fa..6b6c43ce8195d15c6467740aecbb278d3f50e691 100644 --- a/core/java/com/android/internal/util/CharSequences.java +++ b/core/java/com/android/internal/util/CharSequences.java @@ -16,6 +16,8 @@ package com.android.internal.util; +import android.annotation.UnsupportedAppUsage; + /** * {@link CharSequence} utility methods. */ @@ -93,6 +95,7 @@ public class CharSequences { /** * Compares two character sequences for equality. */ + @UnsupportedAppUsage public static boolean equals(CharSequence a, CharSequence b) { if (a.length() != b.length()) { return false; @@ -114,6 +117,7 @@ public class CharSequences { * @param another The other CharSequence. * @return See {@link Comparable#compareTo}. */ + @UnsupportedAppUsage public static int compareToIgnoreCase(CharSequence me, CharSequence another) { // Code adapted from String#compareTo int myLen = me.length(), anotherLen = another.length(); diff --git a/core/java/com/android/internal/util/FastMath.java b/core/java/com/android/internal/util/FastMath.java index 88a17e6ba2594a423fc5001d134ebbe0d89c5fbc..35efe708795e7728f05c0bd972752dd50c756969 100644 --- a/core/java/com/android/internal/util/FastMath.java +++ b/core/java/com/android/internal/util/FastMath.java @@ -16,6 +16,8 @@ package com.android.internal.util; +import android.annotation.UnsupportedAppUsage; + /** * Fast and loose math routines. */ @@ -26,6 +28,7 @@ public class FastMath { * thought it may return slightly different results. It does not try to * handle (in any meaningful way) NaN or infinities. */ + @UnsupportedAppUsage public static int round(float value) { long lx = (long) (value * (65536 * 256f)); return (int) ((lx + 0x800000) >> 24); diff --git a/core/java/com/android/internal/util/FastXmlSerializer.java b/core/java/com/android/internal/util/FastXmlSerializer.java index b85b84fb3dc89a97d53c2594575122ecc64124a6..9f76aeb663c5fb874c1ebdd2aacc93822e7d7f29 100644 --- a/core/java/com/android/internal/util/FastXmlSerializer.java +++ b/core/java/com/android/internal/util/FastXmlSerializer.java @@ -18,6 +18,7 @@ package com.android.internal.util; import org.xmlpull.v1.XmlSerializer; +import android.annotation.UnsupportedAppUsage; import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; @@ -69,6 +70,7 @@ public class FastXmlSerializer implements XmlSerializer { private int mNesting = 0; private boolean mLineStart = true; + @UnsupportedAppUsage public FastXmlSerializer() { this(DEFAULT_BUFFER_LEN); } diff --git a/core/java/com/android/internal/util/GrowingArrayUtils.java b/core/java/com/android/internal/util/GrowingArrayUtils.java index 968d9204b106bbe250700f86d1121617cb76afa0..9f563667e0191895b89f21ceac668675083cd31d 100644 --- a/core/java/com/android/internal/util/GrowingArrayUtils.java +++ b/core/java/com/android/internal/util/GrowingArrayUtils.java @@ -16,6 +16,8 @@ package com.android.internal.util; +import android.annotation.UnsupportedAppUsage; + /** * A helper class that aims to provide comparable growth performance to ArrayList, but on primitive * arrays. Common array operations are implemented for efficient use in dynamic containers. @@ -37,6 +39,7 @@ public final class GrowingArrayUtils { * @return the array to which the element was appended. This may be different than the given * array. */ + @UnsupportedAppUsage public static T[] append(T[] array, int currentSize, T element) { assert currentSize <= array.length; @@ -54,6 +57,7 @@ public final class GrowingArrayUtils { /** * Primitive int version of {@link #append(Object[], int, Object)}. */ + @UnsupportedAppUsage public static int[] append(int[] array, int currentSize, int element) { assert currentSize <= array.length; diff --git a/core/java/com/android/internal/util/HexDump.java b/core/java/com/android/internal/util/HexDump.java index af004009e1ee7cd2e7e2099d87eca0ca55f6e3d8..6ffc92853b08f048d5d56dedc6fe789ba7cf47f7 100644 --- a/core/java/com/android/internal/util/HexDump.java +++ b/core/java/com/android/internal/util/HexDump.java @@ -17,6 +17,7 @@ package com.android.internal.util; import android.annotation.Nullable; +import android.annotation.UnsupportedAppUsage; public class HexDump { @@ -100,16 +101,19 @@ public class HexDump return toHexString(toByteArray(b)); } + @UnsupportedAppUsage public static String toHexString(byte[] array) { return toHexString(array, 0, array.length, true); } + @UnsupportedAppUsage public static String toHexString(byte[] array, boolean upperCase) { return toHexString(array, 0, array.length, upperCase); } + @UnsupportedAppUsage public static String toHexString(byte[] array, int offset, int length) { return toHexString(array, offset, length, true); @@ -131,6 +135,7 @@ public class HexDump return new String(buf); } + @UnsupportedAppUsage public static String toHexString(int i) { return toHexString(toByteArray(i)); @@ -164,6 +169,7 @@ public class HexDump throw new RuntimeException ("Invalid hex char '" + c + "'"); } + @UnsupportedAppUsage public static byte[] hexStringToByteArray(String hexString) { int length = hexString.length(); diff --git a/core/java/com/android/internal/util/IState.java b/core/java/com/android/internal/util/IState.java index 056f8e9b0424157bbb126f5bbb8a714bad661215..eb66e2ce94d72b93f014c87414323dfb75aa8ebb 100644 --- a/core/java/com/android/internal/util/IState.java +++ b/core/java/com/android/internal/util/IState.java @@ -16,6 +16,7 @@ package com.android.internal.util; +import android.annotation.UnsupportedAppUsage; import android.os.Message; /** @@ -67,5 +68,6 @@ public interface IState { * * @return name of state. */ + @UnsupportedAppUsage String getName(); } diff --git a/core/java/com/android/internal/util/MemInfoReader.java b/core/java/com/android/internal/util/MemInfoReader.java index 8d7166679b783832aa1ff40e6149840feb7738fd..630916ebeecbc258faacc800b29d9d684ead8853 100644 --- a/core/java/com/android/internal/util/MemInfoReader.java +++ b/core/java/com/android/internal/util/MemInfoReader.java @@ -16,12 +16,14 @@ package com.android.internal.util; +import android.annotation.UnsupportedAppUsage; import android.os.Debug; import android.os.StrictMode; public final class MemInfoReader { final long[] mInfos = new long[Debug.MEMINFO_COUNT]; + @UnsupportedAppUsage public void readMemInfo() { // Permit disk reads here, as /proc/meminfo isn't really "on // disk" and should be fast. TODO: make BlockGuard ignore @@ -37,6 +39,7 @@ public final class MemInfoReader { /** * Total amount of RAM available to the kernel. */ + @UnsupportedAppUsage public long getTotalSize() { return mInfos[Debug.MEMINFO_TOTAL] * 1024; } @@ -44,6 +47,7 @@ public final class MemInfoReader { /** * Amount of RAM that is not being used for anything. */ + @UnsupportedAppUsage public long getFreeSize() { return mInfos[Debug.MEMINFO_FREE] * 1024; } @@ -52,6 +56,7 @@ public final class MemInfoReader { * Amount of RAM that the kernel is being used for caches, not counting caches * that are mapped in to processes. */ + @UnsupportedAppUsage public long getCachedSize() { return getCachedSizeKb() * 1024; } @@ -107,6 +112,7 @@ public final class MemInfoReader { return mInfos[Debug.MEMINFO_ZRAM_TOTAL]; } + @UnsupportedAppUsage public long[] getRawInfo() { return mInfos; } diff --git a/core/java/com/android/internal/util/Preconditions.java b/core/java/com/android/internal/util/Preconditions.java index 2c6a0e06f6e78e1567cc590b6d32587434cc108f..731b93c18b09331d56c750e9b50ab0ee81f42ed0 100644 --- a/core/java/com/android/internal/util/Preconditions.java +++ b/core/java/com/android/internal/util/Preconditions.java @@ -18,6 +18,7 @@ package com.android.internal.util; import android.annotation.IntRange; import android.annotation.NonNull; +import android.annotation.UnsupportedAppUsage; import android.text.TextUtils; import java.util.Collection; @@ -28,6 +29,7 @@ import java.util.Collection; */ public class Preconditions { + @UnsupportedAppUsage public static void checkArgument(boolean expression) { if (!expression) { throw new IllegalArgumentException(); @@ -42,6 +44,7 @@ public class Preconditions { * be converted to a string using {@link String#valueOf(Object)} * @throws IllegalArgumentException if {@code expression} is false */ + @UnsupportedAppUsage public static void checkArgument(boolean expression, final Object errorMessage) { if (!expression) { throw new IllegalArgumentException(String.valueOf(errorMessage)); @@ -106,6 +109,7 @@ public class Preconditions { * @return the non-null reference that was validated * @throws NullPointerException if {@code reference} is null */ + @UnsupportedAppUsage public static @NonNull T checkNotNull(final T reference) { if (reference == null) { throw new NullPointerException(); @@ -123,6 +127,7 @@ public class Preconditions { * @return the non-null reference that was validated * @throws NullPointerException if {@code reference} is null */ + @UnsupportedAppUsage public static @NonNull T checkNotNull(final T reference, final Object errorMessage) { if (reference == null) { throw new NullPointerException(String.valueOf(errorMessage)); @@ -158,6 +163,7 @@ public class Preconditions { * @param message exception message * @throws IllegalStateException if {@code expression} is false */ + @UnsupportedAppUsage public static void checkState(final boolean expression, String message) { if (!expression) { throw new IllegalStateException(message); @@ -171,6 +177,7 @@ public class Preconditions { * @param expression a boolean expression * @throws IllegalStateException if {@code expression} is false */ + @UnsupportedAppUsage public static void checkState(final boolean expression) { checkState(expression, null); } @@ -368,6 +375,7 @@ public class Preconditions { * * @throws IllegalArgumentException if {@code value} was not within the range */ + @UnsupportedAppUsage public static int checkArgumentInRange(int value, int lower, int upper, String valueName) { if (value < lower) { diff --git a/core/java/com/android/internal/util/State.java b/core/java/com/android/internal/util/State.java index 3eadff58bc09f159d3d99109c9a4c3518c42da17..3c61e035e88676d2aa07e36b45d22966cd4cef36 100644 --- a/core/java/com/android/internal/util/State.java +++ b/core/java/com/android/internal/util/State.java @@ -16,6 +16,7 @@ package com.android.internal.util; +import android.annotation.UnsupportedAppUsage; import android.os.Message; /** @@ -28,12 +29,14 @@ public class State implements IState { /** * Constructor */ + @UnsupportedAppUsage protected State() { } /* (non-Javadoc) * @see com.android.internal.util.IState#enter() */ + @UnsupportedAppUsage @Override public void enter() { } @@ -41,6 +44,7 @@ public class State implements IState { /* (non-Javadoc) * @see com.android.internal.util.IState#exit() */ + @UnsupportedAppUsage @Override public void exit() { } @@ -48,6 +52,7 @@ public class State implements IState { /* (non-Javadoc) * @see com.android.internal.util.IState#processMessage(android.os.Message) */ + @UnsupportedAppUsage @Override public boolean processMessage(Message msg) { return false; @@ -65,6 +70,7 @@ public class State implements IState { * * @see com.android.internal.util.IState#processMessage(android.os.Message) */ + @UnsupportedAppUsage @Override public String getName() { String name = getClass().getName(); diff --git a/core/java/com/android/internal/util/StateMachine.java b/core/java/com/android/internal/util/StateMachine.java index 7398e9526a42f8f921e04667c7554ec0697b2dde..dacdae6fd6c6ac287a48f1e0df809b33af7dfed4 100644 --- a/core/java/com/android/internal/util/StateMachine.java +++ b/core/java/com/android/internal/util/StateMachine.java @@ -1301,6 +1301,7 @@ public class StateMachine { * * @param name of the state machine */ + @UnsupportedAppUsage protected StateMachine(String name) { mSmThread = new HandlerThread(name); mSmThread.start(); @@ -1314,6 +1315,7 @@ public class StateMachine { * * @param name of the state machine */ + @UnsupportedAppUsage protected StateMachine(String name, Looper looper) { initStateMachine(name, looper); } @@ -1323,6 +1325,7 @@ public class StateMachine { * * @param name of the state machine */ + @UnsupportedAppUsage protected StateMachine(String name, Handler handler) { initStateMachine(name, handler.getLooper()); } @@ -1678,6 +1681,7 @@ public class StateMachine { * @param arg2 is assigned to Message.arg2 * @return A Message object from the global pool */ + @UnsupportedAppUsage public final Message obtainMessage(int what, int arg1, int arg2) { return Message.obtain(mSmHandler, what, arg1, arg2); } @@ -1697,6 +1701,7 @@ public class StateMachine { * @param obj is assigned to Message.obj * @return A Message object from the global pool */ + @UnsupportedAppUsage public final Message obtainMessage(int what, int arg1, int arg2, Object obj) { return Message.obtain(mSmHandler, what, arg1, arg2, obj); } @@ -1706,6 +1711,7 @@ public class StateMachine { * * Message is ignored if state machine has quit. */ + @UnsupportedAppUsage public void sendMessage(int what) { // mSmHandler can be null if the state machine has quit. SmHandler smh = mSmHandler; @@ -1719,6 +1725,7 @@ public class StateMachine { * * Message is ignored if state machine has quit. */ + @UnsupportedAppUsage public void sendMessage(int what, Object obj) { // mSmHandler can be null if the state machine has quit. SmHandler smh = mSmHandler; @@ -1732,6 +1739,7 @@ public class StateMachine { * * Message is ignored if state machine has quit. */ + @UnsupportedAppUsage public void sendMessage(int what, int arg1) { // mSmHandler can be null if the state machine has quit. SmHandler smh = mSmHandler; @@ -1758,6 +1766,7 @@ public class StateMachine { * * Message is ignored if state machine has quit. */ + @UnsupportedAppUsage public void sendMessage(int what, int arg1, int arg2, Object obj) { // mSmHandler can be null if the state machine has quit. SmHandler smh = mSmHandler; @@ -1771,6 +1780,7 @@ public class StateMachine { * * Message is ignored if state machine has quit. */ + @UnsupportedAppUsage public void sendMessage(Message msg) { // mSmHandler can be null if the state machine has quit. SmHandler smh = mSmHandler; @@ -2074,6 +2084,7 @@ public class StateMachine { * @param pw * @param args */ + @UnsupportedAppUsage public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { pw.println(getName() + ":"); pw.println(" total records=" + getLogRecCount()); diff --git a/core/java/com/android/internal/view/ActionBarPolicy.java b/core/java/com/android/internal/view/ActionBarPolicy.java index 755faf333a1e94bb0398d419d530c92a8898a038..d18c35e703dae8904d241bab3df1029ddae95e1f 100644 --- a/core/java/com/android/internal/view/ActionBarPolicy.java +++ b/core/java/com/android/internal/view/ActionBarPolicy.java @@ -18,6 +18,7 @@ package com.android.internal.view; import com.android.internal.R; +import android.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; @@ -29,12 +30,15 @@ import android.os.Build; * about how the action bar should lay out and behave on the current device. */ public class ActionBarPolicy { + @UnsupportedAppUsage private Context mContext; + @UnsupportedAppUsage public static ActionBarPolicy get(Context context) { return new ActionBarPolicy(context); } + @UnsupportedAppUsage private ActionBarPolicy(Context context) { mContext = context; } @@ -44,6 +48,7 @@ public class ActionBarPolicy { * bar/action mode. This will be used to determine how many showAsAction="ifRoom" items can fit. * "always" items can override this. */ + @UnsupportedAppUsage public int getMaxActionButtons() { final Configuration config = mContext.getResources().getConfiguration(); final int width = config.screenWidthDp; @@ -62,14 +67,17 @@ public class ActionBarPolicy { return 2; } } + @UnsupportedAppUsage public boolean showsOverflowMenuButton() { return true; } + @UnsupportedAppUsage public int getEmbeddedMenuWidthLimit() { return mContext.getResources().getDisplayMetrics().widthPixels / 2; } + @UnsupportedAppUsage public boolean hasEmbeddedTabs() { final int targetSdk = mContext.getApplicationInfo().targetSdkVersion; if (targetSdk >= Build.VERSION_CODES.JELLY_BEAN) { @@ -85,6 +93,7 @@ public class ActionBarPolicy { width >= 480 || (width >= 640 && height >= 480); } + @UnsupportedAppUsage public int getTabContainerHeight() { TypedArray a = mContext.obtainStyledAttributes(null, R.styleable.ActionBar, com.android.internal.R.attr.actionBarStyle, 0); @@ -106,6 +115,7 @@ public class ActionBarPolicy { Build.VERSION_CODES.ICE_CREAM_SANDWICH; } + @UnsupportedAppUsage public int getStackedTabMaxWidth() { return mContext.getResources().getDimensionPixelSize( R.dimen.action_bar_stacked_tab_max_width); diff --git a/core/java/com/android/internal/view/BaseIWindow.java b/core/java/com/android/internal/view/BaseIWindow.java index ae5c67df8f1e4cccec688a15380062af783c8e5f..fb9ff15c79ac59785c36a33e4ec3f58da3b01897 100644 --- a/core/java/com/android/internal/view/BaseIWindow.java +++ b/core/java/com/android/internal/view/BaseIWindow.java @@ -44,7 +44,7 @@ public class BaseIWindow extends IWindow.Stub { public void resized(Rect frame, Rect overscanInsets, Rect contentInsets, Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw, MergedConfiguration mergedConfiguration, Rect backDropFrame, boolean forceLayout, - boolean alwaysConsumeNavBar, int displayId, + boolean alwaysConsumeSystemBars, int displayId, DisplayCutout.ParcelableWrapper displayCutout) { if (reportDraw) { try { diff --git a/core/java/com/android/internal/view/InputConnectionWrapper.java b/core/java/com/android/internal/view/InputConnectionWrapper.java index 3bd3072c0ebe9760bed674ec32a59c086f7b4960..0c057ea6df59bf2e3df9acbaf44b3e79f529adc4 100644 --- a/core/java/com/android/internal/view/InputConnectionWrapper.java +++ b/core/java/com/android/internal/view/InputConnectionWrapper.java @@ -19,6 +19,7 @@ package com.android.internal.view; import android.annotation.AnyThread; import android.annotation.BinderThread; import android.annotation.NonNull; +import android.annotation.UnsupportedAppUsage; import android.inputmethodservice.AbstractInputMethodService; import android.os.Bundle; import android.os.Handler; @@ -78,6 +79,7 @@ public class InputConnectionWrapper implements InputConnection { * sequence number is set to a new integer. We use a sequence number so that replies that * occur after a timeout has expired are not interpreted as replies to a later request. */ + @UnsupportedAppUsage @AnyThread private static InputContextCallback getInstance() { synchronized (InputContextCallback.class) { @@ -102,6 +104,7 @@ public class InputConnectionWrapper implements InputConnection { /** * Makes the given InputContextCallback available for use in the future. */ + @UnsupportedAppUsage @AnyThread private void dispose() { synchronized (InputContextCallback.class) { diff --git a/core/java/com/android/internal/view/WindowManagerPolicyThread.java b/core/java/com/android/internal/view/WindowManagerPolicyThread.java index c8c38bb01886aee80e7cb176ecccb3839748a81b..b009a2d8ca30542fefd7f90d8991ad02de550b31 100644 --- a/core/java/com/android/internal/view/WindowManagerPolicyThread.java +++ b/core/java/com/android/internal/view/WindowManagerPolicyThread.java @@ -16,6 +16,7 @@ package com.android.internal.view; +import android.annotation.UnsupportedAppUsage; import android.os.Looper; /** @@ -35,6 +36,7 @@ public class WindowManagerPolicyThread { return mThread; } + @UnsupportedAppUsage public static Looper getLooper() { return mLooper; } diff --git a/core/java/com/android/internal/view/menu/ActionMenu.java b/core/java/com/android/internal/view/menu/ActionMenu.java index c657b872e71e367fd0cb2a5aff17c38bf5e5c0c2..977c1f6fda7bd696e1aa09ead99eeec5e744883d 100644 --- a/core/java/com/android/internal/view/menu/ActionMenu.java +++ b/core/java/com/android/internal/view/menu/ActionMenu.java @@ -19,6 +19,7 @@ package com.android.internal.view.menu; import java.util.ArrayList; import java.util.List; +import android.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -39,6 +40,7 @@ public class ActionMenu implements Menu { private ArrayList mItems; + @UnsupportedAppUsage public ActionMenu(Context context) { mContext = context; mItems = new ArrayList(); diff --git a/core/java/com/android/internal/view/menu/ActionMenuItem.java b/core/java/com/android/internal/view/menu/ActionMenuItem.java index b807a42e922e461868ad42f953083bcb99db63b1..ed253d58fb82bd461aab27c792ba322bbc72bdcd 100644 --- a/core/java/com/android/internal/view/menu/ActionMenuItem.java +++ b/core/java/com/android/internal/view/menu/ActionMenuItem.java @@ -17,6 +17,7 @@ package com.android.internal.view.menu; import android.annotation.Nullable; +import android.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.Intent; import android.content.res.ColorStateList; @@ -69,6 +70,7 @@ public class ActionMenuItem implements MenuItem { private static final int HIDDEN = 0x00000008; private static final int ENABLED = 0x00000010; + @UnsupportedAppUsage public ActionMenuItem(Context context, int group, int id, int categoryOrder, int ordering, CharSequence title) { mContext = context; diff --git a/core/java/com/android/internal/view/menu/ContextMenuBuilder.java b/core/java/com/android/internal/view/menu/ContextMenuBuilder.java index 82f061cb86ca8e1224d2ad228b1e8d41b3fbce0c..3d3aceb4a85f4fc28d4904c920051603795fabc4 100644 --- a/core/java/com/android/internal/view/menu/ContextMenuBuilder.java +++ b/core/java/com/android/internal/view/menu/ContextMenuBuilder.java @@ -16,6 +16,7 @@ package com.android.internal.view.menu; +import android.annotation.UnsupportedAppUsage; import android.content.Context; import android.graphics.drawable.Drawable; import android.os.IBinder; @@ -39,6 +40,7 @@ import android.view.View; */ public class ContextMenuBuilder extends MenuBuilder implements ContextMenu { + @UnsupportedAppUsage public ContextMenuBuilder(Context context) { super(context); } diff --git a/core/java/com/android/internal/view/menu/IconMenuItemView.java b/core/java/com/android/internal/view/menu/IconMenuItemView.java index 6c8f330fbcc80cdfd237e82ead9886cdf201b89c..3d888d347d65c8994d3d33e1d4a19e20f6130dec 100644 --- a/core/java/com/android/internal/view/menu/IconMenuItemView.java +++ b/core/java/com/android/internal/view/menu/IconMenuItemView.java @@ -18,6 +18,7 @@ package com.android.internal.view.menu; import com.android.internal.view.menu.MenuBuilder.ItemInvoker; +import android.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Rect; @@ -213,6 +214,7 @@ public final class IconMenuItemView extends TextView implements MenuView.ItemVie } } + @UnsupportedAppUsage public void setItemInvoker(ItemInvoker itemInvoker) { mItemInvoker = itemInvoker; } @@ -232,6 +234,7 @@ public final class IconMenuItemView extends TextView implements MenuView.ItemVie } } + @UnsupportedAppUsage void setIconMenuView(IconMenuView iconMenuView) { mIconMenuView = iconMenuView; } @@ -267,6 +270,7 @@ public final class IconMenuItemView extends TextView implements MenuView.ItemVie * @return layout params appropriate for this view. If layout params already exist, it will * augment them to be appropriate to the current text size. */ + @UnsupportedAppUsage IconMenuView.LayoutParams getTextAppropriateLayoutParams() { IconMenuView.LayoutParams lp = (IconMenuView.LayoutParams) getLayoutParams(); if (lp == null) { diff --git a/core/java/com/android/internal/view/menu/IconMenuView.java b/core/java/com/android/internal/view/menu/IconMenuView.java index dab43ebfe5d514f06d305b113638012fc29de7d4..6f264341f7b437d1ff07276844a3a5ca4918c555 100644 --- a/core/java/com/android/internal/view/menu/IconMenuView.java +++ b/core/java/com/android/internal/view/menu/IconMenuView.java @@ -18,6 +18,7 @@ package com.android.internal.view.menu; import com.android.internal.view.menu.MenuBuilder.ItemInvoker; +import android.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Resources; import android.content.res.TypedArray; @@ -51,6 +52,7 @@ import java.util.ArrayList; public final class IconMenuView extends ViewGroup implements ItemInvoker, MenuView, Runnable { private static final int ITEM_CAPTION_CYCLE_DELAY = 1000; + @UnsupportedAppUsage private MenuBuilder mMenu; /** Height of each row */ @@ -58,6 +60,7 @@ public final class IconMenuView extends ViewGroup implements ItemInvoker, MenuVi /** Maximum number of rows to be shown */ private int mMaxRows; /** Maximum number of items to show in the icon menu. */ + @UnsupportedAppUsage private int mMaxItems; /** Maximum number of items per row */ private int mMaxItemsPerRow; @@ -82,6 +85,7 @@ public final class IconMenuView extends ViewGroup implements ItemInvoker, MenuVi private Drawable mMoreIcon; /** Background of each item (should contain the selected and focused states) */ + @UnsupportedAppUsage private Drawable mItemBackground; /** Default animations for this menu */ @@ -288,6 +292,7 @@ public final class IconMenuView extends ViewGroup implements ItemInvoker, MenuVi * have a MenuItemData backing it. * @return The IconMenuItemView for the 'More' button */ + @UnsupportedAppUsage IconMenuItemView createMoreItemView() { Context context = getContext(); LayoutInflater inflater = LayoutInflater.from(context); @@ -494,6 +499,7 @@ public final class IconMenuView extends ViewGroup implements ItemInvoker, MenuVi * {@link MenuView.ItemView} implementation--eg: excludes More * item). */ + @UnsupportedAppUsage int getNumActualItemsShown() { return mNumActualItemsShown; } @@ -717,6 +723,7 @@ public final class IconMenuView extends ViewGroup implements ItemInvoker, MenuVi /** * Constructor called from {@link #CREATOR} */ + @UnsupportedAppUsage private SavedState(Parcel in) { super(in); focusedPosition = in.readInt(); diff --git a/core/java/com/android/internal/view/menu/MenuDialogHelper.java b/core/java/com/android/internal/view/menu/MenuDialogHelper.java index ecab29fdbbd4fd1166d9e56c399d327c1c3bda8e..88d0a03bd55f491040b6753c151c0a2f61203181 100644 --- a/core/java/com/android/internal/view/menu/MenuDialogHelper.java +++ b/core/java/com/android/internal/view/menu/MenuDialogHelper.java @@ -16,6 +16,7 @@ package com.android.internal.view.menu; +import android.annotation.UnsupportedAppUsage; import android.app.AlertDialog; import android.app.Dialog; import android.content.DialogInterface; @@ -36,6 +37,7 @@ public class MenuDialogHelper implements MenuHelper, DialogInterface.OnKeyListen ListMenuPresenter mPresenter; private MenuPresenter.Callback mPresenterCallback; + @UnsupportedAppUsage public MenuDialogHelper(MenuBuilder menu) { mMenu = menu; } @@ -45,6 +47,7 @@ public class MenuDialogHelper implements MenuHelper, DialogInterface.OnKeyListen * * @param windowToken Optional token to assign to the window. */ + @UnsupportedAppUsage public void show(IBinder windowToken) { // Many references to mMenu, create local reference final MenuBuilder menu = mMenu; @@ -132,6 +135,7 @@ public class MenuDialogHelper implements MenuHelper, DialogInterface.OnKeyListen * * @see Dialog#dismiss() */ + @UnsupportedAppUsage @Override public void dismiss() { if (mDialog != null) { diff --git a/core/java/com/android/internal/widget/AbsActionBarView.java b/core/java/com/android/internal/widget/AbsActionBarView.java index 582c4f1dd669e467e4dfc0b1a1aabfe99268efa6..9ccee7fc32ff1e28f3daf8cfe662e71edc87f7e9 100644 --- a/core/java/com/android/internal/widget/AbsActionBarView.java +++ b/core/java/com/android/internal/widget/AbsActionBarView.java @@ -27,6 +27,7 @@ import android.animation.Animator; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.animation.TimeInterpolator; +import android.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Configuration; import android.content.res.TypedArray; @@ -294,6 +295,7 @@ public abstract class AbsActionBarView extends ViewGroup { return isOverflowReserved() && getVisibility() == VISIBLE; } + @UnsupportedAppUsage public void dismissPopupMenus() { if (mActionMenuPresenter != null) { mActionMenuPresenter.dismissPopupMenus(); diff --git a/core/java/com/android/internal/widget/ActionBarContextView.java b/core/java/com/android/internal/widget/ActionBarContextView.java index 693b194caa8be601e070fbd19c8ddb02b96f413e..78ed53fa918cc32c68be404122d8270f29d5e7e0 100644 --- a/core/java/com/android/internal/widget/ActionBarContextView.java +++ b/core/java/com/android/internal/widget/ActionBarContextView.java @@ -21,6 +21,7 @@ import android.widget.ActionMenuPresenter; import android.widget.ActionMenuView; import com.android.internal.view.menu.MenuBuilder; +import android.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.TypedArray; import android.graphics.drawable.Drawable; @@ -58,6 +59,7 @@ public class ActionBarContextView extends AbsActionBarView { this(context, null); } + @UnsupportedAppUsage public ActionBarContextView(Context context, AttributeSet attrs) { this(context, attrs, com.android.internal.R.attr.actionModeStyle); } diff --git a/core/java/com/android/internal/widget/ActionBarOverlayLayout.java b/core/java/com/android/internal/widget/ActionBarOverlayLayout.java index ba0ff01b68de694352dd900a9dbc7c8669ec1e22..e9e3cdab7a10346262e1e2f925b262c75e834580 100644 --- a/core/java/com/android/internal/widget/ActionBarOverlayLayout.java +++ b/core/java/com/android/internal/widget/ActionBarOverlayLayout.java @@ -18,6 +18,7 @@ package com.android.internal.widget; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; +import android.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.ActivityInfo; import android.content.res.Configuration; @@ -168,6 +169,7 @@ public class ActionBarOverlayLayout extends ViewGroup implements DecorContentPar init(context); } + @UnsupportedAppUsage public ActionBarOverlayLayout(Context context, AttributeSet attrs) { super(context, attrs); init(context); @@ -671,6 +673,7 @@ public class ActionBarOverlayLayout extends ViewGroup implements DecorContentPar return finalY > mActionBarTop.getHeight(); } + @UnsupportedAppUsage @Override public void setWindowCallback(Window.Callback cb) { pullChildren(); diff --git a/core/java/com/android/internal/widget/EditableInputConnection.java b/core/java/com/android/internal/widget/EditableInputConnection.java index 78688edb3f88ce20ba72c0fe9b124c6c07b7e0c9..2b648e90f7dd4d485e65bfa764b460fc60115db5 100644 --- a/core/java/com/android/internal/widget/EditableInputConnection.java +++ b/core/java/com/android/internal/widget/EditableInputConnection.java @@ -16,6 +16,7 @@ package com.android.internal.widget; +import android.annotation.UnsupportedAppUsage; import android.os.Bundle; import android.text.Editable; import android.text.method.KeyListener; @@ -39,6 +40,7 @@ public class EditableInputConnection extends BaseInputConnection { // A negative value means that this connection has been finished by the InputMethodManager. private int mBatchEditNesting; + @UnsupportedAppUsage public EditableInputConnection(TextView textview) { super(textview, true); mTextView = textview; diff --git a/core/java/com/android/internal/widget/ILockSettings.aidl b/core/java/com/android/internal/widget/ILockSettings.aidl index 41e2fc84593e9c97683d47e4c1e0c64ab71e3a2e..b36c3fa79251345212d6a1b9091828168b368c42 100644 --- a/core/java/com/android/internal/widget/ILockSettings.aidl +++ b/core/java/com/android/internal/widget/ILockSettings.aidl @@ -42,7 +42,7 @@ interface ILockSettings { long getLong(in String key, in long defaultValue, in int userId); @UnsupportedAppUsage String getString(in String key, in String defaultValue, in int userId); - void setLockCredential(in byte[] credential, int type, in byte[] savedCredential, int requestedQuality, int userId); + void setLockCredential(in byte[] credential, int type, in byte[] savedCredential, int requestedQuality, int userId, boolean allowUntrustedChange); void resetKeyStore(int userId); VerifyCredentialResponse checkCredential(in byte[] credential, int type, int userId, in ICheckCredentialProgressCallback progressCallback); diff --git a/core/java/com/android/internal/widget/LinearLayoutWithDefaultTouchRecepient.java b/core/java/com/android/internal/widget/LinearLayoutWithDefaultTouchRecepient.java index b2001cbe15ef68c68bcd1ad8fc1967fd26e2e752..cc7911da0b96b76ea2cc91e1e94603652408758c 100644 --- a/core/java/com/android/internal/widget/LinearLayoutWithDefaultTouchRecepient.java +++ b/core/java/com/android/internal/widget/LinearLayoutWithDefaultTouchRecepient.java @@ -16,6 +16,7 @@ package com.android.internal.widget; +import android.annotation.UnsupportedAppUsage; import android.content.Context; import android.graphics.Rect; import android.util.AttributeSet; @@ -36,6 +37,7 @@ public class LinearLayoutWithDefaultTouchRecepient extends LinearLayout { private final Rect mTempRect = new Rect(); private View mDefaultTouchRecepient; + @UnsupportedAppUsage public LinearLayoutWithDefaultTouchRecepient(Context context) { super(context); } @@ -44,6 +46,7 @@ public class LinearLayoutWithDefaultTouchRecepient extends LinearLayout { super(context, attrs); } + @UnsupportedAppUsage public void setDefaultTouchRecepient(View defaultTouchRecepient) { mDefaultTouchRecepient = defaultTouchRecepient; } diff --git a/core/java/com/android/internal/widget/LockPatternChecker.java b/core/java/com/android/internal/widget/LockPatternChecker.java index bda3b5728fdc4536e95015fb3c41a0a7b70b2fa6..09bc28c1f5ec603a75506a8b1ae9e63ac31185d6 100644 --- a/core/java/com/android/internal/widget/LockPatternChecker.java +++ b/core/java/com/android/internal/widget/LockPatternChecker.java @@ -1,5 +1,6 @@ package com.android.internal.widget; +import android.annotation.UnsupportedAppUsage; import android.os.AsyncTask; import com.android.internal.widget.LockPatternUtils.RequestThrottledException; @@ -245,6 +246,7 @@ public final class LockPatternChecker { * @param callback The callback to be invoked with the check result. * @deprecated Pass passwords as byte[] */ + @UnsupportedAppUsage @Deprecated public static AsyncTask checkPassword(final LockPatternUtils utils, final String password, diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java index 1965609ff9596f8495ad2d9d608d6c9e5c59529b..07f8ee077c21d99456cde53c1dd49ffd59ee44f9 100644 --- a/core/java/com/android/internal/widget/LockPatternUtils.java +++ b/core/java/com/android/internal/widget/LockPatternUtils.java @@ -27,6 +27,7 @@ import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED import android.annotation.IntDef; import android.annotation.Nullable; +import android.annotation.UnsupportedAppUsage; import android.app.admin.DevicePolicyManager; import android.app.admin.PasswordMetrics; import android.app.trust.IStrongAuthTracker; @@ -78,7 +79,6 @@ import java.util.StringJoiner; public class LockPatternUtils { private static final String TAG = "LockPatternUtils"; - private static final boolean DEBUG = false; private static final boolean FRP_CREDENTIAL_ENABLED = true; /** @@ -86,12 +86,6 @@ public class LockPatternUtils { */ public static final String LEGACY_LOCK_PATTERN_ENABLED = "legacy_lock_pattern_enabled"; - /** - * The number of incorrect attempts before which we fall back on an alternative - * method of verifying the user, and resetting their lock pattern. - */ - public static final int FAILED_ATTEMPTS_BEFORE_RESET = 20; - /** * The interval of the countdown for showing progress of the lockout. */ @@ -115,18 +109,23 @@ public class LockPatternUtils { public static final int MIN_LOCK_PASSWORD_SIZE = 4; /** - * The minimum number of dots the user must include in a wrong pattern - * attempt for it to be counted against the counts that affect - * {@link #FAILED_ATTEMPTS_BEFORE_TIMEOUT} and {@link #FAILED_ATTEMPTS_BEFORE_RESET} + * The minimum number of dots the user must include in a wrong pattern attempt for it to be + * counted. */ public static final int MIN_PATTERN_REGISTER_FAIL = MIN_LOCK_PATTERN_SIZE; public static final int CREDENTIAL_TYPE_NONE = -1; - public static final int CREDENTIAL_TYPE_PATTERN = 1; - public static final int CREDENTIAL_TYPE_PASSWORD = 2; + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"CREDENTIAL_TYPE_"}, value = { + CREDENTIAL_TYPE_NONE, + CREDENTIAL_TYPE_PATTERN, + CREDENTIAL_TYPE_PASSWORD, // Either pin or password. + }) + public @interface CredentialType {} + /** * Special user id for triggering the FRP verification flow. */ @@ -171,7 +170,9 @@ public class LockPatternUtils { public static final String SYNTHETIC_PASSWORD_ENABLED_KEY = "enable-sp"; private static final String HISTORY_DELIMITER = ","; + @UnsupportedAppUsage private final Context mContext; + @UnsupportedAppUsage private final ContentResolver mContentResolver; private DevicePolicyManager mDevicePolicyManager; private ILockSettings mLockSettingsService; @@ -215,6 +216,7 @@ public class LockPatternUtils { public static final class RequestThrottledException extends Exception { private int mTimeoutMs; + @UnsupportedAppUsage public RequestThrottledException(int timeoutMs) { mTimeoutMs = timeoutMs; } @@ -223,12 +225,14 @@ public class LockPatternUtils { * @return The amount of time in ms before another request may * be executed */ + @UnsupportedAppUsage public int getTimeoutMs() { return mTimeoutMs; } } + @UnsupportedAppUsage public DevicePolicyManager getDevicePolicyManager() { if (mDevicePolicyManager == null) { mDevicePolicyManager = @@ -257,6 +261,7 @@ public class LockPatternUtils { return trust; } + @UnsupportedAppUsage public LockPatternUtils(Context context) { mContext = context; mContentResolver = context.getContentResolver(); @@ -265,6 +270,7 @@ public class LockPatternUtils { mHandler = looper != null ? new Handler(looper) : null; } + @UnsupportedAppUsage @VisibleForTesting public ILockSettings getLockSettings() { if (mLockSettingsService == null) { @@ -319,6 +325,7 @@ public class LockPatternUtils { return getDevicePolicyManager().getPasswordMinimumNonLetter(null, userId); } + @UnsupportedAppUsage public void reportFailedPasswordAttempt(int userId) { if (userId == USER_FRP && frpCredentialEnabled(mContext)) { return; @@ -327,6 +334,7 @@ public class LockPatternUtils { getTrustManager().reportUnlockAttempt(false /* authenticated */, userId); } + @UnsupportedAppUsage public void reportSuccessfulPasswordAttempt(int userId) { if (userId == USER_FRP && frpCredentialEnabled(mContext)) { return; @@ -487,6 +495,7 @@ public class LockPatternUtils { * @param password The password to check. * @return Whether the password matches the stored one. */ + @UnsupportedAppUsage public boolean checkPassword(String password, int userId) throws RequestThrottledException { byte[] passwordBytes = password != null ? password.getBytes() : null; return checkPassword(passwordBytes, userId, null /* progressCallback */); @@ -640,6 +649,7 @@ public class LockPatternUtils { * Used by device policy manager to validate the current password * information it has. */ + @UnsupportedAppUsage public int getActivePasswordQuality(int userId) { int quality = getKeyguardStoredPasswordQuality(userId); @@ -671,17 +681,25 @@ public class LockPatternUtils { /** * Clear any lock pattern or password. */ - public void clearLock(byte[] savedCredential, int userHandle) { + public boolean clearLock(byte[] savedCredential, int userHandle) { + return clearLock(savedCredential, userHandle, false); + } + + /** + * Clear any lock pattern or password, with the option to ignore incorrect existing credential. + */ + public boolean clearLock(byte[] savedCredential, int userHandle, boolean allowUntrustedChange) { final int currentQuality = getKeyguardStoredPasswordQuality(userHandle); setKeyguardStoredPasswordQuality(PASSWORD_QUALITY_UNSPECIFIED, userHandle); try{ getLockSettings().setLockCredential(null, CREDENTIAL_TYPE_NONE, - savedCredential, PASSWORD_QUALITY_UNSPECIFIED, userHandle); + savedCredential, PASSWORD_QUALITY_UNSPECIFIED, userHandle, + allowUntrustedChange); } catch (Exception e) { Log.e(TAG, "Failed to clear lock", e); setKeyguardStoredPasswordQuality(currentQuality, userHandle); - return; + return false; } if (userHandle == UserHandle.USER_SYSTEM) { @@ -691,6 +709,7 @@ public class LockPatternUtils { } onAfterChangingPassword(userHandle); + return true; } /** @@ -710,6 +729,7 @@ public class LockPatternUtils { * * @return true if lock screen is disabled */ + @UnsupportedAppUsage public boolean isLockScreenDisabled(int userId) { if (isSecure(userId)) { return false; @@ -728,19 +748,28 @@ public class LockPatternUtils { /** * Save a lock pattern. * @param pattern The new pattern to save. + * @param savedPattern The previously saved pattern, converted to byte[] format * @param userId the user whose pattern is to be saved. + * + * @return whether this was successful or not. */ - public void saveLockPattern(List pattern, int userId) { - this.saveLockPattern(pattern, null, userId); + public boolean saveLockPattern(List pattern, byte[] savedPattern, + int userId) { + return saveLockPattern(pattern, savedPattern, userId, false); } + /** * Save a lock pattern. * @param pattern The new pattern to save. * @param savedPattern The previously saved pattern, converted to byte[] format * @param userId the user whose pattern is to be saved. + * @param allowUntrustedChange whether we want to allow saving a new password if the existing + * password being provided is incorrect. + * + * @return whether this was successful or not. */ - public void saveLockPattern(List pattern, byte[] savedPattern, - int userId) { + public boolean saveLockPattern(List pattern, byte[] savedPattern, + int userId, boolean allowUntrustedChange) { if (!hasSecureLockScreen()) { throw new UnsupportedOperationException( "This operation requires the lock screen feature."); @@ -755,11 +784,11 @@ public class LockPatternUtils { setKeyguardStoredPasswordQuality(PASSWORD_QUALITY_SOMETHING, userId); try { getLockSettings().setLockCredential(bytePattern, CREDENTIAL_TYPE_PATTERN, savedPattern, - PASSWORD_QUALITY_SOMETHING, userId); + PASSWORD_QUALITY_SOMETHING, userId, allowUntrustedChange); } catch (Exception e) { Log.e(TAG, "Couldn't save lock pattern", e); setKeyguardStoredPasswordQuality(currentQuality, userId); - return; + return false; } // Update the device encryption password. if (userId == UserHandle.USER_SYSTEM @@ -773,6 +802,7 @@ public class LockPatternUtils { reportPatternWasChosen(userId); onAfterChangingPassword(userId); + return true; } private void updateCryptoUserInfo(int userId) { @@ -797,16 +827,19 @@ public class LockPatternUtils { } } + @UnsupportedAppUsage public void setOwnerInfo(String info, int userId) { setString(LOCK_SCREEN_OWNER_INFO, info, userId); updateCryptoUserInfo(userId); } + @UnsupportedAppUsage public void setOwnerInfoEnabled(boolean enabled, int userId) { setBoolean(LOCK_SCREEN_OWNER_INFO_ENABLED, enabled, userId); updateCryptoUserInfo(userId); } + @UnsupportedAppUsage public String getOwnerInfo(int userId) { return getString(LOCK_SCREEN_OWNER_INFO, userId); } @@ -875,17 +908,20 @@ public class LockPatternUtils { * password. * @param password The password to save * @param savedPassword The previously saved lock password, or null if none - * @param requestedQuality {@see DevicePolicyManager#getPasswordQuality(android.content.ComponentName)} + * @param requestedQuality {@see DevicePolicyManager#getPasswordQuality( + * android.content.ComponentName)} * @param userHandle The userId of the user to change the password for * + * @return whether this was successful or not. + * * @deprecated Pass password as a byte array */ @Deprecated - public void saveLockPassword(String password, String savedPassword, int requestedQuality, + public boolean saveLockPassword(String password, String savedPassword, int requestedQuality, int userHandle) { byte[] passwordBytes = password != null ? password.getBytes() : null; byte[] savedPasswordBytes = savedPassword != null ? savedPassword.getBytes() : null; - saveLockPassword(passwordBytes, savedPasswordBytes, requestedQuality, userHandle); + return saveLockPassword(passwordBytes, savedPasswordBytes, requestedQuality, userHandle); } /** @@ -895,11 +931,34 @@ public class LockPatternUtils { * @param password The password to save * @param savedPassword The previously saved lock password, or null if none * @param requestedQuality {@see DevicePolicyManager#getPasswordQuality( - * android.content.ComponentName)} + * android.content.ComponentName)} * @param userHandle The userId of the user to change the password for + * + * @return whether this was successful or not. */ - public void saveLockPassword(byte[] password, byte[] savedPassword, int requestedQuality, + public boolean saveLockPassword(byte[] password, byte[] savedPassword, int requestedQuality, int userHandle) { + return saveLockPassword(password, savedPassword, requestedQuality, + userHandle, false); + } + + /** + * Save a lock password. Does not ensure that the password is as good + * as the requested mode, but will adjust the mode to be as good as the + * password. + * @param password The password to save + * @param savedPassword The previously saved lock password, or null if none + * @param requestedQuality {@see DevicePolicyManager#getPasswordQuality( + * android.content.ComponentName)} + * @param userHandle The userId of the user to change the password for + * @param allowUntrustedChange whether we want to allow saving a new password if the existing + * password being provided is incorrect. + * + * @return whether this method saved the new password successfully or not. This flow will fail + * and return false if the given credential is wrong and allowUntrustedChange is false. + */ + public boolean saveLockPassword(byte[] password, byte[] savedPassword, + int requestedQuality, int userHandle, boolean allowUntrustedChange) { if (!hasSecureLockScreen()) { throw new UnsupportedOperationException( "This operation requires the lock screen feature."); @@ -915,22 +974,36 @@ public class LockPatternUtils { } final int currentQuality = getKeyguardStoredPasswordQuality(userHandle); - setKeyguardStoredPasswordQuality( - computePasswordQuality(CREDENTIAL_TYPE_PASSWORD, password, requestedQuality), - userHandle); + final int passwordQuality = PasswordMetrics.computeForPassword(password).quality; + final int newKeyguardQuality = + computeKeyguardQuality(CREDENTIAL_TYPE_PASSWORD, requestedQuality, passwordQuality); + setKeyguardStoredPasswordQuality(newKeyguardQuality, userHandle); try { getLockSettings().setLockCredential(password, CREDENTIAL_TYPE_PASSWORD, savedPassword, - requestedQuality, userHandle); + requestedQuality, userHandle, allowUntrustedChange); } catch (Exception e) { Log.e(TAG, "Unable to save lock password", e); setKeyguardStoredPasswordQuality(currentQuality, userHandle); - return; + return false; } - updateEncryptionPasswordIfNeeded(password, - PasswordMetrics.computeForPassword(password).quality, userHandle); + updateEncryptionPasswordIfNeeded(password, passwordQuality, userHandle); updatePasswordHistory(password, userHandle); onAfterChangingPassword(userHandle); + return true; + } + + /** + * Compute keyguard credential quality to store in PASSWORD_TYPE_KEY by computing max between + * them so that digit-only password is distinguished from PIN. + * + * TODO: remove this method and make CREDENTIAL_TYPE distinguish between PIN and password, so + * that this quality is no longer needs to be persisted. + */ + private int computeKeyguardQuality( + @CredentialType int credentialType, int requestedQuality, int passwordQuality) { + return credentialType == CREDENTIAL_TYPE_PASSWORD + ? Math.max(passwordQuality, requestedQuality) : passwordQuality; } /** @@ -999,6 +1072,7 @@ public class LockPatternUtils { * encrypted with the default password. * @return true if device encryption is enabled */ + @UnsupportedAppUsage public static boolean isDeviceEncryptionEnabled() { return StorageManager.isEncrypted(); } @@ -1024,6 +1098,7 @@ public class LockPatternUtils { * * @return stored password quality */ + @UnsupportedAppUsage public int getKeyguardStoredPasswordQuality(int userHandle) { return (int) getLong(PASSWORD_TYPE_KEY, PASSWORD_QUALITY_UNSPECIFIED, userHandle); } @@ -1032,24 +1107,6 @@ public class LockPatternUtils { setLong(PASSWORD_TYPE_KEY, quality, userHandle); } - /** - * Returns the password quality of the given credential, promoting it to a higher level - * if DevicePolicyManager has a stronger quality requirement. This value will be written - * to PASSWORD_TYPE_KEY. - */ - private int computePasswordQuality(int type, byte[] credential, int requestedQuality) { - final int quality; - if (type == CREDENTIAL_TYPE_PASSWORD) { - int computedQuality = PasswordMetrics.computeForPassword(credential).quality; - quality = Math.max(requestedQuality, computedQuality); - } else if (type == CREDENTIAL_TYPE_PATTERN) { - quality = PASSWORD_QUALITY_SOMETHING; - } else /* if (type == CREDENTIAL_TYPE_NONE) */ { - quality = PASSWORD_QUALITY_UNSPECIFIED; - } - return quality; - } - /** * Enables/disables the Separate Profile Challenge for this {@param userHandle}. This is a no-op * for user handles that do not belong to a managed profile. @@ -1159,6 +1216,7 @@ public class LockPatternUtils { * @return The pattern in string form. * @deprecated Use patternToByteArray instead. */ + @UnsupportedAppUsage @Deprecated public static String patternToString(List pattern) { return new String(patternToByteArray(pattern)); @@ -1208,6 +1266,7 @@ public class LockPatternUtils { * @param pattern the gesture pattern. * @return the hash of the pattern in a byte array. */ + @UnsupportedAppUsage public static byte[] patternToHash(List pattern) { if (pattern == null) { return null; @@ -1305,11 +1364,13 @@ public class LockPatternUtils { * @param userId the user for which to report the value * @return Whether the lock screen is secured. */ + @UnsupportedAppUsage public boolean isSecure(int userId) { int mode = getKeyguardStoredPasswordQuality(userId); return isLockPatternEnabled(mode, userId) || isLockPasswordEnabled(mode, userId); } + @UnsupportedAppUsage public boolean isLockPasswordEnabled(int userId) { return isLockPasswordEnabled(getKeyguardStoredPasswordQuality(userId), userId); } @@ -1327,6 +1388,7 @@ public class LockPatternUtils { /** * @return Whether the lock pattern is enabled */ + @UnsupportedAppUsage public boolean isLockPatternEnabled(int userId) { return isLockPatternEnabled(getKeyguardStoredPasswordQuality(userId), userId); } @@ -1351,6 +1413,7 @@ public class LockPatternUtils { /** * @return Whether the visible pattern is enabled. */ + @UnsupportedAppUsage public boolean isVisiblePatternEnabled(int userId) { return getBoolean(Settings.Secure.LOCK_PATTERN_VISIBLE, false, userId); } @@ -1410,6 +1473,7 @@ public class LockPatternUtils { /** * @return Whether tactile feedback for the pattern is enabled. */ + @UnsupportedAppUsage public boolean isTactileFeedbackEnabled() { return Settings.System.getIntForUser(mContentResolver, Settings.System.HAPTIC_FEEDBACK_ENABLED, 1, UserHandle.USER_CURRENT) != 0; @@ -1420,6 +1484,7 @@ public class LockPatternUtils { * pattern until the deadline has passed. * @return the chosen deadline. */ + @UnsupportedAppUsage public long setLockoutAttemptDeadline(int userId, int timeoutMs) { final long deadline = SystemClock.elapsedRealtime() + timeoutMs; if (userId == USER_FRP) { @@ -1472,6 +1537,7 @@ public class LockPatternUtils { } } + @UnsupportedAppUsage private void setLong(String secureSettingKey, long value, int userHandle) { try { getLockSettings().setLong(secureSettingKey, value, userHandle); @@ -1481,6 +1547,7 @@ public class LockPatternUtils { } } + @UnsupportedAppUsage private String getString(String secureSettingKey, int userHandle) { try { return getLockSettings().getString(secureSettingKey, null, userHandle); @@ -1489,6 +1556,7 @@ public class LockPatternUtils { } } + @UnsupportedAppUsage private void setString(String secureSettingKey, String value, int userHandle) { try { getLockSettings().setString(secureSettingKey, value, userHandle); @@ -1502,6 +1570,7 @@ public class LockPatternUtils { setBoolean(LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS, enabled, userId); } + @UnsupportedAppUsage public boolean getPowerButtonInstantlyLocks(int userId) { return getBoolean(LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS, true, userId); } @@ -1752,9 +1821,10 @@ public class LockPatternUtils { throw new IllegalArgumentException("password must not be null and at least " + "of length " + MIN_LOCK_PASSWORD_SIZE); } - final int quality = computePasswordQuality(type, credential, requestedQuality); + final int quality = PasswordMetrics.computeForCredential(type, credential).quality; + final int keyguardQuality = computeKeyguardQuality(type, quality, requestedQuality); if (!localService.setLockCredentialWithToken(credential, type, tokenHandle, token, - quality, userId)) { + keyguardQuality, userId)) { return false; } setKeyguardStoredPasswordQuality(quality, userId); diff --git a/core/java/com/android/internal/widget/LockPatternView.java b/core/java/com/android/internal/widget/LockPatternView.java index 4b269901ccf67deb77e8eb541e65c0787b96410d..22182677babeeccf800108b1fa7c20699c3e0b1e 100644 --- a/core/java/com/android/internal/widget/LockPatternView.java +++ b/core/java/com/android/internal/widget/LockPatternView.java @@ -19,6 +19,7 @@ package com.android.internal.widget; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; +import android.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Resources; import android.content.res.TypedArray; @@ -78,7 +79,9 @@ public class LockPatternView extends View { private boolean mDrawingProfilingStarted = false; + @UnsupportedAppUsage private final Paint mPaint = new Paint(); + @UnsupportedAppUsage private final Paint mPathPaint = new Paint(); /** @@ -98,6 +101,7 @@ public class LockPatternView extends View { private static final String TAG = "LockPatternView"; private OnPatternListener mOnPatternListener; + @UnsupportedAppUsage private final ArrayList mPattern = new ArrayList(9); /** @@ -119,16 +123,21 @@ public class LockPatternView extends View { private long mAnimatingPeriodStart; private long[] mLineFadeStart = new long[9]; + @UnsupportedAppUsage private DisplayMode mPatternDisplayMode = DisplayMode.Correct; private boolean mInputEnabled = true; + @UnsupportedAppUsage private boolean mInStealthMode = false; private boolean mEnableHapticFeedback = true; + @UnsupportedAppUsage private boolean mPatternInProgress = false; private boolean mFadePattern = true; private float mHitFactor = 0.6f; + @UnsupportedAppUsage private float mSquareWidth; + @UnsupportedAppUsage private float mSquareHeight; private final Path mCurrentPath = new Path(); @@ -153,7 +162,9 @@ public class LockPatternView extends View { * Represents a cell in the 3 X 3 matrix of the unlock pattern view. */ public static final class Cell { + @UnsupportedAppUsage final int row; + @UnsupportedAppUsage final int column; // keep # objects limited to 9 @@ -231,16 +242,19 @@ public class LockPatternView extends View { /** * The pattern drawn is correct (i.e draw it in a friendly color) */ + @UnsupportedAppUsage Correct, /** * Animate the pattern (for demo, and help). */ + @UnsupportedAppUsage Animate, /** * The pattern is wrong (i.e draw a foreboding color) */ + @UnsupportedAppUsage Wrong } @@ -276,6 +290,7 @@ public class LockPatternView extends View { this(context, null); } + @UnsupportedAppUsage public LockPatternView(Context context, AttributeSet attrs) { super(context, attrs); @@ -347,6 +362,7 @@ public class LockPatternView extends View { a.recycle(); } + @UnsupportedAppUsage public CellState[][] getCellStates() { return mCellStates; } @@ -371,6 +387,7 @@ public class LockPatternView extends View { * * @param inStealthMode Whether in stealth mode. */ + @UnsupportedAppUsage public void setInStealthMode(boolean inStealthMode) { mInStealthMode = inStealthMode; } @@ -389,6 +406,7 @@ public class LockPatternView extends View { * * @param tactileFeedbackEnabled Whether tactile feedback is enabled */ + @UnsupportedAppUsage public void setTactileFeedbackEnabled(boolean tactileFeedbackEnabled) { mEnableHapticFeedback = tactileFeedbackEnabled; } @@ -397,6 +415,7 @@ public class LockPatternView extends View { * Set the call back for pattern detection. * @param onPatternListener The call back. */ + @UnsupportedAppUsage public void setOnPatternListener( OnPatternListener onPatternListener) { mOnPatternListener = onPatternListener; @@ -425,6 +444,7 @@ public class LockPatternView extends View { * in progress result to correct or wrong. * @param displayMode The display mode. */ + @UnsupportedAppUsage public void setDisplayMode(DisplayMode displayMode) { mPatternDisplayMode = displayMode; if (displayMode == DisplayMode.Animate) { @@ -564,6 +584,7 @@ public class LockPatternView extends View { } } + @UnsupportedAppUsage private void notifyPatternDetected() { sendAccessEvent(R.string.lockscreen_access_pattern_detected); if (mOnPatternListener != null) { @@ -581,6 +602,7 @@ public class LockPatternView extends View { /** * Clear the pattern. */ + @UnsupportedAppUsage public void clearPattern() { resetPattern(); } @@ -621,6 +643,7 @@ public class LockPatternView extends View { * Disable input (for instance when displaying a message that will * timeout so user doesn't get view into messy state). */ + @UnsupportedAppUsage public void disableInput() { mInputEnabled = false; } @@ -628,6 +651,7 @@ public class LockPatternView extends View { /** * Enable input. */ + @UnsupportedAppUsage public void enableInput() { mInputEnabled = true; } @@ -1308,6 +1332,7 @@ public class LockPatternView extends View { /** * Constructor called from {@link LockPatternView#onSaveInstanceState()} */ + @UnsupportedAppUsage private SavedState(Parcelable superState, String serializedPattern, int displayMode, boolean inputEnabled, boolean inStealthMode, boolean tactileFeedbackEnabled) { super(superState); @@ -1321,6 +1346,7 @@ public class LockPatternView extends View { /** * Constructor called from {@link #CREATOR} */ + @UnsupportedAppUsage private SavedState(Parcel in) { super(in); mSerializedPattern = in.readString(); diff --git a/core/java/com/android/internal/widget/PointerLocationView.java b/core/java/com/android/internal/widget/PointerLocationView.java index 3205b5aef281f4b6d40188bdca60678a1f993e4d..3881093f5540236e4d33e4779c25f5611d9369dc 100644 --- a/core/java/com/android/internal/widget/PointerLocationView.java +++ b/core/java/com/android/internal/widget/PointerLocationView.java @@ -16,6 +16,7 @@ package com.android.internal.widget; +import android.annotation.UnsupportedAppUsage; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; @@ -59,6 +60,7 @@ public class PointerLocationView extends View implements InputDeviceListener, private int mTraceCount; // True if the pointer is down. + @UnsupportedAppUsage private boolean mCurDown; // Most recent coordinates. @@ -123,10 +125,14 @@ public class PointerLocationView extends View implements InputDeviceListener, private final FontMetricsInt mTextMetrics = new FontMetricsInt(); private int mHeaderBottom; private int mHeaderPaddingTop = 0; + @UnsupportedAppUsage private boolean mCurDown; + @UnsupportedAppUsage private int mCurNumPointers; + @UnsupportedAppUsage private int mMaxNumPointers; private int mActivePointerId; + @UnsupportedAppUsage private final ArrayList mPointers = new ArrayList(); private final PointerCoords mTempCoords = new PointerCoords(); @@ -139,6 +145,7 @@ public class PointerLocationView extends View implements InputDeviceListener, private final FasterStringBuilder mText = new FasterStringBuilder(); + @UnsupportedAppUsage private boolean mPrintCoords = true; public PointerLocationView(Context c) { diff --git a/core/java/com/android/internal/widget/PreferenceImageView.java b/core/java/com/android/internal/widget/PreferenceImageView.java index 8730cdab258bf52d46457ceee317fabbcc7d7cf8..02a0b8d436b910438b07108ff665e952060def16 100644 --- a/core/java/com/android/internal/widget/PreferenceImageView.java +++ b/core/java/com/android/internal/widget/PreferenceImageView.java @@ -16,6 +16,7 @@ package com.android.internal.widget; +import android.annotation.UnsupportedAppUsage; import android.content.Context; import android.util.AttributeSet; import android.widget.ImageView; @@ -29,6 +30,7 @@ public class PreferenceImageView extends ImageView { this(context, null); } + @UnsupportedAppUsage public PreferenceImageView(Context context, AttributeSet attrs) { this(context, attrs, 0); } diff --git a/core/java/com/android/internal/widget/RecyclerView.java b/core/java/com/android/internal/widget/RecyclerView.java index 408a4e9b02a456c45fbd374a0a71293b2bb7fdc7..b66a7b44f05d0da091ecef6e91d85062c7c11600 100644 --- a/core/java/com/android/internal/widget/RecyclerView.java +++ b/core/java/com/android/internal/widget/RecyclerView.java @@ -20,6 +20,7 @@ import android.annotation.CallSuper; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.TypedArray; import android.database.Observable; @@ -4953,6 +4954,7 @@ public class RecyclerView extends ViewGroup implements ScrollingView, NestedScro * constructed by {@link GapWorker} prefetch from being bound to a lower priority prefetch. */ static class ScrapData { + @UnsupportedAppUsage ArrayList mScrapHeap = new ArrayList<>(); int mMaxScrap = DEFAULT_MAX_SCRAP; long mCreateRunningAverageNs = 0; diff --git a/core/java/com/android/internal/widget/ScrollBarUtils.java b/core/java/com/android/internal/widget/ScrollBarUtils.java index 0ae9f74167d5adfcb848072a0c38e70aa2bdf59c..982e3152fc7cd3cb8cef4cf22f3bec2ca1320fa4 100644 --- a/core/java/com/android/internal/widget/ScrollBarUtils.java +++ b/core/java/com/android/internal/widget/ScrollBarUtils.java @@ -16,8 +16,11 @@ package com.android.internal.widget; +import android.annotation.UnsupportedAppUsage; + public class ScrollBarUtils { + @UnsupportedAppUsage public static int getThumbLength(int size, int thickness, int extent, int range) { // Avoid the tiny thumb. final int minLength = thickness * 2; diff --git a/core/java/com/android/internal/widget/SlidingTab.java b/core/java/com/android/internal/widget/SlidingTab.java index 79adada9cc98bdfd235c9f88546e3b049aff82bd..4b5d62467af0ee306c3db1ffcb873581edba4193 100644 --- a/core/java/com/android/internal/widget/SlidingTab.java +++ b/core/java/com/android/internal/widget/SlidingTab.java @@ -16,6 +16,7 @@ package com.android.internal.widget; +import android.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Resources; import android.content.res.TypedArray; @@ -83,7 +84,9 @@ public class SlidingTab extends ViewGroup { */ private final int mOrientation; + @UnsupportedAppUsage private final Slider mLeftSlider; + @UnsupportedAppUsage private final Slider mRightSlider; private Slider mCurrentSlider; private boolean mTracking; @@ -95,6 +98,7 @@ public class SlidingTab extends ViewGroup { /** * Listener used to reset the view when the current animation completes. */ + @UnsupportedAppUsage private final AnimationListener mAnimationDoneListener = new AnimationListener() { public void onAnimationStart(Animation animation) { @@ -178,7 +182,9 @@ public class SlidingTab extends ViewGroup { private static final int STATE_PRESSED = 1; private static final int STATE_ACTIVE = 2; + @UnsupportedAppUsage private final ImageView tab; + @UnsupportedAppUsage private final TextView text; private final ImageView target; private int currentState = STATE_NORMAL; @@ -708,6 +714,7 @@ public class SlidingTab extends ViewGroup { slider.startAnimation(trans1, trans2); } + @UnsupportedAppUsage private void onAnimationDone() { resetView(); mAnimating = false; @@ -722,6 +729,7 @@ public class SlidingTab extends ViewGroup { return mOrientation == HORIZONTAL; } + @UnsupportedAppUsage private void resetView() { mLeftSlider.reset(false); mRightSlider.reset(false); @@ -763,6 +771,7 @@ public class SlidingTab extends ViewGroup { * @param barId the resource of the bar drawable (stateful) * @param tabId the resource of the */ + @UnsupportedAppUsage public void setLeftTabResources(int iconId, int targetId, int barId, int tabId) { mLeftSlider.setIcon(iconId); mLeftSlider.setTarget(targetId); @@ -776,6 +785,7 @@ public class SlidingTab extends ViewGroup { * * @param resId */ + @UnsupportedAppUsage public void setLeftHintText(int resId) { if (isHorizontal()) { mLeftSlider.setHintText(resId); @@ -793,6 +803,7 @@ public class SlidingTab extends ViewGroup { * @param barId the resource of the bar drawable (stateful) * @param tabId the resource of the */ + @UnsupportedAppUsage public void setRightTabResources(int iconId, int targetId, int barId, int tabId) { mRightSlider.setIcon(iconId); mRightSlider.setTarget(targetId); @@ -806,12 +817,14 @@ public class SlidingTab extends ViewGroup { * * @param resId */ + @UnsupportedAppUsage public void setRightHintText(int resId) { if (isHorizontal()) { mRightSlider.setHintText(resId); } } + @UnsupportedAppUsage public void setHoldAfterTrigger(boolean holdLeft, boolean holdRight) { mHoldLeftOnTransition = holdLeft; mHoldRightOnTransition = holdRight; @@ -838,6 +851,7 @@ public class SlidingTab extends ViewGroup { * * @param listener the OnDialTriggerListener to attach to this view */ + @UnsupportedAppUsage public void setOnTriggerListener(OnTriggerListener listener) { mOnTriggerListener = listener; } diff --git a/core/java/com/android/internal/widget/TextViewInputDisabler.java b/core/java/com/android/internal/widget/TextViewInputDisabler.java index fb0b3b95b6f2d8ebf73216422bcd8e03736c1170..8d8f0fe52d64265ccbb7377272ab76d8efe0cba0 100644 --- a/core/java/com/android/internal/widget/TextViewInputDisabler.java +++ b/core/java/com/android/internal/widget/TextViewInputDisabler.java @@ -16,6 +16,7 @@ package com.android.internal.widget; +import android.annotation.UnsupportedAppUsage; import android.text.InputFilter; import android.text.Spanned; import android.widget.TextView; @@ -38,11 +39,13 @@ public class TextViewInputDisabler { } }; + @UnsupportedAppUsage public TextViewInputDisabler(TextView textView) { mTextView = textView; mDefaultFilters = mTextView.getFilters(); } + @UnsupportedAppUsage public void setInputEnabled(boolean enabled) { mTextView.setFilters(enabled ? mDefaultFilters : mNoInputFilters); } diff --git a/core/java/com/android/internal/widget/ViewPager.java b/core/java/com/android/internal/widget/ViewPager.java index f48b56d7af365bd04385710ffea5dbb6d05f5531..7d36b02d4157518d71bff09f2e60bab021181d34 100644 --- a/core/java/com/android/internal/widget/ViewPager.java +++ b/core/java/com/android/internal/widget/ViewPager.java @@ -18,6 +18,7 @@ package com.android.internal.widget; import android.annotation.DrawableRes; import android.annotation.NonNull; +import android.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.res.Resources; import android.content.res.TypedArray; @@ -244,6 +245,7 @@ public class ViewPager extends ViewGroup { * @param positionOffset Value from [0, 1) indicating the offset from the page at position. * @param positionOffsetPixels Value in pixels indicating the offset from position. */ + @UnsupportedAppUsage public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels); /** @@ -252,6 +254,7 @@ public class ViewPager extends ViewGroup { * * @param position Position index of the new selected page. */ + @UnsupportedAppUsage public void onPageSelected(int position); /** @@ -264,6 +267,7 @@ public class ViewPager extends ViewGroup { * @see com.android.internal.widget.ViewPager#SCROLL_STATE_DRAGGING * @see com.android.internal.widget.ViewPager#SCROLL_STATE_SETTLING */ + @UnsupportedAppUsage public void onPageScrollStateChanged(int state); } @@ -484,6 +488,7 @@ public class ViewPager extends ViewGroup { setCurrentItemInternal(item, smoothScroll, false); } + @UnsupportedAppUsage public int getCurrentItem() { return mCurItem; } diff --git a/core/java/com/android/server/ResettableTimeout.java b/core/java/com/android/server/ResettableTimeout.java index ac5b160670b0d362e8f422d3042619a051244770..64083f72aff5ea0ee5e65f675611ad39b20a0ee0 100644 --- a/core/java/com/android/server/ResettableTimeout.java +++ b/core/java/com/android/server/ResettableTimeout.java @@ -18,6 +18,7 @@ package com.android.server; import android.os.SystemClock; +import android.annotation.UnsupportedAppUsage; import android.os.ConditionVariable; /** @@ -120,9 +121,11 @@ abstract class ResettableTimeout } } + @UnsupportedAppUsage private ConditionVariable mLock = new ConditionVariable(); // turn it off at this time. + @UnsupportedAppUsage private volatile long mOffAt; private volatile boolean mOffCalled; diff --git a/core/java/com/android/server/net/BaseNetworkObserver.java b/core/java/com/android/server/net/BaseNetworkObserver.java index 3d9fb5c872f7e1db605715129aa659590a79ae4c..a0740eee5df6be98041a0ec9e00df0fdcfc520cb 100644 --- a/core/java/com/android/server/net/BaseNetworkObserver.java +++ b/core/java/com/android/server/net/BaseNetworkObserver.java @@ -16,6 +16,7 @@ package com.android.server.net; +import android.annotation.UnsupportedAppUsage; import android.net.INetworkManagementEventObserver; import android.net.LinkAddress; import android.net.RouteInfo; diff --git a/core/java/com/android/server/net/NetlinkTracker.java b/core/java/com/android/server/net/NetlinkTracker.java index 5b421d988e0a8772823f8952fb9e075e62f480bb..647fb5b9d07932fb613b5f8e33e91c30304f368d 100644 --- a/core/java/com/android/server/net/NetlinkTracker.java +++ b/core/java/com/android/server/net/NetlinkTracker.java @@ -16,6 +16,7 @@ package com.android.server.net; +import android.annotation.UnsupportedAppUsage; import android.net.LinkAddress; import android.net.LinkProperties; import android.net.RouteInfo; @@ -79,6 +80,7 @@ public class NetlinkTracker extends BaseNetworkObserver { private static final boolean DBG = false; + @UnsupportedAppUsage public NetlinkTracker(String iface, Callback callback) { TAG = "NetlinkTracker/" + iface; mInterfaceName = iface; @@ -187,10 +189,12 @@ public class NetlinkTracker extends BaseNetworkObserver { /** * Returns a copy of this object's LinkProperties. */ + @UnsupportedAppUsage public synchronized LinkProperties getLinkProperties() { return new LinkProperties(mLinkProperties); } + @UnsupportedAppUsage public synchronized void clearLinkProperties() { // Clear the repository before clearing mLinkProperties. That way, if a clear() happens // while interfaceDnsServerInfo() is being called, we'll end up with no DNS servers in diff --git a/core/java/com/google/android/collect/Lists.java b/core/java/com/google/android/collect/Lists.java index 3ea873bbb0f93412afd4f9ab075e3a423a806147..8f6594aefb0a3ff298539e00ce74a0059a5538a4 100644 --- a/core/java/com/google/android/collect/Lists.java +++ b/core/java/com/google/android/collect/Lists.java @@ -57,6 +57,7 @@ public class Lists { * @param elements the elements that the list should contain, in order * @return a newly-created {@code ArrayList} containing those elements */ + @UnsupportedAppUsage public static ArrayList newArrayList(E... elements) { int capacity = (elements.length * 110) / 100 + 5; ArrayList list = new ArrayList(capacity); diff --git a/core/java/com/google/android/collect/Sets.java b/core/java/com/google/android/collect/Sets.java index dd3cab15d0b2769282ae755cb780d245056362a0..09b5e51ae2c6d78a47eae95add49067e161ef089 100644 --- a/core/java/com/google/android/collect/Sets.java +++ b/core/java/com/google/android/collect/Sets.java @@ -16,6 +16,7 @@ package com.google.android.collect; +import android.annotation.UnsupportedAppUsage; import android.util.ArraySet; import java.util.Collections; @@ -42,6 +43,7 @@ public class Sets { * * @return a newly-created, initially-empty {@code HashSet} */ + @UnsupportedAppUsage public static HashSet newHashSet() { return new HashSet(); } @@ -63,6 +65,7 @@ public class Sets { * @return a newly-created {@code HashSet} containing those elements (minus * duplicates) */ + @UnsupportedAppUsage public static HashSet newHashSet(E... elements) { int capacity = elements.length * 4 / 3 + 1; HashSet set = new HashSet(capacity); @@ -75,6 +78,7 @@ public class Sets { * * @return a newly-created, initially-empty {@code SortedSet}. */ + @UnsupportedAppUsage public static SortedSet newSortedSet() { return new TreeSet(); } @@ -95,6 +99,7 @@ public class Sets { /** * Creates a {@code ArraySet} instance. */ + @UnsupportedAppUsage public static ArraySet newArraySet() { return new ArraySet(); } @@ -102,6 +107,7 @@ public class Sets { /** * Creates a {@code ArraySet} instance containing the given elements. */ + @UnsupportedAppUsage public static ArraySet newArraySet(E... elements) { int capacity = elements.length * 4 / 3 + 1; ArraySet set = new ArraySet(capacity); diff --git a/core/java/com/google/android/util/AbstractMessageParser.java b/core/java/com/google/android/util/AbstractMessageParser.java index 1871682ee063c60d5dfd3e6dfe568c310ad1117f..9d12f82aeb75f3f99312024c9134be63b090caa9 100644 --- a/core/java/com/google/android/util/AbstractMessageParser.java +++ b/core/java/com/google/android/util/AbstractMessageParser.java @@ -16,6 +16,7 @@ package com.google.android.util; +import android.annotation.UnsupportedAppUsage; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashMap; @@ -654,15 +655,25 @@ public abstract class AbstractMessageParser { public static abstract class Token { public enum Type { + @UnsupportedAppUsage HTML ("html"), + @UnsupportedAppUsage FORMAT ("format"), // subtype of HTML + @UnsupportedAppUsage LINK ("l"), + @UnsupportedAppUsage SMILEY ("e"), + @UnsupportedAppUsage ACRONYM ("a"), + @UnsupportedAppUsage MUSIC ("m"), + @UnsupportedAppUsage GOOGLE_VIDEO ("v"), + @UnsupportedAppUsage YOUTUBE_VIDEO ("yt"), + @UnsupportedAppUsage PHOTO ("p"), + @UnsupportedAppUsage FLICKR ("f"); //stringreps for HTML and FORMAT don't really matter diff --git a/core/jni/Android.bp b/core/jni/Android.bp index cd34d2e1b441d2c9d4f8607cfe1a3c5faf3075d7..664f7f47cf18166ae7b5f77de69604d42c7e3849 100644 --- a/core/jni/Android.bp +++ b/core/jni/Android.bp @@ -1,10 +1,10 @@ genrule { - name: "android_util_StatsLog.cpp", + name: "android_util_StatsLogInternal.cpp", tools: ["stats-log-api-gen"], - cmd: "$(location stats-log-api-gen) --jni $(genDir)/android_util_StatsLog.cpp", + cmd: "$(location stats-log-api-gen) --jni $(genDir)/android_util_StatsLogInternal.cpp", out: [ - "android_util_StatsLog.cpp", + "android_util_StatsLogInternal.cpp", ], } @@ -111,6 +111,7 @@ cc_library_shared { "android_util_Binder.cpp", "android_util_EventLog.cpp", "android_util_Log.cpp", + "android_util_StatsLog.cpp", "android_util_MemoryIntArray.cpp", "android_util_PathParser.cpp", "android_util_Process.cpp", @@ -306,7 +307,7 @@ cc_library_shared { "server_configurable_flags", ], - generated_sources: ["android_util_StatsLog.cpp"], + generated_sources: ["android_util_StatsLogInternal.cpp"], local_include_dirs: ["android/graphics"], export_include_dirs: [ diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index da27852a3a350b1431f3a3777a28106b12e58ec8..ccd0b666865e1740341591ab47bfc1d6125371dc 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -127,6 +127,7 @@ extern int register_android_app_admin_SecurityLog(JNIEnv* env); extern int register_android_content_AssetManager(JNIEnv* env); extern int register_android_util_EventLog(JNIEnv* env); extern int register_android_util_StatsLog(JNIEnv* env); +extern int register_android_util_StatsLogInternal(JNIEnv* env); extern int register_android_util_Log(JNIEnv* env); extern int register_android_util_MemoryIntArray(JNIEnv* env); extern int register_android_util_PathParser(JNIEnv* env); @@ -1126,6 +1127,12 @@ void AndroidRuntime::start(const char* className, const Vector& options return; } + const char* tzdataRootDir = getenv("ANDROID_TZDATA_ROOT"); + if (tzdataRootDir == NULL) { + LOG_FATAL("No tz data directory specified with ANDROID_TZDATA_ROOT environment variable."); + return; + } + //const char* kernelHack = getenv("LD_ASSUME_KERNEL"); //ALOGD("Found LD_ASSUME_KERNEL='%s'\n", kernelHack); @@ -1394,6 +1401,7 @@ static const RegJNIRec gRegJNI[] = { REG_JNI(register_android_util_MemoryIntArray), REG_JNI(register_android_util_PathParser), REG_JNI(register_android_util_StatsLog), + REG_JNI(register_android_util_StatsLogInternal), REG_JNI(register_android_app_admin_SecurityLog), REG_JNI(register_android_content_AssetManager), REG_JNI(register_android_content_StringBlock), diff --git a/core/jni/android_media_AudioRecord.cpp b/core/jni/android_media_AudioRecord.cpp index 02dffdc2ca25cd71ffe4dc582c2a0668b4f80e18..342aba024fc561a825e2fd0dfe3587a23f253a00 100644 --- a/core/jni/android_media_AudioRecord.cpp +++ b/core/jni/android_media_AudioRecord.cpp @@ -821,18 +821,18 @@ static jint android_media_AudioRecord_get_active_microphones(JNIEnv *env, return jStatus; } -static int android_media_AudioRecord_set_microphone_direction(JNIEnv *env, jobject thiz, - jint direction) { +static int android_media_AudioRecord_set_preferred_microphone_direction( + JNIEnv *env, jobject thiz, jint direction) { sp lpRecorder = getAudioRecord(env, thiz); if (lpRecorder == NULL) { jniThrowException(env, "java/lang/IllegalStateException", - "Unable to retrieve AudioRecord pointer for setMicrophoneDirection()"); + "Unable to retrieve AudioRecord pointer for setPreferredMicrophoneDirection()"); return (jint)AUDIO_JAVA_ERROR; } jint jStatus = AUDIO_JAVA_SUCCESS; - status_t status = - lpRecorder->setMicrophoneDirection(static_cast(direction)); + status_t status = lpRecorder->setPreferredMicrophoneDirection( + static_cast(direction)); if (status != NO_ERROR) { jStatus = nativeToJavaStatus(status); } @@ -840,17 +840,17 @@ static int android_media_AudioRecord_set_microphone_direction(JNIEnv *env, jobje return jStatus; } -static int android_media_AudioRecord_set_microphone_field_dimension(JNIEnv *env, jobject thiz, - jfloat zoom) { +static int android_media_AudioRecord_set_preferred_microphone_field_dimension( + JNIEnv *env, jobject thiz, jfloat zoom) { sp lpRecorder = getAudioRecord(env, thiz); if (lpRecorder == NULL) { jniThrowException(env, "java/lang/IllegalStateException", - "Unable to retrieve AudioRecord pointer for setMicrophoneFieldDimension()"); + "Unable to retrieve AudioRecord pointer for setPreferredMicrophoneFieldDimension()"); return (jint)AUDIO_JAVA_ERROR; } jint jStatus = AUDIO_JAVA_SUCCESS; - status_t status = lpRecorder->setMicrophoneFieldDimension(zoom); + status_t status = lpRecorder->setPreferredMicrophoneFieldDimension(zoom); if (status != NO_ERROR) { jStatus = nativeToJavaStatus(status); } @@ -913,10 +913,10 @@ static const JNINativeMethod gMethods[] = { {"native_get_active_microphones", "(Ljava/util/ArrayList;)I", (void *)android_media_AudioRecord_get_active_microphones}, {"native_getPortId", "()I", (void *)android_media_AudioRecord_get_port_id}, - {"native_set_microphone_direction", "(I)I", - (void *)android_media_AudioRecord_set_microphone_direction}, - {"native_set_microphone_field_dimension", "(F)I", - (void *)android_media_AudioRecord_set_microphone_field_dimension}, + {"native_set_preferred_microphone_direction", "(I)I", + (void *)android_media_AudioRecord_set_preferred_microphone_direction}, + {"native_set_preferred_microphone_field_dimension", "(F)I", + (void *)android_media_AudioRecord_set_preferred_microphone_field_dimension}, }; // field names found in android/media/AudioRecord.java diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp index 1a90ebfee999edd433c37fd0120ab44d3098df1e..c8f81e2193c8640b9f5dda437453287debdc9b71 100644 --- a/core/jni/android_media_AudioSystem.cpp +++ b/core/jni/android_media_AudioSystem.cpp @@ -2038,13 +2038,13 @@ android_media_AudioSystem_getStreamVolumeDB(JNIEnv *env, jobject thiz, static jboolean android_media_AudioSystem_isOffloadSupported(JNIEnv *env, jobject thiz, - jint encoding, jint sampleRate, jint channelMask, jint channelIndexMask) + jint encoding, jint sampleRate, jint channelMask, jint channelIndexMask, jint streamType) { audio_offload_info_t format = AUDIO_INFO_INITIALIZER; format.format = (audio_format_t) audioFormatToNative(encoding); format.sample_rate = (uint32_t) sampleRate; format.channel_mask = nativeChannelMaskFromJavaChannelMasks(channelMask, channelIndexMask); - format.stream_type = AUDIO_STREAM_MUSIC; + format.stream_type = (audio_stream_type_t) streamType; format.has_video = false; format.is_streaming = false; // offload duration unknown at this point: @@ -2292,7 +2292,7 @@ static const JNINativeMethod gMethods[] = { (void *)android_media_AudioSystem_registerRecordingCallback}, {"systemReady", "()I", (void *)android_media_AudioSystem_systemReady}, {"getStreamVolumeDB", "(III)F", (void *)android_media_AudioSystem_getStreamVolumeDB}, - {"native_is_offload_supported", "(IIII)Z", (void *)android_media_AudioSystem_isOffloadSupported}, + {"native_is_offload_supported", "(IIIII)Z", (void *)android_media_AudioSystem_isOffloadSupported}, {"getMicrophones", "(Ljava/util/ArrayList;)I", (void *)android_media_AudioSystem_getMicrophones}, {"getSurroundFormats", "(Ljava/util/Map;Z)I", (void *)android_media_AudioSystem_getSurroundFormats}, {"setSurroundFormatEnabled", "(IZ)I", (void *)android_media_AudioSystem_setSurroundFormatEnabled}, diff --git a/core/jni/android_net_NetUtils.cpp b/core/jni/android_net_NetUtils.cpp index cfb2dd199f3989051fb8531b981b4848af40bba5..d7a981ed3e9d00956e7a97bf1d975af517600da0 100644 --- a/core/jni/android_net_NetUtils.cpp +++ b/core/jni/android_net_NetUtils.cpp @@ -487,6 +487,11 @@ static jbyteArray android_net_utils_resNetworkResult(JNIEnv *env, jobject thiz, return answer; } +static void android_net_utils_resNetworkCancel(JNIEnv *env, jobject thiz, jobject javaFd) { + int fd = jniGetFDFromFileDescriptor(env, javaFd); + resNetworkCancel(fd); +} + static jobject android_net_utils_getTcpRepairWindow(JNIEnv *env, jobject thiz, jobject javaFd) { if (javaFd == NULL) { jniThrowNullPointerException(env, NULL); @@ -546,6 +551,7 @@ static const JNINativeMethod gNetworkUtilMethods[] = { { "resNetworkSend", "(I[BII)Ljava/io/FileDescriptor;", (void*) android_net_utils_resNetworkSend }, { "resNetworkQuery", "(ILjava/lang/String;III)Ljava/io/FileDescriptor;", (void*) android_net_utils_resNetworkQuery }, { "resNetworkResult", "(Ljava/io/FileDescriptor;)[B", (void*) android_net_utils_resNetworkResult }, + { "resNetworkCancel", "(Ljava/io/FileDescriptor;)V", (void*) android_net_utils_resNetworkCancel }, }; int register_android_net_NetworkUtils(JNIEnv* env) diff --git a/core/jni/android_util_StatsLog.cpp b/core/jni/android_util_StatsLog.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e749d34035dd4d66c4ec4fe20ff2a99061516806 --- /dev/null +++ b/core/jni/android_util_StatsLog.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_NAMESPACE "StatsLog.tag." +#define LOG_TAG "StatsLog_println" + +#include +#include + +#include "jni.h" +#include +#include "utils/misc.h" +#include "core_jni_helpers.h" +#include "stats_event_list.h" + +namespace android { + +static void android_util_StatsLog_writeRaw(JNIEnv* env, jobject clazz, jbyteArray buf, jint size) +{ + if (buf == NULL) { + return; + } + jint actualSize = env->GetArrayLength(buf); + if (actualSize < size) { + return; + } + + jbyte* bufferArray = env->GetByteArrayElements(buf, NULL); + if (bufferArray == NULL) { + return; + } + const uint32_t statsEventTag = 1937006964; + struct iovec vec[2]; + vec[0].iov_base = (void*) &statsEventTag; + vec[0].iov_len = sizeof(statsEventTag); + vec[1].iov_base = (void*) bufferArray; + vec[1].iov_len = size; + write_to_statsd(vec, 2); + + env->ReleaseByteArrayElements(buf, bufferArray, 0); +} + +/* + * JNI registration. + */ +static const JNINativeMethod gMethods[] = { + /* name, signature, funcPtr */ + { "writeRaw", "([BI)V", (void*) android_util_StatsLog_writeRaw }, +}; + +int register_android_util_StatsLog(JNIEnv* env) +{ + return RegisterMethodsOrDie(env, "android/util/StatsLog", gMethods, NELEM(gMethods)); +} + +}; // namespace android diff --git a/core/jni/android_view_InputDevice.cpp b/core/jni/android_view_InputDevice.cpp index a698d66965e44d5c1948883ada955b1633db67f3..9f4e3e516adaa5e0230f39413b961244126e523f 100644 --- a/core/jni/android_view_InputDevice.cpp +++ b/core/jni/android_view_InputDevice.cpp @@ -68,9 +68,8 @@ jobject android_view_InputDevice_create(JNIEnv* env, const InputDeviceInfo& devi deviceInfo.getKeyboardType(), kcmObj.get(), deviceInfo.hasVibrator(), hasMic, deviceInfo.hasButtonUnderPad())); - const Vector& ranges = deviceInfo.getMotionRanges(); - for (size_t i = 0; i < ranges.size(); i++) { - const InputDeviceInfo::MotionRange& range = ranges.itemAt(i); + const std::vector& ranges = deviceInfo.getMotionRanges(); + for (const InputDeviceInfo::MotionRange& range: ranges) { env->CallVoidMethod(inputDeviceObj.get(), gInputDeviceClassInfo.addMotionRange, range.axis, range.source, range.min, range.max, range.flat, range.fuzz, range.resolution); if (env->ExceptionCheck()) { diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp index 4a6c72bda283c1c614f92ad6974333c126dbf566..94f96babaf90bb7c9492dc71c5198d3e45d408d3 100644 --- a/core/jni/android_view_SurfaceControl.cpp +++ b/core/jni/android_view_SurfaceControl.cpp @@ -126,6 +126,41 @@ static struct { jfieldID white; } gDisplayPrimariesClassInfo; +static struct { + jclass clazz; + jmethodID builder; +} gScreenshotGraphicBufferClassInfo; + +class JNamedColorSpace { +public: + // ColorSpace.Named.SRGB.ordinal() = 0; + static constexpr jint SRGB = 0; + + // ColorSpace.Named.DISPLAY_P3.ordinal() = 6; + static constexpr jint DISPLAY_P3 = 6; +}; + +constexpr jint fromDataspaceToNamedColorSpaceValue(const ui::Dataspace dataspace) { + switch (dataspace) { + case ui::Dataspace::DISPLAY_P3: + return JNamedColorSpace::DISPLAY_P3; + default: + return JNamedColorSpace::SRGB; + } +} + +constexpr ui::Dataspace pickDataspaceFromColorMode(const ui::ColorMode colorMode) { + switch (colorMode) { + case ui::ColorMode::DISPLAY_P3: + case ui::ColorMode::BT2100_PQ: + case ui::ColorMode::BT2100_HLG: + case ui::ColorMode::DISPLAY_BT2020: + return ui::Dataspace::DISPLAY_P3; + default: + return ui::Dataspace::V0_SRGB; + } +} + // ---------------------------------------------------------------------------- static jlong nativeCreateTransaction(JNIEnv* env, jclass clazz) { @@ -210,9 +245,12 @@ static jobject nativeScreenshot(JNIEnv* env, jclass clazz, if (displayToken == NULL) { return NULL; } + const ui::ColorMode colorMode = SurfaceComposerClient::getActiveColorMode(displayToken); + const ui::Dataspace dataspace = pickDataspaceFromColorMode(colorMode); + Rect sourceCrop = rectFromObj(env, sourceCropObj); sp buffer; - status_t res = ScreenshotClient::capture(displayToken, ui::Dataspace::V0_SRGB, + status_t res = ScreenshotClient::capture(displayToken, dataspace, ui::PixelFormat::RGBA_8888, sourceCrop, width, height, useIdentityTransform, rotation, captureSecureLayers, &buffer); @@ -220,13 +258,15 @@ static jobject nativeScreenshot(JNIEnv* env, jclass clazz, return NULL; } - return env->CallStaticObjectMethod(gGraphicBufferClassInfo.clazz, - gGraphicBufferClassInfo.builder, + const jint namedColorSpace = fromDataspaceToNamedColorSpaceValue(dataspace); + return env->CallStaticObjectMethod(gScreenshotGraphicBufferClassInfo.clazz, + gScreenshotGraphicBufferClassInfo.builder, buffer->getWidth(), buffer->getHeight(), buffer->getPixelFormat(), (jint)buffer->getUsage(), - (jlong)buffer.get()); + (jlong)buffer.get(), + namedColorSpace); } static jobject nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject layerHandleToken, @@ -243,20 +283,23 @@ static jobject nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject layerHandl } sp buffer; - status_t res = ScreenshotClient::captureChildLayers(layerHandle, ui::Dataspace::V0_SRGB, + const ui::Dataspace dataspace = ui::Dataspace::V0_SRGB; + status_t res = ScreenshotClient::captureChildLayers(layerHandle, dataspace, ui::PixelFormat::RGBA_8888, sourceCrop, frameScale, &buffer); if (res != NO_ERROR) { return NULL; } - return env->CallStaticObjectMethod(gGraphicBufferClassInfo.clazz, - gGraphicBufferClassInfo.builder, + const jint namedColorSpace = fromDataspaceToNamedColorSpaceValue(dataspace); + return env->CallStaticObjectMethod(gScreenshotGraphicBufferClassInfo.clazz, + gScreenshotGraphicBufferClassInfo.builder, buffer->getWidth(), buffer->getHeight(), buffer->getPixelFormat(), (jint)buffer->getUsage(), - (jlong)buffer.get()); + (jlong)buffer.get(), + namedColorSpace); } static void nativeApplyTransaction(JNIEnv* env, jclass clazz, jlong transactionObj, jboolean sync) { @@ -1306,9 +1349,13 @@ static const JNINativeMethod sSurfaceControlMethods[] = { (void*)nativeSetOverrideScalingMode }, {"nativeGetHandle", "(J)Landroid/os/IBinder;", (void*)nativeGetHandle }, - {"nativeScreenshot", "(Landroid/os/IBinder;Landroid/graphics/Rect;IIZIZ)Landroid/graphics/GraphicBuffer;", + {"nativeScreenshot", + "(Landroid/os/IBinder;Landroid/graphics/Rect;IIZIZ)" + "Landroid/view/SurfaceControl$ScreenshotGraphicBuffer;", (void*)nativeScreenshot }, - {"nativeCaptureLayers", "(Landroid/os/IBinder;Landroid/graphics/Rect;F)Landroid/graphics/GraphicBuffer;", + {"nativeCaptureLayers", + "(Landroid/os/IBinder;Landroid/graphics/Rect;F)" + "Landroid/view/SurfaceControl$ScreenshotGraphicBuffer;", (void*)nativeCaptureLayers }, {"nativeSetInputWindowInfo", "(JJLandroid/view/InputWindowHandle;)V", (void*)nativeSetInputWindowInfo }, @@ -1386,6 +1433,14 @@ int register_android_view_SurfaceControl(JNIEnv* env) gGraphicBufferClassInfo.builder = GetStaticMethodIDOrDie(env, graphicsBufferClazz, "createFromExisting", "(IIIIJ)Landroid/graphics/GraphicBuffer;"); + jclass screenshotGraphicsBufferClazz = FindClassOrDie(env, + "android/view/SurfaceControl$ScreenshotGraphicBuffer"); + gScreenshotGraphicBufferClassInfo.clazz = + MakeGlobalRefOrDie(env, screenshotGraphicsBufferClazz); + gScreenshotGraphicBufferClassInfo.builder = GetStaticMethodIDOrDie(env, + screenshotGraphicsBufferClazz, + "createFromNative", "(IIIIJI)Landroid/view/SurfaceControl$ScreenshotGraphicBuffer;"); + jclass displayedContentSampleClazz = FindClassOrDie(env, "android/hardware/display/DisplayedContentSample"); gDisplayedContentSampleClassInfo.clazz = MakeGlobalRefOrDie(env, displayedContentSampleClazz); diff --git a/core/proto/android/app/settings_enums.proto b/core/proto/android/app/settings_enums.proto index f03740725fe1d465c66edf40830bce6706eb0de8..b4be3f59960449884525f84a755cc71fc860aad2 100644 --- a/core/proto/android/app/settings_enums.proto +++ b/core/proto/android/app/settings_enums.proto @@ -590,6 +590,13 @@ enum Action { // OS: P DIALOG_SWITCH_HFP_DEVICES = 1416; + // OPEN: QS Sensor Privacy Mode tile shown + // ACTION: QS Sensor Privacy Mode tile tapped + // SUBTYPE: 0 is off, 1 is on + // CATEGORY: QUICK_SETTINGS + // OS: Q + QS_SENSOR_PRIVACY = 1598; + // ACTION: Tap & Pay -> Default Application Setting -> Use Forground ACTION_NFC_PAYMENT_FOREGROUND_SETTING = 1622; @@ -2309,4 +2316,7 @@ enum PageId { // OPEN: Settings > Face > Remove face // OS: Q DIALOG_FACE_REMOVE = 1693; + + // Settings > Display > Theme + DARK_UI_SETTINGS = 1698; } diff --git a/core/proto/android/stats/connectivity/Android.bp b/core/proto/android/stats/connectivity/Android.bp new file mode 100644 index 0000000000000000000000000000000000000000..5aa4ddbdf7f9638972467758ad7f8273d5b08074 --- /dev/null +++ b/core/proto/android/stats/connectivity/Android.bp @@ -0,0 +1,25 @@ +// Copyright (C) 2019 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +java_library_static { + name: "networkstackprotosnano", + proto: { + type: "nano", + }, + srcs: [ + "network_stack.proto", + ], + sdk_version: "system_current", + no_framework_libs: true, +} \ No newline at end of file diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/SettingsCompat.java b/core/proto/android/stats/connectivity/network_stack.proto similarity index 63% rename from packages/SystemUI/shared/src/com/android/systemui/shared/system/SettingsCompat.java rename to core/proto/android/stats/connectivity/network_stack.proto index c16cf92a5e8f8dff3010aad12655ecd160516ff5..7d9aa1c6eb230ab293eb7cea7af81a1c6a3619b3 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/SettingsCompat.java +++ b/core/proto/android/stats/connectivity/network_stack.proto @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 The Android Open Source Project + * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,15 +11,16 @@ * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and - * limitations under the License + * limitations under the License. */ -package com.android.systemui.shared.system; +syntax = "proto2"; -import android.provider.Settings; +package android.stats.connectivity; +option java_multiple_files = true; +option java_outer_classname = "NetworkStackProto"; -public class SettingsCompat { +message NetworkStackEventData { - public static final String SWIPE_UP_SETTING_NAME - = Settings.Secure.SWIPE_UP_TO_SWITCH_APPS_ENABLED; } + diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 5427147aa32a387efb0825c774441fe6344673b7..8bfa038c8e8f8b510050f2811823119c93a7f94a 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -1849,8 +1849,8 @@ - - + + + + @@ -4420,6 +4426,13 @@ + + + + + + + android:color="?android:attr/colorControlHighlight"> diff --git a/core/res/res/layout/chooser_row.xml b/core/res/res/layout/chooser_row.xml index d4585eb1e6fcd927dff19dd25b78596b8c06b44f..742d7eedaceddba9714757f7476771cfa4d51e02 100644 --- a/core/res/res/layout/chooser_row.xml +++ b/core/res/res/layout/chooser_row.xml @@ -21,8 +21,8 @@ android:layout_width="match_parent" android:layout_height="100dp" android:gravity="start|top" - android:paddingStart="@dimen/chooser_grid_padding" - android:paddingEnd="@dimen/chooser_grid_padding"> + android:paddingStart="@dimen/chooser_edge_margin_normal" + android:paddingEnd="@dimen/chooser_edge_margin_normal"> - - - - + "‏الاتصال عبر WiFi" "VoWifi" "إيقاف" - "‏شبكة Wi-Fi مفضّلة" - "شبكة بيانات الجوال مفضَّلة" + + + + "‏Wi-Fi فقط" "{0}: لم تتم إعادة التوجيه" "{0}: {1}" @@ -236,7 +238,8 @@ "تقرير الأخطاء" "إنهاء الجلسة" "لقطة شاشة" - "إعداد تقرير بالأخطاء" + + "سيجمع هذا معلومات حول حالة جهازك الحالي لإرسالها كرسالة إلكترونية، ولكنه سيستغرق وقتًا قليلاً من بدء عرض تقرير بالأخطاء. وحتى يكون جاهزًا للإرسال، يُرجى الانتظار." "تقرير تفاعلي" "يمكنك استخدام هذا الخيار في معظم الأحيان، حيث يتيح لك إمكانية تتبع مستوى تقدم التقرير والحصول على مزيد من المعلومات حول المشكلة وتسجيل لقطات شاشة. وقد يتم إغفال بعض الأقسام الأقل استخدامًا والتي تستغرق وقتًا طويلاً أثناء إعداد التقرير." @@ -293,9 +296,12 @@ "الموقع الجغرافي" "الوصول إلى موقع هذا الجهاز" "‏هل تريد السماح لتطبيق <b>%1$s</b> بالوصول إلى الموقع الجغرافي لهذا الجهاز؟" - "لن يكون بإمكان التطبيق الوصول إلى الموقع الجغرافي إلا عند استخدامك لهذا التطبيق." - "‏هل تريد السماح دائمًا لتطبيق <b>%1$s</b> بالوصول إلى الموقع الجغرافي لهذا الجهاز؟" - "سيكون بإمكان التطبيق دائمًا الوصول إلى الموقع الجغرافي، حتى عند عدم استخدامك لهذا التطبيق." + + + + + + "التقويم" "الوصول تقويمك" "‏هل تريد السماح لتطبيق <b>%1$s</b> بالدخول إلى التقويم؟" @@ -328,7 +334,10 @@ "‏هل تريد السماح لتطبيق <b>%1$s</b> بالوصول إلى الموسيقى؟" "الصور والفيديوهات" "الوصول إلى صورك وفيديوهاتك" - "‏هل تريد السماح للتطبيق <b>%1$s</b> بالوصول إلى صورك وفيديوهاتك، بما في ذلك المواقع الجغرافية ذات العلامات؟" + + + + "استرداد محتوى النافذة" "فحص محتوى نافذة يتم التفاعل معها" "تشغيل الاستكشاف باللمس" @@ -521,8 +530,10 @@ "‏للسماح للتطبيق بالاتصال بعلامات الاتصال قريب المدى (NFC)، والبطاقات وبرامج القراءة." "إيقاف قفل الشاشة" "للسماح للتطبيق بإيقاف تأمين المفاتيح وأي أمان لكلمة مرور مرتبطة. على سبيل المثال، يعطل الهاتف تأمين المفاتيح عند استقبال مكالمة هاتفية واردة، ثم يعيد تفعيل تأمين المفاتيح عند انتهاء المكالمة." - "طلب معرفة مستوى صعوبة قفل الشاشة" - "للسماح للتطبيق بمعرفة مستوى صعوبة قفل الشاشة (عالي أو متوسط أو منخفض الصعوبة أو بدون)، والذي يحدّد النطاق المحتمل لطول ونوع قفل الشاشة. ويمكن أن يقترح التطبيق للمستخدمين أيضًا تعديل قفل الشاشة إلى مستوى معيّن، ولهم مطلق الحرية في تجاهل هذا الاقتراح ورفضه. وتجدر الإشارة إلى أنه لا يتم حفظ قفل الشاشة في نص عادي، لذا لا يعرف التطبيق كلمة المرور تحديدًا." + + + + "استخدام الأجهزة البيومترية" "للسماح للتطبيق باستخدام الأجهزة البيومترية للمصادقة" "لإدارة أجهزة بصمة الإصبع" @@ -577,37 +588,59 @@ "السماح للتطبيق باستدعاء طرق لإضافة نماذج من الوجوه وحذفها" "استخدام أجهزة مصادقة الوجه" "السماح للتطبيق باستخدام أجهزة مصادقة الوجه" - "تعذَّر التعرُّف على الوجه. يُرجى إعادة المحاولة." - "الوجه ساطع جدًا. يُرجى إعادة المحاولة بإضاءة أقل." - "الوجه مظلم جدًا. يُرجى الاستعانة بمصدر إضاءة." - "يُرجى إبعاد جهاز الاستشعار عن الوجه." - "يُرجى تقريب جهاز الاستشعار من الوجه." - "يُرجى تحريك جهاز الاستشعار للأعلى." - "يُرجى تحريك جهاز الاستشعار للأسفل." - "يُرجى تحريك جهاز الاستشعار جهة اليمين." - "يُرجى تحريك جهاز الاستشعار جهة اليسار." - "يُرجى النظر إلى جهاز الاستشعار." - "لم يتم رصد أي وجه." - "حركة أكثر من اللازم" + + + + + + + + + + + + + + + + + + + + + + + + "يُرجى إعادة تسجيل وجهك." - "تم التعرّف على وجه مختلف." + + "الوجه مشابه جدًا، يُرجى تغيير وضعيتك." - "يُرجى النظر إلى الكاميرا مباشرة أكثر." - "يُرجى النظر إلى الكاميرا مباشرة أكثر." + + + + "يُرجى تثبيت الرأس في وضع عمودي." - "يُرجى الكشف عن وجهك." + + + + "أجهزة مصادقة الوجه غير متاحة." - "انتهت مهلة التعرُّف على الوجه. أعِد المحاولة." + + "يتعذَّر حفظ الوجه." "تمّ إلغاء عملية مصادقة الوجه." "ألغَى المستخدم مصادقة الوجه." "تمّ إجراء محاولات كثيرة. أعِد المحاولة لاحقًا." "تمّ إجراء محاولات كثيرة. ميزة مصادقة الوجه متوقفة." - "يُرجى إعادة المحاولة." - "ليس هناك وجه مسجّل." - "لا يحتوي هذا الجهاز على مستشعِر مصادقة للوجه." + + + + + + "الوجه %d" @@ -1293,9 +1326,16 @@ "فتح %1$s" "سيتم إغلاق %1$s من دون حفظ" "لقد تجاوزت %1$s حد الذاكرة." + + "تم جمع مقدار كبير من بيانات الذاكرة. انقر للمشاركة." "هل تريد مشاركة نَسْخ الذاكرة؟" - "تجاوزت عملية %1$s حد الذاكرة المخصص لها وقدره %2$s، ويتوفر نَسْخ للذاكرة لمشاركته مع مطور برامج العملية ولكن توخ الحذر حيث قد يحتوي نَسْخ الذاكرة هذا على معلومات شخصية يملك التطبيق حق الوصول إليها." + + + + + + "اختيار إجراء للنص" "مستوى صوت الرنين" "مستوى صوت الوسائط" @@ -1342,8 +1382,10 @@ "انقر للاطلاع على جميع الشبكات" "اتصال" "جميع الشبكات" - "‏تتوفَّر شبكة Wi‑Fi مقترَحة من قِبَل %s." - "هل ترغب في الاتصال بالشبكات المقترَحة من %s؟" + + + + "نعم" "لا" "‏سيتم تشغيل شبكة Wi-Fi تلقائيًا." @@ -1355,9 +1397,14 @@ "تسجيل الدخول إلى الشبكة" - "‏شبكة Wi-Fi غير متصلة بالإنترنت" + + "انقر للحصول على الخيارات." "تمّ الاتصال." + + + + "التغييرات التي طرأت على إعدادات نقطة الاتصال" "تمّ تغيير نطاق نقطة الاتصال الخاصة بك." "لا يتوافق هذا الجهاز مع إعدادك المفضّل الخاص باستخدام النطاق 5 غيغاهرتز فقط. وسيستخدم الجهاز بدلاً من ذلك النطاق 5 غيغاهرتز عندما يكون متاحًا." @@ -1442,6 +1489,10 @@ "‏تم توصيل تصحيح أخطاء USB" "‏انقر لإيقاف تصحيح أخطاء USB." "‏اختيار إيقاف تصحيح أخطاء USB." + + + + "‏السوائل والشوائب في منفذ USB" "‏تمّ إيقاف منفذ USB تلقائيًا. انقُر لمعرفة المزيد من المعلومات." "‏الأمان في استخدام منفذ USB" @@ -2041,8 +2092,6 @@ "انقر لإلغاء قفل الملف الشخصي للعمل" "تم الاتصال بـ %1$s" "انقر لعرض الملفات" - "تثبيت" - "إزالة تثبيت" "معلومات عن التطبيق" "−%1$s" "جارٍ بدء العرض التوضيحي…" @@ -2137,6 +2186,22 @@ "إشعار معلومات \"وضع سلسلة الإجراءات\"" "قد تنفد طاقة البطارية قبل الشحن المعتاد" "تم تفعيل \"توفير شحن البطارية\" لإطالة عمرها." + + + + + + + + + + + + + + + + "مجلّد" "‏تطبيق Android" "ملف" diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml index 3e784b9c8ece1751a10905abe96d9f59df50d117..da6ccb0ba68b4e2e30347339f35ddda97619d422 100644 --- a/core/res/res/values-ca/strings.xml +++ b/core/res/res/values-ca/strings.xml @@ -141,8 +141,10 @@ "Trucades per Wi‑Fi" "VoWifi" "Desactivat" - "Preferència per la Wi-Fi" - "Preferència per dades mòbils" + + + + "Només Wi-Fi" "{0}: no s\'ha desviat" "{0}: {1}" @@ -228,7 +230,8 @@ "Informe d\'error" "Finalitza la sessió" "Captura de pantalla" - "Crea informe d\'errors" + + "Es recopilarà informació sobre l\'estat actual del dispositiu i se t\'enviarà per correu electrònic. Passaran uns quants minuts des de l\'inici de l\'informe d\'errors fins al seu enviament, per la qual cosa et recomanem que tinguis paciència." "Informe interactiu" "Utilitza aquesta opció en la majoria de circumstàncies. Et permet fer un seguiment del progrés de l\'informe, introduir més dades sobre el problema i fer captures de pantalla. És possible que ometi seccions poc utilitzades que requereixen molt de temps." @@ -281,9 +284,12 @@ "Ubicació" "accedir a la ubicació del dispositiu" "Vols permetre que <b>%1$s</b> accedeixi a la ubicació del dispositiu?" - "L\'aplicació només tindrà accés a la ubicació quan l\'estiguis utilitzant." - "Vols permetre que <b>%1$s</b> accedeixi sempre a la ubicació del dispositiu?" - "L\'aplicació tindrà accés sempre a la ubicació, fins i tot quan no l\'estiguis utilitzant." + + + + + + "Calendari" "accedir al calendari" "Vols permetre que <b>%1$s</b> accedeixi al calendari?" @@ -316,7 +322,10 @@ "Vols permetre que <b>%1$s</b> accedeixi a la teva música?" "Fotos i vídeos" "accedir a les teves fotos i als teus vídeos" - "Vols permetre que <b>%1$s</b> accedeixi a les fotos i als vídeos, incloses les ubicacions etiquetades?" + + + + "Recuperar el contingut de la finestra" "Inspecciona el contingut d\'una finestra amb què estàs interaccionant." "Activar Exploració tàctil" @@ -509,8 +518,10 @@ "Permet que l\'aplicació es comuniqui amb les etiquetes, les targetes i els lectors de Comunicació de camp proper (NFC)." "desactivació del bloqueig de pantalla" "Permet que l\'aplicació desactivi el bloqueig del teclat i qualsevol element de seguretat de contrasenyes associat. Per exemple, el telèfon desactiva el bloqueig del teclat en rebre una trucada entrant i, a continuació, reactiva el bloqueig del teclat quan finalitza la trucada." - "sol·licita una determinada complexitat del bloqueig de pantalla" - "Permet que l\'aplicació conegui el nivell de complexitat del bloqueig de pantalla (alt, mitjà, baix o cap), que indica la llargària i el tipus de bloqueig de pantalla possibles. L\'aplicació també pot suggerir que els usuaris actualitzin el bloqueig de pantalla a un nivell determinat, però els usuaris poden ignorar aquestes recomanacions. Tingues en compte que el bloqueig de pantalla no s\'emmagatzema com a text sense format, de manera que l\'aplicació no coneix la contrasenya exacta." + + + + "utilitza maquinari biomètric" "Permet que l\'aplicació faci servir maquinari biomètric per a l\'autenticació" "Gestionar el maquinari d\'empremtes digitals" @@ -565,37 +576,59 @@ "Permet que l\'aplicació afegeixi i suprimeixi plantilles de cares que es puguin fer servir." "utilitza el maquinari d\'autenticació facial" "Permet que l\'aplicació faci servir maquinari d\'autenticació facial" - "Error en processar la cara. Torna-ho a provar." - "La cara brilla massa. Prova amb menys llum." - "La cara és massa fosca. Prova amb més llum." - "Allunya el sensor de la cara." - "Apropa el sensor a la cara." - "Puja el sensor més amunt." - "Baixa el sensor més avall." - "Mou el sensor cap a la dreta." - "Mou el sensor cap a l\'esquerra." - "Mira el sensor." - "No s\'ha detectat cap cara." - "Massa moviment." + + + + + + + + + + + + + + + + + + + + + + + + "Torna a registrar la teva cara." - "S\'ha detectat una altra cara." + + "És massa semblant; canvia de postura." - "Mira més directament cap a la càmera." - "Mira més directament cap a la càmera." + + + + "Mantén el cap recte, sense inclinar-lo." - "No et tapis la cara." + + + + "Maquinari de reconeixement facial no disponible." - "S\'ha esgotat el temps d\'espera. Torna-ho a provar." + + "La cara no es pot desar." "S\'ha cancel·lat el reconeixement facial." "Autenticació facial cancel·lada per l\'usuari." "Massa intents. Torna-ho a provar més tard." "Massa intents. Autenticació facial desactivada." - "Torna-ho a provar." - "No s\'ha registrat cap cara." - "Aquest dispositiu no té sensor d\'autenticació facial." + + + + + + "Cara %d" @@ -1213,9 +1246,16 @@ "Obre %1$s" "%1$s es tancarà sense desar els canvis" "%1$s ha superat el límit de memòria" + + "S\'ha recopilat un procés \"heap dump\". Toca per compartir-lo." "Vols compartir el \"heap dump\"?" - "El procés %1$s ha superat el límit de %2$s de memòria del procés. Hi ha un procés \"heap dump\" disponible perquè el comparteixis amb el desenvolupador. Ves amb compte: aquest \"heap dump\" pot contenir les dades personals a les quals l\'aplicació tingui accés." + + + + + + "Tria una acció per al text" "Volum del timbre" "Volum de multimèdia" @@ -1254,8 +1294,10 @@ "Toca per veure totes les xarxes" "Connecta" "Totes les xarxes" - "Hi ha disponible una xarxa Wi‑Fi proposada per %s" - "Vols connectar-te a les xarxes proposades per %s?" + + + + "Sí" "No" "La Wi-Fi s\'activarà automàticament" @@ -1267,9 +1309,14 @@ "Inicia la sessió a la xarxa" - "La Wi-Fi no té accés a Internet" + + "Toca per veure les opcions" - "S\'ha establert la connexió" + "Connectat" + + + + "Canvis en la configuració del punt d\'accés Wi-Fi" "Ha canviat la teva banda del punt d\'accés Wi-Fi." "Aquest dispositiu no admet utilitzar exclusivament una banda de 5 GHz. El dispositiu utilitzarà una banda de 5 GHz quan estigui disponible." @@ -1354,6 +1401,10 @@ "Depuració per USB activada" "Toca per desactivar la depuració per USB" "Selecciona per desactivar la depuració per USB" + + + + "Hi ha líquid o pols al port USB" "El port USB es desactiva automàticament. Toca per obtenir més informació." "És segur utilitzar el port USB" @@ -1905,8 +1956,6 @@ "Toca per desbloquejar el perfil" "S\'ha connectat a %1$s" "Toca per veure els fitxers" - "Fixa" - "No fixis" "Informació de l\'aplicació" "-%1$s" "S\'està iniciant la demostració…" @@ -1997,6 +2046,22 @@ "Notificació d\'informació del mode de rutina" "És possible que la bateria s\'esgoti abans de la càrrega habitual" "S\'ha activat l\'estalvi de bateria per allargar-ne la durada" + + + + + + + + + + + + + + + + "Carpeta" "Aplicació per a Android" "Fitxer" diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index a790b504eaf21f315998c550207dafcac026c53c..4344b3d8eff304d0299bfd29c0529b7bf22840dc 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -63,7 +63,7 @@ "Rufweiterleitung" "Anklopfen" "Anrufsperre" - "Passwort-Änderung" + "Passwortänderung" "PIN-Änderung" "Rufnummer vorhanden" "Rufnummer begrenzt" @@ -141,8 +141,10 @@ "WLAN-Telefonie" "VoWifi" "Aus" - "WLAN bevorzugt" - "Mobilverbindung bevorzugt" + + + + "Nur WLAN" "{0}: Nicht weitergeleitet" "{0}: {1}" @@ -228,7 +230,8 @@ "Fehlerbericht" "Sitzung beenden" "Screenshot" - "Fehlerbericht abrufen" + + "Bei diesem Fehlerbericht werden Daten zum aktuellen Status deines Geräts erfasst und als E-Mail versandt. Vom Start des Berichts bis zu seinem Versand kann es eine Weile dauern. Bitte habe etwas Geduld." "Interaktiver Bericht" "Diese Option kann in den meisten Fällen verwendet werden. Du kannst darüber den aktuellen Stand der Berichterstellung verfolgen, genauere Angaben zu dem Problem machen und Screenshots aufnehmen. Einige selten genutzte Bereiche, deren Berichterstellung längere Zeit in Anspruch nimmt, werden unter Umständen ausgelassen." @@ -281,9 +284,12 @@ "Standort" "auf den Standort deines Geräts zugreifen" "<b>%1$s</b> erlauben, den Gerätestandort abzurufen?" - "Die App hat nur Zugriff auf den Gerätestandort, wenn du sie verwendest." - "<b>%1$s</b> immer erlauben, den Gerätestandort abzurufen?" - "Die App hat immer Zugriff auf den Gerätestandort, auch wenn du sie gerade nicht verwendest." + + + + + + "Kalender" "auf deinen Kalender zugreifen" "<b>%1$s</b> Zugriff auf deinen Kalender erlauben?" @@ -316,7 +322,10 @@ "<b>%1$s</b> Zugriff auf deine Musik gewähren?" "Fotos & Videos" "auf meine Fotos und Videos zugreifen" - "<b>%1$s</b> Zugriff auf deine Fotos und Videos gewähren, einschließlich gekennzeichneter Standorte?" + + + + "Fensterinhalte abrufen" "Die Inhalte eines Fensters, mit dem du interagierst, werden abgerufen." "\"Tippen & Entdecken\" aktivieren" @@ -509,8 +518,10 @@ "Ermöglicht der App die Kommunikation mit Tags für die Nahfeldkommunikation, Karten und Readern" "Displaysperre deaktivieren" "Ermöglicht der App, die Tastensperre sowie den damit verbundenen Passwortschutz zu deaktivieren. Das Telefon deaktiviert die Tastensperre beispielsweise, wenn ein Anruf eingeht, und aktiviert sie wieder, nachdem das Gespräch beendet wurde." - "Komplexitätsstufe der Displaysperre anfragen" - "Ermöglicht es der App, die Komplexitätsstufe der Displaysperre (hoch, mittel, niedrig oder keine) zu erfahren, was auf die mögliche Dauer und Art der Displaysperre hinweist. Die App kann Nutzern auch vorschlagen, dass sie die Displaysperre auf eine bestimmte Stufe aktualisieren, Nutzer können diesen Vorschlag jedoch einfach ignorieren und fortfahren. Beachten Sie, dass die Displaysperre nicht im Klartext gespeichert ist, sodass die App nicht das genaue Passwort kennt." + + + + "Biometrische Hardware verwenden" "Erlaubt der App, biometrische Hardware zur Authentifizierung zu verwenden" "Fingerabdruckhardware verwalten" @@ -565,37 +576,59 @@ "Ermöglicht der App, Gesichtsvorlagen hinzuzufügen oder zu entfernen." "Gesichtserkennungshardware verwenden" "Ermöglicht der App, für die Authentifizierung Gesichtserkennungshardware zu verwenden" - "Kann Gesicht nicht verarbeiten. Versuch es erneut." - "Gesicht zu hell. Bei weniger Licht versuchen." - "Gesicht zu dunkel. Bei mehr Licht versuchen." - "Sensor weiter weg vom Gesicht halten." - "Sensor näher an das Gesicht halten." - "Sensor höher halten." - "Sensor niedriger halten." - "Sensor nach rechts bewegen." - "Sensor nach links bewegen." - "Blick auf den Sensor richten." - "Kein Gesicht erkannt." - "Bitte halte das Gerät ruhig." + + + + + + + + + + + + + + + + + + + + + + + + "Bitte registriere dein Gesicht noch einmal." - "Anderes Gesicht erkannt." + + "Zu ähnlich. Bitte dreh deinen Kopf etwas." - "Bitte sieh direkt in die Kamera." - "Bitte sieh direkt in die Kamera." + + + + "Bitte halte deinen Kopf gerade." - "Dein Gesicht darf nicht verdeckt sein." + + + + "Hardware zur Gesichtserkennung nicht verfügbar." - "Zeitüberschreitung für Gesicht. Versuch es erneut." + + "Gesicht kann nicht gespeichert werden." "Gesichtserkennung abgebrochen." "Gesichtsauthentifizierung vom Nutzer abgebrochen." "Zu viele Versuche, bitte später noch einmal versuchen" "Zu viele Versuche. Gesichtserkennung deaktiviert." - "Versuch es noch einmal." - "Kein Gesicht erfasst." - "Dieses Gerät hat keinen Sensor zur Gesichtserkennung." + + + + + + "Gesicht %d" @@ -1213,9 +1246,16 @@ "%1$s öffnen" "%1$s wird ohne Speichern geschlossen" "Speicherlimit für \"%1$s\" überschritten" + + "Heap-Dump wurde erfasst. Tippe, um ihn zu teilen." "Heap-Dump teilen?" - "Für den Prozess \"%1$s\" wurde das Prozessspeicherlimit von %2$s überschritten. Es steht ein Heap-Dump zur Verfügung, den du mit dem Entwickler teilen kannst. Beachte jedoch unbedingt, dass der Heap-Dump personenbezogene Daten von dir enthalten kann, auf die die App zugreifen kann." + + + + + + "Aktion für Text auswählen" "Klingeltonlautstärke" "Medienlautstärke" @@ -1254,8 +1294,10 @@ "Tippen, um alle Netzwerke zu sehen" "Verbinden" "Alle Netzwerke" - "Ein von %s vorgeschlagenes WLAN-Netzwerk ist verfügbar" - "Möchtest du eine Verbindung zu den von %s vorgeschlagenen Netzwerken herstellen?" + + + + "Ja" "Nein" "WLAN wird automatisch aktiviert" @@ -1267,9 +1309,14 @@ "Im Netzwerk anmelden" - "WLAN hat keinen Internetzugriff" + + "Für Optionen tippen" "Verbunden" + + + + "Änderungen an deinen Hotspot-Einstellungen" "Dein Hotspot-Band hat sich geändert." "Dieses Gerät unterstützt die ausschließliche Nutzung von 5 GHz nicht. Es greift aber immer auf das 5-GHz-Band zurück, wenn dieses verfügbar ist." @@ -1354,6 +1401,10 @@ "USB-Debugging aktiviert" "Zum Deaktivieren von USB-Debugging tippen" "USB-Debugging deaktivieren: auswählen" + + + + "Flüssigkeiten oder Fremdkörper im USB-Port" "Der USB-Port wird automatisch deaktiviert. Für weitere Informationen tippen." "USB-Port kann wieder sicher verwendet werden" @@ -1905,8 +1956,6 @@ "Zum Entsperren des Arbeitsprofils tippen" "Verbunden mit %1$s" "Zum Ansehen der Dateien tippen" - "Markieren" - "Markierung entfernen" "App-Informationen" "−%1$s" "Demo wird gestartet…" @@ -1997,6 +2046,22 @@ "Infomitteilung zum Ablaufmodus" "Dein Akku könnte vor der gewöhnlichen Ladezeit leer sein" "Energiesparmodus aktiviert, um die Akkulaufzeit zu verlängern" + + + + + + + + + + + + + + + + "Ordner" "Android-App" "Datei" diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml index 017f31bf76c049f06b811086a9cb99c8f878f7ff..54a3860df985d34645b40d1e6be32f6318e6051b 100644 --- a/core/res/res/values-es/strings.xml +++ b/core/res/res/values-es/strings.xml @@ -141,9 +141,11 @@ "Llamada por Wi‑Fi" "VoWiFi" "Desactivado" - "Dar preferencia a Wi-Fi" - "Preferir datos móviles" - "Solo conexión Wi-Fi" + + + + + "Solo Wi-Fi" "{0}: No desviada" "{0}: {1}" "{0}: {1} transcurridos {2} segundos" @@ -228,7 +230,8 @@ "Informe de error" "Finalizar sesión" "Captura de pantalla" - "Crear informe de errores" + + "Se recopilará información sobre el estado actual de tu dispositivo y se enviará por correo electrónico. Pasarán unos minutos desde que empiece a generarse el informe de errores hasta que se envíe." "Informe interactivo" "Usa esta opción en la mayoría de los casos. Te permite realizar un seguimiento del progreso del informe, introducir más información sobre el problema y hacer capturas de pantalla. Es posible que se omitan algunas secciones menos utilizadas y que requieran más tiempo." @@ -281,9 +284,12 @@ "Ubicación" "acceder a la ubicación de este dispositivo" "¿Quieres permitir que <b>%1$s</b> acceda a la ubicación de este dispositivo?" - "La aplicación solo podrá acceder a la ubicación cuando estés usando la aplicación." - "¿Permites que <b>%1$s</b> acceda a ubic. del disp.?" - "La aplicación siempre podrá acceder a la ubicación, aunque no estés usando la aplicación." + + + + + + "Calendario" "acceder a tu calendario" "¿Quieres permitir que <b>%1$s</b> acceda a tu calendario?" @@ -316,7 +322,10 @@ "¿Quieres permitir que <b>%1$s</b> acceda a tu música?" "Fotos y vídeos" "acceder a tus fotos y vídeos" - "¿Quieres permitir que <b>%1$s</b> acceda a tus fotos y vídeos, así como a las ubicaciones etiquetadas?" + + + + "Comprobar el contenido de la ventana" "Inspecciona el contenido de una ventana con la que estés interactuando." "Activar la exploración táctil" @@ -509,8 +518,10 @@ "Permite que la aplicación se comunique con lectores, tarjetas y etiquetas de Comunicación de campo cercano (NFC)." "inhabilitar el bloqueo de pantalla" "Permite que la aplicación inhabilite el bloqueo del teclado y cualquier protección con contraseña asociada. Por ejemplo, el teléfono puede inhabilitar el bloqueo del teclado cuando se recibe una llamada telefónica y volver a habilitarlo cuando finaliza la llamada." - "solicitar complejidad del bloqueo de pantalla" - "Permite que la aplicación entienda el nivel de complejidad del bloqueo de pantalla (alto, medio, bajo o ninguno) que indica la longitud y el tipo del bloqueo de pantalla posibles. La aplicación también puede sugerir a los usuarios que actualicen el bloqueo de pantalla para que tenga un nivel concreto de complejidad, pero los usuarios pueden ignorar la advertencia libremente. El bloqueo de pantalla no se almacena en texto sin formato, así que la aplicación no puede saber cuál es la contraseña exacta." + + + + "usar hardware biométrico" "Permite que la aplicación utilice el hardware biométrico para realizar la autenticación" "administrar hardware de huellas digitales" @@ -565,37 +576,59 @@ "Permite que la app use métodos para añadir y suprimir plantillas de caras para su uso." "usar el hardware de autenticación facial" "Permite que la aplicación utilice el hardware de autenticación facial para autenticarte" - "No se ha reconocido la cara. Vuelve a intentarlo." - "La cara se ve muy clara. Inténtalo con menos luz." - "La cara se ve muy oscura. Inténtalo con más luz." - "Aleja la cara del sensor." - "Acerca la cara al sensor." - "Coloca el sensor más arriba." - "Coloca el sensor más abajo." - "Mueve el sensor hacia la derecha." - "Mueve el sensor hacia la izquierda." - "Mira al sensor." - "No se ha detectado ninguna cara." - "Te mueves demasiado." + + + + + + + + + + + + + + + + + + + + + + + + "Vuelve a registrar tu cara." - "Se ha detectado otra cara." + + "Se parece mucha a la anterior. Pon otra cara." - "Mira más fijamente a la cámara." - "Mira más fijamente a la cámara." + + + + "Mantén la cabeza en posición vertical." - "No te tapes la cara." + + + + "Hardware de reconocimiento facial no disponible." - "Has sobrepasado el tiempo. Inténtalo de nuevo." + + "No se pueden registrar más caras." "Se ha cancelado el reconocimiento facial." "El usuario ha cancelado la autenticación de la cara." "Demasiados intentos. Inténtalo de nuevo más tarde." "Demasiados intentos. Autent. facial inhabilitada." - "Inténtalo de nuevo." - "No has registrado ninguna cara." - "Este dispositivo no tiene sensor de autenticación facial." + + + + + + "Cara %d" @@ -1213,9 +1246,16 @@ "Abrir %1$s" "%1$s se cerrará sin guardar" "%1$s ha superado el límite de memoria" + + "Se ha recopilado un volcado de pila. Toca para compartir." "¿Compartir volcado de pila?" - "El proceso %1$s ha superado su límite de memoria de %2$s. Hay un volcado de pila disponible que puedes compartir con su desarrollador (ten cuidado, ya que puede incluir información personal a la que tenga acceso la aplicación)." + + + + + + "Selecciona una acción para el texto" "Volumen del timbre" "Volumen de multimedia" @@ -1254,8 +1294,10 @@ "Toca para ver todas las redes" "Conectarse" "Todas las redes" - "Hay disponible una red Wi‑Fi propuesta por %s" - "¿Quieres conectarte a las redes propuestas por %s?" + + + + "Sí" "No" "La conexión Wi‑Fi se activará automáticamente" @@ -1267,9 +1309,14 @@ "Iniciar sesión en la red" - "La red Wi-Fi no tiene acceso a Internet" + + "Toca para ver opciones" "Conectado" + + + + "Cambios en los ajustes de tu punto de acceso" "La banda de tu punto de acceso ha cambiado." "Este dispositivo no admite la opción de conectarse exclusivamente a bandas de 5 GHz, pero las usará cuando estén disponibles." @@ -1354,6 +1401,10 @@ "Depuración USB habilitada" "Toca para desactivar la depuración USB." "Seleccionar para inhabilitar la depuración USB" + + + + "Se ha detectado líquido o suciedad en el puerto USB" "El puerto USB se ha inhabilitado automáticamente. Toca para obtener más información." "Ya puedes usar el puerto USB" @@ -1905,8 +1956,6 @@ "Toca para desbloquear" "Conectado a %1$s" "Toca para ver archivos" - "Fijar" - "No fijar" "Información de la aplicación" "−%1$s" "Iniciando demostración…" @@ -1997,6 +2046,22 @@ "Notificación sobre el modo rutina" "Es posible que te quedes sin batería antes de lo habitual" "Se ha activado el ahorro de batería para aumentar la duración de la batería" + + + + + + + + + + + + + + + + "Carpeta" "Aplicación de Android" "Archivo" diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml index adc4dc465dd72ad29793dddfdd89c7e1ffad0c63..1ba4da2d0c1ce534952ace57909f12db9bea27c0 100644 --- a/core/res/res/values-eu/strings.xml +++ b/core/res/res/values-eu/strings.xml @@ -141,8 +141,10 @@ "Wi-Fi bidezko deiak" "VoWifi" "Desaktibatuta" - "Wi-Fi sarea hobesten da" - "Datu-konexioa hobesten da" + + + + "Wi-Fi sarea soilik" "{0}: ez da desbideratu" "{0}: {1}" @@ -228,7 +230,8 @@ "Akatsen txostena" "Amaitu saioa" "Pantaila-argazkia" - "Sortu akatsen txostena" + + "Gailuaren uneko egoerari buruzko informazioa bilduko da, mezu elektroniko gisa bidaltzeko. Minutu batzuk igaroko dira akatsen txostena sortzen hasten denetik bidaltzeko prest egon arte. Itxaron, mesedez." "Txosten dinamikoa" "Aukera hau erabili beharko zenuke ia beti. Txostenaren jarraipena egin ahal izango duzu eta arazoari buruzko xehetasunak eman ahal izango dituzu. Baliteke gutxitan erabili behar izaten diren atalak ez agertzea, denbora aurrezteko." @@ -281,9 +284,12 @@ "Kokapena" "atzitu gailuaren kokapena" "<b>%1$s</b> aplikazioari gailuaren kokapena atzitzea baimendu nahi diozu?" - "Aplikazioa erabiltzen ari zarenean soilik atzituko du aplikazioak kokapena." - "Gailuaren kokapena beti atzitzeko baimena eman nahi diozu <b>%1$s</b> aplikazioari?" - "Aplikazioak beti atzituko du kokapena, baita aplikazioa erabiltzen ari ez bazara ere." + + + + + + "Egutegia" "atzitu egutegia" "<b>%1$s</b> aplikazioari egutegia atzitzea baimendu nahi diozu?" @@ -316,7 +322,10 @@ "<b>%1$s</b> aplikazioari musika atzitzea baimendu nahi diozu?" "Argazkiak eta bideoak" "argazkiak eta bideoak atzitu" - "<b>%1$s</b> aplikazioari zure argazkiak eta bideoak (etiketatutako kokapenak barne) atzitzeko baimena eman?" + + + + "Eskuratu leihoko edukia" "Arakatu irekita daukazun leihoko edukia." "Aktibatu \"Arakatu ukituta\"" @@ -509,8 +518,10 @@ "Near Field Communication (NFC) etiketekin, txartelekin eta irakurgailuekin komunikatzea baimentzen die aplikazioei." "desgaitu pantailaren blokeoa" "Teklen blokeoa eta erlazionatutako pasahitz-segurtasuna desgaitzeko baimena ematen die aplikazioei. Adibidez, telefonoak teklen blokeoa desgaitzen du telefono-deiak jasotzen dituenean, eta berriro gaitzen du deiak amaitzean." - "eskatu pantailaren blokeoaren konplexutasuna" - "Pantailaren blokeoaren konplexutasun-maila (handia, ertaina, txikia edo bat ere ez) ezagutzeko aukera ematen dio aplikazioari; haren bidez, pantailaren blokeoaren luzeraren barruti edo mota posiblea adierazten da. Halaber, erabiltzaileei pantailaren blokeoa maila jakin batera igotzeko iradoki diezaieke aplikazioak, baina erabiltzaileek horri ez ikusi egiteko eta aplikazioa erabiltzen jarraitzeko aukera dute. Kontuan izan pantailaren blokeoa ez dela gordetzen testu arrunt gisa; beraz, aplikazioak ez du jakingo zein den pasahitz zehatza." + + + + "Erabili hardware biometrikoa" "Autentifikatzeko hardware biometrikoa erabiltzea baimentzen die aplikazioei." "kudeatu erreferentzia-gako digitalen hardwarea" @@ -565,37 +576,59 @@ "Aurpegi-txantiloiak gehitu eta ezabatzeko metodoei dei egitea baimentzen dio aplikazioari." "erabili aurpegi bidez autentifikatzeko hardwarea" "Aurpegi bidez autentifikatzeko hardwarea erabiltzea baimentzen dio aplikazioari" - "Ezin izan da prozesatu aurpegia. Saiatu berriro." - "Aurpegiak distira gehiegi du. Murriztu argitasuna." - "Aurpegia ilunegi dago. Estalgabetu argi-iturburua." - "Urrundu sentsorea aurpegitik." - "Hurbildu sentsorea aurpegira." - "Eraman sentsorea gora." - "Eraman sentsorea behera." - "Eraman sentsorea eskuinera." - "Eraman sentsorea ezkerrera." - "Begiratu sentsoreari." - "Ez dugu hauteman aurpegirik." - "Gailua gehiegi mugitu da." + + + + + + + + + + + + + + + + + + + + + + + + "Erregistratu berriro aurpegia." - "Beste aurpegi bat hauteman da." + + "Jarrera berdintsuegia da. Alda ezazu." - "Begiratu zuzenago kamerari." - "Begiratu zuzenago kamerari." + + + + "Jarri burua zuzen." - "Kendua aurpegia estaltzen dizun hori." + + + + "Aurpegia hautemateko hardwarea ez dago erabilgarri." - "Gainditu da aurpegiak prozesatzeko denbora-muga. Saiatu berriro." + + "Ezin da gorde aurpegia." "Utzi da aurpegiaren bidezko eragiketa." "Erabiltzaileak utzi du aurpegi-autentifikazioa." "Saiakera gehiegi egin dituzu. Saiatu berriro geroago." "Saiakera gehiegi egin dituzu. Desgaitu egin da autentifikazioa." - "Saiatu berriro." - "Ez dago aurpegirik erregistratuta." - "Gailu honek ez du aurpegia autentifikatzeko sentsorerik." + + + + + + "%d aurpegia" @@ -1213,9 +1246,16 @@ "Ireki %1$s" "Gorde gabe itxiko da %1$s" "%1$s prozesuak memoria-muga gainditu du" + + "Sortu da uneko memoria-prozesuaren txostena. Sakatu partekatzeko." "Uneko memoria-prozesuaren txostena partekatu nahi duzu?" - "%1$s prozesuak memoria-prozesuaren muga (%2$s) gainditu du. Uneko memoria-prozesuaren txostena sortu da, garatzailearekin parteka dezazun. Kontuz ibili: txosten horrek aplikazioak atzi dezakeen informazio pertsonala izan dezake." + + + + + + "Aukeratu testurako ekintza" "Tonu-jotzailearen bolumena" "Multimedia-edukiaren bolumena" @@ -1254,8 +1294,10 @@ "Sakatu hau sare guztiak ikusteko" "Konektatu" "Sare guztiak" - "%s aplikazioak iradokitako wifi sare bat erabil daiteke" - "%s aplikazioak iradokitako sareetara konektatu nahi zara?" + + + + "Bai" "Ez" "Wi‑Fi konexioa automatikoki aktibatuko da" @@ -1267,9 +1309,14 @@ "Hasi saioa sarean" - "Ezin da konektatu Internetera Wi-Fi bidez" + + "Sakatu aukerak ikusteko" "Konektatuta" + + + + "Aldaketak egin dira sare publikoaren ezarpenetan" "Aldatu da sare publikoaren banda." "Gailuak ez du onartzen 5 GHz-ko banda soilik erabiltzeko hobespena. Horren ordez, erabilgarri dagoen bakoitzean erabiliko da 5 GHz-ko banda." @@ -1355,6 +1402,10 @@ "USB arazketa konektatuta" "Sakatu USB arazketa desaktibatzeko" "Hautatu USB arazketa desgaitzeko." + + + + "Likidoa edo zikinkeriak daude USB atakan" "USB ataka automatikoki desgaitu da. Informazio gehiago lortzeko, sakatu hau." "Segurtasunez erabil daiteke USB ataka" @@ -1906,8 +1957,6 @@ "Sakatu profila desblokeatzeko" "%1$s zerbitzura konektatuta" "Sakatu fitxategiak ikusteko" - "Ainguratu" - "Kendu aingura" "Aplikazioari buruzko informazioa" "−%1$s" "Demoa abiarazten…" @@ -1998,6 +2047,22 @@ "Ohitura moduaren informazio-jakinarazpena" "Baliteke bateria ohi baino lehenago agortzea" "Bateria-aurrezlea aktibatuta dago bateriaren iraupena luzatzeko" + + + + + + + + + + + + + + + + "Karpeta" "Android aplikazioa" "Fitxategia" diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml index 9e8b92cbe1ffe983f1d20fbdf935f79dc443deac..41597434215bc474746e3de5676862ae712fe036 100644 --- a/core/res/res/values-fr-rCA/strings.xml +++ b/core/res/res/values-fr-rCA/strings.xml @@ -141,8 +141,10 @@ "Appels Wi-Fi" "Voix par Wi-Fi" "Désactivé" - "Réseau Wi-Fi de préférence" - "Connexion cellulaire de préférence" + + + + "Wi-Fi seulement" "{0} : non transféré" "{0} : {1}" @@ -228,7 +230,8 @@ "Rapport de bogue" "Fermer la session" "Capture d\'écran" - "Créer un rapport de bogue" + + "Cela permet de recueillir des informations concernant l\'état actuel de votre appareil. Ces informations sont ensuite envoyées sous forme de courriel. Merci de patienter pendant la préparation du rapport de bogue. Cette opération peut prendre quelques instants." "Rapport interactif" "Utilisez cette option dans la plupart des circonstances. Elle vous permet de suivre la progression du rapport, d\'entrer plus d\'information sur le problème et d\'effectuer des saisies d\'écran. Certaines sections moins utilisées et dont le remplissage demande beaucoup de temps peuvent être omises." @@ -281,9 +284,12 @@ "Localisation" "accéder à la position de cet appareil" "Autoriser <b>%1$s</b> à accéder à la position de cet appareil?" - "L\'application aura uniquement accès à la position lorsque vous l\'utilisez." - "Toujours autoriser %1$s à accéder à la position de cet appareil?" - "L\'application aura toujours accès à la position, même lorsque vous ne l\'utilisez pas." + + + + + + "Agenda" "accéder à votre agenda" "Autoriser <b>%1$s</b> à accéder à votre agenda?" @@ -316,7 +322,10 @@ "Autoriser <b>%1$s</b> à accéder à votre musique?" "Photos et vidéos" "accéder à vos photos et à vos vidéos" - "Autoriser « %1$s » à accéder à vos photos et vos videos, y compris les lieux balisés?" + + + + "Récupérer le contenu d\'une fenêtre" "Inspecter le contenu d\'une fenêtre avec laquelle vous interagissez." "Activer la fonctionnalité Explorer au toucher" @@ -509,8 +518,10 @@ "Permet à l\'application de communiquer avec des bornes, des cartes et des lecteurs compatibles avec la technologie NFC (communication en champ proche)." "désactiver le verrouillage de l\'écran" "Permet à l\'application de désactiver le verrouillage des touches et toute mesure de sécurité par mot de passe associée. Par exemple, votre téléphone désactive le verrouillage des touches lorsque vous recevez un appel, puis le réactive lorsque vous raccrochez." - "demander la complexité du verrouillage d\'écran" - "Autorise l\'application à apprendre le niveau de complexité de l\'écran de verrouillage (élevé, moyen, faible ou aucun), qui indique la gamme possible de longueur et de type de verrouillage d\'écran. L\'application peut aussi suggérer aux utilisateurs de mettre à jour l\'écran de verrouillage afin d\'utiliser un certain niveau de complexité, mais ils peuvent ignorer la suggestion. Notez que le verrouillage d\'écran n\'est pas stocké en texte brut pour de manière à ce que l\'application n\'ait pas accès au mot de passe exact." + + + + "utiliser le matériel biométrique" "Permet à l\'application d\'utiliser du matériel biométrique pour l\'authentification" "gérer le matériel d\'empreinte digitale" @@ -565,37 +576,59 @@ "Permet à l\'appli d\'employer des méthodes d\'aj. et de suppr. de modèles de reconn. visage." "utiliser le matériel d\'authentification de visage" "Permet à l\'appli d\'utiliser du matériel de reconnaissance du visage pour l\'authentification" - "Impossible de traiter le visage. Réessayez." - "Visage trop lumineux. Essayez avec moins de lumière." - "Visage trop sombre. Essayez avec plus de lumière." - "Veuillez éloigner le capteur du visage." - "Veuillez rapprocher le capteur du visage." - "Veuillez déplacer le capteur plus haut." - "Veuillez déplacer le capteur plus bas." - "Veuillez déplacer le capteur vers la droite." - "Veuillez déplacer le capteur vers la gauche." - "Veuillez regarder le capteur." - "Aucun visage détecté." - "Trop de mouvement." + + + + + + + + + + + + + + + + + + + + + + + + "Veuillez inscrire votre visage à nouveau." - "Un visage différent a été détecté." + + "Trop similaire. Changez de pose." - "Veuillez regarder l\'appareil photo plus directement." - "Veuillez regarder l\'appareil photo plus directement." + + + + "Veuillez redresse votre tête verticalement." - "Veuillez découvrir votre visage." + + + + "Matériel de reconnaissance du visage indisponible." - "Temps de reconn. visage écoulé. Veuillez réessayer." + + "Impossible de stocker le visage." "Opération de reconnaissance du visage annulée." "Authentification du visage annulée par l\'utilisateur" "Trop de tentatives. Veuillez réessayer plus tard." "Trop de tentatives. Capt. reconn. visage désactivé." - "Réessayez." - "Aucun visage inscrit." - "Cet appareil ne possède pas de capteur de reconn. du visage." + + + + + + "Visage %d" @@ -1213,9 +1246,16 @@ "Ouvrir %1$s" "%1$s va fermer sans enregistrement" "%1$s a dépassé la limite de mémoire" + + "L\'empreinte de mémoire a été recueillie. Touchez ici pour la partager." "Partager l\'empreinte de mémoire?" - "Le processus %1$s a dépassé sa limite de mémoire de %2$s. Vous pouvez partager son empreinte de mémoire avec son développeur. Attention : cette empreinte peut contenir certains de vos renseignements personnels auxquels l\'application a accès." + + + + + + "Sélectionner une action pour le texte" "Volume de la sonnerie" "Volume" @@ -1254,8 +1294,10 @@ "Touchez pour afficher tous les réseaux" "Connexion" "Tous les réseaux" - "Un réseau Wi‑Fi proposé par %s est proposé" - "Voulez-vous vous connecter aux réseaux proposés par %s?" + + + + "Oui" "Non" "Le Wi-Fi s\'activera automatiquement" @@ -1267,9 +1309,14 @@ "Connectez-vous au réseau" - "Le réseau Wi-Fi ne dispose d\'aucun accès à Internet" + + "Touchez pour afficher les options" "Connecté" + + + + "Modifications apportées à vos paramètres de point d\'accès" "La bande de votre point d\'accès a changé." "Cet appareil ne prend pas en charge votre préférence pour la bande de 5 GHz seulement. Au lieu de cela, cet appareil utilisera la bande de 5 GHz lorsqu\'elle sera disponible." @@ -1354,6 +1401,10 @@ "Débogage USB activé" "Touchez l\'écran pour désactiver le débogage USB" "Sélectionnez cette option pour désactiver le débogage USB." + + + + "Liquide ou débris dans le port USB" "Le port USB est désactivé automatiquement. Touchez ici pour en savoir plus." "Vous pouvez maintenant utiliser le port USB" @@ -1905,8 +1956,6 @@ "Touch. pr déver. profil profess." "Connecté à %1$s" "Touchez ici pour afficher les fichiers" - "Épingler" - "Annuler l\'épinglage" "Détails de l\'application" "−%1$s" "Démarrage de la démonstration en cours…" @@ -1997,6 +2046,22 @@ "Notification d\'information du mode Routine" "La pile pourrait s\'épuiser avant la charge habituelle" "Le mode Économiseur de pile est activé afin de prolonger l\'autonomie" + + + + + + + + + + + + + + + + "Dossier" "Application Android" "Fichier" diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml index 17230391a5c5889f479a5e36983bddae60fe3906..72fe0d67718c5ff6f9ba8f03229561b09b92d59b 100644 --- a/core/res/res/values-fr/strings.xml +++ b/core/res/res/values-fr/strings.xml @@ -141,8 +141,10 @@ "Appels Wi-Fi" "VoWiFi" "Désactivé" - "Wi-Fi de préférence" - "Données mobiles de préférence" + + + + "Wi-Fi uniquement" "{0} : non transféré" "{0} : {1}" @@ -228,7 +230,8 @@ "Rapport de bug" "Fermer la session" "Capture d\'écran" - "Créer un rapport de bug" + + "Cela permet de recueillir des informations concernant l\'état actuel de votre appareil. Ces informations sont ensuite envoyées sous forme d\'e-mail. Merci de patienter pendant la préparation du rapport de bug. Cette opération peut prendre quelques instants." "Rapport interactif" "Utilisez cette option dans la plupart des circonstances. Elle vous permet de suivre la progression du rapport, de saisir plus d\'informations sur le problème et d\'effectuer des captures d\'écran. Certaines sections moins utilisées et dont le remplissage demande beaucoup de temps peuvent être omises." @@ -281,9 +284,12 @@ "Localisation" "accéder à la position de l\'appareil" "Permettre à <b>%1$s</b> d\'accéder à la position de cet appareil ?" - "L\'application n\'a accès à la position de l\'appareil que lorsqu\'elle est en cours d\'utilisation." - "Toujours autoriser <b>%1$s</b> à accéder à la position de l\'appareil ?" - "L\'application a toujours accès à la position de l\'appareil, même lorsqu\'elle n\'est pas en cours d\'utilisation." + + + + + + "Agenda" "accéder à votre agenda" "Permettre à <b>%1$s</b> d\'accéder à votre agenda ?" @@ -316,7 +322,10 @@ "Autoriser <b>%1$s</b> à accéder à votre musique ?" "Photos et vidéos" "accéder à vos photos et vos vidéos" - "Autoriser <b>%1$s</b> à accéder à vos photos et vidéos, y compris aux tags de lieu ?" + + + + "Récupérer le contenu d\'une fenêtre" "Inspecte le contenu d\'une fenêtre avec laquelle vous interagissez." "Activer la fonctionnalité Explorer au toucher" @@ -509,8 +518,10 @@ "Permet à l\'application de communiquer avec des tags, des cartes et des lecteurs compatibles avec la technologie NFC (communication en champ proche)." "Désactiver le verrouillage de l\'écran" "Permet à l\'application de désactiver le verrouillage des touches et toute mesure de sécurité via mot de passe associée. Par exemple, votre téléphone désactive le verrouillage des touches lorsque vous recevez un appel, puis le réactive lorsque vous raccrochez." - "demander la complexité du verrouillage de l\'écran" - "Permet à l\'application de connaître le niveau de complexité du verrouillage de l\'écran (élevé, moyen, faible ou aucun), qui indique les possibilités en matière de longueur du mot de passe et de type de verrouillage de l\'écran. L\'application peut également suggérer aux utilisateurs de modifier la complexité du verrouillage, mais ces derniers peuvent librement l\'ignorer. Remarque : Comme le verrouillage de l\'écran n\'est pas stocké au format texte brut, l\'application ne connaît pas le mot de passe exact." + + + + "utiliser les composants biométriques" "Autoriser l\'application à utiliser les composants biométriques pour l\'authentification" "Gérer le matériel d\'empreintes digitales" @@ -565,37 +576,59 @@ "Autorise l\'appli à invoquer des méthodes pour ajouter et supprimer des modèles de visages." "utiliser le matériel d\'authentification faciale" "Autorise l\'appli à utiliser le matériel d\'authentification faciale pour l\'authentification" - "Impossible reconnaître visage. Veuillez réessayer." - "Visage trop éclairé. Veuillez réduire la lumière." - "Visage trop sombre. Veuillez accroître la lumière." - "Veuillez éloigner le capteur de votre visage." - "Veuillez rapprocher le capteur de votre visage." - "Veuillez déplacer le capteur vers le haut." - "Veuillez déplacer le capteur vers le bas." - "Veuillez déplacer le capteur vers la droite." - "Veuillez déplacer le capteur vers la gauche." - "Veuillez regarder le capteur." - "Aucun visage détecté." - "Trop de mouvement." + + + + + + + + + + + + + + + + + + + + + + + + "Veuillez enregistrer à nouveau votre visage." - "Visage différent détecté." + + "Ressemble à un visage existant, changez de pose." - "Regardez l\'appareil photo plus directement." - "Regardez l\'appareil photo plus directement." + + + + "Veuillez tenir votre tête droite." - "Veuillez découvrir votre visage." + + + + "Matériel de reconnaissance faciale indisponible." - "Délai de détection du visage expiré. Réessayez." + + "Impossible de stocker les informations du visage." "Opération de reconnaissance faciale annulée." "Authentification faciale annulée par l\'utilisateur." "Trop de tentatives. Réessayez plus tard." "Trop d\'essais. Authentification faciale désactivée." - "Réessayez." - "Aucun visage enregistré." - "Aucun capteur d\'authentification faciale sur cet appareil." + + + + + + "Visage %d" @@ -1213,9 +1246,16 @@ "Ouvrir %1$s" "%1$s va se fermer sans enregistrer les données" "Le processus \"%1$s\" a dépassé la limite de mémoire" + + "Une empreinte de la mémoire a bien été générée. Appuyez pour partager." "Partager l\'empreinte de la mémoire ?" - "Le processus \"%1$s\" a dépassé sa limite de mémoire fixée à %2$s. Une empreinte de la mémoire est disponible pour que vous la communiquiez à son développeur. Attention : celle-ci peut contenir des informations personnelles auxquelles l\'application a accès." + + + + + + "Sélectionner une action pour le texte" "Volume de la sonnerie" "Volume" @@ -1254,8 +1294,10 @@ "Appuyer pour afficher tous les réseaux" "Se connecter" "Tous les réseaux" - "Un réseau Wi-Fi proposé par %s est disponible" - "Voulez-vous vous connecter aux réseaux proposés par %s ?" + + + + "Oui" "Non" "Le Wi-Fi sera activé automatiquement" @@ -1267,9 +1309,14 @@ "Se connecter au réseau" - "Impossible de se connecter à Internet via le réseau Wi-Fi" + + "Appuyez ici pour afficher des options." "Connecté" + + + + "Modifications apportées à vos paramètres de point d\'accès" "Votre bande de point d\'accès a été modifiée." "Cet appareil n\'est pas compatible avec votre préférence d\'utilisation de la bande 5 GHz uniquement. Il utilisera la bande 5 GHz lorsqu\'elle sera disponible." @@ -1354,6 +1401,10 @@ "Débogage USB activé" "Appuyez pour désactiver le débogage USB" "Sélectionnez cette option pour désactiver le débogage USB." + + + + "Présence de liquide ou de saletés dans le port USB" "Le port USB est désactivé automatiquement. Appuyez sur cette notification pour en savoir plus." "Possibilité d\'utiliser le port USB en toute sécurité" @@ -1905,8 +1956,6 @@ "Appuyez pour déverrouiller profil pro" "Connecté à %1$s" "Appuyez ici pour voir les fichiers." - "Épingler" - "Retirer" "Infos sur l\'appli" "− %1$s" "Lancement de la démo…" @@ -1997,6 +2046,22 @@ "Notification d\'information du mode Routine" "Vous risquez d\'être à court de batterie plus tôt que prévu" "Économiseur de batterie activé pour prolonger l\'autonomie" + + + + + + + + + + + + + + + + "Dossier" "Application Android" "Fichier" diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml index 7d9f8ac6a57d682f0ebfc243a1d5e352b006ea87..5f3026cf2d962a04c8dd77a6e54e46a8bf7f265b 100644 --- a/core/res/res/values-hy/strings.xml +++ b/core/res/res/values-hy/strings.xml @@ -48,7 +48,7 @@ "Մուտքագրեք PIN, որը 4-ից 8 թիվ է:" "Մուտքագրեք PUK, որն 8 կամ ավել թիվ ունի:" "Ձեր SIM քարտը PUK-ով կողպված է: Մուտքագրեք PUK կոդը այն ապակողպելու համար:" - "Մուտքագրեք PUK2-ը` SIM քարտն արգելաբացելու համար:" + "Մուտքագրեք PUK2-ը` SIM քարտն արգելահանելու համար:" "Ձախողվեց: Միացրեք SIM/RUIM կողպումը:" Մնաց %d փորձ, որից հետո SIM քարտն արգելափակվելու է: @@ -141,8 +141,10 @@ "Զանգեր Wi-Fi-ի միջոցով" "VoWifi" "Անջատված է" - "Wi-Fi, նախընտրելի" - "Նախընտրելի է բջջային ցանցը" + + + + "Միայն Wi-Fi" "{0}. Չի վերահասցեավորվել" "{0}. {1}" @@ -228,7 +230,8 @@ "Վրիպակի զեկույց" "Ավարտել աշխատաշրջանը" "Սքրինշոթ" - "Հաղորդել սխալի մասին" + + "Սա տեղեկություններ կհավաքագրի ձեր սարքի առկա կարգավիճակի մասին և կուղարկի այն էլեկտրոնային նամակով: Որոշակի ժամանակ կպահանջվի վրիպակի մասին զեկուցելու պահից սկսած մինչ ուղարկելը: Խնդրում ենք փոքր-ինչ համբերատար լինել:" "Ինտերակտիվ զեկույց" "Հիմնականում օգտագործեք այս տարբերակը: Այն ձեզ թույլ է տալիս հետևել զեկույցի ստեղծման գործընթացին, խնդրի մասին լրացուցիչ տեղեկություններ մուտքագրել և սքրինշոթներ ստեղծել: Կարող է բաց թողնել քիչ օգտագործվող որոշ բաժիններ, որոնց ստեղծումը երկար է տևում:" @@ -241,9 +244,9 @@ "Անձայն ռեժիմ" "Ձայնը անջատված է" "Ձայնը միացված է" - "Ինքնաթիռի ռեժիմ" - "Ինքնաթիռի ռեժիմը միացված է" - "Ինքնաթիռի ռեժիմը անջատված է" + "Ավիառեժիմ" + "Ավիառեժիմը միացված է" + "Ավիառեժիմը անջատված է" "Կարգավորումներ" "Օգնական" "Ձայնային օգնութ" @@ -281,9 +284,12 @@ "Տեղորոշում" "տեղորոշել այս սարքը" "Թույլ տա՞լ <b>%1$s</b> հավելվածին օգտագործել այս սարքի տեղադրության տվյալները:" - "Տեղադրության տվյալները հավելվածին հասանելի կլինեն միայն, երբ այն օգտագործելիս լինեք:" - "Միշտ թույլ տա՞լ <b>%1$s</b>-ին օգտագործել սարքի տեղադրությունը:" - "Տեղադրության տվյալները հավելվածին միշտ հասանելի կլինեն, նույնիսկ եթե այն չեք օգտագործում:" + + + + + + "Օրացույց" "օգտագործել օրացույցը" "Թույլ տա՞լ <b>%1$s</b> հավելվածին օգտագործել ձեր օրացույցը:" @@ -316,7 +322,10 @@ "Հասանելի դարձնե՞լ <b>%1$s</b> հավելվածին ձեր երաժշտությունը:" "Լուսանկարներ և տեսանյութեր" "լուսանկարների և տեսանյութերի հասանելիություն" - "Հասանելի դարձնե՞լ <b>%1$s</b> հավելվածին ձեր լուսանկարները, տեսանյութերը և տեղանշված վայրերը:" + + + + "Առբերել պատուհանի բովանդակությունը" "Վերլուծել գործող պատուհանի բովանդակությունը" "Միացնել Հպման միջոցով հետազոտումը" @@ -509,8 +518,10 @@ "Թույլ է տալիս հավելվածին հաղորդակցվել Մոտ տարածությամբ հաղորդակցման (NFC) պիտակների, քարտերի և ընթերցիչների հետ:" "անջատել ձեր էկրանի կողպեքը" "Թույլ է տալիս հավելվածին անջատել ստեղնաշարի կողպումը և ցանկացած կապված գաղտնաբառի պաշտպանվածությունը: Սրա ճիշտ օրինակն է, երբ հեռախոսը անջատում է ստեղնաշարի կողպումը մուտքային զանգ ստանալիս, հետո այն կրկին միացնում է, երբ զանգը ավարտվում է:" - "էկրանի կողպման բարդության մակարդակի մասին տեղեկությունների ստացում" - "Հավելվածին հասանելի կդառնան էկրանի կողպման բարդության մակարդակի մասին տեղեկությունները (բարձր, միջին, ցածր կամ ոչ մի), այդ թվում կողպման տեսակի և գաղտնաբառի երկարության մասին տվյալները: Բացի այդ, հավելվածը կկարողանա առաջարկել օգտատերերին բարձրացնել կողպման բարդության մակարդակը: Օգտատերերը կարող են անտեսել այդ առաջարկները: Նկատի ունեցեք, որ գաղտնաբառը չի պահվում բաց տեքստի տեսքով և հասանելի չէ հավելվածին:" + + + + "կենսաչափական սարքի օգտագործում" "Հավելվածին թույլ է տալիս օգտագործել նույնականացման համար նախատեսված կենսաչափական սարքը" "կառավարել մատնահետքերի գրանցման սարքը" @@ -565,37 +576,59 @@ "Հավելվածին թույլ է տալիս ավելացնել և հեռացնել դեմքի նմուշներ:" "օգտագործել դեմքի ճանաչման սարքը" "Հավելվածին թույլ է տալիս օգտագործել նույնականացման համար նախատեսված սարքը" - "Չհաջողվեց ճանաչել ձեր դեմքը: Նորից փորձեք:" - "Դեմքը չափազանց վառ է երևում։ Թուլացրեք լույսը։" - "Դեմքը չափազանց մուգ է երևում։ Ուժեղացրեք լույսը։" - "Սարքը մի փոքր հեռացրեք դեմքից։" - "Սարքը մի փոքր մոտեցրեք դեմքին։" - "Սարքը մի փոքր վերև պահեք։" - "Սարքը մի փոքր ներքև պահեք։" - "Սարքը մի փոքր ձախ պահեք։" - "Սարքը մի փոքր ձախ պահեք։" - "Նայեք սարքի տեսախցիկին։" - "Դեմք չի հայտնաբերվել։" - "Սարքն անշարժ պահեք։" + + + + + + + + + + + + + + + + + + + + + + + + "Նորից փորձեք։" - "Հայտնաբերվել է այլ դեմք։" + + "Շատ նման է նախորդին։ Փոխեք ձեր դիրքը։" - "Նայեք ուղիղ տեսախցիկին։" - "Նայեք ուղիղ տեսախցիկին։" + + + + "Ուղղեք գլուխը հորիզոնական գծով։" - "Բացեք դեմքը։" + + + + "Դեմքի ճանաչման սարքն անհասանելի է։" - "Ժամանակը սպառվել է: Նորից փորձեք:" + + "Դեմքը հնարավոր չէ պահել։" "Դեմքի ճանաչումը չեղարկվել է։" "Դեմքի ճանաչումը չեղարկվել է օգտատիրոջ կողմից:" "Չափից շատ փորձեր եք կատարել: Փորձեք ավելի ուշ:" "Չափից շատ փորձեր եք կատարել: Դեմքի ճանաչման գործառույթն անջատվել է։" - "Նորից փորձեք:" - "Գրանցված դեմք չկա։" - "Այս սարքը չունի դեմքի ճանաչման սկաներ։" + + + + + + "Դեմք %d" @@ -1213,9 +1246,16 @@ "Բացել %1$s հավելվածը" "%1$s հավելվածը կփակվի առանց տվյալները պահելու" "%1$s գործընթացը գերազանցել է հիշողության սահմանաչափը" + + "Դինամիկ հիշողության տվյալները հավաքվել են: Հպեք՝ դրանք ուղարկելու համար:" "Տրամադրե՞լ օգտագործվող օբյեկտների վերաբերյալ տվյալները:" - "%1$s գործընթացը գերազանցել է իր կողմից հիշողության օգտագործման սահմանաչափը՝ %2$s: Հավաքվել են օգտագործվող օբյեկտների վերաբերյալ տվյալներ, որոնք կարող եք ուղարկել մշակողին: Սակայն զգույշ եղեք՝ նշված տվյալները կարող են ներառել հավելվածի կողմից օգտագործվող ձեր անձնական տվյալները:" + + + + + + "Ընտրեք գործողություն տեքստի համար" "Զանգակի ձայնի ուժգնությունը" "Մեդիա ձայնի բարձրություն" @@ -1254,8 +1294,10 @@ "Հպեք՝ բոլոր ցանցերը տեսնելու համար" "Միանալ" "Բոլոր ցանցերը" - "%s հավելվածն առաջարկում է միանալ հասանելի Wi‑Fi ցանցի" - "Միանա՞լ %s հավելվածի առաջարկած ցանցերին:" + + + + "Այո" "Ոչ" "Wi‑Fi-ն ավտոմատ կմիանա" @@ -1267,9 +1309,14 @@ "Մուտք գործեք ցանց" - "Wi-Fi ցանցում ինտերնետ կապ չկա" + + "Հպեք՝ ընտրանքները տեսնելու համար" "Միացված է" + + + + "Փոփոխություններ թեժ կետի կարգավորումներում" "Ձեր թեժ կետի հաճախականությունը փոխվել է։" "Սարքը չի կարող աշխատել միայն 5 ԳՀց հաճախականությամբ։ Այդ հաճախականությունը կօգտագործվի հնարավորության դեպքում։" @@ -1354,6 +1401,10 @@ "USB վրիպազերծումը միացված է" "Հպեք՝ USB-ի վրիպազերծումն անջատելու համար" "Ընտրել` USB կարգաբերումը կասեցնելու համար:" + + + + "USB միացքում ջուր կամ աղտ է հայտնաբերվել" "USB միացքն ավտոմատ անջատվել է: Հպեք՝ ավելին իմանալու համար:" "USB միացքը կարող է օգտագործվել" @@ -1396,8 +1447,7 @@ "Կարգավորել" "Անջատել" "Ուսումնասիրել" - - + "Աուդիոելքի սարքի փոխարկում" "%s-ը տեղադրված չէ" "Նորից տեղադրեք սարքը" "%s-ի տեղափոխում" @@ -1906,8 +1956,6 @@ "Հպեք՝ այն ապակողպելու համար" "Միացված է %1$s-ին" "Հպեք՝ ֆայլերը տեսնելու համար" - "Ամրացնել" - "Ապամրացնել" "Հավելվածի տվյալներ" "−%1$s" "Ցուցադրական օգտատերը գործարկվում է…" @@ -1998,6 +2046,22 @@ "Ծանուցում լիցքավորման մասին" "Մարտկոցի լիցքը կարող է սովորականից շուտ սպառվել" "Մարտկոցի կյանքը երկարացնելու համար ակտիվացվել է մարտկոցի տնտեսման ռեժիմը" + + + + + + + + + + + + + + + + "Պանակ" "Android հավելված" "Ֆայլ" diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml index 951c4e2afb2273cb6b8a5df067068b76e99a260d..5b8028d19d37cd4008c44a7e71155b7927c48ef3 100644 --- a/core/res/res/values-kk/strings.xml +++ b/core/res/res/values-kk/strings.xml @@ -141,8 +141,10 @@ "WiFi қоңыраулары" "VoWifi" "Өшірулі" - "Қалаулы Wi-Fi" - "Таңдаулы мобильдік байланыс" + + + + "Тек Wi-Fi" "{0}: Басқа нөмірге бағытталмады" "{0}: {1}" @@ -228,7 +230,8 @@ "Вирус туралы хабарлау" "Сеансты аяқтау" "Скриншот" - "Қате туралы есеп құру" + + "Құрылғының қазіргі күйі туралы ақпаратты жинап, электрондық хабармен жібереді. Есеп әзір болғанша біраз уақыт кетеді, шыдай тұрыңыз." "Интерактивті есеп" "Бұл көптеген жағдайларда пайдаланылады. Ол есептің орындалу барысын бақылауға, мәселе туралы қосымша мәліметтер енгізуге және скриншоттар алуға мүмкіндік береді. Ол есеп беруіне ұзақ уақыт кететін кейбір азырақ пайдаланылатын бөлімдерді өткізіп жіберуі мүмкін." @@ -281,9 +284,12 @@ "Орналасу" "бұл құрылғының орналасқан жерін көру" "<b>%1$s</b> қолданбасына құрылғының орналасқан жері туралы мәліметтерді пайдалануға рұқсат берілсін бе?" - "Қолданбаны пайдалану кезінде ғана оған геодеректеріңізді көруге рұқсат етіледі." - "\"%1$s\" кез келген уақытта құрылғы геодеректерін пайдалансын ба?" - "Қолданба пайдаланылмаса да, оған геодеректеріңізді көруге рұқсат етіледі." + + + + + + "Күнтізбе" "күнтізбеге кіру" "<b>%1$s</b> қолданбасына күнтізбеге кіруге рұқсат берілсін бе?" @@ -316,7 +322,10 @@ "<b>%1$s</b> қолданбасына музыка мазмұнына кіруге рұқсат етілсін бе?" "Суреттер және бейнелер" "суреттер мен бейнелерге кіру" - "<b>%1$s</b> қолданбасына суреттер мен бейнелерді, тэг енгізілген орындарды пайдалануға рұқсат етілсін бе?" + + + + "Терезе мазмұнын оқып отыру" "Ашық тұрған терезе мазмұнын тексеру." "Explore by Touch функциясын қосу" @@ -509,8 +518,10 @@ "Қолданбаға NFC белгілерімен, карталармен және оқу құралдарымен байланысуға рұқсат береді." "экран бекітпесін істен шығару" "Қолданбаларға кілтперне және басқа кілтсөзге қатысты қауіпсіздік шараларын өшіру мүмкіндігін береді. Мысалы, телефон кіріс қоңырауларын алғанда кілтпернені өшіреді және қоңырау аяқталғанда қайта қосады." - "экранды құлыптау күрделілігін сұрау" - "Қолданбаға экранды құлыптаудың күрделілік деңгейін (жоғары, орташа, төмен немесе жоқ), соның ішінде ұзақтығы мен түрін анықтауға мүмкіндік береді. Сонымен қатар қолданба пайдаланушыларға құлыпты белгілі бір деңгейге жаңартуды ұсынады. Бірақ бұл ұсыныстарды елемеуге болады. Экран құлпы қарапайым мәтін түрінде сақталмайтынын және құпия сөз қолданбаға белгісіз болатынын ескеріңіз." + + + + "биометрикалық жабдықты пайдалану" "Аутентификациялау үшін қолданбаға биометрикалық жабдықты пайдалануға рұқсат береді" "саусақ ізі жабдығын басқару" @@ -565,37 +576,59 @@ "Қолданбаға пайдаланатын бет үлгілерін енгізу және жою әдістерін шақыруға мүмкіндік береді." "бетті тану жабдығын пайдалану" "Қолданбаға бетті тану жабдығын қолдануға рұқсат етеді" - "Бет өңделмеді. Әрекетті қайталаңыз." - "Бет тым ашық түсті болып шықты. Жарықты азайтыңыз." - "Бет тым күңгірт түсті. Жарық көзін бөгемеңіз." - "Датчикті беттен алыстатыңыз." - "Датчикті бетке жақындатыңыз." - "Датчикті жоғары көтеріңіз." - "Датчикті төмен қарай жылжытыңыз." - "Датчикті оңға қарай жылжытыңыз." - "Датчикті солға қарай жылжытыңыз." - "Датчикке қараңыз." - "Бет анықталмады." - "Құрылғыны қозғалтпаңыз." + + + + + + + + + + + + + + + + + + + + + + + + "Қайта тіркеліңіз." - "Басқа адамның беті анықталды." + + "Алдыңғысына тым ұқсас, басқаша қалыпта түсіңіз." - "Камераға тура қараңыз." - "Камераға тура қараңыз." + + + + "Басыңызды тік ұстаңыз." - "Бетіңізді жаппаңыз." + + + + "Бетті тану жабдығы қолжетімді емес." - "Күту уақыты бітті. Әрекетті қайталаңыз." + + "Бетті сақтау мүмкін емес." "Бетті танудан бас тартылды." "Пайдаланушы бетті тану әрекетінен бас тартты." "Тым көп әрекет жасалды. Кейінірек қайталаңыз." "Тым көп әрекет жасалды. Бетті тану функциясы өшірілді." - "Қайталап көріңіз." - "Ешқандай бет тіркелмеген." - "Бұл құрылғыда бетті тану датчигі жоқ." + + + + + + "%d беті" @@ -1213,9 +1246,16 @@ "%1$s қолданбасын ашу" "%1$s қолданбасының жұмысы сақталмай жабылады" "%1$s жад шегінен асты" + + "Үйінді дамп жиналды. Бөлісу үшін түртіңіз." "Үйінді дамппен бөлісу қажет пе?" - "%1$s процесі %2$s процесс жады шегінен асып кетті. Үйінді дамп оның әзірлеушісімен ​​бөлісуге қолжетімді. Абай болыңыз: бұл үйінді дампта бағдарлама кіре алатын кейбір жеке ақпараттарыңыз болуы мүмкін." + + + + + + "Мәтін үшін әрекет таңдау" "Қоңырау шырылының қаттылығы" "Meдиа дыбысының қаттылығы" @@ -1254,8 +1294,10 @@ "Барлық желілерді көру үшін түртіңіз" "Қосылу" "Барлық желілер" - "%s ұсынған Wi‑Fi желісі қолжетімді" - "%s ұсынған желілерге қосылғыңыз келе ме?" + + + + "Иә" "Жоқ" "Wi‑Fi автоматты түрде қосылады" @@ -1267,9 +1309,14 @@ "Желіге кіру" - "Wi-Fi желісінде интернет байланысы жоқ" + + "Опциялар үшін түртіңіз" "Жалғанды" + + + + "Хотспот параметрлеріне өзгерістер енгізілді" "Хотспот жолағы өзгертілді." "Бұл құрылғы тек 5 ГГц жиілікте жұмыс істей алмайды. Бұл жиілік мүмкін болған жағдайда ғана қолданылады." @@ -1355,6 +1402,10 @@ "USB түзетуі қосылған" "USB арқылы түзетуді өшіру үшін түртіңіз" "USB түзетуін өшіру үшін таңдаңыз." + + + + "USB портына сұйықтық немесе қоқыс кірді" "USB порты автоматты түрде өшірілді. Толығырақ ақпарат алу үшін түртіңіз." "USB портын пайдалана беруге болады" @@ -1906,8 +1957,6 @@ "Жұмыс профилінің құлпын ашу үшін түртіңіз" "%1$s қосылу орындалды" "Файлдарды көру үшін түртіңіз" - "PIN коды" - "Босату" "Қолданба ақпараты" "−%1$s" "Демо нұсқасы іске қосылуда..." @@ -1998,6 +2047,22 @@ "Режим туралы хабарландыру" "Батарея заряды азаюы мүмкін" "Батарея ұзаққа жетуі үшін, Battery Saver іске қосылды" + + + + + + + + + + + + + + + + "Қалта" "Android қолданбасы" "Файл" diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml index c8d43963fe0bb8a62203f5a6051b4d5cae246cbf..5c1fe245ebb3df16d56d45be3df5759c05f0dcc6 100644 --- a/core/res/res/values-kn/strings.xml +++ b/core/res/res/values-kn/strings.xml @@ -141,8 +141,10 @@ "ವೈಫೈ ಕರೆ ಮಾಡುವಿಕೆ" "VoWifi" "ಆಫ್" - "ವೈ-ಫೈಗೆ ಆದ್ಯತೆ" - "ಮೊಬೈಲ್‌ಗೆ ಆದ್ಯತೆ" + + + + "ವೈ-ಫೈ ಮಾತ್ರ" "{0}: ಫಾರ್ವರ್ಡ್ ಮಾಡಲಾಗಿಲ್ಲ" "{0}: {1}" @@ -228,7 +230,8 @@ "ದೋಷದ ವರದಿ" "ಸೆಷನ್ ಅಂತ್ಯಗೊಳಿಸಿ" "ಸ್ಕ್ರೀನ್‌ಶಾಟ್" - "ದೋಷ ವರದಿ ರಚಿಸಿ" + + "ನಿಮ್ಮ ಸಾಧನದ ಪ್ರಸ್ತುತ ಸ್ಥಿತಿಯ ಕುರಿತು ಮಾಹಿತಿಯನ್ನು ಸಂಗ್ರಹಿಸಿಕೊಳ್ಳುವುದರ ಜೊತೆ ಇ-ಮೇಲ್ ರೂಪದಲ್ಲಿ ನಿಮಗೆ ರವಾನಿಸುತ್ತದೆ. ಇದು ದೋಷ ವರದಿಯನ್ನು ಪ್ರಾರಂಭಿಸಿದ ಸಮಯದಿಂದ ಅದನ್ನು ಕಳುಹಿಸುವವರೆಗೆ ಸ್ವಲ್ಪ ಸಮಯವನ್ನು ತೆಗೆದುಕೊಳ್ಳುತ್ತದೆ; ದಯವಿಟ್ಟು ತಾಳ್ಮೆಯಿಂದಿರಿ." "ಪರಸ್ಪರ ಸಂವಹನ ವರದಿ" "ಹೆಚ್ಚಿನ ಸಂದರ್ಭಗಳಲ್ಲಿ ಇದನ್ನು ಬಳಸಿ. ಇದು ವರದಿಯ ಪ್ರಗತಿಯನ್ನು ಟ್ರ್ಯಾಕ್ ಮಾಡಲು, ಸಮಸ್ಯೆ ಕುರಿತು ಹೆಚ್ಚಿನ ವಿವರಗಳನ್ನು ನಮೂದಿಸಲು ಮತ್ತು ಸ್ಕ್ರೀನ್‌ಶಾಟ್‌ಗಳನ್ನು ತೆಗೆದುಕೊಳ್ಳಲು ಅನುಮತಿಸುತ್ತದೆ. ಇದು ವರದಿ ಮಾಡಲು ಹೆಚ್ಚು ಸಮಯ ತೆಗೆದುಕೊಳ್ಳುವಂತಹ ಕೆಲವು ಕಡಿಮೆ ಬಳಸಲಾದ ವಿಭಾಗಗಳನ್ನು ತ್ಯಜಿಸಬಹುದು." @@ -281,9 +284,12 @@ "ಸ್ಥಳ" "ಈ ಸಾಧನದ ಸ್ಥಳವನ್ನು ಪ್ರವೇಶಿಸಿ" "ಈ ಸಾಧನದ ಸ್ಥಳವನ್ನು ಪ್ರವೇಶಿಸಲು <b>%1$s</b> ಗೆ ಅನುಮತಿಸಬೇಕೇ?" - "ನೀವು ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ಬಳಸುವಾಗ ಈ ಅಪ್ಲಿಕೇಶನ್‌ ಸ್ಥಳಕ್ಕೆ ಮಾತ್ರ ಪ್ರವೇಶವನ್ನು ಹೊಂದಿರುತ್ತದೆ." - "ಈ ಸಾಧನದ ಸ್ಥಳವನ್ನು ಪ್ರವೇಶಿಸಲು ಯಾವಾಗಲೂ <b>%1$s</b> ಗೆ ಅನುಮತಿಸಬೇಕೇ?" - "ನೀವು ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ಬಳಸದಿರುವಾಗಲೂ ಅಪ್ಲಿಕೇಶನ್ ಯಾವಾಗಲೂ ಸ್ಥಳಕ್ಕೆ ಪ್ರವೇಶವನ್ನು ಹೊಂದಿರುತ್ತದೆ." + + + + + + "ಕ್ಯಾಲೆಂಡರ್" "ನಿಮ್ಮ ಕ್ಯಾಲೆಂಡರ್ ಪ್ರವೇಶಿಸಲು" "ನಿಮ್ಮ ಕ್ಯಾಲೆಂಡರ್ ಪ್ರವೇಶಿಸಲು <b>%1$s</b> ಗೆ ಅನುಮತಿಸಬೇಕೇ?" @@ -316,7 +322,10 @@ "ನಿಮ್ಮ ಸಂಗೀತವನ್ನು ಪ್ರವೇಶಿಸಲು <b>%1$s</b> ಗೆ ಅನುಮತಿಸಬೇಕೇ?" "ಫೋಟೋಗಳು ಮತ್ತು ವೀಡಿಯೊಗಳು" "ನಿಮ್ಮ ಫೋಟೋಗಳು & ವೀಡಿಯೊಗಳನ್ನು ಪ್ರವೇಶಿಸಿ" - "ಟ್ಯಾಗ್ ಮಾಡಿದ ಸ್ಥಳಗಳೂ ಸೇರಿದಂತೆ ನಿಮ್ಮ ಫೋಟೋಗಳು ಹಾಗೂ ವೀಡಿಯೊಗಳಿಗೆ ಪ್ರವೇಶ ಪಡೆಯಲು <b>%1$s</b> ಗೆ ಅನುಮತಿ ನೀಡಬೇಕೇ?" + + + + "ವಿಂಡೋ ವಿಷಯವನ್ನು ಹಿಂಪಡೆಯುತ್ತದೆ" "ನೀವು ಬಳಸುತ್ತಿರುವ ವಿಂಡೋದ ವಿಷಯ ಪರೀಕ್ಷಿಸುತ್ತದೆ." "ಸ್ಪರ್ಶ-ಎಕ್ಸ್‌ಪ್ಲೋರ್ ಆನ್ ಮಾಡುತ್ತದೆ" @@ -509,8 +518,10 @@ "ಸಮೀಪದ ಕ್ಷೇತ್ರ ಸಂವಹನ (NFC) ಟ್ಯಾಗ್‌ಗಳು, ಕಾರ್ಡ್‌ಗಳು, ಮತ್ತು ಓದುಗರನ್ನು ಅಪ್ಲಿಕೇಶನ್‌ ಅನುಮತಿಸುತ್ತದೆ." "ನಿಮ್ಮ ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಅನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ" "ಕೀಲಾಕ್ ಮತ್ತು ಯಾವುದೇ ಸಂಬಂಧಿತ ಭದ್ರತಾ ಪಾಸ್‍‍ವರ್ಡ್ ಭದ್ರತೆಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲು ಅಪ್ಲಿಕೇಶನ್‍‍ಗೆ ಅನುಮತಿ ನೀಡುತ್ತದೆ. ಉದಾಹರಣೆಗೆ, ಒಳಬರುವ ಕರೆಯನ್ನು ಸ್ವೀಕರಿಸುವಾಗ ಕೀಲಾಕ್ ಅನ್ನು ಫೋನ್ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸುತ್ತದೆ, ನಂತರ ಕರೆಯು ಅಂತ್ಯಗೊಂಡಾಗ ಕೀಲಾಕ್ ಅನ್ನು ಮರು ಸಕ್ರಿಯಗೊಳಿಸುತ್ತದೆ." - "ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಸಂಕೀರ್ಣತೆಯನ್ನು ವಿನಂತಿಸಿ" - "ಆ್ಯಪ್‌ಗೆ ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಸಂಕೀರ್ಣತೆ ಮಟ್ಟವನ್ನು ತಿಳಿದುಕೊಳ್ಳಲು ಅನುಮತಿಸುತ್ತದೆ (ಹೆಚ್ಚು, ಮಧ್ಯಮ, ಕಡಿಮೆ ಅಥವಾ ಯಾವುದೂ ಅಲ್ಲ), ಇದು ಉದ್ದದ ಸಂಭವನೀಯ ಶ್ರೇಣಿ ಮತ್ತು ಸ್ಕ್ರೀನ್ ಲಾಕ್‌ನ ವಿಧವನ್ನು ಸೂಚಿಸುತ್ತದೆ. ಬಳಕೆದಾರರು ನಿರ್ದಿಷ್ಟ ಮಟ್ಟದವರೆಗೆ ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಅನ್ನು ಅಪ್‌ಡೇಟ್ ಮಾಡಬಹುದು ಎಂಬುದಾಗಿ ಕೂಡ ಆ್ಯಪ್‌ ಬಳಕೆದಾರರಿಗೆ ಸಲಹೆ ಮಾಡುತ್ತದೆ ಆದರೆ ಬಳಕೆದಾರರು ಮುಕ್ತವಾಗಿ ತಿರಸ್ಕರಿಸಬಹುದು ಮತ್ತು ನ್ಯಾವಿಗೇಟ್ ಮಾಡಬಹುದು. ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಅನ್ನು ಖಾಲಿಪಠ್ಯದಲ್ಲಿ ಸಂಗ್ರಹಿಸಿಲ್ಲ ಎಂಬುದನ್ನು ಗಮನಿಸಿ, ಇದರಿಂದ ಆ್ಯಪ್‌ಗೆ ಸರಿಯಾದ ಪಾಸ್‌ವರ್ಡ್ ಗೊತ್ತಿರುವುದಿಲ್ಲ." + + + + "ಬಯೋಮೆಟ್ರಿಕ್ ಹಾರ್ಡ್‌ವೇರ್‌ ಬಳಸಿ" "ಪ್ರಮಾಣೀಕರಣಕ್ಕಾಗಿ ಬಯೋಮೆಟ್ರಿಕ್ ಹಾರ್ಡ್‌ವೇರ್ ಬಳಸಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ" "ಬೆರಳಚ್ಚು ಹಾರ್ಡ್‌ವೇರ್ ನಿರ್ವಹಿಸಿ" @@ -565,37 +576,59 @@ "ಬಳಕೆಗೆ ಮುಖದ ಟೆಂಪ್ಲೇಟ್‌ಗಳನ್ನು ಸೇರಿಸಲು ಮತ್ತು ಅಳಿಸಲು ವಿಧಾನಗಳನ್ನು ಮನವಿ ಮಾಡಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ." "ಮುಖ ದೃಢೀಕರಣ ಹಾರ್ಡ್‌ವೇರ್‌ ಅನ್ನು ಬಳಸಿ" "ಧೃಡೀಕರಣಕ್ಕಾಗಿ ಮುಖದ ಹಾರ್ಡ್‌ವೇರ್ ಬಳಸಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ" - "ಮುಖವನ್ನು ಪ್ರಕ್ರಿಯೆಗೊಳಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ. ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ." - "ಮುಖವು ತುಂಬಾ ಪ್ರಕಾಶಮಾನವಾಗಿದೆ. ಕಡಿಮೆ ಲೈಟ್‌ನಲ್ಲಿ ಪ್ರಯತ್ನಿಸಿ." - "ಮುಖ ತುಂಬಾ ಕಪ್ಪಾಗಿದೆ. ನೇರವಾಗಿ ಬೆಳಕು ಬಿಳುವಂತೆ ಮಾಡಿ." - "ಮುಖದಿಂದ ಸೆನ್ಸರ್ ಅನ್ನು ದೂರ ಸರಿಸಿ." - "ಸೆನ್ಸರ್ ಅನ್ನು ಮುಖದ ಹತ್ತಿರಕ್ಕೆ ತನ್ನಿ." - "ಸೆನ್ಸರ್ ಅನ್ನು ಮೇಲಕ್ಕೆ ಸರಿಸಿ." - "ಸೆನ್ಸರ್ ಅನ್ನು ಕೆಳಕ್ಕೆ ಸರಿಸಿ." - "ಸೆನ್ಸರ್ ಅನ್ನು ಬಲಕ್ಕೆ ಸರಿಸಿ." - "ಸೆನ್ಸರ್ ಅನ್ನು ಎಡಕ್ಕೆ ಸರಿಸಿ." - "ಸೆನ್ಸರ್ ಅನ್ನು ನೋಡಿ." - "ಯಾವುದೇ ಮುಖ ಪತ್ತೆಯಾಗಿಲ್ಲ." - "ತುಂಬಾ ಚಲನೆ." + + + + + + + + + + + + + + + + + + + + + + + + "ನಿಮ್ಮ ಮುಖವನ್ನು ಮರುನೋಂದಣಿ ಮಾಡಿ." - "ವಿಭಿನ್ನ ಮುಖ ಪತ್ತೆಯಾಗಿದೆ." + + "ತುಂಬಾ ಸಮಾನ, ನಿಮ್ಮ ಪೋಸ್ ಬದಲಾಯಿಸಿ." - "ಕ್ಯಾಮರಾ ಕಡೆ ಹೆಚ್ಚು ನೇರವಾಗಿ ನೋಡಿ." - "ಕ್ಯಾಮರಾ ಕಡೆ ಹೆಚ್ಚು ನೇರವಾಗಿ ನೋಡಿ." + + + + "ನಿಮ್ಮ ತಲೆಯನ್ನು ವರ್ಟಿಕಲ್‌ ಆಗಿ ನೇರವಾಗಿಸಿ." - "ನಿಮ್ಮ ಮುಖವನ್ನು ಬಹಿರಂಗಪಡಿಸಿ." + + + + "ಮುಖದ ಹಾರ್ಡ್‌ವೇರ್‌ ಲಭ್ಯವಿಲ್ಲ." - "ಮುಖ ಸಮಯದ ಅವಧಿಯನ್ನು ತಲುಪಿದೆ. ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ." + + "ಮುಖವನ್ನು ಸಂಗ್ರಹಿಸಲಾಗುವುದಿಲ್ಲ." "ಮುಖದ ಕಾರ್ಯಚರಣೆಯನ್ನು ರದ್ದುಗೊಳಿಸಲಾಗಿದೆ." "ಮುಖ ದೃಢೀಕರಣವನ್ನು ಬಳಕೆದಾರರ ಮೂಲಕ ರದ್ದುಗೊಳಿಸಲಾಗಿದೆ." "ಹಲವು ಬಾರಿ ಪ್ರಯತ್ನಿಸಿದ್ದೀರಿ. ನಂತರ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ." "ಹಲವು ಪ್ರಯತ್ನ. ಮುಖದ ದೃಢೀಕರಣ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ." - "ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ." - "ಯಾವುದೇ ಮುಖವನ್ನು ನೋಂದಣಿ ಮಾಡಿಲ್ಲ." - "ಈ ಸಾಧನವು ಮುಖ ಪ್ರಮಾಣೀಕರಣ ಸೆನ್ಸರ್ ಅನ್ನು ಹೊಂದಿಲ್ಲ." + + + + + + "ಮುಖದ %d" @@ -1213,9 +1246,16 @@ "%1$s ಅನ್ನು ತೆರೆಯಿರಿ" "%1$s ಅನ್ನು ಉಳಿಸದೆಯೇ ಮುಚ್ಚಲಾಗುತ್ತದೆ" "%1$s ಮೆಮೊರಿ ಮಿತಿಯನ್ನು ಮೀರಿದೆ" + + "ಹೀಪ್ ಡಂಪ್ ಅನ್ನು ಸಂಗ್ರಹಿಸಲಾಗಿದೆ; ಹಂಚಲು ಟ್ಯಾಪ್ ಮಾಡಿ" "ಹೀಪ್ ಡಂಪ್ ಹಂಚಿಕೊಳ್ಳುವುದೇ?" - "%1$s ಪ್ರಕ್ರಿಯೆಯು %2$s ರ ಪ್ರಕ್ರಿಯೆ ಮೆಮೊರಿ ಮಿತಿಯನ್ನು ಮೀರಿದೆ. ನೀವು ಅದರ ಡೆವಲಪರ್ ಜೊತೆ ಹಂಚಿಕೊಳ್ಳಲು ಹೀಪ್ ಡಂಪ್ ಲಭ್ಯವಿದೆ. ಎಚ್ಚರಿಕೆ: ಈ ಹೀಪ್ ಡಂಪ್ ಅಪ್ಲಿಕೇಶನ್ ಪ್ರವೇಶ ಹೊಂದಿರುವ ನಿಮ್ಮ ಯಾವುದೇ ವೈಯಕ್ತಿಕ ಮಾಹಿತಿಯನ್ನು ಹೊಂದಿರಬಹುದು." + + + + + + "ಪಠ್ಯಕ್ಕೆ ಕ್ರಿಯೆಯನ್ನು ಆಯ್ಕೆಮಾಡಿ" "ರಿಂಗರ್ ವಾಲ್ಯೂಮ್" "ಮೀಡಿಯಾ ವಾಲ್ಯೂಮ್" @@ -1254,8 +1294,10 @@ "ಎಲ್ಲಾ ನೆಟ್‌ವರ್ಕ್‌ಗಳನ್ನು ನೋಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ" "ಸಂಪರ್ಕಿಸಿ" "ಎಲ್ಲಾ ನೆಟ್‌ವರ್ಕ್‌ಗಳು" - "%s ಅವರು ಪ್ರಸ್ತಾಪಿಸಿದ ವೈ-ಫೈ ನೆಟ್‌ವರ್ಕ್‌ ಲಭ್ಯವಿದೆ" - "%s ಅವರು ಪ್ರಸ್ತಾಪಿಸಿದ ನೆಟ್ವರ್ಕ್‌ಗಳಿಗೆ ನೀವು ಸಂಪರ್ಕಿಸಲು ಬಯಸುವಿರಾ?" + + + + "ಹೌದು" "ಇಲ್ಲ" "ವೈ‑ಫೈ ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಆನ್ ಆಗುತ್ತದೆ" @@ -1267,9 +1309,14 @@ "ನೆಟ್‌ವರ್ಕ್‌ಗೆ ಸೈನ್ ಇನ್ ಮಾಡಿ" - "ವೈ ಫೈ ಯಾವುದೇ ಇಂಟರ್ನೆಟ್ ಪ್ರವೇಶವನ್ನು ಹೊಂದಿಲ್ಲ" + + "ಆಯ್ಕೆಗಳಿಗೆ ಟ್ಯಾಪ್ ಮಾಡಿ" "ಸಂಪರ್ಕಿಸಲಾಗಿದೆ" + + + + "ನಿಮ್ಮ ಹಾಟ್‌ಸ್ಪಾಟ್‌ ಸೆಟ್ಟಿಂಗ್‌ಗಳಿಗೆ ಬದಲಾವಣೆಗಳು" "ನಿಮ್ಮ ಹಾಟ್‌ಸ್ಪಾಟ್‌ ಬ್ಯಾಂಡ್ ಬದಲಾಗಿದೆ." "ಈ ಸಾಧನವು 5GHz ಗೆ ಮಾತ್ರ ನಿಮ್ಮ ಆದ್ಯತೆಯನ್ನು ಬೆಂಬಲಿಸುವುದಿಲ್ಲ. ಬದಲಿಗೆ, ಈ ಸಾಧನವು 5GHz ಬ್ಯಾಂಡ್ ಅನ್ನು ಲಭ್ಯವಿರುವಾಗ ಬಳಸುತ್ತದೆ." @@ -1352,9 +1399,13 @@ "ಸಂಪರ್ಕಗೊಂಡಿರುವ ಸಾಧನವನ್ನು ಚಾರ್ಜ್ ಮಾಡಲಾಗುತ್ತಿದೆ. ಹೆಚ್ಚಿನ ಆಯ್ಕೆಗಳಿಗಾಗಿ ಟ್ಯಾಪ್ ಮಾಡಿ." "ಅನ್‌ಲಾಗ್ ಆಡಿಯೋ ಪರಿಕರ ಪತ್ತೆಯಾಗಿದೆ" "ಲಗತ್ತಿಸಲಾದ ಸಾಧನವು ಈ ಫೋನಿನೊಂದಿಗೆ ಹೊಂದಿಕೆಯಾಗುವುದಿಲ್ಲ. ಇನ್ನಷ್ಟು ತಿಳಿಯಲು ಟ್ಯಾಪ್ ಮಾಡಿ." - "USB ಡೀಬಗಿಂಗ್‌‌ ಸಂಪರ್ಕ" + "USB ಡೀಬಗಿಂಗ್‌‌ ಸಂಪರ್ಕಗೊಂಡಿದೆ" "USB ಡೀಬಗ್‌ ಮಾಡುವಿಕೆಯನ್ನು ಆಫ್‌ ಮಾಡಲು ಟ್ಯಾಪ್‌ ಮಾಡಿ" "USB ಡೀಬಗ್‌ ಮಾಡುವಿಕೆಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲು ಆಯ್ಕೆ ಮಾಡಿ." + + + + "USB ಪೋರ್ಟ್‌ನಲ್ಲಿ ದ್ರವ ಅಥವಾ ಧೂಳಿನ ಕಣಗಳಿವೆ" "USB ಪೋರ್ಟ್ ಸ್ವಯಂಚಾಲಿತವಾಗಿ ನಿಷ್ಕ್ರಿಯಗೊಂಡಿದೆ. ಇನ್ನಷ್ಟು ತಿಳಿಯಲು ಟ್ಯಾಪ್ ಮಾಡಿ" "USB ಪೋರ್ಟ್ ಬಳಸಲು ಸುರಕ್ಷಿತವಾಗಿದೆ" @@ -1397,8 +1448,7 @@ "ಹೊಂದಿಸು" "ಇಜೆಕ್ಟ್" "ಎಕ್ಸ್‌ಪ್ಲೋರ್‌‌" - - + "ಔಟ್‌ಪುಟ್‌ಗೆ ಬದಲಿಸಿ" "%s ಕಾಣೆಯಾಗಿದೆ" "ಸಾಧನವನ್ನು ಪುನಃ ಸೇರಿಸಿ" "%s ಸರಿಸಲಾಗುತ್ತಿದೆ" @@ -1907,8 +1957,6 @@ "ಕೆಲಸದ ಪ್ರೊಫೈಲ್ ಅನ್‌ಲಾಕ್ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ" "%1$s ಗೆ ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದೆ" "ಫೈಲ್‌ಗಳನ್ನು ವೀಕ್ಷಿಸಲು ಟ್ಯಾಪ್‌ ಮಾಡಿ" - "ಪಿನ್ ಮಾಡು" - "ಅನ್‌ಪಿನ್" "ಅಪ್ಲಿಕೇಶನ್ ಮಾಹಿತಿ" "−%1$s" "ಡೆಮೋ ಪ್ರಾರಂಭಿಸಲಾಗುತ್ತಿದೆ..." @@ -1999,6 +2047,22 @@ "ದೈನಂದಿನ ಸ್ಥಿತಿಯ ಮಾಹಿತಿಯ ಅಧಿಸೂಚನೆ" "ಚಾರ್ಜ್‌ಗೆ ಮೊದಲೆ ಬ್ಯಾಟರಿ ಮುಗಿದು ಬಿಡಬಹುದು" "ಬ್ಯಾಟರಿ ಅವಧಿ ಹೆಚ್ಚಿಸಲು ಬ್ಯಾಟರಿ ಸೇವರ್ ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ" + + + + + + + + + + + + + + + + "ಫೋಲ್ಡರ್" "Android ಆ್ಯಪ್‌" "ಫೈಲ್" diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml index 938c53972fa5010adbf6ee1b01262d71cd1016c4..e27883234376bf0c0dca660fd3a624766c97d1a2 100644 --- a/core/res/res/values-mr/strings.xml +++ b/core/res/res/values-mr/strings.xml @@ -141,8 +141,10 @@ "वायफाय कॉलिंग" "VoWifi" "बंद" - "वाय-फाय अग्रमानांकित" - "प्राधान्य दिलेला मोबाइल" + + + + "केवळ वाय-फाय" "{0}: अग्रेषित केला नाही" "{0}: {1}" @@ -228,7 +230,8 @@ "बग रीपोर्ट" "सेशन समाप्त करा" "स्क्रीनशॉट" - "बग रीपोर्ट घ्या" + + "ई-मेल मेसेज म्हणून पाठविण्यासाठी, हे तुमच्या सद्य डिव्हाइस स्थितीविषयी माहिती संकलित करेल. बग रीपोर्ट सुरू करण्यापासून तो पाठविण्यापर्यंत थोडा वेळ लागेल; कृपया धीर धरा." "परस्परसंवादी अहवाल" "बहुतांश प्रसंगांमध्ये याचा वापर करा. ते तुम्हाला अहवालाच्या प्रगतीचा मागोवा घेण्याची, समस्येविषयी आणखी तपाशील एंटर करण्याची आणि स्क्रीनशॉट घेण्याची अनुमती देते. ते कदाचित अहवाल देण्यासाठी बराच वेळ घेणारे कमी-वापरलेले विभाग वगळू शकते." @@ -281,9 +284,12 @@ "स्थान" "या डिव्हाइसच्या स्थानावर प्रवेश" "<b>%1$s</b> ला या डिव्हाइसचे स्थान अॅक्सेस करू द्यायचे?" - "तुम्ही अ‍ॅप वापरत असताना, अ‍ॅपला फक्त स्थानाचा अॅक्सेस असेल." - "या डिव्हाइसचे स्थान अॅक्सेस करण्याची <b>%1$s</b> ला नेहेमी अनुमती द्यायची का?" - "तुम्ही अ‍ॅप वापरत नसलात तरीही, अ‍ॅपला स्थानाचा नेहेमी अॅक्सेस असेल." + + + + + + "कॅलेंडर" "आपल्या कॅलेंडरवर प्रवेश" "<b>%1$s</b> ला तुमचे कॅलेंडर अॅक्सेस करू द्यायचे?" @@ -316,7 +322,10 @@ "<b>%1$s</b> ला तुमचे संगीत अॅक्सेस करू द्यायचे का?" "फोटो आणि व्हिडिओ" "तुमचे फोटो आणि व्हिडिओ अॅक्सेस करा" - "<b>%1$s</b> ला टॅग केलेल्या स्थानांसह तुमचे फोटो आणि व्हिडिओ अॅक्सेस करण्याची अनुमती द्यायची का?" + + + + "विंडोमधील आशय पुन्हा मिळवा" "तुम्ही वापरत असलेल्‍या विंडोमधील आशय तपासा." "स्पर्श करून अन्वेषण चालू करा" @@ -509,8 +518,10 @@ "फील्ड जवळील कम्युनिकेशन (NFC) टॅग, कार्डे आणि वाचक यांच्यासह संवाद करण्यासाठी अॅपला अनुमती देते." "तुमचे स्क्रीन लॉक अक्षम करा" "कीलॉक आणि कोणतीही संबद्ध पासवर्ड सुरक्षितता अक्षम करण्यासाठी अ‍ॅप ला अनुमती देते. उदाहरणार्थ, येणारा फोन कॉल प्राप्त करताना फोन कीलॉक अक्षम करतो, नंतर जेव्हा कॉल समाप्त होतो तेव्हा तो कीलॉक पुन्हा-सक्षम करतो." - "स्क्रीन लॉक क्लिष्टतेची विनंती करा" - "अ‍ॅपला स्क्रीन लॉक कितपात क्लिष्ट आहे (खूप, मध्यम, कमी किंवा अजिबात नाही) हे जाणून घेण्याची अनुमती देते, जी वर्णांची साधारण रेंज आणि स्क्रीन लॉकचा प्रकार सूचित करते. अ‍ॅप वापरकर्त्यांना असे देखील सुचवू शकते की त्यांनी स्क्रीन लॉक ठराविक पातळीपर्यंत अपडेट करावे पण वापरकर्ते त्याकडे दुर्लक्षत करू शकतात आणि तेथून नेव्हिगेट करू शकता. लक्षात ठेवा की, स्क्रीन लॉक प्लेनटेक्स्टमध्ये स्टोअर केले जात नसल्यामुळे अ‍ॅपला नेमका पासवर्ड माहीत नसतो." + + + + "बायोमेट्रिक हार्डवेअर वापरा" "ऑथेंटिकेशनसाठी बायोमेट्रिक हार्डवेअरचा वापर करण्याची अॅपला अनुमती देते" "फिंगरप्रिंट हार्डवेअर व्यवस्थापित करा" @@ -565,37 +576,59 @@ "अॅपला वापरासाठी चेहरा टेम्पलेट जोडण्याच्या आणि हटवण्याच्या पद्धती जारी करू देते." "चेहरा ऑथेंटिकेशन हार्डवेअर वापरा" "अॅपला चेहरा ऑथेंटिकेशनसाठी ऑथेंटिकेशन हार्डवेअर वापरू देते" - "चेहऱ्यावर प्रक्रिया झाली नाही. पुन्हा प्रयत्न करा." - "चेहऱ्यावर खूप प्रकाश आहे. कृपया कमी प्रकाशात प्रयत्न करा." - "चेहऱ्यावर खूप अंधार आहे. कृपया प्रकाश स्रोत खुला करा." - "कृपया सेन्सर चेहऱ्यापासून आणखी दूर हलवा." - "कृपया सेन्सर चेहऱ्याच्या आणखी जवळ आणा." - "कृपया सेन्सर आणखी वर हलवा." - "कृपया सेन्सर आणखी खाली हलवा." - "कृपया सेन्सर उजवीकडे हलवा." - "कृपया सेन्सर डावीकडे हलवा." - "कृपया सेन्सरकडे पहा." - "चेहरा आढळला नाही." - "डिव्हाइस खूप हलत आहे." + + + + + + + + + + + + + + + + + + + + + + + + "कृपया तुमच्या चेहऱ्याची पुन्हा नोंदणी करा." - "वेगळा चेहरा आढळला आहे." + + "एकाच प्रकारची पोझ देत आहात कृपया तुमची पोझ बदला." - "कृपया थेट कॅमेऱ्याच्या दिशेने पाहा." - "कृपया थेट कॅमेऱ्याच्या दिशेने पाहा." + + + + "कृपया तुमची मान वर करा." - "कृपया तुमचा चेहरा दाखवा." + + + + "चेहरा हार्डवेअर उपलब्ध नाही." - "चेहरा टाइमआउट झाला. पुन्हा प्रयत्न करा." + + "चेहरा स्टोअर केला जाऊ शकत नाही." "चेहरा ऑपरेशन रद्द केले गेले." "वापरकर्त्याने चेहरा ऑथेंटिकेशन रद्द केले." "खूप जास्त प्रयत्न केले. नंतर पुन्हा प्रयत्न करा." "खूप जास्त प्रयत्न केले. चेहरा ऑथेंटिकेशन बंद केले गेले." - "पुन्हा प्रयत्न करा." - "चेहरा नोंदवलेला नाही." - "या डिव्हाइसमध्ये चेहरा ऑथेंटिकेशन सेन्सर नाही." + + + + + + "चेहरा %d" @@ -1164,7 +1197,7 @@ "%1$s थांबतो" "%1$s थांबते" "अ‍ॅप पुन्हा उघडा" - "अभिप्राय पाठवा" + "फीडबॅक पाठवा" "बंद करा" "डिव्हाइस रीस्टार्ट होईपर्यंत म्यूट करा" "प्रतीक्षा करा" @@ -1213,9 +1246,16 @@ "%1$s उघडा" "%1$s सेव्ह न करता बंद होईल" "%1$s ने मेमेरी मर्यादा वाढविली" + + "हीप डंप गोळा केले. शेअर करण्यासाठी टॅप करा." "हीप डंप शेअर करायचे?" - "%1$s प्रक्रियेने त्याची %2$s ची प्रक्रिया मेमरी मर्यादा ओलांडली आहे. त्याच्या विकासकासह शेअर करण्यासाठी तुमच्यासाठी हीप डंप उपलब्ध आहे. सावधगिरी बाळगा: या हीप डंपमध्ये तुमची कोणतीही वैयक्तिक माहिती असू शकते ज्यात अॅप्लिकेशन प्रवेश करू शकतो." + + + + + + "मजकुरासाठी क्रिया निवडा" "रिंगर व्हॉल्यूम" "मीडिया व्हॉल्यूम" @@ -1254,8 +1294,10 @@ "सर्व नेटवर्क पाहण्यासाठी टॅप करा" "कनेक्ट करा" "सर्व नेटवर्क" - "%s ने प्रस्तावित केलेले वाय-फाय नेटवर्क उपलब्ध आहे" - "%s द्वारे प्रस्तावित नेटवर्कशी कनेक्ट करायचे आहे का?" + + + + "होय" "नाही" "वाय-फाय आपोआप चालू होईल" @@ -1267,9 +1309,14 @@ "नेटवर्कवर साइन इन करा" - "वाय-फाय ला इंटरनेटचा अॅक्सेस नाही" + + "पर्यायांसाठी टॅप करा" "कनेक्ट केले" + + + + "तुमच्या हॉटस्पॉट सेटिंग्जमधील बदल" "तुमचा हॉटस्पॉट बँड बदलला आहे." "हे डिव्हाइस तुमच्या फक्त ५GHz साठी प्राधान्याला सपोर्ट करत नाही. त्याऐवजी, हे डिव्हाइस ५GHz बँड उपलब्ध असताना वापरेल." @@ -1355,6 +1402,10 @@ "USB डीबग करणे कनेक्‍ट केले" "USB डीबगिंग बंद करण्यासाठी टॅप करा" "USB डीबगिंग बंद करण्यासाठी निवडा." + + + + "USB पोर्ट मध्ये ओलावा किंवा धूळ आहे" "USB पोर्ट आपोआप बंद होईल. अधिक जाणून घेण्यासाठी टॅप करा." "USB फोर्ट वापरण्यासाठी सुरक्षित आहे" @@ -1906,8 +1957,6 @@ "कार्य प्रोफाईल अनलॉक करण्यासाठी टॅप करा" "%1$s शी कनेक्ट केलेले" "फायली पाहण्यासाठी टॅप करा" - "पिन" - "अनपिन करा" "अ‍ॅप माहिती" "−%1$s" "डेमो प्रारंभ करत आहे..." @@ -1998,6 +2047,22 @@ "दिनक्रम मोडची माहिती सूचना" "चार्जिंगची सामान्य पातळी गाठेपर्यंत कदाचित बॅटरी संपू शकते" "बॅटरी लाइफ वाढवण्यासाठी बॅटरी सेव्हर सुरू केला आहे" + + + + + + + + + + + + + + + + "फोल्डर" "Android अ‍ॅप्लिकेशन" "फाइल" diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml index ecaff4d23ba5a2e6c93db9874432e19781a353d8..d501cd7be67091a76c17c15a17091051f06e24db 100644 --- a/core/res/res/values-pt-rPT/strings.xml +++ b/core/res/res/values-pt-rPT/strings.xml @@ -141,8 +141,10 @@ "Chamadas Wi-Fi" "VoWifi" "Desativado" - "Rede Wi-Fi preferida" - "Preferência pela rede móvel" + + + + "Apenas Wi-Fi" "{0}: Não reencaminhado" "{0}: {1}" @@ -228,7 +230,8 @@ "Relatório de erros" "Terminar sessão" "Captura de ecrã" - "Criar relatório de erros" + + "Será recolhida informação sobre o estado atual do seu dispositivo a enviar através de uma mensagem de email. Demorará algum tempo até que o relatório de erro esteja pronto para ser enviado. Aguarde um pouco." "Relatório interativo" "Utilize esta opção na maioria das circunstâncias. Permite monitorizar o progresso do relatório, introduzir mais detalhes acerca do problema e tirar capturas de ecrã. Pode omitir algumas secções menos utilizadas que demoram muito tempo a comunicar." @@ -281,9 +284,12 @@ "Localização" "aceder à localização do seu dispositivo" "Pretende permitir que a aplicação <b>%1$s</b> aceda à localização deste dispositivo?" - "A aplicação tem acesso à localização apenas quando a estiver a utilizar." - "Pretende permitir que a aplicação <b>%1$s</b> aceda sempre à localização deste dispositivo?" - "A aplicação terá sempre acesso à localização, mesmo quando não está a utilizá-la." + + + + + + "Calendário" "aceder ao calendário" "Pretende permitir que a aplicação <b>%1$s</b> aceda ao calendário?" @@ -316,7 +322,10 @@ "Pretende permitir que a aplicação <b>%1$s</b> aceda à sua música?" "Fotos e vídeos" "aceder aos seus vídeos e fotos" - "Pretende permitir que a aplicação <b>%1$s</b> aceda aos seus vídeos e fotos, incluindo localizações etiquetadas?" + + + + "Obter conteúdo da janela" "Inspecionar o conteúdo de uma janela com a qual está a interagir." "Ativar Explorar Através do Toque" @@ -509,8 +518,10 @@ "Permite que a aplicação comunique com etiquetas, cartões e leitores Near Field Communication (NFC)." "desativar o bloqueio do ecrã" "Permite que a aplicação desative o bloqueio de teclas e qualquer segurança por palavra-passe associada. Por exemplo, o telemóvel desativa o bloqueio de teclas quando recebe uma chamada e reativa o bloqueio de teclas ao terminar a chamada." - "solicitar a complexidade do bloqueio de ecrã" - "Permite que a aplicação aprenda o nível de complexidade do bloqueio de ecrã (elevado, médio, baixo ou nenhum), que indica o intervalo de comprimento e o tipo de bloqueio de ecrã possíveis. A aplicação também pode sugerir aos utilizadores que atualizem o bloqueio de ecrã para um determinado nível, mas estes podem ignorar livremente a sugestão e continuar a navegação. Tenha em atenção que o bloqueio de ecrã não é armazenado em texto simples, pelo que a aplicação desconhece a palavra-passe exata." + + + + "Utilizar hardware biométrico" "Permite que a aplicação utilize hardware biométrico para autenticação." "gerir o hardware de impressão digital" @@ -565,37 +576,59 @@ "Permite à aplicação invocar métodos para adicionar e eliminar modelos faciais para uso." "utilizar hardware de autenticação facial" "Permite que a aplicação utilize hardware de autenticação facial para autenticação." - "Não foi possível processar o rosto. Tente de novo." - "Rosto demasiado claro. Experimente com menos luz." - "Rosto demasiado escuro. Destape a fonte de luz." - "Afaste o sensor do rosto." - "Aproxime o sensor do rosto." - "Mova o sensor para cima." - "Mova o sensor para baixo." - "Mova o sensor para a direita." - "Mova o sensor para a esquerda." - "Olhe para o sensor." - "Nenhum rosto detetado." - "Demasiado movimento." + + + + + + + + + + + + + + + + + + + + + + + + "Volte a inscrever o rosto." - "Foi detetado um rosto diferente." + + "Muito parecida, mude de pose." - "Olhe mais diretamente para a câmara." - "Olhe mais diretamente para a câmara." + + + + "Endireite a cabeça na vertical." - "Destape o rosto." + + + + "O hardware de rosto não está disponível." - "Limite de tempo de rosto atingido. Tente novamente." + + "Não é possível armazenar o rosto." "Operação de rosto cancelada." "Autenticação facial cancelada pelo utilizador." "Demasiadas tentativas. Tente novamente mais tarde." "Demasiadas tentativas. Autenticação facial desativada." - "Tente novamente." - "Nenhum rosto inscrito." - "Este dispositivo não tem sensor de autenticação facial." + + + + + + "Rosto %d" @@ -1213,9 +1246,16 @@ "Abrir a aplicação %1$s" "A aplicação %1$s vai fechar sem guardar." "%1$s excedeu o limite da memória" + + "Foi recolhida a captura da área dinâmica para dados. Toque para partilhar." "Pretende partilhar a captura da área dinâmica para dados?" - "O processo %1$s excedeu o respetivo limite de memória do processo de %2$s. Está disponível uma captura da área dinâmica para dados para partilhar com o respetivo programador. Tenha atenção: esta captura da área dinâmica para dados pode conter algumas das suas informações pessoais a que a aplicação tem acesso." + + + + + + "Escolha uma ação para o texto" "Volume da campainha" "Volume de multimédia" @@ -1254,8 +1294,10 @@ "Toque para ver todas as redes" "Ligar" "Todas as redes" - "Está disponível uma rede Wi-Fi proposta por %s" - "Pretende estabelecer ligação às redes propostas por %s?" + + + + "Sim" "Não" "O Wi‑Fi será ativado automaticamente" @@ -1267,9 +1309,14 @@ "Início de sessão na rede" - "O Wi-Fi não tem acesso à Internet." + + "Toque para obter mais opções" "Ligado" + + + + "Alterações às definições de zona Wi-Fi" "A banda da sua zona Wi-Fi foi alterada." "Este dispositivo não suporta a sua preferência apenas para 5 GHz. Em alternativa, este dispositivo vai utilizar a banda de 5 GHz quando estiver disponível." @@ -1354,6 +1401,10 @@ "Depuração USB ligada" "Toque para desativar a depuração USB." "Selecione para desativar a depuração por USB." + + + + "Líquido ou resíduos na porta USB" "A porta USB é automaticamente desativada. Toque para saber mais." "É seguro utilizar a porta USB" @@ -1905,8 +1956,6 @@ "Toque p/ desb. perfil trabalho" "Ligado a %1$s" "Tocar para ver ficheiros" - "Fixar" - "Soltar" "Info. da aplicação" "-%1$s" "A iniciar a demonstração…" @@ -1997,6 +2046,22 @@ "Notificação de informações do Modo rotina" "Pode ficar sem bateria antes do carregamento habitual" "Poupança de bateria ativada para prolongar a duração da bateria" + + + + + + + + + + + + + + + + "Pasta" "Aplicação para Android" "Ficheiro" diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml index 31fa1274b063ae1b3af67ec76490d1a497167bc7..714f0b40e9b310b9e33e8dc9f7a24e5362f509d2 100644 --- a/core/res/res/values-sk/strings.xml +++ b/core/res/res/values-sk/strings.xml @@ -143,8 +143,10 @@ "Volanie cez Wi‑Fi" "VoWifi" "Vypnuté" - "Preferovať Wi‑Fi" - "Preferovať mobilné spojenie" + + + + "Len Wi‑Fi" "{0}: Nepresmerované" "{0}: {1}" @@ -232,7 +234,8 @@ "Hlásenie o chybách" "Ukončiť reláciu" "Snímka obrazovky" - "Vytvoriť hlásenie chyby" + + "Týmto zhromaždíte informácie o aktuálnom stave zariadenia. Informácie je potom možné odoslať e-mailom, chvíľu však potrvá, kým bude hlásenie chyby pripravené na odoslanie. Prosíme vás preto o trpezlivosť." "Interaktívne nahlásenie" "Táto možnosť je vhodná pre väčšinu prípadov. Umožňuje sledovať priebeh nahlásenia, zadávať ďalšie podrobnosti o probléme a vytvárať snímky obrazovky. Môžu byť vynechané niektoré menej používané sekcie, ktorých nahlásenie trvá dlho." @@ -287,9 +290,12 @@ "Poloha" "prístup k polohe tohto zariadenia" "Povoliť aplikácii <b>%1$s</b> prístup k polohe tohto zariadenia?" - "Aplikácia bude mať prístup k polohe iba vtedy, keď ju budete používať." - "Chcete vždy povoliť aplikácii <b>%1$s</b> prístup k polohe tohto zariadenia?" - "Aplikácia bude mať vždy prístup k polohe, aj keď ju nebudete používať." + + + + + + "Kalendár" "prístup ku kalendáru" "Povoliť aplikácii <b>%1$s</b> prístup ku kalendáru?" @@ -322,7 +328,10 @@ "Chcete povoliť aplikácii <b>%1$s</b> prístup k hudbe?" "Fotky a videá" "prístup k fotkám a videám" - "Chcete povoliť aplikácii <b>%1$s</b> prístup k vašim fotkám a videám vrátane označených miest?" + + + + "Načítať obsah okna" "Môžete preskúmať obsah okna, s ktorým pracujete." "Zapnúť funkciu Preskúmanie dotykom" @@ -515,8 +524,10 @@ "Umožňuje aplikácii komunikovať so značkami, kartami a čítačkami s podporou technológie NFC." "deaktivácia zámky obrazovky" "Umožňuje aplikácii zakázať uzamknutie klávesnice a akékoľvek súvisiace zabezpečenie heslom. Príkladom je zakázanie uzamknutia klávesnice pri prichádzajúcom telefonickom hovore a jeho opätovné povolenie po skončení hovoru." - "požadovať zložitosť zámky obrazovky" - "Umožňuje aplikácii zapamätať si úroveň zložitosti zámky obrazovky (vysoká, stredná, nízka alebo žiadna), ktorá udáva pravdepodobný rozsah dĺžky a typu zámky obrazovky. Aplikácia tiež navrhuje používateľom aktualizáciu zámky obrazovky na určitú úroveň, používatelia sa však môžu na základe vlastného uváženia rozhodnúť tento návrh ignorovať a prejsť inam. Upozorňujeme, že zámka obrazovky nie je uložená vo forme obyčajného textu, takže aplikácia nepozná presné heslo." + + + + "používať biometrický hardvér" "Umožňuje aplikácii používať na overenie totožnosti biometrický hardvér" "spravovať hardvér na snímanie odtlačkov prstov" @@ -571,37 +582,59 @@ "Umožňuje aplikácii vyvolať metódy, ktoré pridávajú a odstraňujú šablóny tvárí." "používanie hardvéru na overenie tváre" "Umožňuje aplikácii používať na overenie totožnosti hardvér na overenie tváre" - "Tvár sa nepodarilo spracovať. Skúste to znova." - "Tvár je príliš svetlá. Skúste to pri nižšom osvetlení." - "Tvár je príliš tmavá. Zvýšte osvetlenie." - "Oddiaľte senzor od tváre." - "Priblížte senzor k tvári." - "Pohnite senzor vyššie." - "Pohnite senzor nižšie." - "Pohnite senzor doprava." - "Pohnite senzor doľava." - "Pozerajte sa na senzor." - "Nebola rozpoznaná žiadna tvár." - "Priveľa pohybu." + + + + + + + + + + + + + + + + + + + + + + + + "Znova zaregistrujte svoju tvár." - "Bola rozpoznaná iná tvár." + + "Príliš rovnaké, zmeňte postoj." - "Pozrite sa priamejšie do fotoaparátu." - "Pozrite sa priamejšie do fotoaparátu." + + + + "Zvisle vyrovnajte hlavu." - "Odkryte svoju tvár." + + + + "Hardvér na snímanie tváre nie je k dispozícii" - "Limit rozpoznania tváre vypršal. Skúste to znova." + + "Tvár sa nedá uchovať." "Operácia týkajúca sa tváre bola zrušená" "Overenie tváre bolo zrušené používateľom." "Príliš veľa pokusov. Skúste to znova neskôr." "Príliš veľa pokusov. Overenie tváre je zakázané." - "Skúste to znova." - "Nemáte zaregistrovanú žiadnu tvár." - "Toto zariadenie nemá senzor na overenie tváre." + + + + + + "Tvár %d" @@ -1253,9 +1286,16 @@ "Otvoriť %1$s" "%1$s sa zavrie bez uloženia" "Proces %1$s prekročil limit pamäte" + + "Boli zhromaždené zálohy dát. Zdieľajte ich klepnutím." "Chcete zdieľať zálohy údajov?" - "Proces %1$s prekročil limit %2$s pre pamäť procesu. Máte k dispozícii zálohy údajov, ktoré môžete zdieľať s vývojárom. Postupujte opatrne: tieto zálohy údajov nesmú obsahovať žiadne osobné informácie, ku ktorým má táto aplikácia prístup." + + + + + + "Zvoľte akciu pre text" "Hlasitosť vyzváňania" "Hlasitosť médií" @@ -1298,8 +1338,10 @@ "Klepnutím zobrazíte všetky siete" "Pripojiť" "Všetky siete" - "K dispozícii je sieť Wi-Fi, ktorú navrhla aplikácia %s" - "Chcete sa pripájať k sieťam navrhnutým aplikáciou %s?" + + + + "Áno" "Nie" "Wi‑Fi sa zapne automaticky" @@ -1311,9 +1353,14 @@ "Prihlásenie do siete" - "Sieť Wi‑Fi nemá prístup k internetu" + + "Klepnutím získate možnosti" "Pripojené" + + + + "Zmeny nastavení hotspotu" "Pásmo vášho hotspotu sa zmenilo." "Toto zariadenie nepodporuje vašu predvoľbu používať iba 5 GHz. Namiesto toho bude pásmo 5 GHz používať vtedy, keď bude k dispozícii." @@ -1398,6 +1445,10 @@ "Ladenie cez USB pripojené" "Klepnutím vypnite ladenie cez USB" "Vyberte, ak chcete zakázať ladenie cez USB." + + + + "Tekutina alebo nečistoty v porte USB" "Port USB je automaticky deaktivovaný. Ďalšie informácie zobrazíte klepnutím." "Port USB môžete bezpečne používať" @@ -1973,8 +2024,6 @@ "Profil odomknete klepnutím" "Pripojené k zariadeniu %1$s" "Klepnutím zobrazíte súbory" - "Pripnúť" - "Uvoľniť" "Info o aplikácii" "-%1$s" "Spúšťa sa ukážka…" @@ -2067,6 +2116,22 @@ "Upozornenie s informáciami o rutinnom režime" "Batéria sa môže vybiť pred obvyklým nabitím" "Bol aktivovaný šetrič batérie na predĺženie výdrže batérie" + + + + + + + + + + + + + + + + "Priečinok" "Aplikácia pre Android" "Súbor" diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml index 16ea0b7c282bc91c0a6146738b5820cd38a1c787..41f81efc084f76d8bf6a415ad39c9f7fa31dd503 100644 --- a/core/res/res/values-ta/strings.xml +++ b/core/res/res/values-ta/strings.xml @@ -141,8 +141,10 @@ "வைஃபை அழைப்பு" "VoWifi" "ஆஃப்" - "வைஃபைக்கு முன்னுரிமை" - "மொபைல் தரவிற்கு முன்னுரிமை" + + + + "வைஃபை மட்டும்" "{0}: பகிரப்படவில்லை" "{0}: {1}" @@ -228,7 +230,8 @@ "பிழை அறிக்கை" "அமர்வை முடிக்கிறது" "ஸ்கிரீன்ஷாட்" - "பிழை அறிக்கையை எடு" + + "உங்கள் நடப்புச் சாதன நிலையை மின்னஞ்சல் செய்தியாக அனுப்ப, அது குறித்த தகவலை இது சேகரிக்கும். பிழை அறிக்கையைத் தொடங்குவதில் இருந்து, அது அனுப்புவதற்குத் தயாராகும் வரை, இதற்குச் சிறிது நேரம் ஆகும்; பொறுமையாகக் காத்திருக்கவும்." "ஊடாடத்தக்க அறிக்கை" "பெரும்பாலான சூழ்நிலைகளில் இதைப் பயன்படுத்தவும். இது அறிக்கையின் நிலையைக் கண்காணிக்க, சிக்கலைப் பற்றி மேலும் விவரங்களை உள்ளிட மற்றும் ஸ்கிரீன் ஷாட்டுகளை எடுக்க அனுமதிக்கும். அறிக்கையிட நீண்ட நேரம் எடுக்கக்கூடிய குறைவாகப் பயன்படுத்தப்படும் பிரிவுகள் சிலவற்றை இது தவிர்க்கக்கூடும்." @@ -281,9 +284,12 @@ "இருப்பிடம்" "இந்தச் சாதனத்தின் இருப்பிடத்தை அறிந்து கொள்ள" "இந்தச் சாதனத்தின் இருப்பிடத்தை அணுகுவதற்கு <b>%1$s</b> ஆப்ஸை அனுமதிக்கவா?" - "இந்த ஆப்ஸைப் பயன்படுத்தும் சமயத்தில் மட்டுமே, இது உங்கள் இருப்பிடத்தை அணுகும்." - "இதன் இருப்பிடத்தை எப்போதுமே <b>%1$s</b> அணுக அனுமதிக்கவா?" - "இந்த ஆப்ஸைப் பயன்படுத்தாத சமயங்களில் கூட, இது உங்கள் இருப்பிடத்தை அணுகும்." + + + + + + "கேலெண்டர்" "கேலெண்டரை அணுகலாம்" "கேலெண்டரை அணுகுவதற்கு <b>%1$s</b> பயன்பாட்டை அனுமதிக்கவா?" @@ -308,17 +314,17 @@ "ஃபோன்" "யாரையும் தொலைபேசியில் அழைக்கலாம்" "மொபைல் அழைப்புகள் செய்யவும், அவற்றை நிர்வகிக்கவும், <b>%1$s</b> ஆப்ஸை அனுமதிக்கவா?" - - + "உடல் சென்சார்கள்" "உங்கள் உடல் இயக்கம் பற்றி உணர்விகள் கூறும் தகவலைப் பார்க்கலாம்" "உங்கள் உடலியக்கக் குறிகள் பற்றிய சென்சார் தரவை அணுகுவதற்கு <b>%1$s</b> பயன்பாட்டை அனுமதிக்கவா?" "இசை" "இசையைக் கேட்கலாம்" "இசையை அணுக <b>%1$s</b> ஆப்ஸை அனுமதிக்கவா?" - - + "படங்கள் & வீடியோக்கள்" "படங்கள் & வீடியோக்களைப் பார்க்கலாம்" - + + + "சாளர உள்ளடக்கத்தைப் பெறும்" "நீங்கள் பணியாற்றிக் கொண்டிருக்கும் சாளரத்தின் உள்ளடக்கத்தைப் பார்க்கலாம்." @@ -512,8 +518,10 @@ "குறுகிய இடைவெளி தகவல்பரிமாற்றம் (NFC), குறிகள், கார்டுகள் மற்றும் ரீடர்கள் ஆகியவற்றுடன் தொடர்புகொள்ள, பயன்பாட்டை அனுமதிக்கிறது." "உங்கள் திரைப் பூட்டை முடக்குதல்" "விசைப்பூட்டையும், தொடர்புடைய கடவுச்சொல் பாதுகாப்பையும் முடக்கப் பயன்பாட்டை அனுமதிக்கிறது. எடுத்துக்காட்டாக, உள்வரும் மொபைல் அழைப்பைப் பெறும்போது மொபைல் விசைப்பூட்டை முடக்குகிறது, பிறகு அழைப்பு முடிந்தவுடன் விசைப்பூட்டை மீண்டும் இயக்குகிறது." - "திரைப் பூட்டு தொடர்பான சிக்கலைத் தீர்க்க அனுமதி கோருதல்" - "திரைப் பூட்டு தொடர்பான சிக்கலின் தன்மையைப் பற்றி (அதிகம், நடுத்தரம், குறைவு அல்லது ஏதுமில்லை) அறிந்துகொள்ள ஆப்ஸை அனுமதிக்கிறது. இதன் மூலம் திரைப் பூட்டின் பாதுகாப்பு அளவையும் வகையையும் பற்றி அறிந்துகொள்ள முடிகிறது. மேலும் திரைப் பூட்டு தொடர்பான சிக்கலின் தன்மையைக் குறிப்பிட்ட நிலைக்கு மாற்றிக் கொள்ளலாம் என்பதையும் ஆப்ஸ் பயனர்களுக்குப் பரிந்துரைக்கலாம். ஆனால் தங்கள் விருப்பப்படி அவற்றைப் பயனர்கள் நிராகரிக்கவோ ஏற்கவோ செய்யலாம். கவனத்திற்கு: திரைப் பூட்டு எளிய உரையிலான கடவுச்சொல்லால் சேமிக்கப்படுவதில்லை என்பதால் சரியான கடவுச்சொல்லை ஆப்ஸால் அறிய இயலாது." + + + + "பயோமெட்ரிக் வன்பொருளைப் பயன்படுத்து" "பயோமெட்ரிக் வன்பொருளைப் பயன்படுத்தி அங்கீகரிப்பதற்கு, பயன்பாட்டை அனுமதிக்கும்" "கைரேகை வன்பொருளை நிர்வகி" @@ -568,37 +576,59 @@ "உபயோகிப்பதற்காக முக டெம்ப்ளேட்டுகளை சேர்க்கும்/நீக்கும் முறைகளை இயக்க, ஆப்ஸை அனுமதிக்கும்." "முக அங்கீகாரத்திற்கான வன்பொருளைப் பயன்படுத்துதல்" "அடையாளம் காண்பதற்கு, முக அங்கீகார வன்பொருளைப் பயன்படுத்த ஆப்ஸை அனுமதிக்கிறது" - "அடையாளம் காண முடியவில்லை. மீண்டும் முயலவும்." - "முகம் பிரகாசமாக உள்ளது. குறைந்த ஒளியில் முயலவும்." - "முகம் தெரியவில்லை, வெளிச்சமான இடத்தில் முயலவும்." - "சென்சாரை முகத்திலிருந்து சற்று தொலைவில் நகர்த்துக." - "சென்சாரை முகத்திற்கு அருகில் கொண்டு வரவும்." - "சென்சாரை மேலே உயர்த்தவும்." - "சென்சாரைக் கீழே நகர்த்தவும்." - "சென்சாரை வலது புறமாக நகர்த்தவும்." - "சென்சாரை இடது புறமாக நகர்த்தவும்." - "சென்சாரைப் பார்க்கவும்." - "முகம் தெரியவில்லை." - "சாதனம் அதிகமாக அசைகிறது." + + + + + + + + + + + + + + + + + + + + + + + + "உங்கள் முகத்தை மீண்டும் பதிவுசெய்யுங்கள்." - "வேறு முகம் கண்டறியப்பட்டது." + + "மீண்டும் அதே போஸ் தருகிறீர்கள், வேறு முயலுங்கள்." - "கேமராவை நேரடியாகப் பாருங்கள்." - "கேமராவை நேரடியாகப் பாருங்கள்." + + + + "உங்கள் தலையை நேராக வைக்கவும்." - "முகத்தை மறைக்காதீர்கள்." + + + + "முக அங்கீகாரத்திற்கான வன்பொருள் இல்லை." - "முகப் பதிவிற்கான நேரம் முடிந்தது. மீண்டும் முயல்க." + + "முகத்தைச் சேமிக்க இயலாது." "முக அங்கீகாரச் செயல்பாடு ரத்துசெய்யப்பட்டது." "பயனர், முக அங்கீகாரத்தை ரத்துசெய்தார்." "பலமுறை முயன்றுவிட்டீர்கள். பிறகு முயலவும்." "பலமுறை தோல்வி. முக அங்கீகாரம் முடக்கப்பட்டது." - "மீண்டும் முயலவும்." - "முகம் எதுவும் பதிவு செய்யப்படவில்லை." - "இந்தச் சாதனத்தில் முக அங்கீகாரத்திற்கான சென்சார் இல்லை." + + + + + + "முகம் %d" @@ -1216,9 +1246,16 @@ "%1$s பயன்பாட்டைத் திற" "சேமிக்கப்படாமலேயே %1$s மூடப்படும்" "நினைவக வரம்பை %1$s மீறியது" + + "ஹீப் டம்ப் சேகரிக்கப்பட்டது. பகிர, தட்டவும்." "ஹீப் டம்பைப் பகிரவா?" - "%2$s அளவான தனது செயலாக்க நினைவக வரம்பை %1$s செயலாக்கம் மீறியது. உங்களுக்கான ஹீப் டம்பினை அதன் டெவெலப்பருடன் பகிரலாம். கவனம்: பயன்பாடு அணுகும் விதத்தில், உங்களைப் பற்றிய எந்தத் தனிப்பட்ட தகவலும் இந்த ஹீப் டம்பில் இருக்கலாம் என்பதை நினைவில்கொள்ளவும்." + + + + + + "உரைக்கான செயலைத் தேர்வுசெய்யவும்" "ரிங்கரின் ஒலியளவு" "மீடியாவின் ஒலியளவு" @@ -1257,8 +1294,10 @@ "எல்லா நெட்வொர்க்குகளையும் பார்க்க, தட்டவும்" "இணை" "எல்லா நெட்வொர்க்குகளும்" - "%s பரிந்துரைத்த வைஃபை நெட்வொர்க் கிடைக்கிறது" - "%s பரிந்துரைத்த நெட்வொர்க்குகளுடன் இணைக்க வேண்டுமா?" + + + + "சரி" "வேண்டாம்" "வைஃபை தானாக ஆன் ஆகும்" @@ -1270,9 +1309,14 @@ "நெட்வொர்க்கில் உள்நுழையவும்" - "வைஃபையில் இண்டர்நெட் அணுகல் இல்லை" + + "விருப்பங்களுக்கு, தட்டவும்" "இணைக்கப்பட்டது" + + + + "உங்கள் ஹாட்ஸ்பாட் அமைப்புகளில் செய்யப்பட்டுள்ள மாற்றங்கள்" "உங்கள் ஹாட்ஸ்பாட்டின் அலைவரிசை மாறிவிட்டது." "இந்தச் சாதனத்தில், ’5GHz மட்டும்’ எனும் முன்னுரிமைத் தேர்வு ஆதரிக்கப்படவில்லை. எனினும் 5GHz அலைவரிசை கிடைக்கும்போது, சாதனம் அதைப் பயன்படுத்திக்கொள்ளும்." @@ -1358,6 +1402,10 @@ "USB பிழைதிருத்தம் இணைக்கப்பட்டது" "USB பிழைதிருத்தத்தை ஆஃப் செய்ய, தட்டவும்" "USB பிழைதிருத்தத்தை முடக்க, தேர்ந்தெடுக்கவும்." + + + + "USB போர்ட்டில் சேதம் உள்ளது" "USB போர்ட் தானாகவே முடக்கப்பட்டது மேலும் அறிய, தட்டவும்." "USB போர்ட்டைப் பாதுகாப்பாகப் பயன்படுத்தலாம்" @@ -1909,8 +1957,6 @@ "பணிக் கணக்கை திறக்க, தட்டுக" "%1$s உடன் இணைக்கப்பட்டது" "கோப்புகளைப் பார்க்க, தட்டவும்" - "பின் செய்" - "பின்னை அகற்று" "பயன்பாட்டுத் தகவல்" "−%1$s" "டெமோவைத் தொடங்குகிறது…" @@ -2001,6 +2047,22 @@ "வழக்கமான பேட்டரி சேமிப்பானுக்கான விவர அறிவிப்பு" "வழக்கமாகச் சார்ஜ் செய்வதற்கு முன்பே பேட்டரி தீர்ந்துபோகக்கூடும்" "பேட்டரி நிலையை நீட்டிக்க பேட்டரி சேமிப்பான் இயக்கப்பட்டுள்ளது" + + + + + + + + + + + + + + + + "கோப்புறை" "Android ஆப்ஸ்" "ஃபைல்" diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml index 5f237a7a5a564074b23b04ad89ecd8c979648fd8..f3ae7631acb7fc85033dea87c7a20590d75f7f07 100644 --- a/core/res/res/values-vi/strings.xml +++ b/core/res/res/values-vi/strings.xml @@ -141,8 +141,10 @@ "Gọi qua Wi-Fi" "VoWifi" "Tắt" - "Ưu tiên Wi-Fi" - "Ưu tiên dữ liệu di động" + + + + "Chỉ Wi-Fi" "{0}: Không được chuyển tiếp" "{0}: {1}" @@ -228,7 +230,8 @@ "Báo cáo lỗi" "Kết thúc phiên" "Chụp ảnh màn hình" - "Tạo báo cáo lỗi" + + "Báo cáo này sẽ thu thập thông tin về tình trạng thiết bị hiện tại của bạn, để gửi dưới dạng thông báo qua email. Sẽ mất một chút thời gian kể từ khi bắt đầu báo cáo lỗi cho tới khi báo cáo sẵn sàng để gửi; xin vui lòng kiên nhẫn." "Báo cáo tương tác" "Sử dụng tùy chọn này trong hầu hết các trường hợp. Tùy chọn này cho phép bạn theo dõi tiến trình của báo cáo, nhập thêm thông tin chi tiết về sự cố cũng như chụp ảnh màn hình. Tùy chọn này có thể bỏ qua một số phần ít được sử dụng mà mất nhiều thời gian để báo cáo." @@ -281,9 +284,12 @@ "Vị trí" "truy cập vị trí của thiết bị này" "Cho phép <b>%1$s</b> truy cập vào vị trí của thiết bị này?" - "Ứng dụng sẽ chỉ có quyền truy cập vào vị trí khi bạn sử dụng." - "Luôn cho phép <b>%1$s</b> truy cập vị trí thiết bị?" - "Ứng dụng sẽ luôn có quyền truy cập vào vị trí, ngay cả khi bạn không sử dụng." + + + + + + "Lịch" "truy cập lịch của bạn" "Cho phép <b>%1$s</b> truy cập vào lịch của bạn?" @@ -316,7 +322,10 @@ "Bạn có muốn cho phép <b>%1$s</b> sử dụng nhạc không?" "Ảnh và video" "sử dụng ảnh và video" - "Cho phép <b>%1$s</b> truy cập vào ảnh và video của bạn, bao gồm cả vị trí được gắn thẻ?" + + + + "Truy xuất nội dung cửa sổ" "Kiểm tra nội dung của cửa sổ bạn đang tương tác." "Bật Khám phá bằng cách chạm" @@ -509,8 +518,10 @@ "Cho phép ứng dụng giao tiếp với thẻ Giao tiếp trường gần (NFC), thẻ và trình đọc." "vô hiệu hóa khóa màn hình của bạn" "Cho phép ứng dụng tắt khóa phím và bất kỳ bảo mật mật khẩu được liên kết nào. Ví dụ: điện thoại tắt khóa phím khi nhận được cuộc gọi đến, sau đó bật lại khóa phím khi cuộc gọi kết thúc." - "yêu cầu mức độ phức tạp của khóa màn hình" - "Cho phép ứng dụng nắm được độ phức tạp của khóa màn hình (cao, trung bình, thấp hoặc không có). Mức độ này cho biết khoảng độ dài và loại khóa màn hình có thể có. Ứng dụng cũng có thể gợi ý người dùng nên cập nhật khóa màn hình lên một mức độ nhất định, nhưng người dùng có thể tùy ý bỏ qua và chuyển sang phần khác. Xin lưu ý rằng khóa màn hình không được lưu trữ dưới dạng văn bản thuần túy, vì vậy ứng dụng sẽ không biết mật khẩu chính xác." + + + + "sử dụng phần cứng sinh trắc học" "Cho phép ứng dụng dùng phần cứng sinh trắc học để xác thực" "quản lý phần cứng vân tay" @@ -565,37 +576,59 @@ "Cho phép ứng dụng gọi ra các phương pháp để thêm và xóa mẫu khuôn mặt sử dụng." "sử dụng phần cứng xác thực khuôn mặt" "Cho phép ứng dụng sử dụng phần cứng xác thực khuôn mặt để tiến hành xác thực" - "Không thể xử lý khuôn mặt. Vui lòng thử lại." - "Khuôn mặt quá sáng. Hãy thử dưới ánh sáng yếu hơn." - "Khuôn mặt quá tối. Hãy tìm nguồn sáng tốt hơn." - "Hãy đưa cảm biến ra xa khuôn mặt hơn." - "Hãy đưa cảm biến lại gần khuôn mặt hơn." - "Hãy đưa cảm biến lên cao hơn." - "Hãy đưa cảm biến xuống thấp hơn." - "Hãy đưa cảm biến sang bên phải." - "Hay đưa cảm biến sang bên trái." - "Hãy nhìn vào cảm biến." - "Không phát hiện được khuôn mặt nào." - "Thiết bị chuyển động quá nhiều." + + + + + + + + + + + + + + + + + + + + + + + + "Vui lòng đăng ký lại khuôn mặt của bạn." - "Đã phát hiện thấy khuôn mặt khác." + + "Khuôn mặt quá giống nhau, vui lòng đổi tư thế." - "Vui lòng nhìn thẳng vào máy ảnh." - "Vui lòng nhìn thẳng vào máy ảnh." + + + + "Vui lòng giữ thẳng đầu." - "Vui lòng không che mặt của bạn." + + + + "Không truy cập được phần cứng nhận dạng khuôn mặt." - "Đã hết thời gian chờ khuôn mặt. Hãy thử lại." + + "Không thể lưu khuôn mặt." "Đã hủy thao tác dùng khuôn mặt." "Người dùng đã hủy thao tác xác thực khuôn mặt." "Bạn đã thử quá nhiều lần. Hãy thử lại sau." "Đã thử quá nhiều lần. Đã tắt xác thực khuôn mặt." - "Hãy thử lại." - "Bạn chưa đăng ký khuôn mặt." - "Thiết bị này không có cảm biến xác thực khuôn mặt." + + + + + + "Khuôn mặt %d" @@ -1213,9 +1246,16 @@ "Mở %1$s" "%1$s sẽ đóng mà không lưu" "%1$s đã vượt quá giới hạn bộ nhớ" + + "Đã thu thập tệp báo lỗi. Hãy nhấn để chia sẻ." "Chia sẻ tệp báo lỗi?" - "Quá trình %1$s đã vượt quá giới hạn bộ nhớ xử lý %2$s. Tệp báo lỗi khả dụng để bạn chia sẻ với nhà phát triển. Hãy cẩn thận: tệp báo lỗi này có thể chứa bất kỳ thông tin cá nhân nào mà ứng dụng có quyền truy cập." + + + + + + "Chọn một tác vụ cho văn bản" "Âm lượng chuông" "Âm lượng phương tiện" @@ -1254,8 +1294,10 @@ "Nhấn để xem tất cả các mạng" "Kết nối" "Tất cả các mạng" - "Hiện có thể kết nối với mạng Wi‑Fi do %s đề xuất" - "Bạn có muốn kết nối với các mạng do %s đề xuất không?" + + + + "Có" "Không" "Wi-Fi sẽ tự động bật" @@ -1267,9 +1309,14 @@ "Đăng nhập vào mạng" - "Wi-Fi không có quyền truy cập Internet" + + "Nhấn để biết tùy chọn" "Đã kết nối" + + + + "Những thay đổi trong mục cài đặt điểm phát sóng của bạn" "Bằng tần của điểm phát sóng đã thay đổi." "Thiết bị này không hỗ trợ tùy chọn chỉ sử dụng băng tần 5 GHz. Thay vào đó, thiết bị này sẽ sử dụng băng tần 5 GHz khi có thể." @@ -1354,6 +1401,10 @@ "Đã kết nối gỡ lỗi USB" "Nhấn để tắt tính năng gỡ lỗi USB" "Chọn để vô hiệu hóa gỡ lỗi USB." + + + + "Có chất lỏng hoặc mảnh vỡ trong cổng USB" "Cổng USB đã tự động tắt. Nhấn để tìm hiểu thêm." "Có thể sử dụng cổng USB một cách an toàn" @@ -1396,8 +1447,7 @@ "Thiết lập" "Tháo" "Khám phá" - - + "Chuyển đổi đầu ra" "%s bị thiếu" "Hãy lắp lại thiết bị" "Di chuyển %s" @@ -1906,8 +1956,6 @@ "Nhấn để mở khóa hồ sơ công việc" "Đã kết nối với %1$s" "Nhấn để xem tệp" - "Ghim" - "Bỏ ghim" "Thông tin ứng dụng" "−%1$s" "Đang bắt đầu bản trình diễn..." @@ -1998,6 +2046,22 @@ "Thông báo cung cấp thông tin về chế độ sạc thông thường" "Pin có thể hết trước khi sạc bình thường" "Trình tiết kiệm pin được kích hoạt để kéo dài thời lượng pin" + + + + + + + + + + + + + + + + "Thư mục" "Ứng dụng Android" "Tệp" diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 71e071c14557a8eef838efe2fed22e2e08675529..dc0ec03ca7a236c4bde0e1c9bcd542d952395723 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -58,6 +58,7 @@ @string/status_bar_mobile @string/status_bar_airplane @string/status_bar_battery + @string/status_bar_sensors_off rotate @@ -92,6 +93,7 @@ microphone camera airplane + sensors_off 1 + + http://connectivitycheck.gstatic.com/generate_204 + 0 @@ -914,6 +925,11 @@ case, this can be disabled (set to false). --> true + + false + 0 + + 0 + 16x16 @@ -3738,9 +3760,6 @@ com.android.managedprovisioning - - false - false diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml index 7134eed8dde897a0c997218a7b3cbffafcf75e2c..023fbaddfb8317fd4a3e450805932c4190213d71 100644 --- a/core/res/res/values/dimens.xml +++ b/core/res/res/values/dimens.xml @@ -578,7 +578,6 @@ 0dp 1.25 - 0dp 8dp @@ -725,4 +724,5 @@ -1px 42dp 18dp + 76dp diff --git a/core/res/res/values/dimens_car.xml b/core/res/res/values/dimens_car.xml index d2cf40a6bc1f1ddd8c0edc6b92d52b2e08604246..7b3ac2e0e4b59bac01bf459764154aebfb21c12e 100644 --- a/core/res/res/values/dimens_car.xml +++ b/core/res/res/values/dimens_car.xml @@ -21,6 +21,7 @@ 356dp 96dp 96dp + 96dp diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 74970e810181a5979ad0d3377192567a31461575..bb473705b41625ad46868402059a271033e5a6f2 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -802,7 +802,7 @@ Allow <b>%1$s</b> to access your photos and videos? - Locations and other people in your photos and videos can be identified by the app + This includes any locations tagged in your photos and videos Retrieve window content @@ -1584,7 +1584,7 @@ Face hardware not available. - Face time out reached. Try again. + Face timeout reached. Try again. Face can\u2019t be stored. @@ -1596,11 +1596,11 @@ Too many attempts. Facial authentication disabled. - Try again. + Can\u2019t verify face. Try again. - No face enrolled. + You haven\u2019t set up face authentication. - This device does not have a face authentication sensor. + Face authentication is not supported on this device. Face %d @@ -3283,18 +3283,36 @@ %1$s exceeded memory limit + + + %1$s heap dump ready + Heap dump collected. Tap to share. Share heap dump? - - The process %1$s has exceeded - its process memory limit of %2$s. A heap dump is available + + The + %1$s process has exceeded + its memory limit of %2$s. A heap dump is available for you to share with its developer. Be careful: this heap dump can contain any of your personal information that the application has access to. + + The + %1$s process has exceeded + its memory limit of %2$s. A heap dump is available + for you to share. Be careful: this heap dump can contain any sensitive personal information + that the process has access to. + + + A heap dump of + %1$s\u2019s process is available + for you to share. Be careful: this heap dump may contain any sensitive personal information + that the process has access to. + Deleted by your admin + + Confirm + - To extend your battery life, Battery Saver turns off some device features and restricts apps. Learn More + Battery Saver turns off or restricts background activity, some visual effects \u0026 other high-power features to extend battery life. Learn More - To extend your battery life, Battery Saver turns off some device features and restricts apps. + Battery Saver turns off or restricts background activity, some visual effects \u0026 other high-power features to extend battery life. To help reduce data usage, Data Saver prevents some apps from sending or receiving data in the background. An app you’re currently using can access data, but may do so less frequently. This may mean, for example, that images don’t display until you tap them. @@ -5295,6 +5316,29 @@ Battery Saver activated to extend battery life + + + Battery Saver + + Battery Saver won\u2019t reactivate until battery low again + + Battery has been charged to a sufficient level. Battery Saver won\u2019t reactivate until the battery is low again. + + Phone %1$s charged + + Tablet %1$s charged + + Device %1$s charged + + Battery Saver is off. Features no longer restricted. + + Battery Saver turned off. Features no longer restricted. + Folder diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 17ccc31179f9734655e78676cfae1f282ee97d74..ae54a6aa41107ba19c05f79304cebc6f1ce3c4e8 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -1713,6 +1713,7 @@ + @@ -2004,6 +2005,7 @@ + @@ -2114,8 +2116,11 @@ + + + @@ -2761,6 +2766,7 @@ + @@ -2778,7 +2784,6 @@ - @@ -2831,6 +2836,7 @@ + @@ -2924,6 +2930,7 @@ + @@ -3508,7 +3515,6 @@ - @@ -3588,6 +3594,7 @@ + @@ -3643,6 +3650,12 @@ + + + + + + diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java index 7322a5445e86174e2cea942ca11999b1474af654..8fc6a96945865d70bccecab5ddd7459d891c9bca 100644 --- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java +++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java @@ -129,7 +129,7 @@ public class SettingsBackupTest { Settings.Global.AUTOFILL_LOGGING_LEVEL, Settings.Global.AUTOFILL_MAX_PARTITIONS_SIZE, Settings.Global.AUTOFILL_MAX_VISIBLE_DATASETS, - Settings.Global.AUTOMATIC_POWER_SAVER_MODE, + Settings.Global.AUTOMATIC_POWER_SAVE_MODE, Settings.Global.BACKGROUND_ACTIVITY_STARTS_ENABLED, Settings.Global.BACKGROUND_ACTIVITY_STARTS_PACKAGE_NAMES_WHITELIST, Settings.Global.BATTERY_CHARGING_STATE_UPDATE_DELAY, @@ -623,7 +623,6 @@ public class SettingsBackupTest { Settings.Secure.DEFAULT_INPUT_METHOD, Settings.Secure.DEVICE_PAIRED, Settings.Secure.DIALER_DEFAULT_APPLICATION, - Settings.Secure.DISABLE_AIRPLANE_MODE_AFTER_SP_DISABLED, Settings.Secure.DISABLED_PRINT_SERVICES, Settings.Secure.DISABLED_SYSTEM_INPUT_METHODS, Settings.Secure.DISPLAY_DENSITY_FORCED, @@ -647,8 +646,6 @@ public class SettingsBackupTest { Settings.Secure.LOCK_SCREEN_ALLOW_REMOTE_INPUT, // Candidate? Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT, Settings.Secure.LOCK_TO_APP_EXIT_LOCKED, - Settings.Secure.MAINTAIN_AIRPLANE_MODE_AFTER_SP_DISABLED, - Settings.Secure.MAINTAIN_LOCATION_AFTER_SP_DISABLED, Settings.Secure.MANAGED_PROFILE_CONTACT_REMOTE_SEARCH, Settings.Secure.MULTI_PRESS_TIMEOUT, Settings.Secure.NFC_PAYMENT_FOREGROUND, @@ -656,12 +653,12 @@ public class SettingsBackupTest { Settings.Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME, Settings.Secure.NUM_ROTATION_SUGGESTIONS_ACCEPTED, Settings.Secure.ODI_CAPTIONS_ENABLED, + Settings.Secure.ODI_CAPTIONS_OPTED_OUT, Settings.Secure.PACKAGE_VERIFIER_STATE, Settings.Secure.PACKAGE_VERIFIER_USER_CONSENT, Settings.Secure.PARENTAL_CONTROL_LAST_UPDATE, Settings.Secure.PAYMENT_SERVICE_SEARCH_URI, Settings.Secure.PRINT_SERVICE_SEARCH_URI, - Settings.Secure.REENABLE_LOCATION_AFTER_SP_DISABLED, Settings.Secure.SCREENSAVER_DEFAULT_COMPONENT, // Candidate? Settings.Secure.SEARCH_GLOBAL_SEARCH_ACTIVITY, Settings.Secure.SEARCH_MAX_RESULTS_PER_SOURCE, @@ -685,7 +682,6 @@ public class SettingsBackupTest { Settings.Secure.SELECTED_INPUT_METHOD_SUBTYPE, Settings.Secure.SELECTED_SPELL_CHECKER, // Intentionally removed in Q Settings.Secure.SELECTED_SPELL_CHECKER_SUBTYPE, // Intentionally removed in Q - Settings.Secure.SENSOR_PRIVACY_SENSOR_STATE, Settings.Secure.SETTINGS_CLASSNAME, Settings.Secure.SHOW_NOTE_ABOUT_NOTIFICATION_HIDING, // candidate? Settings.Secure.SHOW_ROTATION_SUGGESTIONS, diff --git a/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java b/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java index 66146c936dcaade2af3e8181dc6660fc9fecd934..4266ba9fe86e2b1266a5aa2574f90762f7056ac4 100644 --- a/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java +++ b/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java @@ -24,10 +24,16 @@ import static org.mockito.Mockito.reset; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyZeroInteractions; +import android.app.Instrumentation; +import android.content.Context; import android.graphics.Point; import android.platform.test.annotations.Presubmit; import android.view.SurfaceControl.Transaction; +import android.view.WindowManager.BadTokenException; +import android.view.WindowManager.LayoutParams; +import android.widget.TextView; +import androidx.test.InstrumentationRegistry; import androidx.test.filters.FlakyTest; import androidx.test.runner.AndroidJUnit4; @@ -47,7 +53,6 @@ public class InsetsSourceConsumerTest { private SurfaceSession mSession = new SurfaceSession(); private SurfaceControl mLeash; @Mock Transaction mMockTransaction; - @Mock InsetsController mMockController; @Before public void setup() { @@ -55,8 +60,21 @@ public class InsetsSourceConsumerTest { mLeash = new SurfaceControl.Builder(mSession) .setName("testSurface") .build(); - mConsumer = new InsetsSourceConsumer(TYPE_TOP_BAR, new InsetsState(), - () -> mMockTransaction, mMockController); + final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); + instrumentation.runOnMainSync(() -> { + final Context context = instrumentation.getTargetContext(); + // cannot mock ViewRootImpl since it's final. + final ViewRootImpl viewRootImpl = new ViewRootImpl(context, context.getDisplay()); + try { + viewRootImpl.setView(new TextView(context), new LayoutParams(), null); + } catch (BadTokenException e) { + // activity isn't running, lets ignore BadTokenException. + } + mConsumer = new InsetsSourceConsumer(TYPE_TOP_BAR, new InsetsState(), + () -> mMockTransaction, new InsetsController(viewRootImpl)); + }); + instrumentation.waitForIdleSync(); + mConsumer.setControl(new InsetsSourceControl(TYPE_TOP_BAR, mLeash, new Point())); } diff --git a/core/tests/coretests/src/android/view/textclassifier/ActionsSuggestionsHelperTest.java b/core/tests/coretests/src/android/view/textclassifier/ActionsSuggestionsHelperTest.java index 5c7287f000b739d851fc686a6b856bcc1a2e2348..67423c8402a30520ff3fcacd96ec06de72c9b5a1 100644 --- a/core/tests/coretests/src/android/view/textclassifier/ActionsSuggestionsHelperTest.java +++ b/core/tests/coretests/src/android/view/textclassifier/ActionsSuggestionsHelperTest.java @@ -215,6 +215,7 @@ public class ActionsSuggestionsHelperTest { ConversationAction.TYPE_OPEN_URL, 1.0f, null, + null, null ); @@ -235,6 +236,7 @@ public class ActionsSuggestionsHelperTest { ConversationAction.TYPE_OPEN_URL, 1.0f, null, + null, new RemoteActionTemplate[0] ); @@ -255,6 +257,7 @@ public class ActionsSuggestionsHelperTest { ConversationAction.TYPE_OPEN_URL, 1.0f, null, + null, new RemoteActionTemplate[]{ new RemoteActionTemplate( "title", diff --git a/core/tests/coretests/src/android/view/textclassifier/intent/LegacyIntentClassificationFactoryTest.java b/core/tests/coretests/src/android/view/textclassifier/intent/LegacyIntentClassificationFactoryTest.java index 19e5b0a250bbd6de65c99bfec8c4d91ce6e0594d..e1ccd7523ebaa642dd980bd9ca1d4bc3fad70a9b 100644 --- a/core/tests/coretests/src/android/view/textclassifier/intent/LegacyIntentClassificationFactoryTest.java +++ b/core/tests/coretests/src/android/view/textclassifier/intent/LegacyIntentClassificationFactoryTest.java @@ -63,7 +63,10 @@ public class LegacyIntentClassificationFactoryTest { null, null, null, - null); + null, + null, + 0, + 0); List intents = mLegacyIntentClassificationFactory.create( InstrumentationRegistry.getContext(), @@ -96,7 +99,10 @@ public class LegacyIntentClassificationFactoryTest { null, null, null, - null); + null, + null, + 0, + 0); List intents = mLegacyIntentClassificationFactory.create( InstrumentationRegistry.getContext(), diff --git a/core/tests/coretests/src/android/view/textclassifier/intent/TemplateClassificationIntentFactoryTest.java b/core/tests/coretests/src/android/view/textclassifier/intent/TemplateClassificationIntentFactoryTest.java index eaef0a0c42b155857e4353784f0f601865495899..2e97e638ba5737d2300cf1b4d5f119bdb3b8edef 100644 --- a/core/tests/coretests/src/android/view/textclassifier/intent/TemplateClassificationIntentFactoryTest.java +++ b/core/tests/coretests/src/android/view/textclassifier/intent/TemplateClassificationIntentFactoryTest.java @@ -81,7 +81,10 @@ public class TemplateClassificationIntentFactoryTest { null, null, null, - createRemoteActionTemplates()); + null, + createRemoteActionTemplates(), + 0, + 0); List intents = mTemplateClassificationIntentFactory.create( @@ -119,7 +122,10 @@ public class TemplateClassificationIntentFactoryTest { null, null, null, - createRemoteActionTemplates()); + null, + createRemoteActionTemplates(), + 0, + 0); List intents = mTemplateClassificationIntentFactory.create( @@ -153,7 +159,10 @@ public class TemplateClassificationIntentFactoryTest { null, null, null, - null); + null, + null, + 0, + 0); mTemplateClassificationIntentFactory.create( InstrumentationRegistry.getContext(), @@ -185,7 +194,10 @@ public class TemplateClassificationIntentFactoryTest { null, null, null, - new RemoteActionTemplate[0]); + null, + new RemoteActionTemplate[0], + 0, + 0); mTemplateClassificationIntentFactory.create( InstrumentationRegistry.getContext(), diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java index 185fa0750ff11bbd0075f7bfec6d313bf746c1a4..8c2375eaaf4c208711c1356937f71a426d22b976 100644 --- a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java +++ b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java @@ -599,7 +599,7 @@ public class ChooserActivityTest { mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); waitForIdle(); - verify(mockLogger, Mockito.times(2)).write(logMakerCaptor.capture()); + verify(mockLogger, Mockito.times(3)).write(logMakerCaptor.capture()); // First invocation is from onCreate assertThat(logMakerCaptor.getAllValues().get(1).getCategory(), is(MetricsEvent.ACTION_SHARE_WITH_PREVIEW)); @@ -629,7 +629,7 @@ public class ChooserActivityTest { ArgumentCaptor logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class); mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); waitForIdle(); - verify(mockLogger, Mockito.times(2)).write(logMakerCaptor.capture()); + verify(mockLogger, Mockito.times(3)).write(logMakerCaptor.capture()); // First invocation is from onCreate assertThat(logMakerCaptor.getAllValues().get(1).getCategory(), is(MetricsEvent.ACTION_SHARE_WITH_PREVIEW)); diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsCounterTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsCounterTest.java index 37f818a70ec9dcdd9adbb9fbe49036f941593a94..ade3a991b5766c64451396304eef6623fd85fc16 100644 --- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsCounterTest.java +++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsCounterTest.java @@ -44,8 +44,6 @@ public class BatteryStatsCounterTest extends TestCase { counter.stepAtomic(); counter.stepAtomic(); assertEquals(0, counter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); - assertEquals(0, counter.getCountLocked(BatteryStats.STATS_CURRENT)); - assertEquals(0, counter.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED)); // timeBase on (i.e. unplugged) timeBase.setRunning(true, 2, 2); @@ -54,8 +52,6 @@ public class BatteryStatsCounterTest extends TestCase { counter.stepAtomic(); counter.stepAtomic(); assertEquals(4, counter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); - assertEquals(4, counter.getCountLocked(BatteryStats.STATS_CURRENT)); - assertEquals(4, counter.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED)); // timeBase off (i.e. plugged in) timeBase.setRunning(false, 3, 3); @@ -63,16 +59,12 @@ public class BatteryStatsCounterTest extends TestCase { counter.stepAtomic(); counter.stepAtomic(); assertEquals(4, counter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); - assertEquals(4, counter.getCountLocked(BatteryStats.STATS_CURRENT)); - assertEquals(4, counter.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED)); // timeBase on (i.e. unplugged) timeBase.setRunning(true, 4, 4); counter.stepAtomic(); counter.stepAtomic(); assertEquals(6, counter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); - assertEquals(6, counter.getCountLocked(BatteryStats.STATS_CURRENT)); - assertEquals(2, counter.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED)); } @@ -88,8 +80,6 @@ public class BatteryStatsCounterTest extends TestCase { timeBase.setRunning(true, 1, 1); origCounter.stepAtomic(); origCounter.stepAtomic(); origCounter.stepAtomic(); // three times assertEquals(3, origCounter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); - assertEquals(3, origCounter.getCountLocked(BatteryStats.STATS_CURRENT)); - assertEquals(3, origCounter.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED)); // Test summary parcelling (from origCounter) final Parcel summaryParcel = Parcel.obtain(); @@ -102,22 +92,16 @@ public class BatteryStatsCounterTest extends TestCase { // timeBase still on (i.e. unplugged) summaryCounter.stepAtomic(); // once assertEquals(4, summaryCounter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); - assertEquals(1, summaryCounter.getCountLocked(BatteryStats.STATS_CURRENT)); - assertEquals(1, summaryCounter.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED)); // timeBase off (i.e. plugged in) timeBase.setRunning(false, 3, 3); summaryCounter.stepAtomic(); summaryCounter.stepAtomic(); // twice assertEquals(4, summaryCounter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); - assertEquals(1, summaryCounter.getCountLocked(BatteryStats.STATS_CURRENT)); - assertEquals(1, summaryCounter.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED)); // timeBase on (i.e. unplugged) timeBase.setRunning(true, 4, 4); summaryCounter.stepAtomic(); summaryCounter.stepAtomic(); // twice assertEquals(6, summaryCounter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); - assertEquals(3, summaryCounter.getCountLocked(BatteryStats.STATS_CURRENT)); - assertEquals(2, summaryCounter.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED)); // Test full parcelling (from summaryCounter) @@ -130,21 +114,15 @@ public class BatteryStatsCounterTest extends TestCase { // timeBase still on (i.e. unplugged) fullParcelCounter.stepAtomic(); // once assertEquals(7, fullParcelCounter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); - assertEquals(4, fullParcelCounter.getCountLocked(BatteryStats.STATS_CURRENT)); - assertEquals(3, fullParcelCounter.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED)); // timeBase off (i.e. plugged in) timeBase.setRunning(false, 5, 5); fullParcelCounter.stepAtomic(); fullParcelCounter.stepAtomic(); // twice assertEquals(7, fullParcelCounter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); - assertEquals(4, fullParcelCounter.getCountLocked(BatteryStats.STATS_CURRENT)); - assertEquals(3, fullParcelCounter.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED)); // timeBase on (i.e. unplugged) timeBase.setRunning(true, 6, 6); fullParcelCounter.stepAtomic(); fullParcelCounter.stepAtomic(); // twice assertEquals(9, fullParcelCounter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); - assertEquals(6, fullParcelCounter.getCountLocked(BatteryStats.STATS_CURRENT)); - assertEquals(2, fullParcelCounter.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED)); } } diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsDurationTimerTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsDurationTimerTest.java index a42286f6882f933afa101a16cac6cf6ff957a9a3..78fa3fb734d67390de67861c44c180fe242b41f5 100644 --- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsDurationTimerTest.java +++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsDurationTimerTest.java @@ -100,8 +100,70 @@ public class BatteryStatsDurationTimerTest extends TestCase { assertEquals(30802, timer.getTotalDurationMsLocked(220302)); } + /** + * Tests that reset(boolean detachIfReset) clears the correct times if detachIfReset is false. + */ @SmallTest public void testReset() throws Exception { + final MockClocks clocks = new MockClocks(); + + final BatteryStatsImpl.TimeBase timeBase = new BatteryStatsImpl.TimeBase(); + timeBase.init(clocks.uptimeMillis(), clocks.elapsedRealtime()); + + final BatteryStatsImpl.DurationTimer timer = new BatteryStatsImpl.DurationTimer(clocks, + null, BatteryStats.WAKE_TYPE_PARTIAL, null, timeBase); + + timeBase.setRunning(true, /* uptimeUs */ 0, /* realtimeUs */ 100_000); + timer.startRunningLocked(700); + timer.stopRunningLocked(3_100); + assertFalse(timer.isRunningLocked()); + assertEquals(0, timer.getCurrentDurationMsLocked(6_300)); + assertEquals(2_400, timer.getMaxDurationMsLocked(6_301)); + assertEquals(2_400, timer.getTotalDurationMsLocked(6_302)); + + timer.reset(false); + assertEquals(0, timer.getCurrentDurationMsLocked(12_000)); + assertEquals(0, timer.getMaxDurationMsLocked(12_001)); + assertEquals(0, timer.getTotalDurationMsLocked(12_002)); + + assertEquals(true, timeBase.hasObserver(timer)); + + timer.startRunningLocked(24_100); + clocks.uptime = clocks.realtime = 24_200; + timer.reset(false); + assertEquals(34_300, timer.getCurrentDurationMsLocked(58_500)); + assertEquals(34_301, timer.getMaxDurationMsLocked(58_501)); + assertEquals(34_302, timer.getTotalDurationMsLocked(58_502)); + } + + /** + * Tests that reset(boolean detachIfReset) clears the correct times if detachIfReset is true. + */ + @SmallTest + public void testResetAndDetach() throws Exception { + final MockClocks clocks = new MockClocks(); + + final BatteryStatsImpl.TimeBase timeBase = new BatteryStatsImpl.TimeBase(); + timeBase.init(clocks.uptimeMillis(), clocks.elapsedRealtime()); + + final BatteryStatsImpl.DurationTimer timer = new BatteryStatsImpl.DurationTimer(clocks, + null, BatteryStats.WAKE_TYPE_PARTIAL, null, timeBase); + + timeBase.setRunning(true, /* uptimeUs */ 0, /* realtimeUs */ 100_000); + timer.startRunningLocked(700); + timer.stopRunningLocked(3_100); + assertFalse(timer.isRunningLocked()); + assertEquals(0, timer.getCurrentDurationMsLocked(6_300)); + assertEquals(2_400, timer.getMaxDurationMsLocked(6_301)); + assertEquals(2_400, timer.getTotalDurationMsLocked(6_302)); + + timer.reset(true); + clocks.uptime = clocks.realtime = 7_000; + assertEquals(0, timer.getCurrentDurationMsLocked(8_000)); + assertEquals(0, timer.getMaxDurationMsLocked(8_001)); + assertEquals(0, timer.getTotalDurationMsLocked(8_002)); + + assertEquals(false, timeBase.hasObserver(timer)); } @SmallTest diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsImplTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsImplTest.java index 0771829211188a0898c2937fd881a90c5c1a3756..4b37dd226e69d1f917000f0d28b5bff5dad5f146 100644 --- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsImplTest.java +++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsImplTest.java @@ -325,7 +325,7 @@ public class BatteryStatsImplTest { // Get the total acquisition time long totalTime = u.getWifiMulticastTime(currentTimeMs*1000, - BatteryStats.STATS_SINCE_UNPLUGGED); + BatteryStats.STATS_SINCE_CHARGED); assertEquals("Miscalculations of Multicast wakelock acquisition time", (releaseTimeMs - acquireTimeMs) * 1000, totalTime); } @@ -347,7 +347,7 @@ public class BatteryStatsImplTest { // Get the total acquisition time long totalTime = u.getWifiMulticastTime(currentTimeMs*1000, - BatteryStats.STATS_SINCE_UNPLUGGED); + BatteryStats.STATS_SINCE_CHARGED); assertEquals("Miscalculations of Multicast wakelock acquisition time", (currentTimeMs - acquireTimeMs) * 1000, totalTime); } @@ -377,7 +377,7 @@ public class BatteryStatsImplTest { // Get the total acquisition time long totalTime = u.getWifiMulticastTime(currentTimeMs*1000, - BatteryStats.STATS_SINCE_UNPLUGGED); + BatteryStats.STATS_SINCE_CHARGED); assertEquals("Miscalculations of Multicast wakelock acquisition time", (releaseTimeMs_2 - acquireTimeMs_1) * 1000, totalTime); } @@ -407,7 +407,7 @@ public class BatteryStatsImplTest { // Get the total acquisition time long totalTime = u.getWifiMulticastTime(currentTimeMs*1000, - BatteryStats.STATS_SINCE_UNPLUGGED); + BatteryStats.STATS_SINCE_CHARGED); assertEquals("Miscalculations of Multicast wakelock acquisition time", ((releaseTimeMs_1 - acquireTimeMs_1) + (releaseTimeMs_2 - acquireTimeMs_2)) * 1000, totalTime); diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java index 3e33273feddbca9ba6fef22e91d8817d1f5c6501..8f5dfc5589fe087aeccc46d05f5769bef9f21de8 100644 --- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java +++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java @@ -16,7 +16,6 @@ package com.android.internal.os; -import static android.os.BatteryStats.STATS_CURRENT; import static android.os.BatteryStats.STATS_SINCE_CHARGED; import static android.os.BatteryStats.WAKE_TYPE_PARTIAL; @@ -388,7 +387,7 @@ public class BatteryStatsNoteTest extends TestCase { bi.noteWakupAlarmLocked("com.foo.bar", UID, null, "tag"); Uid.Pkg pkg = bi.getPackageStatsLocked(UID, "com.foo.bar"); - assertEquals(1, pkg.getWakeupAlarmStats().get("tag").getCountLocked(STATS_CURRENT)); + assertEquals(1, pkg.getWakeupAlarmStats().get("tag").getCountLocked(STATS_SINCE_CHARGED)); assertEquals(1, pkg.getWakeupAlarmStats().size()); } diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsServTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsServTest.java index b9995c443f35aaebb878b8575c031cd80463c2f0..df549c5b51c8085550579418f0df3b23a0860820 100644 --- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsServTest.java +++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsServTest.java @@ -44,15 +44,6 @@ public class BatteryStatsServTest extends TestCase { mLaunchedSince = 6064; mLaunched = true; mLaunches = 8085; - mLoadedStartTime = 9096; - mLoadedStarts = 10017; - mLoadedLaunches = 11118; - mLastStartTime = 12219; - mLastStarts = 13310; - mLastLaunches = 14411; - mUnpluggedStartTime = 15512; - mUnpluggedStarts = 16613; - mUnpluggedLaunches = 17714; } long getStartTime() { @@ -94,42 +85,6 @@ public class BatteryStatsServTest extends TestCase { int getLaunches() { return mLaunches; } - - long getLoadedStartTime() { - return mLoadedStartTime; - } - - int getLoadedStarts() { - return mLoadedStarts; - } - - int getLoadedLaunches() { - return mLoadedLaunches; - } - - long getLastStartTime() { - return mLastStartTime; - } - - int getLastStarts() { - return mLastStarts; - } - - int getLastLaunches() { - return mLastLaunches; - } - - long getUnpluggedStartTime() { - return mUnpluggedStartTime; - } - - int getUnpluggedStarts() { - return mUnpluggedStarts; - } - - int getUnpluggedLaunches() { - return mUnpluggedLaunches; - } } /** @@ -146,29 +101,6 @@ public class BatteryStatsServTest extends TestCase { Assert.assertFalse(bsi.getOnBatteryTimeBase().hasObserver(serv)); } - /** - * Test OnTimeStarted - */ - @SmallTest - public void testOnTimeStarted() throws Exception { - MockBatteryStatsImpl bsi = new MockBatteryStatsImpl(); - TestServ serv = new TestServ(bsi); - - serv.populate(); - serv.setRunning(true); - serv.onTimeStarted(111111, 20000, 222222); - Assert.assertEquals(18989, serv.getUnpluggedStartTime()); - Assert.assertEquals(4042, serv.getUnpluggedStarts()); - Assert.assertEquals(8085, serv.getUnpluggedLaunches()); - - serv.populate(); - serv.setRunning(false); - serv.onTimeStarted(111111, 20000, 222222); - Assert.assertEquals(1010, serv.getUnpluggedStartTime()); - Assert.assertEquals(4042, serv.getUnpluggedStarts()); - Assert.assertEquals(8085, serv.getUnpluggedLaunches()); - } - /** * Test parceling and unparceling. */ @@ -185,7 +117,7 @@ public class BatteryStatsServTest extends TestCase { TestServ serv = new TestServ(bsi); serv.readFromParcelLocked(parcel); - + Assert.assertEquals(1010, serv.getStartTime()); Assert.assertEquals(2021, serv.getRunningSince()); Assert.assertTrue(serv.getRunning()); @@ -194,15 +126,8 @@ public class BatteryStatsServTest extends TestCase { Assert.assertEquals(6064, serv.getLaunchedSince()); Assert.assertTrue(serv.getLaunched()); Assert.assertEquals(8085, serv.getLaunches()); - Assert.assertEquals(9096, serv.getLoadedStartTime()); - Assert.assertEquals(10017, serv.getLoadedStarts()); - Assert.assertEquals(11118, serv.getLoadedLaunches()); - Assert.assertEquals(0, serv.getLastStartTime()); - Assert.assertEquals(0, serv.getLastStarts()); - Assert.assertEquals(0, serv.getLastLaunches()); - Assert.assertEquals(15512, serv.getUnpluggedStartTime()); - Assert.assertEquals(16613, serv.getUnpluggedStarts()); - Assert.assertEquals(17714, serv.getUnpluggedLaunches()); + + parcel.recycle(); } /** @@ -267,15 +192,6 @@ public class BatteryStatsServTest extends TestCase { Assert.assertEquals(6064, serv.getLaunchedSince()); Assert.assertTrue(serv.getLaunched()); Assert.assertEquals(8085, serv.getLaunches()); - Assert.assertEquals(9096, serv.getLoadedStartTime()); - Assert.assertEquals(10017, serv.getLoadedStarts()); - Assert.assertEquals(11118, serv.getLoadedLaunches()); - Assert.assertEquals(12219, serv.getLastStartTime()); - Assert.assertEquals(13310, serv.getLastStarts()); - Assert.assertEquals(14411, serv.getLastLaunches()); - Assert.assertEquals(15512, serv.getUnpluggedStartTime()); - Assert.assertEquals(16613, serv.getUnpluggedStarts()); - Assert.assertEquals(17714, serv.getUnpluggedLaunches()); } /** @@ -303,15 +219,6 @@ public class BatteryStatsServTest extends TestCase { Assert.assertEquals(777777L, serv.getLaunchedSince()); // <-- changed Assert.assertTrue(serv.getLaunched()); // <-- changed Assert.assertEquals(8086, serv.getLaunches()); // <-- changed - Assert.assertEquals(9096, serv.getLoadedStartTime()); - Assert.assertEquals(10017, serv.getLoadedStarts()); - Assert.assertEquals(11118, serv.getLoadedLaunches()); - Assert.assertEquals(12219, serv.getLastStartTime()); - Assert.assertEquals(13310, serv.getLastStarts()); - Assert.assertEquals(14411, serv.getLastLaunches()); - Assert.assertEquals(15512, serv.getUnpluggedStartTime()); - Assert.assertEquals(16613, serv.getUnpluggedStarts()); - Assert.assertEquals(17714, serv.getUnpluggedLaunches()); } /** @@ -341,15 +248,6 @@ public class BatteryStatsServTest extends TestCase { Assert.assertEquals(6064, serv.getLaunchedSince()); Assert.assertFalse(serv.getLaunched()); Assert.assertEquals(8085, serv.getLaunches()); - Assert.assertEquals(9096, serv.getLoadedStartTime()); - Assert.assertEquals(10017, serv.getLoadedStarts()); - Assert.assertEquals(11118, serv.getLoadedLaunches()); - Assert.assertEquals(12219, serv.getLastStartTime()); - Assert.assertEquals(13310, serv.getLastStarts()); - Assert.assertEquals(14411, serv.getLastLaunches()); - Assert.assertEquals(15512, serv.getUnpluggedStartTime()); - Assert.assertEquals(16613, serv.getUnpluggedStarts()); - Assert.assertEquals(17714, serv.getUnpluggedLaunches()); } /** @@ -375,19 +273,10 @@ public class BatteryStatsServTest extends TestCase { Assert.assertEquals(2021, serv.getRunningSince()); Assert.assertTrue(serv.getRunning()); Assert.assertEquals(4042, serv.getStarts()); - Assert.assertEquals(777777L-6064+5053, serv.getLaunchedTime()); // <-- changed + Assert.assertEquals(777777L-6064+5053, serv.getLaunchedTime()); // <-- changed Assert.assertEquals(6064, serv.getLaunchedSince()); Assert.assertFalse(serv.getLaunched()); Assert.assertEquals(8085, serv.getLaunches()); - Assert.assertEquals(9096, serv.getLoadedStartTime()); - Assert.assertEquals(10017, serv.getLoadedStarts()); - Assert.assertEquals(11118, serv.getLoadedLaunches()); - Assert.assertEquals(12219, serv.getLastStartTime()); - Assert.assertEquals(13310, serv.getLastStarts()); - Assert.assertEquals(14411, serv.getLastLaunches()); - Assert.assertEquals(15512, serv.getUnpluggedStartTime()); - Assert.assertEquals(16613, serv.getUnpluggedStarts()); - Assert.assertEquals(17714, serv.getUnpluggedLaunches()); } /** @@ -416,16 +305,7 @@ public class BatteryStatsServTest extends TestCase { Assert.assertEquals(5053, serv.getLaunchedTime()); Assert.assertEquals(6064, serv.getLaunchedSince()); Assert.assertFalse(serv.getLaunched()); - Assert.assertEquals(8085-1, serv.getLaunches()); // <-- changed - Assert.assertEquals(9096, serv.getLoadedStartTime()); - Assert.assertEquals(10017, serv.getLoadedStarts()); - Assert.assertEquals(11118, serv.getLoadedLaunches()); - Assert.assertEquals(12219, serv.getLastStartTime()); - Assert.assertEquals(13310, serv.getLastStarts()); - Assert.assertEquals(14411, serv.getLastLaunches()); - Assert.assertEquals(15512, serv.getUnpluggedStartTime()); - Assert.assertEquals(16613, serv.getUnpluggedStarts()); - Assert.assertEquals(17714, serv.getUnpluggedLaunches()); + Assert.assertEquals(8085-1, serv.getLaunches()); // <-- changed } /** @@ -455,15 +335,6 @@ public class BatteryStatsServTest extends TestCase { Assert.assertEquals(6064, serv.getLaunchedSince()); Assert.assertTrue(serv.getLaunched()); Assert.assertEquals(8085, serv.getLaunches()); - Assert.assertEquals(9096, serv.getLoadedStartTime()); - Assert.assertEquals(10017, serv.getLoadedStarts()); - Assert.assertEquals(11118, serv.getLoadedLaunches()); - Assert.assertEquals(12219, serv.getLastStartTime()); - Assert.assertEquals(13310, serv.getLastStarts()); - Assert.assertEquals(14411, serv.getLastLaunches()); - Assert.assertEquals(15512, serv.getUnpluggedStartTime()); - Assert.assertEquals(16613, serv.getUnpluggedStarts()); - Assert.assertEquals(17714, serv.getUnpluggedLaunches()); } /** @@ -492,15 +363,6 @@ public class BatteryStatsServTest extends TestCase { Assert.assertEquals(6064, serv.getLaunchedSince()); Assert.assertTrue(serv.getLaunched()); Assert.assertEquals(8085, serv.getLaunches()); - Assert.assertEquals(9096, serv.getLoadedStartTime()); - Assert.assertEquals(10017, serv.getLoadedStarts()); - Assert.assertEquals(11118, serv.getLoadedLaunches()); - Assert.assertEquals(12219, serv.getLastStartTime()); - Assert.assertEquals(13310, serv.getLastStarts()); - Assert.assertEquals(14411, serv.getLastLaunches()); - Assert.assertEquals(15512, serv.getUnpluggedStartTime()); - Assert.assertEquals(16613, serv.getUnpluggedStarts()); - Assert.assertEquals(17714, serv.getUnpluggedLaunches()); } /** @@ -530,15 +392,6 @@ public class BatteryStatsServTest extends TestCase { Assert.assertEquals(6064, serv.getLaunchedSince()); Assert.assertTrue(serv.getLaunched()); Assert.assertEquals(8085, serv.getLaunches()); - Assert.assertEquals(9096, serv.getLoadedStartTime()); - Assert.assertEquals(10017, serv.getLoadedStarts()); - Assert.assertEquals(11118, serv.getLoadedLaunches()); - Assert.assertEquals(12219, serv.getLastStartTime()); - Assert.assertEquals(13310, serv.getLastStarts()); - Assert.assertEquals(14411, serv.getLastLaunches()); - Assert.assertEquals(15512, serv.getUnpluggedStartTime()); - Assert.assertEquals(16613, serv.getUnpluggedStarts()); - Assert.assertEquals(17714, serv.getUnpluggedLaunches()); } /** @@ -568,15 +421,6 @@ public class BatteryStatsServTest extends TestCase { Assert.assertEquals(6064, serv.getLaunchedSince()); Assert.assertTrue(serv.getLaunched()); Assert.assertEquals(8085, serv.getLaunches()); - Assert.assertEquals(9096, serv.getLoadedStartTime()); - Assert.assertEquals(10017, serv.getLoadedStarts()); - Assert.assertEquals(11118, serv.getLoadedLaunches()); - Assert.assertEquals(12219, serv.getLastStartTime()); - Assert.assertEquals(13310, serv.getLastStarts()); - Assert.assertEquals(14411, serv.getLastLaunches()); - Assert.assertEquals(15512, serv.getUnpluggedStartTime()); - Assert.assertEquals(16613, serv.getUnpluggedStarts()); - Assert.assertEquals(17714, serv.getUnpluggedLaunches()); } /** @@ -600,8 +444,6 @@ public class BatteryStatsServTest extends TestCase { serv.populate(); Assert.assertEquals(8085, serv.getLaunches(BatteryStats.STATS_SINCE_CHARGED)); - Assert.assertEquals(8085-11118, serv.getLaunches(BatteryStats.STATS_CURRENT)); - Assert.assertEquals(8085-17714, serv.getLaunches(BatteryStats.STATS_SINCE_UNPLUGGED)); // No change to fields Assert.assertEquals(1010, serv.getStartTime()); @@ -612,15 +454,6 @@ public class BatteryStatsServTest extends TestCase { Assert.assertEquals(6064, serv.getLaunchedSince()); Assert.assertTrue(serv.getLaunched()); Assert.assertEquals(8085, serv.getLaunches()); - Assert.assertEquals(9096, serv.getLoadedStartTime()); - Assert.assertEquals(10017, serv.getLoadedStarts()); - Assert.assertEquals(11118, serv.getLoadedLaunches()); - Assert.assertEquals(12219, serv.getLastStartTime()); - Assert.assertEquals(13310, serv.getLastStarts()); - Assert.assertEquals(14411, serv.getLastLaunches()); - Assert.assertEquals(15512, serv.getUnpluggedStartTime()); - Assert.assertEquals(16613, serv.getUnpluggedStarts()); - Assert.assertEquals(17714, serv.getUnpluggedLaunches()); } /** @@ -637,10 +470,6 @@ public class BatteryStatsServTest extends TestCase { Assert.assertEquals(startTimeToNow, serv.getStartTime(20000, BatteryStats.STATS_SINCE_CHARGED)); - Assert.assertEquals(startTimeToNow-9096, - serv.getStartTime(20000, BatteryStats.STATS_CURRENT)); - Assert.assertEquals(startTimeToNow-15512, - serv.getStartTime(20000, BatteryStats.STATS_SINCE_UNPLUGGED)); // No change to fields Assert.assertEquals(1010, serv.getStartTime()); @@ -651,15 +480,6 @@ public class BatteryStatsServTest extends TestCase { Assert.assertEquals(6064, serv.getLaunchedSince()); Assert.assertTrue(serv.getLaunched()); Assert.assertEquals(8085, serv.getLaunches()); - Assert.assertEquals(9096, serv.getLoadedStartTime()); - Assert.assertEquals(10017, serv.getLoadedStarts()); - Assert.assertEquals(11118, serv.getLoadedLaunches()); - Assert.assertEquals(12219, serv.getLastStartTime()); - Assert.assertEquals(13310, serv.getLastStarts()); - Assert.assertEquals(14411, serv.getLastLaunches()); - Assert.assertEquals(15512, serv.getUnpluggedStartTime()); - Assert.assertEquals(16613, serv.getUnpluggedStarts()); - Assert.assertEquals(17714, serv.getUnpluggedLaunches()); } /** @@ -676,10 +496,6 @@ public class BatteryStatsServTest extends TestCase { Assert.assertEquals(startTimeToNow, serv.getStartTime(20000, BatteryStats.STATS_SINCE_CHARGED)); - Assert.assertEquals(startTimeToNow-9096, - serv.getStartTime(20000, BatteryStats.STATS_CURRENT)); - Assert.assertEquals(startTimeToNow-15512, - serv.getStartTime(20000, BatteryStats.STATS_SINCE_UNPLUGGED)); // No change to fields Assert.assertEquals(1010, serv.getStartTime()); @@ -690,15 +506,6 @@ public class BatteryStatsServTest extends TestCase { Assert.assertEquals(6064, serv.getLaunchedSince()); Assert.assertTrue(serv.getLaunched()); Assert.assertEquals(8085, serv.getLaunches()); - Assert.assertEquals(9096, serv.getLoadedStartTime()); - Assert.assertEquals(10017, serv.getLoadedStarts()); - Assert.assertEquals(11118, serv.getLoadedLaunches()); - Assert.assertEquals(12219, serv.getLastStartTime()); - Assert.assertEquals(13310, serv.getLastStarts()); - Assert.assertEquals(14411, serv.getLastLaunches()); - Assert.assertEquals(15512, serv.getUnpluggedStartTime()); - Assert.assertEquals(16613, serv.getUnpluggedStarts()); - Assert.assertEquals(17714, serv.getUnpluggedLaunches()); } @@ -712,8 +519,6 @@ public class BatteryStatsServTest extends TestCase { serv.populate(); Assert.assertEquals(4042, serv.getStarts(BatteryStats.STATS_SINCE_CHARGED)); - Assert.assertEquals(4042-10017, serv.getStarts(BatteryStats.STATS_CURRENT)); - Assert.assertEquals(4042-16613, serv.getStarts(BatteryStats.STATS_SINCE_UNPLUGGED)); // No change to fields Assert.assertEquals(1010, serv.getStartTime()); @@ -724,15 +529,6 @@ public class BatteryStatsServTest extends TestCase { Assert.assertEquals(6064, serv.getLaunchedSince()); Assert.assertTrue(serv.getLaunched()); Assert.assertEquals(8085, serv.getLaunches()); - Assert.assertEquals(9096, serv.getLoadedStartTime()); - Assert.assertEquals(10017, serv.getLoadedStarts()); - Assert.assertEquals(11118, serv.getLoadedLaunches()); - Assert.assertEquals(12219, serv.getLastStartTime()); - Assert.assertEquals(13310, serv.getLastStarts()); - Assert.assertEquals(14411, serv.getLastLaunches()); - Assert.assertEquals(15512, serv.getUnpluggedStartTime()); - Assert.assertEquals(16613, serv.getUnpluggedStarts()); - Assert.assertEquals(17714, serv.getUnpluggedLaunches()); } } diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsTimeBaseTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsTimeBaseTest.java index bce8b40cc31de81ca1d7d2af88f8b673424c5b03..e5441c0188758ed6ce1e35de898ca582fba4b248 100644 --- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsTimeBaseTest.java +++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsTimeBaseTest.java @@ -282,12 +282,6 @@ public class BatteryStatsTimeBaseTest extends TestCase { Assert.assertEquals(100+300+666-400, tb.computeUptime(666, BatteryStats.STATS_SINCE_CHARGED)); - Assert.assertEquals(300+666-400, - tb.computeUptime(666, BatteryStats.STATS_CURRENT)); - Assert.assertEquals(300+666-400-50, - tb.computeUptime(666, BatteryStats.STATS_SINCE_UNPLUGGED)); - - Assert.assertEquals(0, tb.computeUptime(666, 6000)); } /** @@ -301,12 +295,6 @@ public class BatteryStatsTimeBaseTest extends TestCase { Assert.assertEquals(200+500+6666-600, tb.computeRealtime(6666, BatteryStats.STATS_SINCE_CHARGED)); - Assert.assertEquals(500+6666-600, - tb.computeRealtime(6666, BatteryStats.STATS_CURRENT)); - Assert.assertEquals(500+6666-600-60, - tb.computeRealtime(6666, BatteryStats.STATS_SINCE_UNPLUGGED)); - - Assert.assertEquals(0, tb.computeUptime(666, 6000)); } /** diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsTimerTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsTimerTest.java index 87dc2f3dd43b404a6a0051263cf411876ab5477b..40e3a5f55ca545cb65d1a1dc4f7ffe0e6326aab1 100644 --- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsTimerTest.java +++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsTimerTest.java @@ -66,30 +66,6 @@ public class BatteryStatsTimerTest extends TestCase { mCount = val; } - public int getLoadedCount() { - return mLoadedCount; - } - - public void setLoadedCount(int val) { - mLoadedCount = val; - } - - public int getLastCount() { - return mLastCount; - } - - public void setLastCount(int val) { - mLastCount = val; - } - - public int getUnpluggedCount() { - return mUnpluggedCount; - } - - public void setUnpluggedCount(int val) { - mUnpluggedCount = val; - } - public long getTotalTime() { return mTotalTime; } @@ -98,30 +74,6 @@ public class BatteryStatsTimerTest extends TestCase { mTotalTime = val; } - public long getLoadedTime() { - return mLoadedTime; - } - - public void setLoadedTime(long val) { - mLoadedTime = val; - } - - public long getLastTime() { - return mLastTime; - } - - public void setLastTime(long val) { - mLastTime = val; - } - - public long getUnpluggedTime() { - return mUnpluggedTime; - } - - public void setUnpluggedTime(long val) { - mUnpluggedTime = val; - } - public long getTimeBeforeMark() { return mTimeBeforeMark; } @@ -143,16 +95,12 @@ public class BatteryStatsTimerTest extends TestCase { TestTimer timer = new TestTimer(clocks, 0, timeBase); timer.nextComputeCurrentCount = 3000; - // Test that starting the timer counts the unplugged time and counters + // Test that stopping the timer updates mTotalTime and mCount timer.nextComputeRunTime = 4; timer.onTimeStarted(10, 20, 50); - Assert.assertEquals(50, timer.lastComputeRunTimeRealtime); - Assert.assertEquals(4, timer.getUnpluggedTime()); - Assert.assertEquals(3000, timer.getUnpluggedCount()); - - // Test that stopping the timer updates mTotalTime and mCount timer.nextComputeRunTime = 17; timer.onTimeStopped(100, 130, 170); + Assert.assertEquals(170, timer.lastComputeRunTimeRealtime); Assert.assertEquals(17, timer.getTotalTime()); Assert.assertEquals(3000, timer.getCount()); } @@ -168,13 +116,7 @@ public class BatteryStatsTimerTest extends TestCase { // Test write then read TestTimer timer1 = new TestTimer(clocks, 0, timeBase); timer1.setCount(1); - timer1.setLoadedCount(3); - timer1.setLastCount(4); - timer1.setUnpluggedCount(5); timer1.setTotalTime(9223372036854775807L); - timer1.setLoadedTime(9223372036854775806L); - timer1.setLastTime(9223372036854775805L); - timer1.setUnpluggedTime(9223372036854775804L); timer1.setTimeBeforeMark(9223372036854775803L); timer1.nextComputeRunTime = 201; timer1.nextComputeCurrentCount = 2; @@ -187,13 +129,7 @@ public class BatteryStatsTimerTest extends TestCase { TestTimer timer2 = new TestTimer(clocks, 0, timeBase, parcel); Assert.assertEquals(2, timer2.getCount()); // from computeTotalCountLocked() - Assert.assertEquals(3, timer2.getLoadedCount()); - Assert.assertEquals(0, timer2.getLastCount()); // NOT saved - Assert.assertEquals(5, timer2.getUnpluggedCount()); Assert.assertEquals(201, timer2.getTotalTime()); // from computeRunTimeLocked() - Assert.assertEquals(9223372036854775806L, timer2.getLoadedTime()); - Assert.assertEquals(0, timer2.getLastTime()); // NOT saved - Assert.assertEquals(9223372036854775804L, timer2.getUnpluggedTime()); Assert.assertEquals(9223372036854775803L, timer2.getTimeBeforeMark()); parcel.recycle(); @@ -224,25 +160,13 @@ public class BatteryStatsTimerTest extends TestCase { TestTimer timer = new TestTimer(clocks, 0, timeBase); timer.setCount(1); - timer.setLoadedCount(2); - timer.setLastCount(3); - timer.setUnpluggedCount(4); timer.setTotalTime(9223372036854775807L); - timer.setLoadedTime(9223372036854775806L); - timer.setLastTime(9223372036854775805L); - timer.setUnpluggedTime(9223372036854775804L); timer.setTimeBeforeMark(9223372036854775803L); timer.reset(false); Assert.assertEquals(0, timer.getCount()); - Assert.assertEquals(0, timer.getLoadedCount()); - Assert.assertEquals(0, timer.getLastCount()); - Assert.assertEquals(4, timer.getUnpluggedCount()); Assert.assertEquals(0, timer.getTotalTime()); - Assert.assertEquals(0, timer.getLoadedTime()); - Assert.assertEquals(0, timer.getLastTime()); - Assert.assertEquals(9223372036854775804L, timer.getUnpluggedTime()); Assert.assertEquals(0, timer.getTimeBeforeMark()); // reset(false) shouldn't remove it from the list @@ -259,25 +183,13 @@ public class BatteryStatsTimerTest extends TestCase { TestTimer timer = new TestTimer(clocks, 0, timeBase); timer.setCount(1); - timer.setLoadedCount(2); - timer.setLastCount(3); - timer.setUnpluggedCount(4); timer.setTotalTime(9223372036854775807L); - timer.setLoadedTime(9223372036854775806L); - timer.setLastTime(9223372036854775805L); - timer.setUnpluggedTime(9223372036854775804L); timer.setTimeBeforeMark(9223372036854775803L); timer.reset(true); Assert.assertEquals(0, timer.getCount()); - Assert.assertEquals(0, timer.getLoadedCount()); - Assert.assertEquals(0, timer.getLastCount()); - Assert.assertEquals(4, timer.getUnpluggedCount()); Assert.assertEquals(0, timer.getTotalTime()); - Assert.assertEquals(0, timer.getLoadedTime()); - Assert.assertEquals(0, timer.getLastTime()); - Assert.assertEquals(9223372036854775804L, timer.getUnpluggedTime()); Assert.assertEquals(0, timer.getTimeBeforeMark()); // reset(true) should remove it from the list @@ -299,13 +211,7 @@ public class BatteryStatsTimerTest extends TestCase { TestTimer timer1 = new TestTimer(clocks, 0, timeBase); timer1.setCount(1); - timer1.setLoadedCount(2); - timer1.setLastCount(3); - timer1.setUnpluggedCount(4); timer1.setTotalTime(9223372036854775807L); - timer1.setLoadedTime(9223372036854775806L); - timer1.setLastTime(9223372036854775805L); - timer1.setUnpluggedTime(9223372036854775804L); timer1.setTimeBeforeMark(9223372036854775803L); Parcel parcel = Parcel.obtain(); @@ -318,13 +224,7 @@ public class BatteryStatsTimerTest extends TestCase { // Make sure that all the values get touched timer2.setCount(666); - timer2.setLoadedCount(666); - timer2.setLastCount(666); - timer2.setUnpluggedCount(666); timer2.setTotalTime(666); - timer2.setLoadedTime(666); - timer2.setLastTime(666); - timer2.setUnpluggedTime(666); timer2.setTimeBeforeMark(666); parcel.setDataPosition(0); @@ -333,13 +233,7 @@ public class BatteryStatsTimerTest extends TestCase { timer2.readSummaryFromParcelLocked(parcel); Assert.assertEquals(1, timer2.getCount()); - Assert.assertEquals(1, timer2.getLoadedCount()); - Assert.assertEquals(0, timer2.getLastCount()); - Assert.assertEquals(1, timer2.getUnpluggedCount()); Assert.assertEquals(9223372036854775800L, timer2.getTotalTime()); - Assert.assertEquals(9223372036854775800L, timer2.getLoadedTime()); - Assert.assertEquals(0, timer2.getLastTime()); - Assert.assertEquals(9223372036854775800L, timer2.getUnpluggedTime()); Assert.assertEquals(9223372036854775800L, timer2.getTimeBeforeMark()); parcel.recycle(); @@ -359,32 +253,15 @@ public class BatteryStatsTimerTest extends TestCase { TestTimer timer = new TestTimer(clocks, 0, timeBase); timer.setCount(1); - timer.setLoadedCount(2); - timer.setLastCount(3); - timer.setUnpluggedCount(4); timer.setTotalTime(100); - timer.setLoadedTime(200); - timer.setLastTime(300); - timer.setUnpluggedTime(400); timer.setTimeBeforeMark(500); timer.nextComputeRunTime = 10000; - // Timer.getTotalTimeLocked(STATS_SINCE_CHARGED) timer.lastComputeRunTimeRealtime = -1; Assert.assertEquals(10000, timer.getTotalTimeLocked(66, BatteryStats.STATS_SINCE_CHARGED)); Assert.assertEquals(40, timer.lastComputeRunTimeRealtime); - - // Timer.getTotalTimeLocked(STATS_CURRENT) - timer.lastComputeRunTimeRealtime = -1; - Assert.assertEquals(9800, timer.getTotalTimeLocked(66, BatteryStats.STATS_CURRENT)); - Assert.assertEquals(40, timer.lastComputeRunTimeRealtime); - - // Timer.getTotalTimeLocked(STATS_SINCE_UNPLUGGED) - timer.lastComputeRunTimeRealtime = -1; - Assert.assertEquals(9600, timer.getTotalTimeLocked(66, BatteryStats.STATS_SINCE_UNPLUGGED)); - Assert.assertEquals(40, timer.lastComputeRunTimeRealtime); } /** @@ -401,26 +278,11 @@ public class BatteryStatsTimerTest extends TestCase { TestTimer timer = new TestTimer(clocks, 0, timeBase); timer.setCount(1); - timer.setLoadedCount(2); - timer.setLastCount(3); - timer.setUnpluggedCount(4); timer.setTotalTime(100); - timer.setLoadedTime(200); - timer.setLastTime(300); - timer.setUnpluggedTime(400); timer.setTimeBeforeMark(500); - // Timer.getCountLocked(STATS_SINCE_CHARGED) timer.nextComputeCurrentCount = 10000; Assert.assertEquals(10000, timer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); - - // Timer.getCountLocked(STATS_CURRENT) - timer.nextComputeCurrentCount = 10000; - Assert.assertEquals(9998, timer.getCountLocked(BatteryStats.STATS_CURRENT)); - - // Timer.getCountLocked(STATS_SINCE_UNPLUGGED) - timer.nextComputeCurrentCount = 10000; - Assert.assertEquals(9996, timer.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED)); } /** @@ -437,13 +299,7 @@ public class BatteryStatsTimerTest extends TestCase { TestTimer timer = new TestTimer(clocks, 0, timeBase); timer.setCount(1); - timer.setLoadedCount(2); - timer.setLastCount(3); - timer.setUnpluggedCount(4); timer.setTotalTime(100); - timer.setLoadedTime(200); - timer.setLastTime(300); - timer.setUnpluggedTime(400); timer.setTimeBeforeMark(500); timer.nextComputeRunTime = 10000; @@ -460,30 +316,16 @@ public class BatteryStatsTimerTest extends TestCase { TestTimer timer = new TestTimer(clocks, 0, timeBase); timer.setTotalTime(100); - timer.setLoadedTime(200); - timer.setLastTime(300); - timer.setUnpluggedTime(400); timer.setTimeBeforeMark(500); timer.setCount(1); - timer.setLoadedCount(2); - timer.setLastCount(3); - timer.setUnpluggedCount(4); timer.setTotalTime(9223372036854775807L); - timer.setLoadedTime(9223372036854775806L); - timer.setLastTime(9223372036854775805L); - timer.setUnpluggedTime(9223372036854775804L); timer.setTimeBeforeMark(9223372036854775803L); StringBuilder sb = new StringBuilder(); StringBuilderPrinter pw = new StringBuilderPrinter(sb); timer.logState(pw, " "); - - Assert.assertEquals( - " mCount=1 mLoadedCount=2 mLastCount=3 mUnpluggedCount=4\n" - + " mTotalTime=9223372036854775807 mLoadedTime=9223372036854775806\n" - + " mLastTime=9223372036854775805 mUnpluggedTime=9223372036854775804\n", - sb.toString()); + Assert.assertEquals(" mCount=1\n mTotalTime=9223372036854775807\n", sb.toString()); } } diff --git a/core/tests/coretests/src/com/android/internal/os/LongSamplingCounterArrayTest.java b/core/tests/coretests/src/com/android/internal/os/LongSamplingCounterArrayTest.java index 0516bb7f74d7afcff1c72c9b48eca6aa7febe5e4..ee5d2d62f5fd525460515790326b18fe1fc50050 100644 --- a/core/tests/coretests/src/com/android/internal/os/LongSamplingCounterArrayTest.java +++ b/core/tests/coretests/src/com/android/internal/os/LongSamplingCounterArrayTest.java @@ -16,14 +16,12 @@ package com.android.internal.os; -import static android.os.BatteryStats.STATS_CURRENT; import static android.os.BatteryStats.STATS_SINCE_CHARGED; -import static android.os.BatteryStats.STATS_SINCE_UNPLUGGED; import static com.android.internal.os.BatteryStatsImpl.LongSamplingCounterArray; import static com.android.internal.os.BatteryStatsImpl.TimeBase; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertArrayEquals; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.verifyZeroInteractions; @@ -41,8 +39,6 @@ import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; -import java.util.Arrays; - /** * Test class for {@link BatteryStatsImpl.LongSamplingCounterArray}. * @@ -57,14 +53,15 @@ import java.util.Arrays; * ${ANDROID_PRODUCT_OUT}/data/app/FrameworksCoreTests/FrameworksCoreTests.apk * Run: adb shell am instrument -e class com.android.internal.os.LongSamplingCounterArrayTest -w \ * com.android.frameworks.coretests/androidx.test.runner.AndroidJUnitRunner + * + * or just do + * atest frameworks/base/core/tests/coretests/src/com/android/internal/os/LongSamplingCounterArrayTest.java */ @SmallTest @RunWith(AndroidJUnit4.class) public class LongSamplingCounterArrayTest { private static final long[] COUNTS = {1111, 2222, 3333, 4444}; - private static final long[] LOADED_COUNTS = {5555, 6666, 7777, 8888}; - private static final long[] UNPLUGGED_COUNTS = {44444, 55555, 66666, 77777}; private static final long[] ZEROES = {0, 0, 0, 0}; @Mock private TimeBase mTimeBase; @@ -80,75 +77,54 @@ public class LongSamplingCounterArrayTest { @Test public void testReadWriteParcel() { final Parcel parcel = Parcel.obtain(); - initializeCounterArrayWithDefaultValues(); + updateCounts(COUNTS); LongSamplingCounterArray.writeToParcel(parcel, mCounterArray); parcel.setDataPosition(0); // Now clear counterArray and verify values are read from parcel correctly. - updateCounts(null, null, null); + updateCounts(null); mCounterArray = LongSamplingCounterArray.readFromParcel(parcel, mTimeBase); - assertArrayEquals(COUNTS, mCounterArray.mCounts, "Unexpected counts"); - assertArrayEquals(LOADED_COUNTS, mCounterArray.mLoadedCounts, "Unexpected loadedCounts"); - assertArrayEquals(UNPLUGGED_COUNTS, mCounterArray.mUnpluggedCounts, - "Unexpected unpluggedCounts"); + assertArrayEquals(COUNTS, mCounterArray.mCounts); parcel.recycle(); } @Test public void testReadWriteSummaryParcel() { final Parcel parcel = Parcel.obtain(); - initializeCounterArrayWithDefaultValues(); + updateCounts(COUNTS); LongSamplingCounterArray.writeSummaryToParcelLocked(parcel, mCounterArray); parcel.setDataPosition(0); // Now clear counterArray and verify values are read from parcel correctly. - updateCounts(null, null, null); + updateCounts(null); mCounterArray = LongSamplingCounterArray.readSummaryFromParcelLocked(parcel, mTimeBase); - assertArrayEquals(COUNTS, mCounterArray.mCounts, "Unexpected counts"); - assertArrayEquals(COUNTS, mCounterArray.mLoadedCounts, "Unexpected loadedCounts"); - assertArrayEquals(COUNTS, mCounterArray.mUnpluggedCounts, "Unexpected unpluggedCounts"); + assertArrayEquals(COUNTS, mCounterArray.mCounts); parcel.recycle(); } @Test public void testOnTimeStarted() { - initializeCounterArrayWithDefaultValues(); + updateCounts(COUNTS); mCounterArray.onTimeStarted(0, 0, 0); - assertArrayEquals(COUNTS, mCounterArray.mCounts, "Unexpected counts"); - assertArrayEquals(LOADED_COUNTS, mCounterArray.mLoadedCounts, "Unexpected loadedCounts"); - assertArrayEquals(COUNTS, mCounterArray.mUnpluggedCounts, - "Unexpected unpluggedCounts"); + assertArrayEquals(COUNTS, mCounterArray.mCounts); } @Test public void testOnTimeStopped() { - initializeCounterArrayWithDefaultValues(); + updateCounts(COUNTS); mCounterArray.onTimeStopped(0, 0, 0); - assertArrayEquals(COUNTS, mCounterArray.mCounts, "Unexpected counts"); - assertArrayEquals(LOADED_COUNTS, mCounterArray.mLoadedCounts, "Unexpected loadedCounts"); - assertArrayEquals(UNPLUGGED_COUNTS, mCounterArray.mUnpluggedCounts, - "Unexpected unpluggedCounts"); + assertArrayEquals(COUNTS, mCounterArray.mCounts); } @Test public void testGetCountsLocked() { - initializeCounterArrayWithDefaultValues(); + updateCounts(COUNTS); when(mTimeBase.isRunning()).thenReturn(false); - assertArrayEquals(COUNTS, mCounterArray.getCountsLocked(STATS_SINCE_CHARGED), - "Unexpected values"); - assertArrayEquals(subtract(COUNTS, LOADED_COUNTS), - mCounterArray.getCountsLocked(STATS_CURRENT), "Unexpected values"); - assertArrayEquals(subtract(COUNTS, UNPLUGGED_COUNTS), - mCounterArray.getCountsLocked(STATS_SINCE_UNPLUGGED), "Unexpected values"); + assertArrayEquals(COUNTS, mCounterArray.getCountsLocked(STATS_SINCE_CHARGED)); when(mTimeBase.isRunning()).thenReturn(true); - assertArrayEquals(COUNTS, mCounterArray.getCountsLocked(STATS_SINCE_CHARGED), - "Unexpected values"); - assertArrayEquals(subtract(COUNTS, LOADED_COUNTS), - mCounterArray.getCountsLocked(STATS_CURRENT), "Unexpected values"); - assertArrayEquals(subtract(COUNTS, UNPLUGGED_COUNTS), - mCounterArray.getCountsLocked(STATS_SINCE_UNPLUGGED), "Unexpected values"); + assertArrayEquals(COUNTS, mCounterArray.getCountsLocked(STATS_SINCE_CHARGED)); } private long[] subtract(long[] val, long[] toSubtract) { @@ -163,64 +139,45 @@ public class LongSamplingCounterArrayTest { @Test public void testAddCountLocked() { - updateCounts(null, null, null); + updateCounts(null); final long[] deltas = {123, 234, 345, 456}; when(mTimeBase.isRunning()).thenReturn(true); mCounterArray.addCountLocked(deltas); - assertArrayEquals(deltas, mCounterArray.mCounts, "Unexpected counts"); - assertArrayEquals(null, mCounterArray.mLoadedCounts, "Unexpected loadedCounts"); - assertArrayEquals(null, mCounterArray.mUnpluggedCounts, "Unexpected unpluggedCounts"); + assertArrayEquals(deltas, mCounterArray.mCounts); - updateCounts(null, null, null); + updateCounts(null); mCounterArray.addCountLocked(deltas, false); - assertArrayEquals(null, mCounterArray.mCounts, "Unexpected counts"); - assertArrayEquals(null, mCounterArray.mLoadedCounts, "Unexpected loadedCounts"); - assertArrayEquals(null, mCounterArray.mUnpluggedCounts, "Unexpected unpluggedCounts"); + assertArrayEquals(null, mCounterArray.mCounts); mCounterArray.addCountLocked(deltas, true); - assertArrayEquals(deltas, mCounterArray.mCounts, "Unexpected counts"); - assertArrayEquals(null, mCounterArray.mLoadedCounts, "Unexpected loadedCounts"); - assertArrayEquals(null, mCounterArray.mUnpluggedCounts, "Unexpected unpluggedCounts"); + assertArrayEquals(deltas, mCounterArray.mCounts); - initializeCounterArrayWithDefaultValues(); + updateCounts(COUNTS); final long[] newCounts = new long[deltas.length]; for (int i = 0; i < deltas.length; ++i) { newCounts[i] = COUNTS[i] + deltas[i]; } mCounterArray.addCountLocked(deltas); - assertArrayEquals(newCounts, mCounterArray.mCounts, "Unexpected counts"); - assertArrayEquals(LOADED_COUNTS, mCounterArray.mLoadedCounts, "Unexpected loadedCounts"); - assertArrayEquals(UNPLUGGED_COUNTS, mCounterArray.mUnpluggedCounts, - "Unexpected unpluggedCounts"); + assertArrayEquals(newCounts, mCounterArray.mCounts); - initializeCounterArrayWithDefaultValues(); + updateCounts(COUNTS); mCounterArray.addCountLocked(deltas, false); - assertArrayEquals(COUNTS, mCounterArray.mCounts, "Unexpected counts"); - assertArrayEquals(LOADED_COUNTS, mCounterArray.mLoadedCounts, "Unexpected loadedCounts"); - assertArrayEquals(UNPLUGGED_COUNTS, mCounterArray.mUnpluggedCounts, - "Unexpected unpluggedCounts"); + assertArrayEquals(COUNTS, mCounterArray.mCounts); mCounterArray.addCountLocked(deltas, true); - assertArrayEquals(newCounts, mCounterArray.mCounts, "Unexpected counts"); - assertArrayEquals(LOADED_COUNTS, mCounterArray.mLoadedCounts, "Unexpected loadedCounts"); - assertArrayEquals(UNPLUGGED_COUNTS, mCounterArray.mUnpluggedCounts, - "Unexpected unpluggedCounts"); + assertArrayEquals(newCounts, mCounterArray.mCounts); } @Test public void testReset() { - initializeCounterArrayWithDefaultValues(); + updateCounts(COUNTS); // Test with detachIfReset=false mCounterArray.reset(false /* detachIfReset */); - assertArrayEquals(ZEROES, mCounterArray.mCounts, "Unexpected counts"); - assertArrayEquals(ZEROES, mCounterArray.mLoadedCounts, "Unexpected loadedCounts"); - assertArrayEquals(ZEROES, mCounterArray.mUnpluggedCounts, "Unexpected unpluggedCounts"); + assertArrayEquals(ZEROES, mCounterArray.mCounts); verifyZeroInteractions(mTimeBase); - initializeCounterArrayWithDefaultValues(); + updateCounts(COUNTS); // Test with detachIfReset=true mCounterArray.reset(true /* detachIfReset */); - assertArrayEquals(ZEROES, mCounterArray.mCounts, "Unexpected counts"); - assertArrayEquals(ZEROES, mCounterArray.mLoadedCounts, "Unexpected loadedCounts"); - assertArrayEquals(ZEROES, mCounterArray.mUnpluggedCounts, "Unexpected unpluggedCounts"); + assertArrayEquals(ZEROES, mCounterArray.mCounts); verify(mTimeBase).remove(mCounterArray); verifyNoMoreInteractions(mTimeBase); } @@ -232,18 +189,7 @@ public class LongSamplingCounterArrayTest { verifyNoMoreInteractions(mTimeBase); } - private void initializeCounterArrayWithDefaultValues() { - updateCounts(COUNTS, LOADED_COUNTS, UNPLUGGED_COUNTS); - } - - private void assertArrayEquals(long[] expected, long[] actual, String msg) { - assertTrue(msg + ", expected: " + Arrays.toString(expected) - + ", actual: " + Arrays.toString(actual), Arrays.equals(expected, actual)); - } - - private void updateCounts(long[] counts, long[] loadedCounts, long[] unpluggedCounts) { + private void updateCounts(long[] counts) { mCounterArray.mCounts = counts == null ? null : counts.clone(); - mCounterArray.mLoadedCounts = loadedCounts == null ? null : loadedCounts.clone(); - mCounterArray.mUnpluggedCounts = unpluggedCounts == null ? null : unpluggedCounts.clone(); } } diff --git a/core/tests/coretests/src/com/android/internal/os/LongSamplingCounterTest.java b/core/tests/coretests/src/com/android/internal/os/LongSamplingCounterTest.java index d2f5735ce3c134ed5903799a3bf6c800b0266a0d..dccc3d3d76fa42a1db0013497b2ff85b8eff5054 100644 --- a/core/tests/coretests/src/com/android/internal/os/LongSamplingCounterTest.java +++ b/core/tests/coretests/src/com/android/internal/os/LongSamplingCounterTest.java @@ -51,7 +51,6 @@ import org.mockito.MockitoAnnotations; public class LongSamplingCounterTest { private static final long COUNT = 1111; - private static final long CURRENT_COUNT = 5555; @Mock private TimeBase mTimeBase; @@ -67,116 +66,87 @@ public class LongSamplingCounterTest { @Test public void testReadWriteParcel() { final Parcel parcel = Parcel.obtain(); - updateCounts(COUNT, CURRENT_COUNT); + mCounter.addCountLocked(COUNT, true); + assertEquals(COUNT, getCount()); mCounter.writeToParcel(parcel); parcel.setDataPosition(0); - // Now clear counterArray and verify values are read from parcel correctly. - updateCounts(0, 0); + // Now change count but verify values are read from parcel correctly. + mCounter.addCountLocked(7 * COUNT, true); + assertEquals(8 * COUNT, getCount()); mCounter = new LongSamplingCounter(mTimeBase, parcel); - assertEquals(COUNT, mCounter.mCount); - assertEquals(CURRENT_COUNT, mCounter.mCurrentCount); + assertEquals(COUNT, getCount()); parcel.recycle(); } @Test public void testReadWriteSummaryParcel() { final Parcel parcel = Parcel.obtain(); - updateCounts(COUNT, CURRENT_COUNT); + mCounter.addCountLocked(COUNT, true); + assertEquals(COUNT, getCount()); mCounter.writeSummaryFromParcelLocked(parcel); parcel.setDataPosition(0); - // Now clear counterArray and verify values are read from parcel correctly. - updateCounts(0, 0); + // Now change count but verify values are read from parcel correctly. + mCounter.addCountLocked(7 * COUNT, true); + assertEquals(8 * COUNT, getCount()); mCounter.readSummaryFromParcelLocked(parcel); - assertEquals(COUNT, mCounter.mCount); + assertEquals(COUNT, getCount()); parcel.recycle(); } @Test public void testOnTimeStarted() { - updateCounts(COUNT, CURRENT_COUNT); + mCounter.addCountLocked(COUNT, true); + assertEquals(COUNT, getCount()); mCounter.onTimeStarted(0, 0, 0); - assertEquals(COUNT, mCounter.mCount); - assertEquals(COUNT, mCounter.mUnpluggedCount); + assertEquals(COUNT, getCount()); } @Test public void testOnTimeStopped() { - updateCounts(COUNT, CURRENT_COUNT); + mCounter.addCountLocked(COUNT, true); + assertEquals(COUNT, getCount()); mCounter.onTimeStopped(0, 0, 0); - assertEquals(COUNT, mCounter.mCount); + assertEquals(COUNT, getCount()); } @Test public void testAddCountLocked() { - updateCounts(0, 0); - assertEquals(0, mCounter.getCountLocked(0)); + assertEquals(0, getCount()); when(mTimeBase.isRunning()).thenReturn(true); mCounter.addCountLocked(111); assertEquals(111, mCounter.getCountLocked(STATS_SINCE_CHARGED)); - assertEquals(111, mCounter.mCurrentCount); mCounter.addCountLocked(222); assertEquals(333, mCounter.getCountLocked(STATS_SINCE_CHARGED)); - assertEquals(333, mCounter.mCurrentCount); when(mTimeBase.isRunning()).thenReturn(false); mCounter.addCountLocked(456); assertEquals(333, mCounter.getCountLocked(STATS_SINCE_CHARGED)); - assertEquals(789, mCounter.mCurrentCount); mCounter.addCountLocked(444, true); assertEquals(777, mCounter.getCountLocked(STATS_SINCE_CHARGED)); - assertEquals(1233, mCounter.mCurrentCount); mCounter.addCountLocked(567, false); assertEquals(777, mCounter.getCountLocked(STATS_SINCE_CHARGED)); - assertEquals(1800, mCounter.mCurrentCount); } - @Test - public void testUpdate() { - updateCounts(0, 0); - assertEquals(0, mCounter.getCountLocked(0)); - when(mTimeBase.isRunning()).thenReturn(true); - mCounter.update(111); - assertEquals(111, mCounter.getCountLocked(STATS_SINCE_CHARGED)); - assertEquals(111, mCounter.mCurrentCount); - mCounter.update(333); - assertEquals(333, mCounter.getCountLocked(STATS_SINCE_CHARGED)); - assertEquals(333, mCounter.mCurrentCount); - - when(mTimeBase.isRunning()).thenReturn(false); - mCounter.update(789); - assertEquals(333, mCounter.getCountLocked(STATS_SINCE_CHARGED)); - assertEquals(789, mCounter.mCurrentCount); - mCounter.update(100); - assertEquals(333, mCounter.getCountLocked(STATS_SINCE_CHARGED)); - assertEquals(100, mCounter.mCurrentCount); - - mCounter.update(544, true); - assertEquals(777, mCounter.getCountLocked(STATS_SINCE_CHARGED)); - assertEquals(544, mCounter.mCurrentCount); - mCounter.update(1544, false); - assertEquals(777, mCounter.getCountLocked(STATS_SINCE_CHARGED)); - assertEquals(1544, mCounter.mCurrentCount); - } @Test public void testReset() { - updateCounts(COUNT, CURRENT_COUNT); + mCounter.addCountLocked(COUNT, true); + assertEquals(COUNT, getCount()); // Test with detachIfReset=false mCounter.reset(false /* detachIfReset */); - assertEquals(0, mCounter.mCount); - assertEquals(CURRENT_COUNT, mCounter.mCurrentCount); + assertEquals(0, getCount()); verifyZeroInteractions(mTimeBase); - updateCounts(COUNT, CURRENT_COUNT); + mCounter.addCountLocked(COUNT, true); + assertEquals(COUNT, getCount()); // Test with detachIfReset=true mCounter.reset(true /* detachIfReset */); - assertEquals(0, mCounter.mCount); - assertEquals(CURRENT_COUNT, mCounter.mCurrentCount); + assertEquals(0, getCount()); verify(mTimeBase).remove(mCounter); verifyNoMoreInteractions(mTimeBase); } @@ -188,8 +158,7 @@ public class LongSamplingCounterTest { verifyNoMoreInteractions(mTimeBase); } - private void updateCounts(long total, long current) { - mCounter.mCount = total; - mCounter.mCurrentCount = current; + private long getCount() { + return mCounter.getCountLocked(STATS_SINCE_CHARGED); } } diff --git a/core/tests/overlaytests/device/test-apps/AppOverlayOne/AndroidManifest.xml b/core/tests/overlaytests/device/test-apps/AppOverlayOne/AndroidManifest.xml index 17191589e3f2a402ac9211e8c3405579cd35c4e3..8ac6953b44e5a8ca2f52ac0edc168c409d5c8676 100644 --- a/core/tests/overlaytests/device/test-apps/AppOverlayOne/AndroidManifest.xml +++ b/core/tests/overlaytests/device/test-apps/AppOverlayOne/AndroidManifest.xml @@ -18,5 +18,6 @@ package="com.android.overlaytest.app_overlay_one" android:versionCode="1" android:versionName="1.0"> + diff --git a/core/tests/overlaytests/device/test-apps/AppOverlayTwo/AndroidManifest.xml b/core/tests/overlaytests/device/test-apps/AppOverlayTwo/AndroidManifest.xml index ae8307c446c1644193ba9bab9cefb36171912637..f3c39ccbb301eafd1cf65a6069b1b4c89f75f238 100644 --- a/core/tests/overlaytests/device/test-apps/AppOverlayTwo/AndroidManifest.xml +++ b/core/tests/overlaytests/device/test-apps/AppOverlayTwo/AndroidManifest.xml @@ -18,5 +18,6 @@ package="com.android.overlaytest.app_overlay_two" android:versionCode="1" android:versionName="1.0"> + diff --git a/core/tests/overlaytests/device/test-apps/FrameworkOverlay/AndroidManifest.xml b/core/tests/overlaytests/device/test-apps/FrameworkOverlay/AndroidManifest.xml index 77ea16afff830273cd6ded8568a241f473f0fdc7..73a83e09d50daa927a35b21c7d3a0494d7c2072c 100644 --- a/core/tests/overlaytests/device/test-apps/FrameworkOverlay/AndroidManifest.xml +++ b/core/tests/overlaytests/device/test-apps/FrameworkOverlay/AndroidManifest.xml @@ -18,5 +18,6 @@ package="com.android.overlaytest.framework" android:versionCode="1" android:versionName="1.0"> + diff --git a/core/tests/overlaytests/host/src/com/android/server/om/hosttest/InstallOverlayTests.java b/core/tests/overlaytests/host/src/com/android/server/om/hosttest/InstallOverlayTests.java index 27986cce083562341b7454da44074704a2a7a369..f9672d27e129d4f52615252f85eff2c0a3ccc379 100644 --- a/core/tests/overlaytests/host/src/com/android/server/om/hosttest/InstallOverlayTests.java +++ b/core/tests/overlaytests/host/src/com/android/server/om/hosttest/InstallOverlayTests.java @@ -155,12 +155,26 @@ public class InstallOverlayTests extends BaseHostJUnit4Test { } } + private void delay() { + try { + Thread.sleep(100); + } catch (InterruptedException e) { + } + } + + private void installPackage(String pkg) throws Exception { + super.installPackage(pkg); + delay(); + } + private void setPackageEnabled(String pkg, boolean enabled) throws Exception { getDevice().executeShellCommand("cmd package " + (enabled ? "enable " : "disable ") + pkg); + delay(); } private void setOverlayEnabled(String pkg, boolean enabled) throws Exception { getDevice().executeShellCommand("cmd overlay " + (enabled ? "enable " : "disable ") + pkg); + delay(); } private boolean overlayManagerContainsPackage(String pkg) throws Exception { diff --git a/core/tests/overlaytests/host/test-apps/SignatureOverlay/AndroidManifest.xml b/core/tests/overlaytests/host/test-apps/SignatureOverlay/AndroidManifest.xml index b08ac96aca684f209b2dd253c1f23f1ba0840037..26b3875caab632808232a35094f7a5350f66dd22 100644 --- a/core/tests/overlaytests/host/test-apps/SignatureOverlay/AndroidManifest.xml +++ b/core/tests/overlaytests/host/test-apps/SignatureOverlay/AndroidManifest.xml @@ -16,5 +16,6 @@ + diff --git a/core/tests/overlaytests/host/test-apps/SignatureOverlay/static/AndroidManifest.xml b/core/tests/overlaytests/host/test-apps/SignatureOverlay/static/AndroidManifest.xml index 139dd9653b4a19c8a8dbc661f3bb982596c1a564..8a664235ac3d85659566db894acbe9ca3b24f17f 100644 --- a/core/tests/overlaytests/host/test-apps/SignatureOverlay/static/AndroidManifest.xml +++ b/core/tests/overlaytests/host/test-apps/SignatureOverlay/static/AndroidManifest.xml @@ -16,5 +16,6 @@ + diff --git a/core/tests/overlaytests/host/test-apps/UpdateOverlay/app/v1/AndroidManifest.xml b/core/tests/overlaytests/host/test-apps/UpdateOverlay/app/v1/AndroidManifest.xml index 73804ebd211f56c1bf83ff7cc29f933d692e906e..b6ff0c3c672588302695c284e915305b3e3f8b8f 100644 --- a/core/tests/overlaytests/host/test-apps/UpdateOverlay/app/v1/AndroidManifest.xml +++ b/core/tests/overlaytests/host/test-apps/UpdateOverlay/app/v1/AndroidManifest.xml @@ -16,5 +16,6 @@ + diff --git a/core/tests/overlaytests/host/test-apps/UpdateOverlay/app/v2/AndroidManifest.xml b/core/tests/overlaytests/host/test-apps/UpdateOverlay/app/v2/AndroidManifest.xml index 9ec7d06ce5d7470b3855c81960cb4d7b1f8c5e24..f1a39817af8685a585181b8dfb7b6759ac67902e 100644 --- a/core/tests/overlaytests/host/test-apps/UpdateOverlay/app/v2/AndroidManifest.xml +++ b/core/tests/overlaytests/host/test-apps/UpdateOverlay/app/v2/AndroidManifest.xml @@ -16,6 +16,7 @@ + diff --git a/core/tests/overlaytests/host/test-apps/UpdateOverlay/framework/AndroidManifest.xml b/core/tests/overlaytests/host/test-apps/UpdateOverlay/framework/AndroidManifest.xml index 8c8fe94809615ef710d954b2083f97860ee44796..025d1a26d4ce6470035a600f4e84649b93a4d222 100644 --- a/core/tests/overlaytests/host/test-apps/UpdateOverlay/framework/AndroidManifest.xml +++ b/core/tests/overlaytests/host/test-apps/UpdateOverlay/framework/AndroidManifest.xml @@ -16,5 +16,6 @@ + diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml index fcd5d566f250578aa136cbf0b900236256afe66c..afb50714a93d2b83c3ba6a214b206d745fb45464 100644 --- a/data/etc/privapp-permissions-platform.xml +++ b/data/etc/privapp-permissions-platform.xml @@ -112,7 +112,6 @@ applications that come with the platform - @@ -124,6 +123,7 @@ applications that come with the platform + @@ -307,6 +307,9 @@ applications that come with the platform + + + @@ -329,9 +332,9 @@ applications that come with the platform - + - + diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java index 346c7ab970dd92beba459314273fa73f07be45cc..c48546103a6f15e8a81f83da7253fcccec901983 100644 --- a/graphics/java/android/graphics/Paint.java +++ b/graphics/java/android/graphics/Paint.java @@ -229,7 +229,8 @@ public class Paint { public static final int VERTICAL_TEXT_FLAG = 0x1000; // These flags are always set on a new/reset paint, even if flags 0 is passed. - static final int HIDDEN_DEFAULT_PAINT_FLAGS = DEV_KERN_TEXT_FLAG | EMBEDDED_BITMAP_TEXT_FLAG; + static final int HIDDEN_DEFAULT_PAINT_FLAGS = DEV_KERN_TEXT_FLAG | EMBEDDED_BITMAP_TEXT_FLAG + | FILTER_BITMAP_FLAG; /** * Font hinter option that disables font hinting. diff --git a/graphics/java/android/graphics/text/MeasuredText.java b/graphics/java/android/graphics/text/MeasuredText.java index 9db7533044e2f05e462d73a3c3dc206b0aeb8b9b..b6d8fa19fca85396086b25b5a7c476532d8af11d 100644 --- a/graphics/java/android/graphics/text/MeasuredText.java +++ b/graphics/java/android/graphics/text/MeasuredText.java @@ -42,7 +42,7 @@ import libcore.util.NativeAllocationRegistry; * String text = "Hello, Android."; * MeasuredText mt = new MeasuredText.Builder(text.toCharArray()) * .appendStyleRun(paint, 7, false) // Use paint for "Hello, " - * .appendStyleRun(bigPaint, 8, false) // Use bigPaint for "Hello, " + * .appendStyleRun(bigPaint, 8, false) // Use bigPaint for "Android." * .build(); * *

diff --git a/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp b/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp index fe2d41ef630b6a73b4d8f9eff1b1cf5b378d3a80..ceab407cb939bd86521badba3c04b8e8368c0a94 100644 --- a/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp +++ b/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp @@ -65,7 +65,6 @@ void VkFunctorDrawHandler::draw(const GrBackendDrawableInfo& info) { VkFunctorDrawParams params{ .width = mImageInfo.width(), .height = mImageInfo.height(), - .is_layer = false, // TODO(boliu): Populate is_layer. .color_space_ptr = mImageInfo.colorSpace(), .clip_left = mClip.fLeft, .clip_top = mClip.fTop, diff --git a/libs/hwui/private/hwui/DrawVkInfo.h b/libs/hwui/private/hwui/DrawVkInfo.h index fb55f5ca4c935127176112bbbf7c6b8bfc1381b0..4ae0f5a0a2e5a192327b738550f860af2a4f9333 100644 --- a/libs/hwui/private/hwui/DrawVkInfo.h +++ b/libs/hwui/private/hwui/DrawVkInfo.h @@ -42,9 +42,6 @@ struct VkFunctorDrawParams { int width; int height; - // Input: is the render target a FBO - bool is_layer; - // Input: current transform matrix float transform[16]; diff --git a/libs/hwui/renderthread/VulkanManager.cpp b/libs/hwui/renderthread/VulkanManager.cpp index 9916da5d9f10b6e10c9f8882435cc62514a5c70b..b8ebf3bb0ca9159b9126766fd4d270982edf27e3 100644 --- a/libs/hwui/renderthread/VulkanManager.cpp +++ b/libs/hwui/renderthread/VulkanManager.cpp @@ -439,34 +439,47 @@ Frame VulkanManager::dequeueNextBuffer(VulkanSurface* surface) { LOG_ALWAYS_FATAL_IF(!bufferInfo->dequeued); if (bufferInfo->dequeue_fence != -1) { - int fence_clone = dup(bufferInfo->dequeue_fence); - if (fence_clone == -1) { - ALOGE("dup(fence) failed, stalling until signalled: %s (%d)", strerror(errno), errno); - sync_wait(bufferInfo->dequeue_fence, -1 /* forever */); - } else { - VkSemaphoreCreateInfo semaphoreInfo; - semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; - semaphoreInfo.pNext = nullptr; - semaphoreInfo.flags = 0; - VkSemaphore semaphore; - VkResult err = mCreateSemaphore(mDevice, &semaphoreInfo, nullptr, &semaphore); - LOG_ALWAYS_FATAL_IF(VK_SUCCESS != err, "Failed to create import semaphore, err: %d", - err); - - VkImportSemaphoreFdInfoKHR importInfo; - importInfo.sType = VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR; - importInfo.pNext = nullptr; - importInfo.semaphore = semaphore; - importInfo.flags = VK_SEMAPHORE_IMPORT_TEMPORARY_BIT; - importInfo.handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT; - importInfo.fd = fence_clone; - - err = mImportSemaphoreFdKHR(mDevice, &importInfo); - LOG_ALWAYS_FATAL_IF(VK_SUCCESS != err, "Failed to import semaphore, err: %d", err); - - GrBackendSemaphore backendSemaphore; - backendSemaphore.initVulkan(semaphore); - bufferInfo->skSurface->wait(1, &backendSemaphore); + struct sync_file_info* finfo = sync_file_info(bufferInfo->dequeue_fence); + bool isSignalPending = false; + if (finfo != NULL) { + isSignalPending = finfo->status != 1; + sync_file_info_free(finfo); + } + if (isSignalPending) { + int fence_clone = dup(bufferInfo->dequeue_fence); + if (fence_clone == -1) { + ALOGE("dup(fence) failed, stalling until signalled: %s (%d)", strerror(errno), + errno); + sync_wait(bufferInfo->dequeue_fence, -1 /* forever */); + } else { + VkSemaphoreCreateInfo semaphoreInfo; + semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; + semaphoreInfo.pNext = nullptr; + semaphoreInfo.flags = 0; + VkSemaphore semaphore; + VkResult err = mCreateSemaphore(mDevice, &semaphoreInfo, nullptr, &semaphore); + LOG_ALWAYS_FATAL_IF(VK_SUCCESS != err, "Failed to create import semaphore, err: %d", + err); + + VkImportSemaphoreFdInfoKHR importInfo; + importInfo.sType = VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR; + importInfo.pNext = nullptr; + importInfo.semaphore = semaphore; + importInfo.flags = VK_SEMAPHORE_IMPORT_TEMPORARY_BIT; + importInfo.handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT; + importInfo.fd = fence_clone; + + err = mImportSemaphoreFdKHR(mDevice, &importInfo); + LOG_ALWAYS_FATAL_IF(VK_SUCCESS != err, "Failed to import semaphore, err: %d", err); + + GrBackendSemaphore backendSemaphore; + backendSemaphore.initVulkan(semaphore); + bufferInfo->skSurface->wait(1, &backendSemaphore); + // The following flush blocks the GPU immediately instead of waiting for other + // drawing ops. It seems dequeue_fence is not respected otherwise. + //TODO: remove the flush after finding why backendSemaphore is not working. + bufferInfo->skSurface->flush(); + } } } diff --git a/libs/hwui/renderthread/VulkanSurface.cpp b/libs/hwui/renderthread/VulkanSurface.cpp index c03c3a896e2634aa6910afacbdce1375218dbbfb..a98eb322cfc76ba93bdae249db2900855d4ba704 100644 --- a/libs/hwui/renderthread/VulkanSurface.cpp +++ b/libs/hwui/renderthread/VulkanSurface.cpp @@ -256,11 +256,44 @@ VulkanSurface* VulkanSurface::Create(ANativeWindow* window, ColorMode colorMode, vkPixelFormat = VK_FORMAT_R16G16B16A16_SFLOAT; } - uint64_t producerUsage = - AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER | AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE; - uint64_t consumerUsage; - native_window_get_consumer_usage(window, &consumerUsage); - windowInfo.windowUsageFlags = consumerUsage | producerUsage; + if (nullptr != vkManager.mGetPhysicalDeviceImageFormatProperties2) { + VkPhysicalDeviceExternalImageFormatInfo externalImageFormatInfo; + externalImageFormatInfo.sType = + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO; + externalImageFormatInfo.pNext = nullptr; + externalImageFormatInfo.handleType = + VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID; + + VkPhysicalDeviceImageFormatInfo2 imageFormatInfo; + imageFormatInfo.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2; + imageFormatInfo.pNext = &externalImageFormatInfo; + imageFormatInfo.format = vkPixelFormat; + imageFormatInfo.type = VK_IMAGE_TYPE_2D; + imageFormatInfo.tiling = VK_IMAGE_TILING_OPTIMAL; + imageFormatInfo.usage = usageFlags; + imageFormatInfo.flags = 0; + + VkAndroidHardwareBufferUsageANDROID hwbUsage; + hwbUsage.sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_USAGE_ANDROID; + hwbUsage.pNext = nullptr; + + VkImageFormatProperties2 imgFormProps; + imgFormProps.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2; + imgFormProps.pNext = &hwbUsage; + + res = vkManager.mGetPhysicalDeviceImageFormatProperties2(vkManager.mPhysicalDevice, + &imageFormatInfo, &imgFormProps); + if (VK_SUCCESS != res) { + ALOGE("Failed to query GetPhysicalDeviceImageFormatProperties2"); + return nullptr; + } + + windowInfo.windowUsageFlags = hwbUsage.androidHardwareBufferUsage; + + } else { + ALOGE("VulkanSurface::Create() vkmGetPhysicalDeviceImageFormatProperties2 is missing"); + return nullptr; + } /* * Now we attempt to modify the window! diff --git a/location/java/android/location/GnssClock.java b/location/java/android/location/GnssClock.java index 8507c8344b6c7136a3339ba74c3f24d2a4dfc6e8..538406180367fe16c1281018772a08c2a44c3afd 100644 --- a/location/java/android/location/GnssClock.java +++ b/location/java/android/location/GnssClock.java @@ -16,6 +16,8 @@ package android.location; +import android.annotation.FloatRange; +import android.annotation.IntRange; import android.annotation.TestApi; import android.os.Parcel; import android.os.Parcelable; @@ -36,6 +38,8 @@ public final class GnssClock implements Parcelable { private static final int HAS_BIAS_UNCERTAINTY = (1<<4); private static final int HAS_DRIFT = (1<<5); private static final int HAS_DRIFT_UNCERTAINTY = (1<<6); + private static final int HAS_ELAPSED_REALTIME_NANOS = (1 << 7); + private static final int HAS_ELAPSED_REALTIME_UNCERTAINTY_NANOS = (1 << 8); // End enumerations in sync with gps.h @@ -49,6 +53,8 @@ public final class GnssClock implements Parcelable { private double mDriftNanosPerSecond; private double mDriftUncertaintyNanosPerSecond; private int mHardwareClockDiscontinuityCount; + private long mElapsedRealtimeNanos; + private long mElapsedRealtimeUncertaintyNanos; /** * @hide @@ -74,6 +80,8 @@ public final class GnssClock implements Parcelable { mDriftNanosPerSecond = clock.mDriftNanosPerSecond; mDriftUncertaintyNanosPerSecond = clock.mDriftUncertaintyNanosPerSecond; mHardwareClockDiscontinuityCount = clock.mHardwareClockDiscontinuityCount; + mElapsedRealtimeNanos = clock.mElapsedRealtimeNanos; + mElapsedRealtimeUncertaintyNanos = clock.mElapsedRealtimeUncertaintyNanos; } /** @@ -167,6 +175,7 @@ public final class GnssClock implements Parcelable { *

This value is often effectively zero (it is the reference clock by which all other times * and time uncertainties are measured), and thus this field may often be 0, or not provided. */ + @FloatRange(from = 0.0f) public double getTimeUncertaintyNanos() { return mTimeUncertaintyNanos; } @@ -176,7 +185,7 @@ public final class GnssClock implements Parcelable { * @hide */ @TestApi - public void setTimeUncertaintyNanos(double timeUncertaintyNanos) { + public void setTimeUncertaintyNanos(@FloatRange(from = 0.0f) double timeUncertaintyNanos) { setFlag(HAS_TIME_UNCERTAINTY); mTimeUncertaintyNanos = timeUncertaintyNanos; } @@ -297,6 +306,7 @@ public final class GnssClock implements Parcelable { * *

The value is only available if {@link #hasBiasUncertaintyNanos()} is {@code true}. */ + @FloatRange(from = 0.0f) public double getBiasUncertaintyNanos() { return mBiasUncertaintyNanos; } @@ -306,7 +316,7 @@ public final class GnssClock implements Parcelable { * @hide */ @TestApi - public void setBiasUncertaintyNanos(double biasUncertaintyNanos) { + public void setBiasUncertaintyNanos(@FloatRange(from = 0.0f) double biasUncertaintyNanos) { setFlag(HAS_BIAS_UNCERTAINTY); mBiasUncertaintyNanos = biasUncertaintyNanos; } @@ -379,6 +389,7 @@ public final class GnssClock implements Parcelable { *

The value is only available if {@link #hasDriftUncertaintyNanosPerSecond()} is * {@code true}. */ + @FloatRange(from = 0.0f) public double getDriftUncertaintyNanosPerSecond() { return mDriftUncertaintyNanosPerSecond; } @@ -388,7 +399,8 @@ public final class GnssClock implements Parcelable { * @hide */ @TestApi - public void setDriftUncertaintyNanosPerSecond(double driftUncertaintyNanosPerSecond) { + public void setDriftUncertaintyNanosPerSecond( + @FloatRange(from = 0.0f) double driftUncertaintyNanosPerSecond) { setFlag(HAS_DRIFT_UNCERTAINTY); mDriftUncertaintyNanosPerSecond = driftUncertaintyNanosPerSecond; } @@ -403,6 +415,90 @@ public final class GnssClock implements Parcelable { mDriftUncertaintyNanosPerSecond = Double.NaN; } + /** + * Returns {@code true} if {@link #getElapsedRealtimeNanos()} is available, {@code false} + * otherwise. + */ + public boolean hasElapsedRealtimeNanos() { + return isFlagSet(HAS_ELAPSED_REALTIME_NANOS); + } + + /** + * Returns the elapsed real-time of this clock since system boot, in nanoseconds. + * + *

The value is only available if {@link #hasElapsedRealtimeNanos()} is + * {@code true}. + */ + public long getElapsedRealtimeNanos() { + return mElapsedRealtimeNanos; + } + + /** + * Sets the elapsed real-time of this clock since system boot, in nanoseconds. + * @hide + */ + @TestApi + public void setElapsedRealtimeNanos(long elapsedRealtimeNanos) { + setFlag(HAS_ELAPSED_REALTIME_NANOS); + mElapsedRealtimeNanos = elapsedRealtimeNanos; + } + + /** + * Resets the elapsed real-time of this clock since system boot, in nanoseconds. + * @hide + */ + @TestApi + public void resetElapsedRealtimeNanos() { + resetFlag(HAS_ELAPSED_REALTIME_NANOS); + mElapsedRealtimeNanos = 0; + } + + /** + * Returns {@code true} if {@link #getElapsedRealtimeUncertaintyNanos()} is available, {@code + * false} otherwise. + */ + public boolean hasElapsedRealtimeUncertaintyNanos() { + return isFlagSet(HAS_ELAPSED_REALTIME_UNCERTAINTY_NANOS); + } + + /** + * Gets the estimate of the relative precision of the alignment of the + * {@link #getElapsedRealtimeNanos()} timestamp, with the reported measurements in + * nanoseconds (68% confidence). + * + *

The value is only available if {@link #hasElapsedRealtimeUncertaintyNanos()} is + * {@code true}. + */ + @IntRange(from = 0) + public long getElapsedRealtimeUncertaintyNanos() { + return mElapsedRealtimeUncertaintyNanos; + } + + /** + * Sets the estimate of the relative precision of the alignment of the + * {@link #getElapsedRealtimeNanos()} timestamp, with the reported measurements in + * nanoseconds (68% confidence). + * @hide + */ + @TestApi + public void setElapsedRealtimeUncertaintyNanos( + @IntRange(from = 0) long elapsedRealtimeUncertaintyNanos) { + setFlag(HAS_ELAPSED_REALTIME_UNCERTAINTY_NANOS); + mElapsedRealtimeUncertaintyNanos = elapsedRealtimeUncertaintyNanos; + } + + /** + * Resets the estimate of the relative precision of the alignment of the + * {@link #getElapsedRealtimeNanos()} timestamp, with the reported measurements in + * nanoseconds (68% confidence). + * @hide + */ + @TestApi + public void resetElapsedRealtimeUncertaintyNanos() { + resetFlag(HAS_ELAPSED_REALTIME_UNCERTAINTY_NANOS); + mElapsedRealtimeUncertaintyNanos = Long.MAX_VALUE; + } + /** * Gets count of hardware clock discontinuities. * @@ -446,6 +542,8 @@ public final class GnssClock implements Parcelable { gpsClock.mDriftNanosPerSecond = parcel.readDouble(); gpsClock.mDriftUncertaintyNanosPerSecond = parcel.readDouble(); gpsClock.mHardwareClockDiscontinuityCount = parcel.readInt(); + gpsClock.mElapsedRealtimeNanos = parcel.readLong(); + gpsClock.mElapsedRealtimeUncertaintyNanos = parcel.readLong(); return gpsClock; } @@ -468,6 +566,8 @@ public final class GnssClock implements Parcelable { parcel.writeDouble(mDriftNanosPerSecond); parcel.writeDouble(mDriftUncertaintyNanosPerSecond); parcel.writeInt(mHardwareClockDiscontinuityCount); + parcel.writeLong(mElapsedRealtimeNanos); + parcel.writeLong(mElapsedRealtimeUncertaintyNanos); } @Override @@ -514,6 +614,16 @@ public final class GnssClock implements Parcelable { "HardwareClockDiscontinuityCount", mHardwareClockDiscontinuityCount)); + builder.append(String.format( + format, + "ElapsedRealtimeNanos", + hasElapsedRealtimeNanos() ? mElapsedRealtimeNanos : null)); + + builder.append(String.format( + format, + "ElapsedRealtimeUncertaintyNanos", + hasElapsedRealtimeUncertaintyNanos() ? mElapsedRealtimeUncertaintyNanos : null)); + return builder.toString(); } @@ -528,6 +638,8 @@ public final class GnssClock implements Parcelable { resetDriftNanosPerSecond(); resetDriftUncertaintyNanosPerSecond(); setHardwareClockDiscontinuityCount(Integer.MIN_VALUE); + resetElapsedRealtimeNanos(); + resetElapsedRealtimeUncertaintyNanos(); } private void setFlag(int flag) { diff --git a/location/java/android/location/ILocationManager.aidl b/location/java/android/location/ILocationManager.aidl index a4582b7ece92daedee876d5c63e82ba42f862969..93dc6fa9bf937ce05ea18912b3f2d6b91f37771b 100644 --- a/location/java/android/location/ILocationManager.aidl +++ b/location/java/android/location/ILocationManager.aidl @@ -29,6 +29,7 @@ import android.location.IGnssNavigationMessageListener; import android.location.ILocationListener; import android.location.Location; import android.location.LocationRequest; +import android.location.LocationTime; import android.os.Bundle; import com.android.internal.location.ProviderProperties; @@ -104,6 +105,7 @@ interface ILocationManager void setTestProviderLocation(String provider, in Location loc, String opPackageName); void setTestProviderEnabled(String provider, boolean enabled, String opPackageName); List getTestProviderCurrentRequests(String provider, String opPackageName); + LocationTime getGnssTimeMillis(); // --- deprecated --- void setTestProviderStatus(String provider, int status, in Bundle extras, long updateTime, diff --git a/location/java/android/location/LocationTime.aidl b/location/java/android/location/LocationTime.aidl new file mode 100644 index 0000000000000000000000000000000000000000..f6263637bb33307d3a5d74383e685d90f6740452 --- /dev/null +++ b/location/java/android/location/LocationTime.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2019, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.location; + +parcelable LocationTime; diff --git a/location/java/android/location/LocationTime.java b/location/java/android/location/LocationTime.java new file mode 100644 index 0000000000000000000000000000000000000000..e5535d192776fe3bbcc6cef8aca0f9d3a3008eaf --- /dev/null +++ b/location/java/android/location/LocationTime.java @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.location; + +import android.annotation.NonNull; +import android.os.Parcel; +import android.os.Parcelable; + +/** + * Data class for passing location derived time. + * @hide + */ +public final class LocationTime implements Parcelable { + + private final long mTime; + private final long mElapsedRealtimeNanos; + + public LocationTime(long time, long elapsedRealtimeNanos) { + mTime = time; + mElapsedRealtimeNanos = elapsedRealtimeNanos; + } + + /** + * The current time, according to the Gnss location provider. */ + public long getTime() { + return mTime; + } + + /** + * The elapsed nanos since boot {@link #getTime} was computed at. + */ + public long getElapsedRealtimeNanos() { + return mElapsedRealtimeNanos; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeLong(mTime); + out.writeLong(mElapsedRealtimeNanos); + } + + @Override + public int describeContents() { + return 0; + } + + public static final @NonNull Parcelable.Creator CREATOR = + new Parcelable.Creator() { + public LocationTime createFromParcel(Parcel in) { + long time = in.readLong(); + long elapsedRealtimeNanos = in.readLong(); + return new LocationTime(time, elapsedRealtimeNanos); + } + + public LocationTime[] newArray(int size) { + return new LocationTime[size]; + } + }; +} diff --git a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java index e5fd0d342e9d1547f81ef30d2c14ad11551f2b27..b4be21987cf7214dd1c8c9d2cc5bda14ba186e4e 100644 --- a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java +++ b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java @@ -238,6 +238,8 @@ public class GpsNetInitiatedHandler { * window after the end of that call. * 3. If the device is in a emergency callback state, this is provided by querying * TelephonyManager. + * 4. If the user has recently sent an Emergency SMS and telephony reports that it is in + * emergency SMS mode, this is provided by querying TelephonyManager. * @return true if is considered in user initiated emergency mode for NI purposes */ public boolean getInEmergency() { @@ -246,7 +248,9 @@ public class GpsNetInitiatedHandler { && ((SystemClock.elapsedRealtime() - mCallEndElapsedRealtimeMillis) < mEmergencyExtensionMillis); boolean isInEmergencyCallback = mTelephonyManager.getEmergencyCallbackMode(); - return mIsInEmergencyCall || isInEmergencyCallback || isInEmergencyExtension; + boolean isInEmergencySmsMode = mTelephonyManager.isInEmergencySmsMode(); + return mIsInEmergencyCall || isInEmergencyCallback || isInEmergencyExtension + || isInEmergencySmsMode; } public void setEmergencyExtensionSeconds(int emergencyExtensionSeconds) { diff --git a/media/Android.bp b/media/Android.bp index 86dc509501a42f7378b3f86804a27914611ff6c1..34801813ee87290bb92a24159bcd798f48b20e96 100644 --- a/media/Android.bp +++ b/media/Android.bp @@ -90,7 +90,6 @@ filegroup { "apex/java/android/media/DataSourceDesc.java", "apex/java/android/media/UriDataSourceDesc.java", "apex/java/android/media/FileDataSourceDesc.java", - "apex/java/android/media/CallbackDataSourceDesc.java", "apex/java/android/media/Media2Utils.java", "apex/java/android/media/MediaPlayer2Utils.java", "apex/java/android/media/MediaPlayer2.java", @@ -98,6 +97,7 @@ filegroup { "apex/java/android/media/Media2HTTPConnection.java", "apex/java/android/media/RoutingDelegate.java", "apex/java/android/media/BufferingParams.java", + "apex/java/android/media/ProxyDataSourceCallback.java", ], } diff --git a/media/apex/java/android/media/CallbackDataSourceDesc.java b/media/apex/java/android/media/CallbackDataSourceDesc.java deleted file mode 100644 index 9209ca94897f752859ed07a391cf2bd2cf10ed1f..0000000000000000000000000000000000000000 --- a/media/apex/java/android/media/CallbackDataSourceDesc.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.media; - -import android.annotation.NonNull; -import android.annotation.Nullable; - -/** - * Structure of data source descriptor for sources using callback. - * - * Used by {@link MediaPlayer2#setDataSource}, {@link MediaPlayer2#setNextDataSource} and - * {@link MediaPlayer2#setNextDataSources} to set data source for playback. - * - *

Users should use {@link Builder} to create {@link CallbackDataSourceDesc}. - * - */ -public class CallbackDataSourceDesc extends DataSourceDesc { - private DataSourceCallback mDataSourceCallback; - - private CallbackDataSourceDesc() { - } - - /** - * Return the DataSourceCallback of this data source. - * @return the DataSourceCallback of this data source - */ - public @NonNull DataSourceCallback getDataSourceCallback() { - return mDataSourceCallback; - } - - /** - * Builder class for {@link CallbackDataSourceDesc} objects. - *

Here is an example where Builder is used to define the - * {@link CallbackDataSourceDesc} to be used by a {@link MediaPlayer2} instance: - * - *

-     * CallbackDataSourceDesc newDSD = new CallbackDataSourceDesc.Builder()
-     *         .setDataSource(media2DataSource)
-     *         .setStartPosition(1000)
-     *         .setEndPosition(15000)
-     *         .build();
-     * mediaplayer2.setDataSourceDesc(newDSD);
-     * 
- */ - public static class Builder extends BuilderBase { - private DataSourceCallback mDataSourceCallback; - - /** - * Constructs a new Builder with the defaults. - */ - public Builder() { - super(); - } - - /** - * Constructs a new Builder from a given {@link CallbackDataSourceDesc} instance - * @param dsd the {@link CallbackDataSourceDesc} object whose data will be reused - * in the new Builder. - */ - public Builder(@Nullable CallbackDataSourceDesc dsd) { - super(dsd); - if (dsd == null) { - return; // use default - } - mDataSourceCallback = dsd.mDataSourceCallback; - } - - /** - * Combines all of the fields that have been set and return a new - * {@link CallbackDataSourceDesc} object. IllegalStateException will be - * thrown if there is conflict between fields. - * - * @return a new {@link CallbackDataSourceDesc} object - */ - public @NonNull CallbackDataSourceDesc build() { - if (mDataSourceCallback == null) { - throw new IllegalStateException( - "DataSourceCallback should not be null"); - } - - CallbackDataSourceDesc dsd = new CallbackDataSourceDesc(); - super.build(dsd); - dsd.mDataSourceCallback = mDataSourceCallback; - - return dsd; - } - - /** - * Sets the data source (DataSourceCallback) to use. - * - * @param dscb the DataSourceCallback for the media to play - * @return the same Builder instance. - * @throws NullPointerException if dscb is null. - */ - public @NonNull Builder setDataSource(@NonNull DataSourceCallback dscb) { - Media2Utils.checkArgument(dscb != null, "data source cannot be null."); - mDataSourceCallback = dscb; - return this; - } - } -} diff --git a/media/apex/java/android/media/DataSourceCallback.java b/media/apex/java/android/media/DataSourceCallback.java index 6515bd6a2c09ae9adf6fb339d41779c975d00021..c297ecda249cd58fdb665a9fc96b78435dc23948 100644 --- a/media/apex/java/android/media/DataSourceCallback.java +++ b/media/apex/java/android/media/DataSourceCallback.java @@ -32,8 +32,12 @@ import java.io.IOException; * you don't need to do your own synchronization unless you're modifying the * DataSourceCallback from another thread while it's being used by the framework.

* + * @hide */ public abstract class DataSourceCallback implements Closeable { + + public static final int END_OF_STREAM = -1; + /** * Called to request data from the given position. * @@ -49,7 +53,7 @@ public abstract class DataSourceCallback implements Closeable { * @param offset the offset within buffer to read the data into. * @param size the number of bytes to read. * @throws IOException on fatal errors. - * @return the number of bytes read, or -1 if end of stream is reached. + * @return the number of bytes read, or {@link #END_OF_STREAM} if end of stream is reached. */ public abstract int readAt(long position, @NonNull byte[] buffer, int offset, int size) throws IOException; diff --git a/media/apex/java/android/media/DataSourceDesc.java b/media/apex/java/android/media/DataSourceDesc.java index e6fd120b6d5bf878b06c33a066fb3a70e9b23661..d00ff2a70955902c6397d7a3fd8f3dbf0d9b8ca7 100644 --- a/media/apex/java/android/media/DataSourceDesc.java +++ b/media/apex/java/android/media/DataSourceDesc.java @@ -18,15 +18,22 @@ package android.media; import android.annotation.NonNull; import android.annotation.Nullable; +import android.net.Uri; +import android.os.ParcelFileDescriptor; + +import java.net.CookieHandler; +import java.net.CookieManager; +import java.net.HttpCookie; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; /** - * Base class of data source descriptor. + * Data source descriptor. * * Used by {@link MediaPlayer2#setDataSource}, {@link MediaPlayer2#setNextDataSource} and * {@link MediaPlayer2#setNextDataSources} to set data source for playback. - * - *

Users should use subclasses' builder to change {@link DataSourceDesc}. - * */ public class DataSourceDesc { // intentionally less than long.MAX_VALUE @@ -45,7 +52,10 @@ public class DataSourceDesc { private long mStartPositionMs = 0; private long mEndPositionMs = POSITION_UNKNOWN; - DataSourceDesc() { + DataSourceDesc(String mediaId, long startPositionMs, long endPositionMs) { + mMediaId = mediaId; + mStartPositionMs = startPositionMs; + mEndPositionMs = endPositionMs; } /** @@ -97,17 +107,44 @@ public class DataSourceDesc { } /** - * Base class for Builders in the subclasses of {@link DataSourceDesc}. + * Builder for {@link DataSourceDesc}. + *

+ * Here is an example where Builder is used to define the + * {@link DataSourceDesc} to be used by a {@link MediaPlayer2} instance: + * + *

+     * DataSourceDesc newDSD = new DataSourceDesc.Builder()
+     *         .setDataSource(context, uri, headers, cookies)
+     *         .setStartPosition(1000)
+     *         .setEndPosition(15000)
+     *         .build();
+     * mediaplayer2.setDataSourceDesc(newDSD);
+     * 
*/ - protected static class BuilderBase { + public static final class Builder { + private static final int SOURCE_TYPE_UNKNOWN = 0; + private static final int SOURCE_TYPE_URI = 1; + private static final int SOURCE_TYPE_FILE = 2; + + private int mSourceType = SOURCE_TYPE_UNKNOWN; private String mMediaId; private long mStartPositionMs = 0; private long mEndPositionMs = POSITION_UNKNOWN; + // For UriDataSourceDesc + private Uri mUri; + private Map mHeader; + private List mCookies; + + // For FileDataSourceDesc + private ParcelFileDescriptor mPFD; + private long mOffset = 0; + private long mLength = FileDataSourceDesc.FD_LENGTH_UNKNOWN; + /** * Constructs a new BuilderBase with the defaults. */ - BuilderBase() { + public Builder() { } /** @@ -115,33 +152,55 @@ public class DataSourceDesc { * @param dsd the {@link DataSourceDesc} object whose data will be reused * in the new BuilderBase. */ - BuilderBase(DataSourceDesc dsd) { + public Builder(@Nullable DataSourceDesc dsd) { if (dsd == null) { return; } mMediaId = dsd.mMediaId; mStartPositionMs = dsd.mStartPositionMs; mEndPositionMs = dsd.mEndPositionMs; + if (dsd instanceof FileDataSourceDesc) { + mSourceType = SOURCE_TYPE_FILE; + mPFD = ((FileDataSourceDesc) dsd).getParcelFileDescriptor(); + mOffset = ((FileDataSourceDesc) dsd).getOffset(); + mLength = ((FileDataSourceDesc) dsd).getLength(); + } else if (dsd instanceof UriDataSourceDesc) { + mSourceType = SOURCE_TYPE_URI; + mUri = ((UriDataSourceDesc) dsd).getUri(); + mHeader = ((UriDataSourceDesc) dsd).getHeaders(); + mCookies = ((UriDataSourceDesc) dsd).getCookies(); + } else { + throw new IllegalStateException("Unknown source type:" + mSourceType); + } } /** * Sets all fields that have been set in the {@link DataSourceDesc} object. * IllegalStateException will be thrown if there is conflict between fields. * - * @param dsd an instance of subclass of {@link DataSourceDesc} whose data will be set - * @return the same instance of subclass of {@link DataSourceDesc} + * @return {@link DataSourceDesc} */ - void build(@NonNull DataSourceDesc dsd) { - Media2Utils.checkArgument(dsd != null, "dsd cannot be null."); - + @NonNull + public DataSourceDesc build() { + if (mSourceType == SOURCE_TYPE_UNKNOWN) { + throw new IllegalStateException("Source is not set."); + } if (mStartPositionMs > mEndPositionMs) { throw new IllegalStateException("Illegal start/end position: " + mStartPositionMs + " : " + mEndPositionMs); } - dsd.mMediaId = mMediaId; - dsd.mStartPositionMs = mStartPositionMs; - dsd.mEndPositionMs = mEndPositionMs; + DataSourceDesc desc; + if (mSourceType == SOURCE_TYPE_FILE) { + desc = new FileDataSourceDesc( + mMediaId, mStartPositionMs, mEndPositionMs, mPFD, mOffset, mLength); + } else if (mSourceType == SOURCE_TYPE_URI) { + desc = new UriDataSourceDesc( + mMediaId, mStartPositionMs, mEndPositionMs, mUri, mHeader, mCookies); + } else { + throw new IllegalStateException("Unknown source type:" + mSourceType); + } + return desc; } /** @@ -150,9 +209,10 @@ public class DataSourceDesc { * @param mediaId the media Id of this data source * @return the same Builder instance. */ - public @NonNull T setMediaId(@Nullable String mediaId) { + @NonNull + public Builder setMediaId(@Nullable String mediaId) { mMediaId = mediaId; - return (T) this; + return this; } /** @@ -163,12 +223,13 @@ public class DataSourceDesc { * @return the same Builder instance. * */ - public @NonNull T setStartPosition(long position) { + @NonNull + public Builder setStartPosition(long position) { if (position < 0) { position = 0; } mStartPositionMs = position; - return (T) this; + return this; } /** @@ -179,12 +240,143 @@ public class DataSourceDesc { * @param position the end position in milliseconds at which the playback will end * @return the same Builder instance. */ - public @NonNull T setEndPosition(long position) { + @NonNull + public Builder setEndPosition(long position) { if (position < 0) { position = LONG_MAX_TIME_MS; } mEndPositionMs = position; - return (T) this; + return this; + } + + /** + * Sets the data source as a content Uri. + * + * @param uri the Content URI of the data you want to play + * @return the same Builder instance. + * @throws NullPointerException if context or uri is null. + */ + @NonNull + public Builder setDataSource(@NonNull Uri uri) { + setSourceType(SOURCE_TYPE_URI); + Media2Utils.checkArgument(uri != null, "uri cannot be null"); + mUri = uri; + return this; + } + + /** + * Sets the data source as a content Uri. + * + * To provide cookies for the subsequent HTTP requests, you can install your own default + * cookie handler and use other variants of setDataSource APIs instead. Alternatively, you + * can use this API to pass the cookies as a list of HttpCookie. If the app has not + * installed a CookieHandler already, {@link MediaPlayer2} will create a CookieManager + * and populates its CookieStore with the provided cookies when this data source is passed + * to {@link MediaPlayer2}. If the app has installed its own handler already, the handler + * is required to be of CookieManager type such that {@link MediaPlayer2} can update the + * manager’s CookieStore. + * + *

Note that the cross domain redirection is allowed by default, + * but that can be changed with key/value pairs through the headers parameter with + * "android-allow-cross-domain-redirect" as the key and "0" or "1" as the value to + * disallow or allow cross domain redirection. + * + * @param uri the Content URI of the data you want to play + * @param headers the headers to be sent together with the request for the data + * The headers must not include cookies. Instead, use the cookies param. + * @param cookies the cookies to be sent together with the request + * @return the same Builder instance. + * @throws NullPointerException if context or uri is null. + * @throws IllegalArgumentException if the cookie handler is not of CookieManager type + * when cookies are provided. + */ + @NonNull + public Builder setDataSource(@NonNull Uri uri, @Nullable Map headers, + @Nullable List cookies) { + setSourceType(SOURCE_TYPE_URI); + Media2Utils.checkArgument(uri != null, "uri cannot be null"); + if (cookies != null) { + CookieHandler cookieHandler = CookieHandler.getDefault(); + if (cookieHandler != null && !(cookieHandler instanceof CookieManager)) { + throw new IllegalArgumentException( + "The cookie handler has to be of CookieManager type " + + "when cookies are provided."); + } + } + + mUri = uri; + if (headers != null) { + mHeader = new HashMap(headers); + } + if (cookies != null) { + mCookies = new ArrayList(cookies); + } + return this; + } + + /** + * Sets the data source (ParcelFileDescriptor) to use. The ParcelFileDescriptor must be + * seekable (N.B. a LocalSocket is not seekable). When the {@link DataSourceDesc} + * created by this builder is passed to {@link MediaPlayer2} via + * {@link MediaPlayer2#setDataSource}, + * {@link MediaPlayer2#setNextDataSource} or + * {@link MediaPlayer2#setNextDataSources}, MediaPlayer2 will + * close the ParcelFileDescriptor. + * + * @param pfd the ParcelFileDescriptor for the file to play + * @return the same Builder instance. + * @throws NullPointerException if pfd is null. + */ + @NonNull + public Builder setDataSource(@NonNull ParcelFileDescriptor pfd) { + setSourceType(SOURCE_TYPE_FILE); + Media2Utils.checkArgument(pfd != null, "pfd cannot be null."); + mPFD = pfd; + return this; + } + + /** + * Sets the data source (ParcelFileDescriptor) to use. The ParcelFileDescriptor must be + * seekable (N.B. a LocalSocket is not seekable). When the {@link DataSourceDesc} + * created by this builder is passed to {@link MediaPlayer2} via + * {@link MediaPlayer2#setDataSource}, + * {@link MediaPlayer2#setNextDataSource} or + * {@link MediaPlayer2#setNextDataSources}, MediaPlayer2 will + * close the ParcelFileDescriptor. + * + * Any negative number for offset is treated as 0. + * Any negative number for length is treated as maximum length of the data source. + * + * @param pfd the ParcelFileDescriptor for the file to play + * @param offset the offset into the file where the data to be played starts, in bytes + * @param length the length in bytes of the data to be played + * @return the same Builder instance. + * @throws NullPointerException if pfd is null. + */ + @NonNull + public Builder setDataSource( + @NonNull ParcelFileDescriptor pfd, long offset, long length) { + setSourceType(SOURCE_TYPE_FILE); + if (pfd == null) { + throw new NullPointerException("pfd cannot be null."); + } + if (offset < 0) { + offset = 0; + } + if (length < 0) { + length = FileDataSourceDesc.FD_LENGTH_UNKNOWN; + } + mPFD = pfd; + mOffset = offset; + mLength = length; + return this; + } + + private void setSourceType(int type) { + if (mSourceType != SOURCE_TYPE_UNKNOWN) { + throw new IllegalStateException("Source is already set. type=" + mSourceType); + } + mSourceType = type; } } } diff --git a/media/apex/java/android/media/FileDataSourceDesc.java b/media/apex/java/android/media/FileDataSourceDesc.java index 4b703670abf11915e882672fa0512d27fc7fd540..feb67e136d9bc4bfddf52c0efd2261b751e1ae78 100644 --- a/media/apex/java/android/media/FileDataSourceDesc.java +++ b/media/apex/java/android/media/FileDataSourceDesc.java @@ -17,7 +17,7 @@ package android.media; import android.annotation.NonNull; -import android.annotation.Nullable; +import android.annotation.TestApi; import android.os.ParcelFileDescriptor; import android.util.Log; @@ -30,8 +30,9 @@ import java.io.IOException; * {@link MediaPlayer2#setNextDataSources} to set data source for playback. * *

Users should use {@link Builder} to create {@link FileDataSourceDesc}. - * + * @hide */ +@TestApi public class FileDataSourceDesc extends DataSourceDesc { private static final String TAG = "FileDataSourceDesc"; @@ -48,8 +49,12 @@ public class FileDataSourceDesc extends DataSourceDesc { private int mCount = 0; private boolean mClosed = false; - private FileDataSourceDesc() { - super(); + FileDataSourceDesc(String mediaId, long startPositionMs, long endPositionMs, + ParcelFileDescriptor pfd, long offset, long length) { + super(mediaId, startPositionMs, endPositionMs); + mPFD = pfd; + mOffset = offset; + mLength = length; } /** @@ -128,133 +133,4 @@ public class FileDataSourceDesc extends DataSourceDesc { public long getLength() { return mLength; } - - /** - * Builder class for {@link FileDataSourceDesc} objects. - *

Here is an example where Builder is used to define the - * {@link FileDataSourceDesc} to be used by a {@link MediaPlayer2} instance: - * - *

-     * FileDataSourceDesc newDSD = new FileDataSourceDesc.Builder()
-     *         .setDataSource(pfd, 0, srcLength)
-     *         .setStartPosition(1000)
-     *         .setEndPosition(15000)
-     *         .build();
-     * mediaplayer2.setDataSourceDesc(newDSD);
-     * 
- */ - public static class Builder extends BuilderBase { - private ParcelFileDescriptor mPFD; - private long mOffset = 0; - private long mLength = FD_LENGTH_UNKNOWN; - - /** - * Constructs a new Builder with the defaults. - */ - public Builder() { - super(); - } - - /** - * Constructs a new Builder from a given {@link FileDataSourceDesc} instance - * @param dsd the {@link FileDataSourceDesc} object whose data will be reused - * in the new Builder. - */ - public Builder(@Nullable FileDataSourceDesc dsd) { - super(dsd); - if (dsd == null) { - return; // use default - } - mPFD = dsd.mPFD; - mOffset = dsd.mOffset; - mLength = dsd.mLength; - } - - /** - * Combines all of the fields that have been set and return a new - * {@link FileDataSourceDesc} object. IllegalStateException will be - * thrown if there is conflict between fields. - * - * @return a new {@link FileDataSourceDesc} object - */ - public @NonNull FileDataSourceDesc build() { - if (mPFD == null) { - throw new IllegalStateException( - "underline ParcelFileDescriptor should not be null"); - } - try { - mPFD.getFd(); - } catch (IllegalStateException e) { - throw new IllegalStateException("ParcelFileDescriptor has been closed"); - } - - FileDataSourceDesc dsd = new FileDataSourceDesc(); - super.build(dsd); - dsd.mPFD = mPFD; - dsd.mOffset = mOffset; - dsd.mLength = mLength; - - return dsd; - } - - /** - * Sets the data source (ParcelFileDescriptor) to use. The ParcelFileDescriptor must be - * seekable (N.B. a LocalSocket is not seekable). When the {@link FileDataSourceDesc} - * created by this builder is passed to {@link MediaPlayer2} via - * {@link MediaPlayer2#setDataSource}, - * {@link MediaPlayer2#setNextDataSource} or - * {@link MediaPlayer2#setNextDataSources}, MediaPlayer2 will - * close the ParcelFileDescriptor. - * - * @param pfd the ParcelFileDescriptor for the file to play - * @return the same Builder instance. - * @throws NullPointerException if pfd is null. - */ - public @NonNull Builder setDataSource(@NonNull ParcelFileDescriptor pfd) { - Media2Utils.checkArgument(pfd != null, "pfd cannot be null."); - resetDataSource(); - mPFD = pfd; - return this; - } - - /** - * Sets the data source (ParcelFileDescriptor) to use. The ParcelFileDescriptor must be - * seekable (N.B. a LocalSocket is not seekable). When the {@link FileDataSourceDesc} - * created by this builder is passed to {@link MediaPlayer2} via - * {@link MediaPlayer2#setDataSource}, - * {@link MediaPlayer2#setNextDataSource} or - * {@link MediaPlayer2#setNextDataSources}, MediaPlayer2 will - * close the ParcelFileDescriptor. - * - * Any negative number for offset is treated as 0. - * Any negative number for length is treated as maximum length of the data source. - * - * @param pfd the ParcelFileDescriptor for the file to play - * @param offset the offset into the file where the data to be played starts, in bytes - * @param length the length in bytes of the data to be played - * @return the same Builder instance. - * @throws NullPointerException if pfd is null. - */ - public @NonNull Builder setDataSource( - @NonNull ParcelFileDescriptor pfd, long offset, long length) { - Media2Utils.checkArgument(pfd != null, "pfd cannot be null."); - if (offset < 0) { - offset = 0; - } - if (length < 0) { - length = FD_LENGTH_UNKNOWN; - } - resetDataSource(); - mPFD = pfd; - mOffset = offset; - mLength = length; - return this; - } - - private void resetDataSource() { - mPFD = null; - mOffset = 0; - mLength = FD_LENGTH_UNKNOWN; - } - } } diff --git a/media/apex/java/android/media/MediaController2.java b/media/apex/java/android/media/MediaController2.java index 2743a34d3f552db3cb157530ea6793f42d1cbe4f..1e8438ec9fe87e5fc66dcfeaaf00078bc67f241f 100644 --- a/media/apex/java/android/media/MediaController2.java +++ b/media/apex/java/android/media/MediaController2.java @@ -22,8 +22,8 @@ import static android.media.MediaConstants.KEY_PID; import static android.media.MediaConstants.KEY_PLAYBACK_ACTIVE; import static android.media.MediaConstants.KEY_SESSION2LINK; import static android.media.MediaConstants.KEY_TOKEN_EXTRAS; -import static android.media.Session2Command.RESULT_ERROR_UNKNOWN_ERROR; -import static android.media.Session2Command.RESULT_INFO_SKIPPED; +import static android.media.Session2Command.Result.RESULT_ERROR_UNKNOWN_ERROR; +import static android.media.Session2Command.Result.RESULT_INFO_SKIPPED; import static android.media.Session2Token.TYPE_SESSION; import android.annotation.NonNull; @@ -329,7 +329,7 @@ public class MediaController2 implements AutoCloseable { MediaController2.this, command, args); if (resultReceiver != null) { if (result == null) { - resultReceiver.send(Session2Command.RESULT_INFO_SKIPPED, null); + resultReceiver.send(RESULT_INFO_SKIPPED, null); } else { resultReceiver.send(result.getResultCode(), result.getResultData()); } diff --git a/media/apex/java/android/media/MediaPlayer2.java b/media/apex/java/android/media/MediaPlayer2.java index fbe184bf144f20e8e8be89606a5598b3820cc92b..19bb2586af35ed78aa8ccfafb69363d0a45e856d 100644 --- a/media/apex/java/android/media/MediaPlayer2.java +++ b/media/apex/java/android/media/MediaPlayer2.java @@ -274,8 +274,7 @@ import java.util.concurrent.atomic.AtomicLong; * successful transition. Any other value will be an error. Call {@link #getState()} to * determine the current state.

*/ -public class MediaPlayer2 implements AutoCloseable - , AudioRouting { +public class MediaPlayer2 implements AutoCloseable, AudioRouting { static { System.loadLibrary("media2_jni"); native_init(); @@ -879,27 +878,32 @@ public class MediaPlayer2 implements AutoCloseable throws IOException { Media2Utils.checkArgument(dsd != null, "the DataSourceDesc cannot be null"); - if (dsd instanceof CallbackDataSourceDesc) { - CallbackDataSourceDesc cbDSD = (CallbackDataSourceDesc) dsd; - handleDataSource(isCurrent, - srcId, - cbDSD.getDataSourceCallback(), - cbDSD.getStartPosition(), - cbDSD.getEndPosition()); - } else if (dsd instanceof FileDataSourceDesc) { + if (dsd instanceof FileDataSourceDesc) { FileDataSourceDesc fileDSD = (FileDataSourceDesc) dsd; - handleDataSource(isCurrent, - srcId, - fileDSD.getParcelFileDescriptor(), - fileDSD.getOffset(), - fileDSD.getLength(), - fileDSD.getStartPosition(), - fileDSD.getEndPosition()); + ParcelFileDescriptor pfd = fileDSD.getParcelFileDescriptor(); + if (pfd.getStatSize() == -1) { + // Underlying pipeline doesn't understand '-1' size. Create a wrapper for + // translation. + // TODO: Make native code handle '-1' size. + handleDataSource(isCurrent, + srcId, + new ProxyDataSourceCallback(pfd), + fileDSD.getStartPosition(), + fileDSD.getEndPosition()); + } else { + handleDataSource(isCurrent, + srcId, + pfd, + fileDSD.getOffset(), + fileDSD.getLength(), + fileDSD.getStartPosition(), + fileDSD.getEndPosition()); + } } else if (dsd instanceof UriDataSourceDesc) { UriDataSourceDesc uriDSD = (UriDataSourceDesc) dsd; handleDataSource(isCurrent, srcId, - uriDSD.getContext(), + mContext, uriDSD.getUri(), uriDSD.getHeaders(), uriDSD.getCookies(), @@ -1810,12 +1814,10 @@ public class MediaPlayer2 implements AutoCloseable public MediaTimestamp getTimestamp() { try { // TODO: get the timestamp from native side - return new MediaTimestamp.Builder() - .setMediaTimestamp( - getCurrentPosition() * 1000L, - System.nanoTime(), - getState() == PLAYER_STATE_PLAYING ? getPlaybackParams().getSpeed() : 0.f) - .build(); + return new MediaTimestamp( + getCurrentPosition() * 1000L, + System.nanoTime(), + getState() == PLAYER_STATE_PLAYING ? getPlaybackParams().getSpeed() : 0.f); } catch (IllegalStateException e) { return null; } @@ -1965,6 +1967,17 @@ public class MediaPlayer2 implements AutoCloseable private native byte[] native_invoke(byte[] request); + /** + * @hide + */ + @IntDef(flag = false, prefix = "MEDIA_TRACK_TYPE", value = { + TrackInfo.MEDIA_TRACK_TYPE_VIDEO, + TrackInfo.MEDIA_TRACK_TYPE_AUDIO, + TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE + }) + @Retention(RetentionPolicy.SOURCE) + public @interface TrackType {} + /** * Class for MediaPlayer2 to return each audio/video/subtitle track's metadata. * @@ -2012,10 +2025,11 @@ public class MediaPlayer2 implements AutoCloseable public static final int MEDIA_TRACK_TYPE_SUBTITLE = 4; public static final int MEDIA_TRACK_TYPE_METADATA = 5; + final int mId; final int mTrackType; final MediaFormat mFormat; - static TrackInfo create(Iterator in) { + static TrackInfo create(int idx, Iterator in) { int trackType = in.next().getInt32Value(); // TODO: build the full MediaFormat; currently we are using createSubtitleFormat // even for audio/video tracks, meaning we only set the mime and language. @@ -2028,11 +2042,12 @@ public class MediaPlayer2 implements AutoCloseable format.setInteger(MediaFormat.KEY_IS_DEFAULT, in.next().getInt32Value()); format.setInteger(MediaFormat.KEY_IS_FORCED_SUBTITLE, in.next().getInt32Value()); } - return new TrackInfo(trackType, format); + return new TrackInfo(idx, trackType, format); } /** @hide */ - TrackInfo(int type, MediaFormat format) { + TrackInfo(int id, int type, MediaFormat format) { + mId = id; mTrackType = type; mFormat = format; } @@ -2119,7 +2134,7 @@ public class MediaPlayer2 implements AutoCloseable } TrackInfo[] trackInfo = new TrackInfo[size]; for (int i = 0; i < size; ++i) { - trackInfo[i] = TrackInfo.create(in); + trackInfo[i] = TrackInfo.create(i, in); } return trackInfo; } @@ -2127,54 +2142,56 @@ public class MediaPlayer2 implements AutoCloseable /** * Returns the index of the audio, video, or subtitle track currently selected for playback. * The return value is an index into the array returned by {@link #getTrackInfo}, and can - * be used in calls to {@link #selectTrack(int)} or {@link #deselectTrack(int)}. + * be used in calls to {@link #selectTrack(TrackInfo)} or {@link #deselectTrack(TrackInfo)}. * Same as {@link #getSelectedTrack(DataSourceDesc, int)} with * {@code dsd = getCurrentDataSource()}. * * @param trackType should be one of {@link TrackInfo#MEDIA_TRACK_TYPE_VIDEO}, * {@link TrackInfo#MEDIA_TRACK_TYPE_AUDIO}, or * {@link TrackInfo#MEDIA_TRACK_TYPE_SUBTITLE} - * @return index of the audio, video, or subtitle track currently selected for playback; - * a negative integer is returned when there is no selected track for {@code trackType} or + * @return metadata corresponding to the audio, video, or subtitle track currently selected for + * playback; {@code null} is returned when there is no selected track for {@code trackType} or * when {@code trackType} is not one of audio, video, or subtitle. * @throws IllegalStateException if called after {@link #close()} * @throws NullPointerException if current data source is null * * @see #getTrackInfo() - * @see #selectTrack(int) - * @see #deselectTrack(int) + * @see #selectTrack(TrackInfo) + * @see #deselectTrack(TrackInfo) */ - public int getSelectedTrack(int trackType) { + @Nullable + public TrackInfo getSelectedTrack(@TrackType int trackType) { return getSelectedTrack(getCurrentDataSource(), trackType); } /** * Returns the index of the audio, video, or subtitle track currently selected for playback. * The return value is an index into the array returned by {@link #getTrackInfo}, and can - * be used in calls to {@link #selectTrack(DataSourceDesc, int)} or - * {@link #deselectTrack(DataSourceDesc, int)}. + * be used in calls to {@link #selectTrack(DataSourceDesc, TrackInfo)} or + * {@link #deselectTrack(DataSourceDesc, TrackInfo)}. * * @param dsd the descriptor of data source of which you want to get selected track * @param trackType should be one of {@link TrackInfo#MEDIA_TRACK_TYPE_VIDEO}, * {@link TrackInfo#MEDIA_TRACK_TYPE_AUDIO}, or * {@link TrackInfo#MEDIA_TRACK_TYPE_SUBTITLE} - * @return index of the audio, video, or subtitle track currently selected for playback; - * a negative integer is returned when there is no selected track for {@code trackType} or + * @return metadata corresponding to the audio, video, or subtitle track currently selected for + * playback; {@code null} is returned when there is no selected track for {@code trackType} or * when {@code trackType} is not one of audio, video, or subtitle. * @throws IllegalStateException if called after {@link #close()} * @throws NullPointerException if dsd is null * * @see #getTrackInfo(DataSourceDesc) - * @see #selectTrack(DataSourceDesc, int) - * @see #deselectTrack(DataSourceDesc, int) + * @see #selectTrack(DataSourceDesc, TrackInfo) + * @see #deselectTrack(DataSourceDesc, TrackInfo) */ - public int getSelectedTrack(@NonNull DataSourceDesc dsd, int trackType) { + @Nullable + public TrackInfo getSelectedTrack(@NonNull DataSourceDesc dsd, @TrackType int trackType) { if (dsd == null) { throw new NullPointerException("non-null dsd is expected"); } SourceInfo sourceInfo = getSourceInfo(dsd); if (sourceInfo == null) { - return -1; + return null; } PlayerMessage request = PlayerMessage.newBuilder() @@ -2184,26 +2201,30 @@ public class MediaPlayer2 implements AutoCloseable .build(); PlayerMessage response = invoke(request); if (response == null) { - return -1; + return null; } - return response.getValues(0).getInt32Value(); + // TODO: return full TrackInfo data from native player instead of index + final int idx = response.getValues(0).getInt32Value(); + final List trackInfos = getTrackInfo(dsd); + return trackInfos.isEmpty() ? null : trackInfos.get(idx); } /** * Selects a track of current data source. - * Same as {@link #selectTrack(DataSourceDesc, int)} with + * Same as {@link #selectTrack(DataSourceDesc, TrackInfo)} with * {@code dsd = getCurrentDataSource()}. * - * @param index the index of the track to be selected. The valid range of the index - * is 0..total number of track - 1. The total number of tracks as well as the type of - * each individual track can be found by calling {@link #getTrackInfo()} method. + * @param trackInfo metadata corresponding to the track to be selected. A {@code trackInfo} + * object can be obtained from {@link #getTrackInfo()}. * @return a token which can be used to cancel the operation later with {@link #cancelCommand}. * + * This is an asynchronous call. + * * @see MediaPlayer2#getTrackInfo() */ - // This is an asynchronous call. - public @NonNull Object selectTrack(int index) { - return selectTrack(getCurrentDataSource(), index); + @NonNull + public Object selectTrack(@NonNull TrackInfo trackInfo) { + return selectTrack(getCurrentDataSource(), trackInfo); } /** @@ -2228,38 +2249,40 @@ public class MediaPlayer2 implements AutoCloseable * in that an audio track can only be selected in the Prepared state. *

* @param dsd the descriptor of data source of which you want to select track - * @param index the index of the track to be selected. The valid range of the index - * is 0..total number of track - 1. The total number of tracks as well as the type of - * each individual track can be found by calling {@link #getTrackInfo(DataSourceDesc)} method. + * @param trackInfo metadata corresponding to the track to be selected. A {@code trackInfo} + * object can be obtained from {@link #getTrackInfo()}. * @return a token which can be used to cancel the operation later with {@link #cancelCommand}. * + * This is an asynchronous call. + * * @see MediaPlayer2#getTrackInfo(DataSourceDesc) */ - // This is an asynchronous call. - public @NonNull Object selectTrack(@NonNull DataSourceDesc dsd, int index) { + @NonNull + public Object selectTrack(@NonNull DataSourceDesc dsd, @NonNull TrackInfo trackInfo) { return addTask(new Task(CALL_COMPLETED_SELECT_TRACK, false) { @Override void process() { - selectOrDeselectTrack(dsd, index, true /* select */); + selectOrDeselectTrack(dsd, trackInfo.mId, true /* select */); } }); } /** * Deselect a track of current data source. - * Same as {@link #deselectTrack(DataSourceDesc, int)} with + * Same as {@link #deselectTrack(DataSourceDesc, TrackInfo)} with * {@code dsd = getCurrentDataSource()}. * - * @param index the index of the track to be deselected. The valid range of the index - * is 0..total number of tracks - 1. The total number of tracks as well as the type of - * each individual track can be found by calling {@link #getTrackInfo()} method. + * @param trackInfo metadata corresponding to the track to be selected. A {@code trackInfo} + * object can be obtained from {@link #getTrackInfo()}. * @return a token which can be used to cancel the operation later with {@link #cancelCommand}. * + * This is an asynchronous call. + * * @see MediaPlayer2#getTrackInfo() */ - // This is an asynchronous call. - public @NonNull Object deselectTrack(int index) { - return deselectTrack(getCurrentDataSource(), index); + @NonNull + public Object deselectTrack(@NonNull TrackInfo trackInfo) { + return deselectTrack(getCurrentDataSource(), trackInfo); } /** @@ -2270,19 +2293,20 @@ public class MediaPlayer2 implements AutoCloseable * selected before, it throws an exception. *

* @param dsd the descriptor of data source of which you want to deselect track - * @param index the index of the track to be deselected. The valid range of the index - * is 0..total number of tracks - 1. The total number of tracks as well as the type of - * each individual track can be found by calling {@link #getTrackInfo} method. + * @param trackInfo metadata corresponding to the track to be selected. A {@code trackInfo} + * object can be obtained from {@link #getTrackInfo()}. * @return a token which can be used to cancel the operation later with {@link #cancelCommand}. * + * This is an asynchronous call. + * * @see MediaPlayer2#getTrackInfo(DataSourceDesc) */ - // This is an asynchronous call. - public @NonNull Object deselectTrack(@NonNull DataSourceDesc dsd, int index) { + @NonNull + public Object deselectTrack(@NonNull DataSourceDesc dsd, @NonNull TrackInfo trackInfo) { return addTask(new Task(CALL_COMPLETED_DESELECT_TRACK, false) { @Override void process() { - selectOrDeselectTrack(dsd, index, false /* select */); + selectOrDeselectTrack(dsd, trackInfo.mId, false /* select */); } }); } @@ -2643,13 +2667,13 @@ public class MediaPlayer2 implements AutoCloseable return; } Iterator in = playerMsg.getValuesList().iterator(); - SubtitleData data = new SubtitleData.Builder() - .setSubtitleData( - in.next().getInt32Value(), // trackIndex - in.next().getInt64Value(), // startTimeUs - in.next().getInt64Value(), // durationUs - in.next().getBytesValue().toByteArray()) // data - .build(); + final int trackIndex = in.next().getInt32Value(); + TrackInfo trackInfo = getTrackInfo(dsd).get(trackIndex); + final long startTimeUs = in.next().getInt64Value(); + final long durationTimeUs = in.next().getInt64Value(); + final byte[] subData = in.next().getBytesValue().toByteArray(); + SubtitleData data = new SubtitleData(trackInfo, + startTimeUs, durationTimeUs, subData); sendEvent(new EventNotifier() { @Override public void notify(EventCallback callback) { @@ -2673,11 +2697,9 @@ public class MediaPlayer2 implements AutoCloseable return; } Iterator in = playerMsg.getValuesList().iterator(); - data = new TimedMetaData.Builder() - .setTimedMetaData( - in.next().getInt64Value(), // timestampUs - in.next().getBytesValue().toByteArray()) // metaData - .build(); + data = new TimedMetaData( + in.next().getInt64Value(), // timestampUs + in.next().getBytesValue().toByteArray()); // metaData } else { data = null; } @@ -2771,6 +2793,74 @@ public class MediaPlayer2 implements AutoCloseable } } + /** + * Class encapsulating subtitle data, as received through the + * {@link EventCallback#onSubtitleData} interface. + *

+ * A {@link SubtitleData} object includes: + *

    + *
  • track metadadta in a {@link TrackInfo} object
  • + *
  • the start time (in microseconds) of the data
  • + *
  • the duration (in microseconds) of the data
  • + *
  • the actual data.
  • + *
+ * The data is stored in a byte-array, and is encoded in one of the supported in-band + * subtitle formats. The subtitle encoding is determined by the MIME type of the + * {@link TrackInfo} of the subtitle track, one of + * {@link MediaFormat#MIMETYPE_TEXT_CEA_608}, {@link MediaFormat#MIMETYPE_TEXT_CEA_708}, + * {@link MediaFormat#MIMETYPE_TEXT_VTT}. + */ + public static final class SubtitleData { + + private TrackInfo mTrackInfo; + private long mStartTimeUs; + private long mDurationUs; + private byte[] mData; + + private SubtitleData(TrackInfo trackInfo, long startTimeUs, long durationUs, byte[] data) { + mTrackInfo = trackInfo; + mStartTimeUs = startTimeUs; + mDurationUs = durationUs; + mData = (data != null ? data : new byte[0]); + } + + /** + * @return metadata of track which contains this subtitle data + */ + @NonNull + public TrackInfo getTrackInfo() { + return mTrackInfo; + } + + /** + * @return media time at which the subtitle should start to be displayed in microseconds + */ + public long getStartTimeUs() { + return mStartTimeUs; + } + + /** + * @return the duration in microsecond during which the subtitle should be displayed + */ + public long getDurationUs() { + return mDurationUs; + } + + /** + * Returns the encoded data for the subtitle content. + * Encoding format depends on the subtitle type, refer to + * CEA 708, + * CEA/EIA 608 and + * WebVTT, defined by the MIME type + * of the subtitle track. + * @return the encoded subtitle data + */ + @NonNull + public byte[] getData() { + return mData; + } + } + /** * Interface definition for callbacks to be invoked when the player has the corresponding * events. @@ -3446,10 +3536,18 @@ public class MediaPlayer2 implements AutoCloseable /** * Mutable builder to create a {@link MediaPlayer2.DrmPreparationInfo} object. + * + * {@link Builder#Builder(UUID) UUID} must not be null; {@link #setKeyType keyType} + * must be one of {@link MediaDrm#KEY_TYPE_STREAMING} or {@link MediaDrm#KEY_TYPE_OFFLINE}. + *

+ * When {@link #setKeyType keyType} is {@link MediaDrm#KEY_TYPE_STREAMING}, + * {@link #setInitData(byte[]) initData} and {@link #setMimeType(String) mimeType} + * must not be null; When {@link #setKeyType keyType} is {@link MediaDrm#KEY_TYPE_OFFLINE}, + * {@link #setKeySetId(byte[]) keySetId} must not be null. */ public static final class Builder { - private UUID mUUID; + private final UUID mUUID; private byte[] mKeySetId; private byte[] mInitData; private String mMimeType; @@ -3457,15 +3555,11 @@ public class MediaPlayer2 implements AutoCloseable private Map mOptionalParameters; /** - * Set UUID of the crypto scheme selected to decrypt content. An UUID can be retrieved - * from the source listening to {@link MediaPlayer2.DrmEventCallback#onDrmInfo}. - * - * @param uuid of selected crypto scheme - * @return this + * @param uuid UUID of the crypto scheme selected to decrypt content. An UUID can be + * retrieved from the source listening to {@link DrmEventCallback#onDrmInfo}. */ - public @NonNull Builder setUuid(@NonNull UUID uuid) { + public Builder(@NonNull UUID uuid) { this.mUUID = uuid; - return this; } /** @@ -3538,12 +3632,16 @@ public class MediaPlayer2 implements AutoCloseable } /** - * @return an immutable {@link MediaPlayer2.DrmPreparationInfo} representing the - * settings of this builder + * @return an immutable {@link DrmPreparationInfo} based on settings of this builder */ - public @NonNull MediaPlayer2.DrmPreparationInfo build() { - return new MediaPlayer2.DrmPreparationInfo(mUUID, mKeySetId, mInitData, mMimeType, - mKeyType, mOptionalParameters); + @NonNull + public DrmPreparationInfo build() { + final DrmPreparationInfo info = new DrmPreparationInfo(mUUID, mKeySetId, mInitData, + mMimeType, mKeyType, mOptionalParameters); + if (!info.isValid()) { + throw new IllegalArgumentException("invalid DrmPreparationInfo"); + } + return info; } } @@ -3579,13 +3677,61 @@ public class MediaPlayer2 implements AutoCloseable } return false; } + + /** + * @return UUID of the crypto scheme selected to decrypt content. + */ + @NonNull + public UUID getUuid() { + return mUUID; + } + + /** + * @return identifier of the persisted offline key. + */ + @Nullable + public byte[] getKeySetId() { + return mKeySetId; + } + + /** + * @return container-specific DRM initialization data. + */ + @Nullable + public byte[] getInitData() { + return mInitData; + } + + /** + * @return mime type of the content + */ + @Nullable + public String getMimeType() { + return mMimeType; + } + + /** + * @return type of the key request. + */ + @MediaPlayer2.MediaDrmKeyType + public int getKeyType() { + return mKeyType; + } + + /** + * @return optional parameters to be included in the {@link MediaDrm.KeyRequest}. + */ + @Nullable + public Map getOptionalParameters() { + return mOptionalParameters; + } } /** * Interface definition for callbacks to be invoked when the player has the corresponding * DRM events. */ - public static class DrmEventCallback { + public static abstract class DrmEventCallback { /** * Called to indicate DRM info is available. Return a {@link DrmPreparationInfo} object that @@ -3598,10 +3744,9 @@ public class MediaPlayer2 implements AutoCloseable * @return a {@link DrmPreparationInfo} object to initialize DRM playback, or null to skip * DRM initialization */ - public @Nullable DrmPreparationInfo onDrmInfo(@NonNull MediaPlayer2 mp, - @NonNull DataSourceDesc dsd, @NonNull DrmInfo drmInfo) { - return null; - } + @Nullable + public abstract DrmPreparationInfo onDrmInfo(@NonNull MediaPlayer2 mp, + @NonNull DataSourceDesc dsd, @NonNull DrmInfo drmInfo); /** * Called to give the app the opportunity to configure DRM before the session is created. @@ -3636,10 +3781,9 @@ public class MediaPlayer2 implements AutoCloseable * throwing an {@link RuntimeException} from this callback would trigger an * {@link EventCallback#onError}. */ - public @NonNull byte[] onDrmKeyRequest(@NonNull MediaPlayer2 mp, - @NonNull DataSourceDesc dsd, @NonNull MediaDrm.KeyRequest request) { - return new byte[0]; - } + @NonNull + public abstract byte[] onDrmKeyRequest(@NonNull MediaPlayer2 mp, + @NonNull DataSourceDesc dsd, @NonNull MediaDrm.KeyRequest request); /** * Called to notify the client that {@code mp} is ready to decrypt DRM protected data source @@ -3664,10 +3808,11 @@ public class MediaPlayer2 implements AutoCloseable /** * Registers the callback to be invoked for various DRM events. * + * This is a synchronous call. + * * @param eventCallback the callback that will be run * @param executor the executor through which the callback should be invoked */ - // This is a synchronous call. public void setDrmEventCallback(@NonNull @CallbackExecutor Executor executor, @NonNull DrmEventCallback eventCallback) { if (eventCallback == null) { @@ -3684,8 +3829,9 @@ public class MediaPlayer2 implements AutoCloseable /** * Clear the {@link DrmEventCallback}. + * + * This is a synchronous call. */ - // This is a synchronous call. public void clearDrmEventCallback() { synchronized (mDrmEventCallbackLock) { mDrmEventCallback = null; diff --git a/media/apex/java/android/media/MediaPlayer2Utils.java b/media/apex/java/android/media/MediaPlayer2Utils.java index c6dee22813a063cc738c9110d004e07ba4d290a5..ac34260f9bcf0db6708a6aa8d5ffaf43f3768e22 100644 --- a/media/apex/java/android/media/MediaPlayer2Utils.java +++ b/media/apex/java/android/media/MediaPlayer2Utils.java @@ -36,6 +36,8 @@ public class MediaPlayer2Utils { .setSampleRate(sampleRate) .setChannelMask(channelMask) .build(); - return AudioManager.isOffloadedPlaybackSupported(format); + //TODO MP2 needs to pass AudioAttributes for this query, instead of using default attr + return AudioManager.isOffloadedPlaybackSupported(format, + (new AudioAttributes.Builder()).build()); } } diff --git a/media/apex/java/android/media/MediaSession2.java b/media/apex/java/android/media/MediaSession2.java index d63de098eceefdf820dcaf6c014d1bf6c9fe34ed..a900d87450067cb80f73ef7c8d6ef2e7731fbc22 100644 --- a/media/apex/java/android/media/MediaSession2.java +++ b/media/apex/java/android/media/MediaSession2.java @@ -22,8 +22,8 @@ import static android.media.MediaConstants.KEY_PID; import static android.media.MediaConstants.KEY_PLAYBACK_ACTIVE; import static android.media.MediaConstants.KEY_SESSION2LINK; import static android.media.MediaConstants.KEY_TOKEN_EXTRAS; -import static android.media.Session2Command.RESULT_ERROR_UNKNOWN_ERROR; -import static android.media.Session2Command.RESULT_INFO_SKIPPED; +import static android.media.Session2Command.Result.RESULT_ERROR_UNKNOWN_ERROR; +import static android.media.Session2Command.Result.RESULT_INFO_SKIPPED; import static android.media.Session2Token.TYPE_SESSION; import android.annotation.NonNull; @@ -415,7 +415,7 @@ public class MediaSession2 implements AutoCloseable { MediaSession2.this, controllerInfo, command, args); if (resultReceiver != null) { if (result == null) { - resultReceiver.send(Session2Command.RESULT_INFO_SKIPPED, null); + resultReceiver.send(RESULT_INFO_SKIPPED, null); } else { resultReceiver.send(result.getResultCode(), result.getResultData()); } diff --git a/media/apex/java/android/media/ProxyDataSourceCallback.java b/media/apex/java/android/media/ProxyDataSourceCallback.java new file mode 100644 index 0000000000000000000000000000000000000000..14d3ce87f03df114a79637292f84a8ac0b71c90b --- /dev/null +++ b/media/apex/java/android/media/ProxyDataSourceCallback.java @@ -0,0 +1,68 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.media; + +import android.os.ParcelFileDescriptor; +import android.system.ErrnoException; +import android.system.Os; +import android.system.OsConstants; +import android.util.Log; + +import java.io.FileDescriptor; +import java.io.IOException; + +/** + * A DataSourceCallback that is backed by a ParcelFileDescriptor. + */ +class ProxyDataSourceCallback extends DataSourceCallback { + private static final String TAG = "TestDataSourceCallback"; + + ParcelFileDescriptor mPFD; + FileDescriptor mFD; + + ProxyDataSourceCallback(ParcelFileDescriptor pfd) throws IOException { + mPFD = pfd.dup(); + mFD = mPFD.getFileDescriptor(); + } + + @Override + public synchronized int readAt(long position, byte[] buffer, int offset, int size) + throws IOException { + try { + Os.lseek(mFD, position, OsConstants.SEEK_SET); + int ret = Os.read(mFD, buffer, offset, size); + return (ret == 0) ? END_OF_STREAM : ret; + } catch (ErrnoException e) { + throw new IOException(e); + } + } + + @Override + public synchronized long getSize() throws IOException { + return mPFD.getStatSize(); + } + + @Override + public synchronized void close() { + try { + mPFD.close(); + } catch (IOException e) { + Log.e(TAG, "Failed to close the PFD.", e); + } + } +} + diff --git a/media/apex/java/android/media/Session2Command.java b/media/apex/java/android/media/Session2Command.java index 6822ea56b5e82bb3fbfd0c2bb9581d324481cca2..7f73dc12306364982b96bbd2ead492f0e148b456 100644 --- a/media/apex/java/android/media/Session2Command.java +++ b/media/apex/java/android/media/Session2Command.java @@ -48,22 +48,6 @@ public final class Session2Command implements Parcelable { */ public static final int COMMAND_CODE_CUSTOM = 0; - /** - * Result code representing that the command is skipped or canceled. For an example, a seek - * command can be skipped if it is followed by another seek command. - */ - public static final int RESULT_INFO_SKIPPED = 1; - - /** - * Result code representing that the command is successfully completed. - */ - public static final int RESULT_SUCCESS = 0; - - /** - * Result code represents that call is ended with an unknown error. - */ - public static final int RESULT_ERROR_UNKNOWN_ERROR = -1; - public static final @android.annotation.NonNull Parcelable.Creator CREATOR = new Parcelable.Creator() { @Override @@ -184,6 +168,22 @@ public final class Session2Command implements Parcelable { private final int mResultCode; private final Bundle mResultData; + /** + * Result code representing that the command is skipped or canceled. For an example, a seek + * command can be skipped if it is followed by another seek command. + */ + public static final int RESULT_INFO_SKIPPED = 1; + + /** + * Result code representing that the command is successfully completed. + */ + public static final int RESULT_SUCCESS = 0; + + /** + * Result code represents that call is ended with an unknown error. + */ + public static final int RESULT_ERROR_UNKNOWN_ERROR = -1; + /** * Constructor of {@link Result}. * diff --git a/media/apex/java/android/media/Session2CommandGroup.java b/media/apex/java/android/media/Session2CommandGroup.java index 73a59d00ae344e1a6bdaea8469dd48c4256f460f..06ae8737fdc07ae8561e5d59b321b0baacb4a7b3 100644 --- a/media/apex/java/android/media/Session2CommandGroup.java +++ b/media/apex/java/android/media/Session2CommandGroup.java @@ -166,22 +166,6 @@ public final class Session2CommandGroup implements Parcelable { return this; } - /** - * Adds a predefined command with given {@code commandCode} to this command group. - * - * @param commandCode A command code to add. - * Shouldn't be {@link Session2Command#COMMAND_CODE_CUSTOM}. - */ - @NonNull - public Builder addCommand(int commandCode) { - if (commandCode == COMMAND_CODE_CUSTOM) { - throw new IllegalArgumentException( - "Use addCommand(Session2Command) for COMMAND_CODE_CUSTOM."); - } - mCommands.add(new Session2Command(commandCode)); - return this; - } - /** * Removes a command from this group which matches given {@code command}. * @@ -196,21 +180,6 @@ public final class Session2CommandGroup implements Parcelable { return this; } - /** - * Removes a command from this group which matches given {@code commandCode}. - * - * @param commandCode A command code to find. - * Shouldn't be {@link Session2Command#COMMAND_CODE_CUSTOM}. - */ - @NonNull - public Builder removeCommand(int commandCode) { - if (commandCode == COMMAND_CODE_CUSTOM) { - throw new IllegalArgumentException("commandCode shouldn't be COMMAND_CODE_CUSTOM"); - } - mCommands.remove(new Session2Command(commandCode)); - return this; - } - /** * Builds {@link Session2CommandGroup}. * diff --git a/media/apex/java/android/media/UriDataSourceDesc.java b/media/apex/java/android/media/UriDataSourceDesc.java index c0b3c825323caac4978922cfeaa0ba56ff896833..eaedf1e377e2e1d822e495095a42280466f75f72 100644 --- a/media/apex/java/android/media/UriDataSourceDesc.java +++ b/media/apex/java/android/media/UriDataSourceDesc.java @@ -18,11 +18,9 @@ package android.media; import android.annotation.NonNull; import android.annotation.Nullable; -import android.content.Context; +import android.annotation.TestApi; import android.net.Uri; -import java.net.CookieHandler; -import java.net.CookieManager; import java.net.HttpCookie; import java.util.ArrayList; import java.util.HashMap; @@ -36,15 +34,20 @@ import java.util.Map; * {@link MediaPlayer2#setNextDataSources} to set data source for playback. * *

Users should use {@link Builder} to change {@link UriDataSourceDesc}. - * + * @hide */ +@TestApi public class UriDataSourceDesc extends DataSourceDesc { private Uri mUri; private Map mHeader; private List mCookies; - private Context mContext; - private UriDataSourceDesc() { + UriDataSourceDesc(String mediaId, long startPositionMs, long endPositionMs, + Uri uri, Map header, List cookies) { + super(mediaId, startPositionMs, endPositionMs); + mUri = uri; + mHeader = header; + mCookies = cookies; } /** @@ -76,155 +79,4 @@ public class UriDataSourceDesc extends DataSourceDesc { } return new ArrayList(mCookies); } - - /** - * Return the Context used for resolving the Uri of this data source. - * @return the Context used for resolving the Uri of this data source - */ - public @NonNull Context getContext() { - return mContext; - } - - /** - * Builder class for {@link UriDataSourceDesc} objects. - *

Here is an example where Builder is used to define the - * {@link UriDataSourceDesc} to be used by a {@link MediaPlayer2} instance: - * - *

-     * UriDataSourceDesc newDSD = new UriDataSourceDesc.Builder()
-     *         .setDataSource(context, uri, headers, cookies)
-     *         .setStartPosition(1000)
-     *         .setEndPosition(15000)
-     *         .build();
-     * mediaplayer2.setDataSourceDesc(newDSD);
-     * 
- */ - public static class Builder extends BuilderBase { - private Uri mUri; - private Map mHeader; - private List mCookies; - private Context mContext; - - /** - * Constructs a new Builder with the defaults. - */ - public Builder() { - super(); - } - - /** - * Constructs a new Builder from a given {@link UriDataSourceDesc} instance - * @param dsd the {@link UriDataSourceDesc} object whose data will be reused - * in the new Builder. - */ - public Builder(@Nullable UriDataSourceDesc dsd) { - super(dsd); - if (dsd == null) { - return; // use default - } - mUri = dsd.mUri; - mHeader = dsd.mHeader; - mCookies = dsd.mCookies; - mContext = dsd.mContext; - } - - /** - * Combines all of the fields that have been set and return a new - * {@link UriDataSourceDesc} object. IllegalStateException will be - * thrown if there is conflict between fields. - * - * @return a new {@link UriDataSourceDesc} object - */ - public @NonNull UriDataSourceDesc build() { - if (mUri == null || mContext == null) { - throw new IllegalStateException( - "Uri and Context should not be null"); - } - - UriDataSourceDesc dsd = new UriDataSourceDesc(); - super.build(dsd); - dsd.mUri = mUri; - dsd.mHeader = mHeader; - dsd.mCookies = mCookies; - dsd.mContext = mContext; - - return dsd; - } - - /** - * Sets the data source as a content Uri. - * - * @param context the Context to use when resolving the Uri - * @param uri the Content URI of the data you want to play - * @return the same Builder instance. - * @throws NullPointerException if context or uri is null. - */ - public @NonNull Builder setDataSource(@NonNull Context context, @NonNull Uri uri) { - Media2Utils.checkArgument(context != null, "context cannot be null"); - Media2Utils.checkArgument(uri != null, "uri cannot be null"); - resetDataSource(); - mUri = uri; - mContext = context; - return this; - } - - /** - * Sets the data source as a content Uri. - * - * To provide cookies for the subsequent HTTP requests, you can install your own default - * cookie handler and use other variants of setDataSource APIs instead. Alternatively, you - * can use this API to pass the cookies as a list of HttpCookie. If the app has not - * installed a CookieHandler already, {@link MediaPlayer2} will create a CookieManager - * and populates its CookieStore with the provided cookies when this data source is passed - * to {@link MediaPlayer2}. If the app has installed its own handler already, the handler - * is required to be of CookieManager type such that {@link MediaPlayer2} can update the - * manager’s CookieStore. - * - *

Note that the cross domain redirection is allowed by default, - * but that can be changed with key/value pairs through the headers parameter with - * "android-allow-cross-domain-redirect" as the key and "0" or "1" as the value to - * disallow or allow cross domain redirection. - * - * @param context the Context to use when resolving the Uri - * @param uri the Content URI of the data you want to play - * @param headers the headers to be sent together with the request for the data - * The headers must not include cookies. Instead, use the cookies param. - * @param cookies the cookies to be sent together with the request - * @return the same Builder instance. - * @throws NullPointerException if context or uri is null. - * @throws IllegalArgumentException if the cookie handler is not of CookieManager type - * when cookies are provided. - */ - public @NonNull Builder setDataSource(@NonNull Context context, @NonNull Uri uri, - @Nullable Map headers, @Nullable List cookies) { - Media2Utils.checkArgument(context != null, "context cannot be null"); - Media2Utils.checkArgument(uri != null, "uri cannot be null"); - if (cookies != null) { - CookieHandler cookieHandler = CookieHandler.getDefault(); - if (cookieHandler != null && !(cookieHandler instanceof CookieManager)) { - throw new IllegalArgumentException( - "The cookie handler has to be of CookieManager type " - + "when cookies are provided."); - } - } - - resetDataSource(); - mUri = uri; - if (headers != null) { - mHeader = new HashMap(headers); - } - if (cookies != null) { - mCookies = new ArrayList(cookies); - } - mContext = context; - return this; - } - - private void resetDataSource() { - mUri = null; - mHeader = null; - mCookies = null; - mContext = null; - } - } } diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index f9080a70206e970b3170bfec371fa2a19a5092cf..7cb5e00e7684d41a4789208a3dc1910a162e1fb7 100644 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -44,6 +44,7 @@ import android.media.session.MediaController; import android.media.session.MediaSession; import android.media.session.MediaSessionLegacyHelper; import android.media.session.MediaSessionManager; +import android.net.Uri; import android.os.Binder; import android.os.Build; import android.os.Handler; @@ -1488,13 +1489,18 @@ public class AudioManager { * it does not indicate whether the resources necessary for the offloaded playback are * available at that instant. * @param format the audio format (codec, sample rate, channels) being checked. + * @param attributes the {@link AudioAttributes} to be used for playback * @return true if the given audio format can be offloaded. */ - public static boolean isOffloadedPlaybackSupported(@NonNull AudioFormat format) { + public static boolean isOffloadedPlaybackSupported(@NonNull AudioFormat format, + @NonNull AudioAttributes attributes) { if (format == null) { - throw new IllegalArgumentException("Illegal null AudioFormat"); + throw new NullPointerException("Illegal null AudioFormat"); } - return AudioSystem.isOffloadSupported(format); + if (attributes == null) { + throw new NullPointerException("Illegal null AudioAttributes"); + } + return AudioSystem.isOffloadSupported(format, attributes); } //==================================================================== @@ -3307,7 +3313,8 @@ public class AudioManager { try { MediaProjection projection = policy.getMediaProjection(); String regId = service.registerAudioPolicy(policy.getConfig(), policy.cb(), - policy.hasFocusListener(), policy.isFocusPolicy(), policy.isVolumeController(), + policy.hasFocusListener(), policy.isFocusPolicy(), policy.isTestFocusPolicy(), + policy.isVolumeController(), projection == null ? null : projection.getProjection()); if (regId == null) { return ERROR; @@ -5441,6 +5448,20 @@ public class AudioManager { sAudioAudioVolumeGroupChangedHandler.unregisterListener(callback); } + /** + * Return if an asset contains haptic channels or not. + * @param uri the {@link Uri} of the asset. + * @return true if the assert contains haptic channels. + * @hide + */ + public static boolean hasHapticChannels(Uri uri) { + try { + return getService().hasHapticChannels(uri); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + //--------------------------------------------------------- // Inner classes //-------------------- diff --git a/media/java/android/media/AudioPlaybackCaptureConfiguration.java b/media/java/android/media/AudioPlaybackCaptureConfiguration.java index 333cd2d4f0cf63768f565c718c47bc444ede84a7..4aa0b903bcdf65d9e8cbe7d1f5732597cf16a534 100644 --- a/media/java/android/media/AudioPlaybackCaptureConfiguration.java +++ b/media/java/android/media/AudioPlaybackCaptureConfiguration.java @@ -17,6 +17,7 @@ package android.media; import android.annotation.NonNull; +import android.media.AudioAttributes.AttributeUsage; import android.media.audiopolicy.AudioMix; import android.media.audiopolicy.AudioMixingRule; import android.media.projection.MediaProjection; @@ -41,12 +42,9 @@ import com.android.internal.util.Preconditions; *

  *     MediaProjection mediaProjection;
  *     // Retrieve a audio capable projection from the MediaProjectionManager
- *     AudioAttributes mediaAttr = new AudioAttributes.Builder()
- *         .setUsage(AudioAttributes.USAGE_MEDIA)
- *         .build();
  *     AudioPlaybackCaptureConfiguration config =
  *              new AudioPlaybackCaptureConfiguration.Builder(mediaProjection)
- *         .addMatchingUsage(mediaAttr)
+ *         .addMatchingUsage(AudioAttributes.USAGE_MEDIA)
  *         .build();
  *     AudioRecord record = new AudioRecord.Builder()
  *         .setAudioPlaybackCaptureConfig(config)
@@ -67,6 +65,15 @@ public final class AudioPlaybackCaptureConfiguration {
         mProjection = projection;
     }
 
+    /**
+     * @return the {@code MediaProjection} used to build this object.
+     * @see {@code Builder.Builder}
+     */
+    public @NonNull MediaProjection getMediaProjection() {
+        return mProjection;
+    }
+
+
     /**
      * Returns a mix that routes audio back into the app while still playing it from the speakers.
      *
@@ -78,9 +85,6 @@ public final class AudioPlaybackCaptureConfiguration {
                 .setRouteFlags(AudioMix.ROUTE_FLAG_LOOP_BACK | AudioMix.ROUTE_FLAG_RENDER)
                 .build();
     }
-    MediaProjection getMediaProjection() {
-        return mProjection;
-    }
 
     /** Builder for creating {@link AudioPlaybackCaptureConfiguration} instances. */
     public static final class Builder {
@@ -121,14 +125,13 @@ public final class AudioPlaybackCaptureConfiguration {
          * attributes.
          *
          * @throws IllegalStateException if called in conjunction with
-         *     {@link #excludeUsage(AudioAttributes)}.
+         *     {@link #excludeUsage(int)}.
          */
-        public @NonNull Builder addMatchingUsage(@NonNull AudioAttributes audioAttributes) {
-            Preconditions.checkNotNull(audioAttributes);
+        public @NonNull Builder addMatchingUsage(@AttributeUsage int usage) {
             Preconditions.checkState(
                     mUsageMatchType != MATCH_TYPE_EXCLUSIVE, ERROR_MESSAGE_MISMATCHED_RULES);
-            mAudioMixingRuleBuilder
-                    .addRule(audioAttributes, AudioMixingRule.RULE_MATCH_ATTRIBUTE_USAGE);
+            mAudioMixingRuleBuilder.addRule(new AudioAttributes.Builder().setUsage(usage).build(),
+                                            AudioMixingRule.RULE_MATCH_ATTRIBUTE_USAGE);
             mUsageMatchType = MATCH_TYPE_INCLUSIVE;
             return this;
         }
@@ -156,14 +159,15 @@ public final class AudioPlaybackCaptureConfiguration {
          * given attributes.
          *
          * @throws IllegalStateException if called in conjunction with
-         *     {@link #addMatchingUsage(AudioAttributes)}.
+         *     {@link #addMatchingUsage(int)}.
          */
-        public @NonNull Builder excludeUsage(@NonNull AudioAttributes audioAttributes) {
-            Preconditions.checkNotNull(audioAttributes);
+        public @NonNull Builder excludeUsage(@AttributeUsage int usage) {
             Preconditions.checkState(
                     mUsageMatchType != MATCH_TYPE_INCLUSIVE, ERROR_MESSAGE_MISMATCHED_RULES);
-            mAudioMixingRuleBuilder.excludeRule(audioAttributes,
-                    AudioMixingRule.RULE_MATCH_ATTRIBUTE_USAGE);
+            mAudioMixingRuleBuilder.excludeRule(new AudioAttributes.Builder()
+                                                    .setUsage(usage)
+                                                    .build(),
+                                                AudioMixingRule.RULE_MATCH_ATTRIBUTE_USAGE);
             mUsageMatchType = MATCH_TYPE_EXCLUSIVE;
             return this;
         }
diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java
index 8051236680aacb45a57c731aae6ceb4bd36f1275..a7760a80974dd05664e63cc598fdc9f80f8389e8 100644
--- a/media/java/android/media/AudioRecord.java
+++ b/media/java/android/media/AudioRecord.java
@@ -1798,8 +1798,8 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection,
      *
      * @return true if sucessful.
      */
-    public boolean setMicrophoneDirection(@DirectionMode int direction) {
-        return native_set_microphone_direction(direction) == AudioSystem.SUCCESS;
+    public boolean setPreferredMicrophoneDirection(@DirectionMode int direction) {
+        return native_set_preferred_microphone_direction(direction) == AudioSystem.SUCCESS;
     }
 
     /**
@@ -1810,10 +1810,11 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection,
      * though 0 (no zoom) to 1 (maximum zoom).
      * @return true if sucessful.
      */
-    public boolean setMicrophoneFieldDimension(@FloatRange(from = -1.0, to = 1.0) float zoom) {
+    public boolean setPreferredMicrophoneFieldDimension(
+                            @FloatRange(from = -1.0, to = 1.0) float zoom) {
         Preconditions.checkArgument(
                 zoom >= -1 && zoom <= 1, "Argument must fall between -1 & 1 (inclusive)");
-        return native_set_microphone_field_dimension(zoom) == AudioSystem.SUCCESS;
+        return native_set_preferred_microphone_field_dimension(zoom) == AudioSystem.SUCCESS;
     }
 
     //---------------------------------------------------------
@@ -1969,8 +1970,8 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection,
 
     private native int native_getPortId();
 
-    private native int native_set_microphone_direction(int direction);
-    private native int native_set_microphone_field_dimension(float zoom);
+    private native int native_set_preferred_microphone_direction(int direction);
+    private native int native_set_preferred_microphone_field_dimension(float zoom);
 
     //---------------------------------------------------------
     // Utility methods
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index a976d707f5cbab962b7bc311cb7efea0ff2c90b0..ad255fe3d5a23b47d4ee099ebb40b006aed800ca 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -1022,13 +1022,14 @@ public class AudioSystem
 
     public static native float getStreamVolumeDB(int stream, int index, int device);
 
-    static boolean isOffloadSupported(@NonNull AudioFormat format) {
+    static boolean isOffloadSupported(@NonNull AudioFormat format, @NonNull AudioAttributes attr) {
         return native_is_offload_supported(format.getEncoding(), format.getSampleRate(),
-                format.getChannelMask(), format.getChannelIndexMask());
+                format.getChannelMask(), format.getChannelIndexMask(),
+                attr.getVolumeControlStream());
     }
 
     private static native boolean native_is_offload_supported(int encoding, int sampleRate,
-            int channelMask, int channelIndexMask);
+            int channelMask, int channelIndexMask, int streamType);
 
     public static native int getMicrophones(ArrayList microphonesInfo);
 
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index 41e059bba92de8e7ed6615ce6f97223a27658d04..325e227e6f93d21cac2363506cadd36cf2e524f6 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -914,8 +914,9 @@ public class AudioTrack extends PlayerBase
         /**
          * Sets whether this track will play through the offloaded audio path.
          * When set to true, at build time, the audio format will be checked against
-         * {@link AudioManager#isOffloadedPlaybackSupported(AudioFormat)} to verify the audio format
-         * used by this track is supported on the device's offload path (if any).
+         * {@link AudioManager#isOffloadedPlaybackSupported(AudioFormat,AudioAttributes)}
+         * to verify the audio format used by this track is supported on the device's offload
+         * path (if any).
          * 
Offload is only supported for media audio streams, and therefore requires that * the usage be {@link AudioAttributes#USAGE_MEDIA}. * @param offload true to require the offload path for playback. @@ -979,7 +980,7 @@ public class AudioTrack extends PlayerBase throw new UnsupportedOperationException( "Cannot create AudioTrack, offload requires USAGE_MEDIA"); } - if (!AudioSystem.isOffloadSupported(mFormat)) { + if (!AudioSystem.isOffloadSupported(mFormat, mAttributes)) { throw new UnsupportedOperationException( "Cannot create AudioTrack, offload format not supported"); } @@ -3177,7 +3178,8 @@ public class AudioTrack extends PlayerBase * Registers a callback for the notification of stream events. * This callback can only be registered for instances operating in offloaded mode * (see {@link AudioTrack.Builder#setOffloadedPlayback(boolean)} and - * {@link AudioManager#isOffloadedPlaybackSupported(AudioFormat)} for more details). + * {@link AudioManager#isOffloadedPlaybackSupported(AudioFormat,AudioAttributes)} for + * more details). * @param executor {@link Executor} to handle the callbacks. * @param eventCallback the callback to receive the stream event notifications. */ diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl index c29f355181f49becac263f7628fa5ed3a66beecb..980cb04598217cb6dec36120cea21ee0d565d1f9 100644 --- a/media/java/android/media/IAudioService.aidl +++ b/media/java/android/media/IAudioService.aidl @@ -37,6 +37,7 @@ import android.media.audiopolicy.AudioProductStrategies; import android.media.audiopolicy.AudioVolumeGroups; import android.media.audiopolicy.IAudioPolicyCallback; import android.media.projection.IMediaProjection; +import android.net.Uri; /** * {@hide} @@ -195,6 +196,7 @@ interface IAudioService { String registerAudioPolicy(in AudioPolicyConfig policyConfig, in IAudioPolicyCallback pcb, boolean hasFocusListener, boolean isFocusPolicy, + boolean isTestFocusPolicy, boolean isVolumeController, in IMediaProjection projection); oneway void unregisterAudioPolicyAsync(in IAudioPolicyCallback pcb); @@ -250,6 +252,8 @@ interface IAudioService { int removeUidDeviceAffinity(in IAudioPolicyCallback pcb, in int uid); + boolean hasHapticChannels(in Uri uri); + // WARNING: read warning at top of file, new methods that need to be used by native // code via IAudioManager.h need to be added to the top section. } diff --git a/media/java/android/media/session/SessionCallbackLink.aidl b/media/java/android/media/IMediaRoute2Callback.aidl similarity index 82% rename from media/java/android/media/session/SessionCallbackLink.aidl rename to media/java/android/media/IMediaRoute2Callback.aidl index c489e5bee6e204eb537fdfa0ba3117ea403c00cd..f03c8ab444c40d043b72958f805f873ee67155bb 100644 --- a/media/java/android/media/session/SessionCallbackLink.aidl +++ b/media/java/android/media/IMediaRoute2Callback.aidl @@ -13,6 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package android.media.session; -parcelable SessionCallbackLink; +package android.media; + +/** + * @hide + */ +oneway interface IMediaRoute2Callback { + void onRouteSelected(int uid, String routeId); +} diff --git a/tools/processors/view_inspector/src/java/android/processor/view/inspector/ModelProcessor.java b/media/java/android/media/IMediaRoute2Provider.aidl similarity index 53% rename from tools/processors/view_inspector/src/java/android/processor/view/inspector/ModelProcessor.java rename to media/java/android/media/IMediaRoute2Provider.aidl index ab38f4c9e1b02f5894e830b6ff727c29275f9b85..b97dcc521a048b19bf4e7e395f854d2c373fbc0e 100644 --- a/tools/processors/view_inspector/src/java/android/processor/view/inspector/ModelProcessor.java +++ b/media/java/android/media/IMediaRoute2Provider.aidl @@ -14,21 +14,14 @@ * limitations under the License. */ -package android.processor.view.inspector; +package android.media; -import androidx.annotation.NonNull; - -import javax.lang.model.element.Element; +import android.media.IMediaRoute2Callback; /** - * An interface for annotation processors that operate on a single element and a class model. + * {@hide} */ -public interface ModelProcessor { - /** - * Process the supplied element, mutating the model as needed. - * - * @param element The annotated element to operate on - * @param model The model this element should be merged into - */ - void process(@NonNull Element element, @NonNull InspectableClassModel model); +oneway interface IMediaRoute2Provider { + void setCallback(IMediaRoute2Callback callback); + void selectRoute(int uid, String id); } diff --git a/media/java/android/media/IMediaRouter2ManagerClient.aidl b/media/java/android/media/IMediaRouter2ManagerClient.aidl new file mode 100644 index 0000000000000000000000000000000000000000..234551b37a10b8a6fe960ba404cf51db84c9e0e9 --- /dev/null +++ b/media/java/android/media/IMediaRouter2ManagerClient.aidl @@ -0,0 +1,25 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.media; + +/** + * {@hide} + */ +oneway interface IMediaRouter2ManagerClient { + void onRouteSelected(int uid, String routeId); + void onControlCategoriesChanged(int uid, in List categories); +} diff --git a/media/java/android/media/IMediaRouterService.aidl b/media/java/android/media/IMediaRouterService.aidl index 3308fc929b0354689c5330c58c5a8bf290e83e53..59f1d0dcbed8acb8a6e2d3574eebc35152e912a4 100644 --- a/media/java/android/media/IMediaRouterService.aidl +++ b/media/java/android/media/IMediaRouterService.aidl @@ -17,6 +17,7 @@ package android.media; import android.media.IMediaRouterClient; +import android.media.IMediaRouter2ManagerClient; import android.media.MediaRouterClientState; /** @@ -29,8 +30,15 @@ interface IMediaRouterService { MediaRouterClientState getState(IMediaRouterClient client); boolean isPlaybackActive(IMediaRouterClient client); + void setControlCategories(IMediaRouterClient client, in List categories); void setDiscoveryRequest(IMediaRouterClient client, int routeTypes, boolean activeScan); void setSelectedRoute(IMediaRouterClient client, String routeId, boolean explicit); void requestSetVolume(IMediaRouterClient client, String routeId, int volume); void requestUpdateVolume(IMediaRouterClient client, String routeId, int direction); + + void registerManagerAsUser(IMediaRouter2ManagerClient callback, + String packageName, int userId); + void unregisterManager(IMediaRouter2ManagerClient callback); + void setRemoteRoute(IMediaRouter2ManagerClient callback, + int uid, String routeId, boolean explicit); } diff --git a/media/java/android/media/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java index 2ec935598c1b12a365255b5d5fdc7f1bcd97ecb8..a687c141960f6ea92b6d461bb5121326615bc937 100644 --- a/media/java/android/media/MediaCodecInfo.java +++ b/media/java/android/media/MediaCodecInfo.java @@ -21,6 +21,7 @@ import static android.media.Utils.sortDistinctRanges; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.TestApi; import android.annotation.UnsupportedAppUsage; import android.os.Build; import android.util.Log; @@ -31,6 +32,7 @@ import android.util.Size; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -1332,7 +1334,7 @@ public final class MediaCodecInfo { private Range mBlockAspectRatioRange; private Range mBlocksPerSecondRange; private Map> mMeasuredFrameRates; - private Vector mPerformancePoints; + private List mPerformancePoints; private Range mFrameRateRange; private int mBlockWidth; @@ -1620,45 +1622,136 @@ public final class MediaCodecInfo { * rate. */ public static final class PerformancePoint { + private Size mBlockSize; // codec block size in macroblocks + private int mWidth; // width in macroblocks + private int mHeight; // height in macroblocks + private int mMaxFrameRate; // max frames per second + private long mMaxMacroBlockRate; // max macro block rate + /** - * (Maximum) number of macroblocks in the frame. + * Maximum number of macroblocks in the frame. * * Video frames are conceptually divided into 16-by-16 pixel blocks called macroblocks. * Most coding standards operate on these 16-by-16 pixel blocks; thus, codec performance * is characterized using such blocks. + * + * @hide */ - public final int macroBlocks; + @TestApi + public int getMaxMacroBlocks() { + return saturateLongToInt(mWidth * (long)mHeight); + } /** - * (Maximum) frame rate in frames per second. + * Maximum frame rate in frames per second. + * + * @hide */ - public final int frameRate; + @TestApi + public int getMaxFrameRate() { + return mMaxFrameRate; + } + + /** + * Maximum number of macroblocks processed per second. + * + * @hide + */ + @TestApi + public long getMaxMacroBlockRate() { + return mMaxMacroBlockRate; + } + + /** Convert to a debug string */ + public String toString() { + int blockWidth = 16 * mBlockSize.getWidth(); + int blockHeight = 16 * mBlockSize.getHeight(); + int origRate = (int)Utils.divUp(mMaxMacroBlockRate, getMaxMacroBlocks()); + String info = (mWidth * 16) + "x" + (mHeight * 16) + "@" + origRate; + if (origRate < mMaxFrameRate) { + info += ", max " + mMaxFrameRate + "fps"; + } + if (blockWidth > 16 || blockHeight > 16) { + info += ", " + blockWidth + "x" + blockHeight + " blocks"; + } + return "PerformancePoint(" + info + ")"; + } /** - * (Maximum) number of macroblocks processed per second. + * Create a detailed performance point with custom max frame rate and macroblock size. + * + * @param width frame width in pixels + * @param height frame height in pixels + * @param frameRate frames per second for frame width and height + * @param maxFrameRate maximum frames per second for any frame size + * @param blockSize block size for codec implementation. Must be powers of two in both + * width and height. + * + * @throws IllegalArgumentException if the blockSize dimensions are not powers of two. + * + * @hide */ - public final long macroBlockRate; + @TestApi + public PerformancePoint( + int width, int height, int frameRate, int maxFrameRate, + @NonNull Size blockSize) { + checkPowerOfTwo(blockSize.getWidth(), "block width"); + checkPowerOfTwo(blockSize.getHeight(), "block height"); + + mBlockSize = new Size(Utils.divUp(blockSize.getWidth(), 16), + Utils.divUp(blockSize.getHeight(), 16)); + // these are guaranteed not to overflow as we decimate by 16 + mWidth = (int)(Utils.divUp(Math.max(1L, width), + Math.max(blockSize.getWidth(), 16)) + * mBlockSize.getWidth()); + mHeight = (int)(Utils.divUp(Math.max(1L, height), + Math.max(blockSize.getHeight(), 16)) + * mBlockSize.getHeight()); + mMaxFrameRate = Math.max(1, Math.max(frameRate, maxFrameRate)); + mMaxMacroBlockRate = Math.max(1, frameRate) * getMaxMacroBlocks(); + Log.i("PP", "Created " + this); + } - /* package private */ - PerformancePoint(int width_, int height_, int frameRate_, int maxFrameRate_) { - macroBlocks = saturateLongToInt( - ((Math.max(1, (long)width_) + 15) / 16) - * ((Math.max(1, (long)height_) + 15) / 16)); - frameRate = Math.max(1, frameRate_); - macroBlockRate = Math.max(maxFrameRate_, frameRate) * macroBlocks; + /** + * Convert a performance point to a larger blocksize. + * + * @param pp performance point + * @param blockSize block size for codec implementation + * + * @hide + */ + @TestApi + public PerformancePoint(@NonNull PerformancePoint pp, @NonNull Size newBlockSize) { + this( + pp.mWidth * 16, pp.mHeight * 16, + // guaranteed not to overflow as these were multiplied at construction + (int)Utils.divUp(pp.mMaxMacroBlockRate, pp.getMaxMacroBlocks()), + pp.mMaxFrameRate, + new Size(Math.max(newBlockSize.getWidth(), pp.mBlockSize.getWidth() * 16), + Math.max(newBlockSize.getHeight(), pp.mBlockSize.getHeight() * 16)) + ); + /* + // these are guaranteed not to overflow as size * blockSize is decimated by 16 + width = align(pp.width * pp.blockSize.getWidth(), blockSize.getWidth()); + height = align(pp.height * pp.blockSize.getHeight(), blockSize.getHeight()); + frameRate = pp.frameRate; + macroBlockRate = align(pp.macroBlockRate, blockSize.getWidth * blockSize.getHeight()); + */ + Log.i("PP", " from " + pp + " and " + newBlockSize); } /** * Create a performance point for a given frame size and frame rate. * - * @param width_ width of the frame in pixels - * @param height_ height of the frame in pixels - * @param frameRate_ frame rate in frames per second + * @param width width of the frame in pixels + * @param height height of the frame in pixels + * @param frameRate frame rate in frames per second */ - public PerformancePoint(int width_, int height_, int frameRate_) { - this(width_, height_, frameRate_, frameRate_ /* maxFrameRate */); + public PerformancePoint(int width, int height, int frameRate) { + this(width, height, frameRate, frameRate /* maxFrameRate */, new Size(16, 16)); } + /** Saturates a long value to int */ private int saturateLongToInt(long value) { if (value < Integer.MIN_VALUE) { return Integer.MIN_VALUE; @@ -1669,6 +1762,19 @@ public final class MediaCodecInfo { } } + /* This method may overflow */ + private int align(int value, int alignment) { + return Utils.divUp(value, alignment) * alignment; + } + + /** Checks that value is a power of two. */ + private void checkPowerOfTwo2(int value, @NonNull String description) { + if (value == 0 || (value & (value - 1)) != 0) { + throw new IllegalArgumentException( + description + " (" + value + ") must be a power of 2"); + } + } + /** * Checks whether the performance point covers a media format. * @@ -1680,7 +1786,7 @@ public final class MediaCodecInfo { PerformancePoint other = new PerformancePoint( format.getInteger(MediaFormat.KEY_WIDTH, 0), format.getInteger(MediaFormat.KEY_HEIGHT, 0), - // safely convert ceil(double) to int through float case and Math.round + // safely convert ceil(double) to int through float cast and Math.round Math.round((float)( Math.ceil(format.getNumber(MediaFormat.KEY_FRAME_RATE, 0) .doubleValue())))); @@ -1690,7 +1796,7 @@ public final class MediaCodecInfo { /** * Checks whether the performance point covers another performance point. Use this * method to determine if a performance point advertised by a codec covers the - * performance point required. This method can also be used for lose ordering as this + * performance point required. This method can also be used for loose ordering as this * method is transitive. * * @param other other performance point considered @@ -1698,91 +1804,139 @@ public final class MediaCodecInfo { * @return {@code true} if the performance point covers the other. */ public boolean covers(@NonNull PerformancePoint other) { - return (macroBlocks >= other.macroBlocks - && frameRate >= other.frameRate - && macroBlockRate >= other.macroBlockRate); + // convert performance points to common block size + Size commonSize = getCommonBlockSize(other); + PerformancePoint aligned = new PerformancePoint(this, commonSize); + PerformancePoint otherAligned = new PerformancePoint(other, commonSize); + + return (aligned.getMaxMacroBlocks() >= otherAligned.getMaxMacroBlocks() + && aligned.mMaxFrameRate >= otherAligned.mMaxFrameRate + && aligned.mMaxMacroBlockRate >= otherAligned.mMaxMacroBlockRate); } + private @NonNull Size getCommonBlockSize(@NonNull PerformancePoint other) { + return new Size( + Math.max(mBlockSize.getWidth(), other.mBlockSize.getWidth()) * 16, + Math.max(mBlockSize.getHeight(), other.mBlockSize.getHeight()) * 16); + } @Override public boolean equals(Object o) { if (o instanceof PerformancePoint) { + // convert performance points to common block size PerformancePoint other = (PerformancePoint)o; - return (macroBlocks == other.macroBlocks - && frameRate == other.frameRate - && macroBlockRate == other.macroBlockRate); + Size commonSize = getCommonBlockSize(other); + PerformancePoint aligned = new PerformancePoint(this, commonSize); + PerformancePoint otherAligned = new PerformancePoint(other, commonSize); + + return (aligned.getMaxMacroBlocks() == otherAligned.getMaxMacroBlocks() + && aligned.mMaxFrameRate == otherAligned.mMaxFrameRate + && aligned.mMaxMacroBlockRate == otherAligned.mMaxMacroBlockRate); } return false; } /** 480p 24fps */ + @NonNull public static final PerformancePoint SD_24 = new PerformancePoint(720, 480, 24); /** 576p 25fps */ + @NonNull public static final PerformancePoint SD_25 = new PerformancePoint(720, 576, 25); /** 480p 30fps */ + @NonNull public static final PerformancePoint SD_30 = new PerformancePoint(720, 480, 30); /** 480p 48fps */ + @NonNull public static final PerformancePoint SD_48 = new PerformancePoint(720, 480, 48); /** 576p 50fps */ + @NonNull public static final PerformancePoint SD_50 = new PerformancePoint(720, 576, 50); /** 480p 60fps */ + @NonNull public static final PerformancePoint SD_60 = new PerformancePoint(720, 480, 60); /** 720p 24fps */ + @NonNull public static final PerformancePoint HD_24 = new PerformancePoint(1280, 720, 24); /** 720p 25fps */ + @NonNull public static final PerformancePoint HD_25 = new PerformancePoint(1280, 720, 25); /** 720p 30fps */ + @NonNull public static final PerformancePoint HD_30 = new PerformancePoint(1280, 720, 30); /** 720p 50fps */ + @NonNull public static final PerformancePoint HD_50 = new PerformancePoint(1280, 720, 50); /** 720p 60fps */ + @NonNull public static final PerformancePoint HD_60 = new PerformancePoint(1280, 720, 60); /** 720p 100fps */ + @NonNull public static final PerformancePoint HD_100 = new PerformancePoint(1280, 720, 100); /** 720p 120fps */ + @NonNull public static final PerformancePoint HD_120 = new PerformancePoint(1280, 720, 120); /** 720p 200fps */ + @NonNull public static final PerformancePoint HD_200 = new PerformancePoint(1280, 720, 200); /** 720p 240fps */ + @NonNull public static final PerformancePoint HD_240 = new PerformancePoint(1280, 720, 240); /** 1080p 24fps */ + @NonNull public static final PerformancePoint FHD_24 = new PerformancePoint(1920, 1080, 24); /** 1080p 25fps */ + @NonNull public static final PerformancePoint FHD_25 = new PerformancePoint(1920, 1080, 25); /** 1080p 30fps */ + @NonNull public static final PerformancePoint FHD_30 = new PerformancePoint(1920, 1080, 30); /** 1080p 50fps */ + @NonNull public static final PerformancePoint FHD_50 = new PerformancePoint(1920, 1080, 50); /** 1080p 60fps */ + @NonNull public static final PerformancePoint FHD_60 = new PerformancePoint(1920, 1080, 60); /** 1080p 100fps */ + @NonNull public static final PerformancePoint FHD_100 = new PerformancePoint(1920, 1080, 100); /** 1080p 120fps */ + @NonNull public static final PerformancePoint FHD_120 = new PerformancePoint(1920, 1080, 120); /** 1080p 200fps */ + @NonNull public static final PerformancePoint FHD_200 = new PerformancePoint(1920, 1080, 200); /** 1080p 240fps */ + @NonNull public static final PerformancePoint FHD_240 = new PerformancePoint(1920, 1080, 240); /** 2160p 24fps */ + @NonNull public static final PerformancePoint UHD_24 = new PerformancePoint(3840, 2160, 24); /** 2160p 25fps */ + @NonNull public static final PerformancePoint UHD_25 = new PerformancePoint(3840, 2160, 25); /** 2160p 30fps */ + @NonNull public static final PerformancePoint UHD_30 = new PerformancePoint(3840, 2160, 30); /** 2160p 50fps */ + @NonNull public static final PerformancePoint UHD_50 = new PerformancePoint(3840, 2160, 50); /** 2160p 60fps */ + @NonNull public static final PerformancePoint UHD_60 = new PerformancePoint(3840, 2160, 60); /** 2160p 100fps */ + @NonNull public static final PerformancePoint UHD_100 = new PerformancePoint(3840, 2160, 100); /** 2160p 120fps */ + @NonNull public static final PerformancePoint UHD_120 = new PerformancePoint(3840, 2160, 120); /** 2160p 200fps */ + @NonNull public static final PerformancePoint UHD_200 = new PerformancePoint(3840, 2160, 200); /** 2160p 240fps */ + @NonNull public static final PerformancePoint UHD_240 = new PerformancePoint(3840, 2160, 240); } @@ -1803,10 +1957,7 @@ public final class MediaCodecInfo { */ @Nullable public List getSupportedPerformancePoints() { - if (mPerformancePoints == null) { - return null; - } - return new ArrayList(mPerformancePoints); + return mPerformancePoints; } /** @@ -1945,7 +2096,7 @@ public final class MediaCodecInfo { mSmallerDimensionUpperLimit = SIZE_RANGE.getUpper(); } - private @Nullable Vector getPerformancePoints(Map map) { + private @Nullable List getPerformancePoints(Map map) { Vector ret = new Vector<>(); final String prefix = "performance-point-"; Set keys = map.keySet(); @@ -1959,7 +2110,7 @@ public final class MediaCodecInfo { // This means that component knowingly did not publish performance points. // This is different from when the component forgot to publish performance // points. - return ret; + return Collections.unmodifiableList(ret); } String[] temp = key.split("-"); if (temp.length != 4) { @@ -1974,23 +2125,32 @@ public final class MediaCodecInfo { if (range == null || range.getLower() < 0 || range.getUpper() < 0) { continue; } - ret.add(new PerformancePoint( + PerformancePoint given = new PerformancePoint( size.getWidth(), size.getHeight(), range.getLower().intValue(), - range.getUpper().intValue())); + range.getUpper().intValue(), new Size(mBlockWidth, mBlockHeight)); + PerformancePoint rotated = new PerformancePoint( + size.getHeight(), size.getWidth(), range.getLower().intValue(), + range.getUpper().intValue(), new Size(mBlockWidth, mBlockHeight)); + ret.add(given); + if (!given.covers(rotated)) { + ret.add(rotated); + } } + // check if the component specified no performance point indication if (ret.size() == 0) { return null; } // sort reversed by area first, then by frame rate - ret.sort((a, b) -> -((a.macroBlocks != b.macroBlocks) ? - (a.macroBlocks < b.macroBlocks ? -1 : 1) : - (a.macroBlockRate != b.macroBlockRate) ? - (a.macroBlockRate < b.macroBlockRate ? -1 : 1) : - (a.frameRate != b.frameRate) ? - (a.frameRate < b.frameRate ? -1 : 1) : 0)); - return ret; + ret.sort((a, b) -> + -((a.getMaxMacroBlocks() != b.getMaxMacroBlocks()) ? + (a.getMaxMacroBlocks() < b.getMaxMacroBlocks() ? -1 : 1) : + (a.getMaxMacroBlockRate() != b.getMaxMacroBlockRate()) ? + (a.getMaxMacroBlockRate() < b.getMaxMacroBlockRate() ? -1 : 1) : + (a.getMaxFrameRate() != b.getMaxFrameRate()) ? + (a.getMaxFrameRate() < b.getMaxFrameRate() ? -1 : 1) : 0)); + return Collections.unmodifiableList(ret); } private Map> getMeasuredFrameRates(Map map) { @@ -3404,14 +3564,29 @@ public final class MediaCodecInfo { public static final int VP8ProfileMain = 0x01; + /** VP9 Profile 0 4:2:0 8-bit */ public static final int VP9Profile0 = 0x01; + + /** VP9 Profile 1 4:2:2 8-bit */ public static final int VP9Profile1 = 0x02; + + /** VP9 Profile 2 4:2:0 10-bit */ public static final int VP9Profile2 = 0x04; + + /** VP9 Profile 3 4:2:2 10-bit */ public static final int VP9Profile3 = 0x08; + // HDR profiles also support passing HDR metadata + /** VP9 Profile 2 4:2:0 10-bit HDR */ public static final int VP9Profile2HDR = 0x1000; + + /** VP9 Profile 3 4:2:2 10-bit HDR */ public static final int VP9Profile3HDR = 0x2000; + + /** VP9 Profile 2 4:2:0 10-bit HDR10Plus */ public static final int VP9Profile2HDR10Plus = 0x4000; + + /** VP9 Profile 3 4:2:2 10-bit HDR10Plus */ public static final int VP9Profile3HDR10Plus = 0x8000; public static final int VP9Level1 = 0x1; @@ -3489,35 +3664,34 @@ public final class MediaCodecInfo { public static final int DolbyVisionLevelUhd48 = 0x80; public static final int DolbyVisionLevelUhd60 = 0x100; - // Profiles and levels for AV1 Codec, corresponding to the - // definitions in + // Profiles and levels for AV1 Codec, corresponding to the definitions in // "AV1 Bitstream & Decoding Process Specification", Annex A - // found at - // https://aomedia.org/av1-bitstream-and-decoding-process-specification/ + // found at https://aomedia.org/av1-bitstream-and-decoding-process-specification/ /** - * AV1 Main profile. + * AV1 Main profile 4:2:0 8-bit + * * See definition in - * AV1 Bitstream and Decoding Process Specification + * AV1 Specification * Annex A. */ - public static final int AV1Profile0 = 0x1; + public static final int AV1ProfileMain8 = 0x1; /** - * AV1 High profile. + * AV1 Main profile 4:2:0 10-bit + * * See definition in - * AV1 Bitstream and Decoding Process Specification + * AV1 Specification * Annex A. */ - public static final int AV1Profile1 = 0x2; + public static final int AV1ProfileMain10 = 0x2; - /** - * AV1 Professional profile. - * See definition in - * AV1 Bitstream and Decoding Process Specification - * Annex A. - */ - public static final int AV1Profile2 = 0x4; + + /** AV1 Main profile 4:2:0 10-bit with HDR10. */ + public static final int AV1ProfileMain10HDR10 = 0x1000; + + /** AV1 Main profile 4:2:0 10-bit with HDR10Plus. */ + public static final int AV1ProfileMain10HDR10Plus = 0x2000; public static final int AV1Level2 = 0x1; public static final int AV1Level21 = 0x2; diff --git a/media/java/android/media/MediaDrm.java b/media/java/android/media/MediaDrm.java index aeb77cfddbbdeae6d12a0947383fc8a24a434f5a..a08aec3ed20cf91d96ed5b435f8157f66af4b61a 100644 --- a/media/java/android/media/MediaDrm.java +++ b/media/java/android/media/MediaDrm.java @@ -303,6 +303,11 @@ public final class MediaDrm implements AutoCloseable { mErrorCode = errorCode; } + /** + * The SessionException has an unknown error code. + */ + public static final int ERROR_UNKNOWN = 0; + /** * This indicates that apps using MediaDrm sessions are * temporarily exceeding the capacity of available crypto @@ -547,6 +552,13 @@ public final class MediaDrm implements AutoCloseable { */ public static final int STATUS_INTERNAL_ERROR = 4; + /** + * The key is not yet usable to decrypt media because the start + * time is in the future. The key will become usable when + * its start time is reached. + */ + public static final int STATUS_USABLE_IN_FUTURE = 5; + /** @hide */ @IntDef({ STATUS_USABLE, @@ -554,6 +566,7 @@ public final class MediaDrm implements AutoCloseable { STATUS_OUTPUT_NOT_ALLOWED, STATUS_PENDING, STATUS_INTERNAL_ERROR, + STATUS_USABLE_IN_FUTURE, }) @Retention(RetentionPolicy.SOURCE) public @interface KeyStatusCode {} diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java index 27499c6160d31dde5964b9e69883e7f10a7ea5f7..a22c8d0a845732241558d32860f50dcd7b3b0b80 100644 --- a/media/java/android/media/MediaFormat.java +++ b/media/java/android/media/MediaFormat.java @@ -413,7 +413,18 @@ public final class MediaFormat { */ public static final String KEY_INTRA_REFRESH_PERIOD = "intra-refresh-period"; - /** + /** + * An optional key describing whether encoders prepend headers to sync frames (e.g. + * SPS and PPS to IDR frames for H.264). This is an optional parameter that applies only + * to video encoders. A video encoder may not support this feature; check the output + * format to verify that this feature was enabled. + * + * The value is an integer, with 1 indicating to prepend headers to every sync frames, + * or 0 otherwise. The default value is 0. + */ + public static final String KEY_PREPEND_HEADER_TO_SYNC_FRAMES = "prepend-sps-pps-to-idr-frames"; + + /** * A key describing the temporal layering schema. This is an optional parameter * that applies only to video encoders. Use {@link MediaCodec#getOutputFormat} * after {@link MediaCodec#configure configure} to query if the encoder supports @@ -863,6 +874,12 @@ public final class MediaFormat { */ public static final String KEY_IS_FORCED_SUBTITLE = "is-forced-subtitle"; + /** + * A key describing the number of haptic channels in an audio format. + * The associated value is an integer. + */ + public static final String KEY_HAPTIC_CHANNEL_COUNT = "haptic-channel-count"; + /** @hide */ public static final String KEY_IS_TIMED_TEXT = "is-timed-text"; diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java index e7b4752701fb0ea090e5d1036fb63cd0db7ee8d3..575a0bb03f7b7014d0868e31e8ef7d65fe6b15be 100644 --- a/media/java/android/media/MediaRecorder.java +++ b/media/java/android/media/MediaRecorder.java @@ -1537,8 +1537,8 @@ public class MediaRecorder implements AudioRouting, * @param direction Direction constant. * @return true if sucessful. */ - public boolean setMicrophoneDirection(@DirectionMode int direction) { - return native_setMicrophoneDirection(direction) == 0; + public boolean setPreferredMicrophoneDirection(@DirectionMode int direction) { + return native_setPreferredMicrophoneDirection(direction) == 0; } /** @@ -1549,14 +1549,15 @@ public class MediaRecorder implements AudioRouting, * though 0 (no zoom) to 1 (maximum zoom). * @return true if sucessful. */ - public boolean setMicrophoneFieldDimension(@FloatRange(from = -1.0, to = 1.0) float zoom) { + public boolean setPreferredMicrophoneFieldDimension( + @FloatRange(from = -1.0, to = 1.0) float zoom) { Preconditions.checkArgument( zoom >= -1 && zoom <= 1, "Argument must fall between -1 & 1 (inclusive)"); - return native_setMicrophoneFieldDimension(zoom) == 0; + return native_setPreferredMicrophoneFieldDimension(zoom) == 0; } - private native int native_setMicrophoneDirection(int direction); - private native int native_setMicrophoneFieldDimension(float zoom); + private native int native_setPreferredMicrophoneDirection(int direction); + private native int native_setPreferredMicrophoneFieldDimension(float zoom); //-------------------------------------------------------------------------- // Implementation of AudioRecordingMonitor interface diff --git a/media/java/android/media/MediaRoute2ProviderService.java b/media/java/android/media/MediaRoute2ProviderService.java new file mode 100644 index 0000000000000000000000000000000000000000..04ddc3089b91e3835027b716d20f1ce0eabb9f6e --- /dev/null +++ b/media/java/android/media/MediaRoute2ProviderService.java @@ -0,0 +1,108 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.media; + +import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage; + +import android.app.Service; +import android.content.Intent; +import android.os.Handler; +import android.os.IBinder; +import android.os.Looper; +import android.os.RemoteException; +import android.util.Log; + +/** + * @hide + */ +public abstract class MediaRoute2ProviderService extends Service { + private static final String TAG = "MediaRouteProviderSrv"; + + public static final String SERVICE_INTERFACE = "android.media.MediaRoute2ProviderService"; + + private final Handler mHandler; + private ProviderStub mStub; + private IMediaRoute2Callback mCallback; + + public MediaRoute2ProviderService() { + mHandler = new Handler(Looper.getMainLooper()); + } + + @Override + public IBinder onBind(Intent intent) { + if (SERVICE_INTERFACE.equals(intent.getAction())) { + if (mStub == null) { + mStub = new ProviderStub(); + } + return mStub; + } + return null; + } + + /** + * Called when selectRoute is called on a route of the provider. + * + * @param uid The target application uid + * @param routeId The id of the target route + */ + public abstract void onSelect(int uid, String routeId); + + /** + * Updates provider info from selected route and appliation. + * + * TODO: When provider descriptor is defined, this should update the descriptor correctly. + * + * @param uid + * @param routeId + */ + public void updateProvider(int uid, String routeId) { + if (mCallback != null) { + try { + //TODO: After publishState() is fully implemented, delete this. + mCallback.onRouteSelected(uid, routeId); + } catch (RemoteException ex) { + Log.d(TAG, "Failed to update provider"); + } + } + publishState(); + } + + void setCallback(IMediaRoute2Callback callback) { + mCallback = callback; + publishState(); + } + + void publishState() { + //TODO: Send provider descriptor to the MediaRouterService + } + + final class ProviderStub extends IMediaRoute2Provider.Stub { + ProviderStub() { } + + @Override + public void setCallback(IMediaRoute2Callback callback) { + mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::setCallback, + MediaRoute2ProviderService.this, callback)); + } + + @Override + public void selectRoute(int uid, String id) { + mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onSelect, + MediaRoute2ProviderService.this, uid, id)); + } + } +} diff --git a/media/java/android/media/MediaRouter.java b/media/java/android/media/MediaRouter.java index 3444e92779490ac4320e40c8ec85a26fbf2d0ba9..5a89d8c82f3a0026055553b5ac884c391aadbcd3 100644 --- a/media/java/android/media/MediaRouter.java +++ b/media/java/android/media/MediaRouter.java @@ -347,6 +347,17 @@ public class MediaRouter { return mDisplayService.getDisplays(DisplayManager.DISPLAY_CATEGORY_PRESENTATION); } + void setControlCategories(List categories) { + if (mClient != null) { + try { + mMediaRouterService.setControlCategories(mClient, + categories); + } catch (RemoteException ex) { + Log.e(TAG, "Unable to set control categories.", ex); + } + } + } + private void updatePresentationDisplays(int changedDisplayId) { final int count = mRoutes.size(); for (int i = 0; i < count; i++) { @@ -919,6 +930,25 @@ public class MediaRouter { return -1; } + //TODO: Remove @hide when it is ready. + //TODO: Provide pre-defined categories for app developers. + /** + * Sets control categories of the client application. + * Control categories can be used to filter out media routes + * that don't correspond with the client application. + * The only routes that match any of the categories will be shown on other applications. + * + * @hide + * @param categories Categories to set + */ + public void setControlCategories(@NonNull List categories) { + if (categories == null) { + throw new IllegalArgumentException("Categories must not be null"); + } + sStatic.setControlCategories(categories); + } + + /** * Select the specified route to use for output of the given media types. *

diff --git a/media/java/android/media/MediaRouter2Manager.java b/media/java/android/media/MediaRouter2Manager.java new file mode 100644 index 0000000000000000000000000000000000000000..ac5958ea9aa16aa6bdf809fef060a1fe4c2699de --- /dev/null +++ b/media/java/android/media/MediaRouter2Manager.java @@ -0,0 +1,241 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.media; + +import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage; + +import android.annotation.CallbackExecutor; +import android.annotation.NonNull; +import android.content.Context; +import android.os.Handler; +import android.os.RemoteException; +import android.os.ServiceManager; +import android.os.UserHandle; +import android.util.Log; + +import com.android.internal.annotations.GuardedBy; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Executor; + +/** + * @hide + */ +public class MediaRouter2Manager { + private static final String TAG = "MediaRouter2Manager"; + private static final Object sLock = new Object(); + + @GuardedBy("sLock") + private static MediaRouter2Manager sInstance; + + final String mPackageName; + + private Context mContext; + private Client mClient; + private final IMediaRouterService mMediaRouterService; + final Handler mHandler; + + @GuardedBy("sLock") + final ArrayList mCallbacks = new ArrayList<>(); + + /** + * Gets an instance of media router manager that controls media route of other apps. + * @param context + * @return + */ + public static MediaRouter2Manager getInstance(@NonNull Context context) { + if (context == null) { + throw new IllegalArgumentException("context must not be null"); + } + synchronized (sLock) { + if (sInstance == null) { + sInstance = new MediaRouter2Manager(context); + } + return sInstance; + } + } + + private MediaRouter2Manager(Context context) { + mContext = context.getApplicationContext(); + mMediaRouterService = IMediaRouterService.Stub.asInterface( + ServiceManager.getService(Context.MEDIA_ROUTER_SERVICE)); + mPackageName = mContext.getPackageName(); + mHandler = new Handler(context.getMainLooper()); + } + + /** + * Registers a callback to listen route info. + * + * @param executor The executor that runs the callback. + * @param callback The callback to add. + */ + public void addCallback(@NonNull @CallbackExecutor Executor executor, + @NonNull Callback callback) { + + if (executor == null) { + throw new IllegalArgumentException("executor must not be null"); + } + if (callback == null) { + throw new IllegalArgumentException("callback must not be null"); + } + + synchronized (sLock) { + final int index = findCallbackRecord(callback); + if (index >= 0) { + Log.w(TAG, "Ignore adding the same callback twice."); + return; + } + if (mCallbacks.size() == 0) { + Client client = new Client(); + try { + mMediaRouterService.registerManagerAsUser(client, mPackageName, + UserHandle.myUserId()); + mClient = client; + } catch (RemoteException ex) { + Log.e(TAG, "Unable to register media router manager.", ex); + } + } + mCallbacks.add(new CallbackRecord(executor, callback)); + } + } + + /** + * Removes the specified callback. + * + * @param callback The callback to remove. + */ + public void removeCallback(@NonNull Callback callback) { + if (callback == null) { + throw new IllegalArgumentException("callback must not be null"); + } + + synchronized (sLock) { + final int index = findCallbackRecord(callback); + if (index < 0) { + Log.w(TAG, "Ignore removing unknown callback. " + callback); + return; + } + mCallbacks.remove(index); + if (mCallbacks.size() == 0 && mClient != null) { + try { + mMediaRouterService.unregisterManager(mClient); + } catch (RemoteException ex) { + Log.e(TAG, "Unable to unregister media router manager", ex); + } + mClient = null; + } + } + } + + private int findCallbackRecord(Callback callback) { + final int count = mCallbacks.size(); + for (int i = 0; i < count; i++) { + if (mCallbacks.get(i).mCallback == callback) { + return i; + } + } + return -1; + } + + /** + * Selects media route for the specified application uid. + * + * @param uid The uid of the application that should change it's media route. + * @param routeId The id of the route to select + */ + public void selectRoute(int uid, String routeId) { + if (mClient != null) { + try { + mMediaRouterService.setRemoteRoute(mClient, uid, routeId, /* explicit= */true); + } catch (RemoteException ex) { + Log.e(TAG, "Unable to select media route", ex); + } + } + } + + /** + * Unselects media route for the specified application uid. + * + * @param uid The uid of the application that should stop routing. + */ + public void unselectRoute(int uid) { + if (mClient != null) { + try { + mMediaRouterService.setRemoteRoute(mClient, uid, null, /* explicit= */ true); + } catch (RemoteException ex) { + Log.e(TAG, "Unable to select media route", ex); + } + } + } + + void notifyRouteSelected(int uid, String routeId) { + for (CallbackRecord record : mCallbacks) { + record.mExecutor.execute(() -> record.mCallback.onRouteSelected(uid, routeId)); + } + } + + void notifyControlCategoriesChanged(int uid, List categories) { + for (CallbackRecord record : mCallbacks) { + record.mExecutor.execute( + () -> record.mCallback.onControlCategoriesChanged(uid, categories)); + } + } + + /** + * Interface for receiving events about media routing changes. + */ + public abstract static class Callback { + /** + * Called when a route is selected for some application uid. + * @param uid + * @param routeId + */ + public abstract void onRouteSelected(int uid, String routeId); + + /** + * Called when the control categories of an application is changed. + * @param uid the uid of the app that changed control categories + * @param categories the changed categories + */ + public abstract void onControlCategoriesChanged(int uid, List categories); + } + + final class CallbackRecord { + public final Executor mExecutor; + public final Callback mCallback; + + CallbackRecord(Executor executor, Callback callback) { + mExecutor = executor; + mCallback = callback; + } + } + + class Client extends IMediaRouter2ManagerClient.Stub { + @Override + public void onRouteSelected(int uid, String routeId) { + mHandler.sendMessage(obtainMessage(MediaRouter2Manager::notifyRouteSelected, + MediaRouter2Manager.this, uid, routeId)); + } + + @Override + public void onControlCategoriesChanged(int uid, List categories) { + mHandler.sendMessage(obtainMessage(MediaRouter2Manager::notifyControlCategoriesChanged, + MediaRouter2Manager.this, uid, categories)); + } + } +} diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java index 30719fd8c75019b78346606157575f676efbf74c..771628cf7b1e8e015c8af81011c7508fd2c57eb6 100644 --- a/media/java/android/media/MediaScanner.java +++ b/media/java/android/media/MediaScanner.java @@ -116,7 +116,14 @@ import java.util.concurrent.atomic.AtomicBoolean; * The MediaScanner class is not thread-safe, so it should only be used in a single threaded manner. * * {@hide} + * + * @deprecated this media scanner has served faithfully for many years, but it's + * become tedious to test and maintain, mainly due to the way it + * weaves obscurely between managed and native code. It's been + * replaced by {@code ModernMediaScanner} in the + * {@code MediaProvider} package. */ +@Deprecated public class MediaScanner implements AutoCloseable { static { System.loadLibrary("media_jni"); diff --git a/media/java/android/media/MediaTimestamp.java b/media/java/android/media/MediaTimestamp.java index da3362a019b923a412d161463cbff0c6354f0f92..0777ba3144ea5d7e2e8ac10ea0fa2ed22b01525a 100644 --- a/media/java/android/media/MediaTimestamp.java +++ b/media/java/android/media/MediaTimestamp.java @@ -16,8 +16,7 @@ package android.media; -import android.annotation.NonNull; -import android.annotation.SystemApi; +import android.annotation.FloatRange; /** * An immutable object that represents the linear correlation between the media time @@ -76,6 +75,7 @@ public final class MediaTimestamp * greater than 1.0 if media clock is faster than the system clock; * less than 1.0 if media clock is slower than the system clock. */ + @FloatRange(from = 0.0f, to = Float.MAX_VALUE) public float getMediaClockRate() { return clockRate; } @@ -87,11 +87,19 @@ public final class MediaTimestamp /** @hide - accessor shorthand */ public final float clockRate; - /** @hide */ - MediaTimestamp(long mediaUs, long systemNs, float rate) { - mediaTimeUs = mediaUs; - nanoTime = systemNs; - clockRate = rate; + /** + * Constructor. + * + * @param mediaTimeUs the media time of the anchor in microseconds + * @param nanoTimeNs the {@link java.lang.System#nanoTime system time} corresponding to the + * media time in nanoseconds. + * @param clockRate the rate of the media clock in relation to the system time. + */ + public MediaTimestamp(long mediaTimeUs, long nanoTimeNs, + @FloatRange(from = 0.0f, to = Float.MAX_VALUE) float clockRate) { + this.mediaTimeUs = mediaTimeUs; + this.nanoTime = nanoTimeNs; + this.clockRate = clockRate; } /** @hide */ @@ -120,71 +128,4 @@ public final class MediaTimestamp + " clockRate=" + clockRate + "}"; } - - /** - * Builder class for {@link MediaTimestamp} objects. - *

Here is an example where Builder is used to define the - * {@link MediaTimestamp}: - * - *

-     * MediaTimestamp mts = new MediaTimestamp.Builder()
-     *         .setMediaTimestamp(mediaTime, systemTime, rate)
-     *         .build();
-     * 
- * @hide - */ - @SystemApi - public static final class Builder { - long mMediaTimeUs; - long mNanoTime; - float mClockRate = 1.0f; - - /** - * Constructs a new Builder with the defaults. - */ - public Builder() { - } - - /** - * Constructs a new Builder from a given {@link MediaTimestamp} instance - * @param mts the {@link MediaTimestamp} object whose data will be reused - * in the new Builder. - */ - public Builder(@NonNull MediaTimestamp mts) { - if (mts == null) { - throw new IllegalArgumentException("null MediaTimestamp is not allowed"); - } - mMediaTimeUs = mts.mediaTimeUs; - mNanoTime = mts.nanoTime; - mClockRate = mts.clockRate; - } - - /** - * Combines all of the fields that have been set and return a new - * {@link MediaTimestamp} object. - * - * @return a new {@link MediaTimestamp} object - */ - public @NonNull MediaTimestamp build() { - return new MediaTimestamp(mMediaTimeUs, mNanoTime, mClockRate); - } - - /** - * Sets the info of media timestamp. - * - * @param mediaTimeUs the media time of the anchor in microseconds - * @param nanoTime the {@link java.lang.System#nanoTime system time} corresponding to - * the media time in nanoseconds. - * @param clockRate the rate of the media clock in relation to the system time. - * @return the same Builder instance. - */ - public @NonNull Builder setMediaTimestamp( - long mediaTimeUs, long nanoTime, float clockRate) { - mMediaTimeUs = mediaTimeUs; - mNanoTime = nanoTime; - mClockRate = clockRate; - - return this; - } - } } diff --git a/media/java/android/media/MicrophoneDirection.java b/media/java/android/media/MicrophoneDirection.java index 2382da54801c09c3ca0800870e6fcec3e31f319d..e4eec446b7bc5e053d5e811cb9ef9243437a6352 100644 --- a/media/java/android/media/MicrophoneDirection.java +++ b/media/java/android/media/MicrophoneDirection.java @@ -32,13 +32,21 @@ public interface MicrophoneDirection { */ int MIC_DIRECTION_UNSPECIFIED = 0; /** - * Optimize capture for audio coming from the screen-side of the device. + * Optimize capture for audio coming from the side of the device facing the user. + * In the typical case, a device with a single screen, screen-side camera/microphone and + * non-screen-side camera/microphone, this will be the screen side (as in a "selfie"). + * For a different device geometry, it is the side for which the expectation is to be + * facing the user. */ - int MIC_DIRECTION_FRONT = 1; + int MIC_DIRECTION_TOWARDS_USER = 1; /** - * Optimize capture for audio coming from the side of the device opposite the screen. + * Optimize capture for audio coming from the side of the device pointing away from the user. + * In the typical case, a device with a single screen, screen-side camera/microphone and + * non-screen-side camera/microphone, this will be the non-screen side. + * For a different device geometry, it is the side for which the expectation is to be + * facing away from the user. This is the "taking a video of something else" case. */ - int MIC_DIRECTION_BACK = 2; + int MIC_DIRECTION_AWAY_FROM_USER = 2; /** * Optimize capture for audio coming from an off-device microphone. */ @@ -47,8 +55,8 @@ public interface MicrophoneDirection { /** @hide */ /*public*/ @IntDef({ MIC_DIRECTION_UNSPECIFIED, - MIC_DIRECTION_FRONT, - MIC_DIRECTION_BACK, + MIC_DIRECTION_TOWARDS_USER, + MIC_DIRECTION_AWAY_FROM_USER, MIC_DIRECTION_EXTERNAL }) @Retention(RetentionPolicy.SOURCE) @@ -58,18 +66,23 @@ public interface MicrophoneDirection { * which side of the device to optimize capture from. Typically used in conjunction with * the camera capturing video. * + * Usage would include specifying the audio capture to follow camera being used to capture + * video. * @param direction Direction constant. * @return true if sucessful. */ - boolean setMicrophoneDirection(@DirectionMode int direction); + boolean setPreferredMicrophoneDirection(@DirectionMode int direction); /** * Specifies the zoom factor (i.e. the field dimension) for the selected microphone * (for processing). The selected microphone is determined by the use-case for the stream. * + * Usage would include specifying the audio focus to follow the zoom specified for the camera + * being used to capture video. + * * @param zoom the desired field dimension of microphone capture. Range is from -1 (wide angle), * though 0 (no zoom) to 1 (maximum zoom). * @return true if sucessful. */ - boolean setMicrophoneFieldDimension(@FloatRange(from = -1.0, to = 1.0) float zoom); + boolean setPreferredMicrophoneFieldDimension(@FloatRange(from = -1.0, to = 1.0) float zoom); } diff --git a/media/java/android/media/RingtoneManager.java b/media/java/android/media/RingtoneManager.java index 9a609236aa3092f641ef3025c3942c387713a4e7..e0e657bb4474dd4ea84114071a76dde7eb28cf9b 100644 --- a/media/java/android/media/RingtoneManager.java +++ b/media/java/android/media/RingtoneManager.java @@ -1097,6 +1097,28 @@ public class RingtoneManager { return afd; } + /** + * Returns if the {@link Ringtone} at the given position in the + * {@link Cursor} contains haptic channels. + * + * @param position The position (in the {@link Cursor}) of the ringtone. + * @return true if the ringtone contains haptic channels. + */ + public boolean hasHapticChannels(int position) { + return hasHapticChannels(getRingtoneUri(position)); + } + + /** + * Returns if the {@link Ringtone} from a given sound URI contains + * haptic channels or not. + * + * @param ringtoneUri The {@link Uri} of a sound or ringtone. + * @return true if the ringtone contains haptic channels. + */ + public static boolean hasHapticChannels(@NonNull Uri ringtoneUri) { + return AudioManager.hasHapticChannels(ringtoneUri); + } + /** * Creates a {@link android.media.MediaScannerConnection} to scan a ringtone file and add its * information to the internal database. diff --git a/media/java/android/media/SubtitleData.java b/media/java/android/media/SubtitleData.java index 2c6c61f8df18dbd678917d9449d643105dd09471..2ef69820fb841f2255a455e2f17ea661f3e85718 100644 --- a/media/java/android/media/SubtitleData.java +++ b/media/java/android/media/SubtitleData.java @@ -17,11 +17,8 @@ package android.media; import android.annotation.NonNull; -import android.annotation.SystemApi; import android.os.Parcel; -import java.util.Arrays; - /** * Class encapsulating subtitle data, as received through the * {@link MediaPlayer.OnSubtitleDataListener} interface. @@ -82,12 +79,23 @@ public final class SubtitleData } } - /** @hide */ + /** + * Constructor. + * + * @param trackIndex the index of the media player track which contains this subtitle data. + * @param startTimeUs the start time in microsecond for the subtitle data + * @param durationUs the duration in microsecond for the subtitle data + * @param data the data array for the subtitle data. It should not be null. + * No data copying is made. + */ public SubtitleData(int trackIndex, long startTimeUs, long durationUs, @NonNull byte[] data) { + if (data == null) { + throw new IllegalArgumentException("null data is not allowed"); + } mTrackIndex = trackIndex; mStartTimeUs = startTimeUs; mDurationUs = durationUs; - mData = (data != null ? data : new byte[0]); + mData = data; } /** @@ -141,80 +149,4 @@ public final class SubtitleData return true; } - - /** - * Builder class for {@link SubtitleData} objects. - *

Here is an example where Builder is used to define the - * {@link SubtitleData}: - * - *

-     * SubtitleData sd = new SubtitleData.Builder()
-     *         .setSubtitleData(trackIndex, startTime, duration, data)
-     *         .build();
-     * 
- * @hide - */ - @SystemApi - public static final class Builder { - private int mTrackIndex; - private long mStartTimeUs; - private long mDurationUs; - private byte[] mData = new byte[0]; - - /** - * Constructs a new Builder with the defaults. - */ - public Builder() { - } - - /** - * Constructs a new Builder from a given {@link SubtitleData} instance - * @param sd the {@link SubtitleData} object whose data will be reused - * in the new Builder. It should not be null. The data array is copied. - */ - public Builder(@NonNull SubtitleData sd) { - if (sd == null) { - throw new IllegalArgumentException("null SubtitleData is not allowed"); - } - mTrackIndex = sd.mTrackIndex; - mStartTimeUs = sd.mStartTimeUs; - mDurationUs = sd.mDurationUs; - if (sd.mData != null) { - mData = Arrays.copyOf(sd.mData, sd.mData.length); - } - } - - /** - * Combines all of the fields that have been set and return a new - * {@link SubtitleData} object. IllegalStateException will be - * thrown if there is conflict between fields. - * - * @return a new {@link SubtitleData} object - */ - public @NonNull SubtitleData build() { - return new SubtitleData(mTrackIndex, mStartTimeUs, mDurationUs, mData); - } - - /** - * Sets the info of subtitle data. - * - * @param trackIndex the index of the media player track which contains this subtitle data. - * @param startTimeUs the start time in microsecond for the subtile data - * @param durationUs the duration in microsecond for the subtile data - * @param data the data array for the subtile data. It should not be null. - * No data copying is made. - * @return the same Builder instance. - */ - public @NonNull Builder setSubtitleData( - int trackIndex, long startTimeUs, long durationUs, @NonNull byte[] data) { - if (data == null) { - throw new IllegalArgumentException("null data is not allowed"); - } - mTrackIndex = trackIndex; - mStartTimeUs = startTimeUs; - mDurationUs = durationUs; - mData = data; - return this; - } - } } diff --git a/media/java/android/media/TimedMetaData.java b/media/java/android/media/TimedMetaData.java index 990760cf32aedc1e01c89f871e8418f840134807..b99b30c58cf371dd13785c7dc4f77f22f92d9b5d 100644 --- a/media/java/android/media/TimedMetaData.java +++ b/media/java/android/media/TimedMetaData.java @@ -17,11 +17,8 @@ package android.media; import android.annotation.NonNull; -import android.annotation.SystemApi; import android.os.Parcel; -import java.util.Arrays; - /** * Class that embodies one timed metadata access unit, including * @@ -52,7 +49,11 @@ public final class TimedMetaData { } /** - * @hide + * Constructor. + * + * @param timestampUs the timestamp in microsecond for the timed metadata + * @param metaData the metadata array for the timed metadata. No data copying is made. + * It should not be null. */ public TimedMetaData(long timestampUs, @NonNull byte[] metaData) { if (metaData == null) { @@ -90,71 +91,4 @@ public final class TimedMetaData { return true; } - - /** - * Builder class for {@link TimedMetaData} objects. - *

Here is an example where Builder is used to define the - * {@link TimedMetaData}: - * - *

-     * TimedMetaData tmd = new TimedMetaData.Builder()
-     *         .setTimedMetaData(timestamp, metaData)
-     *         .build();
-     * 
- * @hide - */ - @SystemApi - public static final class Builder { - private long mTimestampUs; - private byte[] mMetaData = new byte[0]; - - /** - * Constructs a new Builder with the defaults. - */ - public Builder() { - } - - /** - * Constructs a new Builder from a given {@link TimedMetaData} instance - * @param tmd the {@link TimedMetaData} object whose data will be reused - * in the new Builder. It should not be null. The metadata array is copied. - */ - public Builder(@NonNull TimedMetaData tmd) { - if (tmd == null) { - throw new IllegalArgumentException("null TimedMetaData is not allowed"); - } - mTimestampUs = tmd.mTimestampUs; - if (tmd.mMetaData != null) { - mMetaData = Arrays.copyOf(tmd.mMetaData, tmd.mMetaData.length); - } - } - - /** - * Combines all of the fields that have been set and return a new - * {@link TimedMetaData} object. IllegalStateException will be - * thrown if there is conflict between fields. - * - * @return a new {@link TimedMetaData} object - */ - public @NonNull TimedMetaData build() { - return new TimedMetaData(mTimestampUs, mMetaData); - } - - /** - * Sets the info of timed metadata. - * - * @param timestamp the timestamp in microsecond for the timed metadata - * @param metaData the metadata array for the timed metadata. No data copying is made. - * It should not be null. - * @return the same Builder instance. - */ - public @NonNull Builder setTimedMetaData(long timestamp, @NonNull byte[] metaData) { - if (metaData == null) { - throw new IllegalArgumentException("null metaData is not allowed"); - } - mTimestampUs = timestamp; - mMetaData = metaData; - return this; - } - } } diff --git a/media/java/android/media/audiopolicy/AudioMixingRule.java b/media/java/android/media/audiopolicy/AudioMixingRule.java index 6c48cdb7b64320a5102e64f09c22267b5be0ceef..d41f416f3d51e6043582cf5150f918ebb00df046 100644 --- a/media/java/android/media/audiopolicy/AudioMixingRule.java +++ b/media/java/android/media/audiopolicy/AudioMixingRule.java @@ -409,6 +409,10 @@ public class AudioMixingRule { final int match_rule = rule & ~RULE_EXCLUSION_MASK; while (crIterator.hasNext()) { final AudioMixMatchCriterion criterion = crIterator.next(); + + if ((criterion.mRule & ~RULE_EXCLUSION_MASK) != match_rule) { + continue; // The two rules are not of the same type + } switch (match_rule) { case RULE_MATCH_ATTRIBUTE_USAGE: // "usage"-based rule diff --git a/media/java/android/media/audiopolicy/AudioPolicy.java b/media/java/android/media/audiopolicy/AudioPolicy.java index 978583e99971609283b10370cdf657287748f114..00f6013881641f3f2508bc7dd19f8853ce2a2f02 100644 --- a/media/java/android/media/audiopolicy/AudioPolicy.java +++ b/media/java/android/media/audiopolicy/AudioPolicy.java @@ -75,6 +75,7 @@ public class AudioPolicy { private String mRegistrationId; private AudioPolicyStatusListener mStatusListener; private boolean mIsFocusPolicy; + private boolean mIsTestFocusPolicy; /** * The list of AudioTrack instances created to inject audio into the associated mixes @@ -121,6 +122,10 @@ public class AudioPolicy { /** @hide */ public boolean isFocusPolicy() { return mIsFocusPolicy; } /** @hide */ + public boolean isTestFocusPolicy() { + return mIsTestFocusPolicy; + } + /** @hide */ public boolean isVolumeController() { return mVolCb != null; } /** @hide */ public @Nullable MediaProjection getMediaProjection() { @@ -128,10 +133,11 @@ public class AudioPolicy { } /** - * The parameter is guaranteed non-null through the Builder + * The parameters are guaranteed non-null through the Builder */ private AudioPolicy(AudioPolicyConfig config, Context context, Looper looper, - AudioPolicyFocusListener fl, AudioPolicyStatusListener sl, boolean isFocusPolicy, + AudioPolicyFocusListener fl, AudioPolicyStatusListener sl, + boolean isFocusPolicy, boolean isTestFocusPolicy, AudioPolicyVolumeCallback vc, @Nullable MediaProjection projection) { mConfig = config; mStatus = POLICY_STATUS_UNREGISTERED; @@ -148,6 +154,7 @@ public class AudioPolicy { mFocusListener = fl; mStatusListener = sl; mIsFocusPolicy = isFocusPolicy; + mIsTestFocusPolicy = isTestFocusPolicy; mVolCb = vc; mProjection = projection; } @@ -163,6 +170,7 @@ public class AudioPolicy { private AudioPolicyFocusListener mFocusListener; private AudioPolicyStatusListener mStatusListener; private boolean mIsFocusPolicy = false; + private boolean mIsTestFocusPolicy = false; private AudioPolicyVolumeCallback mVolCb; private MediaProjection mProjection; @@ -181,6 +189,7 @@ public class AudioPolicy { * @return the same Builder instance. * @throws IllegalArgumentException */ + @NonNull public Builder addMix(@NonNull AudioMix mix) throws IllegalArgumentException { if (mix == null) { throw new IllegalArgumentException("Illegal null AudioMix argument"); @@ -195,6 +204,7 @@ public class AudioPolicy { * @return the same Builder instance. * @throws IllegalArgumentException */ + @NonNull public Builder setLooper(@NonNull Looper looper) throws IllegalArgumentException { if (looper == null) { throw new IllegalArgumentException("Illegal null Looper argument"); @@ -220,11 +230,27 @@ public class AudioPolicy { * @param enforce true if the policy will govern audio focus decisions. * @return the same Builder instance. */ + @NonNull public Builder setIsAudioFocusPolicy(boolean isFocusPolicy) { mIsFocusPolicy = isFocusPolicy; return this; } + /** + * Test method to declare whether this audio focus policy is for test purposes only. + * Having a test policy registered will disable the current focus policy and replace it + * with this test policy. When unregistered, the previous focus policy will be restored. + *

A value of true will be ignored if the AudioPolicy is not also + * focus policy. + * @param isTestFocusPolicy true if the focus policy to register is for testing purposes. + * @return the same Builder instance + */ + @NonNull + public Builder setIsTestFocusPolicy(boolean isTestFocusPolicy) { + mIsTestFocusPolicy = isTestFocusPolicy; + return this; + } + /** * Sets the audio policy status listener. * @param l a {@link AudioPolicy.AudioPolicyStatusListener} @@ -240,6 +266,7 @@ public class AudioPolicy { * @param vc * @return the same Builder instance. */ + @NonNull public Builder setAudioPolicyVolumeCallback(@NonNull AudioPolicyVolumeCallback vc) { if (vc == null) { throw new IllegalArgumentException("Invalid null volume callback"); @@ -256,6 +283,7 @@ public class AudioPolicy { * * @hide */ + @NonNull public Builder setMediaProjection(@NonNull MediaProjection projection) { if (projection == null) { throw new IllegalArgumentException("Invalid null volume callback"); @@ -273,6 +301,7 @@ public class AudioPolicy { * {@link AudioPolicy.AudioPolicyStatusListener} but the policy was configured * as an audio focus policy with {@link #setIsAudioFocusPolicy(boolean)}. */ + @NonNull public AudioPolicy build() { if (mStatusListener != null) { // the AudioPolicy status listener includes updates on each mix activity state @@ -285,7 +314,8 @@ public class AudioPolicy { + "an AudioPolicyFocusListener"); } return new AudioPolicy(new AudioPolicyConfig(mMixes), mContext, mLooper, - mFocusListener, mStatusListener, mIsFocusPolicy, mVolCb, mProjection); + mFocusListener, mStatusListener, mIsFocusPolicy, mIsTestFocusPolicy, + mVolCb, mProjection); } } diff --git a/media/java/android/media/projection/OWNERS b/media/java/android/media/projection/OWNERS new file mode 100644 index 0000000000000000000000000000000000000000..7e7335d68d3bda6633feb94210e17f31ee2cf772 --- /dev/null +++ b/media/java/android/media/projection/OWNERS @@ -0,0 +1 @@ +michaelwr@google.com diff --git a/media/java/android/media/session/ISessionCallback.aidl b/media/java/android/media/session/ISessionCallback.aidl index cd33c044d142e3d4e092d6b72231896e3ead9834..0add1b417c4f63dced13a1309d10bc6c751388bc 100644 --- a/media/java/android/media/session/ISessionCallback.aidl +++ b/media/java/android/media/session/ISessionCallback.aidl @@ -26,48 +26,48 @@ import android.os.ResultReceiver; * @hide */ oneway interface ISessionCallback { - void notifyCommand(String packageName, int pid, int uid, in ControllerCallbackLink caller, + void onCommand(String packageName, int pid, int uid, in ControllerCallbackLink caller, String command, in Bundle args, in ResultReceiver cb); - void notifyMediaButton(String packageName, int pid, int uid, in Intent mediaButtonIntent, + void onMediaButton(String packageName, int pid, int uid, in Intent mediaButtonIntent, int sequenceNumber, in ResultReceiver cb); - void notifyMediaButtonFromController(String packageName, int pid, int uid, + void onMediaButtonFromController(String packageName, int pid, int uid, in ControllerCallbackLink caller, in Intent mediaButtonIntent); - // These callbacks are for the TransportPerformer - void notifyPrepare(String packageName, int pid, int uid, in ControllerCallbackLink caller); - void notifyPrepareFromMediaId(String packageName, int pid, int uid, + // These callbacks are for the TransportControls + void onPrepare(String packageName, int pid, int uid, in ControllerCallbackLink caller); + void onPrepareFromMediaId(String packageName, int pid, int uid, in ControllerCallbackLink caller, String mediaId, in Bundle extras); - void notifyPrepareFromSearch(String packageName, int pid, int uid, + void onPrepareFromSearch(String packageName, int pid, int uid, in ControllerCallbackLink caller, String query, in Bundle extras); - void notifyPrepareFromUri(String packageName, int pid, int uid, + void onPrepareFromUri(String packageName, int pid, int uid, in ControllerCallbackLink caller, in Uri uri, in Bundle extras); - void notifyPlay(String packageName, int pid, int uid, in ControllerCallbackLink caller); - void notifyPlayFromMediaId(String packageName, int pid, int uid, + void onPlay(String packageName, int pid, int uid, in ControllerCallbackLink caller); + void onPlayFromMediaId(String packageName, int pid, int uid, in ControllerCallbackLink caller, String mediaId, in Bundle extras); - void notifyPlayFromSearch(String packageName, int pid, int uid, + void onPlayFromSearch(String packageName, int pid, int uid, in ControllerCallbackLink caller, String query, in Bundle extras); - void notifyPlayFromUri(String packageName, int pid, int uid, in ControllerCallbackLink caller, + void onPlayFromUri(String packageName, int pid, int uid, in ControllerCallbackLink caller, in Uri uri, in Bundle extras); - void notifySkipToTrack(String packageName, int pid, int uid, in ControllerCallbackLink caller, + void onSkipToTrack(String packageName, int pid, int uid, in ControllerCallbackLink caller, long id); - void notifyPause(String packageName, int pid, int uid, in ControllerCallbackLink caller); - void notifyStop(String packageName, int pid, int uid, in ControllerCallbackLink caller); - void notifyNext(String packageName, int pid, int uid, in ControllerCallbackLink caller); - void notifyPrevious(String packageName, int pid, int uid, in ControllerCallbackLink caller); - void notifyFastForward(String packageName, int pid, int uid, in ControllerCallbackLink caller); - void notifyRewind(String packageName, int pid, int uid, in ControllerCallbackLink caller); - void notifySeekTo(String packageName, int pid, int uid, in ControllerCallbackLink caller, + void onPause(String packageName, int pid, int uid, in ControllerCallbackLink caller); + void onStop(String packageName, int pid, int uid, in ControllerCallbackLink caller); + void onNext(String packageName, int pid, int uid, in ControllerCallbackLink caller); + void onPrevious(String packageName, int pid, int uid, in ControllerCallbackLink caller); + void onFastForward(String packageName, int pid, int uid, in ControllerCallbackLink caller); + void onRewind(String packageName, int pid, int uid, in ControllerCallbackLink caller); + void onSeekTo(String packageName, int pid, int uid, in ControllerCallbackLink caller, long pos); - void notifyRate(String packageName, int pid, int uid, in ControllerCallbackLink caller, + void onRate(String packageName, int pid, int uid, in ControllerCallbackLink caller, in Rating rating); - void notifySetPlaybackSpeed(String packageName, int pid, int uid, + void onSetPlaybackSpeed(String packageName, int pid, int uid, in ControllerCallbackLink caller, float speed); - void notifyCustomAction(String packageName, int pid, int uid, in ControllerCallbackLink caller, + void onCustomAction(String packageName, int pid, int uid, in ControllerCallbackLink caller, String action, in Bundle args); // These callbacks are for volume handling - void notifyAdjustVolume(String packageName, int pid, int uid, in ControllerCallbackLink caller, + void onAdjustVolume(String packageName, int pid, int uid, in ControllerCallbackLink caller, int direction); - void notifySetVolumeTo(String packageName, int pid, int uid, + void onSetVolumeTo(String packageName, int pid, int uid, in ControllerCallbackLink caller, int value); } diff --git a/media/java/android/media/session/ISessionManager.aidl b/media/java/android/media/session/ISessionManager.aidl index 023484764a5295635693176ea02c6c7e00c0f1df..e073a4e2f6c8d8189f932ed9b0275ec3573eea4b 100644 --- a/media/java/android/media/session/ISessionManager.aidl +++ b/media/java/android/media/session/ISessionManager.aidl @@ -23,9 +23,9 @@ import android.media.session.ICallback; import android.media.session.IOnMediaKeyListener; import android.media.session.IOnVolumeKeyLongPressListener; import android.media.session.ISession; +import android.media.session.ISessionCallback; import android.media.session.ISession2TokensListener; import android.media.session.MediaSession; -import android.media.session.SessionCallbackLink; import android.os.Bundle; import android.view.KeyEvent; @@ -34,7 +34,7 @@ import android.view.KeyEvent; * @hide */ interface ISessionManager { - ISession createSession(String packageName, in SessionCallbackLink sessionCb, String tag, + ISession createSession(String packageName, in ISessionCallback sessionCb, String tag, in Bundle sessionInfo, int userId); void notifySession2Created(in Session2Token sessionToken); List getSessions(in ComponentName compName, int userId); diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java index cbc6c9d6e45145bb812c8a0ed87cf3e274402899..aa61a01310c93f9b069cad59fccd24b66b3a9021 100644 --- a/media/java/android/media/session/MediaSession.java +++ b/media/java/android/media/session/MediaSession.java @@ -27,12 +27,15 @@ import android.content.Intent; import android.media.AudioAttributes; import android.media.MediaDescription; import android.media.MediaMetadata; +import android.media.MediaParceledListSlice; import android.media.Rating; import android.media.VolumeProvider; import android.media.session.MediaSessionManager.RemoteUserInfo; import android.net.Uri; import android.os.Bundle; import android.os.Handler; +import android.os.Looper; +import android.os.Message; import android.os.Parcel; import android.os.Parcelable; import android.os.Process; @@ -40,9 +43,14 @@ import android.os.RemoteException; import android.os.ResultReceiver; import android.service.media.MediaBrowserService; import android.text.TextUtils; +import android.util.Log; +import android.util.Pair; +import android.view.KeyEvent; +import android.view.ViewConfiguration; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.lang.ref.WeakReference; import java.util.List; import java.util.Objects; @@ -116,12 +124,21 @@ public final class MediaSession { FLAG_EXCLUSIVE_GLOBAL_PRIORITY }) public @interface SessionFlags { } - private final MediaSessionEngine mImpl; + private final Object mLock = new Object(); private final int mMaxBitmapSize; + private final Token mSessionToken; + private final MediaController mController; + private final ISession mBinder; + private final CallbackStub mCbStub; + // Do not change the name of mCallback. Support lib accesses this by using reflection. @UnsupportedAppUsage - private Object mCallback; + private CallbackMessageHandler mCallback; + private VolumeProvider mVolumeProvider; + private PlaybackState mPlaybackState; + + private boolean mActive = false; /** * Creates a new session. The session will automatically be registered with @@ -160,14 +177,15 @@ public final class MediaSession { if (TextUtils.isEmpty(tag)) { throw new IllegalArgumentException("tag cannot be null or empty"); } + mMaxBitmapSize = context.getResources().getDimensionPixelSize( + com.android.internal.R.dimen.config_mediaMetadataBitmapMaxSize); + mCbStub = new CallbackStub(this); MediaSessionManager manager = (MediaSessionManager) context .getSystemService(Context.MEDIA_SESSION_SERVICE); try { - SessionCallbackLink cbLink = new SessionCallbackLink(context); - ISession binder = manager.createSession(cbLink, tag, sessionInfo); - mImpl = new MediaSessionEngine(context, binder, cbLink); - mMaxBitmapSize = context.getResources().getDimensionPixelSize( - com.android.internal.R.dimen.config_mediaMetadataBitmapMaxSize); + mBinder = manager.createSession(mCbStub, tag, sessionInfo); + mSessionToken = new Token(mBinder.getController()); + mController = new MediaController(context, mSessionToken); } catch (RemoteException e) { throw new RuntimeException("Remote error creating session.", e); } @@ -183,8 +201,7 @@ public final class MediaSession { * @param callback The callback object */ public void setCallback(@Nullable Callback callback) { - mCallback = callback == null ? null : new Object(); - mImpl.setCallback(callback); + setCallback(callback, null); } /** @@ -197,8 +214,24 @@ public final class MediaSession { * @param handler The handler that events should be posted on. */ public void setCallback(@Nullable Callback callback, @Nullable Handler handler) { - mCallback = callback == null ? null : new Object(); - mImpl.setCallback(callback, handler); + synchronized (mLock) { + if (mCallback != null) { + // We're updating the callback, clear the session from the old one. + mCallback.mCallback.mSession = null; + mCallback.removeCallbacksAndMessages(null); + } + if (callback == null) { + mCallback = null; + return; + } + if (handler == null) { + handler = new Handler(); + } + callback.mSession = this; + CallbackMessageHandler msgHandler = new CallbackMessageHandler(handler.getLooper(), + callback); + mCallback = msgHandler; + } } /** @@ -209,7 +242,11 @@ public final class MediaSession { * @param pi The intent to launch to show UI for this Session. */ public void setSessionActivity(@Nullable PendingIntent pi) { - mImpl.setSessionActivity(pi); + try { + mBinder.setLaunchPendingIntent(pi); + } catch (RemoteException e) { + Log.wtf(TAG, "Failure in setLaunchPendingIntent.", e); + } } /** @@ -221,7 +258,11 @@ public final class MediaSession { * @param mbr The {@link PendingIntent} to send the media button event to. */ public void setMediaButtonReceiver(@Nullable PendingIntent mbr) { - mImpl.setMediaButtonReceiver(mbr); + try { + mBinder.setMediaButtonReceiver(mbr); + } catch (RemoteException e) { + Log.wtf(TAG, "Failure in setMediaButtonReceiver.", e); + } } /** @@ -230,7 +271,11 @@ public final class MediaSession { * @param flags The flags to set for this session. */ public void setFlags(@SessionFlags int flags) { - mImpl.setFlags(flags); + try { + mBinder.setFlags(flags); + } catch (RemoteException e) { + Log.wtf(TAG, "Failure in setFlags.", e); + } } /** @@ -245,7 +290,14 @@ public final class MediaSession { * @param attributes The {@link AudioAttributes} for this session's audio. */ public void setPlaybackToLocal(AudioAttributes attributes) { - mImpl.setPlaybackToLocal(attributes); + if (attributes == null) { + throw new IllegalArgumentException("Attributes cannot be null for local playback."); + } + try { + mBinder.setPlaybackToLocal(attributes); + } catch (RemoteException e) { + Log.wtf(TAG, "Failure in setPlaybackToLocal.", e); + } } /** @@ -260,7 +312,26 @@ public final class MediaSession { * not be null. */ public void setPlaybackToRemote(@NonNull VolumeProvider volumeProvider) { - mImpl.setPlaybackToRemote(volumeProvider); + if (volumeProvider == null) { + throw new IllegalArgumentException("volumeProvider may not be null!"); + } + synchronized (mLock) { + mVolumeProvider = volumeProvider; + } + volumeProvider.setCallback(new VolumeProvider.Callback() { + @Override + public void onVolumeChanged(VolumeProvider volumeProvider) { + notifyRemoteVolumeChanged(volumeProvider); + } + }); + + try { + mBinder.setPlaybackToRemote(volumeProvider.getVolumeControl(), + volumeProvider.getMaxVolume()); + mBinder.setCurrentVolume(volumeProvider.getCurrentVolume()); + } catch (RemoteException e) { + Log.wtf(TAG, "Failure in setPlaybackToRemote.", e); + } } /** @@ -272,7 +343,15 @@ public final class MediaSession { * @param active Whether this session is active or not. */ public void setActive(boolean active) { - mImpl.setActive(active); + if (mActive == active) { + return; + } + try { + mBinder.setActive(active); + mActive = active; + } catch (RemoteException e) { + Log.wtf(TAG, "Failure in setActive.", e); + } } /** @@ -281,7 +360,7 @@ public final class MediaSession { * @return True if the session is active, false otherwise. */ public boolean isActive() { - return mImpl.isActive(); + return mActive; } /** @@ -293,7 +372,14 @@ public final class MediaSession { * @param extras Any extras included with the event */ public void sendSessionEvent(@NonNull String event, @Nullable Bundle extras) { - mImpl.sendSessionEvent(event, extras); + if (TextUtils.isEmpty(event)) { + throw new IllegalArgumentException("event cannot be null or empty"); + } + try { + mBinder.sendEvent(event, extras); + } catch (RemoteException e) { + Log.wtf(TAG, "Error sending event", e); + } } /** @@ -302,7 +388,11 @@ public final class MediaSession { * but it must be released if your activity or service is being destroyed. */ public void release() { - mImpl.close(); + try { + mBinder.destroySession(); + } catch (RemoteException e) { + Log.wtf(TAG, "Error releasing session: ", e); + } } /** @@ -314,7 +404,7 @@ public final class MediaSession { * session */ public @NonNull Token getSessionToken() { - return mImpl.getSessionToken(); + return mSessionToken; } /** @@ -324,7 +414,7 @@ public final class MediaSession { * @return A controller for this session. */ public @NonNull MediaController getController() { - return mImpl.getController(); + return mController; } /** @@ -333,7 +423,12 @@ public final class MediaSession { * @param state The current state of playback */ public void setPlaybackState(@Nullable PlaybackState state) { - mImpl.setPlaybackState(state); + mPlaybackState = state; + try { + mBinder.setPlaybackState(state); + } catch (RemoteException e) { + Log.wtf(TAG, "Dead object in setPlaybackState.", e); + } } /** @@ -345,10 +440,24 @@ public final class MediaSession { * @see android.media.MediaMetadata.Builder#putBitmap */ public void setMetadata(@Nullable MediaMetadata metadata) { + long duration = -1; + int fields = 0; + MediaDescription description = null; if (metadata != null) { - metadata = new MediaMetadata.Builder(metadata, mMaxBitmapSize).build(); + metadata = (new MediaMetadata.Builder(metadata, mMaxBitmapSize)).build(); + if (metadata.containsKey(MediaMetadata.METADATA_KEY_DURATION)) { + duration = metadata.getLong(MediaMetadata.METADATA_KEY_DURATION); + } + fields = metadata.size(); + description = metadata.getDescription(); + } + String metadataDescription = "size=" + fields + ", description=" + description; + + try { + mBinder.setMetadata(metadata, duration, metadataDescription); + } catch (RemoteException e) { + Log.wtf(TAG, "Dead object in setPlaybackState.", e); } - mImpl.setMetadata(metadata); } /** @@ -363,7 +472,11 @@ public final class MediaSession { * @param queue A list of items in the play queue. */ public void setQueue(@Nullable List queue) { - mImpl.setQueue(queue); + try { + mBinder.setQueue(queue == null ? null : new MediaParceledListSlice(queue)); + } catch (RemoteException e) { + Log.wtf("Dead object in setQueue.", e); + } } /** @@ -374,7 +487,11 @@ public final class MediaSession { * @param title The title of the play queue. */ public void setQueueTitle(@Nullable CharSequence title) { - mImpl.setQueueTitle(title); + try { + mBinder.setQueueTitle(title); + } catch (RemoteException e) { + Log.wtf("Dead object in setQueueTitle.", e); + } } /** @@ -391,7 +508,11 @@ public final class MediaSession { * */ public void setRatingType(@Rating.Style int type) { - mImpl.setRatingType(type); + try { + mBinder.setRatingType(type); + } catch (RemoteException e) { + Log.e(TAG, "Error in setRatingType.", e); + } } /** @@ -402,7 +523,11 @@ public final class MediaSession { * @param extras The extras associated with the {@link MediaSession}. */ public void setExtras(@Nullable Bundle extras) { - mImpl.setExtras(extras); + try { + mBinder.setExtras(extras); + } catch (RemoteException e) { + Log.wtf("Dead object in setExtras.", e); + } } /** @@ -414,7 +539,31 @@ public final class MediaSession { * @see MediaSessionManager#isTrustedForMediaControl(RemoteUserInfo) */ public final @NonNull RemoteUserInfo getCurrentControllerInfo() { - return mImpl.getCurrentControllerInfo(); + if (mCallback == null || mCallback.mCurrentControllerInfo == null) { + throw new IllegalStateException( + "This should be called inside of MediaSession.Callback methods"); + } + return mCallback.mCurrentControllerInfo; + } + + /** + * Notify the system that the remote volume changed. + * + * @param provider The provider that is handling volume changes. + * @hide + */ + public void notifyRemoteVolumeChanged(VolumeProvider provider) { + synchronized (mLock) { + if (provider == null || provider != mVolumeProvider) { + Log.w(TAG, "Received update from stale volume provider"); + return; + } + } + try { + mBinder.setCurrentVolume(provider.getCurrentVolume()); + } catch (RemoteException e) { + Log.e(TAG, "Error in notifyVolumeChanged", e); + } } /** @@ -426,7 +575,10 @@ public final class MediaSession { */ @UnsupportedAppUsage public String getCallingPackage() { - return mImpl.getCallingPackage(); + if (mCallback != null && mCallback.mCurrentControllerInfo != null) { + return mCallback.mCurrentControllerInfo.getPackageName(); + } + return null; } /** @@ -435,7 +587,130 @@ public final class MediaSession { * @hide */ public static boolean isActiveState(int state) { - return MediaSessionEngine.isActiveState(state); + switch (state) { + case PlaybackState.STATE_FAST_FORWARDING: + case PlaybackState.STATE_REWINDING: + case PlaybackState.STATE_SKIPPING_TO_PREVIOUS: + case PlaybackState.STATE_SKIPPING_TO_NEXT: + case PlaybackState.STATE_BUFFERING: + case PlaybackState.STATE_CONNECTING: + case PlaybackState.STATE_PLAYING: + return true; + } + return false; + } + + void dispatchPrepare(RemoteUserInfo caller) { + postToCallback(caller, CallbackMessageHandler.MSG_PREPARE, null, null); + } + + void dispatchPrepareFromMediaId(RemoteUserInfo caller, String mediaId, Bundle extras) { + postToCallback(caller, CallbackMessageHandler.MSG_PREPARE_MEDIA_ID, mediaId, extras); + } + + void dispatchPrepareFromSearch(RemoteUserInfo caller, String query, Bundle extras) { + postToCallback(caller, CallbackMessageHandler.MSG_PREPARE_SEARCH, query, extras); + } + + void dispatchPrepareFromUri(RemoteUserInfo caller, Uri uri, Bundle extras) { + postToCallback(caller, CallbackMessageHandler.MSG_PREPARE_URI, uri, extras); + } + + void dispatchPlay(RemoteUserInfo caller) { + postToCallback(caller, CallbackMessageHandler.MSG_PLAY, null, null); + } + + void dispatchPlayFromMediaId(RemoteUserInfo caller, String mediaId, Bundle extras) { + postToCallback(caller, CallbackMessageHandler.MSG_PLAY_MEDIA_ID, mediaId, extras); + } + + void dispatchPlayFromSearch(RemoteUserInfo caller, String query, Bundle extras) { + postToCallback(caller, CallbackMessageHandler.MSG_PLAY_SEARCH, query, extras); + } + + void dispatchPlayFromUri(RemoteUserInfo caller, Uri uri, Bundle extras) { + postToCallback(caller, CallbackMessageHandler.MSG_PLAY_URI, uri, extras); + } + + void dispatchSkipToItem(RemoteUserInfo caller, long id) { + postToCallback(caller, CallbackMessageHandler.MSG_SKIP_TO_ITEM, id, null); + } + + void dispatchPause(RemoteUserInfo caller) { + postToCallback(caller, CallbackMessageHandler.MSG_PAUSE, null, null); + } + + void dispatchStop(RemoteUserInfo caller) { + postToCallback(caller, CallbackMessageHandler.MSG_STOP, null, null); + } + + void dispatchNext(RemoteUserInfo caller) { + postToCallback(caller, CallbackMessageHandler.MSG_NEXT, null, null); + } + + void dispatchPrevious(RemoteUserInfo caller) { + postToCallback(caller, CallbackMessageHandler.MSG_PREVIOUS, null, null); + } + + void dispatchFastForward(RemoteUserInfo caller) { + postToCallback(caller, CallbackMessageHandler.MSG_FAST_FORWARD, null, null); + } + + void dispatchRewind(RemoteUserInfo caller) { + postToCallback(caller, CallbackMessageHandler.MSG_REWIND, null, null); + } + + void dispatchSeekTo(RemoteUserInfo caller, long pos) { + postToCallback(caller, CallbackMessageHandler.MSG_SEEK_TO, pos, null); + } + + void dispatchRate(RemoteUserInfo caller, Rating rating) { + postToCallback(caller, CallbackMessageHandler.MSG_RATE, rating, null); + } + + void dispatchSetPlaybackSpeed(RemoteUserInfo caller, float speed) { + postToCallback(caller, CallbackMessageHandler.MSG_SET_PLAYBACK_SPEED, speed, null); + } + + void dispatchCustomAction(RemoteUserInfo caller, String action, Bundle args) { + postToCallback(caller, CallbackMessageHandler.MSG_CUSTOM_ACTION, action, args); + } + + void dispatchMediaButton(RemoteUserInfo caller, Intent mediaButtonIntent) { + postToCallback(caller, CallbackMessageHandler.MSG_MEDIA_BUTTON, mediaButtonIntent, null); + } + + void dispatchMediaButtonDelayed(RemoteUserInfo info, Intent mediaButtonIntent, + long delay) { + postToCallbackDelayed(info, CallbackMessageHandler.MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT, + mediaButtonIntent, null, delay); + } + + void dispatchAdjustVolume(RemoteUserInfo caller, int direction) { + postToCallback(caller, CallbackMessageHandler.MSG_ADJUST_VOLUME, direction, null); + } + + void dispatchSetVolumeTo(RemoteUserInfo caller, int volume) { + postToCallback(caller, CallbackMessageHandler.MSG_SET_VOLUME, volume, null); + } + + void dispatchCommand(RemoteUserInfo caller, String command, Bundle args, + ResultReceiver resultCb) { + Command cmd = new Command(command, args, resultCb); + postToCallback(caller, CallbackMessageHandler.MSG_COMMAND, cmd, null); + } + + void postToCallback(RemoteUserInfo caller, int what, Object obj, Bundle data) { + postToCallbackDelayed(caller, what, obj, data, 0); + } + + void postToCallbackDelayed(RemoteUserInfo caller, int what, Object obj, Bundle data, + long delay) { + synchronized (mLock) { + if (mCallback != null) { + mCallback.post(caller, what, obj, data, delay); + } + } } /** @@ -534,7 +809,9 @@ public final class MediaSession { */ public abstract static class Callback { - MediaSessionEngine.MediaButtonEventDelegate mMediaButtonEventDelegate; + private MediaSession mSession; + private CallbackMessageHandler mHandler; + private boolean mMediaPlayPauseKeyPending; public Callback() { } @@ -566,12 +843,110 @@ public final class MediaSession { * @return True if the event was handled, false otherwise. */ public boolean onMediaButtonEvent(@NonNull Intent mediaButtonIntent) { - if (mMediaButtonEventDelegate != null) { - return mMediaButtonEventDelegate.onMediaButtonIntent(mediaButtonIntent); + if (mSession != null && mHandler != null + && Intent.ACTION_MEDIA_BUTTON.equals(mediaButtonIntent.getAction())) { + KeyEvent ke = mediaButtonIntent.getParcelableExtra(Intent.EXTRA_KEY_EVENT); + if (ke != null && ke.getAction() == KeyEvent.ACTION_DOWN) { + PlaybackState state = mSession.mPlaybackState; + long validActions = state == null ? 0 : state.getActions(); + switch (ke.getKeyCode()) { + case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE: + case KeyEvent.KEYCODE_HEADSETHOOK: + if (ke.getRepeatCount() > 0) { + // Consider long-press as a single tap. + handleMediaPlayPauseKeySingleTapIfPending(); + } else if (mMediaPlayPauseKeyPending) { + // Consider double tap as the next. + mHandler.removeMessages(CallbackMessageHandler + .MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT); + mMediaPlayPauseKeyPending = false; + if ((validActions & PlaybackState.ACTION_SKIP_TO_NEXT) != 0) { + onSkipToNext(); + } + } else { + mMediaPlayPauseKeyPending = true; + mSession.dispatchMediaButtonDelayed( + mSession.getCurrentControllerInfo(), + mediaButtonIntent, ViewConfiguration.getDoubleTapTimeout()); + } + return true; + default: + // If another key is pressed within double tap timeout, consider the + // pending play/pause as a single tap to handle media keys in order. + handleMediaPlayPauseKeySingleTapIfPending(); + break; + } + + switch (ke.getKeyCode()) { + case KeyEvent.KEYCODE_MEDIA_PLAY: + if ((validActions & PlaybackState.ACTION_PLAY) != 0) { + onPlay(); + return true; + } + break; + case KeyEvent.KEYCODE_MEDIA_PAUSE: + if ((validActions & PlaybackState.ACTION_PAUSE) != 0) { + onPause(); + return true; + } + break; + case KeyEvent.KEYCODE_MEDIA_NEXT: + if ((validActions & PlaybackState.ACTION_SKIP_TO_NEXT) != 0) { + onSkipToNext(); + return true; + } + break; + case KeyEvent.KEYCODE_MEDIA_PREVIOUS: + if ((validActions & PlaybackState.ACTION_SKIP_TO_PREVIOUS) != 0) { + onSkipToPrevious(); + return true; + } + break; + case KeyEvent.KEYCODE_MEDIA_STOP: + if ((validActions & PlaybackState.ACTION_STOP) != 0) { + onStop(); + return true; + } + break; + case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD: + if ((validActions & PlaybackState.ACTION_FAST_FORWARD) != 0) { + onFastForward(); + return true; + } + break; + case KeyEvent.KEYCODE_MEDIA_REWIND: + if ((validActions & PlaybackState.ACTION_REWIND) != 0) { + onRewind(); + return true; + } + break; + } + } } return false; } + private void handleMediaPlayPauseKeySingleTapIfPending() { + if (!mMediaPlayPauseKeyPending) { + return; + } + mMediaPlayPauseKeyPending = false; + mHandler.removeMessages(CallbackMessageHandler.MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT); + PlaybackState state = mSession.mPlaybackState; + long validActions = state == null ? 0 : state.getActions(); + boolean isPlaying = state != null + && state.getState() == PlaybackState.STATE_PLAYING; + boolean canPlay = (validActions & (PlaybackState.ACTION_PLAY_PAUSE + | PlaybackState.ACTION_PLAY)) != 0; + boolean canPause = (validActions & (PlaybackState.ACTION_PLAY_PAUSE + | PlaybackState.ACTION_PAUSE)) != 0; + if (isPlaying && canPause) { + onPause(); + } else if (!isPlaying && canPlay) { + onPlay(); + } + } + /** * Override to handle requests to prepare playback. During the preparation, a session should * not hold audio focus in order to allow other sessions play seamlessly. The state of @@ -727,13 +1102,259 @@ public final class MediaSession { */ public void onCustomAction(@NonNull String action, @Nullable Bundle extras) { } + } + + /** + * @hide + */ + public static class CallbackStub extends ISessionCallback.Stub { + private WeakReference mMediaSession; + + public CallbackStub(MediaSession session) { + mMediaSession = new WeakReference<>(session); + } - /** - * @hide - */ - public void onSetMediaButtonEventDelegate( - @NonNull MediaSessionEngine.MediaButtonEventDelegate delegate) { - mMediaButtonEventDelegate = delegate; + private static RemoteUserInfo createRemoteUserInfo(String packageName, int pid, int uid) { + return new RemoteUserInfo(packageName, pid, uid); + } + + @Override + public void onCommand(String packageName, int pid, int uid, + ControllerCallbackLink caller, String command, Bundle args, ResultReceiver cb) { + MediaSession session = mMediaSession.get(); + if (session != null) { + session.dispatchCommand(createRemoteUserInfo(packageName, pid, uid), + command, args, cb); + } + } + + @Override + public void onMediaButton(String packageName, int pid, int uid, Intent mediaButtonIntent, + int sequenceNumber, ResultReceiver cb) { + MediaSession session = mMediaSession.get(); + try { + if (session != null) { + session.dispatchMediaButton(createRemoteUserInfo(packageName, pid, uid), + mediaButtonIntent); + } + } finally { + if (cb != null) { + cb.send(sequenceNumber, null); + } + } + } + + @Override + public void onMediaButtonFromController(String packageName, int pid, int uid, + ControllerCallbackLink caller, Intent mediaButtonIntent) { + MediaSession session = mMediaSession.get(); + if (session != null) { + session.dispatchMediaButton(createRemoteUserInfo(packageName, pid, uid), + mediaButtonIntent); + } + } + + @Override + public void onPrepare(String packageName, int pid, int uid, + ControllerCallbackLink caller) { + MediaSession session = mMediaSession.get(); + if (session != null) { + session.dispatchPrepare(createRemoteUserInfo(packageName, pid, uid)); + } + } + + @Override + public void onPrepareFromMediaId(String packageName, int pid, int uid, + ControllerCallbackLink caller, String mediaId, + Bundle extras) { + MediaSession session = mMediaSession.get(); + if (session != null) { + session.dispatchPrepareFromMediaId( + createRemoteUserInfo(packageName, pid, uid), mediaId, extras); + } + } + + @Override + public void onPrepareFromSearch(String packageName, int pid, int uid, + ControllerCallbackLink caller, String query, + Bundle extras) { + MediaSession session = mMediaSession.get(); + if (session != null) { + session.dispatchPrepareFromSearch( + createRemoteUserInfo(packageName, pid, uid), query, extras); + } + } + + @Override + public void onPrepareFromUri(String packageName, int pid, int uid, + ControllerCallbackLink caller, Uri uri, Bundle extras) { + MediaSession session = mMediaSession.get(); + if (session != null) { + session.dispatchPrepareFromUri(createRemoteUserInfo(packageName, pid, uid), + uri, extras); + } + } + + @Override + public void onPlay(String packageName, int pid, int uid, + ControllerCallbackLink caller) { + MediaSession session = mMediaSession.get(); + if (session != null) { + session.dispatchPlay(createRemoteUserInfo(packageName, pid, uid)); + } + } + + @Override + public void onPlayFromMediaId(String packageName, int pid, int uid, + ControllerCallbackLink caller, String mediaId, + Bundle extras) { + MediaSession session = mMediaSession.get(); + if (session != null) { + session.dispatchPlayFromMediaId(createRemoteUserInfo(packageName, pid, uid), + mediaId, extras); + } + } + + @Override + public void onPlayFromSearch(String packageName, int pid, int uid, + ControllerCallbackLink caller, String query, + Bundle extras) { + MediaSession session = mMediaSession.get(); + if (session != null) { + session.dispatchPlayFromSearch(createRemoteUserInfo(packageName, pid, uid), + query, extras); + } + } + + @Override + public void onPlayFromUri(String packageName, int pid, int uid, + ControllerCallbackLink caller, Uri uri, Bundle extras) { + MediaSession session = mMediaSession.get(); + if (session != null) { + session.dispatchPlayFromUri(createRemoteUserInfo(packageName, pid, uid), + uri, extras); + } + } + + @Override + public void onSkipToTrack(String packageName, int pid, int uid, + ControllerCallbackLink caller, long id) { + MediaSession session = mMediaSession.get(); + if (session != null) { + session.dispatchSkipToItem(createRemoteUserInfo(packageName, pid, uid), id); + } + } + + @Override + public void onPause(String packageName, int pid, int uid, + ControllerCallbackLink caller) { + MediaSession session = mMediaSession.get(); + if (session != null) { + session.dispatchPause(createRemoteUserInfo(packageName, pid, uid)); + } + } + + @Override + public void onStop(String packageName, int pid, int uid, + ControllerCallbackLink caller) { + MediaSession session = mMediaSession.get(); + if (session != null) { + session.dispatchStop(createRemoteUserInfo(packageName, pid, uid)); + } + } + + @Override + public void onNext(String packageName, int pid, int uid, + ControllerCallbackLink caller) { + MediaSession session = mMediaSession.get(); + if (session != null) { + session.dispatchNext(createRemoteUserInfo(packageName, pid, uid)); + } + } + + @Override + public void onPrevious(String packageName, int pid, int uid, + ControllerCallbackLink caller) { + MediaSession session = mMediaSession.get(); + if (session != null) { + session.dispatchPrevious(createRemoteUserInfo(packageName, pid, uid)); + } + } + + @Override + public void onFastForward(String packageName, int pid, int uid, + ControllerCallbackLink caller) { + MediaSession session = mMediaSession.get(); + if (session != null) { + session.dispatchFastForward(createRemoteUserInfo(packageName, pid, uid)); + } + } + + @Override + public void onRewind(String packageName, int pid, int uid, + ControllerCallbackLink caller) { + MediaSession session = mMediaSession.get(); + if (session != null) { + session.dispatchRewind(createRemoteUserInfo(packageName, pid, uid)); + } + } + + @Override + public void onSeekTo(String packageName, int pid, int uid, + ControllerCallbackLink caller, long pos) { + MediaSession session = mMediaSession.get(); + if (session != null) { + session.dispatchSeekTo(createRemoteUserInfo(packageName, pid, uid), pos); + } + } + + @Override + public void onRate(String packageName, int pid, int uid, ControllerCallbackLink caller, + Rating rating) { + MediaSession session = mMediaSession.get(); + if (session != null) { + session.dispatchRate(createRemoteUserInfo(packageName, pid, uid), rating); + } + } + + @Override + public void onSetPlaybackSpeed(String packageName, int pid, int uid, + ControllerCallbackLink caller, float speed) { + MediaSession session = mMediaSession.get(); + if (session != null) { + session.dispatchSetPlaybackSpeed( + createRemoteUserInfo(packageName, pid, uid), speed); + } + } + + @Override + public void onCustomAction(String packageName, int pid, int uid, + ControllerCallbackLink caller, String action, Bundle args) { + MediaSession session = mMediaSession.get(); + if (session != null) { + session.dispatchCustomAction(createRemoteUserInfo(packageName, pid, uid), + action, args); + } + } + + @Override + public void onAdjustVolume(String packageName, int pid, int uid, + ControllerCallbackLink caller, int direction) { + MediaSession session = mMediaSession.get(); + if (session != null) { + session.dispatchAdjustVolume(createRemoteUserInfo(packageName, pid, uid), + direction); + } + } + + @Override + public void onSetVolumeTo(String packageName, int pid, int uid, + ControllerCallbackLink caller, int value) { + MediaSession session = mMediaSession.get(); + if (session != null) { + session.dispatchSetVolumeTo(createRemoteUserInfo(packageName, pid, uid), + value); + } } } @@ -747,7 +1368,7 @@ public final class MediaSession { */ public static final int UNKNOWN_ID = -1; - private final MediaSessionEngine.QueueItem mImpl; + private final MediaDescription mDescription; @UnsupportedAppUsage private final long mId; @@ -759,32 +1380,39 @@ public final class MediaSession { * play queue and cannot be {@link #UNKNOWN_ID}. */ public QueueItem(MediaDescription description, long id) { - mImpl = new MediaSessionEngine.QueueItem(description, id); + if (description == null) { + throw new IllegalArgumentException("Description cannot be null."); + } + if (id == UNKNOWN_ID) { + throw new IllegalArgumentException("Id cannot be QueueItem.UNKNOWN_ID"); + } + mDescription = description; mId = id; } private QueueItem(Parcel in) { - mImpl = new MediaSessionEngine.QueueItem(in); - mId = mImpl.getQueueId(); + mDescription = MediaDescription.CREATOR.createFromParcel(in); + mId = in.readLong(); } /** * Get the description for this item. */ public MediaDescription getDescription() { - return mImpl.getDescription(); + return mDescription; } /** * Get the queue id for this item. */ public long getQueueId() { - return mImpl.getQueueId(); + return mId; } @Override public void writeToParcel(Parcel dest, int flags) { - mImpl.writeToParcel(dest, flags); + mDescription.writeToParcel(dest, flags); + dest.writeLong(mId); } @Override @@ -795,20 +1423,21 @@ public final class MediaSession { public static final @android.annotation.NonNull Creator CREATOR = new Creator() { - @Override - public MediaSession.QueueItem createFromParcel(Parcel p) { - return new MediaSession.QueueItem(p); - } + @Override + public MediaSession.QueueItem createFromParcel(Parcel p) { + return new MediaSession.QueueItem(p); + } - @Override - public MediaSession.QueueItem[] newArray(int size) { - return new MediaSession.QueueItem[size]; - } - }; + @Override + public MediaSession.QueueItem[] newArray(int size) { + return new MediaSession.QueueItem[size]; + } + }; @Override public String toString() { - return mImpl.toString(); + return "MediaSession.QueueItem {" + "Description=" + mDescription + ", Id=" + mId + + " }"; } @Override @@ -821,7 +1450,171 @@ public final class MediaSession { return false; } - return mImpl.equals(((QueueItem) o).mImpl); + final QueueItem item = (QueueItem) o; + if (mId != item.mId) { + return false; + } + + if (!Objects.equals(mDescription, item.mDescription)) { + return false; + } + + return true; + } + } + + private static final class Command { + public final String command; + public final Bundle extras; + public final ResultReceiver stub; + + Command(String command, Bundle extras, ResultReceiver stub) { + this.command = command; + this.extras = extras; + this.stub = stub; + } + } + + private class CallbackMessageHandler extends Handler { + private static final int MSG_COMMAND = 1; + private static final int MSG_MEDIA_BUTTON = 2; + private static final int MSG_PREPARE = 3; + private static final int MSG_PREPARE_MEDIA_ID = 4; + private static final int MSG_PREPARE_SEARCH = 5; + private static final int MSG_PREPARE_URI = 6; + private static final int MSG_PLAY = 7; + private static final int MSG_PLAY_MEDIA_ID = 8; + private static final int MSG_PLAY_SEARCH = 9; + private static final int MSG_PLAY_URI = 10; + private static final int MSG_SKIP_TO_ITEM = 11; + private static final int MSG_PAUSE = 12; + private static final int MSG_STOP = 13; + private static final int MSG_NEXT = 14; + private static final int MSG_PREVIOUS = 15; + private static final int MSG_FAST_FORWARD = 16; + private static final int MSG_REWIND = 17; + private static final int MSG_SEEK_TO = 18; + private static final int MSG_RATE = 19; + private static final int MSG_SET_PLAYBACK_SPEED = 20; + private static final int MSG_CUSTOM_ACTION = 21; + private static final int MSG_ADJUST_VOLUME = 22; + private static final int MSG_SET_VOLUME = 23; + private static final int MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT = 24; + + private MediaSession.Callback mCallback; + private RemoteUserInfo mCurrentControllerInfo; + + CallbackMessageHandler(Looper looper, MediaSession.Callback callback) { + super(looper); + mCallback = callback; + mCallback.mHandler = this; + } + + void post(RemoteUserInfo caller, int what, Object obj, Bundle data, long delayMs) { + Pair objWithCaller = Pair.create(caller, obj); + Message msg = obtainMessage(what, objWithCaller); + msg.setAsynchronous(true); + msg.setData(data); + if (delayMs > 0) { + sendMessageDelayed(msg, delayMs); + } else { + sendMessage(msg); + } + } + + @Override + public void handleMessage(Message msg) { + mCurrentControllerInfo = ((Pair) msg.obj).first; + + VolumeProvider vp; + Object obj = ((Pair) msg.obj).second; + + switch (msg.what) { + case MSG_COMMAND: + Command cmd = (Command) obj; + mCallback.onCommand(cmd.command, cmd.extras, cmd.stub); + break; + case MSG_MEDIA_BUTTON: + mCallback.onMediaButtonEvent((Intent) obj); + break; + case MSG_PREPARE: + mCallback.onPrepare(); + break; + case MSG_PREPARE_MEDIA_ID: + mCallback.onPrepareFromMediaId((String) obj, msg.getData()); + break; + case MSG_PREPARE_SEARCH: + mCallback.onPrepareFromSearch((String) obj, msg.getData()); + break; + case MSG_PREPARE_URI: + mCallback.onPrepareFromUri((Uri) obj, msg.getData()); + break; + case MSG_PLAY: + mCallback.onPlay(); + break; + case MSG_PLAY_MEDIA_ID: + mCallback.onPlayFromMediaId((String) obj, msg.getData()); + break; + case MSG_PLAY_SEARCH: + mCallback.onPlayFromSearch((String) obj, msg.getData()); + break; + case MSG_PLAY_URI: + mCallback.onPlayFromUri((Uri) obj, msg.getData()); + break; + case MSG_SKIP_TO_ITEM: + mCallback.onSkipToQueueItem((Long) obj); + break; + case MSG_PAUSE: + mCallback.onPause(); + break; + case MSG_STOP: + mCallback.onStop(); + break; + case MSG_NEXT: + mCallback.onSkipToNext(); + break; + case MSG_PREVIOUS: + mCallback.onSkipToPrevious(); + break; + case MSG_FAST_FORWARD: + mCallback.onFastForward(); + break; + case MSG_REWIND: + mCallback.onRewind(); + break; + case MSG_SEEK_TO: + mCallback.onSeekTo((Long) obj); + break; + case MSG_RATE: + mCallback.onSetRating((Rating) obj); + break; + case MSG_SET_PLAYBACK_SPEED: + mCallback.onSetPlaybackSpeed((Float) obj); + break; + case MSG_CUSTOM_ACTION: + mCallback.onCustomAction((String) obj, msg.getData()); + break; + case MSG_ADJUST_VOLUME: + synchronized (mLock) { + vp = mVolumeProvider; + } + if (vp != null) { + vp.onAdjustVolume((int) obj); + } + break; + case MSG_SET_VOLUME: + synchronized (mLock) { + vp = mVolumeProvider; + } + if (vp != null) { + vp.onSetVolumeTo((int) obj); + } + break; + case MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT: + mCallback.handleMediaPlayPauseKeySingleTapIfPending(); + break; + } + mCurrentControllerInfo = null; } } } diff --git a/media/java/android/media/session/MediaSessionEngine.java b/media/java/android/media/session/MediaSessionEngine.java deleted file mode 100644 index 7c5243ac31cdb7b30a73ffb1d20746d187cf58a8..0000000000000000000000000000000000000000 --- a/media/java/android/media/session/MediaSessionEngine.java +++ /dev/null @@ -1,1236 +0,0 @@ -/* - * Copyright 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.media.session; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.app.Activity; -import android.app.PendingIntent; -import android.content.Context; -import android.content.Intent; -import android.media.AudioAttributes; -import android.media.MediaDescription; -import android.media.MediaMetadata; -import android.media.MediaParceledListSlice; -import android.media.Rating; -import android.media.VolumeProvider; -import android.media.session.MediaSessionManager.RemoteUserInfo; -import android.net.Uri; -import android.os.Bundle; -import android.os.Handler; -import android.os.Looper; -import android.os.Message; -import android.os.Parcel; -import android.os.RemoteException; -import android.os.ResultReceiver; -import android.service.media.MediaBrowserService; -import android.text.TextUtils; -import android.util.Log; -import android.util.Pair; -import android.view.KeyEvent; -import android.view.ViewConfiguration; - -import java.util.List; -import java.util.Objects; - -/** - * @hide - */ -public final class MediaSessionEngine implements AutoCloseable { - private static final String TAG = "MediaSession"; - - private final Object mLock = new Object(); - - private final MediaSession.Token mSessionToken; - private final MediaController mController; - private final ISession mBinder; - - private CallbackMessageHandler mCallbackHandler; - private VolumeProvider mVolumeProvider; - private PlaybackState mPlaybackState; - - private boolean mActive = false; - - /** - * Creates a new session. The session will automatically be registered with - * the system but will not be published until {@link #setActive(boolean) - * setActive(true)} is called. You must call {@link #close()} when - * finished with the session. - * - * @param context The context to use to create the session. - * @param binder A session binder - */ - public MediaSessionEngine(@NonNull Context context, @NonNull ISession binder, - @NonNull SessionCallbackLink cbLink) throws RemoteException { - mBinder = binder; - - cbLink.setSessionEngine(this); - mSessionToken = new MediaSession.Token(mBinder.getController()); - mController = new MediaController(context, mSessionToken); - } - - /** - * Set the callback to receive updates for the MediaSession. This includes - * media button events and transport controls. The caller's thread will be - * used to post updates. - *

- * Set the callback to null to stop receiving updates. - * - * @param callback The callback object - */ - public void setCallback(@Nullable MediaSession.Callback callback) { - setCallback(callback, new Handler()); - } - - /** - * Set the callback to receive updates for the MediaSession. This includes - * media button events and transport controls. - *

- * Set the callback to null to stop receiving updates. - * - * @param callback The callback to receive updates on. - * @param handler The handler that events should be posted on. - */ - public void setCallback(@Nullable MediaSession.Callback callback, @NonNull Handler handler) { - setCallbackInternal(callback == null ? null : new CallbackWrapper(callback), handler); - } - - private void setCallbackInternal(CallbackWrapper callback, Handler handler) { - synchronized (mLock) { - if (mCallbackHandler != null) { - // We're updating the callback, clear the session from the old one. - mCallbackHandler.mCallbackWrapper.mSessionImpl = null; - mCallbackHandler.removeCallbacksAndMessages(null); - } - if (callback == null) { - mCallbackHandler = null; - return; - } - callback.mSessionImpl = this; - CallbackMessageHandler msgHandler = new CallbackMessageHandler(handler.getLooper(), - callback); - mCallbackHandler = msgHandler; - } - } - - /** - * Set an intent for launching UI for this Session. This can be used as a - * quick link to an ongoing media screen. The intent should be for an - * activity that may be started using {@link Activity#startActivity(Intent)}. - * - * @param pi The intent to launch to show UI for this Session. - */ - public void setSessionActivity(@Nullable PendingIntent pi) { - try { - mBinder.setLaunchPendingIntent(pi); - } catch (RemoteException e) { - Log.wtf(TAG, "Failure in setLaunchPendingIntent.", e); - } - } - - /** - * Set a pending intent for your media button receiver to allow restarting - * playback after the session has been stopped. If your app is started in - * this way an {@link Intent#ACTION_MEDIA_BUTTON} intent will be sent via - * the pending intent. - * - * @param mbr The {@link PendingIntent} to send the media button event to. - */ - public void setMediaButtonReceiver(@Nullable PendingIntent mbr) { - try { - mBinder.setMediaButtonReceiver(mbr); - } catch (RemoteException e) { - Log.wtf(TAG, "Failure in setMediaButtonReceiver.", e); - } - } - - /** - * Set any flags for the session. - * - * @param flags The flags to set for this session. - */ - public void setFlags(int flags) { - try { - mBinder.setFlags(flags); - } catch (RemoteException e) { - Log.wtf(TAG, "Failure in setFlags.", e); - } - } - - /** - * Set the attributes for this session's audio. This will affect the - * system's volume handling for this session. If - * {@link #setPlaybackToRemote} was previously called it will stop receiving - * volume commands and the system will begin sending volume changes to the - * appropriate stream. - *

- * By default sessions use attributes for media. - * - * @param attributes The {@link AudioAttributes} for this session's audio. - */ - public void setPlaybackToLocal(AudioAttributes attributes) { - if (attributes == null) { - throw new IllegalArgumentException("Attributes cannot be null for local playback."); - } - try { - mBinder.setPlaybackToLocal(attributes); - } catch (RemoteException e) { - Log.wtf(TAG, "Failure in setPlaybackToLocal.", e); - } - } - - /** - * Configure this session to use remote volume handling. This must be called - * to receive volume button events, otherwise the system will adjust the - * appropriate stream volume for this session. If - * {@link #setPlaybackToLocal} was previously called the system will stop - * handling volume changes for this session and pass them to the volume - * provider instead. - * - * @param volumeProvider The provider that will handle volume changes. May - * not be null. - */ - public void setPlaybackToRemote(@NonNull VolumeProvider volumeProvider) { - if (volumeProvider == null) { - throw new IllegalArgumentException("volumeProvider may not be null!"); - } - synchronized (mLock) { - mVolumeProvider = volumeProvider; - } - volumeProvider.setCallback(new VolumeProvider.Callback() { - @Override - public void onVolumeChanged(VolumeProvider volumeProvider) { - notifyRemoteVolumeChanged(volumeProvider); - } - }); - - try { - mBinder.setPlaybackToRemote(volumeProvider.getVolumeControl(), - volumeProvider.getMaxVolume()); - mBinder.setCurrentVolume(volumeProvider.getCurrentVolume()); - } catch (RemoteException e) { - Log.wtf(TAG, "Failure in setPlaybackToRemote.", e); - } - } - - /** - * Set if this session is currently active and ready to receive commands. If - * set to false your session's controller may not be discoverable. You must - * set the session to active before it can start receiving media button - * events or transport commands. - * - * @param active Whether this session is active or not. - */ - public void setActive(boolean active) { - if (mActive == active) { - return; - } - try { - mBinder.setActive(active); - mActive = active; - } catch (RemoteException e) { - Log.wtf(TAG, "Failure in setActive.", e); - } - } - - /** - * Get the current active state of this session. - * - * @return True if the session is active, false otherwise. - */ - public boolean isActive() { - return mActive; - } - - /** - * Send a proprietary event to all MediaControllers listening to this - * Session. It's up to the Controller/Session owner to determine the meaning - * of any events. - * - * @param event The name of the event to send - * @param extras Any extras included with the event - */ - public void sendSessionEvent(@NonNull String event, @Nullable Bundle extras) { - if (TextUtils.isEmpty(event)) { - throw new IllegalArgumentException("event cannot be null or empty"); - } - try { - mBinder.sendEvent(event, extras); - } catch (RemoteException e) { - Log.wtf(TAG, "Error sending event", e); - } - } - - /** - * This must be called when an app has finished performing playback. If - * playback is expected to start again shortly the session can be left open, - * but it must be released if your activity or service is being destroyed. - */ - public void close() { - try { - mBinder.destroySession(); - } catch (RemoteException e) { - Log.wtf(TAG, "Error releasing session: ", e); - } - } - - /** - * Retrieve a token object that can be used by apps to create a - * {@link MediaController} for interacting with this session. The owner of - * the session is responsible for deciding how to distribute these tokens. - * - * @return A token that can be used to create a MediaController for this - * session - */ - public @NonNull MediaSession.Token getSessionToken() { - return mSessionToken; - } - - /** - * Get a controller for this session. This is a convenience method to avoid - * having to cache your own controller in process. - * - * @return A controller for this session. - */ - public @NonNull MediaController getController() { - return mController; - } - - /** - * Update the current playback state. - * - * @param state The current state of playback - */ - public void setPlaybackState(@Nullable PlaybackState state) { - mPlaybackState = state; - try { - mBinder.setPlaybackState(state); - } catch (RemoteException e) { - Log.wtf(TAG, "Dead object in setPlaybackState.", e); - } - } - - /** - * Update the current metadata. New metadata can be created using - * {@link android.media.MediaMetadata.Builder}. This operation may take time proportional to - * the size of the bitmap to replace large bitmaps with a scaled down copy. - * - * @param metadata The new metadata - * @see android.media.MediaMetadata.Builder#putBitmap - */ - public void setMetadata(@Nullable MediaMetadata metadata) { - long duration = -1; - int fields = 0; - MediaDescription description = null; - if (metadata != null) { - if (metadata.containsKey(MediaMetadata.METADATA_KEY_DURATION)) { - duration = metadata.getLong(MediaMetadata.METADATA_KEY_DURATION); - } - fields = metadata.size(); - description = metadata.getDescription(); - } - String metadataDescription = "size=" + fields + ", description=" + description; - - try { - mBinder.setMetadata(metadata, duration, metadataDescription); - } catch (RemoteException e) { - Log.wtf(TAG, "Dead object in setPlaybackState.", e); - } - } - - /** - * Update the list of items in the play queue. It is an ordered list and - * should contain the current item, and previous or upcoming items if they - * exist. Specify null if there is no current play queue. - *

- * The queue should be of reasonable size. If the play queue is unbounded - * within your app, it is better to send a reasonable amount in a sliding - * window instead. - * - * @param queue A list of items in the play queue. - */ - public void setQueue(@Nullable List queue) { - try { - mBinder.setQueue(queue == null ? null : new MediaParceledListSlice(queue)); - } catch (RemoteException e) { - Log.wtf("Dead object in setQueue.", e); - } - } - - /** - * Set the title of the play queue. The UI should display this title along - * with the play queue itself. - * e.g. "Play Queue", "Now Playing", or an album name. - * - * @param title The title of the play queue. - */ - public void setQueueTitle(@Nullable CharSequence title) { - try { - mBinder.setQueueTitle(title); - } catch (RemoteException e) { - Log.wtf("Dead object in setQueueTitle.", e); - } - } - - /** - * Set the style of rating used by this session. Apps trying to set the - * rating should use this style. Must be one of the following: - *

    - *
  • {@link Rating#RATING_NONE}
  • - *
  • {@link Rating#RATING_3_STARS}
  • - *
  • {@link Rating#RATING_4_STARS}
  • - *
  • {@link Rating#RATING_5_STARS}
  • - *
  • {@link Rating#RATING_HEART}
  • - *
  • {@link Rating#RATING_PERCENTAGE}
  • - *
  • {@link Rating#RATING_THUMB_UP_DOWN}
  • - *
- */ - public void setRatingType(int type) { - try { - mBinder.setRatingType(type); - } catch (RemoteException e) { - Log.e(TAG, "Error in setRatingType.", e); - } - } - - /** - * Set some extras that can be associated with the {@link MediaSession}. No assumptions should - * be made as to how a {@link MediaController} will handle these extras. - * Keys should be fully qualified (e.g. com.example.MY_EXTRA) to avoid conflicts. - * - * @param extras The extras associated with the {@link MediaSession}. - */ - public void setExtras(@Nullable Bundle extras) { - try { - mBinder.setExtras(extras); - } catch (RemoteException e) { - Log.wtf("Dead object in setExtras.", e); - } - } - - /** - * Gets the controller information who sent the current request. - *

- * Note: This is only valid while in a request callback, such as - * {@link MediaSession.Callback#onPlay}. - * - * @throws IllegalStateException If this method is called outside of - * {@link MediaSession.Callback} methods. - * @see MediaSessionManager#isTrustedForMediaControl(RemoteUserInfo) - */ - public @NonNull RemoteUserInfo getCurrentControllerInfo() { - if (mCallbackHandler == null || mCallbackHandler.mCurrentControllerInfo == null) { - throw new IllegalStateException( - "This should be called inside of MediaSession.Callback methods"); - } - return mCallbackHandler.mCurrentControllerInfo; - } - - /** - * Returns the name of the package that sent the last media button, transport control, or - * command from controllers and the system. This is only valid while in a request callback, such - * as {@link MediaSession.Callback#onPlay}. - */ - public String getCallingPackage() { - if (mCallbackHandler != null && mCallbackHandler.mCurrentControllerInfo != null) { - return mCallbackHandler.mCurrentControllerInfo.getPackageName(); - } - return null; - } - - - /** - * Notify the system that the remote volume changed. - * - * @param provider The provider that is handling volume changes. - */ - private void notifyRemoteVolumeChanged(VolumeProvider provider) { - synchronized (mLock) { - if (provider == null || provider != mVolumeProvider) { - Log.w(TAG, "Received update from stale volume provider"); - return; - } - } - try { - mBinder.setCurrentVolume(provider.getCurrentVolume()); - } catch (RemoteException e) { - Log.e(TAG, "Error in notifyVolumeChanged", e); - } - } - - void dispatchPrepare(RemoteUserInfo caller) { - postToCallback(caller, CallbackMessageHandler.MSG_PREPARE, null, null); - } - - void dispatchPrepareFromMediaId(RemoteUserInfo caller, String mediaId, Bundle extras) { - postToCallback(caller, CallbackMessageHandler.MSG_PREPARE_MEDIA_ID, mediaId, extras); - } - - void dispatchPrepareFromSearch(RemoteUserInfo caller, String query, Bundle extras) { - postToCallback(caller, CallbackMessageHandler.MSG_PREPARE_SEARCH, query, extras); - } - - void dispatchPrepareFromUri(RemoteUserInfo caller, Uri uri, Bundle extras) { - postToCallback(caller, CallbackMessageHandler.MSG_PREPARE_URI, uri, extras); - } - - void dispatchPlay(RemoteUserInfo caller) { - postToCallback(caller, CallbackMessageHandler.MSG_PLAY, null, null); - } - - void dispatchPlayFromMediaId(RemoteUserInfo caller, String mediaId, Bundle extras) { - postToCallback(caller, CallbackMessageHandler.MSG_PLAY_MEDIA_ID, mediaId, extras); - } - - void dispatchPlayFromSearch(RemoteUserInfo caller, String query, Bundle extras) { - postToCallback(caller, CallbackMessageHandler.MSG_PLAY_SEARCH, query, extras); - } - - void dispatchPlayFromUri(RemoteUserInfo caller, Uri uri, Bundle extras) { - postToCallback(caller, CallbackMessageHandler.MSG_PLAY_URI, uri, extras); - } - - void dispatchSkipToItem(RemoteUserInfo caller, long id) { - postToCallback(caller, CallbackMessageHandler.MSG_SKIP_TO_ITEM, id, null); - } - - void dispatchPause(RemoteUserInfo caller) { - postToCallback(caller, CallbackMessageHandler.MSG_PAUSE, null, null); - } - - void dispatchStop(RemoteUserInfo caller) { - postToCallback(caller, CallbackMessageHandler.MSG_STOP, null, null); - } - - void dispatchNext(RemoteUserInfo caller) { - postToCallback(caller, CallbackMessageHandler.MSG_NEXT, null, null); - } - - void dispatchPrevious(RemoteUserInfo caller) { - postToCallback(caller, CallbackMessageHandler.MSG_PREVIOUS, null, null); - } - - void dispatchFastForward(RemoteUserInfo caller) { - postToCallback(caller, CallbackMessageHandler.MSG_FAST_FORWARD, null, null); - } - - void dispatchRewind(RemoteUserInfo caller) { - postToCallback(caller, CallbackMessageHandler.MSG_REWIND, null, null); - } - - void dispatchSeekTo(RemoteUserInfo caller, long pos) { - postToCallback(caller, CallbackMessageHandler.MSG_SEEK_TO, pos, null); - } - - void dispatchRate(RemoteUserInfo caller, Rating rating) { - postToCallback(caller, CallbackMessageHandler.MSG_RATE, rating, null); - } - - void dispatchSetPlaybackSpeed(RemoteUserInfo caller, float speed) { - postToCallback(caller, CallbackMessageHandler.MSG_SET_PLAYBACK_SPEED, speed, null); - } - - void dispatchCustomAction(RemoteUserInfo caller, String action, Bundle args) { - postToCallback(caller, CallbackMessageHandler.MSG_CUSTOM_ACTION, action, args); - } - - void dispatchMediaButton(RemoteUserInfo caller, Intent mediaButtonIntent) { - postToCallback(caller, CallbackMessageHandler.MSG_MEDIA_BUTTON, mediaButtonIntent, null); - } - - void dispatchMediaButtonDelayed(RemoteUserInfo info, Intent mediaButtonIntent, - long delay) { - postToCallbackDelayed(info, CallbackMessageHandler.MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT, - mediaButtonIntent, null, delay); - } - - void dispatchAdjustVolume(RemoteUserInfo caller, int direction) { - postToCallback(caller, CallbackMessageHandler.MSG_ADJUST_VOLUME, direction, null); - } - - void dispatchSetVolumeTo(RemoteUserInfo caller, int volume) { - postToCallback(caller, CallbackMessageHandler.MSG_SET_VOLUME, volume, null); - } - - void dispatchCommand(RemoteUserInfo caller, String command, Bundle args, - ResultReceiver resultCb) { - Command cmd = new Command(command, args, resultCb); - postToCallback(caller, CallbackMessageHandler.MSG_COMMAND, cmd, null); - } - - private void postToCallback(RemoteUserInfo caller, int what, Object obj, Bundle data) { - postToCallbackDelayed(caller, what, obj, data, 0); - } - - private void postToCallbackDelayed(RemoteUserInfo caller, int what, Object obj, Bundle data, - long delay) { - synchronized (mLock) { - if (mCallbackHandler != null) { - mCallbackHandler.post(caller, what, obj, data, delay); - } - } - } - - /** - * Return true if this is considered an active playback state. - */ - public static boolean isActiveState(int state) { - switch (state) { - case PlaybackState.STATE_FAST_FORWARDING: - case PlaybackState.STATE_REWINDING: - case PlaybackState.STATE_SKIPPING_TO_PREVIOUS: - case PlaybackState.STATE_SKIPPING_TO_NEXT: - case PlaybackState.STATE_BUFFERING: - case PlaybackState.STATE_CONNECTING: - case PlaybackState.STATE_PLAYING: - return true; - } - return false; - } - - /** - * Interface for handling MediaButtoneEvent - */ - public interface MediaButtonEventDelegate { - /** - * Called when a media button is pressed and this session has the - * highest priority or a controller sends a media button event to the - * session. - * - * @param mediaButtonIntent an intent containing the KeyEvent as an extra - * @return True if the event was handled, false otherwise. - */ - boolean onMediaButtonIntent(Intent mediaButtonIntent); - } - - /** - * Receives media buttons, transport controls, and commands from controllers - * and the system. A callback may be set using {@link #setCallback}. - * @hide - */ - public static class CallbackWrapper implements MediaButtonEventDelegate { - - private final MediaSession.Callback mCallback; - - @SuppressWarnings("WeakerAccess") /* synthetic access */ - MediaSessionEngine mSessionImpl; - @SuppressWarnings("WeakerAccess") /* synthetic access */ - CallbackMessageHandler mHandler; - private boolean mMediaPlayPauseKeyPending; - - public CallbackWrapper(MediaSession.Callback callback) { - mCallback = callback; - if (mCallback != null) { - mCallback.onSetMediaButtonEventDelegate(this); - } - } - - /** - * Called when a controller has sent a command to this session. - * The owner of the session may handle custom commands but is not - * required to. - * - * @param command The command name. - * @param args Optional parameters for the command, may be null. - * @param cb A result receiver to which a result may be sent by the command, may be null. - */ - public void onCommand(@NonNull String command, @Nullable Bundle args, - @Nullable ResultReceiver cb) { - if (mCallback != null) { - mCallback.onCommand(command, args, cb); - } - } - - /** - * Called when a media button is pressed and this session has the - * highest priority or a controller sends a media button event to the - * session. The default behavior will call the relevant method if the - * action for it was set. - *

- * The intent will be of type {@link Intent#ACTION_MEDIA_BUTTON} with a - * KeyEvent in {@link Intent#EXTRA_KEY_EVENT} - * - * @param mediaButtonIntent an intent containing the KeyEvent as an - * extra - * @return True if the event was handled, false otherwise. - */ - public boolean onMediaButtonEvent(@NonNull Intent mediaButtonIntent) { - return mCallback == null ? false : mCallback.onMediaButtonEvent(mediaButtonIntent); - } - - private void handleMediaPlayPauseKeySingleTapIfPending() { - if (!mMediaPlayPauseKeyPending) { - return; - } - mMediaPlayPauseKeyPending = false; - mHandler.removeMessages(CallbackMessageHandler.MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT); - PlaybackState state = mSessionImpl.mPlaybackState; - long validActions = state == null ? 0 : state.getActions(); - boolean isPlaying = state != null - && state.getState() == PlaybackState.STATE_PLAYING; - boolean canPlay = (validActions & (PlaybackState.ACTION_PLAY_PAUSE - | PlaybackState.ACTION_PLAY)) != 0; - boolean canPause = (validActions & (PlaybackState.ACTION_PLAY_PAUSE - | PlaybackState.ACTION_PAUSE)) != 0; - if (isPlaying && canPause) { - onPause(); - } else if (!isPlaying && canPlay) { - onPlay(); - } - } - - /** - * Override to handle requests to prepare playback. During the preparation, a session should - * not hold audio focus in order to allow other sessions play seamlessly. The state of - * playback should be updated to {@link PlaybackState#STATE_PAUSED} after the preparation is - * done. - */ - public void onPrepare() { - if (mCallback != null) { - mCallback.onPrepare(); - } - } - - /** - * Override to handle requests to prepare for playing a specific mediaId that was provided - * by your app's {@link MediaBrowserService}. During the preparation, a session should not - * hold audio focus in order to allow other sessions play seamlessly. The state of playback - * should be updated to {@link PlaybackState#STATE_PAUSED} after the preparation is done. - * The playback of the prepared content should start in the implementation of - * {@link #onPlay}. Override {@link #onPlayFromMediaId} to handle requests for starting - * playback without preparation. - */ - public void onPrepareFromMediaId(String mediaId, Bundle extras) { - if (mCallback != null) { - mCallback.onPrepareFromMediaId(mediaId, extras); - } - } - - /** - * Override to handle requests to prepare playback from a search query. An empty query - * indicates that the app may prepare any music. The implementation should attempt to make a - * smart choice about what to play. During the preparation, a session should not hold audio - * focus in order to allow other sessions play seamlessly. The state of playback should be - * updated to {@link PlaybackState#STATE_PAUSED} after the preparation is done. The playback - * of the prepared content should start in the implementation of {@link #onPlay}. Override - * {@link #onPlayFromSearch} to handle requests for starting playback without preparation. - */ - public void onPrepareFromSearch(String query, Bundle extras) { - if (mCallback != null) { - mCallback.onPrepareFromSearch(query, extras); - } - } - - /** - * Override to handle requests to prepare a specific media item represented by a URI. - * During the preparation, a session should not hold audio focus in order to allow - * other sessions play seamlessly. The state of playback should be updated to - * {@link PlaybackState#STATE_PAUSED} after the preparation is done. - * The playback of the prepared content should start in the implementation of - * {@link #onPlay}. Override {@link #onPlayFromUri} to handle requests - * for starting playback without preparation. - */ - public void onPrepareFromUri(Uri uri, Bundle extras) { - if (mCallback != null) { - mCallback.onPrepareFromUri(uri, extras); - } - } - - /** - * Override to handle requests to begin playback. - */ - public void onPlay() { - if (mCallback != null) { - mCallback.onPlay(); - } - } - - /** - * Override to handle requests to begin playback from a search query. An - * empty query indicates that the app may play any music. The - * implementation should attempt to make a smart choice about what to - * play. - */ - public void onPlayFromSearch(String query, Bundle extras) { - if (mCallback != null) { - mCallback.onPlayFromSearch(query, extras); - } - } - - /** - * Override to handle requests to play a specific mediaId that was - * provided by your app's {@link MediaBrowserService}. - */ - public void onPlayFromMediaId(String mediaId, Bundle extras) { - if (mCallback != null) { - mCallback.onPlayFromMediaId(mediaId, extras); - } - } - - /** - * Override to handle requests to play a specific media item represented by a URI. - */ - public void onPlayFromUri(Uri uri, Bundle extras) { - if (mCallback != null) { - mCallback.onPlayFromUri(uri, extras); - } - } - - /** - * Override to handle requests to play an item with a given id from the - * play queue. - */ - public void onSkipToQueueItem(long id) { - if (mCallback != null) { - mCallback.onSkipToQueueItem(id); - } - } - - /** - * Override to handle requests to pause playback. - */ - public void onPause() { - if (mCallback != null) { - mCallback.onPause(); - } - } - - /** - * Override to handle requests to skip to the next media item. - */ - public void onSkipToNext() { - if (mCallback != null) { - mCallback.onSkipToNext(); - } - } - - /** - * Override to handle requests to skip to the previous media item. - */ - public void onSkipToPrevious() { - if (mCallback != null) { - mCallback.onSkipToPrevious(); - } - } - - /** - * Override to handle requests to fast forward. - */ - public void onFastForward() { - if (mCallback != null) { - mCallback.onFastForward(); - } - } - - /** - * Override to handle requests to rewind. - */ - public void onRewind() { - if (mCallback != null) { - mCallback.onRewind(); - } - } - - /** - * Override to handle requests to stop playback. - */ - public void onStop() { - if (mCallback != null) { - mCallback.onStop(); - } - } - - /** - * Override to handle requests to seek to a specific position in ms. - * - * @param pos New position to move to, in milliseconds. - */ - public void onSeekTo(long pos) { - if (mCallback != null) { - mCallback.onSeekTo(pos); - } - } - - /** - * Override to handle the item being rated. - * - * @param rating - */ - public void onSetRating(@NonNull Rating rating) { - if (mCallback != null) { - mCallback.onSetRating(rating); - } - } - - /** - * Override to handle the playback speed change. - * - * @param speed the playback speed - */ - public void onSetPlaybackSpeed(float speed) { - if (mCallback != null) { - mCallback.onSetPlaybackSpeed(speed); - } - } - - /** - * Called when a {@link MediaController} wants a {@link PlaybackState.CustomAction} to be - * performed. - * - * @param action The action that was originally sent in the - * {@link PlaybackState.CustomAction}. - * @param extras Optional extras specified by the {@link MediaController}. - */ - public void onCustomAction(@NonNull String action, @Nullable Bundle extras) { - if (mCallback != null) { - mCallback.onCustomAction(action, extras); - } - } - - @Override - public boolean onMediaButtonIntent(Intent mediaButtonIntent) { - if (mSessionImpl != null && mHandler != null - && Intent.ACTION_MEDIA_BUTTON.equals(mediaButtonIntent.getAction())) { - KeyEvent ke = mediaButtonIntent.getParcelableExtra(Intent.EXTRA_KEY_EVENT); - if (ke != null && ke.getAction() == KeyEvent.ACTION_DOWN) { - PlaybackState state = mSessionImpl.mPlaybackState; - long validActions = state == null ? 0 : state.getActions(); - switch (ke.getKeyCode()) { - case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE: - case KeyEvent.KEYCODE_HEADSETHOOK: - if (ke.getRepeatCount() > 0) { - // Consider long-press as a single tap. - handleMediaPlayPauseKeySingleTapIfPending(); - } else if (mMediaPlayPauseKeyPending) { - // Consider double tap as the next. - mHandler.removeMessages(CallbackMessageHandler - .MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT); - mMediaPlayPauseKeyPending = false; - if ((validActions & PlaybackState.ACTION_SKIP_TO_NEXT) != 0) { - onSkipToNext(); - } - } else { - mMediaPlayPauseKeyPending = true; - mSessionImpl.dispatchMediaButtonDelayed( - mSessionImpl.getCurrentControllerInfo(), - mediaButtonIntent, ViewConfiguration.getDoubleTapTimeout()); - } - return true; - default: - // If another key is pressed within double tap timeout, consider the - // pending play/pause as a single tap to handle media keys in order. - handleMediaPlayPauseKeySingleTapIfPending(); - break; - } - - switch (ke.getKeyCode()) { - case KeyEvent.KEYCODE_MEDIA_PLAY: - if ((validActions & PlaybackState.ACTION_PLAY) != 0) { - onPlay(); - return true; - } - break; - case KeyEvent.KEYCODE_MEDIA_PAUSE: - if ((validActions & PlaybackState.ACTION_PAUSE) != 0) { - onPause(); - return true; - } - break; - case KeyEvent.KEYCODE_MEDIA_NEXT: - if ((validActions & PlaybackState.ACTION_SKIP_TO_NEXT) != 0) { - onSkipToNext(); - return true; - } - break; - case KeyEvent.KEYCODE_MEDIA_PREVIOUS: - if ((validActions & PlaybackState.ACTION_SKIP_TO_PREVIOUS) != 0) { - onSkipToPrevious(); - return true; - } - break; - case KeyEvent.KEYCODE_MEDIA_STOP: - if ((validActions & PlaybackState.ACTION_STOP) != 0) { - onStop(); - return true; - } - break; - case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD: - if ((validActions & PlaybackState.ACTION_FAST_FORWARD) != 0) { - onFastForward(); - return true; - } - break; - case KeyEvent.KEYCODE_MEDIA_REWIND: - if ((validActions & PlaybackState.ACTION_REWIND) != 0) { - onRewind(); - return true; - } - break; - } - } - } - return false; - } - } - - /** - * A single item that is part of the play queue. It contains a description - * of the item and its id in the queue. - */ - public static final class QueueItem { - /** - * This id is reserved. No items can be explicitly assigned this id. - */ - public static final int UNKNOWN_ID = -1; - - private final MediaDescription mDescription; - private final long mId; - - /** - * Create a new {@link MediaSession.QueueItem}. - * - * @param description The {@link MediaDescription} for this item. - * @param id An identifier for this item. It must be unique within the - * play queue and cannot be {@link #UNKNOWN_ID}. - */ - public QueueItem(MediaDescription description, long id) { - if (description == null) { - throw new IllegalArgumentException("Description cannot be null."); - } - if (id == UNKNOWN_ID) { - throw new IllegalArgumentException("Id cannot be QueueItem.UNKNOWN_ID"); - } - mDescription = description; - mId = id; - } - - public QueueItem(Parcel in) { - mDescription = MediaDescription.CREATOR.createFromParcel(in); - mId = in.readLong(); - } - - /** - * Get the description for this item. - */ - public MediaDescription getDescription() { - return mDescription; - } - - /** - * Get the queue id for this item. - */ - public long getQueueId() { - return mId; - } - - /** - * Flatten this object in to a Parcel. - * - * @param dest The Parcel in which the object should be written. - * @param flags Additional flags about how the object should be written. - */ - public void writeToParcel(Parcel dest, int flags) { - mDescription.writeToParcel(dest, flags); - dest.writeLong(mId); - } - - @Override - public String toString() { - return "MediaSession.QueueItem {" + "Description=" + mDescription + ", Id=" + mId - + " }"; - } - - @Override - public boolean equals(Object o) { - if (o == null) { - return false; - } - - if (!(o instanceof QueueItem)) { - return false; - } - - final QueueItem item = (QueueItem) o; - if (mId != item.mId) { - return false; - } - - if (!Objects.equals(mDescription, item.mDescription)) { - return false; - } - - return true; - } - } - - private static final class Command { - public final String command; - public final Bundle extras; - public final ResultReceiver stub; - - Command(String command, Bundle extras, ResultReceiver stub) { - this.command = command; - this.extras = extras; - this.stub = stub; - } - } - - private class CallbackMessageHandler extends Handler { - private static final int MSG_COMMAND = 1; - private static final int MSG_MEDIA_BUTTON = 2; - private static final int MSG_PREPARE = 3; - private static final int MSG_PREPARE_MEDIA_ID = 4; - private static final int MSG_PREPARE_SEARCH = 5; - private static final int MSG_PREPARE_URI = 6; - private static final int MSG_PLAY = 7; - private static final int MSG_PLAY_MEDIA_ID = 8; - private static final int MSG_PLAY_SEARCH = 9; - private static final int MSG_PLAY_URI = 10; - private static final int MSG_SKIP_TO_ITEM = 11; - private static final int MSG_PAUSE = 12; - private static final int MSG_STOP = 13; - private static final int MSG_NEXT = 14; - private static final int MSG_PREVIOUS = 15; - private static final int MSG_FAST_FORWARD = 16; - private static final int MSG_REWIND = 17; - private static final int MSG_SEEK_TO = 18; - private static final int MSG_RATE = 19; - private static final int MSG_SET_PLAYBACK_SPEED = 20; - private static final int MSG_CUSTOM_ACTION = 21; - private static final int MSG_ADJUST_VOLUME = 22; - private static final int MSG_SET_VOLUME = 23; - private static final int MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT = 24; - - @SuppressWarnings("WeakerAccess") /* synthetic access */ - CallbackWrapper mCallbackWrapper; - @SuppressWarnings("WeakerAccess") /* synthetic access */ - RemoteUserInfo mCurrentControllerInfo; - - CallbackMessageHandler(Looper looper, CallbackWrapper callbackWrapper) { - super(looper); - mCallbackWrapper = callbackWrapper; - mCallbackWrapper.mHandler = this; - } - - void post(RemoteUserInfo caller, int what, Object obj, Bundle data, long delayMs) { - Pair objWithCaller = Pair.create(caller, obj); - Message msg = obtainMessage(what, objWithCaller); - msg.setAsynchronous(true); - msg.setData(data); - if (delayMs > 0) { - sendMessageDelayed(msg, delayMs); - } else { - sendMessage(msg); - } - } - - @Override - public void handleMessage(Message msg) { - mCurrentControllerInfo = ((Pair) msg.obj).first; - - VolumeProvider vp; - Object obj = ((Pair) msg.obj).second; - - switch (msg.what) { - case MSG_COMMAND: - Command cmd = (Command) obj; - mCallbackWrapper.onCommand(cmd.command, cmd.extras, cmd.stub); - break; - case MSG_MEDIA_BUTTON: - mCallbackWrapper.onMediaButtonEvent((Intent) obj); - break; - case MSG_PREPARE: - mCallbackWrapper.onPrepare(); - break; - case MSG_PREPARE_MEDIA_ID: - mCallbackWrapper.onPrepareFromMediaId((String) obj, msg.getData()); - break; - case MSG_PREPARE_SEARCH: - mCallbackWrapper.onPrepareFromSearch((String) obj, msg.getData()); - break; - case MSG_PREPARE_URI: - mCallbackWrapper.onPrepareFromUri((Uri) obj, msg.getData()); - break; - case MSG_PLAY: - mCallbackWrapper.onPlay(); - break; - case MSG_PLAY_MEDIA_ID: - mCallbackWrapper.onPlayFromMediaId((String) obj, msg.getData()); - break; - case MSG_PLAY_SEARCH: - mCallbackWrapper.onPlayFromSearch((String) obj, msg.getData()); - break; - case MSG_PLAY_URI: - mCallbackWrapper.onPlayFromUri((Uri) obj, msg.getData()); - break; - case MSG_SKIP_TO_ITEM: - mCallbackWrapper.onSkipToQueueItem((Long) obj); - break; - case MSG_PAUSE: - mCallbackWrapper.onPause(); - break; - case MSG_STOP: - mCallbackWrapper.onStop(); - break; - case MSG_NEXT: - mCallbackWrapper.onSkipToNext(); - break; - case MSG_PREVIOUS: - mCallbackWrapper.onSkipToPrevious(); - break; - case MSG_FAST_FORWARD: - mCallbackWrapper.onFastForward(); - break; - case MSG_REWIND: - mCallbackWrapper.onRewind(); - break; - case MSG_SEEK_TO: - mCallbackWrapper.onSeekTo((Long) obj); - break; - case MSG_RATE: - mCallbackWrapper.onSetRating((Rating) obj); - break; - case MSG_SET_PLAYBACK_SPEED: - mCallbackWrapper.onSetPlaybackSpeed((Float) obj); - break; - case MSG_CUSTOM_ACTION: - mCallbackWrapper.onCustomAction((String) obj, msg.getData()); - break; - case MSG_ADJUST_VOLUME: - synchronized (mLock) { - vp = mVolumeProvider; - } - if (vp != null) { - vp.onAdjustVolume((int) obj); - } - break; - case MSG_SET_VOLUME: - synchronized (mLock) { - vp = mVolumeProvider; - } - if (vp != null) { - vp.onSetVolumeTo((int) obj); - } - break; - case MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT: - mCallbackWrapper.handleMediaPlayPauseKeySingleTapIfPending(); - break; - } - mCurrentControllerInfo = null; - } - } -} diff --git a/media/java/android/media/session/MediaSessionManager.java b/media/java/android/media/session/MediaSessionManager.java index 7ca5c93983949a972497f10f7ea9a8506f88ddb1..51e3a4dc8c4b8e19250b31b2f2cc1b093f825271 100644 --- a/media/java/android/media/session/MediaSessionManager.java +++ b/media/java/android/media/session/MediaSessionManager.java @@ -107,7 +107,7 @@ public final class MediaSessionManager { * @hide */ @NonNull - public ISession createSession(@NonNull SessionCallbackLink cbStub, @NonNull String tag, + public ISession createSession(@NonNull MediaSession.CallbackStub cbStub, @NonNull String tag, @Nullable Bundle sessionInfo) { try { return mService.createSession(mContext.getPackageName(), cbStub, tag, sessionInfo, diff --git a/media/java/android/media/session/SessionCallbackLink.java b/media/java/android/media/session/SessionCallbackLink.java deleted file mode 100644 index 6ffdc2bace18dbbe580c35577de958e7e5dcab4c..0000000000000000000000000000000000000000 --- a/media/java/android/media/session/SessionCallbackLink.java +++ /dev/null @@ -1,969 +0,0 @@ -/* - * Copyright 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.media.session; - -import android.Manifest; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.RequiresPermission; -import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.media.Rating; -import android.media.session.MediaSessionManager.RemoteUserInfo; -import android.net.Uri; -import android.os.Binder; -import android.os.Bundle; -import android.os.IBinder; -import android.os.Parcel; -import android.os.Parcelable; -import android.os.Process; -import android.os.RemoteException; -import android.os.ResultReceiver; - -import java.lang.ref.WeakReference; - -/** - * Handles incoming commands to {@link MediaSession.Callback}. - * @hide - */ -public final class SessionCallbackLink implements Parcelable { - final Context mContext; - final ISessionCallback mISessionCallback; - - /** - * Constructor for stub (Callee) - * @hide - */ - public SessionCallbackLink(@NonNull Context context) { - mContext = context; - mISessionCallback = new CallbackStub(); - } - - /** - * Constructor for interface (Caller) - */ - public SessionCallbackLink(IBinder binder) { - mContext = null; - mISessionCallback = ISessionCallback.Stub.asInterface(binder); - } - - /** - * Set {@link MediaSessionEngine} which will be used by {@link CallbackStub}. - */ - void setSessionEngine(@Nullable MediaSessionEngine sessionImpl) { - if (mISessionCallback instanceof CallbackStub) { - ((CallbackStub) mISessionCallback).mSessionImpl = new WeakReference<>(sessionImpl); - } - } - - /** - * Notify session that a controller sends a command. - * - * @param packageName the package name of the controller - * @param pid the pid of the controller - * @param uid the uid of the controller - * @param caller the {@link ControllerCallbackLink} of the controller - * @param command the name of the command - * @param args the arguments included with the command - * @param cb the result receiver for getting the result of the command - */ - @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL) - public void notifyCommand(@NonNull String packageName, int pid, int uid, - @NonNull ControllerCallbackLink caller, @NonNull String command, - @Nullable Bundle args, @Nullable ResultReceiver cb) { - try { - mISessionCallback.notifyCommand(packageName, pid, uid, caller, command, args, cb); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** - * Notify session that the android system sends a media button event. - * - * @param packageName the package name of the controller - * @param pid the pid of the controller - * @param uid the uid of the controller - * @param mediaButtonIntent the media button intent - * @param sequenceNumber the sequence number of this call - * @param cb the result receiver for getting the result of the command - */ - @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL) - public void notifyMediaButton(@NonNull String packageName, int pid, int uid, - @NonNull Intent mediaButtonIntent, int sequenceNumber, - @Nullable ResultReceiver cb) { - try { - mISessionCallback.notifyMediaButton(packageName, pid, uid, mediaButtonIntent, - sequenceNumber, cb); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** - * Notify session that a controller sends a media button event. - * - * @param packageName the package name of the controller - * @param pid the pid of the controller - * @param uid the uid of the controller - * @param caller the {@link ControllerCallbackLink} of the controller - * @param mediaButtonIntent the media button intent - */ - @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL) - public void notifyMediaButtonFromController(@NonNull String packageName, int pid, int uid, - @NonNull ControllerCallbackLink caller, @NonNull Intent mediaButtonIntent) { - try { - mISessionCallback.notifyMediaButtonFromController(packageName, pid, uid, caller, - mediaButtonIntent); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** - * Notify session that a controller requests preparing media. - * - * @param packageName the package name of the controller - * @param pid the pid of the controller - * @param uid the uid of the controller - * @param caller the {@link ControllerCallbackLink} of the controller - */ - @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL) - public void notifyPrepare(@NonNull String packageName, int pid, int uid, - @NonNull ControllerCallbackLink caller) { - try { - mISessionCallback.notifyPrepare(packageName, pid, uid, caller); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** - * Notify session that a controller requests preparing media from given media ID. - * - * @param packageName the package name of the controller - * @param pid the pid of the controller - * @param uid the uid of the controller - * @param caller the {@link ControllerCallbackLink} of the controller - * @param mediaId the ID of the media - * @param extras the extras included with this request. - */ - @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL) - public void notifyPrepareFromMediaId(@NonNull String packageName, int pid, int uid, - @NonNull ControllerCallbackLink caller, @NonNull String mediaId, - @Nullable Bundle extras) { - try { - mISessionCallback.notifyPrepareFromMediaId(packageName, pid, uid, caller, mediaId, - extras); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** - * Notify session that a controller requests preparing media from given search query. - * - * @param packageName the package name of the controller - * @param pid the pid of the controller - * @param uid the uid of the controller - * @param caller the {@link ControllerCallbackLink} of the controller - * @param query the search query - * @param extras the extras included with this request. - */ - @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL) - public void notifyPrepareFromSearch(@NonNull String packageName, int pid, int uid, - @NonNull ControllerCallbackLink caller, @NonNull String query, - @Nullable Bundle extras) { - try { - mISessionCallback.notifyPrepareFromSearch(packageName, pid, uid, caller, query, extras); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** - * Notify session that a controller requests preparing media from given uri. - * - * @param packageName the package name of the controller - * @param pid the pid of the controller - * @param uid the uid of the controller - * @param caller the {@link ControllerCallbackLink} of the controller - * @param uri the uri of the media - * @param extras the extras included with this request. - */ - @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL) - public void notifyPrepareFromUri(@NonNull String packageName, int pid, int uid, - @NonNull ControllerCallbackLink caller, @NonNull Uri uri, @Nullable Bundle extras) { - try { - mISessionCallback.notifyPrepareFromUri(packageName, pid, uid, caller, uri, extras); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** - * Notify session that a controller requests playing media. - * - * @param packageName the package name of the controller - * @param pid the pid of the controller - * @param uid the uid of the controller - * @param caller the {@link ControllerCallbackLink} of the controller - */ - @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL) - public void notifyPlay(@NonNull String packageName, int pid, int uid, - @NonNull ControllerCallbackLink caller) { - try { - mISessionCallback.notifyPlay(packageName, pid, uid, caller); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** - * Notify session that a controller requests playing media from given media ID. - * - * @param packageName the package name of the controller - * @param pid the pid of the controller - * @param uid the uid of the controller - * @param caller the {@link ControllerCallbackLink} of the controller - * @param mediaId the ID of the media - * @param extras the extras included with this request. - */ - @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL) - public void notifyPlayFromMediaId(@NonNull String packageName, int pid, int uid, - @NonNull ControllerCallbackLink caller, @NonNull String mediaId, - @Nullable Bundle extras) { - try { - mISessionCallback.notifyPlayFromMediaId(packageName, pid, uid, caller, mediaId, extras); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** - * Notify session that a controller requests playing media from given search query. - * - * @param packageName the package name of the controller - * @param pid the pid of the controller - * @param uid the uid of the controller - * @param caller the {@link ControllerCallbackLink} of the controller - * @param query the search query - * @param extras the extras included with this request. - */ - @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL) - public void notifyPlayFromSearch(@NonNull String packageName, int pid, int uid, - @NonNull ControllerCallbackLink caller, @NonNull String query, - @Nullable Bundle extras) { - try { - mISessionCallback.notifyPlayFromSearch(packageName, pid, uid, caller, query, extras); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** - * Notify session that a controller requests playing media from given uri. - * - * @param packageName the package name of the controller - * @param pid the pid of the controller - * @param uid the uid of the controller - * @param caller the {@link ControllerCallbackLink} of the controller - * @param uri the uri of the media - * @param extras the extras included with this request. - */ - @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL) - public void notifyPlayFromUri(@NonNull String packageName, int pid, int uid, - @NonNull ControllerCallbackLink caller, @NonNull Uri uri, @Nullable Bundle extras) { - try { - mISessionCallback.notifyPlayFromUri(packageName, pid, uid, caller, uri, extras); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** - * Notify session that a controller requests skipping to the queue item with given ID. - * - * @param packageName the package name of the controller - * @param pid the pid of the controller - * @param uid the uid of the controller - * @param caller the {@link ControllerCallbackLink} of the controller - * @param id the queue id of the item - */ - @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL) - public void notifySkipToTrack(@NonNull String packageName, int pid, int uid, - @NonNull ControllerCallbackLink caller, long id) { - try { - mISessionCallback.notifySkipToTrack(packageName, pid, uid, caller, id); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** - * Notify session that a controller requests pausing media. - * - * @param packageName the package name of the controller - * @param pid the pid of the controller - * @param uid the uid of the controller - * @param caller the {@link ControllerCallbackLink} of the controller - */ - @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL) - public void notifyPause(@NonNull String packageName, int pid, int uid, - @NonNull ControllerCallbackLink caller) { - try { - mISessionCallback.notifyPause(packageName, pid, uid, caller); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** - * Notify session that a controller requests stopping media. - * - * @param packageName the package name of the controller - * @param pid the pid of the controller - * @param uid the uid of the controller - * @param caller the {@link ControllerCallbackLink} of the controller - */ - @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL) - public void notifyStop(@NonNull String packageName, int pid, int uid, - @NonNull ControllerCallbackLink caller) { - try { - mISessionCallback.notifyStop(packageName, pid, uid, caller); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** - * Notify session that a controller requests skipping to the next queue item. - * - * @param packageName the package name of the controller - * @param pid the pid of the controller - * @param uid the uid of the controller - * @param caller the {@link ControllerCallbackLink} of the controller - */ - @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL) - public void notifyNext(@NonNull String packageName, int pid, int uid, - @NonNull ControllerCallbackLink caller) { - try { - mISessionCallback.notifyNext(packageName, pid, uid, caller); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** - * Notify session that a controller requests skipping to the previous queue item. - * - * @param packageName the package name of the controller - * @param pid the pid of the controller - * @param uid the uid of the controller - * @param caller the {@link ControllerCallbackLink} of the controller - */ - @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL) - public void notifyPrevious(@NonNull String packageName, int pid, int uid, - @NonNull ControllerCallbackLink caller) { - try { - mISessionCallback.notifyPrevious(packageName, pid, uid, caller); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** - * Notify session that a controller requests fast-forwarding. - * - * @param packageName the package name of the controller - * @param pid the pid of the controller - * @param uid the uid of the controller - * @param caller the {@link ControllerCallbackLink} of the controller - */ - @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL) - public void notifyFastForward(@NonNull String packageName, int pid, int uid, - @NonNull ControllerCallbackLink caller) { - try { - mISessionCallback.notifyFastForward(packageName, pid, uid, caller); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** - * Notify session that a controller requests rewinding. - * - * @param packageName the package name of the controller - * @param pid the pid of the controller - * @param uid the uid of the controller - * @param caller the {@link ControllerCallbackLink} of the controller - */ - @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL) - public void notifyRewind(@NonNull String packageName, int pid, int uid, - @NonNull ControllerCallbackLink caller) { - try { - mISessionCallback.notifyRewind(packageName, pid, uid, caller); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** - * Notify session that a controller requests seeking to the specific position. - * - * @param packageName the package name of the controller - * @param pid the pid of the controller - * @param uid the uid of the controller - * @param caller the {@link ControllerCallbackLink} of the controller - * @param pos the position to move to, in milliseconds - */ - @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL) - public void notifySeekTo(@NonNull String packageName, int pid, int uid, - @NonNull ControllerCallbackLink caller, long pos) { - try { - mISessionCallback.notifySeekTo(packageName, pid, uid, caller, pos); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** - * Notify session that a controller requests rating of the current media. - * - * @param packageName the package name of the controller - * @param pid the pid of the controller - * @param uid the uid of the controller - * @param caller the {@link ControllerCallbackLink} of the controller - * @param rating the rating of the current media - */ - @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL) - public void notifyRate(@NonNull String packageName, int pid, int uid, - @NonNull ControllerCallbackLink caller, @NonNull Rating rating) { - try { - mISessionCallback.notifyRate(packageName, pid, uid, caller, rating); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** - * Notify session that a controller requests changing playback speed. - * - * @param packageName the package name of the controller - * @param pid the pid of the controller - * @param uid the uid of the controller - * @param caller the {@link ControllerCallbackLink} of the controller - * @param speed the playback speed - */ - @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL) - public void notifySetPlaybackSpeed(@NonNull String packageName, int pid, int uid, - @NonNull ControllerCallbackLink caller, float speed) { - try { - mISessionCallback.notifySetPlaybackSpeed(packageName, pid, uid, caller, speed); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** - * Notify session that a controller sends a custom action. - * - * @param packageName the package name of the controller - * @param pid the pid of the controller - * @param uid the uid of the controller - * @param caller the {@link ControllerCallbackLink} of the controller - * @param action the name of the action - * @param args the arguments included with this action - */ - @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL) - public void notifyCustomAction(@NonNull String packageName, int pid, int uid, - @NonNull ControllerCallbackLink caller, @NonNull String action, @Nullable Bundle args) { - try { - mISessionCallback.notifyCustomAction(packageName, pid, uid, caller, action, args); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** - * Notify session that a controller requests adjusting volume. - * - * @param packageName the package name of the controller - * @param pid the pid of the controller - * @param uid the uid of the controller - * @param caller the {@link ControllerCallbackLink} of the controller - * @param direction the direction of the volume change. - */ - @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL) - public void notifyAdjustVolume(@NonNull String packageName, int pid, int uid, - @NonNull ControllerCallbackLink caller, int direction) { - try { - mISessionCallback.notifyAdjustVolume(packageName, pid, uid, caller, direction); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** - * Notify session that a controller requests setting volume. - * - * @param packageName the package name of the controller - * @param pid the pid of the controller - * @param uid the uid of the controller - * @param caller the {@link ControllerCallbackLink} of the controller - * @param value the volume value to set - */ - @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL) - public void notifySetVolumeTo(@NonNull String packageName, int pid, int uid, - @NonNull ControllerCallbackLink caller, int value) { - try { - mISessionCallback.notifySetVolumeTo(packageName, pid, uid, caller, value); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** Gets the binder */ - @NonNull - public IBinder getBinder() { - return mISessionCallback.asBinder(); - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeStrongBinder(mISessionCallback.asBinder()); - } - - public static final @android.annotation.NonNull Parcelable.Creator CREATOR = - new Parcelable.Creator() { - @Override - public SessionCallbackLink createFromParcel(Parcel in) { - return new SessionCallbackLink(in.readStrongBinder()); - } - - @Override - public SessionCallbackLink[] newArray(int size) { - return new SessionCallbackLink[size]; - } - }; - - private class CallbackStub extends ISessionCallback.Stub { - private WeakReference mSessionImpl; - - private RemoteUserInfo createRemoteUserInfo(String packageName, int pid, int uid) { - return new RemoteUserInfo(packageName, pid, uid); - } - - @Override - public void notifyCommand(String packageName, int pid, int uid, - ControllerCallbackLink caller, String command, Bundle args, ResultReceiver cb) { - ensureMediaControlPermission(); - final long token = Binder.clearCallingIdentity(); - try { - MediaSessionEngine sessionImpl = mSessionImpl.get(); - if (sessionImpl != null) { - sessionImpl.dispatchCommand(createRemoteUserInfo(packageName, pid, uid), - command, args, cb); - } - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void notifyMediaButton(String packageName, int pid, int uid, - Intent mediaButtonIntent, int sequenceNumber, ResultReceiver cb) { - ensureMediaControlPermission(); - final long token = Binder.clearCallingIdentity(); - try { - MediaSessionEngine sessionImpl = mSessionImpl.get(); - if (sessionImpl != null) { - sessionImpl.dispatchMediaButton( - createRemoteUserInfo(packageName, pid, uid), mediaButtonIntent); - } - } finally { - if (cb != null) { - cb.send(sequenceNumber, null); - } - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void notifyMediaButtonFromController(String packageName, int pid, int uid, - ControllerCallbackLink caller, Intent mediaButtonIntent) { - ensureMediaControlPermission(); - final long token = Binder.clearCallingIdentity(); - try { - MediaSessionEngine sessionImpl = mSessionImpl.get(); - if (sessionImpl != null) { - sessionImpl.dispatchMediaButton(createRemoteUserInfo(packageName, pid, uid), - mediaButtonIntent); - } - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void notifyPrepare(String packageName, int pid, int uid, - ControllerCallbackLink caller) { - ensureMediaControlPermission(); - final long token = Binder.clearCallingIdentity(); - try { - MediaSessionEngine sessionImpl = mSessionImpl.get(); - if (sessionImpl != null) { - sessionImpl.dispatchPrepare(createRemoteUserInfo(packageName, pid, uid)); - } - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void notifyPrepareFromMediaId(String packageName, int pid, int uid, - ControllerCallbackLink caller, String mediaId, Bundle extras) { - ensureMediaControlPermission(); - final long token = Binder.clearCallingIdentity(); - try { - MediaSessionEngine sessionImpl = mSessionImpl.get(); - if (sessionImpl != null) { - sessionImpl.dispatchPrepareFromMediaId( - createRemoteUserInfo(packageName, pid, uid), mediaId, extras); - } - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void notifyPrepareFromSearch(String packageName, int pid, int uid, - ControllerCallbackLink caller, String query, Bundle extras) { - ensureMediaControlPermission(); - final long token = Binder.clearCallingIdentity(); - try { - MediaSessionEngine sessionImpl = mSessionImpl.get(); - if (sessionImpl != null) { - sessionImpl.dispatchPrepareFromSearch( - createRemoteUserInfo(packageName, pid, uid), query, extras); - } - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void notifyPrepareFromUri(String packageName, int pid, int uid, - ControllerCallbackLink caller, Uri uri, Bundle extras) { - ensureMediaControlPermission(); - final long token = Binder.clearCallingIdentity(); - try { - MediaSessionEngine sessionImpl = mSessionImpl.get(); - if (sessionImpl != null) { - sessionImpl.dispatchPrepareFromUri( - createRemoteUserInfo(packageName, pid, uid), uri, extras); - } - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void notifyPlay(String packageName, int pid, int uid, - ControllerCallbackLink caller) { - ensureMediaControlPermission(); - final long token = Binder.clearCallingIdentity(); - try { - MediaSessionEngine sessionImpl = mSessionImpl.get(); - if (sessionImpl != null) { - sessionImpl.dispatchPlay(createRemoteUserInfo(packageName, pid, uid)); - } - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void notifyPlayFromMediaId(String packageName, int pid, int uid, - ControllerCallbackLink caller, String mediaId, Bundle extras) { - ensureMediaControlPermission(); - final long token = Binder.clearCallingIdentity(); - try { - MediaSessionEngine sessionImpl = mSessionImpl.get(); - if (sessionImpl != null) { - sessionImpl.dispatchPlayFromMediaId( - createRemoteUserInfo(packageName, pid, uid), mediaId, extras); - } - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void notifyPlayFromSearch(String packageName, int pid, int uid, - ControllerCallbackLink caller, String query, Bundle extras) { - ensureMediaControlPermission(); - final long token = Binder.clearCallingIdentity(); - try { - MediaSessionEngine sessionImpl = mSessionImpl.get(); - if (sessionImpl != null) { - sessionImpl.dispatchPlayFromSearch( - createRemoteUserInfo(packageName, pid, uid), query, extras); - } - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void notifyPlayFromUri(String packageName, int pid, int uid, - ControllerCallbackLink caller, Uri uri, Bundle extras) { - ensureMediaControlPermission(); - final long token = Binder.clearCallingIdentity(); - try { - MediaSessionEngine sessionImpl = mSessionImpl.get(); - if (sessionImpl != null) { - sessionImpl.dispatchPlayFromUri( - createRemoteUserInfo(packageName, pid, uid), uri, extras); - } - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void notifySkipToTrack(String packageName, int pid, int uid, - ControllerCallbackLink caller, long id) { - ensureMediaControlPermission(); - final long token = Binder.clearCallingIdentity(); - try { - MediaSessionEngine sessionImpl = mSessionImpl.get(); - if (sessionImpl != null) { - sessionImpl.dispatchSkipToItem( - createRemoteUserInfo(packageName, pid, uid), id); - } - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void notifyPause(String packageName, int pid, int uid, - ControllerCallbackLink caller) { - ensureMediaControlPermission(); - final long token = Binder.clearCallingIdentity(); - try { - MediaSessionEngine sessionImpl = mSessionImpl.get(); - if (sessionImpl != null) { - sessionImpl.dispatchPause(createRemoteUserInfo(packageName, pid, uid)); - } - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void notifyStop(String packageName, int pid, int uid, - ControllerCallbackLink caller) { - ensureMediaControlPermission(); - final long token = Binder.clearCallingIdentity(); - try { - MediaSessionEngine sessionImpl = mSessionImpl.get(); - if (sessionImpl != null) { - sessionImpl.dispatchStop(createRemoteUserInfo(packageName, pid, uid)); - } - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void notifyNext(String packageName, int pid, int uid, - ControllerCallbackLink caller) { - ensureMediaControlPermission(); - final long token = Binder.clearCallingIdentity(); - try { - MediaSessionEngine sessionImpl = mSessionImpl.get(); - if (sessionImpl != null) { - sessionImpl.dispatchNext(createRemoteUserInfo(packageName, pid, uid)); - } - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void notifyPrevious(String packageName, int pid, int uid, - ControllerCallbackLink caller) { - ensureMediaControlPermission(); - final long token = Binder.clearCallingIdentity(); - try { - MediaSessionEngine sessionImpl = mSessionImpl.get(); - if (sessionImpl != null) { - sessionImpl.dispatchPrevious(createRemoteUserInfo(packageName, pid, uid)); - } - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void notifyFastForward(String packageName, int pid, int uid, - ControllerCallbackLink caller) { - ensureMediaControlPermission(); - final long token = Binder.clearCallingIdentity(); - try { - MediaSessionEngine sessionImpl = mSessionImpl.get(); - if (sessionImpl != null) { - sessionImpl.dispatchFastForward( - createRemoteUserInfo(packageName, pid, uid)); - } - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void notifyRewind(String packageName, int pid, int uid, - ControllerCallbackLink caller) { - ensureMediaControlPermission(); - final long token = Binder.clearCallingIdentity(); - try { - MediaSessionEngine sessionImpl = mSessionImpl.get(); - if (sessionImpl != null) { - sessionImpl.dispatchRewind(createRemoteUserInfo(packageName, pid, uid)); - } - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void notifySeekTo(String packageName, int pid, int uid, - ControllerCallbackLink caller, long pos) { - ensureMediaControlPermission(); - final long token = Binder.clearCallingIdentity(); - try { - MediaSessionEngine sessionImpl = mSessionImpl.get(); - if (sessionImpl != null) { - sessionImpl.dispatchSeekTo( - createRemoteUserInfo(packageName, pid, uid), pos); - } - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void notifyRate(String packageName, int pid, int uid, ControllerCallbackLink caller, - Rating rating) { - ensureMediaControlPermission(); - final long token = Binder.clearCallingIdentity(); - try { - MediaSessionEngine sessionImpl = mSessionImpl.get(); - if (sessionImpl != null) { - sessionImpl.dispatchRate( - createRemoteUserInfo(packageName, pid, uid), rating); - } - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void notifySetPlaybackSpeed(String packageName, int pid, int uid, - ControllerCallbackLink caller, float speed) { - ensureMediaControlPermission(); - final long token = Binder.clearCallingIdentity(); - try { - MediaSessionEngine sessionImpl = mSessionImpl.get(); - if (sessionImpl != null) { - sessionImpl.dispatchSetPlaybackSpeed( - createRemoteUserInfo(packageName, pid, uid), speed); - } - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void notifyCustomAction(String packageName, int pid, int uid, - ControllerCallbackLink caller, String action, Bundle args) { - ensureMediaControlPermission(); - final long token = Binder.clearCallingIdentity(); - try { - MediaSessionEngine sessionImpl = mSessionImpl.get(); - if (sessionImpl != null) { - sessionImpl.dispatchCustomAction( - createRemoteUserInfo(packageName, pid, uid), action, args); - } - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void notifyAdjustVolume(String packageName, int pid, int uid, - ControllerCallbackLink caller, int direction) { - ensureMediaControlPermission(); - final long token = Binder.clearCallingIdentity(); - try { - MediaSessionEngine sessionImpl = mSessionImpl.get(); - if (sessionImpl != null) { - sessionImpl.dispatchAdjustVolume( - createRemoteUserInfo(packageName, pid, uid), direction); - } - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void notifySetVolumeTo(String packageName, int pid, int uid, - ControllerCallbackLink caller, int value) { - ensureMediaControlPermission(); - final long token = Binder.clearCallingIdentity(); - try { - MediaSessionEngine sessionImpl = mSessionImpl.get(); - if (sessionImpl != null) { - sessionImpl.dispatchSetVolumeTo( - createRemoteUserInfo(packageName, pid, uid), value); - } - } finally { - Binder.restoreCallingIdentity(token); - } - } - - private void ensureMediaControlPermission() { - // Check if it's system server or has MEDIA_CONTENT_CONTROL. - // Note that system server doesn't have MEDIA_CONTENT_CONTROL, so we need extra - // check here. - if (getCallingUid() == Process.SYSTEM_UID || mContext.checkCallingPermission( - android.Manifest.permission.MEDIA_CONTENT_CONTROL) - == PackageManager.PERMISSION_GRANTED) { - return; - } - throw new SecurityException("Must hold the MEDIA_CONTENT_CONTROL permission."); - } - } -} diff --git a/media/java/android/mtp/MtpDatabase.java b/media/java/android/mtp/MtpDatabase.java index dc2d17753b1d6bed4065ebb3727da2c59b8e1308..6361fd81d2af4f7baec48d7b80f4af60b2c0b121 100755 --- a/media/java/android/mtp/MtpDatabase.java +++ b/media/java/android/mtp/MtpDatabase.java @@ -25,16 +25,13 @@ import android.content.IntentFilter; import android.content.SharedPreferences; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; -import android.media.MediaScanner; import android.net.Uri; import android.os.BatteryManager; import android.os.RemoteException; import android.os.SystemProperties; import android.os.storage.StorageVolume; import android.provider.MediaStore; -import android.provider.MediaStore.Audio; import android.provider.MediaStore.Files; -import android.provider.MediaStore.MediaColumns; import android.system.ErrnoException; import android.system.Os; import android.system.OsConstants; @@ -42,6 +39,8 @@ import android.util.Log; import android.view.Display; import android.view.WindowManager; +import com.android.internal.annotations.VisibleForNative; + import dalvik.system.CloseGuard; import com.google.android.collect.Sets; @@ -72,7 +71,6 @@ public class MtpDatabase implements AutoCloseable { private final ContentProviderClient mMediaProvider; private final String mVolumeName; private final Uri mObjectsUri; - private final MediaScanner mMediaScanner; private final AtomicBoolean mClosed = new AtomicBoolean(); private final CloseGuard mCloseGuard = CloseGuard.get(); @@ -159,7 +157,6 @@ public class MtpDatabase implements AutoCloseable { MtpConstants.PROPERTY_TRACK, MtpConstants.PROPERTY_ORIGINAL_RELEASE_DATE, MtpConstants.PROPERTY_DURATION, - MtpConstants.PROPERTY_GENRE, MtpConstants.PROPERTY_COMPOSER, MtpConstants.PROPERTY_AUDIO_WAVE_CODEC, MtpConstants.PROPERTY_BITRATE_TYPE, @@ -187,6 +184,7 @@ public class MtpDatabase implements AutoCloseable { MtpConstants.DEVICE_PROPERTY_PERCEIVED_DEVICE_TYPE, }; + @VisibleForNative private int[] getSupportedObjectProperties(int format) { switch (format) { case MtpConstants.FORMAT_MP3: @@ -214,14 +212,41 @@ public class MtpDatabase implements AutoCloseable { } } + public static Uri getObjectPropertiesUri(int format, String volumeName) { + switch (format) { + case MtpConstants.FORMAT_MP3: + case MtpConstants.FORMAT_WAV: + case MtpConstants.FORMAT_WMA: + case MtpConstants.FORMAT_OGG: + case MtpConstants.FORMAT_AAC: + return MediaStore.Audio.Media.getContentUri(volumeName); + case MtpConstants.FORMAT_MPEG: + case MtpConstants.FORMAT_3GP_CONTAINER: + case MtpConstants.FORMAT_WMV: + return MediaStore.Video.Media.getContentUri(volumeName); + case MtpConstants.FORMAT_EXIF_JPEG: + case MtpConstants.FORMAT_GIF: + case MtpConstants.FORMAT_PNG: + case MtpConstants.FORMAT_BMP: + case MtpConstants.FORMAT_DNG: + case MtpConstants.FORMAT_HEIF: + return MediaStore.Images.Media.getContentUri(volumeName); + default: + return MediaStore.Files.getContentUri(volumeName); + } + } + + @VisibleForNative private int[] getSupportedDeviceProperties() { return DEVICE_PROPERTIES; } + @VisibleForNative private int[] getSupportedPlaybackFormats() { return PLAYBACK_FORMATS; } + @VisibleForNative private int[] getSupportedCaptureFormats() { // no capture formats yet return null; @@ -254,7 +279,6 @@ public class MtpDatabase implements AutoCloseable { .acquireContentProviderClient(MediaStore.AUTHORITY); mVolumeName = volumeName; mObjectsUri = Files.getMtpObjectsUri(volumeName); - mMediaScanner = new MediaScanner(context, mVolumeName); mManager = new MtpStorageManager(new MtpStorageManager.MtpNotifier() { @Override public void sendObjectAdded(int id) { @@ -304,7 +328,6 @@ public class MtpDatabase implements AutoCloseable { mManager.close(); mCloseGuard.close(); if (mClosed.compareAndSet(false, true)) { - mMediaScanner.close(); if (mMediaProvider != null) { mMediaProvider.close(); } @@ -380,6 +403,7 @@ public class MtpDatabase implements AutoCloseable { } } + @VisibleForNative private int beginSendObject(String path, int format, int parent, int storageId) { MtpStorageManager.MtpObject parentObj = parent == 0 ? mManager.getStorageRoot(storageId) : mManager.getObject(parent); @@ -391,6 +415,7 @@ public class MtpDatabase implements AutoCloseable { return mManager.beginSendObject(parentObj, objPath.getFileName().toString(), format); } + @VisibleForNative private void endSendObject(int handle, boolean succeeded) { MtpStorageManager.MtpObject obj = mManager.getObject(handle); if (obj == null || !mManager.endSendObject(obj, succeeded)) { @@ -399,69 +424,16 @@ public class MtpDatabase implements AutoCloseable { } // Add the new file to MediaProvider if (succeeded) { - String path = obj.getPath().toString(); - int format = obj.getFormat(); - // Get parent info from MediaProvider, since the id is different from MTP's - ContentValues values = new ContentValues(); - values.put(Files.FileColumns.DATA, path); - values.put(Files.FileColumns.FORMAT, format); - values.put(Files.FileColumns.SIZE, obj.getSize()); - values.put(Files.FileColumns.DATE_MODIFIED, obj.getModifiedTime()); - try { - if (obj.getParent().isRoot()) { - values.put(Files.FileColumns.PARENT, 0); - } else { - int parentId = findInMedia(obj.getParent().getPath()); - if (parentId != -1) { - values.put(Files.FileColumns.PARENT, parentId); - } else { - // The parent isn't in MediaProvider. Don't add the new file. - return; - } - } - - Uri uri = mMediaProvider.insert(mObjectsUri, values); - if (uri != null) { - rescanFile(path, Integer.parseInt(uri.getPathSegments().get(2)), format); - } - } catch (RemoteException e) { - Log.e(TAG, "RemoteException in beginSendObject", e); - } + MediaStore.scanFile(mContext, obj.getPath().toFile()); } } + @VisibleForNative private void rescanFile(String path, int handle, int format) { - // handle abstract playlists separately - // they do not exist in the file system so don't use the media scanner here - if (format == MtpConstants.FORMAT_ABSTRACT_AV_PLAYLIST) { - // extract name from path - String name = path; - int lastSlash = name.lastIndexOf('/'); - if (lastSlash >= 0) { - name = name.substring(lastSlash + 1); - } - // strip trailing ".pla" from the name - if (name.endsWith(".pla")) { - name = name.substring(0, name.length() - 4); - } - - ContentValues values = new ContentValues(1); - values.put(Audio.Playlists.DATA, path); - values.put(Audio.Playlists.NAME, name); - values.put(Files.FileColumns.FORMAT, format); - values.put(Files.FileColumns.DATE_MODIFIED, System.currentTimeMillis() / 1000); - values.put(MediaColumns.MEDIA_SCANNER_NEW_OBJECT_ID, handle); - try { - mMediaProvider.insert( - Audio.Playlists.EXTERNAL_CONTENT_URI, values); - } catch (RemoteException e) { - Log.e(TAG, "RemoteException in endSendObject", e); - } - } else { - mMediaScanner.scanMtpFile(path, handle, format); - } + MediaStore.scanFile(mContext, new File(path)); } + @VisibleForNative private int[] getObjectList(int storageID, int format, int parent) { List objs = mManager.getObjects(parent, format, storageID); @@ -475,6 +447,7 @@ public class MtpDatabase implements AutoCloseable { return ret; } + @VisibleForNative private int getNumObjects(int storageID, int format, int parent) { List objs = mManager.getObjects(parent, format, storageID); @@ -484,6 +457,7 @@ public class MtpDatabase implements AutoCloseable { return objs.size(); } + @VisibleForNative private MtpPropertyList getObjectPropertyList(int handle, int format, int property, int groupCode, int depth) { // FIXME - implement group support @@ -551,16 +525,16 @@ public class MtpDatabase implements AutoCloseable { // format should be the same between get & put propertyGroup = mPropertyGroupsByFormat.get(format); if (propertyGroup == null) { - int[] propertyList = getSupportedObjectProperties(format); + final int[] propertyList = getSupportedObjectProperties(format); propertyGroup = new MtpPropertyGroup(mMediaProvider, mVolumeName, propertyList); mPropertyGroupsByFormat.put(format, propertyGroup); } } else { // Get this property value - final int[] propertyList = new int[]{property}; propertyGroup = mPropertyGroupsByProperty.get(property); if (propertyGroup == null) { + final int[] propertyList = new int[]{property}; propertyGroup = new MtpPropertyGroup(mMediaProvider, mVolumeName, propertyList); mPropertyGroupsByProperty.put(property, propertyGroup); @@ -616,28 +590,19 @@ public class MtpDatabase implements AutoCloseable { if (obj.isDir()) { // for directories, check if renamed from something hidden to something non-hidden if (oldPath.getFileName().startsWith(".") && !newPath.startsWith(".")) { - // directory was unhidden - try { - mMediaProvider.call(MediaStore.UNHIDE_CALL, newPath.toString(), null); - } catch (RemoteException e) { - Log.e(TAG, "failed to unhide/rescan for " + newPath); - } + MediaStore.scanFile(mContext, newPath.toFile()); } } else { // for files, check if renamed from .nomedia to something else if (oldPath.getFileName().toString().toLowerCase(Locale.US).equals(NO_MEDIA) && !newPath.getFileName().toString().toLowerCase(Locale.US).equals(NO_MEDIA)) { - try { - mMediaProvider.call(MediaStore.UNHIDE_CALL, - oldPath.getParent().toString(), null); - } catch (RemoteException e) { - Log.e(TAG, "failed to unhide/rescan for " + newPath); - } + MediaStore.scanFile(mContext, newPath.getParent().toFile()); } } return MtpConstants.RESPONSE_OK; } + @VisibleForNative private int beginMoveObject(int handle, int newParent, int newStorage) { MtpStorageManager.MtpObject obj = mManager.getObject(handle); MtpStorageManager.MtpObject parent = newParent == 0 ? @@ -649,6 +614,7 @@ public class MtpDatabase implements AutoCloseable { return allowed ? MtpConstants.RESPONSE_OK : MtpConstants.RESPONSE_GENERAL_ERROR; } + @VisibleForNative private void endMoveObject(int oldParent, int newParent, int oldStorage, int newStorage, int objId, boolean success) { MtpStorageManager.MtpObject oldParentObj = oldParent == 0 ? @@ -698,20 +664,14 @@ public class MtpDatabase implements AutoCloseable { mMediaProvider.update(mObjectsUri, values, PATH_WHERE, whereArgs); } else { // Old parent doesn't exist - add the object - values.put(Files.FileColumns.FORMAT, obj.getFormat()); - values.put(Files.FileColumns.SIZE, obj.getSize()); - values.put(Files.FileColumns.DATE_MODIFIED, obj.getModifiedTime()); - Uri uri = mMediaProvider.insert(mObjectsUri, values); - if (uri != null) { - rescanFile(path.toString(), - Integer.parseInt(uri.getPathSegments().get(2)), obj.getFormat()); - } + MediaStore.scanFile(mContext, path.toFile()); } } catch (RemoteException e) { Log.e(TAG, "RemoteException in mMediaProvider.update", e); } } + @VisibleForNative private int beginCopyObject(int handle, int newParent, int newStorage) { MtpStorageManager.MtpObject obj = mManager.getObject(handle); MtpStorageManager.MtpObject parent = newParent == 0 ? @@ -721,6 +681,7 @@ public class MtpDatabase implements AutoCloseable { return mManager.beginCopyObject(obj, parent); } + @VisibleForNative private void endCopyObject(int handle, boolean success) { MtpStorageManager.MtpObject obj = mManager.getObject(handle); if (obj == null || !mManager.endCopyObject(obj, success)) { @@ -730,39 +691,10 @@ public class MtpDatabase implements AutoCloseable { if (!success) { return; } - String path = obj.getPath().toString(); - int format = obj.getFormat(); - // Get parent info from MediaProvider, since the id is different from MTP's - ContentValues values = new ContentValues(); - values.put(Files.FileColumns.DATA, path); - values.put(Files.FileColumns.FORMAT, format); - values.put(Files.FileColumns.SIZE, obj.getSize()); - values.put(Files.FileColumns.DATE_MODIFIED, obj.getModifiedTime()); - try { - if (obj.getParent().isRoot()) { - values.put(Files.FileColumns.PARENT, 0); - } else { - int parentId = findInMedia(obj.getParent().getPath()); - if (parentId != -1) { - values.put(Files.FileColumns.PARENT, parentId); - } else { - // The parent isn't in MediaProvider. Don't add the new file. - return; - } - } - if (obj.isDir()) { - mMediaScanner.scanDirectories(new String[]{path}); - } else { - Uri uri = mMediaProvider.insert(mObjectsUri, values); - if (uri != null) { - rescanFile(path, Integer.parseInt(uri.getPathSegments().get(2)), format); - } - } - } catch (RemoteException e) { - Log.e(TAG, "RemoteException in beginSendObject", e); - } + MediaStore.scanFile(mContext, obj.getPath().toFile()); } + @VisibleForNative private int setObjectProperty(int handle, int property, long intValue, String stringValue) { switch (property) { @@ -774,6 +706,7 @@ public class MtpDatabase implements AutoCloseable { } } + @VisibleForNative private int getDeviceProperty(int property, long[] outIntValue, char[] outStringValue) { switch (property) { case MtpConstants.DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER: @@ -809,6 +742,7 @@ public class MtpDatabase implements AutoCloseable { } } + @VisibleForNative private int setDeviceProperty(int property, long intValue, String stringValue) { switch (property) { case MtpConstants.DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER: @@ -823,6 +757,7 @@ public class MtpDatabase implements AutoCloseable { return MtpConstants.RESPONSE_DEVICE_PROP_NOT_SUPPORTED; } + @VisibleForNative private boolean getObjectInfo(int handle, int[] outStorageFormatParent, char[] outName, long[] outCreatedModified) { MtpStorageManager.MtpObject obj = mManager.getObject(handle); @@ -842,6 +777,7 @@ public class MtpDatabase implements AutoCloseable { return true; } + @VisibleForNative private int getObjectFilePath(int handle, char[] outFilePath, long[] outFileLengthFormat) { MtpStorageManager.MtpObject obj = mManager.getObject(handle); if (obj == null) { @@ -866,6 +802,7 @@ public class MtpDatabase implements AutoCloseable { return obj.getFormat(); } + @VisibleForNative private int beginDeleteObject(int handle) { MtpStorageManager.MtpObject obj = mManager.getObject(handle); if (obj == null) { @@ -877,6 +814,7 @@ public class MtpDatabase implements AutoCloseable { return MtpConstants.RESPONSE_OK; } + @VisibleForNative private void endDeleteObject(int handle, boolean success) { MtpStorageManager.MtpObject obj = mManager.getObject(handle); if (obj == null) { @@ -922,12 +860,7 @@ public class MtpDatabase implements AutoCloseable { String[] whereArgs = new String[]{path.toString()}; if (mMediaProvider.delete(mObjectsUri, PATH_WHERE, whereArgs) > 0) { if (!isDir && path.toString().toLowerCase(Locale.US).endsWith(NO_MEDIA)) { - try { - String parentPath = path.getParent().toString(); - mMediaProvider.call(MediaStore.UNHIDE_CALL, parentPath, null); - } catch (RemoteException e) { - Log.e(TAG, "failed to unhide/rescan for " + path); - } + MediaStore.scanFile(mContext, path.getParent().toFile()); } } else { Log.i(TAG, "Mediaprovider didn't delete " + path); @@ -937,6 +870,7 @@ public class MtpDatabase implements AutoCloseable { } } + @VisibleForNative private int[] getObjectReferences(int handle) { MtpStorageManager.MtpObject obj = mManager.getObject(handle); if (obj == null) @@ -972,6 +906,7 @@ public class MtpDatabase implements AutoCloseable { return null; } + @VisibleForNative private int setObjectReferences(int handle, int[] references) { MtpStorageManager.MtpObject obj = mManager.getObject(handle); if (obj == null) @@ -1004,7 +939,7 @@ public class MtpDatabase implements AutoCloseable { return MtpConstants.RESPONSE_GENERAL_ERROR; } - // used by the JNI code + @VisibleForNative private long mNativeContext; private native final void native_setup(); diff --git a/media/java/android/mtp/MtpPropertyGroup.java b/media/java/android/mtp/MtpPropertyGroup.java index 77d0f34f1ad6a4f6df6e31560af52702f9e34120..6d5be8ef6985fdafb901088ad22fb4b47547b2f6 100644 --- a/media/java/android/mtp/MtpPropertyGroup.java +++ b/media/java/android/mtp/MtpPropertyGroup.java @@ -48,7 +48,6 @@ class MtpPropertyGroup { private final ContentProviderClient mProvider; private final String mVolumeName; - private final Uri mUri; // list of all properties in this group private final Property[] mProperties; @@ -62,7 +61,6 @@ class MtpPropertyGroup { public MtpPropertyGroup(ContentProviderClient provider, String volumeName, int[] properties) { mProvider = provider; mVolumeName = volumeName; - mUri = Files.getMtpObjectsUri(volumeName); int count = properties.length; ArrayList columns = new ArrayList<>(count); @@ -139,10 +137,6 @@ class MtpPropertyGroup { column = Audio.AudioColumns.ALBUM_ARTIST; type = MtpConstants.TYPE_STR; break; - case MtpConstants.PROPERTY_GENRE: - // genre requires a special query - type = MtpConstants.TYPE_STR; - break; case MtpConstants.PROPERTY_COMPOSER: column = Audio.AudioColumns.COMPOSER; type = MtpConstants.TYPE_STR; @@ -176,46 +170,6 @@ class MtpPropertyGroup { } } - private String queryAudio(String path, String column) { - Cursor c = null; - try { - c = mProvider.query(Audio.Media.getContentUri(mVolumeName), - new String [] { column }, - PATH_WHERE, new String[] {path}, null, null); - if (c != null && c.moveToNext()) { - return c.getString(0); - } else { - return ""; - } - } catch (Exception e) { - return ""; - } finally { - if (c != null) { - c.close(); - } - } - } - - private String queryGenre(String path) { - Cursor c = null; - try { - c = mProvider.query(Audio.Genres.getContentUri(mVolumeName), - new String [] { Audio.GenresColumns.NAME }, - PATH_WHERE, new String[] {path}, null, null); - if (c != null && c.moveToNext()) { - return c.getString(0); - } else { - return ""; - } - } catch (Exception e) { - return ""; - } finally { - if (c != null) { - c.close(); - } - } - } - /** * Gets the values of the properties represented by this property group for the given * object and adds them to the given property list. @@ -229,12 +183,16 @@ class MtpPropertyGroup { if (property.column != -1 && c == null) { try { // Look up the entry in MediaProvider only if one of those properties is needed. - c = mProvider.query(mUri, mColumns, + final Uri uri = MtpDatabase.getObjectPropertiesUri(object.getFormat(), + mVolumeName); + c = mProvider.query(uri, mColumns, PATH_WHERE, new String[] {path}, null, null); if (c != null && !c.moveToNext()) { c.close(); c = null; } + } catch (IllegalArgumentException e) { + return MtpConstants.RESPONSE_INVALID_OBJECT_PROP_CODE; } catch (RemoteException e) { Log.e(TAG, "Mediaprovider lookup failed"); } @@ -290,20 +248,6 @@ class MtpPropertyGroup { list.append(id, property.code, MtpConstants.TYPE_UINT16, track % 1000); break; - case MtpConstants.PROPERTY_ARTIST: - list.append(id, property.code, - queryAudio(path, Audio.AudioColumns.ARTIST)); - break; - case MtpConstants.PROPERTY_ALBUM_NAME: - list.append(id, property.code, - queryAudio(path, Audio.AudioColumns.ALBUM)); - break; - case MtpConstants.PROPERTY_GENRE: - String genre = queryGenre(path); - if (genre != null) { - list.append(id, property.code, genre); - } - break; case MtpConstants.PROPERTY_AUDIO_WAVE_CODEC: case MtpConstants.PROPERTY_AUDIO_BITRATE: case MtpConstants.PROPERTY_SAMPLE_RATE: diff --git a/media/jni/android_media_MediaDrm.cpp b/media/jni/android_media_MediaDrm.cpp index d7ab854d63ba8496e20dcdf7e3029d0cc38ea3e6..f412161f418a2b9d338ead514f380ac9892bcf6b 100644 --- a/media/jni/android_media_MediaDrm.cpp +++ b/media/jni/android_media_MediaDrm.cpp @@ -149,6 +149,7 @@ struct SessionExceptionFields { }; struct SessionExceptionErrorCodes { + jint kErrorUnknown; jint kResourceContention; } gSessionExceptionErrorCodes; @@ -888,6 +889,8 @@ static void android_media_MediaDrm_native_init(JNIEnv *env) { gFields.sessionException.classId = static_cast(env->NewGlobalRef(clazz)); GET_FIELD_ID(gFields.sessionException.errorCode, clazz, "mErrorCode", "I"); + GET_STATIC_FIELD_ID(field, clazz, "ERROR_UNKNOWN", "I"); + gSessionExceptionErrorCodes.kErrorUnknown = env->GetStaticIntField(clazz, field); GET_STATIC_FIELD_ID(field, clazz, "ERROR_RESOURCE_CONTENTION", "I"); gSessionExceptionErrorCodes.kResourceContention = env->GetStaticIntField(clazz, field); } diff --git a/media/jni/android_media_MediaRecorder.cpp b/media/jni/android_media_MediaRecorder.cpp index 3ec0903472bc64aa80472aec88eb0f06fdf53611..24fff0635238acba3c76f8fb4cd842f19c5eb81f 100644 --- a/media/jni/android_media_MediaRecorder.cpp +++ b/media/jni/android_media_MediaRecorder.cpp @@ -760,9 +760,9 @@ android_media_MediaRecord_getActiveMicrophones(JNIEnv *env, return jStatus; } -static jint android_media_MediaRecord_setMicrophoneDirection( +static jint android_media_MediaRecord_setPreferredMicrophoneDirection( JNIEnv *env, jobject thiz, jint direction) { - ALOGV("setMicrophoneDirection(%d)", direction); + ALOGV("setPreferredMicrophoneDirection(%d)", direction); sp mr = getMediaRecorder(env, thiz); if (mr == NULL) { jniThrowException(env, "java/lang/IllegalStateException", NULL); @@ -771,7 +771,7 @@ static jint android_media_MediaRecord_setMicrophoneDirection( jint jStatus = AUDIO_JAVA_SUCCESS; status_t status = - mr->setMicrophoneDirection(static_cast(direction)); + mr->setPreferredMicrophoneDirection(static_cast(direction)); if (status != NO_ERROR) { jStatus = nativeToJavaStatus(status); } @@ -779,9 +779,9 @@ static jint android_media_MediaRecord_setMicrophoneDirection( return jStatus; } -static jint android_media_MediaRecord_setMicrophoneFieldDimension( +static jint android_media_MediaRecord_setPreferredMicrophoneFieldDimension( JNIEnv *env, jobject thiz, jfloat zoom) { - ALOGV("setMicrophoneFieldDimension(%f)", zoom); + ALOGV("setPreferredMicrophoneFieldDimension(%f)", zoom); sp mr = getMediaRecorder(env, thiz); if (mr == NULL) { jniThrowException(env, "java/lang/IllegalStateException", NULL); @@ -789,7 +789,7 @@ static jint android_media_MediaRecord_setMicrophoneFieldDimension( } jint jStatus = AUDIO_JAVA_SUCCESS; - status_t status = mr->setMicrophoneFieldDimension(zoom); + status_t status = mr->setPreferredMicrophoneFieldDimension(zoom); if (status != NO_ERROR) { jStatus = nativeToJavaStatus(status); } @@ -850,8 +850,10 @@ static const JNINativeMethod gMethods[] = { {"native_getActiveMicrophones", "(Ljava/util/ArrayList;)I", (void *)android_media_MediaRecord_getActiveMicrophones}, {"native_getPortId", "()I", (void *)android_media_MediaRecord_getPortId}, - {"native_setMicrophoneDirection", "(I)I", (void *)android_media_MediaRecord_setMicrophoneDirection}, - {"native_setMicrophoneFieldDimension", "(F)I", (void *)android_media_MediaRecord_setMicrophoneFieldDimension}, + {"native_setPreferredMicrophoneDirection", "(I)I", + (void *)android_media_MediaRecord_setPreferredMicrophoneDirection}, + {"native_setPreferredMicrophoneFieldDimension", "(F)I", + (void *)android_media_MediaRecord_setPreferredMicrophoneFieldDimension}, }; // This function only registers the native methods, and is called from diff --git a/media/mca/effect/java/android/media/effect/SingleFilterEffect.java b/media/mca/effect/java/android/media/effect/SingleFilterEffect.java index 47900dfcfd5ab95a6235b4e09ffd075c615a9063..dfbf5d20e074a7c07d14a6da72626971afaaa3ed 100644 --- a/media/mca/effect/java/android/media/effect/SingleFilterEffect.java +++ b/media/mca/effect/java/android/media/effect/SingleFilterEffect.java @@ -17,6 +17,7 @@ package android.media.effect; +import android.annotation.UnsupportedAppUsage; import android.filterfw.core.Filter; import android.filterfw.core.FilterFactory; import android.filterfw.core.FilterFunction; @@ -44,6 +45,7 @@ public class SingleFilterEffect extends FilterEffect { * @param outputName The name of the output image port. * @param finalParameters Key-value pairs of final input port assignments. */ + @UnsupportedAppUsage public SingleFilterEffect(EffectContext context, String name, Class filterClass, diff --git a/media/mca/filterfw/java/android/filterfw/GraphEnvironment.java b/media/mca/filterfw/java/android/filterfw/GraphEnvironment.java index 7c90b2731ff8ba84e3ea3a98fb3a731475cd6337..52615bf09faa4f553f3eb01ab3cc99f410160c35 100644 --- a/media/mca/filterfw/java/android/filterfw/GraphEnvironment.java +++ b/media/mca/filterfw/java/android/filterfw/GraphEnvironment.java @@ -119,6 +119,7 @@ public class GraphEnvironment extends MffEnvironment { * * @param references An alternating argument list of keys (Strings) and values. */ + @UnsupportedAppUsage public void addReferences(Object... references) { getGraphReader().addReferencesByKeysAndValues(references); } diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/CameraTestResultPrinter.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/CameraTestResultPrinter.java index 2492109abb967b822095a324c206fb51556fa5ec..ed2eebf886656c4329a42ba80ef3d253d185271c 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/CameraTestResultPrinter.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/CameraTestResultPrinter.java @@ -40,14 +40,14 @@ public class CameraTestResultPrinter { private Instrumentation mInst = null; private boolean mWriteToFile = true; - public CameraTestResultPrinter(Instrumentation instrumentation, boolean writeToFile) { mInst = instrumentation; mWriteToFile = writeToFile; // Create a log directory if not exists. File baseDir = new File(RESULT_DIR); - if (!baseDir.exists() && !baseDir.mkdirs()) { + baseDir.mkdirs(); + if (!baseDir.isDirectory()) { throw new IllegalStateException("Couldn't create directory for logs: " + baseDir); } Log.v(TAG, String.format("Saving test results under: %s", baseDir.getAbsolutePath())); diff --git a/media/tests/MediaRouteProvider/Android.bp b/media/tests/MediaRouteProvider/Android.bp new file mode 100644 index 0000000000000000000000000000000000000000..da4282495ac2ff3e3c12d6f9e0dfcbc85cbac4a7 --- /dev/null +++ b/media/tests/MediaRouteProvider/Android.bp @@ -0,0 +1,18 @@ +android_test { + name: "mediarouteprovider", + + srcs: ["**/*.java"], + + libs: [ + "android.test.runner", + "android.test.base", + ], + + static_libs: [ + "android-support-test", + "mockito-target-minus-junit4", + ], + + platform_apis: true, + certificate: "platform", +} \ No newline at end of file diff --git a/media/tests/MediaRouteProvider/AndroidManifest.xml b/media/tests/MediaRouteProvider/AndroidManifest.xml new file mode 100644 index 0000000000000000000000000000000000000000..489a6214ecbdbcd1ba00c3c6d8524325bb53c06e --- /dev/null +++ b/media/tests/MediaRouteProvider/AndroidManifest.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + diff --git a/media/tests/MediaRouteProvider/res/values/strings.xml b/media/tests/MediaRouteProvider/res/values/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..bb970641ffdab15ae3020d0bf6173018a8dfdba9 --- /dev/null +++ b/media/tests/MediaRouteProvider/res/values/strings.xml @@ -0,0 +1,5 @@ + + + + SampleMediaRouteProvider + \ No newline at end of file diff --git a/media/tests/MediaRouteProvider/src/com/android/mediarouteprovider/example/SampleMediaRoute2ProviderService.java b/media/tests/MediaRouteProvider/src/com/android/mediarouteprovider/example/SampleMediaRoute2ProviderService.java new file mode 100644 index 0000000000000000000000000000000000000000..22fbd85d6979869bd35dba99f4892cb068524cda --- /dev/null +++ b/media/tests/MediaRouteProvider/src/com/android/mediarouteprovider/example/SampleMediaRoute2ProviderService.java @@ -0,0 +1,33 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.mediarouteprovider.example; + +import android.content.Intent; +import android.media.MediaRoute2ProviderService; +import android.os.IBinder; + +public class SampleMediaRoute2ProviderService extends MediaRoute2ProviderService { + @Override + public IBinder onBind(Intent intent) { + return super.onBind(intent); + } + + @Override + public void onSelect(int uid, String routeId) { + updateProvider(uid, routeId); + } +} diff --git a/media/tests/MediaRouter/Android.bp b/media/tests/MediaRouter/Android.bp new file mode 100644 index 0000000000000000000000000000000000000000..611b25a2f128ca7efa8f3444f211aba020d06e4a --- /dev/null +++ b/media/tests/MediaRouter/Android.bp @@ -0,0 +1,18 @@ +android_test { + name: "mediaroutertest", + + srcs: ["**/*.java"], + + libs: [ + "android.test.runner", + "android.test.base", + ], + + static_libs: [ + "android-support-test", + "mockito-target-minus-junit4", + ], + + platform_apis: true, + certificate: "platform", +} \ No newline at end of file diff --git a/media/tests/MediaRouter/AndroidManifest.xml b/media/tests/MediaRouter/AndroidManifest.xml new file mode 100644 index 0000000000000000000000000000000000000000..a34a264e1247458278c116ce964f86c2d7c1f80a --- /dev/null +++ b/media/tests/MediaRouter/AndroidManifest.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + diff --git a/media/tests/MediaRouter/AndroidTest.xml b/media/tests/MediaRouter/AndroidTest.xml new file mode 100644 index 0000000000000000000000000000000000000000..1301062db496bd8cda695ab942f8262c578cd063 --- /dev/null +++ b/media/tests/MediaRouter/AndroidTest.xml @@ -0,0 +1,16 @@ + + + + + + + diff --git a/media/tests/MediaRouter/res/values/strings.xml b/media/tests/MediaRouter/res/values/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..07370207a3c9d5d5ab60534c2e9019b49f4c76aa --- /dev/null +++ b/media/tests/MediaRouter/res/values/strings.xml @@ -0,0 +1,5 @@ + + + + mediaRouterTest + \ No newline at end of file diff --git a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java new file mode 100644 index 0000000000000000000000000000000000000000..a4bde65925161232421048e953c7be165f241937 --- /dev/null +++ b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java @@ -0,0 +1,110 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.mediaroutertest; + +import static org.mockito.Mockito.after; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.timeout; +import static org.mockito.Mockito.verify; + +import android.content.Context; +import android.media.MediaRouter; +import android.media.MediaRouter2Manager; +import android.support.test.InstrumentationRegistry; +import android.support.test.filters.SmallTest; +import android.support.test.runner.AndroidJUnit4; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Executor; +import java.util.concurrent.SynchronousQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +@RunWith(AndroidJUnit4.class) +@SmallTest +public class MediaRouterManagerTest { + private static final String TAG = "MediaRouterManagerTest"; + + private static final int TARGET_UID = 109992; + private static final String ROUTE_1 = "MediaRoute1"; + + private static final int AWAIT_MS = 1000; + private static final int TIMEOUT_MS = 1000; + + private Context mContext; + private MediaRouter2Manager mManager; + private MediaRouter mRouter; + private Executor mExecutor; + + private static final List TEST_CONTROL_CATEGORIES = new ArrayList(); + private static final String CONTROL_CATEGORY_1 = "android.media.mediarouter.MEDIA1"; + private static final String CONTROL_CATEGORY_2 = "android.media.mediarouter.MEDIA2"; + static { + TEST_CONTROL_CATEGORIES.add(CONTROL_CATEGORY_1); + TEST_CONTROL_CATEGORIES.add(CONTROL_CATEGORY_2); + } + + @Before + public void setUp() throws Exception { + mContext = InstrumentationRegistry.getTargetContext(); + mManager = MediaRouter2Manager.getInstance(mContext); + mRouter = (MediaRouter) mContext.getSystemService(Context.MEDIA_ROUTER_SERVICE); + mExecutor = new ThreadPoolExecutor( + 1, 20, 3, TimeUnit.SECONDS, + new SynchronousQueue()); + } + + @Test + public void transferTest() throws Exception { + MediaRouter2Manager.Callback mockCallback = mock(MediaRouter2Manager.Callback.class); + + mManager.addCallback(mExecutor, mockCallback); + + verify(mockCallback, after(AWAIT_MS).never()) + .onRouteSelected(eq(TARGET_UID), any(String.class)); + + mManager.selectRoute(TARGET_UID, ROUTE_1); + verify(mockCallback, timeout(TIMEOUT_MS)).onRouteSelected(TARGET_UID, ROUTE_1); + + mManager.removeCallback(mockCallback); + } + + @Test + public void controlCategoryTest() throws Exception { + final int uid = android.os.Process.myUid(); + + MediaRouter2Manager.Callback mockCallback = mock(MediaRouter2Manager.Callback.class); + mManager.addCallback(mExecutor, mockCallback); + + verify(mockCallback, after(AWAIT_MS).never()).onControlCategoriesChanged(eq(uid), + any(List.class)); + + mRouter.setControlCategories(TEST_CONTROL_CATEGORIES); + verify(mockCallback, timeout(TIMEOUT_MS).atLeastOnce()) + .onControlCategoriesChanged(uid, TEST_CONTROL_CATEGORIES); + + mManager.removeCallback(mockCallback); + } + +} diff --git a/native/android/libandroid.map.txt b/native/android/libandroid.map.txt index e1dc40636ca55b9a3862d4851239a27d3191a231..1f2480ba0b475f716d18b524145d62eb3d0ffed6 100644 --- a/native/android/libandroid.map.txt +++ b/native/android/libandroid.map.txt @@ -148,6 +148,7 @@ LIBANDROID { AHardwareBuffer_getNativeHandle; # introduced=26 AHardwareBuffer_isSupported; # introduced=29 AHardwareBuffer_lock; # introduced=26 + AHardwareBuffer_lockAndGetInfo; # introduced=29 AHardwareBuffer_lockPlanes; # introduced=29 AHardwareBuffer_recvHandleFromUnixSocket; # introduced=26 AHardwareBuffer_release; # introduced=26 diff --git a/native/webview/plat_support/draw_fn.h b/native/webview/plat_support/draw_fn.h index 5b3e496be81a6eaa7f17a3bd584a04ff1a303e69..42cad43af8fcc510b89d654563268c4ad945eb39 100644 --- a/native/webview/plat_support/draw_fn.h +++ b/native/webview/plat_support/draw_fn.h @@ -44,23 +44,8 @@ struct AwDrawFn_DrawGLParams { int width; int height; - // Input: is the View rendered into an independent layer. - // If false, the surface is likely to hold to the full screen contents, with - // the scissor box set by the caller to the actual View location and size. - // Also the transformation matrix will contain at least a translation to the - // position of the View to render, plus any other transformations required as - // part of any ongoing View animation. View translucency (alpha) is ignored, - // although the framework will set is_layer to true for non-opaque cases. - // Can be requested via the View.setLayerType(View.LAYER_TYPE_NONE, ...) - // Android API method. - // - // If true, the surface is dedicated to the View and should have its size. - // The viewport and scissor box are set by the caller to the whole surface. - // Animation transformations are handled by the caller and not reflected in - // the provided transformation matrix. Translucency works normally. - // Can be requested via the View.setLayerType(View.LAYER_TYPE_HARDWARE, ...) - // Android API method. - bool is_layer; + // Used to be is_layer. + bool deprecated_0; // Input: current transformation matrix in surface pixels. // Uses the column-based OpenGL matrix format. @@ -102,8 +87,7 @@ struct AwDrawFn_DrawVkParams { int width; int height; - // Input: is the render target a FBO - bool is_layer; + bool deprecated_0; // Input: current transform matrix float transform[16]; diff --git a/native/webview/plat_support/draw_functor.cpp b/native/webview/plat_support/draw_functor.cpp index e43a60c3f39649413289d02b48f170f13a017685..7cce61b87d12c66bb6decc28f5ee9a9a86f34d41 100644 --- a/native/webview/plat_support/draw_functor.cpp +++ b/native/webview/plat_support/draw_functor.cpp @@ -65,7 +65,7 @@ void draw_gl(int functor, void* data, .clip_bottom = draw_gl_params.clipBottom, .width = draw_gl_params.width, .height = draw_gl_params.height, - .is_layer = draw_gl_params.isLayer, + .deprecated_0 = false, .transfer_function_g = gabcdef[0], .transfer_function_a = gabcdef[1], .transfer_function_b = gabcdef[2], @@ -126,7 +126,7 @@ void drawVk(int functor, void* data, const uirenderer::VkFunctorDrawParams& draw .version = kAwDrawFnVersion, .width = draw_vk_params.width, .height = draw_vk_params.height, - .is_layer = draw_vk_params.is_layer, + .deprecated_0 = false, .secondary_command_buffer = draw_vk_params.secondary_command_buffer, .color_attachment_index = draw_vk_params.color_attachment_index, .compatible_render_pass = draw_vk_params.compatible_render_pass, diff --git a/packages/CarSystemUI/Android.bp b/packages/CarSystemUI/Android.bp index 4c9629def113f9742dfaa22981b96d2225f5009c..589623b0d6cd89381986f350b7520c81f9e500d0 100644 --- a/packages/CarSystemUI/Android.bp +++ b/packages/CarSystemUI/Android.bp @@ -32,7 +32,6 @@ android_app { "SystemUISharedLib", "SettingsLib", "android.car.userlib", - "androidx.car_car", "androidx.legacy_legacy-support-v4", "androidx.recyclerview_recyclerview", "androidx.preference_preference", @@ -46,7 +45,6 @@ android_app { "androidx.slice_slice-builders", "androidx.arch.core_core-runtime", "androidx.lifecycle_lifecycle-extensions", - "car-theme-lib-bp", "SystemUI-tags", "SystemUI-proto", ], diff --git a/packages/CarSystemUI/res-keyguard/drawable/keyguard_button_background.xml b/packages/CarSystemUI/res-keyguard/drawable/keyguard_button_background.xml index b428931670f5b2c9cdfaa25c8e856184bb17d6ea..8b2779d104810b8d0d71a361793445b047c1e9e6 100644 --- a/packages/CarSystemUI/res-keyguard/drawable/keyguard_button_background.xml +++ b/packages/CarSystemUI/res-keyguard/drawable/keyguard_button_background.xml @@ -18,13 +18,13 @@ - + - + diff --git a/packages/CarSystemUI/res-keyguard/layout-land/keyguard_pattern_view.xml b/packages/CarSystemUI/res-keyguard/layout-land/keyguard_pattern_view.xml index b115a1f3c131487c6be9c27eefedcd683fb7eb7f..a465254afebb3af1a9d7da08c0e9bee7ef5847a6 100644 --- a/packages/CarSystemUI/res-keyguard/layout-land/keyguard_pattern_view.xml +++ b/packages/CarSystemUI/res-keyguard/layout-land/keyguard_pattern_view.xml @@ -28,7 +28,7 @@ android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent" - android:paddingHorizontal="@dimen/car_margin"> + android:paddingHorizontal="@*android:dimen/car_margin"> diff --git a/packages/CarSystemUI/res-keyguard/layout-land/keyguard_pin_view.xml b/packages/CarSystemUI/res-keyguard/layout-land/keyguard_pin_view.xml index ed88c6235d58fd1a4867d603c29b690312e163fe..5746102f5f275be721a767ab15ae2cb791662c1c 100644 --- a/packages/CarSystemUI/res-keyguard/layout-land/keyguard_pin_view.xml +++ b/packages/CarSystemUI/res-keyguard/layout-land/keyguard_pin_view.xml @@ -29,7 +29,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" - android:paddingHorizontal="@dimen/car_margin"> + android:paddingHorizontal="@*android:dimen/car_margin"> diff --git a/packages/CarSystemUI/res-keyguard/layout/keyguard_message_area.xml b/packages/CarSystemUI/res-keyguard/layout/keyguard_message_area.xml index c2304147982a44da253bfbb4c55a46a381e0332f..09cf4722dae0a2a1f5f732b11e1e78a1a402a35d 100644 --- a/packages/CarSystemUI/res-keyguard/layout/keyguard_message_area.xml +++ b/packages/CarSystemUI/res-keyguard/layout/keyguard_message_area.xml @@ -27,5 +27,5 @@ android:singleLine="true" android:ellipsize="marquee" android:focusable="true" - android:layout_marginBottom="@dimen/car_padding_4" - android:textSize="@dimen/car_body2_size" /> + android:layout_marginBottom="@*android:dimen/car_padding_4" + android:textSize="@*android:dimen/car_body2_size" /> diff --git a/packages/CarSystemUI/res-keyguard/layout/keyguard_password_view.xml b/packages/CarSystemUI/res-keyguard/layout/keyguard_password_view.xml index e701fdb956f54fe2df6440f49eb76af7685819da..7004fb64ba067ecb42e7c286262437343ebf53b3 100644 --- a/packages/CarSystemUI/res-keyguard/layout/keyguard_password_view.xml +++ b/packages/CarSystemUI/res-keyguard/layout/keyguard_password_view.xml @@ -51,7 +51,7 @@ android:singleLine="true" android:textStyle="normal" android:inputType="textPassword" - android:textSize="@dimen/car_body1_size" + android:textSize="@*android:dimen/car_body1_size" android:textColor="?attr/wallpaperTextColor" android:textAppearance="?android:attr/textAppearanceMedium" android:imeOptions="flagForceAscii|actionDone" @@ -61,10 +61,10 @@