diff options
460 files changed, 11040 insertions, 6157 deletions
diff --git a/Android.bp b/Android.bp index e756b3428164..eacf57ccd38c 100644 --- a/Android.bp +++ b/Android.bp @@ -366,7 +366,8 @@ filegroup { ":framework-tethering-srcs", ":framework-wifi-updatable-sources", ":updatable-media-srcs", - ] + ], + visibility: ["//visibility:private"], } java_library { @@ -383,7 +384,31 @@ java_library { "framework-wifi.stubs.module_lib", ], sdk_version: "module_current", - visibility: [":__pkg__"], + visibility: ["//visibility:private"], +} + +java_library { + name: "framework-all", + installable: false, + static_libs: [ + "framework-minus-apex", + "framework-appsearch", + "framework-graphics.impl", + "framework-mediaprovider.impl", + "framework-permission.impl", + "framework-sdkextensions.impl", + "framework-statsd.impl", + "framework-tethering.impl", + "framework-wifi.impl", + "updatable-media", + ], + apex_available: ["//apex_available:platform"], + sdk_version: "core_platform", + visibility: [ + // DO NOT ADD ANY MORE ENTRIES TO THIS LIST + "//external/robolectric-shadows:__subpackages__", + "//frameworks/layoutlib:__subpackages__", + ], } filegroup { @@ -474,53 +499,6 @@ java_library { installable: false, } -java_defaults { - name: "framework-defaults", - defaults: ["framework-aidl-export-defaults"], - installable: true, - - aidl: { - generate_get_transaction_name: true, - }, - - srcs: ["core/java/**/*.logtags"], - - exclude_srcs: [ - // See comment on framework-atb-backward-compatibility module below - "core/java/android/content/pm/AndroidTestBaseUpdater.java", - ], - - sdk_version: "core_platform", - libs: [ - "app-compat-annotations", - "ext", - "unsupportedappusage", - ], - - jarjar_rules: ":framework-jarjar-rules", - - static_libs: [ - "framework-internal-utils", - ], - - dxflags: [ - "--core-library", - "--multi-dex", - ], - - plugins: [ - "view-inspector-annotation-processor", - "staledataclass-annotation-processor", - "error_prone_android_framework", - ], - - required: [ - // TODO: remove gps_debug and protolog.conf.json when the build system propagates "required" properly. - "gps_debug.conf", - "protolog.conf.json.gz", - ], -} - filegroup { name: "framework-jarjar-rules", srcs: ["framework-jarjar-rules.txt"], @@ -560,19 +538,47 @@ filegroup { java_library { name: "framework-minus-apex", - defaults: ["framework-defaults"], - srcs: [":framework-non-updatable-sources"], + defaults: ["framework-aidl-export-defaults"], + srcs: [ + ":framework-non-updatable-sources", + "core/java/**/*.logtags", + ], + // See comment on framework-atb-backward-compatibility module below + exclude_srcs: ["core/java/android/content/pm/AndroidTestBaseUpdater.java"], + aidl: { + generate_get_transaction_name: true, + }, + dxflags: [ + "--core-library", + "--multi-dex", + ], installable: true, + jarjar_rules: ":framework-jarjar-rules", javac_shard_size: 150, + plugins: [ + "view-inspector-annotation-processor", + "staledataclass-annotation-processor", + "error_prone_android_framework", + ], required: [ "framework-platform-compat-config", + // TODO: remove gps_debug and protolog.conf.json when the build system propagates "required" properly. + "gps_debug.conf", "libcore-platform-compat-config", + "protolog.conf.json.gz", "services-platform-compat-config", "documents-ui-compat-config", "calendar-provider-compat-config", ], - libs: ["framework-updatable-stubs-module_libs_api"], + libs: [ + "app-compat-annotations", + "ext", + "framework-updatable-stubs-module_libs_api", + "unsupportedappusage", + ], + sdk_version: "core_platform", static_libs: [ + "framework-internal-utils", // If MimeMap ever becomes its own APEX, then this dependency would need to be removed // in favor of an API stubs dependency in java_library "framework" below. "mimemap", @@ -615,32 +621,6 @@ java_library { apex_available: ["//apex_available:platform"], } -java_library { - name: "framework-all", - defaults: ["framework-defaults"], - srcs: [":framework-all-sources"], - installable: false, - static_libs: [ - "exoplayer2-extractor", - "android.hardware.wifi-V1.0-java-constants", - "mediatranscoding_aidl_interface-java", - - // Additional dependencies needed to build the ike API classes. - "ike-internals", - ], - plugins: [ - "intdef-annotation-processor", - ], - libs: ["icing-java-proto-lite"], - apex_available: ["//apex_available:platform"], - visibility: [ - // DO NOT ADD ANY MORE ENTRIES TO THIS LIST - "//external/robolectric-shadows:__subpackages__", - "//frameworks/base", - "//frameworks/layoutlib:__subpackages__", - ], -} - platform_compat_config { name: "framework-platform-compat-config", src: ":framework-minus-apex", diff --git a/apct-tests/perftests/core/src/android/os/PackageParsingPerfTest.kt b/apct-tests/perftests/core/src/android/os/PackageParsingPerfTest.kt index 29721c593646..9e519f7afb93 100644 --- a/apct-tests/perftests/core/src/android/os/PackageParsingPerfTest.kt +++ b/apct-tests/perftests/core/src/android/os/PackageParsingPerfTest.kt @@ -184,11 +184,11 @@ class PackageParsingPerfTest { override fun startParsingPackage( packageName: String, - baseCodePath: String, - codePath: String, + baseApkPath: String, + path: String, manifestArray: TypedArray, isCoreApp: Boolean - ) = ParsingPackageImpl(packageName, baseCodePath, codePath, manifestArray) + ) = ParsingPackageImpl(packageName, baseApkPath, path, manifestArray) }) override fun parseImpl(file: File) = diff --git a/apct-tests/perftests/windowmanager/src/android/wm/RelayoutPerfTest.java b/apct-tests/perftests/windowmanager/src/android/wm/RelayoutPerfTest.java index 269742854cb0..a701f8631969 100644 --- a/apct-tests/perftests/windowmanager/src/android/wm/RelayoutPerfTest.java +++ b/apct-tests/perftests/windowmanager/src/android/wm/RelayoutPerfTest.java @@ -21,14 +21,12 @@ import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentat import android.app.Activity; import android.content.Context; import android.graphics.Point; -import android.graphics.Rect; import android.os.RemoteException; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; import android.perftests.utils.PerfTestActivity; import android.platform.test.annotations.Presubmit; import android.util.MergedConfiguration; -import android.view.DisplayCutout; import android.view.IWindow; import android.view.IWindowSession; import android.view.InsetsSourceControl; @@ -38,6 +36,7 @@ import android.view.View; import android.view.WindowManager; import android.view.WindowManagerGlobal; import android.widget.LinearLayout; +import android.window.ClientWindowFrames; import androidx.test.filters.LargeTest; import androidx.test.rule.ActivityTestRule; @@ -125,13 +124,7 @@ public class RelayoutPerfTest extends WindowManagerPerfTestBase } private static class RelayoutRunner { - final Rect mOutFrame = new Rect(); - final Rect mOutContentInsets = new Rect(); - final Rect mOutVisibleInsets = new Rect(); - final Rect mOutStableInsets = new Rect(); - final Rect mOutBackDropFrame = new Rect(); - final DisplayCutout.ParcelableWrapper mOutDisplayCutout = - new DisplayCutout.ParcelableWrapper(DisplayCutout.NO_CUTOUT); + final ClientWindowFrames mOutFrames = new ClientWindowFrames(); final MergedConfiguration mOutMergedConfiguration = new MergedConfiguration(); final InsetsState mOutInsetsState = new InsetsState(); final InsetsSourceControl[] mOutControls = new InsetsSourceControl[0]; @@ -164,11 +157,9 @@ public class RelayoutPerfTest extends WindowManagerPerfTestBase final IWindowSession session = WindowManagerGlobal.getWindowSession(); while (state.keepRunning()) { session.relayout(mWindow, mSeq, mParams, mWidth, mHeight, - mViewVisibility.getAsInt(), mFlags, mFrameNumber, mOutFrame, - mOutContentInsets, mOutVisibleInsets, mOutStableInsets, - mOutBackDropFrame, mOutDisplayCutout, mOutMergedConfiguration, - mOutSurfaceControl, mOutInsetsState, mOutControls, mOutSurfaceSize, - mOutBlastSurfaceControl); + mViewVisibility.getAsInt(), mFlags, mFrameNumber, mOutFrames, + mOutMergedConfiguration, mOutSurfaceControl, mOutInsetsState, mOutControls, + mOutSurfaceSize, mOutBlastSurfaceControl); } } } diff --git a/apex/Android.bp b/apex/Android.bp index d6d3c27dcd6b..266e6720c1a1 100644 --- a/apex/Android.bp +++ b/apex/Android.bp @@ -106,7 +106,10 @@ java_defaults { stubs_library_visibility: ["//visibility:public"], // Hide impl library and stub sources - impl_library_visibility: [":__package__"], + impl_library_visibility: [ + ":__package__", + "//frameworks/base", // For framework-all + ], stubs_source_visibility: ["//visibility:private"], // Collates API usages from each module for further analysis. diff --git a/apex/media/framework/Android.bp b/apex/media/framework/Android.bp index 4417b681efc3..ce4b030467a7 100644 --- a/apex/media/framework/Android.bp +++ b/apex/media/framework/Android.bp @@ -44,7 +44,6 @@ java_library { plugins: ["java_api_finder"], hostdex: true, // for hiddenapi check - visibility: ["//frameworks/av/apex:__subpackages__"], apex_available: [ "com.android.media", "test_com.android.media", @@ -83,7 +82,7 @@ filegroup { "java/android/media/MediaParser.java" ], path: "java", -} +} java_sdk_library { name: "framework-media", @@ -99,15 +98,7 @@ java_sdk_library { libs: [ "framework_media_annotation", ], - - // Allow access to the stubs from anywhere. - visibility: ["//visibility:public"], - - // Restrict access to implementation library. - impl_library_visibility: [ - "//visibility:override", // Ignore the visibility property. - "//frameworks/av/apex:__subpackages__", - ], + impl_library_visibility: ["//frameworks/av/apex:__subpackages__"], } diff --git a/apex/permission/framework/Android.bp b/apex/permission/framework/Android.bp index be553feb1d34..c0560f61460f 100644 --- a/apex/permission/framework/Android.bp +++ b/apex/permission/framework/Android.bp @@ -25,14 +25,8 @@ java_sdk_library { name: "framework-permission", defaults: ["framework-module-defaults"], - // Allow access to the stubs from anywhere. - visibility: ["//visibility:public"], - // Restrict access to implementation library. - impl_library_visibility: [ - "//visibility:override", // Ignore the visibility property. - "//frameworks/base/apex/permission:__subpackages__", - ], + impl_library_visibility: ["//frameworks/base/apex/permission:__subpackages__"], srcs: [ ":framework-permission-sources", diff --git a/apex/permission/service/Android.bp b/apex/permission/service/Android.bp index 7f3187949712..b7d843352d8e 100644 --- a/apex/permission/service/Android.bp +++ b/apex/permission/service/Android.bp @@ -23,15 +23,7 @@ filegroup { java_sdk_library { name: "service-permission", defaults: ["framework-system-server-module-defaults"], - visibility: [ - "//frameworks/base/services/core", - "//frameworks/base/apex/permission", - "//frameworks/base/apex/permission/testing", - "//frameworks/base/apex/permission/tests", - "//frameworks/base/services/tests/mockingservicestests", - ], impl_library_visibility: [ - "//visibility:override", "//frameworks/base/apex/permission/tests", "//frameworks/base/services/tests/mockingservicestests", "//frameworks/base/services/tests/servicestests", diff --git a/apex/statsd/framework/Android.bp b/apex/statsd/framework/Android.bp index b06f4019b480..bf4323ddfb0b 100644 --- a/apex/statsd/framework/Android.bp +++ b/apex/statsd/framework/Android.bp @@ -72,19 +72,7 @@ java_sdk_library { hostdex: true, // for hiddenapi check - visibility: [ - "//frameworks/base", // Framework - "//frameworks/base/apex/statsd:__subpackages__", // statsd apex - "//frameworks/base/packages/Tethering", // Tethering - "//frameworks/opt/net/wifi/service", // wifi service - "//packages/providers/MediaProvider", // MediaProvider apk - ], - - // Restrict access to implementation library. - impl_library_visibility: [ - "//visibility:override", // Ignore the visibility property. - "//frameworks/base/apex/statsd:__subpackages__", // statsd apex - ], + impl_library_visibility: ["//frameworks/base/apex/statsd/framework/test:__subpackages__"], apex_available: [ "com.android.os.statsd", diff --git a/apex/statsd/service/java/com/android/server/stats/StatsManagerService.java b/apex/statsd/service/java/com/android/server/stats/StatsManagerService.java index 97846f2397a5..1e3846bc4a0b 100644 --- a/apex/statsd/service/java/com/android/server/stats/StatsManagerService.java +++ b/apex/statsd/service/java/com/android/server/stats/StatsManagerService.java @@ -27,6 +27,7 @@ import android.os.Binder; import android.os.IPullAtomCallback; import android.os.IStatsManagerService; import android.os.IStatsd; +import android.os.PowerManager; import android.os.Process; import android.os.RemoteException; import android.util.ArrayMap; @@ -412,8 +413,13 @@ public class StatsManagerService extends IStatsManagerService.Stub { @Override public byte[] getData(long key, String packageName) throws IllegalStateException { enforceDumpAndUsageStatsPermission(packageName); + PowerManager powerManager = (PowerManager) + mContext.getSystemService(Context.POWER_SERVICE); + PowerManager.WakeLock wl = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, + /*tag=*/ StatsManagerService.class.getCanonicalName()); int callingUid = Binder.getCallingUid(); final long token = Binder.clearCallingIdentity(); + wl.acquire(); try { IStatsd statsd = waitForStatsd(); if (statsd != null) { @@ -423,6 +429,7 @@ public class StatsManagerService extends IStatsManagerService.Stub { Log.e(TAG, "Failed to getData with statsd"); throw new IllegalStateException(e.getMessage(), e); } finally { + wl.release(); Binder.restoreCallingIdentity(token); } throw new IllegalStateException("Failed to connect to statsd to getData"); diff --git a/api/current.txt b/api/current.txt index e83450136aa4..5f32dec22de9 100644 --- a/api/current.txt +++ b/api/current.txt @@ -31303,6 +31303,7 @@ package android.net.wifi { @Deprecated public static class WifiConfiguration.GroupCipher { field @Deprecated public static final int CCMP = 3; // 0x3 + field @Deprecated public static final int GCMP_128 = 7; // 0x7 field @Deprecated public static final int GCMP_256 = 5; // 0x5 field @Deprecated public static final int SMS4 = 6; // 0x6 field @Deprecated public static final int TKIP = 2; // 0x2 @@ -31332,6 +31333,7 @@ package android.net.wifi { @Deprecated public static class WifiConfiguration.PairwiseCipher { field @Deprecated public static final int CCMP = 2; // 0x2 + field @Deprecated public static final int GCMP_128 = 5; // 0x5 field @Deprecated public static final int GCMP_256 = 3; // 0x3 field @Deprecated public static final int NONE = 0; // 0x0 field @Deprecated public static final int SMS4 = 4; // 0x4 @@ -31814,6 +31816,7 @@ package android.net.wifi.aware { method public void attach(@NonNull android.net.wifi.aware.AttachCallback, @NonNull android.net.wifi.aware.IdentityChangedListener, @Nullable android.os.Handler); method public android.net.wifi.aware.Characteristics getCharacteristics(); method public boolean isAvailable(); + method public boolean isDeviceAttached(); field public static final String ACTION_WIFI_AWARE_STATE_CHANGED = "android.net.wifi.aware.action.WIFI_AWARE_STATE_CHANGED"; field public static final int WIFI_AWARE_DATA_PATH_ROLE_INITIATOR = 0; // 0x0 field public static final int WIFI_AWARE_DATA_PATH_ROLE_RESPONDER = 1; // 0x1 diff --git a/api/module-lib-current.txt b/api/module-lib-current.txt index 73511c0f5b87..c12d897b9d72 100644 --- a/api/module-lib-current.txt +++ b/api/module-lib-current.txt @@ -35,9 +35,16 @@ package android.graphics { package android.media { public class AudioManager { + method public void adjustStreamVolumeForUid(int, int, int, @NonNull String, int, int, int); + method public void adjustSuggestedStreamVolumeForUid(int, int, int, @NonNull String, int, int, int); + method public void setStreamVolumeForUid(int, int, int, @NonNull String, int, int, int); field public static final int FLAG_FROM_KEY = 4096; // 0x1000 } + public static final class MediaMetadata.Builder { + ctor public MediaMetadata.Builder(@NonNull android.media.MediaMetadata, @IntRange(from=1) int); + } + } package android.media.session { @@ -50,6 +57,10 @@ package android.media.session { field public static final int FLAG_EXCLUSIVE_GLOBAL_PRIORITY = 65536; // 0x10000 } + public static final class MediaSession.Token implements android.os.Parcelable { + method public int getUid(); + } + public final class MediaSessionManager { method public void dispatchMediaKeyEventAsSystemService(@NonNull android.view.KeyEvent); method public boolean dispatchMediaKeyEventAsSystemService(@NonNull android.media.session.MediaSession.Token, @NonNull android.view.KeyEvent); diff --git a/api/system-current.txt b/api/system-current.txt index c3e56643a805..b908cae38ca1 100755..100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -205,6 +205,7 @@ package android { field public static final String REVOKE_RUNTIME_PERMISSIONS = "android.permission.REVOKE_RUNTIME_PERMISSIONS"; field public static final String SCORE_NETWORKS = "android.permission.SCORE_NETWORKS"; field public static final String SECURE_ELEMENT_PRIVILEGED_OPERATION = "android.permission.SECURE_ELEMENT_PRIVILEGED_OPERATION"; + field public static final String SEND_CATEGORY_CAR_NOTIFICATIONS = "android.permission.SEND_CATEGORY_CAR_NOTIFICATIONS"; field public static final String SEND_DEVICE_CUSTOMIZATION_READY = "android.permission.SEND_DEVICE_CUSTOMIZATION_READY"; field public static final String SEND_SHOW_SUSPENDED_APP_DETAILS = "android.permission.SEND_SHOW_SUSPENDED_APP_DETAILS"; field public static final String SEND_SMS_NO_CONFIRMATION = "android.permission.SEND_SMS_NO_CONFIRMATION"; @@ -4199,8 +4200,10 @@ package android.media { public class AudioManager { method @Deprecated public int abandonAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, android.media.AudioAttributes); method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void addOnPreferredDeviceForStrategyChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.OnPreferredDeviceForStrategyChangedListener) throws java.lang.SecurityException; + method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void addOnPreferredDevicesForCapturePresetChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.OnPreferredDevicesForCapturePresetChangedListener) throws java.lang.SecurityException; method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void addOnPreferredDevicesForStrategyChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.OnPreferredDevicesForStrategyChangedListener) throws java.lang.SecurityException; method public void clearAudioServerStateCallback(); + method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean clearPreferredDevicesForCapturePreset(int); method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int dispatchAudioFocusChange(@NonNull android.media.AudioFocusInfo, int, @NonNull android.media.audiopolicy.AudioPolicy); method @IntRange(from=0) public long getAdditionalOutputDeviceDelay(@NonNull android.media.AudioDeviceInfo); method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static java.util.List<android.media.audiopolicy.AudioProductStrategy> getAudioProductStrategies(); @@ -4211,6 +4214,7 @@ package android.media { method @IntRange(from=0) @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getMaxVolumeIndexForAttributes(@NonNull android.media.AudioAttributes); method @IntRange(from=0) @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getMinVolumeIndexForAttributes(@NonNull android.media.AudioAttributes); method @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public android.media.AudioDeviceAttributes getPreferredDeviceForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy); + method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public java.util.List<android.media.AudioDeviceAttributes> getPreferredDevicesForCapturePreset(int); method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public java.util.List<android.media.AudioDeviceAttributes> getPreferredDevicesForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy); method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int[] getSupportedSystemUsages(); method @IntRange(from=0) @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getVolumeIndexForAttributes(@NonNull android.media.AudioAttributes); @@ -4219,6 +4223,7 @@ package android.media { method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int registerAudioPolicy(@NonNull android.media.audiopolicy.AudioPolicy); method public void registerVolumeGroupCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.VolumeGroupCallback); method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void removeOnPreferredDeviceForStrategyChangedListener(@NonNull android.media.AudioManager.OnPreferredDeviceForStrategyChangedListener); + method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void removeOnPreferredDevicesForCapturePresetChangedListener(@NonNull android.media.AudioManager.OnPreferredDevicesForCapturePresetChangedListener); method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void removeOnPreferredDevicesForStrategyChangedListener(@NonNull android.media.AudioManager.OnPreferredDevicesForStrategyChangedListener); method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean removePreferredDeviceForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int requestAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, @NonNull android.media.AudioAttributes, int, int) throws java.lang.IllegalArgumentException; @@ -4228,6 +4233,7 @@ package android.media { method public void setAudioServerStateCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.AudioServerStateCallback); method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setDeviceVolumeBehavior(@NonNull android.media.AudioDeviceAttributes, int); method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setFocusRequestResult(@NonNull android.media.AudioFocusInfo, int, @NonNull android.media.audiopolicy.AudioPolicy); + method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean setPreferredDeviceForCapturePreset(int, @NonNull android.media.AudioDeviceAttributes); method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean setPreferredDeviceForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy, @NonNull android.media.AudioDeviceAttributes); method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean setPreferredDevicesForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy, @NonNull java.util.List<android.media.AudioDeviceAttributes>); method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setSupportedSystemUsages(@NonNull int[]); @@ -4257,6 +4263,10 @@ package android.media { method @Deprecated public void onPreferredDeviceForStrategyChanged(@NonNull android.media.audiopolicy.AudioProductStrategy, @Nullable android.media.AudioDeviceAttributes); } + public static interface AudioManager.OnPreferredDevicesForCapturePresetChangedListener { + method public void onPreferredDevicesForCapturePresetChanged(int, @NonNull java.util.List<android.media.AudioDeviceAttributes>); + } + public static interface AudioManager.OnPreferredDevicesForStrategyChangedListener { method public void onPreferredDevicesForStrategyChanged(@NonNull android.media.audiopolicy.AudioProductStrategy, @NonNull java.util.List<android.media.AudioDeviceAttributes>); } @@ -4385,6 +4395,14 @@ package android.media { method @NonNull public android.media.MediaTranscodeManager.TranscodingRequest.Builder setVideoTrackFormat(@NonNull android.media.MediaFormat); } + public static class MediaTranscodeManager.TranscodingRequest.MediaFormatResolver { + ctor public MediaTranscodeManager.TranscodingRequest.MediaFormatResolver(); + method @Nullable public android.media.MediaFormat resolveVideoFormat(); + method @NonNull public android.media.MediaTranscodeManager.TranscodingRequest.MediaFormatResolver setSourceVideoFormatHint(@NonNull android.media.MediaFormat); + method public boolean shouldTranscode(); + field public static final String CAPS_SUPPORTS_HEVC = "support-hevc"; + } + public class PlayerProxy { method public void pause(); method public void setPan(float); @@ -7326,6 +7344,7 @@ package android.net.wifi { method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public android.net.wifi.WifiConfiguration getWifiApConfiguration(); method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public int getWifiApState(); method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public java.util.List<android.net.wifi.WifiConfiguration> getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(@NonNull java.util.List<android.net.wifi.ScanResult>); + method public boolean is60GHzBandSupported(); method public boolean isApMacRandomizationSupported(); method public boolean isConnectedMacRandomizationSupported(); method @Deprecated public boolean isDeviceToDeviceRttSupported(); @@ -7565,6 +7584,7 @@ package android.net.wifi { field public static final int WIFI_BAND_5_GHZ = 2; // 0x2 field public static final int WIFI_BAND_5_GHZ_DFS_ONLY = 4; // 0x4 field public static final int WIFI_BAND_5_GHZ_WITH_DFS = 6; // 0x6 + field public static final int WIFI_BAND_60_GHZ = 16; // 0x10 field public static final int WIFI_BAND_6_GHZ = 8; // 0x8 field public static final int WIFI_BAND_BOTH = 3; // 0x3 field public static final int WIFI_BAND_BOTH_WITH_DFS = 7; // 0x7 @@ -7804,6 +7824,8 @@ package android.net.wifi.nl80211 { field public static final int BSS_CAPABILITY_CF_POLL_REQUEST = 8; // 0x8 field public static final int BSS_CAPABILITY_CHANNEL_AGILITY = 128; // 0x80 field public static final int BSS_CAPABILITY_DELAYED_BLOCK_ACK = 16384; // 0x4000 + field public static final int BSS_CAPABILITY_DMG_ESS = 3; // 0x3 + field public static final int BSS_CAPABILITY_DMG_IBSS = 1; // 0x1 field public static final int BSS_CAPABILITY_DSSS_OFDM = 8192; // 0x2000 field public static final int BSS_CAPABILITY_ESS = 1; // 0x1 field public static final int BSS_CAPABILITY_IBSS = 2; // 0x2 @@ -7873,7 +7895,7 @@ package android.net.wifi.nl80211 { method @NonNull public java.util.List<android.net.wifi.nl80211.NativeScanResult> getScanResults(@NonNull String, int); method @Nullable public android.net.wifi.nl80211.WifiNl80211Manager.TxPacketCounters getTxPacketCounters(@NonNull String); method @Nullable public static android.net.wifi.nl80211.WifiNl80211Manager.OemSecurityType parseOemSecurityTypeElement(int, int, @NonNull byte[]); - method public boolean registerApCallback(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.nl80211.WifiNl80211Manager.SoftApCallback); + method @Deprecated public boolean registerApCallback(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.nl80211.WifiNl80211Manager.SoftApCallback); method public void sendMgmtFrame(@NonNull String, @NonNull byte[], int, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.nl80211.WifiNl80211Manager.SendMgmtFrameCallback); method public void setOnServiceDeadCallback(@NonNull Runnable); method public boolean setupInterfaceForClientMode(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.nl80211.WifiNl80211Manager.ScanEventCallback, @NonNull android.net.wifi.nl80211.WifiNl80211Manager.ScanEventCallback); @@ -7924,10 +7946,10 @@ package android.net.wifi.nl80211 { field public final int txBitrateMbps; } - public static interface WifiNl80211Manager.SoftApCallback { - method public void onConnectedClientsChanged(@NonNull android.net.wifi.nl80211.NativeWifiClient, boolean); - method public void onFailure(); - method public void onSoftApChannelSwitched(int, int); + @Deprecated public static interface WifiNl80211Manager.SoftApCallback { + method @Deprecated public void onConnectedClientsChanged(@NonNull android.net.wifi.nl80211.NativeWifiClient, boolean); + method @Deprecated public void onFailure(); + method @Deprecated public void onSoftApChannelSwitched(int, int); } public static class WifiNl80211Manager.TxPacketCounters { diff --git a/api/test-current.txt b/api/test-current.txt index 1aa3db6963b7..de2919b8936a 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -133,7 +133,6 @@ package android.app { public class ActivityTaskManager { method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void clearLaunchParamsForPackages(java.util.List<java.lang.String>); method public static boolean currentUiModeSupportsErrorDialogs(@NonNull android.content.Context); - method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public String listAllStacks(); method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void moveTaskToStack(int, int, boolean); method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public boolean moveTopActivityToPinnedStack(int, android.graphics.Rect); method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void removeStacksInWindowingModes(int[]) throws java.lang.SecurityException; @@ -1870,6 +1869,14 @@ package android.media { method @NonNull public android.media.MediaTranscodeManager.TranscodingRequest.Builder setVideoTrackFormat(@NonNull android.media.MediaFormat); } + public static class MediaTranscodeManager.TranscodingRequest.MediaFormatResolver { + ctor public MediaTranscodeManager.TranscodingRequest.MediaFormatResolver(); + method @Nullable public android.media.MediaFormat resolveVideoFormat(); + method @NonNull public android.media.MediaTranscodeManager.TranscodingRequest.MediaFormatResolver setSourceVideoFormatHint(@NonNull android.media.MediaFormat); + method public boolean shouldTranscode(); + field public static final String CAPS_SUPPORTS_HEVC = "support-hevc"; + } + public final class PlaybackParams implements android.os.Parcelable { method public int getAudioStretchMode(); method public android.media.PlaybackParams setAudioStretchMode(int); diff --git a/cmds/screencap/screencap.cpp b/cmds/screencap/screencap.cpp index dec4a567fc81..5c08704a6623 100644 --- a/cmds/screencap/screencap.cpp +++ b/cmds/screencap/screencap.cpp @@ -30,8 +30,9 @@ #include <binder/ProcessState.h> -#include <gui/SurfaceComposerClient.h> #include <gui/ISurfaceComposer.h> +#include <gui/SurfaceComposerClient.h> +#include <gui/SyncScreenCaptureListener.h> #include <ui/DisplayInfo.h> #include <ui/GraphicTypes.h> @@ -181,13 +182,18 @@ int main(int argc, char** argv) ProcessState::self()->setThreadPoolMaxThreadCount(0); ProcessState::self()->startThreadPool(); - ScreenCaptureResults captureResults; - status_t result = ScreenshotClient::captureDisplay(displayId->value, captureResults); + sp<SyncScreenCaptureListener> captureListener = new SyncScreenCaptureListener(); + status_t result = ScreenshotClient::captureDisplay(displayId->value, captureListener); if (result != NO_ERROR) { close(fd); return 1; } + ScreenCaptureResults captureResults = captureListener->waitForResults(); + if (captureResults.result != NO_ERROR) { + close(fd); + return 1; + } ui::Dataspace dataspace = captureResults.capturedDataspace; sp<GraphicBuffer> buffer = captureResults.buffer; diff --git a/core/java/android/app/ActivityManager.aidl b/core/java/android/app/ActivityManager.aidl index 29260e996663..45a0e87ea2d8 100644 --- a/core/java/android/app/ActivityManager.aidl +++ b/core/java/android/app/ActivityManager.aidl @@ -24,8 +24,6 @@ parcelable ActivityManager.RunningAppProcessInfo; parcelable ActivityManager.RunningServiceInfo; parcelable ActivityManager.RunningTaskInfo; /** @hide */ -parcelable ActivityManager.StackInfo; -/** @hide */ parcelable ActivityManager.TaskThumbnail; /** @hide */ parcelable ActivityManager.TaskSnapshot;
\ No newline at end of file diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index a88c6a890844..5aecb61b62b1 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -76,7 +76,6 @@ import android.util.DisplayMetrics; import android.util.Singleton; import android.util.Size; import android.view.Surface; -import android.window.WindowContainerToken; import com.android.internal.app.LocalePicker; import com.android.internal.app.procstats.ProcessStats; @@ -2815,160 +2814,6 @@ public class ActivityManager { } /** - * Information you can retrieve about an ActivityStack in the system. - * @hide - */ - public static class StackInfo implements Parcelable { - @UnsupportedAppUsage - public int stackId; - @UnsupportedAppUsage - public Rect bounds = new Rect(); - @UnsupportedAppUsage - public int[] taskIds; - @UnsupportedAppUsage - public String[] taskNames; - @UnsupportedAppUsage - public Rect[] taskBounds; - @UnsupportedAppUsage - public int[] taskUserIds; - @UnsupportedAppUsage - public ComponentName topActivity; - @UnsupportedAppUsage - public int displayId; - @UnsupportedAppUsage - public int userId; - @UnsupportedAppUsage - public boolean visible; - // Index of the stack in the display's stack list, can be used for comparison of stack order - // TODO: Can be removed since no one is using it. - @UnsupportedAppUsage - @Deprecated - public int position; - public WindowContainerToken stackToken; - /** - * The full configuration the stack is currently running in. - * @hide - */ - final public Configuration configuration = new Configuration(); - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(stackId); - dest.writeInt(bounds.left); - dest.writeInt(bounds.top); - dest.writeInt(bounds.right); - dest.writeInt(bounds.bottom); - dest.writeIntArray(taskIds); - dest.writeStringArray(taskNames); - final int boundsCount = taskBounds == null ? 0 : taskBounds.length; - dest.writeInt(boundsCount); - for (int i = 0; i < boundsCount; i++) { - dest.writeInt(taskBounds[i].left); - dest.writeInt(taskBounds[i].top); - dest.writeInt(taskBounds[i].right); - dest.writeInt(taskBounds[i].bottom); - } - dest.writeIntArray(taskUserIds); - dest.writeInt(displayId); - dest.writeInt(userId); - dest.writeInt(visible ? 1 : 0); - dest.writeInt(position); - stackToken.writeToParcel(dest, 0); - if (topActivity != null) { - dest.writeInt(1); - topActivity.writeToParcel(dest, 0); - } else { - dest.writeInt(0); - } - configuration.writeToParcel(dest, flags); - } - - public void readFromParcel(Parcel source) { - stackId = source.readInt(); - bounds = new Rect( - source.readInt(), source.readInt(), source.readInt(), source.readInt()); - taskIds = source.createIntArray(); - taskNames = source.createStringArray(); - final int boundsCount = source.readInt(); - if (boundsCount > 0) { - taskBounds = new Rect[boundsCount]; - for (int i = 0; i < boundsCount; i++) { - taskBounds[i] = new Rect(); - taskBounds[i].set( - source.readInt(), source.readInt(), source.readInt(), source.readInt()); - } - } else { - taskBounds = null; - } - taskUserIds = source.createIntArray(); - displayId = source.readInt(); - userId = source.readInt(); - visible = source.readInt() > 0; - position = source.readInt(); - stackToken = WindowContainerToken.CREATOR.createFromParcel(source); - if (source.readInt() > 0) { - topActivity = ComponentName.readFromParcel(source); - } - configuration.readFromParcel(source); - } - - public static final @android.annotation.NonNull Creator<StackInfo> CREATOR = new Creator<StackInfo>() { - @Override - public StackInfo createFromParcel(Parcel source) { - return new StackInfo(source); - } - @Override - public StackInfo[] newArray(int size) { - return new StackInfo[size]; - } - }; - - public StackInfo() { - } - - private StackInfo(Parcel source) { - readFromParcel(source); - } - - @UnsupportedAppUsage - public String toString(String prefix) { - StringBuilder sb = new StringBuilder(256); - sb.append(prefix); sb.append("Stack id="); sb.append(stackId); - sb.append(" bounds="); sb.append(bounds.toShortString()); - sb.append(" displayId="); sb.append(displayId); - sb.append(" userId="); sb.append(userId); - sb.append("\n"); - sb.append(" configuration="); sb.append(configuration); - sb.append("\n"); - prefix = prefix + " "; - for (int i = 0; i < taskIds.length; ++i) { - sb.append(prefix); sb.append("taskId="); sb.append(taskIds[i]); - sb.append(": "); sb.append(taskNames[i]); - if (taskBounds != null) { - sb.append(" bounds="); sb.append(taskBounds[i].toShortString()); - } - sb.append(" userId=").append(taskUserIds[i]); - sb.append(" visible=").append(visible); - if (topActivity != null) { - sb.append(" topActivity=").append(topActivity); - } - sb.append("\n"); - } - return sb.toString(); - } - - @Override - public String toString() { - return toString(""); - } - } - - /** * @hide */ @RequiresPermission(anyOf={Manifest.permission.CLEAR_APP_USER_DATA, diff --git a/core/java/android/app/ActivityTaskManager.aidl b/core/java/android/app/ActivityTaskManager.aidl new file mode 100644 index 000000000000..a12bcd536af7 --- /dev/null +++ b/core/java/android/app/ActivityTaskManager.aidl @@ -0,0 +1,20 @@ +/** + * Copyright (c) 2020, 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.app; + +/** @hide */ +parcelable ActivityTaskManager.RootTaskInfo;
\ No newline at end of file diff --git a/core/java/android/app/ActivityTaskManager.java b/core/java/android/app/ActivityTaskManager.java index 4283d7ad2a62..3e4d5eee34fe 100644 --- a/core/java/android/app/ActivityTaskManager.java +++ b/core/java/android/app/ActivityTaskManager.java @@ -29,6 +29,8 @@ import android.graphics.Rect; import android.os.Build; import android.os.Handler; import android.os.IBinder; +import android.os.Parcel; +import android.os.Parcelable; import android.os.RemoteException; import android.os.ServiceManager; import android.util.DisplayMetrics; @@ -391,27 +393,6 @@ public class ActivityTaskManager { } /** - * List all activity stacks information. - */ - @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) - public String listAllStacks() { - final List<ActivityManager.StackInfo> stacks; - try { - stacks = getService().getAllStackInfos(); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - - final StringBuilder sb = new StringBuilder(); - if (stacks != null) { - for (ActivityManager.StackInfo info : stacks) { - sb.append(info).append("\n"); - } - } - return sb.toString(); - } - - /** * Clears launch params for the given package. * @param packageNames the names of the packages of which the launch params are to be cleared */ @@ -468,4 +449,96 @@ public class ActivityTaskManager { final Configuration config = context.getResources().getConfiguration(); return currentUiModeSupportsErrorDialogs(config); } + + /** + * Information you can retrieve about a root task in the system. + * @hide + */ + public static class RootTaskInfo extends TaskInfo implements Parcelable { + // TODO(b/148895075): Move some of the fields to TaskInfo. + public Rect bounds = new Rect(); + public int[] childTaskIds; + public String[] childTaskNames; + public Rect[] childTaskBounds; + public int[] childTaskUserIds; + public boolean visible; + // Index of the stack in the display's stack list, can be used for comparison of stack order + public int position; + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeTypedObject(bounds, flags); + dest.writeIntArray(childTaskIds); + dest.writeStringArray(childTaskNames); + dest.writeTypedArray(childTaskBounds, flags); + dest.writeIntArray(childTaskUserIds); + dest.writeInt(visible ? 1 : 0); + dest.writeInt(position); + super.writeToParcel(dest, flags); + } + + @Override + void readFromParcel(Parcel source) { + bounds = source.readTypedObject(Rect.CREATOR); + childTaskIds = source.createIntArray(); + childTaskNames = source.createStringArray(); + childTaskBounds = source.createTypedArray(Rect.CREATOR); + childTaskUserIds = source.createIntArray(); + visible = source.readInt() > 0; + position = source.readInt(); + super.readFromParcel(source); + } + + public static final @NonNull Creator<RootTaskInfo> CREATOR = new Creator<>() { + @Override + public RootTaskInfo createFromParcel(Parcel source) { + return new RootTaskInfo(source); + } + + @Override + public RootTaskInfo[] newArray(int size) { + return new RootTaskInfo[size]; + } + }; + + public RootTaskInfo() { + } + + private RootTaskInfo(Parcel source) { + readFromParcel(source); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(256); + sb.append("RootTask id="); sb.append(taskId); + sb.append(" bounds="); sb.append(bounds.toShortString()); + sb.append(" displayId="); sb.append(displayId); + sb.append(" userId="); sb.append(userId); + sb.append("\n"); + + sb.append(" configuration="); sb.append(configuration); + sb.append("\n"); + + for (int i = 0; i < childTaskIds.length; ++i) { + sb.append(" taskId="); sb.append(childTaskIds[i]); + sb.append(": "); sb.append(childTaskNames[i]); + if (childTaskBounds != null) { + sb.append(" bounds="); sb.append(childTaskBounds[i].toShortString()); + } + sb.append(" userId=").append(childTaskUserIds[i]); + sb.append(" visible=").append(visible); + if (topActivity != null) { + sb.append(" topActivity=").append(topActivity); + } + sb.append("\n"); + } + return sb.toString(); + } + } } diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index caca05a9e3b3..763ce6c6fd17 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -5418,13 +5418,12 @@ public final class ActivityThread extends ClientTransactionHandler { final int prevState = r.getLifecycleState(); - if (prevState < ON_RESUME || prevState > ON_STOP) { - Log.w(TAG, "Activity state must be in [ON_RESUME..ON_STOP] in order to be relaunched," + if (prevState < ON_START || prevState > ON_STOP) { + Log.w(TAG, "Activity state must be in [ON_START..ON_STOP] in order to be relaunched," + "current state is " + prevState); return; } - // Initialize a relaunch request. final MergedConfiguration mergedConfiguration = new MergedConfiguration( r.createdConfig != null ? r.createdConfig : mConfiguration, diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl index cd9e02d30d05..45b25a3bf317 100644 --- a/core/java/android/app/IActivityManager.aidl +++ b/core/java/android/app/IActivityManager.aidl @@ -17,6 +17,7 @@ package android.app; import android.app.ActivityManager; +import android.app.ActivityTaskManager; import android.app.ApplicationErrorReport; import android.app.ApplicationExitInfo; import android.app.ContentProviderHolder; @@ -99,7 +100,6 @@ interface IActivityManager { void unregisterUidObserver(in IUidObserver observer); boolean isUidActive(int uid, String callingPackage); int getUidProcessState(int uid, in String callingPackage); - boolean setSchedPolicyCgroup(int tid, int group); // =============== End of transactions used on native side as well ============================ // Special low-level communication with activity manager. @@ -449,12 +449,11 @@ interface IActivityManager { @UnsupportedAppUsage void hang(in IBinder who, boolean allowRestart); - @UnsupportedAppUsage - List<ActivityManager.StackInfo> getAllStackInfos(); + List<ActivityTaskManager.RootTaskInfo> getAllRootTaskInfos(); @UnsupportedAppUsage void moveTaskToStack(int taskId, int stackId, boolean toTop); void setFocusedStack(int stackId); - ActivityManager.StackInfo getFocusedStackInfo(); + ActivityTaskManager.RootTaskInfo getFocusedRootTaskInfo(); @UnsupportedAppUsage void restart(); void performIdleMaintenance(); diff --git a/core/java/android/app/IActivityTaskManager.aidl b/core/java/android/app/IActivityTaskManager.aidl index 72a3637d8e07..f3c7fe9412c9 100644 --- a/core/java/android/app/IActivityTaskManager.aidl +++ b/core/java/android/app/IActivityTaskManager.aidl @@ -17,6 +17,7 @@ package android.app; import android.app.ActivityManager; +import android.app.ActivityTaskManager; import android.app.ApplicationErrorReport; import android.app.ContentProviderHolder; import android.app.GrantedUriPermission; @@ -186,7 +187,7 @@ interface IActivityTaskManager { in AssistStructure structure, in AssistContent content, in Uri referrer); void setFocusedStack(int stackId); - ActivityManager.StackInfo getFocusedStackInfo(); + ActivityTaskManager.RootTaskInfo getFocusedRootTaskInfo(); Rect getTaskBounds(int taskId); void cancelRecentsAnimation(boolean restoreHomeStackPosition); @@ -260,11 +261,10 @@ interface IActivityTaskManager { /** Removes stack of the activity types from the system. */ void removeStacksWithActivityTypes(in int[] activityTypes); - List<ActivityManager.StackInfo> getAllStackInfos(); - ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType); - List<ActivityManager.StackInfo> getAllStackInfosOnDisplay(int displayId); - ActivityManager.StackInfo getStackInfoOnDisplay(int windowingMode, int activityType, - int displayId); + List<ActivityTaskManager.RootTaskInfo> getAllRootTaskInfos(); + ActivityTaskManager.RootTaskInfo getRootTaskInfo(int windowingMode, int activityType); + List<ActivityTaskManager.RootTaskInfo> getAllRootTaskInfosOnDisplay(int displayId); + ActivityTaskManager.RootTaskInfo getRootTaskInfoOnDisplay(int windowingMode, int activityType, int displayId); /** * Informs ActivityTaskManagerService that the keyguard is showing. diff --git a/core/java/android/app/TaskInfo.java b/core/java/android/app/TaskInfo.java index f3f00e50715b..4718cf1545ce 100644 --- a/core/java/android/app/TaskInfo.java +++ b/core/java/android/app/TaskInfo.java @@ -36,7 +36,8 @@ public class TaskInfo { private static final String TAG = "TaskInfo"; /** - * The id of the user the task was running as. + * The id of the user the task was running as if this is a leaf task. The id of the current + * running user of the system otherwise. * @hide */ @UnsupportedAppUsage diff --git a/core/java/android/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java index 22d8c87e9268..b5234f8e2e17 100644 --- a/core/java/android/app/assist/AssistStructure.java +++ b/core/java/android/app/assist/AssistStructure.java @@ -36,8 +36,6 @@ import android.view.WindowManagerGlobal; import android.view.autofill.AutofillId; import android.view.autofill.AutofillValue; -import com.android.internal.util.Preconditions; - import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -1676,8 +1674,9 @@ public class AssistStructure implements Parcelable { } /** - * Returns the maximum length of the text associated with this node node, or {@code -1} - * if not supported by the node or not set. + * Returns the maximum length of the text associated with this node, or {@code -1} if not + * supported by the node or not set. System may set a default value if the text length is + * not set. * * <p>It's only relevant when the {@link AssistStructure} is used for autofill purposes, * not for assist purposes. diff --git a/core/java/android/app/servertransaction/TransactionExecutorHelper.java b/core/java/android/app/servertransaction/TransactionExecutorHelper.java index a34be5c3edc7..56bf59b52f74 100644 --- a/core/java/android/app/servertransaction/TransactionExecutorHelper.java +++ b/core/java/android/app/servertransaction/TransactionExecutorHelper.java @@ -185,6 +185,9 @@ public class TransactionExecutorHelper { final ActivityLifecycleItem lifecycleItem; switch (prevState) { // TODO(lifecycler): Extend to support all possible states. + case ON_START: + lifecycleItem = StartActivityItem.obtain(); + break; case ON_PAUSE: lifecycleItem = PauseActivityItem.obtain(); break; diff --git a/core/java/android/app/usage/UsageEvents.java b/core/java/android/app/usage/UsageEvents.java index 0e6a0637d801..3522b1b8aff5 100644 --- a/core/java/android/app/usage/UsageEvents.java +++ b/core/java/android/app/usage/UsageEvents.java @@ -199,7 +199,7 @@ public final class UsageEvents implements Parcelable { public static final int NOTIFICATION_INTERRUPTION = 12; /** - * A Slice was pinned by the default assistant. + * A Slice was pinned by the default launcher or the default assistant. * @hide */ @SystemApi diff --git a/core/java/android/content/PermissionChecker.java b/core/java/android/content/PermissionChecker.java index b4340729a220..eec7c9cc5a63 100644 --- a/core/java/android/content/PermissionChecker.java +++ b/core/java/android/content/PermissionChecker.java @@ -343,20 +343,22 @@ public final class PermissionChecker { * @param permission The permission to check. * @return The permission check result which is either {@link #PERMISSION_GRANTED} * or {@link #PERMISSION_SOFT_DENIED} or {@link #PERMISSION_HARD_DENIED}. - * @param attributionTag attribution tag of caller (if not self) + * @param callingPackageName package name tag of caller (if not self) + * @param callingAttributionTag attribution tag of caller (if not self) * @param message A message describing the reason the permission was checked * * @see #checkCallingOrSelfPermissionForPreflight(Context, String) */ @PermissionResult public static int checkCallingOrSelfPermissionForDataDelivery(@NonNull Context context, - @NonNull String permission, @Nullable String attributionTag, @Nullable String message) { - String packageName = (Binder.getCallingPid() == Process.myPid()) - ? context.getPackageName() : null; - attributionTag = (Binder.getCallingPid() == Process.myPid()) - ? context.getAttributionTag() : attributionTag; + @NonNull String permission, @Nullable String callingPackageName, + @Nullable String callingAttributionTag, @Nullable String message) { + callingPackageName = (Binder.getCallingPid() == Process.myPid()) + ? context.getPackageName() : callingPackageName; + callingAttributionTag = (Binder.getCallingPid() == Process.myPid()) + ? context.getAttributionTag() : callingAttributionTag; return checkPermissionForDataDelivery(context, permission, Binder.getCallingPid(), - Binder.getCallingUid(), packageName, attributionTag, message); + Binder.getCallingUid(), callingPackageName, callingAttributionTag, message); } /** @@ -375,15 +377,15 @@ public final class PermissionChecker { * app's fg/gb state) and this check will not leave a trace that permission protected * data was delivered. When you are about to deliver the location data to a registered * listener you should use {@link #checkCallingOrSelfPermissionForDataDelivery(Context, - * String, String, String)} which will evaluate the permission access based on the current - * fg/bg state of the app and leave a record that the data was accessed. + * String, String, String, String)} which will evaluate the permission access based on the + * current fg/bg state of the app and leave a record that the data was accessed. * * @param context Context for accessing resources. * @param permission The permission to check. * @return The permission check result which is either {@link #PERMISSION_GRANTED} * or {@link #PERMISSION_SOFT_DENIED} or {@link #PERMISSION_HARD_DENIED}. * - * @see #checkCallingOrSelfPermissionForDataDelivery(Context, String, String, String) + * @see #checkCallingOrSelfPermissionForDataDelivery(Context, String, String, String, String) */ @PermissionResult public static int checkCallingOrSelfPermissionForPreflight(@NonNull Context context, diff --git a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java index 542cfc29f1a2..6d92d3e0d219 100644 --- a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java +++ b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java @@ -53,7 +53,7 @@ import java.util.List; /** @hide */ public class ApkLiteParseUtils { - private static final String TAG = ParsingPackageUtils.TAG; + private static final String TAG = ParsingUtils.TAG; // TODO(b/135203078): Consolidate constants private static final int DEFAULT_MIN_SDK_VERSION = 1; diff --git a/core/java/android/content/pm/parsing/PackageInfoWithoutStateUtils.java b/core/java/android/content/pm/parsing/PackageInfoWithoutStateUtils.java index e4507483c08f..e57353922115 100644 --- a/core/java/android/content/pm/parsing/PackageInfoWithoutStateUtils.java +++ b/core/java/android/content/pm/parsing/PackageInfoWithoutStateUtils.java @@ -579,8 +579,8 @@ public class PackageInfoWithoutStateUtils { ii.handleProfiling = i.isHandleProfiling(); ii.functionalTest = i.isFunctionalTest(); - ii.sourceDir = pkg.getBaseCodePath(); - ii.publicSourceDir = pkg.getBaseCodePath(); + ii.sourceDir = pkg.getBaseApkPath(); + ii.publicSourceDir = pkg.getBaseApkPath(); ii.splitNames = pkg.getSplitNames(); ii.splitSourceDirs = pkg.getSplitCodePaths(); ii.splitPublicSourceDirs = pkg.getSplitCodePaths(); diff --git a/core/java/android/content/pm/parsing/ParsingPackageImpl.java b/core/java/android/content/pm/parsing/ParsingPackageImpl.java index 0c0dc313087e..ed12a17ad493 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageImpl.java +++ b/core/java/android/content/pm/parsing/ParsingPackageImpl.java @@ -145,7 +145,7 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { private String realPackage; @NonNull - protected String baseCodePath; + protected String mBaseApkPath; private boolean requiredForAllUsers; @Nullable @@ -280,7 +280,7 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { @NonNull @DataClass.ParcelWith(ForInternedString.class) - protected String codePath; + protected String mPath; private boolean use32BitAbi; private boolean visibleToInstantApps; @@ -429,11 +429,11 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { private ArraySet<String> mimeGroups; @VisibleForTesting - public ParsingPackageImpl(@NonNull String packageName, @NonNull String baseCodePath, - @NonNull String codePath, @Nullable TypedArray manifestArray) { + public ParsingPackageImpl(@NonNull String packageName, @NonNull String baseApkPath, + @NonNull String path, @Nullable TypedArray manifestArray) { this.packageName = TextUtils.safeIntern(packageName); - this.baseCodePath = baseCodePath; - this.codePath = codePath; + this.mBaseApkPath = baseApkPath; + this.mPath = path; if (manifestArray != null) { versionCode = manifestArray.getInteger(R.styleable.AndroidManifest_versionCode, 0); @@ -888,6 +888,9 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { public ApplicationInfo toAppInfoWithoutStateWithoutFlags() { ApplicationInfo appInfo = new ApplicationInfo(); + // Lines that are commented below are state related and should not be assigned here. + // They are left in as placeholders, since there is no good backwards compatible way to + // separate these. appInfo.appComponentFactory = appComponentFactory; appInfo.backupAgentName = backupAgentName; appInfo.banner = banner; @@ -897,13 +900,17 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { appInfo.compatibleWidthLimitDp = compatibleWidthLimitDp; appInfo.compileSdkVersion = compileSdkVersion; appInfo.compileSdkVersionCodename = compileSdkVersionCodeName; -// appInfo.credentialProtectedDataDir = credentialProtectedDataDir; -// appInfo.dataDir = dataDir; +// appInfo.credentialProtectedDataDir + appInfo.crossProfile = isCrossProfile(); +// appInfo.dataDir appInfo.descriptionRes = descriptionRes; -// appInfo.deviceProtectedDataDir = deviceProtectedDataDir; +// appInfo.deviceProtectedDataDir appInfo.enabled = enabled; +// appInfo.enabledSetting appInfo.fullBackupContent = fullBackupContent; -// appInfo.hiddenUntilInstalled = hiddenUntilInstalled; + // TODO(b/135203078): See ParsingPackageImpl#getHiddenApiEnforcementPolicy +// appInfo.mHiddenApiPolicy +// appInfo.hiddenUntilInstalled appInfo.icon = (PackageParser.sUseRoundIcon && roundIconRes != 0) ? roundIconRes : iconRes; appInfo.iconRes = iconRes; appInfo.roundIconRes = roundIconRes; @@ -920,9 +927,9 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { if (appInfo.name != null) { appInfo.name = appInfo.name.trim(); } -// appInfo.nativeLibraryDir = nativeLibraryDir; -// appInfo.nativeLibraryRootDir = nativeLibraryRootDir; -// appInfo.nativeLibraryRootRequiresIsa = nativeLibraryRootRequiresIsa; +// appInfo.nativeLibraryDir +// appInfo.nativeLibraryRootDir +// appInfo.nativeLibraryRootRequiresIsa appInfo.networkSecurityConfigRes = networkSecurityConfigRes; appInfo.nonLocalizedLabel = nonLocalizedLabel; if (appInfo.nonLocalizedLabel != null) { @@ -930,16 +937,17 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { } appInfo.packageName = packageName; appInfo.permission = permission; -// appInfo.primaryCpuAbi = primaryCpuAbi; +// appInfo.primaryCpuAbi appInfo.processName = getProcessName(); appInfo.requiresSmallestWidthDp = requiresSmallestWidthDp; -// appInfo.secondaryCpuAbi = secondaryCpuAbi; -// appInfo.secondaryNativeLibraryDir = secondaryNativeLibraryDir; -// appInfo.seInfo = seInfo; -// appInfo.seInfoUser = seInfoUser; -// appInfo.sharedLibraryFiles = usesLibraryFiles.isEmpty() -// ? null : usesLibraryFiles.toArray(new String[0]); -// appInfo.sharedLibraryInfos = usesLibraryInfos.isEmpty() ? null : usesLibraryInfos; +// appInfo.resourceDirs +// appInfo.secondaryCpuAbi +// appInfo.secondaryNativeLibraryDir +// appInfo.seInfo +// appInfo.seInfoUser +// appInfo.sharedLibraryFiles +// appInfo.sharedLibraryInfos +// appInfo.showUserIcon appInfo.splitClassLoaderNames = splitClassLoaderNames; appInfo.splitDependencies = splitDependencies; appInfo.splitNames = splitNames; @@ -948,29 +956,19 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { appInfo.targetSdkVersion = targetSdkVersion; appInfo.taskAffinity = taskAffinity; appInfo.theme = theme; -// appInfo.uid = uid; +// appInfo.uid appInfo.uiOptions = uiOptions; appInfo.volumeUuid = volumeUuid; appInfo.zygotePreloadName = zygotePreloadName; - appInfo.crossProfile = isCrossProfile(); appInfo.setGwpAsanMode(gwpAsanMode); - appInfo.setBaseCodePath(baseCodePath); - appInfo.setBaseResourcePath(baseCodePath); - appInfo.setCodePath(codePath); - appInfo.setResourcePath(codePath); + appInfo.setBaseCodePath(mBaseApkPath); + appInfo.setBaseResourcePath(mBaseApkPath); + appInfo.setCodePath(mPath); + appInfo.setResourcePath(mPath); appInfo.setSplitCodePaths(splitCodePaths); appInfo.setSplitResourcePaths(splitCodePaths); appInfo.setVersionCode(PackageInfo.composeLongVersionCode(versionCodeMajor, versionCode)); - // TODO(b/135203078): Can this be removed? Looks only used in ActivityInfo. -// appInfo.showUserIcon = pkg.getShowUserIcon(); - // TODO(b/135203078): Unused? -// appInfo.resourceDirs = pkg.getResourceDirs(); - // TODO(b/135203078): Unused? -// appInfo.enabledSetting = pkg.getEnabledSetting(); - // TODO(b/135203078): See ParsingPackageImpl#getHiddenApiEnforcementPolicy -// appInfo.mHiddenApiPolicy = pkg.getHiddenApiPolicy(); - return appInfo; } @@ -995,7 +993,7 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { dest.writeString(this.compileSdkVersionCodeName); sForInternedString.parcel(this.packageName, dest, flags); dest.writeString(this.realPackage); - dest.writeString(this.baseCodePath); + dest.writeString(this.mBaseApkPath); dest.writeBoolean(this.requiredForAllUsers); dest.writeString(this.restrictedAccountType); dest.writeString(this.requiredAccountType); @@ -1050,7 +1048,7 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { dest.writeBundle(this.metaData); sForInternedString.parcel(this.volumeUuid, dest, flags); dest.writeParcelable(this.signingDetails, flags); - dest.writeString(this.codePath); + dest.writeString(this.mPath); dest.writeBoolean(this.use32BitAbi); dest.writeBoolean(this.visibleToInstantApps); dest.writeBoolean(this.forceQueryable); @@ -1159,7 +1157,7 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { this.compileSdkVersionCodeName = in.readString(); this.packageName = sForInternedString.unparcel(in); this.realPackage = in.readString(); - this.baseCodePath = in.readString(); + this.mBaseApkPath = in.readString(); this.requiredForAllUsers = in.readBoolean(); this.restrictedAccountType = in.readString(); this.requiredAccountType = in.readString(); @@ -1214,7 +1212,7 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { this.metaData = in.readBundle(boot); this.volumeUuid = sForInternedString.unparcel(in); this.signingDetails = in.readParcelable(boot); - this.codePath = in.readString(); + this.mPath = in.readString(); this.use32BitAbi = in.readBoolean(); this.visibleToInstantApps = in.readBoolean(); this.forceQueryable = in.readBoolean(); @@ -1363,8 +1361,8 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { @NonNull @Override - public String getBaseCodePath() { - return baseCodePath; + public String getBaseApkPath() { + return mBaseApkPath; } @Override @@ -1649,8 +1647,8 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { @NonNull @Override - public String getCodePath() { - return codePath; + public String getPath() { + return mPath; } @Override diff --git a/core/java/android/content/pm/parsing/ParsingPackageRead.java b/core/java/android/content/pm/parsing/ParsingPackageRead.java index 7e0fe7dc41bf..dbd15f544bcd 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageRead.java +++ b/core/java/android/content/pm/parsing/ParsingPackageRead.java @@ -548,7 +548,7 @@ public interface ParsingPackageRead extends Parcelable { String getPackageName(); /** Path of base APK */ - String getBaseCodePath(); + String getBaseApkPath(); /** * Path where this package was found on disk. For monolithic packages @@ -556,7 +556,7 @@ public interface ParsingPackageRead extends Parcelable { * path to the cluster directory. */ @NonNull - String getCodePath(); + String getPath(); /** * @see ApplicationInfo#compatibleWidthLimitDp diff --git a/core/java/android/content/pm/parsing/ParsingPackageUtils.java b/core/java/android/content/pm/parsing/ParsingPackageUtils.java index d9857e0d2328..bce75cde20c2 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageUtils.java +++ b/core/java/android/content/pm/parsing/ParsingPackageUtils.java @@ -127,7 +127,7 @@ import java.util.StringTokenizer; */ public class ParsingPackageUtils { - public static final String TAG = ParsingUtils.TAG; + private static final String TAG = ParsingUtils.TAG; /** * @see #parseDefault(ParseInput, File, int, boolean) @@ -162,10 +162,10 @@ public class ParsingPackageUtils { @Override public ParsingPackage startParsingPackage( @NonNull String packageName, - @NonNull String baseCodePath, - @NonNull String codePath, + @NonNull String baseApkPath, + @NonNull String path, @NonNull TypedArray manifestArray, boolean isCoreApp) { - return new ParsingPackageImpl(packageName, baseCodePath, codePath, manifestArray); + return new ParsingPackageImpl(packageName, baseApkPath, path, manifestArray); } }); try { @@ -739,7 +739,6 @@ public class ParsingPackageUtils { String tagName = parser.getName(); final ParseResult result; - // TODO(b/135203078): Convert to instance methods to share variables // <application> has special logic, so it's handled outside the general method if (PackageParser.TAG_APPLICATION.equals(tagName)) { if (foundApp) { @@ -1214,9 +1213,9 @@ public class ParsingPackageUtils { features = ArrayUtils.add(features, featureInfo); } else { Slog.w(TAG, - "Unknown element under <feature-group>: " + innerTagName + - " at " + pkg.getBaseCodePath() + " " + - parser.getPositionDescription()); + "Unknown element under <feature-group>: " + innerTagName + + " at " + pkg.getBaseApkPath() + " " + + parser.getPositionDescription()); } } @@ -1719,10 +1718,6 @@ public class ParsingPackageUtils { pkg.setPersistent(requiredFeature == null || mCallback.hasFeature(requiredFeature)); } - // TODO(b/135203078): Should parsing code be responsible for this? Maybe move to a - // util or just have PackageImpl return true if either flag is set - pkg.setProfileableByShell(pkg.isProfileableByShell()); - if (sa.hasValueOrEmpty(R.styleable.AndroidManifestApplication_resizeableActivity)) { pkg.setResizeableActivity(sa.getBoolean( R.styleable.AndroidManifestApplication_resizeableActivity, true)); @@ -2424,7 +2419,7 @@ public class ParsingPackageUtils { R.styleable.AndroidManifestResourceOverlay_requiredSystemPropertyValue); if (!PackageParser.checkRequiredSystemProperties(propName, propValue)) { String message = "Skipping target and overlay pair " + target + " and " - + pkg.getBaseCodePath() + + pkg.getBaseApkPath() + ": overlay ignored due to required system property: " + propName + " with value: " + propValue; Slog.i(TAG, message); @@ -2679,7 +2674,7 @@ public class ParsingPackageUtils { "<meta-data> only supports string, integer, float, color, " + "boolean, and resource reference types: " + parser.getName() + " at " - + pkg.getBaseCodePath() + " " + + pkg.getBaseApkPath() + " " + parser.getPositionDescription()); } else { return input.error("<meta-data> only supports string, integer, float, " @@ -2716,7 +2711,7 @@ public class ParsingPackageUtils { try { ParseResult<SigningDetails> result = getSigningDetails( input, - pkg.getBaseCodePath(), + pkg.getBaseApkPath(), skipVerify, pkg.isStaticSharedLibrary(), signingDetails, @@ -2862,7 +2857,7 @@ public class ParsingPackageUtils { boolean hasFeature(String feature); ParsingPackage startParsingPackage(@NonNull String packageName, - @NonNull String baseCodePath, @NonNull String codePath, + @NonNull String baseApkPath, @NonNull String path, @NonNull TypedArray manifestArray, boolean isCoreApp); } } diff --git a/core/java/android/content/pm/parsing/ParsingUtils.java b/core/java/android/content/pm/parsing/ParsingUtils.java index ba61de1cf950..5da5fbf4d8a7 100644 --- a/core/java/android/content/pm/parsing/ParsingUtils.java +++ b/core/java/android/content/pm/parsing/ParsingUtils.java @@ -33,7 +33,6 @@ import java.io.IOException; /** @hide **/ public class ParsingUtils { - // TODO(b/135203078): Consolidate log tags public static final String TAG = "PackageParsing"; @Nullable @@ -62,7 +61,7 @@ public class ParsingUtils { return input.error("Bad element under " + parentTag + ": " + parser.getName()); } Slog.w(TAG, "Unknown element under " + parentTag + ": " - + parser.getName() + " at " + pkg.getBaseCodePath() + " " + + parser.getName() + " at " + pkg.getBaseApkPath() + " " + parser.getPositionDescription()); XmlUtils.skipCurrentTag(parser); return input.success(null); // Type doesn't matter diff --git a/core/java/android/content/pm/parsing/component/ComponentParseUtils.java b/core/java/android/content/pm/parsing/component/ComponentParseUtils.java index c4caedcb87ff..cfefc016d4a4 100644 --- a/core/java/android/content/pm/parsing/component/ComponentParseUtils.java +++ b/core/java/android/content/pm/parsing/component/ComponentParseUtils.java @@ -24,15 +24,13 @@ import android.content.pm.PackageParser; import android.content.pm.PackageUserState; import android.content.pm.parsing.ParsingPackage; import android.content.pm.parsing.ParsingUtils; +import android.content.pm.parsing.result.ParseInput; +import android.content.pm.parsing.result.ParseResult; import android.content.res.Resources; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; import android.text.TextUtils; -import android.content.pm.parsing.ParsingPackageUtils; -import android.content.pm.parsing.result.ParseInput; -import android.content.pm.parsing.result.ParseResult; - import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -41,8 +39,6 @@ import java.io.IOException; /** @hide */ public class ComponentParseUtils { - private static final String TAG = ParsingPackageUtils.TAG; - public static boolean isImplicitlyExposedIntent(ParsedIntentInfo intentInfo) { return intentInfo.hasCategory(Intent.CATEGORY_BROWSABLE) || intentInfo.hasAction(Intent.ACTION_SEND) diff --git a/core/java/android/content/pm/parsing/component/ParsedActivityUtils.java b/core/java/android/content/pm/parsing/component/ParsedActivityUtils.java index 6927f3b8a97d..8c0bfef19d0f 100644 --- a/core/java/android/content/pm/parsing/component/ParsedActivityUtils.java +++ b/core/java/android/content/pm/parsing/component/ParsedActivityUtils.java @@ -24,7 +24,6 @@ import android.app.ActivityTaskManager; import android.content.pm.ActivityInfo; import android.content.pm.PackageParser; import android.content.pm.parsing.ParsingPackage; -import android.content.pm.parsing.ParsingPackageUtils; import android.content.pm.parsing.ParsingUtils; import android.content.pm.parsing.result.ParseInput; import android.content.pm.parsing.result.ParseInput.DeferredError; @@ -55,7 +54,7 @@ import java.util.Objects; /** @hide */ public class ParsedActivityUtils { - private static final String TAG = ParsingPackageUtils.TAG; + private static final String TAG = ParsingUtils.TAG; @NonNull @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) diff --git a/core/java/android/content/pm/parsing/component/ParsedComponentUtils.java b/core/java/android/content/pm/parsing/component/ParsedComponentUtils.java index 6811e06fbe7e..dd2fb5bd2d78 100644 --- a/core/java/android/content/pm/parsing/component/ParsedComponentUtils.java +++ b/core/java/android/content/pm/parsing/component/ParsedComponentUtils.java @@ -36,8 +36,6 @@ import com.android.internal.annotations.VisibleForTesting; /** @hide */ class ParsedComponentUtils { - private static final String TAG = ParsingPackageUtils.TAG; - @NonNull @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) static <Component extends ParsedComponent> ParseResult<Component> parseComponent( diff --git a/core/java/android/content/pm/parsing/component/ParsedIntentInfo.java b/core/java/android/content/pm/parsing/component/ParsedIntentInfo.java index 0ba92cc4fef7..6b797bcb6ab2 100644 --- a/core/java/android/content/pm/parsing/component/ParsedIntentInfo.java +++ b/core/java/android/content/pm/parsing/component/ParsedIntentInfo.java @@ -22,7 +22,6 @@ import android.os.Parcel; import android.os.Parcelable; import android.util.Pair; -import com.android.internal.util.DataClass; import com.android.internal.util.Parcelling; import java.util.ArrayList; @@ -163,7 +162,7 @@ public final class ParsedIntentInfo extends IntentFilter { } public String toString() { - return "ProviderIntentInfo{" + return "ParsedIntentInfo{" + Integer.toHexString(System.identityHashCode(this)) + '}'; } diff --git a/core/java/android/content/pm/parsing/component/ParsedIntentInfoUtils.java b/core/java/android/content/pm/parsing/component/ParsedIntentInfoUtils.java index 390f76968e7c..c0536bb7eb10 100644 --- a/core/java/android/content/pm/parsing/component/ParsedIntentInfoUtils.java +++ b/core/java/android/content/pm/parsing/component/ParsedIntentInfoUtils.java @@ -21,7 +21,6 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageParser; import android.content.pm.parsing.ParsingPackage; -import android.content.pm.parsing.ParsingPackageUtils; import android.content.pm.parsing.ParsingUtils; import android.content.pm.parsing.result.ParseInput; import android.content.pm.parsing.result.ParseResult; @@ -43,7 +42,7 @@ import java.util.Iterator; /** @hide */ public class ParsedIntentInfoUtils { - private static final String TAG = ParsingPackageUtils.TAG; + private static final String TAG = ParsingUtils.TAG; @NonNull public static ParseResult<ParsedIntentInfo> parseIntentInfo(String className, diff --git a/core/java/android/content/pm/parsing/component/ParsedMainComponentUtils.java b/core/java/android/content/pm/parsing/component/ParsedMainComponentUtils.java index f4c9914cb69f..f70d62b56d49 100644 --- a/core/java/android/content/pm/parsing/component/ParsedMainComponentUtils.java +++ b/core/java/android/content/pm/parsing/component/ParsedMainComponentUtils.java @@ -20,7 +20,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.content.IntentFilter; import android.content.pm.parsing.ParsingPackage; -import android.content.pm.parsing.ParsingPackageUtils; +import android.content.pm.parsing.ParsingUtils; import android.content.pm.parsing.result.ParseInput; import android.content.pm.parsing.result.ParseResult; import android.content.res.Configuration; @@ -39,7 +39,7 @@ import java.io.IOException; /** @hide */ class ParsedMainComponentUtils { - private static final String TAG = ParsingPackageUtils.TAG; + private static final String TAG = ParsingUtils.TAG; @NonNull @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) @@ -113,7 +113,7 @@ class ParsedMainComponentUtils { ParsedIntentInfo intent = intentResult.getResult(); int actionCount = intent.countActions(); if (actionCount == 0 && failOnNoActions) { - Slog.w(TAG, "No actions in " + parser.getName() + " at " + pkg.getBaseCodePath() + " " + Slog.w(TAG, "No actions in " + parser.getName() + " at " + pkg.getBaseApkPath() + " " + parser.getPositionDescription()); // Backward-compat, do not actually fail return input.success(null); diff --git a/core/java/android/content/pm/parsing/component/ParsedPermissionUtils.java b/core/java/android/content/pm/parsing/component/ParsedPermissionUtils.java index 1884a1e27832..894849ada213 100644 --- a/core/java/android/content/pm/parsing/component/ParsedPermissionUtils.java +++ b/core/java/android/content/pm/parsing/component/ParsedPermissionUtils.java @@ -19,15 +19,15 @@ package android.content.pm.parsing.component; import android.annotation.NonNull; import android.content.pm.PermissionInfo; import android.content.pm.parsing.ParsingPackage; +import android.content.pm.parsing.ParsingUtils; +import android.content.pm.parsing.result.ParseInput; +import android.content.pm.parsing.result.ParseResult; import android.content.res.Resources; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; import android.util.Slog; import com.android.internal.R; -import android.content.pm.parsing.ParsingPackageUtils; -import android.content.pm.parsing.result.ParseInput; -import android.content.pm.parsing.result.ParseResult; import org.xmlpull.v1.XmlPullParserException; @@ -36,7 +36,7 @@ import java.io.IOException; /** @hide */ public class ParsedPermissionUtils { - private static final String TAG = ParsingPackageUtils.TAG; + private static final String TAG = ParsingUtils.TAG; @NonNull public static ParseResult<ParsedPermission> parsePermission(ParsingPackage pkg, Resources res, @@ -106,11 +106,6 @@ public class ParsedPermissionUtils { sa.recycle(); } - // TODO(b/135203078): This is impossible because of default value in above getInt - if (permission.protectionLevel == -1) { - return input.error("<permission> does not specify protectionLevel"); - } - permission.protectionLevel = PermissionInfo.fixProtectionLevel(permission.protectionLevel); if (permission.getProtectionFlags() != 0) { diff --git a/core/java/android/content/pm/parsing/component/ParsedProcessUtils.java b/core/java/android/content/pm/parsing/component/ParsedProcessUtils.java index 837270721078..9bff719e45dd 100644 --- a/core/java/android/content/pm/parsing/component/ParsedProcessUtils.java +++ b/core/java/android/content/pm/parsing/component/ParsedProcessUtils.java @@ -40,8 +40,6 @@ import java.util.Set; /** @hide */ public class ParsedProcessUtils { - private static final String TAG = ParsingUtils.TAG; - @NonNull private static ParseResult<Set<String>> parseDenyPermission(Set<String> perms, Resources res, XmlResourceParser parser, ParseInput input) diff --git a/core/java/android/content/pm/parsing/component/ParsedProviderUtils.java b/core/java/android/content/pm/parsing/component/ParsedProviderUtils.java index aa5ea8d4295a..37cbeca1d23a 100644 --- a/core/java/android/content/pm/parsing/component/ParsedProviderUtils.java +++ b/core/java/android/content/pm/parsing/component/ParsedProviderUtils.java @@ -23,7 +23,6 @@ import android.content.pm.PackageParser; import android.content.pm.PathPermission; import android.content.pm.ProviderInfo; import android.content.pm.parsing.ParsingPackage; -import android.content.pm.parsing.ParsingPackageUtils; import android.content.pm.parsing.ParsingUtils; import android.content.pm.parsing.result.ParseInput; import android.content.pm.parsing.result.ParseResult; @@ -45,7 +44,7 @@ import java.util.Objects; /** @hide */ public class ParsedProviderUtils { - private static final String TAG = ParsingPackageUtils.TAG; + private static final String TAG = ParsingUtils.TAG; @NonNull public static ParseResult<ParsedProvider> parseProvider(String[] separateProcesses, @@ -247,7 +246,7 @@ public class ParsedProviderUtils { } Slog.w(TAG, "Unknown element under <path-permission>: " + name + " at " - + pkg.getBaseCodePath() + " " + parser.getPositionDescription()); + + pkg.getBaseApkPath() + " " + parser.getPositionDescription()); } return input.success(provider); @@ -293,7 +292,8 @@ public class ParsedProviderUtils { "No readPermission or writePermission for <path-permission>"); } Slog.w(TAG, "No readPermission or writePermission for <path-permission>: " - + name + " at " + pkg.getBaseCodePath() + " " + parser.getPositionDescription()); + + name + " at " + pkg.getBaseApkPath() + " " + + parser.getPositionDescription()); return input.success(provider); } @@ -342,7 +342,7 @@ public class ParsedProviderUtils { } Slog.w(TAG, "No path, pathPrefix, or pathPattern for <path-permission>: " - + name + " at " + pkg.getBaseCodePath() + + name + " at " + pkg.getBaseApkPath() + " " + parser.getPositionDescription()); } diff --git a/core/java/android/content/pm/parsing/component/ParsedServiceUtils.java b/core/java/android/content/pm/parsing/component/ParsedServiceUtils.java index a8d2d671e5e6..afe3c5494fcb 100644 --- a/core/java/android/content/pm/parsing/component/ParsedServiceUtils.java +++ b/core/java/android/content/pm/parsing/component/ParsedServiceUtils.java @@ -22,7 +22,6 @@ import android.annotation.NonNull; import android.content.pm.ActivityInfo; import android.content.pm.ServiceInfo; import android.content.pm.parsing.ParsingPackage; -import android.content.pm.parsing.ParsingPackageUtils; import android.content.pm.parsing.ParsingUtils; import android.content.pm.parsing.result.ParseInput; import android.content.pm.parsing.result.ParseInput.DeferredError; @@ -43,8 +42,6 @@ import java.util.Objects; /** @hide */ public class ParsedServiceUtils { - private static final String TAG = ParsingPackageUtils.TAG; - @NonNull public static ParseResult<ParsedService> parseService(String[] separateProcesses, ParsingPackage pkg, Resources res, XmlResourceParser parser, int flags, diff --git a/core/java/android/content/pm/parsing/result/ParseTypeImpl.java b/core/java/android/content/pm/parsing/result/ParseTypeImpl.java index 14992fb2a4d1..0f90b5371965 100644 --- a/core/java/android/content/pm/parsing/result/ParseTypeImpl.java +++ b/core/java/android/content/pm/parsing/result/ParseTypeImpl.java @@ -95,7 +95,7 @@ public class ParseTypeImpl implements ParseInput, ParseResult<Object> { return platformCompat.isChangeEnabled(changeId, appInfo); } catch (Exception e) { // This shouldn't happen, but assume enforcement if it does - Slog.wtf(ParsingUtils.TAG, "IPlatformCompat query failed", e); + Slog.wtf(TAG, "IPlatformCompat query failed", e); return true; } }); @@ -125,7 +125,7 @@ public class ParseTypeImpl implements ParseInput, ParseResult<Object> { @Override public <ResultType> ParseResult<ResultType> success(ResultType result) { if (mErrorCode != PackageManager.INSTALL_SUCCEEDED) { - Slog.wtf(ParsingUtils.TAG, "Cannot set to success after set to error, was " + Slog.wtf(TAG, "Cannot set to success after set to error, was " + mErrorMessage, mException); } mResult = result; diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java index 515704ca77f4..bec96f98dbcd 100644 --- a/core/java/android/os/Binder.java +++ b/core/java/android/os/Binder.java @@ -1102,7 +1102,6 @@ public class Binder implements IBinder { } private static native long getNativeBBinderHolder(); - private static native long getFinalizer(); /** * By default, we use the calling uid since we can always trust it. diff --git a/core/java/android/os/storage/StorageManagerInternal.java b/core/java/android/os/storage/StorageManagerInternal.java index e05991b33796..a79a1cfcd64f 100644 --- a/core/java/android/os/storage/StorageManagerInternal.java +++ b/core/java/android/os/storage/StorageManagerInternal.java @@ -118,7 +118,7 @@ public abstract class StorageManagerInternal { * affects them. */ public abstract void onAppOpsChanged(int code, int uid, - @Nullable String packageName, int mode); + @Nullable String packageName, int mode, int previousMode); /** * Asks the StorageManager to reset all state for the provided user; this will result diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 739e169e44c7..18337b661844 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -6801,6 +6801,13 @@ public final class Settings { public static final String KEYGUARD_SLICE_URI = "keyguard_slice_uri"; /** + * Whether to draw text in bold. + * + * @hide + */ + public static final String FORCE_BOLD_TEXT = "force_bold_text"; + + /** * Whether to speak passwords while in accessibility mode. * * @deprecated The speaking of passwords is controlled by individual accessibility services. diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java index e083417644e3..19860eb45fbf 100644 --- a/core/java/android/service/wallpaper/WallpaperService.java +++ b/core/java/android/service/wallpaper/WallpaperService.java @@ -71,6 +71,7 @@ import android.view.ViewGroup; import android.view.WindowInsets; import android.view.WindowManager; import android.view.WindowManagerGlobal; +import android.window.ClientWindowFrames; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.os.HandlerCaller; @@ -186,17 +187,11 @@ public abstract class WallpaperService extends Service { int mCurWindowFlags = mWindowFlags; int mCurWindowPrivateFlags = mWindowPrivateFlags; Rect mPreviewSurfacePosition; - final Rect mVisibleInsets = new Rect(); - final Rect mWinFrame = new Rect(); - final Rect mContentInsets = new Rect(); - final Rect mStableInsets = new Rect(); + final ClientWindowFrames mWinFrames = new ClientWindowFrames(); final Rect mDispatchedContentInsets = new Rect(); final Rect mDispatchedStableInsets = new Rect(); final Rect mFinalSystemInsets = new Rect(); final Rect mFinalStableInsets = new Rect(); - final Rect mBackdropFrame = new Rect(); - final DisplayCutout.ParcelableWrapper mDisplayCutout = - new DisplayCutout.ParcelableWrapper(); DisplayCutout mDispatchedDisplayCutout = DisplayCutout.NO_CUTOUT; final InsetsState mInsetsState = new InsetsState(); final InsetsSourceControl[] mTempControls = new InsetsSourceControl[0]; @@ -332,11 +327,9 @@ public abstract class WallpaperService extends Service { final BaseIWindow mWindow = new BaseIWindow() { @Override - public void resized(Rect frame, Rect contentInsets, - Rect visibleInsets, Rect stableInsets, boolean reportDraw, - MergedConfiguration mergedConfiguration, Rect backDropRect, boolean forceLayout, - boolean alwaysConsumeSystemBars, int displayId, - DisplayCutout.ParcelableWrapper displayCutout) { + public void resized(ClientWindowFrames frames, boolean reportDraw, + MergedConfiguration mergedConfiguration, boolean forceLayout, + boolean alwaysConsumeSystemBars, int displayId) { Message msg = mCaller.obtainMessageI(MSG_WINDOW_RESIZED, reportDraw ? 1 : 0); mCaller.sendMessage(msg); @@ -749,10 +742,7 @@ public abstract class WallpaperService extends Service { out.print(" mCurWindowFlags="); out.println(mCurWindowFlags); out.print(prefix); out.print("mWindowPrivateFlags="); out.print(mWindowPrivateFlags); out.print(" mCurWindowPrivateFlags="); out.println(mCurWindowPrivateFlags); - out.print(prefix); out.print("mVisibleInsets="); - out.print(mVisibleInsets.toShortString()); - out.print(" mWinFrame="); out.print(mWinFrame.toShortString()); - out.print(" mContentInsets="); out.println(mContentInsets.toShortString()); + out.print(prefix); out.println("mWinFrames="); out.println(mWinFrames); out.print(prefix); out.print("mConfiguration="); out.println(mMergedConfiguration.getMergedConfiguration()); out.print(prefix); out.print("mLayout="); out.println(mLayout); @@ -890,8 +880,8 @@ public abstract class WallpaperService extends Service { InputChannel inputChannel = new InputChannel(); if (mSession.addToDisplay(mWindow, mWindow.mSeq, mLayout, View.VISIBLE, - mDisplay.getDisplayId(), mWinFrame, mContentInsets, mStableInsets, - mDisplayCutout, inputChannel, + mDisplay.getDisplayId(), mWinFrames.frame, mWinFrames.contentInsets, + mWinFrames.stableInsets, mWinFrames.displayCutout, inputChannel, mInsetsState, mTempControls) < 0) { Log.w(TAG, "Failed to add window while updating wallpaper surface."); return; @@ -914,34 +904,32 @@ public abstract class WallpaperService extends Service { final int relayoutResult = mSession.relayout( mWindow, mWindow.mSeq, mLayout, mWidth, mHeight, - View.VISIBLE, 0, -1, mWinFrame, mContentInsets, - mVisibleInsets, mStableInsets, mBackdropFrame, - mDisplayCutout, mMergedConfiguration, mSurfaceControl, + View.VISIBLE, 0, -1, mWinFrames, mMergedConfiguration, mSurfaceControl, mInsetsState, mTempControls, mSurfaceSize, mTmpSurfaceControl); if (mSurfaceControl.isValid()) { mSurfaceHolder.mSurface.copyFrom(mSurfaceControl); } if (DEBUG) Log.v(TAG, "New surface: " + mSurfaceHolder.mSurface - + ", frame=" + mWinFrame); + + ", frame=" + mWinFrames); - int w = mWinFrame.width(); - int h = mWinFrame.height(); + int w = mWinFrames.frame.width(); + int h = mWinFrames.frame.height(); if (!fixedSize) { final Rect padding = mIWallpaperEngine.mDisplayPadding; w += padding.left + padding.right; h += padding.top + padding.bottom; - mContentInsets.left += padding.left; - mContentInsets.top += padding.top; - mContentInsets.right += padding.right; - mContentInsets.bottom += padding.bottom; - mStableInsets.left += padding.left; - mStableInsets.top += padding.top; - mStableInsets.right += padding.right; - mStableInsets.bottom += padding.bottom; - mDisplayCutout.set(mDisplayCutout.get().inset(-padding.left, -padding.top, - -padding.right, -padding.bottom)); + mWinFrames.contentInsets.left += padding.left; + mWinFrames.contentInsets.top += padding.top; + mWinFrames.contentInsets.right += padding.right; + mWinFrames.contentInsets.bottom += padding.bottom; + mWinFrames.stableInsets.left += padding.left; + mWinFrames.stableInsets.top += padding.top; + mWinFrames.stableInsets.right += padding.right; + mWinFrames.stableInsets.bottom += padding.bottom; + mWinFrames.displayCutout.set(mWinFrames.displayCutout.get().inset( + -padding.left, -padding.top, -padding.right, -padding.bottom)); } else { w = myWidth; h = myHeight; @@ -960,9 +948,10 @@ public abstract class WallpaperService extends Service { Log.v(TAG, "Wallpaper size has changed: (" + mCurWidth + ", " + mCurHeight); } - insetsChanged |= !mDispatchedContentInsets.equals(mContentInsets); - insetsChanged |= !mDispatchedStableInsets.equals(mStableInsets); - insetsChanged |= !mDispatchedDisplayCutout.equals(mDisplayCutout.get()); + final DisplayCutout displayCutout = mWinFrames.displayCutout.get(); + insetsChanged |= !mDispatchedContentInsets.equals(mWinFrames.contentInsets); + insetsChanged |= !mDispatchedStableInsets.equals(mWinFrames.stableInsets); + insetsChanged |= !mDispatchedDisplayCutout.equals(displayCutout); mSurfaceHolder.setSurfaceFrameSize(w, h); mSurfaceHolder.mSurfaceLock.unlock(); @@ -1021,9 +1010,9 @@ public abstract class WallpaperService extends Service { } if (insetsChanged) { - mDispatchedContentInsets.set(mContentInsets); - mDispatchedStableInsets.set(mStableInsets); - mDispatchedDisplayCutout = mDisplayCutout.get(); + mDispatchedContentInsets.set(mWinFrames.contentInsets); + mDispatchedStableInsets.set(mWinFrames.stableInsets); + mDispatchedDisplayCutout = displayCutout; mFinalStableInsets.set(mDispatchedStableInsets); WindowInsets insets = new WindowInsets(mFinalSystemInsets, mFinalStableInsets, diff --git a/core/java/android/speech/RecognitionService.java b/core/java/android/speech/RecognitionService.java index 4b42209be653..5fd192afed00 100644 --- a/core/java/android/speech/RecognitionService.java +++ b/core/java/android/speech/RecognitionService.java @@ -183,10 +183,9 @@ public abstract class RecognitionService extends Service { @NonNull String packageName, @Nullable String featureId) { if (DBG) Log.d(TAG, "checkPermissions"); if (forDataDelivery) { - if (PermissionChecker.checkCallingPermissionForDataDelivery(this, + if (PermissionChecker.checkCallingOrSelfPermissionForDataDelivery(this, android.Manifest.permission.RECORD_AUDIO, packageName, featureId, - null /*message*/) - == PermissionChecker.PERMISSION_GRANTED) { + null /*message*/) == PermissionChecker.PERMISSION_GRANTED) { return true; } } else { diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java index e338fd977f27..09736085954c 100644 --- a/core/java/android/util/FeatureFlagUtils.java +++ b/core/java/android/util/FeatureFlagUtils.java @@ -65,6 +65,7 @@ public class FeatureFlagUtils { DEFAULT_FLAGS.put(SETTINGS_DO_NOT_RESTORE_PRESERVED, "true"); DEFAULT_FLAGS.put("settings_tether_all_in_one", "false"); + DEFAULT_FLAGS.put("settings_silky_home", "false"); } /** diff --git a/core/java/android/view/BatchedInputEventReceiver.java b/core/java/android/view/BatchedInputEventReceiver.java index 30e3ec135065..7023e4bd0134 100644 --- a/core/java/android/view/BatchedInputEventReceiver.java +++ b/core/java/android/view/BatchedInputEventReceiver.java @@ -24,7 +24,8 @@ import android.os.Looper; * @hide */ public class BatchedInputEventReceiver extends InputEventReceiver { - Choreographer mChoreographer; + private Choreographer mChoreographer; + private boolean mBatchingEnabled; private boolean mBatchedInputScheduled; @UnsupportedAppUsage @@ -32,19 +33,37 @@ public class BatchedInputEventReceiver extends InputEventReceiver { InputChannel inputChannel, Looper looper, Choreographer choreographer) { super(inputChannel, looper); mChoreographer = choreographer; + mBatchingEnabled = true; } @Override public void onBatchedInputEventPending(int source) { - scheduleBatchedInput(); + if (mBatchingEnabled) { + scheduleBatchedInput(); + } else { + consumeBatchedInputEvents(-1); + } } @Override public void dispose() { unscheduleBatchedInput(); + consumeBatchedInputEvents(-1); super.dispose(); } + /** + * Sets whether to enable batching on this input event receiver. + * @hide + */ + public void setBatchingEnabled(boolean batchingEnabled) { + mBatchingEnabled = batchingEnabled; + if (!batchingEnabled) { + unscheduleBatchedInput(); + consumeBatchedInputEvents(-1); + } + } + void doConsumeBatchedInput(long frameTimeNanos) { if (mBatchedInputScheduled) { mBatchedInputScheduled = false; diff --git a/core/java/android/view/IWindow.aidl b/core/java/android/view/IWindow.aidl index e09bf9d2e80a..94e641c62b25 100644 --- a/core/java/android/view/IWindow.aidl +++ b/core/java/android/view/IWindow.aidl @@ -29,6 +29,7 @@ import android.view.InsetsState; import android.view.IScrollCaptureController; import android.view.KeyEvent; import android.view.MotionEvent; +import android.window.ClientWindowFrames; import com.android.internal.os.IResultReceiver; @@ -52,11 +53,9 @@ oneway interface IWindow { */ void executeCommand(String command, String parameters, in ParcelFileDescriptor descriptor); - void resized(in Rect frame, in Rect contentInsets, - in Rect visibleInsets, in Rect stableInsets, boolean reportDraw, - in MergedConfiguration newMergedConfiguration, in Rect backDropFrame, - boolean forceLayout, boolean alwaysConsumeSystemBars, int displayId, - in DisplayCutout.ParcelableWrapper displayCutout); + void resized(in ClientWindowFrames frames, boolean reportDraw, + in MergedConfiguration newMergedConfiguration, + boolean forceLayout, boolean alwaysConsumeSystemBars, int displayId); /** * Called when the window location in parent display has changed. The offset will only be a diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl index 00fc67214f75..8e875d7a889d 100644 --- a/core/java/android/view/IWindowManager.aidl +++ b/core/java/android/view/IWindowManager.aidl @@ -393,11 +393,6 @@ interface IWindowManager oneway void setRecentsVisibility(boolean visible); /** - * Called by System UI to notify of changes to the visibility of PIP. - */ - oneway void setPipVisibility(boolean visible); - - /** * Called by System UI to enable or disable haptic feedback on the navigation bar buttons. */ @UnsupportedAppUsage diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl index 819e89b67b38..70850d855161 100644 --- a/core/java/android/view/IWindowSession.aidl +++ b/core/java/android/view/IWindowSession.aidl @@ -34,6 +34,7 @@ import android.view.InsetsState; import android.view.Surface; import android.view.SurfaceControl; import android.view.SurfaceControl.Transaction; +import android.window.ClientWindowFrames; import java.util.List; @@ -107,10 +108,7 @@ interface IWindowSession { */ int relayout(IWindow window, int seq, in WindowManager.LayoutParams attrs, int requestedWidth, int requestedHeight, int viewVisibility, - int flags, long frameNumber, out Rect outFrame, - out Rect outContentInsets, out Rect outVisibleInsets, out Rect outStableInsets, - out Rect outBackdropFrame, - out DisplayCutout.ParcelableWrapper displayCutout, + int flags, long frameNumber, out ClientWindowFrames outFrames, out MergedConfiguration outMergedConfiguration, out SurfaceControl outSurfaceControl, out InsetsState insetsState, out InsetsSourceControl[] activeControls, out Point outSurfaceSize, out SurfaceControl outBlastSurfaceControl); @@ -152,12 +150,6 @@ interface IWindowSession { in Rect visibleInsets, in Region touchableRegion); /** - * Return the current display size in which the window is being laid out, - * accounting for screen decorations around it. - */ - void getDisplayFrame(IWindow window, out Rect outDisplayFrame); - - /** * Called when the client has finished drawing the surface, if needed. * * @param postDrawTransaction transaction filled by the client that can be diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index 6ef086b55c41..67681dabf3f0 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -65,6 +65,9 @@ import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.ArrayList; import java.util.Objects; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; /** * Handle to an on-screen Surface managed by the system compositor. The SurfaceControl is @@ -87,10 +90,10 @@ public final class SurfaceControl implements Parcelable { private static native void nativeWriteToParcel(long nativeObject, Parcel out); private static native void nativeRelease(long nativeObject); private static native void nativeDisconnect(long nativeObject); - private static native ScreenshotHardwareBuffer nativeCaptureDisplay( - DisplayCaptureArgs captureArgs); - private static native ScreenshotHardwareBuffer nativeCaptureLayers( - LayerCaptureArgs captureArgs); + private static native int nativeCaptureDisplay(DisplayCaptureArgs captureArgs, + ScreenCaptureListener captureListener); + private static native int nativeCaptureLayers(LayerCaptureArgs captureArgs, + ScreenCaptureListener captureListener); private static native long nativeMirrorSurface(long mirrorOfObject); private static native long nativeCreateTransaction(); private static native long nativeGetNativeTransactionFinalizer(); @@ -221,6 +224,8 @@ public final class SurfaceControl implements Parcelable { private static native void nativeReleaseFrameRateFlexibilityToken(long token); private static native void nativeSetFixedTransformHint(long transactionObj, long nativeObject, int transformHint); + private static native void nativeSetFocusedWindow(long transactionObj, IBinder toToken, + IBinder focusedToken, int displayId); @Nullable @GuardedBy("mLock") @@ -493,6 +498,8 @@ public final class SurfaceControl implements Parcelable { private static final int INTERNAL_DATASPACE_DISPLAY_P3 = 143261696; private static final int INTERNAL_DATASPACE_SCRGB = 411107328; + private static final int SCREENSHOT_WAIT_TIME_S = 1; + private void assignNativeObject(long nativeObject, String callsite) { if (mNativeObject != 0) { release(); @@ -611,6 +618,13 @@ public final class SurfaceControl implements Parcelable { } /** + * @hide + */ + public abstract static class ScreenCaptureListener { + abstract void onScreenCaptureComplete(ScreenshotHardwareBuffer hardwareBuffer); + } + + /** * A common arguments class used for various screenshot requests. This contains arguments that * are shared between {@link DisplayCaptureArgs} and {@link LayerCaptureArgs} * @hide @@ -685,7 +699,7 @@ public final class SurfaceControl implements Parcelable { /** * The arguments class used to make display capture requests. * - * @see #nativeCaptureDisplay(DisplayCaptureArgs) + * @see #nativeCaptureDisplay(DisplayCaptureArgs, ScreenCaptureListener) * @hide */ public static class DisplayCaptureArgs extends CaptureArgs { @@ -2226,13 +2240,46 @@ public final class SurfaceControl implements Parcelable { } /** + * @param captureArgs Arguments about how to take the screenshot + * @param captureListener A listener to receive the screenshot callback + * @hide + */ + public static int captureDisplay(@NonNull DisplayCaptureArgs captureArgs, + @NonNull ScreenCaptureListener captureListener) { + return nativeCaptureDisplay(captureArgs, captureListener); + } + + /** * Captures all the surfaces in a display and returns a {@link ScreenshotHardwareBuffer} with * the content. * * @hide */ public static ScreenshotHardwareBuffer captureDisplay(DisplayCaptureArgs captureArgs) { - return nativeCaptureDisplay(captureArgs); + final AtomicReference<ScreenshotHardwareBuffer> outHardwareBuffer = + new AtomicReference<>(null); + + final CountDownLatch countDownLatch = new CountDownLatch(1); + ScreenCaptureListener screenCaptureListener = new ScreenCaptureListener() { + @Override + void onScreenCaptureComplete(ScreenshotHardwareBuffer hardwareBuffer) { + outHardwareBuffer.set(hardwareBuffer); + countDownLatch.countDown(); + } + }; + + int status = captureDisplay(captureArgs, screenCaptureListener); + if (status != 0) { + return null; + } + + try { + countDownLatch.await(SCREENSHOT_WAIT_TIME_S, TimeUnit.SECONDS); + } catch (Exception e) { + Log.e(TAG, "Failed to wait for captureDisplay result", e); + } + + return outHardwareBuffer.get(); } /** @@ -2277,14 +2324,37 @@ public final class SurfaceControl implements Parcelable { .setPixelFormat(format) .build(); - return nativeCaptureLayers(captureArgs); + return captureLayers(captureArgs); } /** * @hide */ public static ScreenshotHardwareBuffer captureLayers(LayerCaptureArgs captureArgs) { - return nativeCaptureLayers(captureArgs); + final AtomicReference<ScreenshotHardwareBuffer> outHardwareBuffer = + new AtomicReference<>(null); + + final CountDownLatch countDownLatch = new CountDownLatch(1); + ScreenCaptureListener screenCaptureListener = new ScreenCaptureListener() { + @Override + void onScreenCaptureComplete(ScreenshotHardwareBuffer hardwareBuffer) { + outHardwareBuffer.set(hardwareBuffer); + countDownLatch.countDown(); + } + }; + + int status = captureLayers(captureArgs, screenCaptureListener); + if (status != 0) { + return null; + } + + try { + countDownLatch.await(SCREENSHOT_WAIT_TIME_S, TimeUnit.SECONDS); + } catch (Exception e) { + Log.e(TAG, "Failed to wait for captureLayers result", e); + } + + return outHardwareBuffer.get(); } /** @@ -2301,7 +2371,17 @@ public final class SurfaceControl implements Parcelable { .setExcludeLayers(exclude) .build(); - return nativeCaptureLayers(captureArgs); + return captureLayers(captureArgs); + } + + /** + * @param captureArgs Arguments about how to take the screenshot + * @param captureListener A listener to receive the screenshot callback + * @hide + */ + public static int captureLayers(@NonNull LayerCaptureArgs captureArgs, + @NonNull ScreenCaptureListener captureListener) { + return nativeCaptureLayers(captureArgs, captureListener); } /** @@ -3184,6 +3264,39 @@ public final class SurfaceControl implements Parcelable { } /** + * Sets focus on the window identified by the input {@code token} if the window is focusable + * otherwise the request is dropped. + * + * If the window is not visible, the request will be queued until the window becomes + * visible or the request is overrriden by another request. The currently focused window + * will lose focus immediately. This is to send the newly focused window any focus + * dispatched events that occur while it is completing its first draw. + * + * @hide + */ + public Transaction setFocusedWindow(@NonNull IBinder token, int displayId) { + nativeSetFocusedWindow(mNativeObject, token, null /* focusedToken */, displayId); + return this; + } + + /** + * Set focus on the window identified by the input {@code token} if the window identified by + * the input {@code focusedToken} is currently focused. If the {@code focusedToken} does not + * have focus, the request is dropped. + * + * This is used by forward focus transfer requests from clients that host embedded windows, + * and want to transfer focus to/from them. + * + * @hide + */ + public Transaction requestFocusTransfer(@NonNull IBinder token, + @NonNull IBinder focusedToken, + int displayId) { + nativeSetFocusedWindow(mNativeObject, token, focusedToken, displayId); + return this; + } + + /** * Merge the other transaction into this transaction, clearing the * other transaction as if it had been applied. * diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 89178217366f..92a0f633aba0 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -14940,20 +14940,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * inside. In effect, this tells you the available area where content can * be placed and remain visible to users. * - * <p>This function requires an IPC back to the window manager to retrieve - * the requested information, so should not be used in performance critical - * code like drawing. - * * @param outRect Filled in with the visible display frame. If the view * is not attached to a window, this is simply the raw display size. */ public void getWindowVisibleDisplayFrame(Rect outRect) { if (mAttachInfo != null) { - try { - mAttachInfo.mSession.getDisplayFrame(mAttachInfo.mWindow, outRect); - } catch (RemoteException e) { - return; - } + mAttachInfo.mViewRootImpl.getDisplayFrame(outRect); // XXX This is really broken, and probably all needs to be done // in the window manager, and we need to know more about whether // we want the area behind or in front of the IME. @@ -14979,11 +14971,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, @UnsupportedAppUsage public void getWindowDisplayFrame(Rect outRect) { if (mAttachInfo != null) { - try { - mAttachInfo.mSession.getDisplayFrame(mAttachInfo.mWindow, outRect); - } catch (RemoteException e) { - return; - } + mAttachInfo.mViewRootImpl.getDisplayFrame(outRect); return; } // The view is not attached to a display so we don't have a context. diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java index ccf1fb07d0bb..abf76ece1f3d 100644 --- a/core/java/android/view/ViewConfiguration.java +++ b/core/java/android/view/ViewConfiguration.java @@ -100,7 +100,7 @@ public class ViewConfiguration { * Defines the duration in milliseconds a user needs to hold down the * appropriate buttons (power + volume down) to trigger the screenshot chord. */ - private static final int SCREENSHOT_CHORD_KEY_TIMEOUT = 500; + private static final int SCREENSHOT_CHORD_KEY_TIMEOUT = 0; /** * Defines the duration in milliseconds a user needs to hold down the diff --git a/core/java/android/view/ViewDebug.java b/core/java/android/view/ViewDebug.java index 8a5be75b6c31..4303d705f945 100644 --- a/core/java/android/view/ViewDebug.java +++ b/core/java/android/view/ViewDebug.java @@ -33,7 +33,6 @@ import android.os.Debug; import android.os.Handler; import android.os.Looper; import android.os.Message; -import android.os.RemoteException; import android.util.DisplayMetrics; import android.util.Log; import android.util.TypedValue; @@ -755,11 +754,7 @@ public class ViewDebug { try { Rect outRect = new Rect(); - try { - root.mAttachInfo.mSession.getDisplayFrame(root.mAttachInfo.mWindow, outRect); - } catch (RemoteException e) { - // Ignore - } + root.mAttachInfo.mViewRootImpl.getDisplayFrame(outRect); clientStream.writeInt(outRect.width()); clientStream.writeInt(outRect.height()); diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index f3a8d9754fd4..af839d4481f7 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -137,7 +137,6 @@ import android.view.View.MeasureSpec; import android.view.Window.OnContentApplyWindowInsetsListener; import android.view.WindowInsets.Type; import android.view.WindowInsets.Type.InsetsType; -import android.view.WindowManager.LayoutParams; import android.view.WindowManager.LayoutParams.SoftInputModeFlags; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; @@ -160,6 +159,7 @@ import android.view.contentcapture.ContentCaptureSession; import android.view.contentcapture.MainContentCaptureSession; import android.view.inputmethod.InputMethodManager; import android.widget.Scroller; +import android.window.ClientWindowFrames; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; @@ -465,6 +465,7 @@ public final class ViewRootImpl implements ViewParent, // used in relayout to get SurfaceControl size // for BLAST adapter surface setup private final Point mSurfaceSize = new Point(); + private final Point mLastSurfaceSize = new Point(); final Rect mTempRect; // used in the transaction to not thrash the heap. final Rect mVisRect; // used to retrieve visible rect of focused view. @@ -559,8 +560,11 @@ public final class ViewRootImpl implements ViewParent, boolean mAdded; boolean mAddedTouchMode; - final Rect mTmpFrame = new Rect(); - final Rect mTmpRect = new Rect(); + /** + * It usually keeps the latest layout result from {@link IWindow#resized} or + * {@link IWindowSession#relayout}. + */ + private final ClientWindowFrames mTmpFrames = new ClientWindowFrames(); // These are accessed by multiple threads. final Rect mWinFrame; // frame given by window manager. @@ -1032,11 +1036,11 @@ public final class ViewRootImpl implements ViewParent, collectViewAttributes(); adjustLayoutParamsForCompatibility(mWindowAttributes); res = mWindowSession.addToDisplayAsUser(mWindow, mSeq, mWindowAttributes, - getHostVisibility(), mDisplay.getDisplayId(), userId, mTmpFrame, + getHostVisibility(), mDisplay.getDisplayId(), userId, mTmpFrames.frame, mAttachInfo.mContentInsets, mAttachInfo.mStableInsets, mAttachInfo.mDisplayCutout, inputChannel, mTempInsets, mTempControls); - setFrame(mTmpFrame); + setFrame(mTmpFrames.frame); } catch (RemoteException e) { mAdded = false; mView = null; @@ -1474,6 +1478,55 @@ public final class ViewRootImpl implements ViewParent, scheduleTraversals(); } + /** Handles messages {@link #MSG_RESIZED} and {@link #MSG_RESIZED_REPORT}. */ + private void handleResized(int msg, SomeArgs args) { + if (!mAdded) { + return; + } + + final ClientWindowFrames frames = (ClientWindowFrames) args.arg1; + final MergedConfiguration mergedConfiguration = (MergedConfiguration) args.arg2; + final boolean forceNextWindowRelayout = args.argi1 != 0; + final int displayId = args.argi3; + final Rect backdropFrame = frames.backdropFrame; + final DisplayCutout displayCutout = frames.displayCutout.get(); + + final boolean frameChanged = !mWinFrame.equals(frames.frame); + final boolean cutoutChanged = !mPendingDisplayCutout.get().equals(displayCutout); + final boolean backdropFrameChanged = !mPendingBackDropFrame.equals(backdropFrame); + final boolean configChanged = !mLastReportedMergedConfiguration.equals(mergedConfiguration); + final boolean displayChanged = mDisplay.getDisplayId() != displayId; + if (msg == MSG_RESIZED && !frameChanged && !cutoutChanged && !backdropFrameChanged + && !configChanged && !displayChanged && !forceNextWindowRelayout) { + return; + } + + if (configChanged) { + // If configuration changed - notify about that and, maybe, about move to display. + performConfigurationChange(mergedConfiguration, false /* force */, + displayChanged ? displayId : INVALID_DISPLAY /* same display */); + } else if (displayChanged) { + // Moved to display without config change - report last applied one. + onMovedToDisplay(displayId, mLastConfigurationFromResources); + } + + setFrame(frames.frame); + mTmpFrames.displayFrame.set(frames.displayFrame); + mPendingDisplayCutout.set(displayCutout); + mPendingBackDropFrame.set(backdropFrame); + mForceNextWindowRelayout = forceNextWindowRelayout; + mPendingAlwaysConsumeSystemBars = args.argi2 != 0; + + if (msg == MSG_RESIZED_REPORT) { + reportNextDraw(); + } + + if (mView != null && (frameChanged || cutoutChanged || configChanged)) { + forceLayout(mView); + } + requestLayout(); + } + private final DisplayListener mDisplayListener = new DisplayListener() { @Override public void onDisplayChanged(int displayId) { @@ -2641,9 +2694,12 @@ public final class ViewRootImpl implements ViewParent, } cutoutChanged = !mPendingDisplayCutout.equals(mAttachInfo.mDisplayCutout); - surfaceSizeChanged = (relayoutResult - & WindowManagerGlobal.RELAYOUT_RES_SURFACE_RESIZED) != 0; - final boolean alwaysConsumeSystemBarsChanged = + surfaceSizeChanged = false; + if (!mLastSurfaceSize.equals(mSurfaceSize)) { + surfaceSizeChanged = true; + mLastSurfaceSize.set(mSurfaceSize.x, mSurfaceSize.y); + } + final boolean alwaysConsumeSystemBarsChanged = mPendingAlwaysConsumeSystemBars != mAttachInfo.mAlwaysConsumeSystemBars; updateColorModeIfNeeded(lp.getColorMode()); surfaceCreated = !hadSurface && mSurface.isValid(); @@ -4919,60 +4975,13 @@ public final class ViewRootImpl implements ViewParent, case MSG_DISPATCH_GET_NEW_SURFACE: handleGetNewSurface(); break; - case MSG_RESIZED: { - // Recycled in the fall through... - SomeArgs args = (SomeArgs) msg.obj; - if (mWinFrame.equals(args.arg1) - && mPendingDisplayCutout.get().equals(args.arg9) - && mPendingBackDropFrame.equals(args.arg8) - && mLastReportedMergedConfiguration.equals(args.arg4) - && args.argi1 == 0 - && mDisplay.getDisplayId() == args.argi3) { - break; - } - } // fall through... - case MSG_RESIZED_REPORT: - if (mAdded) { - SomeArgs args = (SomeArgs) msg.obj; - - final int displayId = args.argi3; - MergedConfiguration mergedConfiguration = (MergedConfiguration) args.arg4; - final boolean displayChanged = mDisplay.getDisplayId() != displayId; - boolean configChanged = false; - - if (!mLastReportedMergedConfiguration.equals(mergedConfiguration)) { - // If configuration changed - notify about that and, maybe, - // about move to display. - performConfigurationChange(mergedConfiguration, false /* force */, - displayChanged - ? displayId : INVALID_DISPLAY /* same display */); - configChanged = true; - } else if (displayChanged) { - // Moved to display without config change - report last applied one. - onMovedToDisplay(displayId, mLastConfigurationFromResources); - } - - final boolean framesChanged = !mWinFrame.equals(args.arg1) - || !mPendingDisplayCutout.get().equals(args.arg9); - - setFrame((Rect) args.arg1); - mPendingDisplayCutout.set((DisplayCutout) args.arg9); - mPendingBackDropFrame.set((Rect) args.arg8); - mForceNextWindowRelayout = args.argi1 != 0; - mPendingAlwaysConsumeSystemBars = args.argi2 != 0; - - args.recycle(); - - if (msg.what == MSG_RESIZED_REPORT) { - reportNextDraw(); - } - - if (mView != null && (framesChanged || configChanged)) { - forceLayout(mView); - } - requestLayout(); - } + case MSG_RESIZED: + case MSG_RESIZED_REPORT: { + final SomeArgs args = (SomeArgs) msg.obj; + handleResized(msg.what, args); + args.recycle(); break; + } case MSG_INSETS_CHANGED: mInsetsController.onStateChanged((InsetsState) msg.obj); break; @@ -5007,11 +5016,11 @@ public final class ViewRootImpl implements ViewParent, final int h = mWinFrame.height(); final int l = msg.arg1; final int t = msg.arg2; - mTmpFrame.left = l; - mTmpFrame.right = l + w; - mTmpFrame.top = t; - mTmpFrame.bottom = t + h; - setFrame(mTmpFrame); + mTmpFrames.frame.left = l; + mTmpFrames.frame.right = l + w; + mTmpFrames.frame.top = t; + mTmpFrames.frame.bottom = t + h; + setFrame(mTmpFrames.frame); mPendingBackDropFrame.set(mWinFrame); maybeHandleWindowMove(mWinFrame); @@ -7418,9 +7427,10 @@ public final class ViewRootImpl implements ViewParent, (int) (mView.getMeasuredWidth() * appScale + 0.5f), (int) (mView.getMeasuredHeight() * appScale + 0.5f), viewVisibility, insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0, frameNumber, - mTmpFrame, mTmpRect, mTmpRect, mTmpRect, mPendingBackDropFrame, - mPendingDisplayCutout, mPendingMergedConfiguration, mSurfaceControl, mTempInsets, + mTmpFrames, mPendingMergedConfiguration, mSurfaceControl, mTempInsets, mTempControls, mSurfaceSize, mBlastSurfaceControl); + mPendingDisplayCutout.set(mTmpFrames.displayCutout); + mPendingBackDropFrame.set(mTmpFrames.backdropFrame); if (mSurfaceControl.isValid()) { if (!useBLAST()) { mSurface.copyFrom(mSurfaceControl); @@ -7446,9 +7456,9 @@ public final class ViewRootImpl implements ViewParent, } if (mTranslator != null) { - mTranslator.translateRectInScreenToAppWinFrame(mTmpFrame); + mTranslator.translateRectInScreenToAppWinFrame(mTmpFrames.frame); } - setFrame(mTmpFrame); + setFrame(mTmpFrames.frame); mInsetsController.onStateChanged(mTempInsets); mInsetsController.onControlsChanged(mTempControls); return relayoutResult; @@ -7460,6 +7470,14 @@ public final class ViewRootImpl implements ViewParent, } /** + * Gets the current display size in which the window is being laid out, accounting for screen + * decorations around it. + */ + void getDisplayFrame(Rect outFrame) { + outFrame.set(mTmpFrames.displayFrame); + } + + /** * {@inheritDoc} */ @Override @@ -7742,11 +7760,14 @@ public final class ViewRootImpl implements ViewParent, } @UnsupportedAppUsage - private void dispatchResized(Rect frame, Rect contentInsets, - Rect visibleInsets, Rect stableInsets, boolean reportDraw, - MergedConfiguration mergedConfiguration, Rect backDropFrame, boolean forceLayout, - boolean alwaysConsumeSystemBars, int displayId, - DisplayCutout.ParcelableWrapper displayCutout) { + private void dispatchResized(ClientWindowFrames frames, boolean reportDraw, + MergedConfiguration mergedConfiguration, boolean forceLayout, + boolean alwaysConsumeSystemBars, int displayId) { + final Rect frame = frames.frame; + final Rect contentInsets = frames.contentInsets; + final Rect visibleInsets = frames.visibleInsets; + final Rect stableInsets = frames.stableInsets; + final Rect backDropFrame = frames.backdropFrame; if (DEBUG_LAYOUT) Log.v(mTag, "Resizing " + this + ": frame=" + frame.toShortString() + " contentInsets=" + contentInsets.toShortString() + " visibleInsets=" + visibleInsets.toShortString() @@ -7773,14 +7794,9 @@ public final class ViewRootImpl implements ViewParent, } SomeArgs args = SomeArgs.obtain(); final boolean sameProcessCall = (Binder.getCallingPid() == android.os.Process.myPid()); - args.arg1 = sameProcessCall ? new Rect(frame) : frame; - args.arg2 = sameProcessCall ? new Rect(contentInsets) : contentInsets; - args.arg3 = sameProcessCall ? new Rect(visibleInsets) : visibleInsets; - args.arg4 = sameProcessCall && mergedConfiguration != null + args.arg1 = sameProcessCall ? new ClientWindowFrames(frames) : frames; + args.arg2 = sameProcessCall && mergedConfiguration != null ? new MergedConfiguration(mergedConfiguration) : mergedConfiguration; - args.arg6 = sameProcessCall ? new Rect(stableInsets) : stableInsets; - args.arg8 = sameProcessCall ? new Rect(backDropFrame) : backDropFrame; - args.arg9 = displayCutout.get(); // DisplayCutout is immutable. args.argi1 = forceLayout ? 1 : 0; args.argi2 = alwaysConsumeSystemBars ? 1 : 0; args.argi3 = displayId; @@ -9074,17 +9090,13 @@ public final class ViewRootImpl implements ViewParent, } @Override - public void resized(Rect frame, Rect contentInsets, - Rect visibleInsets, Rect stableInsets, boolean reportDraw, - MergedConfiguration mergedConfiguration, Rect backDropFrame, boolean forceLayout, - boolean alwaysConsumeSystemBars, int displayId, - DisplayCutout.ParcelableWrapper displayCutout) { + public void resized(ClientWindowFrames frames, boolean reportDraw, + MergedConfiguration mergedConfiguration, boolean forceLayout, + boolean alwaysConsumeSystemBars, int displayId) { final ViewRootImpl viewAncestor = mViewAncestor.get(); if (viewAncestor != null) { - viewAncestor.dispatchResized(frame, contentInsets, - visibleInsets, stableInsets, reportDraw, mergedConfiguration, - backDropFrame, forceLayout, alwaysConsumeSystemBars, displayId, - displayCutout); + viewAncestor.dispatchResized(frames, reportDraw, mergedConfiguration, forceLayout, + alwaysConsumeSystemBars, displayId); } } diff --git a/core/java/android/view/WindowlessWindowManager.java b/core/java/android/view/WindowlessWindowManager.java index 060311ec3da8..368918d28f80 100644 --- a/core/java/android/view/WindowlessWindowManager.java +++ b/core/java/android/view/WindowlessWindowManager.java @@ -26,6 +26,7 @@ import android.os.IBinder; import android.os.RemoteException; import android.util.Log; import android.util.MergedConfiguration; +import android.window.ClientWindowFrames; import java.util.HashMap; import java.util.Objects; @@ -224,9 +225,7 @@ public class WindowlessWindowManager implements IWindowSession { @Override public int relayout(IWindow window, int seq, WindowManager.LayoutParams inAttrs, int requestedWidth, int requestedHeight, int viewFlags, int flags, long frameNumber, - Rect outFrame, Rect outContentInsets, Rect outVisibleInsets, - Rect outStableInsets, Rect outBackdropFrame, - DisplayCutout.ParcelableWrapper cutout, MergedConfiguration mergedConfiguration, + ClientWindowFrames outFrames, MergedConfiguration mergedConfiguration, SurfaceControl outSurfaceControl, InsetsState outInsetsState, InsetsSourceControl[] outActiveControls, Point outSurfaceSize, SurfaceControl outBLASTSurfaceControl) { @@ -255,7 +254,8 @@ public class WindowlessWindowManager implements IWindowSession { t.hide(sc).apply(); outSurfaceControl.release(); } - outFrame.set(0, 0, attrs.width, attrs.height); + outFrames.frame.set(0, 0, attrs.width, attrs.height); + outFrames.displayFrame.set(outFrames.frame); mergedConfiguration.setConfiguration(mConfiguration, mConfiguration); @@ -292,11 +292,6 @@ public class WindowlessWindowManager implements IWindowSession { } @Override - public void getDisplayFrame(android.view.IWindow window, - android.graphics.Rect outDisplayFrame) { - } - - @Override public void finishDrawing(android.view.IWindow window, android.view.SurfaceControl.Transaction postDrawTransaction) { synchronized (this) { diff --git a/core/java/android/view/accessibility/MagnificationAnimationCallback.java b/core/java/android/view/accessibility/MagnificationAnimationCallback.java new file mode 100644 index 000000000000..491f7fb32a8c --- /dev/null +++ b/core/java/android/view/accessibility/MagnificationAnimationCallback.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2020 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.accessibility; + +/** + * A callback for magnification animation result. + * @hide + */ +public interface MagnificationAnimationCallback { + /** + * Called when the animation is finished or interrupted during animating. + * + * @param success {@code true} if animating successfully with given spec or the spec did not + * change. Otherwise {@code false} + */ + void onResult(boolean success); +} diff --git a/core/java/android/widget/TEST_MAPPING b/core/java/android/widget/TEST_MAPPING index df3024eda4b6..b5beac99d4e2 100644 --- a/core/java/android/widget/TEST_MAPPING +++ b/core/java/android/widget/TEST_MAPPING @@ -36,17 +36,6 @@ "name": "CtsAutoFillServiceTestCases", "options": [ { - "include-filter": "android.autofillservice.cts.AutofillValueTest" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] - }, - { - "name": "CtsAutoFillServiceTestCases", - "options": [ - { "include-filter": "android.autofillservice.cts.CheckoutActivityTest" }, { diff --git a/core/java/android/window/ClientWindowFrames.aidl b/core/java/android/window/ClientWindowFrames.aidl new file mode 100644 index 000000000000..22bbea90d35a --- /dev/null +++ b/core/java/android/window/ClientWindowFrames.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2020 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.window; + +parcelable ClientWindowFrames; diff --git a/core/java/android/window/ClientWindowFrames.java b/core/java/android/window/ClientWindowFrames.java new file mode 100644 index 000000000000..0523e64f3e7a --- /dev/null +++ b/core/java/android/window/ClientWindowFrames.java @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2020 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.window; + +import android.annotation.NonNull; +import android.graphics.Rect; +import android.os.Parcel; +import android.os.Parcelable; +import android.view.DisplayCutout; + +/** + * The window frame container class used by client side for layout. + * @hide + */ +public class ClientWindowFrames implements Parcelable { + /** The actual window bounds. */ + public final @NonNull Rect frame; + + /** + * The container frame that is usually the same as display size. It may exclude the area of + * insets if the window layout parameter has specified fit-insets-sides. + */ + public final @NonNull Rect displayFrame; + + /** The background area while the window is resizing. */ + public final @NonNull Rect backdropFrame; + + /** The area cut from the display. */ + public final @NonNull DisplayCutout.ParcelableWrapper displayCutout; + + // TODO(b/149813814): Remove legacy insets. + public final Rect contentInsets; + public final Rect visibleInsets; + public final Rect stableInsets; + + public ClientWindowFrames() { + frame = new Rect(); + displayFrame = new Rect(); + backdropFrame = new Rect(); + displayCutout = new DisplayCutout.ParcelableWrapper(); + contentInsets = new Rect(); + visibleInsets = new Rect(); + stableInsets = new Rect(); + } + + public ClientWindowFrames(ClientWindowFrames other) { + frame = new Rect(other.frame); + displayFrame = new Rect(other.displayFrame); + backdropFrame = new Rect(other.backdropFrame); + displayCutout = new DisplayCutout.ParcelableWrapper(other.displayCutout.get()); + contentInsets = new Rect(other.contentInsets); + visibleInsets = new Rect(other.visibleInsets); + stableInsets = new Rect(other.stableInsets); + } + + private ClientWindowFrames(Parcel in) { + frame = Rect.CREATOR.createFromParcel(in); + displayFrame = Rect.CREATOR.createFromParcel(in); + backdropFrame = Rect.CREATOR.createFromParcel(in); + displayCutout = DisplayCutout.ParcelableWrapper.CREATOR.createFromParcel(in); + contentInsets = Rect.CREATOR.createFromParcel(in); + visibleInsets = Rect.CREATOR.createFromParcel(in); + stableInsets = Rect.CREATOR.createFromParcel(in); + } + + /** Needed for AIDL out parameters. */ + public void readFromParcel(Parcel in) { + frame.set(Rect.CREATOR.createFromParcel(in)); + displayFrame.set(Rect.CREATOR.createFromParcel(in)); + backdropFrame.set(Rect.CREATOR.createFromParcel(in)); + displayCutout.set(DisplayCutout.ParcelableWrapper.CREATOR.createFromParcel(in)); + contentInsets.set(Rect.CREATOR.createFromParcel(in)); + visibleInsets.set(Rect.CREATOR.createFromParcel(in)); + stableInsets.set(Rect.CREATOR.createFromParcel(in)); + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + frame.writeToParcel(dest, flags); + displayFrame.writeToParcel(dest, flags); + backdropFrame.writeToParcel(dest, flags); + displayCutout.writeToParcel(dest, flags); + contentInsets.writeToParcel(dest, flags); + visibleInsets.writeToParcel(dest, flags); + stableInsets.writeToParcel(dest, flags); + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(32); + return "ClientWindowFrames{frame=" + frame.toShortString(sb) + + " display=" + displayFrame.toShortString(sb) + + " backdrop=" + backdropFrame.toShortString(sb) + + " cutout=" + displayCutout + "}"; + } + + @Override + public int describeContents() { + return 0; + } + + public static final Creator<ClientWindowFrames> CREATOR = new Creator<ClientWindowFrames>() { + public ClientWindowFrames createFromParcel(Parcel in) { + return new ClientWindowFrames(in); + } + + public ClientWindowFrames[] newArray(int size) { + return new ClientWindowFrames[size]; + } + }; +} diff --git a/core/java/android/window/VirtualDisplayTaskEmbedder.java b/core/java/android/window/VirtualDisplayTaskEmbedder.java index 9013da36007e..db27d6255de7 100644 --- a/core/java/android/window/VirtualDisplayTaskEmbedder.java +++ b/core/java/android/window/VirtualDisplayTaskEmbedder.java @@ -25,6 +25,7 @@ import static android.view.Display.INVALID_DISPLAY; import android.app.ActivityManager; import android.app.ActivityOptions; import android.app.ActivityTaskManager; +import android.app.ActivityTaskManager.RootTaskInfo; import android.app.ActivityView; import android.app.TaskStackListener; import android.content.ComponentName; @@ -357,40 +358,40 @@ public class VirtualDisplayTaskEmbedder extends TaskEmbedder { private class TaskStackListenerImpl extends TaskStackListener { @Override - public void onTaskDescriptionChanged(ActivityManager.RunningTaskInfo taskInfo) + public void onTaskDescriptionChanged(ActivityManager.RunningTaskInfo runningTaskInfo) throws RemoteException { if (!isInitialized()) { return; } - if (taskInfo.displayId != getDisplayId()) { + if (runningTaskInfo.displayId != getDisplayId()) { return; } - ActivityManager.StackInfo stackInfo = getTopMostStackInfo(); - if (stackInfo == null) { + RootTaskInfo taskInfo = getTopMostRootTaskInfo(); + if (taskInfo == null) { return; } // Found the topmost stack on target display. Now check if the topmost task's // description changed. - if (taskInfo.taskId == stackInfo.taskIds[stackInfo.taskIds.length - 1]) { + if (runningTaskInfo.taskId == taskInfo.childTaskIds[taskInfo.childTaskIds.length - 1]) { mHost.post(()-> mHost.onTaskBackgroundColorChanged(VirtualDisplayTaskEmbedder.this, - taskInfo.taskDescription.getBackgroundColor())); + runningTaskInfo.taskDescription.getBackgroundColor())); } } @Override - public void onTaskMovedToFront(ActivityManager.RunningTaskInfo taskInfo) + public void onTaskMovedToFront(ActivityManager.RunningTaskInfo runningTaskInfo) throws RemoteException { if (!isInitialized() || mListener == null - || taskInfo.displayId != getDisplayId()) { + || runningTaskInfo.displayId != getDisplayId()) { return; } - ActivityManager.StackInfo stackInfo = getTopMostStackInfo(); - // if StackInfo was null or unrelated to the "move to front" then there's no use + RootTaskInfo taskInfo = getTopMostRootTaskInfo(); + // if TaskInfo was null or unrelated to the "move to front" then there's no use // notifying the callback - if (stackInfo != null - && taskInfo.taskId == stackInfo.taskIds[stackInfo.taskIds.length - 1]) { - mListener.onTaskMovedToFront(taskInfo.taskId); + if (taskInfo != null && runningTaskInfo.taskId == taskInfo.childTaskIds[ + taskInfo.childTaskIds.length - 1]) { + mListener.onTaskMovedToFront(runningTaskInfo.taskId); } } @@ -400,11 +401,11 @@ public class VirtualDisplayTaskEmbedder extends TaskEmbedder { return; } - ActivityManager.StackInfo stackInfo = getTopMostStackInfo(); - // if StackInfo was null or unrelated to the task creation then there's no use + RootTaskInfo taskInfo = getTopMostRootTaskInfo(); + // if TaskInfo was null or unrelated to the task creation then there's no use // notifying the callback - if (stackInfo != null - && taskId == stackInfo.taskIds[stackInfo.taskIds.length - 1]) { + if (taskInfo != null + && taskId == taskInfo.childTaskIds[taskInfo.childTaskIds.length - 1]) { mListener.onTaskCreated(taskId, componentName); } } @@ -420,16 +421,16 @@ public class VirtualDisplayTaskEmbedder extends TaskEmbedder { mListener.onTaskRemovalStarted(taskInfo.taskId); } - private ActivityManager.StackInfo getTopMostStackInfo() throws RemoteException { + private RootTaskInfo getTopMostRootTaskInfo() throws RemoteException { // Find the topmost task on our virtual display - it will define the background // color of the surface view during resizing. final int displayId = getDisplayId(); - final List<ActivityManager.StackInfo> stackInfoList = - mActivityTaskManager.getAllStackInfosOnDisplay(displayId); - if (stackInfoList.isEmpty()) { + final List<RootTaskInfo> taskInfoList = + mActivityTaskManager.getAllRootTaskInfosOnDisplay(displayId); + if (taskInfoList.isEmpty()) { return null; } - return stackInfoList.get(0); + return taskInfoList.get(0); } } } diff --git a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java index da26930ca727..8b4fddbec03c 100644 --- a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java +++ b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java @@ -390,9 +390,9 @@ public final class SystemUiDeviceConfigFlags { public static final String CHOOSER_TARGET_RANKING_ENABLED = "chooser_target_ranking_enabled"; /** - * (boolean) Whether to enable user-drag resizing for PIP. + * (boolean) Whether to enable pinch resizing for PIP. */ - public static final String PIP_USER_RESIZE = "pip_user_resize"; + public static final String PIP_PINCH_RESIZE = "pip_pinch_resize"; /** * (float) Bottom height in DP for Back Gesture. diff --git a/core/java/com/android/internal/content/om/OverlayConfig.java b/core/java/com/android/internal/content/om/OverlayConfig.java index 3b5cf487c8da..b38f623e3a6d 100644 --- a/core/java/com/android/internal/content/om/OverlayConfig.java +++ b/core/java/com/android/internal/content/om/OverlayConfig.java @@ -296,7 +296,7 @@ public class OverlayConfig { if (p.getOverlayTarget() != null && isSystem) { overlays.add(new ParsedOverlayInfo(p.getPackageName(), p.getOverlayTarget(), p.getTargetSdkVersion(), p.isOverlayIsStatic(), p.getOverlayPriority(), - new File(p.getBaseCodePath()))); + new File(p.getBaseApkPath()))); } }); return overlays; diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index 84981515e133..41bf74ce9d61 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -256,7 +256,7 @@ public class BatteryStatsImpl extends BatteryStats { @GuardedBy("this") private long mNumBatchedSingleUidCpuTimeReads; @GuardedBy("this") - private long mCpuTimeReadsTrackingStartTime = SystemClock.uptimeMillis(); + private long mCpuTimeReadsTrackingStartTimeMs = SystemClock.uptimeMillis(); @GuardedBy("this") private int mNumUidsRemoved; @GuardedBy("this") @@ -290,7 +290,7 @@ public class BatteryStatsImpl extends BatteryStats { public final class UidToRemove { int startUid; int endUid; - long timeAddedInQueue; + long mTimeAddedInQueueMs; /** Remove just one UID */ public UidToRemove(int uid, long timestamp) { @@ -301,7 +301,7 @@ public class BatteryStatsImpl extends BatteryStats { public UidToRemove(int startUid, int endUid, long timestamp) { this.startUid = startUid; this.endUid = endUid; - timeAddedInQueue = timestamp; + mTimeAddedInQueueMs = timestamp; } void remove() { @@ -382,9 +382,9 @@ public class BatteryStatsImpl extends BatteryStats { } boolean changed = setChargingLocked(true); if (changed) { - final long uptime = mClocks.uptimeMillis(); - final long elapsedRealtime = mClocks.elapsedRealtime(); - addHistoryRecordLocked(elapsedRealtime, uptime); + final long uptimeMs = mClocks.uptimeMillis(); + final long elapsedRealtimeMs = mClocks.elapsedRealtime(); + addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); } } } @@ -502,9 +502,9 @@ public class BatteryStatsImpl extends BatteryStats { } public void clearPendingRemovedUids() { - long cutOffTime = mClocks.elapsedRealtime() - mConstants.UID_REMOVE_DELAY_MS; + long cutOffTimeMs = mClocks.elapsedRealtime() - mConstants.UID_REMOVE_DELAY_MS; while (!mPendingRemovedUids.isEmpty() - && mPendingRemovedUids.peek().timeAddedInQueue < cutOffTime) { + && mPendingRemovedUids.peek().mTimeAddedInQueueMs < cutOffTimeMs) { mPendingRemovedUids.poll().remove(); } } @@ -572,7 +572,7 @@ public class BatteryStatsImpl extends BatteryStats { } @VisibleForTesting - public long[] addCpuTimes(long[] timesA, long[] timesB) { + public static long[] addCpuTimes(long[] timesA, long[] timesB) { if (timesA != null && timesB != null) { for (int i = timesA.length - 1; i >= 0; --i) { timesA[i] += timesB[i]; @@ -700,7 +700,7 @@ public class BatteryStatsImpl extends BatteryStats { final HistoryEventTracker mActiveEvents = new HistoryEventTracker(); - long mHistoryBaseTime; + long mHistoryBaseTimeMs; protected boolean mHaveBatteryLevel = false; protected boolean mRecordingHistory = false; int mNumHistoryItems; @@ -719,9 +719,9 @@ public class BatteryStatsImpl extends BatteryStats { int mHistoryBufferLastPos = -1; int mActiveHistoryStates = 0xffffffff; int mActiveHistoryStates2 = 0xffffffff; - long mLastHistoryElapsedRealtime = 0; - long mTrackRunningHistoryElapsedRealtime = 0; - long mTrackRunningHistoryUptime = 0; + long mLastHistoryElapsedRealtimeMs = 0; + long mTrackRunningHistoryElapsedRealtimeMs = 0; + long mTrackRunningHistoryUptimeMs = 0; final BatteryStatsHistory mBatteryStatsHistory; @@ -742,28 +742,28 @@ public class BatteryStatsImpl extends BatteryStats { /** * Total time (in milliseconds) spent executing in user code. */ - long mLastStepCpuUserTime; - long mCurStepCpuUserTime; + long mLastStepCpuUserTimeMs; + long mCurStepCpuUserTimeMs; /** * Total time (in milliseconds) spent executing in kernel code. */ - long mLastStepCpuSystemTime; - long mCurStepCpuSystemTime; + long mLastStepCpuSystemTimeMs; + long mCurStepCpuSystemTimeMs; /** * Times from /proc/stat (but measured in milliseconds). */ - long mLastStepStatUserTime; - long mLastStepStatSystemTime; - long mLastStepStatIOWaitTime; - long mLastStepStatIrqTime; - long mLastStepStatSoftIrqTime; - long mLastStepStatIdleTime; - long mCurStepStatUserTime; - long mCurStepStatSystemTime; - long mCurStepStatIOWaitTime; - long mCurStepStatIrqTime; - long mCurStepStatSoftIrqTime; - long mCurStepStatIdleTime; + long mLastStepStatUserTimeMs; + long mLastStepStatSystemTimeMs; + long mLastStepStatIOWaitTimeMs; + long mLastStepStatIrqTimeMs; + long mLastStepStatSoftIrqTimeMs; + long mLastStepStatIdleTimeMs; + long mCurStepStatUserTimeMs; + long mCurStepStatSystemTimeMs; + long mCurStepStatIOWaitTimeMs; + long mCurStepStatIrqTimeMs; + long mCurStepStatSoftIrqTimeMs; + long mCurStepStatIdleTimeMs; private HistoryItem mHistoryIterator; private boolean mReadOverflow; @@ -771,14 +771,14 @@ public class BatteryStatsImpl extends BatteryStats { int mStartCount; - long mStartClockTime; + long mStartClockTimeMs; String mStartPlatformVersion; String mEndPlatformVersion; - long mUptime; - long mUptimeStart; - long mRealtime; - long mRealtimeStart; + long mUptimeUs; + long mUptimeStartUs; + long mRealtimeUs; + long mRealtimeStartUs; int mWakeLockNesting; boolean mWakeLockImportant; @@ -810,9 +810,9 @@ public class BatteryStatsImpl extends BatteryStats { StopwatchTimer mDeviceLightIdlingTimer; int mDeviceIdleMode; - long mLastIdleTimeStart; - long mLongestLightIdleTime; - long mLongestFullIdleTime; + long mLastIdleTimeStartMs; + long mLongestLightIdleTimeMs; + long mLongestFullIdleTimeMs; StopwatchTimer mDeviceIdleModeLightTimer; StopwatchTimer mDeviceIdleModeFullTimer; @@ -921,7 +921,7 @@ public class BatteryStatsImpl extends BatteryStats { protected StopwatchTimer mBluetoothScanTimer; int mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; - long mMobileRadioActiveStartTime; + long mMobileRadioActiveStartTimeMs; StopwatchTimer mMobileRadioActiveTimer; StopwatchTimer mMobileRadioActivePerAppTimer; LongSamplingCounter mMobileRadioActiveAdjustedTime; @@ -989,13 +989,13 @@ public class BatteryStatsImpl extends BatteryStats { static final int MAX_DAILY_ITEMS = 10; - long mDailyStartTime = 0; - long mNextMinDailyDeadline = 0; - long mNextMaxDailyDeadline = 0; + long mDailyStartTimeMs = 0; + long mNextMinDailyDeadlineMs = 0; + long mNextMaxDailyDeadlineMs = 0; final ArrayList<DailyItem> mDailyItems = new ArrayList<>(); - long mLastWriteTime = 0; // Milliseconds + long mLastWriteTimeMs = 0; // Milliseconds private int mPhoneServiceState = -1; private int mPhoneServiceStateRaw = -1; @@ -1131,8 +1131,8 @@ public class BatteryStatsImpl extends BatteryStats { * TimeBase observer. */ public interface TimeBaseObs { - void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime); - void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime); + void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs); + void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs); /** * Reset the observer's state, returns true if the timer/counter is inactive @@ -1140,7 +1140,18 @@ public class BatteryStatsImpl extends BatteryStats { * @param detachIfReset detach if true, no-op if false. * @return Returns true if the timer/counter is inactive and can be destroyed. */ - boolean reset(boolean detachIfReset); + default boolean reset(boolean detachIfReset) { + return reset(detachIfReset, SystemClock.elapsedRealtime() * 1000); + } + + /** + * @see #reset(boolean) + * @param detachIfReset detach if true, no-op if false. + * @param elapsedRealtimeUs the timestamp when this reset is actually reequested + * @return Returns true if the timer/counter is inactive and can be destroyed. + */ + boolean reset(boolean detachIfReset, long elapsedRealtimeUs); + /** * Detach the observer from TimeBase. */ @@ -1150,17 +1161,19 @@ public class BatteryStatsImpl extends BatteryStats { // methods are protected not private to be VisibleForTesting public static class TimeBase { protected final Collection<TimeBaseObs> mObservers; - protected long mUptime; - protected long mRealtime; + + // All below time metrics are in microseconds. + protected long mUptimeUs; + protected long mRealtimeUs; protected boolean mRunning; - protected long mPastUptime; - protected long mUptimeStart; - protected long mPastRealtime; - protected long mRealtimeStart; - protected long mUnpluggedUptime; - protected long mUnpluggedRealtime; + protected long mPastUptimeUs; + protected long mUptimeStartUs; + protected long mPastRealtimeUs; + protected long mRealtimeStartUs; + protected long mUnpluggedUptimeUs; + protected long mUnpluggedRealtimeUs; public void dump(PrintWriter pw, String prefix) { StringBuilder sb = new StringBuilder(128); @@ -1168,26 +1181,26 @@ public class BatteryStatsImpl extends BatteryStats { sb.setLength(0); sb.append(prefix); sb.append("mUptime="); - formatTimeMs(sb, mUptime / 1000); + formatTimeMs(sb, mUptimeUs / 1000); pw.println(sb.toString()); sb.setLength(0); sb.append(prefix); sb.append("mRealtime="); - formatTimeMs(sb, mRealtime / 1000); + formatTimeMs(sb, mRealtimeUs / 1000); pw.println(sb.toString()); sb.setLength(0); sb.append(prefix); sb.append("mPastUptime="); - formatTimeMs(sb, mPastUptime / 1000); sb.append("mUptimeStart="); - formatTimeMs(sb, mUptimeStart / 1000); - sb.append("mUnpluggedUptime="); formatTimeMs(sb, mUnpluggedUptime / 1000); + formatTimeMs(sb, mPastUptimeUs / 1000); sb.append("mUptimeStart="); + formatTimeMs(sb, mUptimeStartUs / 1000); + sb.append("mUnpluggedUptime="); formatTimeMs(sb, mUnpluggedUptimeUs / 1000); pw.println(sb.toString()); sb.setLength(0); sb.append(prefix); sb.append("mPastRealtime="); - formatTimeMs(sb, mPastRealtime / 1000); sb.append("mRealtimeStart="); - formatTimeMs(sb, mRealtimeStart / 1000); - sb.append("mUnpluggedRealtime="); formatTimeMs(sb, mUnpluggedRealtime / 1000); + formatTimeMs(sb, mPastRealtimeUs / 1000); sb.append("mRealtimeStart="); + formatTimeMs(sb, mRealtimeStartUs / 1000); + sb.append("mUnpluggedRealtime="); formatTimeMs(sb, mUnpluggedRealtimeUs / 1000); pw.println(sb.toString()); } /** @@ -1219,94 +1232,96 @@ public class BatteryStatsImpl extends BatteryStats { return mObservers.contains(observer); } - public void init(long uptime, long realtime) { - mRealtime = 0; - mUptime = 0; - mPastUptime = 0; - mPastRealtime = 0; - mUptimeStart = uptime; - mRealtimeStart = realtime; - mUnpluggedUptime = getUptime(mUptimeStart); - mUnpluggedRealtime = getRealtime(mRealtimeStart); + public void init(long uptimeUs, long elapsedRealtimeUs) { + mRealtimeUs = 0; + mUptimeUs = 0; + mPastUptimeUs = 0; + mPastRealtimeUs = 0; + mUptimeStartUs = uptimeUs; + mRealtimeStartUs = elapsedRealtimeUs; + mUnpluggedUptimeUs = getUptime(mUptimeStartUs); + mUnpluggedRealtimeUs = getRealtime(mRealtimeStartUs); } - public void reset(long uptime, long realtime) { + public void reset(long uptimeUs, long elapsedRealtimeUs) { if (!mRunning) { - mPastUptime = 0; - mPastRealtime = 0; - } else { - mUptimeStart = uptime; - mRealtimeStart = realtime; - // TODO: Since mUptimeStart was just reset and we are running, getUptime will - // just return mPastUptime. Also, are we sure we don't want to reset that? - mUnpluggedUptime = getUptime(uptime); + mPastUptimeUs = 0; + mPastRealtimeUs = 0; + } else { + mUptimeStartUs = uptimeUs; + mRealtimeStartUs = elapsedRealtimeUs; + // TODO: Since mUptimeStartUs was just reset and we are running, getUptime will + // just return mPastUptimeUs. Also, are we sure we don't want to reset that? + mUnpluggedUptimeUs = getUptime(uptimeUs); // TODO: likewise. - mUnpluggedRealtime = getRealtime(realtime); + mUnpluggedRealtimeUs = getRealtime(elapsedRealtimeUs); } } - public long computeUptime(long curTime, int which) { - return mUptime + getUptime(curTime); + public long computeUptime(long curTimeUs, int which) { + return mUptimeUs + getUptime(curTimeUs); } - public long computeRealtime(long curTime, int which) { - return mRealtime + getRealtime(curTime); + public long computeRealtime(long curTimeUs, int which) { + return mRealtimeUs + getRealtime(curTimeUs); } - public long getUptime(long curTime) { - long time = mPastUptime; + public long getUptime(long curTimeUs) { + long time = mPastUptimeUs; if (mRunning) { - time += curTime - mUptimeStart; + time += curTimeUs - mUptimeStartUs; } return time; } - public long getRealtime(long curTime) { - long time = mPastRealtime; + public long getRealtime(long curTimeUs) { + long time = mPastRealtimeUs; if (mRunning) { - time += curTime - mRealtimeStart; + time += curTimeUs - mRealtimeStartUs; } return time; } public long getUptimeStart() { - return mUptimeStart; + return mUptimeStartUs; } public long getRealtimeStart() { - return mRealtimeStart; + return mRealtimeStartUs; } public boolean isRunning() { return mRunning; } - public boolean setRunning(boolean running, long uptime, long realtime) { + public boolean setRunning(boolean running, long uptimeUs, long elapsedRealtimeUs) { if (mRunning != running) { mRunning = running; if (running) { - mUptimeStart = uptime; - mRealtimeStart = realtime; - long batteryUptime = mUnpluggedUptime = getUptime(uptime); - long batteryRealtime = mUnpluggedRealtime = getRealtime(realtime); + mUptimeStartUs = uptimeUs; + mRealtimeStartUs = elapsedRealtimeUs; + long batteryUptimeUs = mUnpluggedUptimeUs = getUptime(uptimeUs); + long batteryRealtimeUs = mUnpluggedRealtimeUs = getRealtime(elapsedRealtimeUs); // Normally we do not use Iterator in framework code to avoid alloc/dealloc // Iterator object, here is an exception because mObservers' type is Collection // instead of list. final Iterator<TimeBaseObs> iter = mObservers.iterator(); while (iter.hasNext()) { - iter.next().onTimeStarted(realtime, batteryUptime, batteryRealtime); + iter.next().onTimeStarted( + elapsedRealtimeUs, batteryUptimeUs, batteryRealtimeUs); } } else { - mPastUptime += uptime - mUptimeStart; - mPastRealtime += realtime - mRealtimeStart; - long batteryUptime = getUptime(uptime); - long batteryRealtime = getRealtime(realtime); + mPastUptimeUs += uptimeUs - mUptimeStartUs; + mPastRealtimeUs += elapsedRealtimeUs - mRealtimeStartUs; + long batteryUptimeUs = getUptime(uptimeUs); + long batteryRealtimeUs = getRealtime(elapsedRealtimeUs); // Normally we do not use Iterator in framework code to avoid alloc/dealloc // Iterator object, here is an exception because mObservers' type is Collection // instead of list. final Iterator<TimeBaseObs> iter = mObservers.iterator(); while (iter.hasNext()) { - iter.next().onTimeStopped(realtime, batteryUptime, batteryRealtime); + iter.next().onTimeStopped( + elapsedRealtimeUs, batteryUptimeUs, batteryRealtimeUs); } } return true; @@ -1315,38 +1330,38 @@ public class BatteryStatsImpl extends BatteryStats { } public void readSummaryFromParcel(Parcel in) { - mUptime = in.readLong(); - mRealtime = in.readLong(); + mUptimeUs = in.readLong(); + mRealtimeUs = in.readLong(); } - public void writeSummaryToParcel(Parcel out, long uptime, long realtime) { - out.writeLong(computeUptime(uptime, STATS_SINCE_CHARGED)); - out.writeLong(computeRealtime(realtime, STATS_SINCE_CHARGED)); + public void writeSummaryToParcel(Parcel out, long uptimeUs, long elapsedRealtimeUs) { + out.writeLong(computeUptime(uptimeUs, STATS_SINCE_CHARGED)); + out.writeLong(computeRealtime(elapsedRealtimeUs, STATS_SINCE_CHARGED)); } public void readFromParcel(Parcel in) { mRunning = false; - mUptime = in.readLong(); - mPastUptime = in.readLong(); - mUptimeStart = in.readLong(); - mRealtime = in.readLong(); - mPastRealtime = in.readLong(); - mRealtimeStart = in.readLong(); - mUnpluggedUptime = in.readLong(); - mUnpluggedRealtime = in.readLong(); - } - - public void writeToParcel(Parcel out, long uptime, long realtime) { - final long runningUptime = getUptime(uptime); - final long runningRealtime = getRealtime(realtime); - out.writeLong(mUptime); + mUptimeUs = in.readLong(); + mPastUptimeUs = in.readLong(); + mUptimeStartUs = in.readLong(); + mRealtimeUs = in.readLong(); + mPastRealtimeUs = in.readLong(); + mRealtimeStartUs = in.readLong(); + mUnpluggedUptimeUs = in.readLong(); + mUnpluggedRealtimeUs = in.readLong(); + } + + public void writeToParcel(Parcel out, long uptimeUs, long elapsedRealtimeUs) { + final long runningUptime = getUptime(uptimeUs); + final long runningRealtime = getRealtime(elapsedRealtimeUs); + out.writeLong(mUptimeUs); out.writeLong(runningUptime); - out.writeLong(mUptimeStart); - out.writeLong(mRealtime); + out.writeLong(mUptimeStartUs); + out.writeLong(mRealtimeUs); out.writeLong(runningRealtime); - out.writeLong(mRealtimeStart); - out.writeLong(mUnpluggedUptime); - out.writeLong(mUnpluggedRealtime); + out.writeLong(mRealtimeStartUs); + out.writeLong(mUnpluggedUptimeUs); + out.writeLong(mUnpluggedRealtimeUs); } } @@ -1374,11 +1389,11 @@ public class BatteryStatsImpl extends BatteryStats { } @Override - public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) { + public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { } @Override - public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { + public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { } /** @@ -1436,7 +1451,7 @@ public class BatteryStatsImpl extends BatteryStats { * Clear state of this counter. */ @Override - public boolean reset(boolean detachIfReset) { + public boolean reset(boolean detachIfReset, long elapsedRealtimeUs /* unused */) { mCount.set(0); if (detachIfReset) { detach(); @@ -1481,11 +1496,11 @@ public class BatteryStatsImpl extends BatteryStats { } @Override - public void onTimeStarted(long elapsedRealTime, long baseUptime, long baseRealtime) { + public void onTimeStarted(long elapsedRealTimeUs, long baseUptimeUs, long baseRealtimeUs) { } @Override - public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { + public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { } @Override @@ -1524,7 +1539,7 @@ public class BatteryStatsImpl extends BatteryStats { * Clear state of this counter. */ @Override - public boolean reset(boolean detachIfReset) { + public boolean reset(boolean detachIfReset, long elapsedRealtimeUs /* unused */) { if (mCounts != null) { Arrays.fill(mCounts, 0); } @@ -1608,11 +1623,11 @@ public class BatteryStatsImpl extends BatteryStats { } @Override - public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) { + public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { } @Override - public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { + public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { } public long getCountLocked(int which) { @@ -1638,7 +1653,7 @@ public class BatteryStatsImpl extends BatteryStats { * Clear state of this counter. */ @Override - public boolean reset(boolean detachIfReset) { + public boolean reset(boolean detachIfReset, long elapsedRealtimeUs /* unused */) { mCount = 0; if (detachIfReset) { detach(); @@ -1678,13 +1693,13 @@ public class BatteryStatsImpl extends BatteryStats { * boot, to the last time something interesting happened in the * current run. */ - protected long mTotalTime; + protected long mTotalTimeUs; /** * 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. + * Subtract this from mTotalTimeUs to get the time spent running since the mark was set. */ - protected long mTimeBeforeMark; + protected long mTimeBeforeMarkUs; /** * Constructs from a parcel. @@ -1698,10 +1713,10 @@ public class BatteryStatsImpl extends BatteryStats { mTimeBase = timeBase; mCount = in.readInt(); - mTotalTime = in.readLong(); - mTimeBeforeMark = in.readLong(); + mTotalTimeUs = in.readLong(); + mTimeBeforeMarkUs = in.readLong(); timeBase.add(this); - if (DEBUG) Log.i(TAG, "**** READ TIMER #" + mType + ": mTotalTime=" + mTotalTime); + if (DEBUG) Log.i(TAG, "**** READ TIMER #" + mType + ": mTotalTime=" + mTotalTimeUs); } public Timer(Clocks clocks, int type, TimeBase timeBase) { @@ -1714,14 +1729,17 @@ public class BatteryStatsImpl extends BatteryStats { public void writeToParcel(Parcel out, long elapsedRealtimeUs) { if (DEBUG) { Log.i(TAG, "**** WRITING TIMER #" + mType + ": mTotalTime=" - + computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs))); + + computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs), + elapsedRealtimeUs)); } out.writeInt(computeCurrentCountLocked()); - out.writeLong(computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs))); - out.writeLong(mTimeBeforeMark); + out.writeLong(computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs), + elapsedRealtimeUs)); + out.writeLong(mTimeBeforeMarkUs); } - protected abstract long computeRunTimeLocked(long curBatteryRealtime); + protected abstract long computeRunTimeLocked(long curBatteryRealtime, + long elapsedRealtimeUs); protected abstract int computeCurrentCountLocked(); @@ -1731,7 +1749,12 @@ public class BatteryStatsImpl extends BatteryStats { */ @Override public boolean reset(boolean detachIfReset) { - mTotalTime = mTimeBeforeMark = 0; + return reset(detachIfReset, mClocks.elapsedRealtime() * 1000); + } + + @Override + public boolean reset(boolean detachIfReset, long elapsedRealtimeUs /* unused */) { + mTotalTimeUs = mTimeBeforeMarkUs = 0; mCount = 0; if (detachIfReset) { detach(); @@ -1745,19 +1768,20 @@ public class BatteryStatsImpl extends BatteryStats { } @Override - public void onTimeStarted(long elapsedRealtime, long timeBaseUptime, long baseRealtime) { + public void onTimeStarted(long elapsedRealtimeUs, long timeBaseUptimeUs, + long baseRealtimeUs) { } @Override - public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { + public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { if (DEBUG && mType < 0) { - Log.v(TAG, "plug #" + mType + ": realtime=" + baseRealtime - + " old mTotalTime=" + mTotalTime); + Log.v(TAG, "plug #" + mType + ": realtime=" + baseRealtimeUs + + " old mTotalTime=" + mTotalTimeUs); } - mTotalTime = computeRunTimeLocked(baseRealtime); + mTotalTimeUs = computeRunTimeLocked(baseRealtimeUs, elapsedRealtimeUs); mCount = computeCurrentCountLocked(); if (DEBUG && mType < 0) { - Log.v(TAG, "plug #" + mType + ": new mTotalTime=" + mTotalTime); + Log.v(TAG, "plug #" + mType + ": new mTotalTime=" + mTotalTimeUs); } } @@ -1780,7 +1804,8 @@ public class BatteryStatsImpl extends BatteryStats { @Override @UnsupportedAppUsage public long getTotalTimeLocked(long elapsedRealtimeUs, int which) { - return computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs)); + return computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs), + elapsedRealtimeUs); } @Override @@ -1791,29 +1816,31 @@ public class BatteryStatsImpl extends BatteryStats { @Override public long getTimeSinceMarkLocked(long elapsedRealtimeUs) { - long val = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs)); - return val - mTimeBeforeMark; + long val = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs), + elapsedRealtimeUs); + return val - mTimeBeforeMarkUs; } @Override public void logState(Printer pw, String prefix) { pw.println(prefix + "mCount=" + mCount); - pw.println(prefix + "mTotalTime=" + mTotalTime); + pw.println(prefix + "mTotalTime=" + mTotalTimeUs); } public void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) { - long runTime = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs)); - out.writeLong(runTime); + long runTimeUs = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs), + elapsedRealtimeUs); + out.writeLong(runTimeUs); out.writeInt(computeCurrentCountLocked()); } public void readSummaryFromParcelLocked(Parcel in) { // Multiply by 1000 for backwards compatibility - mTotalTime = in.readLong(); + mTotalTimeUs = in.readLong(); mCount = in.readInt(); // When reading the summary, we set the mark to be the latest information. - mTimeBeforeMark = mTotalTime; + mTimeBeforeMarkUs = mTotalTimeUs; } } @@ -1843,14 +1870,14 @@ public class BatteryStatsImpl extends BatteryStats { /** * The most recent reported total_time from /proc/wakelocks. */ - long mCurrentReportedTotalTime; + long mCurrentReportedTotalTimeUs; /** * The reported total_time from /proc/wakelocks when unplug() was last * called. */ - long mUnpluggedReportedTotalTime; + long mUnpluggedReportedTotalTimeUs; /** * Whether we are currently in a discharge cycle. @@ -1872,8 +1899,8 @@ public class BatteryStatsImpl extends BatteryStats { super(clocks, 0, timeBase, in); mCurrentReportedCount = in.readInt(); mUnpluggedReportedCount = in.readInt(); - mCurrentReportedTotalTime = in.readLong(); - mUnpluggedReportedTotalTime = in.readLong(); + mCurrentReportedTotalTimeUs = in.readLong(); + mUnpluggedReportedTotalTimeUs = in.readLong(); mTrackingReportedValues = in.readInt() == 1; mTimeBaseRunning = timeBase.isRunning(); } @@ -1890,9 +1917,16 @@ public class BatteryStatsImpl extends BatteryStats { * be less than the values used for a previous invocation. */ public void endSample() { - mTotalTime = computeRunTimeLocked(0 /* unused by us */); + endSample(mClocks.elapsedRealtime() * 1000); + } + + /** + * @see #endSample() + */ + public void endSample(long elapsedRealtimeUs) { + mTotalTimeUs = computeRunTimeLocked(0 /* unused by us */, elapsedRealtimeUs); mCount = computeCurrentCountLocked(); - mUnpluggedReportedTotalTime = mCurrentReportedTotalTime = 0; + mUnpluggedReportedTotalTimeUs = mCurrentReportedTotalTimeUs = 0; mUnpluggedReportedCount = mCurrentReportedCount = 0; mTrackingReportedValues = false; } @@ -1911,26 +1945,33 @@ public class BatteryStatsImpl extends BatteryStats { * * If the values being recorded have been reset, the monotonically increasing requirement * will be broken. In this case, {@link #endSample()} is automatically called and - * the total value of totalTime and count are recorded, starting a new monotonically + * the total value of totalTimeUs and count are recorded, starting a new monotonically * increasing sample. * - * @param totalTime total time of sample in microseconds. + * @param totalTimeUs total time of sample in microseconds. * @param count total number of times the event being sampled occurred. */ - public void update(long totalTime, int count) { + public void updated(long totalTimeUs, int count) { + update(totalTimeUs, count, mClocks.elapsedRealtime() * 1000); + } + + /** + * @see #update(long, int) + */ + public void update(long totalTimeUs, int count, long elapsedRealtimeUs) { if (mTimeBaseRunning && !mTrackingReportedValues) { // Updating the reported value for the first time. - mUnpluggedReportedTotalTime = totalTime; + mUnpluggedReportedTotalTimeUs = totalTimeUs; mUnpluggedReportedCount = count; } mTrackingReportedValues = true; - if (totalTime < mCurrentReportedTotalTime || count < mCurrentReportedCount) { - endSample(); + if (totalTimeUs < mCurrentReportedTotalTimeUs || count < mCurrentReportedCount) { + endSample(elapsedRealtimeUs); } - mCurrentReportedTotalTime = totalTime; + mCurrentReportedTotalTimeUs = totalTimeUs; mCurrentReportedCount = count; } @@ -1940,23 +1981,31 @@ public class BatteryStatsImpl extends BatteryStats { * @param deltaTime additional time recorded since the last sampled event, in microseconds. * @param deltaCount additional number of times the event being sampled occurred. */ - public void add(long deltaTime, int deltaCount) { - update(mCurrentReportedTotalTime + deltaTime, mCurrentReportedCount + deltaCount); + public void add(long deltaTimeUs, int deltaCount) { + add(deltaTimeUs, deltaCount, mClocks.elapsedRealtime() * 1000); + } + + /** + * @see #add(long, int) + */ + public void add(long deltaTimeUs, int deltaCount, long elapsedRealtimeUs) { + update(mCurrentReportedTotalTimeUs + deltaTimeUs, mCurrentReportedCount + deltaCount, + elapsedRealtimeUs); } @Override - public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) { - super.onTimeStarted(elapsedRealtime, baseUptime, baseRealtime); + public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { + super.onTimeStarted(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); if (mTrackingReportedValues) { - mUnpluggedReportedTotalTime = mCurrentReportedTotalTime; + mUnpluggedReportedTotalTimeUs = mCurrentReportedTotalTimeUs; mUnpluggedReportedCount = mCurrentReportedCount; } mTimeBaseRunning = true; } @Override - public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { - super.onTimeStopped(elapsedRealtime, baseUptime, baseRealtime); + public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { + super.onTimeStopped(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); mTimeBaseRunning = false; } @@ -1965,14 +2014,14 @@ public class BatteryStatsImpl extends BatteryStats { super.logState(pw, prefix); pw.println(prefix + "mCurrentReportedCount=" + mCurrentReportedCount + " mUnpluggedReportedCount=" + mUnpluggedReportedCount - + " mCurrentReportedTotalTime=" + mCurrentReportedTotalTime - + " mUnpluggedReportedTotalTime=" + mUnpluggedReportedTotalTime); + + " mCurrentReportedTotalTime=" + mCurrentReportedTotalTimeUs + + " mUnpluggedReportedTotalTime=" + mUnpluggedReportedTotalTimeUs); } @Override - protected long computeRunTimeLocked(long curBatteryRealtime) { - return mTotalTime + (mTimeBaseRunning && mTrackingReportedValues - ? mCurrentReportedTotalTime - mUnpluggedReportedTotalTime : 0); + protected long computeRunTimeLocked(long curBatteryRealtime, long elapsedRealtimeUs) { + return mTotalTimeUs + (mTimeBaseRunning && mTrackingReportedValues + ? mCurrentReportedTotalTimeUs - mUnpluggedReportedTotalTimeUs : 0); } @Override @@ -1986,16 +2035,16 @@ public class BatteryStatsImpl extends BatteryStats { super.writeToParcel(out, elapsedRealtimeUs); out.writeInt(mCurrentReportedCount); out.writeInt(mUnpluggedReportedCount); - out.writeLong(mCurrentReportedTotalTime); - out.writeLong(mUnpluggedReportedTotalTime); + out.writeLong(mCurrentReportedTotalTimeUs); + out.writeLong(mUnpluggedReportedTotalTimeUs); out.writeInt(mTrackingReportedValues ? 1 : 0); } @Override - public boolean reset(boolean detachIfReset) { - super.reset(detachIfReset); + public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { + super.reset(detachIfReset, elapsedRealtimeUs); mTrackingReportedValues = false; - mUnpluggedReportedTotalTime = 0; + mUnpluggedReportedTotalTimeUs = 0; mUnpluggedReportedCount = 0; return true; } @@ -2011,12 +2060,12 @@ public class BatteryStatsImpl extends BatteryStats { /** * The last time at which we updated the timer. This is in elapsed realtime microseconds. */ - long mLastAddedTime; + long mLastAddedTimeUs; /** * The last duration that we added to the timer. This is in microseconds. */ - long mLastAddedDuration; + long mLastAddedDurationUs; /** * Whether we are currently in a discharge cycle. @@ -2026,8 +2075,8 @@ public class BatteryStatsImpl extends BatteryStats { BatchTimer(Clocks clocks, Uid uid, int type, TimeBase timeBase, Parcel in) { super(clocks, type, timeBase, in); mUid = uid; - mLastAddedTime = in.readLong(); - mLastAddedDuration = in.readLong(); + mLastAddedTimeUs = in.readLong(); + mLastAddedDurationUs = in.readLong(); mInDischarge = timeBase.isRunning(); } @@ -2040,74 +2089,82 @@ public class BatteryStatsImpl extends BatteryStats { @Override public void writeToParcel(Parcel out, long elapsedRealtimeUs) { super.writeToParcel(out, elapsedRealtimeUs); - out.writeLong(mLastAddedTime); - out.writeLong(mLastAddedDuration); + out.writeLong(mLastAddedTimeUs); + out.writeLong(mLastAddedDurationUs); } @Override - public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { - recomputeLastDuration(mClocks.elapsedRealtime() * 1000, false); + public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { + recomputeLastDuration(elapsedRealtimeUs, false); mInDischarge = false; - super.onTimeStopped(elapsedRealtime, baseUptime, baseRealtime); + super.onTimeStopped(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); } @Override - public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) { - recomputeLastDuration(elapsedRealtime, false); + public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { + recomputeLastDuration(elapsedRealtimeUs, false); mInDischarge = true; // If we are still within the last added duration, then re-added whatever remains. - if (mLastAddedTime == elapsedRealtime) { - mTotalTime += mLastAddedDuration; + if (mLastAddedTimeUs == elapsedRealtimeUs) { + mTotalTimeUs += mLastAddedDurationUs; } - super.onTimeStarted(elapsedRealtime, baseUptime, baseRealtime); + super.onTimeStarted(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); } @Override public void logState(Printer pw, String prefix) { super.logState(pw, prefix); - pw.println(prefix + "mLastAddedTime=" + mLastAddedTime - + " mLastAddedDuration=" + mLastAddedDuration); + pw.println(prefix + "mLastAddedTime=" + mLastAddedTimeUs + + " mLastAddedDuration=" + mLastAddedDurationUs); } - private long computeOverage(long curTime) { - if (mLastAddedTime > 0) { - return mLastAddedDuration - curTime; + private long computeOverage(long curTimeUs) { + if (mLastAddedTimeUs > 0) { + return mLastAddedDurationUs - curTimeUs; } return 0; } - private void recomputeLastDuration(long curTime, boolean abort) { - final long overage = computeOverage(curTime); + private void recomputeLastDuration(long curTimeUs, boolean abort) { + final long overage = computeOverage(curTimeUs); if (overage > 0) { // Aborting before the duration ran out -- roll back the remaining // duration. Only do this if currently discharging; otherwise we didn't // actually add the time. if (mInDischarge) { - mTotalTime -= overage; + mTotalTimeUs -= overage; } if (abort) { - mLastAddedTime = 0; + mLastAddedTimeUs = 0; } else { - mLastAddedTime = curTime; - mLastAddedDuration -= overage; + mLastAddedTimeUs = curTimeUs; + mLastAddedDurationUs -= overage; } } } - public void addDuration(BatteryStatsImpl stats, long durationMillis) { - final long now = mClocks.elapsedRealtime() * 1000; - recomputeLastDuration(now, true); - mLastAddedTime = now; - mLastAddedDuration = durationMillis * 1000; + public void addDuration(BatteryStatsImpl stats, long durationMs) { + addDuration(stats, durationMs, mClocks.elapsedRealtime()); + } + + public void addDuration(BatteryStatsImpl stats, long durationMs, long elapsedRealtimeMs) { + final long nowUs = elapsedRealtimeMs * 1000; + recomputeLastDuration(nowUs, true); + mLastAddedTimeUs = nowUs; + mLastAddedDurationUs = durationMs * 1000; if (mInDischarge) { - mTotalTime += mLastAddedDuration; + mTotalTimeUs += mLastAddedDurationUs; mCount++; } } public void abortLastDuration(BatteryStatsImpl stats) { - final long now = mClocks.elapsedRealtime() * 1000; - recomputeLastDuration(now, true); + abortLastDuration(stats, mClocks.elapsedRealtime()); + } + + public void abortLastDuration(BatteryStatsImpl stats, long elapsedRealtimeMs) { + final long nowUs = elapsedRealtimeMs * 1000; + recomputeLastDuration(nowUs, true); } @Override @@ -2116,20 +2173,19 @@ public class BatteryStatsImpl extends BatteryStats { } @Override - protected long computeRunTimeLocked(long curBatteryRealtime) { - final long overage = computeOverage(mClocks.elapsedRealtime() * 1000); + protected long computeRunTimeLocked(long curBatteryRealtimeUs, long elapsedRealtimeUs) { + final long overage = computeOverage(elapsedRealtimeUs); if (overage > 0) { - return mTotalTime = overage; + return mTotalTimeUs = overage; } - return mTotalTime; + return mTotalTimeUs; } @Override - public boolean reset(boolean detachIfReset) { - final long now = mClocks.elapsedRealtime() * 1000; - recomputeLastDuration(now, true); - boolean stillActive = mLastAddedTime == now; - super.reset(!stillActive && detachIfReset); + public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { + recomputeLastDuration(elapsedRealtimeUs, true); + boolean stillActive = mLastAddedTimeUs == elapsedRealtimeUs; + super.reset(!stillActive && detachIfReset, elapsedRealtimeUs); return !stillActive; } } @@ -2225,10 +2281,10 @@ public class BatteryStatsImpl extends BatteryStats { * * If the timer is also running, store the start time. */ - public void onTimeStarted(long elapsedRealtimeUs, long baseUptime, long baseRealtime) { - super.onTimeStarted(elapsedRealtimeUs, baseUptime, baseRealtime); + public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { + super.onTimeStarted(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); if (mNesting > 0) { - mStartTimeMs = baseRealtime / 1000; + mStartTimeMs = baseRealtimeUs / 1000; } } @@ -2238,8 +2294,8 @@ public class BatteryStatsImpl extends BatteryStats { * If the timer is running, add the duration into mCurrentDurationMs. */ @Override - public void onTimeStopped(long elapsedRealtimeUs, long baseUptime, long baseRealtimeUs) { - super.onTimeStopped(elapsedRealtimeUs, baseUptime, baseRealtimeUs); + public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { + super.onTimeStopped(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); if (mNesting > 0) { // baseRealtimeUs has already been converted to the timebase's realtime. mCurrentDurationMs += (baseRealtimeUs / 1000) - mStartTimeMs; @@ -2284,13 +2340,13 @@ public class BatteryStatsImpl extends BatteryStats { } @Override - public boolean reset(boolean detachIfReset) { - boolean result = super.reset(detachIfReset); + public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { + boolean result = super.reset(detachIfReset, elapsedRealtimeUs); mMaxDurationMs = 0; mTotalDurationMs = 0; mCurrentDurationMs = 0; if (mNesting > 0) { - mStartTimeMs = mTimeBase.getRealtime(mClocks.elapsedRealtime() * 1000) / 1000; + mStartTimeMs = mTimeBase.getRealtime(elapsedRealtimeUs) / 1000; } else { mStartTimeMs = -1; } @@ -2364,16 +2420,16 @@ public class BatteryStatsImpl extends BatteryStats { * subtract this from the current battery time to find the amount of * time we have been running since we last computed an update. */ - long mUpdateTime; + long mUpdateTimeUs; /** * The total time at which the timer was acquired, to determine if it * was actually held for an interesting duration. If time base was not running when timer * was acquired, will be -1. */ - long mAcquireTime = -1; + long mAcquireTimeUs = -1; - long mTimeout; + long mTimeoutUs; /** * For partial wake locks, keep track of whether we are in the list @@ -2387,7 +2443,7 @@ public class BatteryStatsImpl extends BatteryStats { super(clocks, type, timeBase, in); mUid = uid; mTimerPool = timerPool; - mUpdateTime = in.readLong(); + mUpdateTimeUs = in.readLong(); } public StopwatchTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool, @@ -2397,56 +2453,56 @@ public class BatteryStatsImpl extends BatteryStats { mTimerPool = timerPool; } - public void setTimeout(long timeout) { - mTimeout = timeout; + public void setTimeout(long timeoutUs) { + mTimeoutUs = timeoutUs; } public void writeToParcel(Parcel out, long elapsedRealtimeUs) { super.writeToParcel(out, elapsedRealtimeUs); - out.writeLong(mUpdateTime); + out.writeLong(mUpdateTimeUs); } - public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { + public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { if (mNesting > 0) { if (DEBUG && mType < 0) { - Log.v(TAG, "old mUpdateTime=" + mUpdateTime); + Log.v(TAG, "old mUpdateTime=" + mUpdateTimeUs); } - super.onTimeStopped(elapsedRealtime, baseUptime, baseRealtime); - mUpdateTime = baseRealtime; + super.onTimeStopped(elapsedRealtimeUs, baseUptimeUs, baseRealtimeUs); + mUpdateTimeUs = baseRealtimeUs; if (DEBUG && mType < 0) { - Log.v(TAG, "new mUpdateTime=" + mUpdateTime); + Log.v(TAG, "new mUpdateTime=" + mUpdateTimeUs); } } } public void logState(Printer pw, String prefix) { super.logState(pw, prefix); - pw.println(prefix + "mNesting=" + mNesting + " mUpdateTime=" + mUpdateTime - + " mAcquireTime=" + mAcquireTime); + pw.println(prefix + "mNesting=" + mNesting + " mUpdateTime=" + mUpdateTimeUs + + " mAcquireTime=" + mAcquireTimeUs); } public void startRunningLocked(long elapsedRealtimeMs) { if (mNesting++ == 0) { - final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000); - mUpdateTime = batteryRealtime; + final long batteryRealtimeUs = mTimeBase.getRealtime(elapsedRealtimeMs * 1000); + mUpdateTimeUs = batteryRealtimeUs; if (mTimerPool != null) { // Accumulate time to all currently active timers before adding // this new one to the pool. - refreshTimersLocked(batteryRealtime, mTimerPool, null); + refreshTimersLocked(batteryRealtimeUs, mTimerPool, null); // Add this timer to the active pool mTimerPool.add(this); } if (mTimeBase.isRunning()) { // Increment the count mCount++; - mAcquireTime = mTotalTime; + mAcquireTimeUs = mTotalTimeUs; } else { - mAcquireTime = -1; + mAcquireTimeUs = -1; } if (DEBUG && mType < 0) { - Log.v(TAG, "start #" + mType + ": mUpdateTime=" + mUpdateTime - + " mTotalTime=" + mTotalTime + " mCount=" + mCount - + " mAcquireTime=" + mAcquireTime); + Log.v(TAG, "start #" + mType + ": mUpdateTime=" + mUpdateTimeUs + + " mTotalTime=" + mTotalTimeUs + " mCount=" + mCount + + " mAcquireTime=" + mAcquireTimeUs); } } } @@ -2461,26 +2517,27 @@ public class BatteryStatsImpl extends BatteryStats { return; } if (--mNesting == 0) { - final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000); + final long batteryRealtimeUs = mTimeBase.getRealtime(elapsedRealtimeMs * 1000); if (mTimerPool != null) { // Accumulate time to all active counters, scaled by the total // active in the pool, before taking this one out of the pool. - refreshTimersLocked(batteryRealtime, mTimerPool, null); + refreshTimersLocked(batteryRealtimeUs, mTimerPool, null); // Remove this timer from the active pool mTimerPool.remove(this); } else { mNesting = 1; - mTotalTime = computeRunTimeLocked(batteryRealtime); + mTotalTimeUs = computeRunTimeLocked(batteryRealtimeUs, + elapsedRealtimeMs * 1000); mNesting = 0; } if (DEBUG && mType < 0) { - Log.v(TAG, "stop #" + mType + ": mUpdateTime=" + mUpdateTime - + " mTotalTime=" + mTotalTime + " mCount=" + mCount - + " mAcquireTime=" + mAcquireTime); + Log.v(TAG, "stop #" + mType + ": mUpdateTime=" + mUpdateTimeUs + + " mTotalTime=" + mTotalTimeUs + " mCount=" + mCount + + " mAcquireTime=" + mAcquireTimeUs); } - if (mAcquireTime >= 0 && mTotalTime == mAcquireTime) { + if (mAcquireTimeUs >= 0 && mTotalTimeUs == mAcquireTimeUs) { // If there was no change in the time, then discard this // count. A somewhat cheezy strategy, but hey. mCount--; @@ -2497,32 +2554,32 @@ public class BatteryStatsImpl extends BatteryStats { // Update the total time for all other running Timers with the same type as this Timer // due to a change in timer count - private static long refreshTimersLocked(long batteryRealtime, + private static long refreshTimersLocked(long batteryRealtimeUs, final ArrayList<StopwatchTimer> pool, StopwatchTimer self) { - long selfTime = 0; + long selfTimeUs = 0; final int N = pool.size(); for (int i=N-1; i>= 0; i--) { final StopwatchTimer t = pool.get(i); - long heldTime = batteryRealtime - t.mUpdateTime; - if (heldTime > 0) { - final long myTime = heldTime / N; + long heldTimeUs = batteryRealtimeUs - t.mUpdateTimeUs; + if (heldTimeUs > 0) { + final long myTimeUs = heldTimeUs / N; if (t == self) { - selfTime = myTime; + selfTimeUs = myTimeUs; } - t.mTotalTime += myTime; + t.mTotalTimeUs += myTimeUs; } - t.mUpdateTime = batteryRealtime; + t.mUpdateTimeUs = batteryRealtimeUs; } - return selfTime; + return selfTimeUs; } @Override - protected long computeRunTimeLocked(long curBatteryRealtime) { - if (mTimeout > 0 && curBatteryRealtime > mUpdateTime + mTimeout) { - curBatteryRealtime = mUpdateTime + mTimeout; + protected long computeRunTimeLocked(long curBatteryRealtimeUs, long elapsedRealtimeUs) { + if (mTimeoutUs > 0 && curBatteryRealtimeUs > mUpdateTimeUs + mTimeoutUs) { + curBatteryRealtimeUs = mUpdateTimeUs + mTimeoutUs; } - return mTotalTime + (mNesting > 0 - ? (curBatteryRealtime - mUpdateTime) + return mTotalTimeUs + (mNesting > 0 + ? (curBatteryRealtimeUs - mUpdateTimeUs) / (mTimerPool != null ? mTimerPool.size() : 1) : 0); } @@ -2533,13 +2590,14 @@ public class BatteryStatsImpl extends BatteryStats { } @Override - public boolean reset(boolean detachIfReset) { + public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { boolean canDetach = mNesting <= 0; - super.reset(canDetach && detachIfReset); + super.reset(canDetach && detachIfReset, elapsedRealtimeUs); if (mNesting > 0) { - mUpdateTime = mTimeBase.getRealtime(mClocks.elapsedRealtime() * 1000); + mUpdateTimeUs = mTimeBase.getRealtime(elapsedRealtimeUs); } - mAcquireTime = -1; // to ensure mCount isn't decreased to -1 if timer is stopped later. + // To ensure mCount isn't decreased to -1 if timer is stopped later. + mAcquireTimeUs = -1; return canDetach; } @@ -2565,17 +2623,17 @@ public class BatteryStatsImpl extends BatteryStats { * @param elapsedRealtimeMs the current elapsed realtime in milliseconds. */ public void setMark(long elapsedRealtimeMs) { - final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000); + final long batteryRealtimeUs = mTimeBase.getRealtime(elapsedRealtimeMs * 1000); if (mNesting > 0) { // We are running. if (mTimerPool != null) { - refreshTimersLocked(batteryRealtime, mTimerPool, this); + refreshTimersLocked(batteryRealtimeUs, mTimerPool, this); } else { - mTotalTime += batteryRealtime - mUpdateTime; - mUpdateTime = batteryRealtime; + mTotalTimeUs += batteryRealtimeUs - mUpdateTimeUs; + mUpdateTimeUs = batteryRealtimeUs; } } - mTimeBeforeMark = mTotalTime; + mTimeBeforeMarkUs = mTotalTimeUs; } } @@ -2641,11 +2699,11 @@ public class BatteryStatsImpl extends BatteryStats { } @Override - public boolean reset(boolean detachIfReset) { + public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { boolean active = false; // Do not detach the subTimer explicitly since that'll be done by DualTimer.detach(). - active |= !mSubTimer.reset(false); - active |= !super.reset(detachIfReset); + active |= !mSubTimer.reset(false, elapsedRealtimeUs); + active |= !super.reset(detachIfReset, elapsedRealtimeUs); return !active; } @@ -2682,10 +2740,10 @@ public class BatteryStatsImpl extends BatteryStats { final ArrayMap<String, T> mMap = new ArrayMap<>(); T mCurOverflow; ArrayMap<String, MutableInt> mActiveOverflow; - long mLastOverflowTime; - long mLastOverflowFinishTime; - long mLastClearTime; - long mLastCleanupTime; + long mLastOverflowTimeMs; + long mLastOverflowFinishTimeMs; + long mLastClearTimeMs; + long mLastCleanupTimeMs; public OverflowArrayMap(int uid) { mUid = uid; @@ -2696,7 +2754,7 @@ public class BatteryStatsImpl extends BatteryStats { } public void clear() { - mLastClearTime = SystemClock.elapsedRealtime(); + mLastClearTimeMs = SystemClock.elapsedRealtime(); mMap.clear(); mCurOverflow = null; mActiveOverflow = null; @@ -2712,8 +2770,8 @@ public class BatteryStatsImpl extends BatteryStats { } } - public void cleanup() { - mLastCleanupTime = SystemClock.elapsedRealtime(); + public void cleanup(long elapsedRealtimeMs) { + mLastCleanupTimeMs = elapsedRealtimeMs; if (mActiveOverflow != null) { if (mActiveOverflow.size() == 0) { mActiveOverflow = null; @@ -2737,7 +2795,7 @@ public class BatteryStatsImpl extends BatteryStats { } } - public T startObject(String name) { + public T startObject(String name, long elapsedRealtimeMs) { if (name == null) { name = ""; } @@ -2780,7 +2838,7 @@ public class BatteryStatsImpl extends BatteryStats { mActiveOverflow = new ArrayMap<>(); } mActiveOverflow.put(name, new MutableInt(1)); - mLastOverflowTime = SystemClock.elapsedRealtime(); + mLastOverflowTimeMs = elapsedRealtimeMs; return obj; } @@ -2790,7 +2848,7 @@ public class BatteryStatsImpl extends BatteryStats { return obj; } - public T stopObject(String name) { + public T stopObject(String name, long elapsedRealtimeMs) { if (name == null) { name = ""; } @@ -2810,7 +2868,7 @@ public class BatteryStatsImpl extends BatteryStats { over.value--; if (over.value <= 0) { mActiveOverflow.remove(name); - mLastOverflowFinishTime = SystemClock.elapsedRealtime(); + mLastOverflowFinishTimeMs = elapsedRealtimeMs; } return obj; } @@ -2830,22 +2888,22 @@ public class BatteryStatsImpl extends BatteryStats { sb.append(mActiveOverflow); sb.append(" curoverflow="); sb.append(mCurOverflow); - long now = SystemClock.elapsedRealtime(); - if (mLastOverflowTime != 0) { + long now = elapsedRealtimeMs; + if (mLastOverflowTimeMs != 0) { sb.append(" lastOverflowTime="); - TimeUtils.formatDuration(mLastOverflowTime-now, sb); + TimeUtils.formatDuration(mLastOverflowTimeMs - now, sb); } - if (mLastOverflowFinishTime != 0) { + if (mLastOverflowFinishTimeMs != 0) { sb.append(" lastOverflowFinishTime="); - TimeUtils.formatDuration(mLastOverflowFinishTime-now, sb); + TimeUtils.formatDuration(mLastOverflowFinishTimeMs - now, sb); } - if (mLastClearTime != 0) { + if (mLastClearTimeMs != 0) { sb.append(" lastClearTime="); - TimeUtils.formatDuration(mLastClearTime-now, sb); + TimeUtils.formatDuration(mLastClearTimeMs - now, sb); } - if (mLastCleanupTime != 0) { + if (mLastCleanupTimeMs != 0) { sb.append(" lastCleanupTime="); - TimeUtils.formatDuration(mLastCleanupTime-now, sb); + TimeUtils.formatDuration(mLastCleanupTimeMs - now, sb); } Slog.wtf(TAG, sb.toString()); return null; @@ -2943,16 +3001,16 @@ public class BatteryStatsImpl extends BatteryStats { mMonitoredRailChargeConsumedMaMs.writeToParcel(dest); } - public void reset(boolean detachIfReset) { - mIdleTimeMillis.reset(detachIfReset); - mScanTimeMillis.reset(detachIfReset); - mSleepTimeMillis.reset(detachIfReset); - mRxTimeMillis.reset(detachIfReset); + public void reset(boolean detachIfReset, long elapsedRealtimeUs) { + mIdleTimeMillis.reset(detachIfReset, elapsedRealtimeUs); + mScanTimeMillis.reset(detachIfReset, elapsedRealtimeUs); + mSleepTimeMillis.reset(detachIfReset, elapsedRealtimeUs); + mRxTimeMillis.reset(detachIfReset, elapsedRealtimeUs); for (LongSamplingCounter counter : mTxTimeMillis) { - counter.reset(detachIfReset); + counter.reset(detachIfReset, elapsedRealtimeUs); } - mPowerDrainMaMs.reset(detachIfReset); - mMonitoredRailChargeConsumedMaMs.reset(detachIfReset); + mPowerDrainMaMs.reset(detachIfReset, elapsedRealtimeUs); + mMonitoredRailChargeConsumedMaMs.reset(detachIfReset, elapsedRealtimeUs); } public void detach() { @@ -3416,82 +3474,82 @@ public class BatteryStatsImpl extends BatteryStats { final int NU = mUidStats.size(); for (int i=0; i<NU; i++) { final BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); - uid.mLastStepUserTime = uid.mCurStepUserTime; - uid.mLastStepSystemTime = uid.mCurStepSystemTime; - } - mLastStepCpuUserTime = mCurStepCpuUserTime; - mLastStepCpuSystemTime = mCurStepCpuSystemTime; - mLastStepStatUserTime = mCurStepStatUserTime; - mLastStepStatSystemTime = mCurStepStatSystemTime; - mLastStepStatIOWaitTime = mCurStepStatIOWaitTime; - mLastStepStatIrqTime = mCurStepStatIrqTime; - mLastStepStatSoftIrqTime = mCurStepStatSoftIrqTime; - mLastStepStatIdleTime = mCurStepStatIdleTime; + uid.mLastStepUserTimeMs = uid.mCurStepUserTimeMs; + uid.mLastStepSystemTimeMs = uid.mCurStepSystemTimeMs; + } + mLastStepCpuUserTimeMs = mCurStepCpuUserTimeMs; + mLastStepCpuSystemTimeMs = mCurStepCpuSystemTimeMs; + mLastStepStatUserTimeMs = mCurStepStatUserTimeMs; + mLastStepStatSystemTimeMs = mCurStepStatSystemTimeMs; + mLastStepStatIOWaitTimeMs = mCurStepStatIOWaitTimeMs; + mLastStepStatIrqTimeMs = mCurStepStatIrqTimeMs; + mLastStepStatSoftIrqTimeMs = mCurStepStatSoftIrqTimeMs; + mLastStepStatIdleTimeMs = mCurStepStatIdleTimeMs; tmp.clear(); return; } if (DEBUG) { - Slog.d(TAG, "Step stats last: user=" + mLastStepCpuUserTime + " sys=" - + mLastStepStatSystemTime + " io=" + mLastStepStatIOWaitTime - + " irq=" + mLastStepStatIrqTime + " sirq=" - + mLastStepStatSoftIrqTime + " idle=" + mLastStepStatIdleTime); - Slog.d(TAG, "Step stats cur: user=" + mCurStepCpuUserTime + " sys=" - + mCurStepStatSystemTime + " io=" + mCurStepStatIOWaitTime - + " irq=" + mCurStepStatIrqTime + " sirq=" - + mCurStepStatSoftIrqTime + " idle=" + mCurStepStatIdleTime); - } - out.userTime = (int)(mCurStepCpuUserTime - mLastStepCpuUserTime); - out.systemTime = (int)(mCurStepCpuSystemTime - mLastStepCpuSystemTime); - out.statUserTime = (int)(mCurStepStatUserTime - mLastStepStatUserTime); - out.statSystemTime = (int)(mCurStepStatSystemTime - mLastStepStatSystemTime); - out.statIOWaitTime = (int)(mCurStepStatIOWaitTime - mLastStepStatIOWaitTime); - out.statIrqTime = (int)(mCurStepStatIrqTime - mLastStepStatIrqTime); - out.statSoftIrqTime = (int)(mCurStepStatSoftIrqTime - mLastStepStatSoftIrqTime); - out.statIdlTime = (int)(mCurStepStatIdleTime - mLastStepStatIdleTime); + Slog.d(TAG, "Step stats last: user=" + mLastStepCpuUserTimeMs + " sys=" + + mLastStepStatSystemTimeMs + " io=" + mLastStepStatIOWaitTimeMs + + " irq=" + mLastStepStatIrqTimeMs + " sirq=" + + mLastStepStatSoftIrqTimeMs + " idle=" + mLastStepStatIdleTimeMs); + Slog.d(TAG, "Step stats cur: user=" + mCurStepCpuUserTimeMs + " sys=" + + mCurStepStatSystemTimeMs + " io=" + mCurStepStatIOWaitTimeMs + + " irq=" + mCurStepStatIrqTimeMs + " sirq=" + + mCurStepStatSoftIrqTimeMs + " idle=" + mCurStepStatIdleTimeMs); + } + out.userTime = (int) (mCurStepCpuUserTimeMs - mLastStepCpuUserTimeMs); + out.systemTime = (int) (mCurStepCpuSystemTimeMs - mLastStepCpuSystemTimeMs); + out.statUserTime = (int) (mCurStepStatUserTimeMs - mLastStepStatUserTimeMs); + out.statSystemTime = (int) (mCurStepStatSystemTimeMs - mLastStepStatSystemTimeMs); + out.statIOWaitTime = (int) (mCurStepStatIOWaitTimeMs - mLastStepStatIOWaitTimeMs); + out.statIrqTime = (int) (mCurStepStatIrqTimeMs - mLastStepStatIrqTimeMs); + out.statSoftIrqTime = (int) (mCurStepStatSoftIrqTimeMs - mLastStepStatSoftIrqTimeMs); + out.statIdlTime = (int) (mCurStepStatIdleTimeMs - mLastStepStatIdleTimeMs); out.appCpuUid1 = out.appCpuUid2 = out.appCpuUid3 = -1; out.appCpuUTime1 = out.appCpuUTime2 = out.appCpuUTime3 = 0; out.appCpuSTime1 = out.appCpuSTime2 = out.appCpuSTime3 = 0; final int NU = mUidStats.size(); for (int i=0; i<NU; i++) { final BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); - final int totalUTime = (int)(uid.mCurStepUserTime - uid.mLastStepUserTime); - final int totalSTime = (int)(uid.mCurStepSystemTime - uid.mLastStepSystemTime); - final int totalTime = totalUTime + totalSTime; - uid.mLastStepUserTime = uid.mCurStepUserTime; - uid.mLastStepSystemTime = uid.mCurStepSystemTime; - if (totalTime <= (out.appCpuUTime3+out.appCpuSTime3)) { + final int totalUTimeMs = (int) (uid.mCurStepUserTimeMs - uid.mLastStepUserTimeMs); + final int totalSTimeMs = (int) (uid.mCurStepSystemTimeMs - uid.mLastStepSystemTimeMs); + final int totalTimeMs = totalUTimeMs + totalSTimeMs; + uid.mLastStepUserTimeMs = uid.mCurStepUserTimeMs; + uid.mLastStepSystemTimeMs = uid.mCurStepSystemTimeMs; + if (totalTimeMs <= (out.appCpuUTime3 + out.appCpuSTime3)) { continue; } - if (totalTime <= (out.appCpuUTime2+out.appCpuSTime2)) { + if (totalTimeMs <= (out.appCpuUTime2 + out.appCpuSTime2)) { out.appCpuUid3 = uid.mUid; - out.appCpuUTime3 = totalUTime; - out.appCpuSTime3 = totalSTime; + out.appCpuUTime3 = totalUTimeMs; + out.appCpuSTime3 = totalSTimeMs; } else { out.appCpuUid3 = out.appCpuUid2; out.appCpuUTime3 = out.appCpuUTime2; out.appCpuSTime3 = out.appCpuSTime2; - if (totalTime <= (out.appCpuUTime1+out.appCpuSTime1)) { + if (totalTimeMs <= (out.appCpuUTime1 + out.appCpuSTime1)) { out.appCpuUid2 = uid.mUid; - out.appCpuUTime2 = totalUTime; - out.appCpuSTime2 = totalSTime; + out.appCpuUTime2 = totalUTimeMs; + out.appCpuSTime2 = totalSTimeMs; } else { out.appCpuUid2 = out.appCpuUid1; out.appCpuUTime2 = out.appCpuUTime1; out.appCpuSTime2 = out.appCpuSTime1; out.appCpuUid1 = uid.mUid; - out.appCpuUTime1 = totalUTime; - out.appCpuSTime1 = totalSTime; + out.appCpuUTime1 = totalUTimeMs; + out.appCpuSTime1 = totalSTimeMs; } } } - mLastStepCpuUserTime = mCurStepCpuUserTime; - mLastStepCpuSystemTime = mCurStepCpuSystemTime; - mLastStepStatUserTime = mCurStepStatUserTime; - mLastStepStatSystemTime = mCurStepStatSystemTime; - mLastStepStatIOWaitTime = mCurStepStatIOWaitTime; - mLastStepStatIrqTime = mCurStepStatIrqTime; - mLastStepStatSoftIrqTime = mCurStepStatSoftIrqTime; - mLastStepStatIdleTime = mCurStepStatIdleTime; + mLastStepCpuUserTimeMs = mCurStepCpuUserTimeMs; + mLastStepCpuSystemTimeMs = mCurStepCpuSystemTimeMs; + mLastStepStatUserTimeMs = mCurStepStatUserTimeMs; + mLastStepStatSystemTimeMs = mCurStepStatSystemTimeMs; + mLastStepStatIOWaitTimeMs = mCurStepStatIOWaitTimeMs; + mLastStepStatIrqTimeMs = mCurStepStatIrqTimeMs; + mLastStepStatSoftIrqTimeMs = mCurStepStatSoftIrqTimeMs; + mLastStepStatIdleTimeMs = mCurStepStatIdleTimeMs; } public void readHistoryDelta(Parcel src, HistoryItem cur) { @@ -3631,29 +3689,35 @@ public class BatteryStatsImpl extends BatteryStats { } public void createFakeHistoryEvents(long numEvents) { + final long elapsedRealtimeMs = mClocks.elapsedRealtime(); + final long uptimeMs = mClocks.uptimeMillis(); for(long i = 0; i < numEvents; i++) { - noteLongPartialWakelockStart("name1", "historyName1", 1000); - noteLongPartialWakelockFinish("name1", "historyName1", 1000); + noteLongPartialWakelockStart("name1", "historyName1", 1000, + elapsedRealtimeMs, uptimeMs); + noteLongPartialWakelockFinish("name1", "historyName1", 1000, + elapsedRealtimeMs, uptimeMs); } } - void addHistoryBufferLocked(long elapsedRealtimeMs, HistoryItem cur) { + void addHistoryBufferLocked(long elapsedRealtimeMs, long uptimeMs, HistoryItem cur) { if (!mHaveBatteryLevel || !mRecordingHistory) { return; } - final long timeDiff = (mHistoryBaseTime+elapsedRealtimeMs) - mHistoryLastWritten.time; + final long timeDiffMs = (mHistoryBaseTimeMs + elapsedRealtimeMs) - mHistoryLastWritten.time; final int diffStates = mHistoryLastWritten.states^(cur.states&mActiveHistoryStates); final int diffStates2 = mHistoryLastWritten.states2^(cur.states2&mActiveHistoryStates2); final int lastDiffStates = mHistoryLastWritten.states^mHistoryLastLastWritten.states; final int lastDiffStates2 = mHistoryLastWritten.states2^mHistoryLastLastWritten.states2; - if (DEBUG) Slog.i(TAG, "ADD: tdelta=" + timeDiff + " diff=" - + Integer.toHexString(diffStates) + " lastDiff=" - + Integer.toHexString(lastDiffStates) + " diff2=" - + Integer.toHexString(diffStates2) + " lastDiff2=" - + Integer.toHexString(lastDiffStates2)); + if (DEBUG) { + Slog.i(TAG, "ADD: tdelta=" + timeDiffMs + " diff=" + + Integer.toHexString(diffStates) + " lastDiff=" + + Integer.toHexString(lastDiffStates) + " diff2=" + + Integer.toHexString(diffStates2) + " lastDiff2=" + + Integer.toHexString(lastDiffStates2)); + } if (mHistoryBufferLastPos >= 0 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE - && timeDiff < 1000 && (diffStates&lastDiffStates) == 0 + && timeDiffMs < 1000 && (diffStates & lastDiffStates) == 0 && (diffStates2&lastDiffStates2) == 0 && (mHistoryLastWritten.wakelockTag == null || cur.wakelockTag == null) && (mHistoryLastWritten.wakeReasonTag == null || cur.wakeReasonTag == null) @@ -3674,7 +3738,7 @@ public class BatteryStatsImpl extends BatteryStats { mHistoryBuffer.setDataSize(mHistoryBufferLastPos); mHistoryBuffer.setDataPosition(mHistoryBufferLastPos); mHistoryBufferLastPos = -1; - elapsedRealtimeMs = mHistoryLastWritten.time - mHistoryBaseTime; + elapsedRealtimeMs = mHistoryLastWritten.time - mHistoryBaseTimeMs; // If the last written history had a wakelock tag, we need to retain it. // Note that the condition above made sure that we aren't in a case where // both it and the current history item have a wakelock tag. @@ -3714,11 +3778,9 @@ public class BatteryStatsImpl extends BatteryStats { mHistoryBuffer.setDataPosition(0); mHistoryBuffer.setDataCapacity(mConstants.MAX_HISTORY_BUFFER / 2); mHistoryBufferLastPos = -1; - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); HistoryItem newItem = new HistoryItem(); newItem.setTo(cur); - startRecordingHistory(elapsedRealtime, uptime, false); + startRecordingHistory(elapsedRealtimeMs, uptimeMs, false); addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_UPDATE, newItem); return; } @@ -3737,11 +3799,11 @@ public class BatteryStatsImpl extends BatteryStats { } mHistoryBufferLastPos = mHistoryBuffer.dataPosition(); mHistoryLastLastWritten.setTo(mHistoryLastWritten); - mHistoryLastWritten.setTo(mHistoryBaseTime + elapsedRealtimeMs, cmd, cur); + mHistoryLastWritten.setTo(mHistoryBaseTimeMs + elapsedRealtimeMs, cmd, cur); mHistoryLastWritten.states &= mActiveHistoryStates; mHistoryLastWritten.states2 &= mActiveHistoryStates2; writeHistoryDelta(mHistoryBuffer, mHistoryLastWritten, mHistoryLastLastWritten); - mLastHistoryElapsedRealtime = elapsedRealtimeMs; + mLastHistoryElapsedRealtimeMs = elapsedRealtimeMs; cur.wakelockTag = null; cur.wakeReasonTag = null; cur.eventCode = HistoryItem.EVENT_NONE; @@ -3755,27 +3817,27 @@ public class BatteryStatsImpl extends BatteryStats { int mChangedStates2 = 0; void addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs) { - if (mTrackRunningHistoryElapsedRealtime != 0) { - final long diffElapsed = elapsedRealtimeMs - mTrackRunningHistoryElapsedRealtime; - final long diffUptime = uptimeMs - mTrackRunningHistoryUptime; - if (diffUptime < (diffElapsed-20)) { - final long wakeElapsedTime = elapsedRealtimeMs - (diffElapsed - diffUptime); + if (mTrackRunningHistoryElapsedRealtimeMs != 0) { + final long diffElapsedMs = elapsedRealtimeMs - mTrackRunningHistoryElapsedRealtimeMs; + final long diffUptimeMs = uptimeMs - mTrackRunningHistoryUptimeMs; + if (diffUptimeMs < (diffElapsedMs - 20)) { + final long wakeElapsedTimeMs = elapsedRealtimeMs - (diffElapsedMs - diffUptimeMs); mHistoryAddTmp.setTo(mHistoryLastWritten); mHistoryAddTmp.wakelockTag = null; mHistoryAddTmp.wakeReasonTag = null; mHistoryAddTmp.eventCode = HistoryItem.EVENT_NONE; mHistoryAddTmp.states &= ~HistoryItem.STATE_CPU_RUNNING_FLAG; - addHistoryRecordInnerLocked(wakeElapsedTime, mHistoryAddTmp); + addHistoryRecordInnerLocked(wakeElapsedTimeMs, uptimeMs, mHistoryAddTmp); } } mHistoryCur.states |= HistoryItem.STATE_CPU_RUNNING_FLAG; - mTrackRunningHistoryElapsedRealtime = elapsedRealtimeMs; - mTrackRunningHistoryUptime = uptimeMs; - addHistoryRecordInnerLocked(elapsedRealtimeMs, mHistoryCur); + mTrackRunningHistoryElapsedRealtimeMs = elapsedRealtimeMs; + mTrackRunningHistoryUptimeMs = uptimeMs; + addHistoryRecordInnerLocked(elapsedRealtimeMs, uptimeMs, mHistoryCur); } - void addHistoryRecordInnerLocked(long elapsedRealtimeMs, HistoryItem cur) { - addHistoryBufferLocked(elapsedRealtimeMs, cur); + void addHistoryRecordInnerLocked(long elapsedRealtimeMs, long uptimeMs, HistoryItem cur) { + addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, cur); if (!USE_OLD_HISTORY) { return; @@ -3790,13 +3852,13 @@ public class BatteryStatsImpl extends BatteryStats { // are now resetting back to their original value, then just collapse // into one record. if (mHistoryEnd != null && mHistoryEnd.cmd == HistoryItem.CMD_UPDATE - && (mHistoryBaseTime+elapsedRealtimeMs) < (mHistoryEnd.time+1000) + && (mHistoryBaseTimeMs + elapsedRealtimeMs) < (mHistoryEnd.time + 1000) && ((mHistoryEnd.states^cur.states)&mChangedStates&mActiveHistoryStates) == 0 && ((mHistoryEnd.states2^cur.states2)&mChangedStates2&mActiveHistoryStates2) == 0) { // If the current is the same as the one before, then we no // longer need the entry. if (mHistoryLastEnd != null && mHistoryLastEnd.cmd == HistoryItem.CMD_UPDATE - && (mHistoryBaseTime+elapsedRealtimeMs) < (mHistoryEnd.time+500) + && (mHistoryBaseTimeMs + elapsedRealtimeMs) < (mHistoryEnd.time + 500) && mHistoryLastEnd.sameNonEvent(cur)) { mHistoryLastEnd.next = null; mHistoryEnd.next = mHistoryCache; @@ -3832,7 +3894,7 @@ public class BatteryStatsImpl extends BatteryStats { } else { rec = new HistoryItem(); } - rec.setTo(mHistoryBaseTime + elapsedRealtimeMs, cmd, cur); + rec.setTo(mHistoryBaseTimeMs + elapsedRealtimeMs, cmd, cur); addHistoryRecordLocked(rec); } @@ -3860,10 +3922,10 @@ public class BatteryStatsImpl extends BatteryStats { mNumHistoryItems = 0; } - mHistoryBaseTime = 0; - mLastHistoryElapsedRealtime = 0; - mTrackRunningHistoryElapsedRealtime = 0; - mTrackRunningHistoryUptime = 0; + mHistoryBaseTimeMs = 0; + mLastHistoryElapsedRealtimeMs = 0; + mTrackRunningHistoryElapsedRealtimeMs = 0; + mTrackRunningHistoryUptimeMs = 0; mHistoryBuffer.setDataSize(0); mHistoryBuffer.setDataPosition(0); @@ -3879,8 +3941,8 @@ public class BatteryStatsImpl extends BatteryStats { } @GuardedBy("this") - public void updateTimeBasesLocked(boolean unplugged, int screenState, long uptime, - long realtime) { + public void updateTimeBasesLocked(boolean unplugged, int screenState, long uptimeUs, + long realtimeUs) { final boolean screenOff = !isScreenOn(screenState); final boolean updateOnBatteryTimeBase = unplugged != mOnBatteryTimeBase.isRunning(); final boolean updateOnBatteryScreenOffTimeBase = @@ -3888,14 +3950,15 @@ public class BatteryStatsImpl extends BatteryStats { if (updateOnBatteryScreenOffTimeBase || updateOnBatteryTimeBase) { if (updateOnBatteryScreenOffTimeBase) { - updateKernelWakelocksLocked(); + updateKernelWakelocksLocked(realtimeUs); updateBatteryPropertiesLocked(); } // This if{} is only necessary due to SCREEN_OFF_RPM_STATS_ENABLED, which exists because // updateRpmStatsLocked is too slow to run each screen change. When the speed is // improved, remove the surrounding if{}. if (SCREEN_OFF_RPM_STATS_ENABLED || updateOnBatteryTimeBase) { - updateRpmStatsLocked(); // if either OnBattery or OnBatteryScreenOff timebase changes. + // if either OnBattery or OnBatteryScreenOfftimebase changes. + updateRpmStatsLocked(realtimeUs); } if (DEBUG_ENERGY_CPU) { Slog.d(TAG, "Updating cpu time because screen is now " @@ -3903,16 +3966,17 @@ public class BatteryStatsImpl extends BatteryStats { + " and battery is " + (unplugged ? "on" : "off")); } - mOnBatteryTimeBase.setRunning(unplugged, uptime, realtime); + mOnBatteryTimeBase.setRunning(unplugged, uptimeUs, realtimeUs); if (updateOnBatteryTimeBase) { for (int i = mUidStats.size() - 1; i >= 0; --i) { - mUidStats.valueAt(i).updateOnBatteryBgTimeBase(uptime, realtime); + mUidStats.valueAt(i).updateOnBatteryBgTimeBase(uptimeUs, realtimeUs); } } if (updateOnBatteryScreenOffTimeBase) { - mOnBatteryScreenOffTimeBase.setRunning(unplugged && screenOff, uptime, realtime); + mOnBatteryScreenOffTimeBase.setRunning(unplugged && screenOff, + uptimeUs, realtimeUs); for (int i = mUidStats.size() - 1; i >= 0; --i) { - mUidStats.valueAt(i).updateOnBatteryScreenOffBgTimeBase(uptime, realtime); + mUidStats.valueAt(i).updateOnBatteryScreenOffBgTimeBase(uptimeUs, realtimeUs); } } } @@ -3931,8 +3995,14 @@ public class BatteryStatsImpl extends BatteryStats { } public void addIsolatedUidLocked(int isolatedUid, int appUid) { + addIsolatedUidLocked(isolatedUid, appUid, + mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void addIsolatedUidLocked(int isolatedUid, int appUid, + long elapsedRealtimeMs, long uptimeMs) { mIsolatedUids.put(isolatedUid, appUid); - final Uid u = getUidStatsLocked(appUid); + final Uid u = getUidStatsLocked(appUid, elapsedRealtimeMs, uptimeMs); u.addIsolatedUid(isolatedUid); } @@ -3955,14 +4025,22 @@ public class BatteryStatsImpl extends BatteryStats { */ @GuardedBy("this") public void removeIsolatedUidLocked(int isolatedUid) { + removeIsolatedUidLocked(isolatedUid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + /** + * @see #removeIsolatedUidLocked(int) + */ + @GuardedBy("this") + public void removeIsolatedUidLocked(int isolatedUid, long elapsedRealtimeMs, long uptimeMs) { final int idx = mIsolatedUids.indexOfKey(isolatedUid); if (idx >= 0) { final int ownerUid = mIsolatedUids.valueAt(idx); - final Uid u = getUidStatsLocked(ownerUid); + final Uid u = getUidStatsLocked(ownerUid, elapsedRealtimeMs, uptimeMs); u.removeIsolatedUid(isolatedUid); mIsolatedUids.removeAt(idx); } - mPendingRemovedUids.add(new UidToRemove(isolatedUid, mClocks.elapsedRealtime())); + mPendingRemovedUids.add(new UidToRemove(isolatedUid, elapsedRealtimeMs)); } public int mapUid(int uid) { @@ -3971,26 +4049,39 @@ public class BatteryStatsImpl extends BatteryStats { } public void noteEventLocked(int code, String name, int uid) { + noteEventLocked(code, name, uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteEventLocked(int code, String name, int uid, + long elapsedRealtimeMs, long uptimeMs) { uid = mapUid(uid); if (!mActiveEvents.updateState(code, name, uid, 0)) { return; } - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); - addHistoryEventLocked(elapsedRealtime, uptime, code, name, uid); + addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, code, name, uid); } public void noteCurrentTimeChangedLocked() { final long currentTime = System.currentTimeMillis(); final long elapsedRealtime = mClocks.elapsedRealtime(); final long uptime = mClocks.uptimeMillis(); - recordCurrentTimeChangeLocked(currentTime, elapsedRealtime, uptime); + noteCurrentTimeChangedLocked(currentTime, elapsedRealtime, uptime); + } + + public void noteCurrentTimeChangedLocked(long currentTimeMs, + long elapsedRealtimeMs, long uptimeMs) { + recordCurrentTimeChangeLocked(currentTimeMs, elapsedRealtimeMs, uptimeMs); } public void noteProcessStartLocked(String name, int uid) { + noteProcessStartLocked(name, uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteProcessStartLocked(String name, int uid, + long elapsedRealtimeMs, long uptimeMs) { uid = mapUid(uid); if (isOnBattery()) { - Uid u = getUidStatsLocked(uid); + Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs); u.getProcessStatsLocked(name).incStartsLocked(); } if (!mActiveEvents.updateState(HistoryItem.EVENT_PROC_START, name, uid, 0)) { @@ -3999,28 +4090,40 @@ public class BatteryStatsImpl extends BatteryStats { if (!mRecordAllHistory) { return; } - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); - addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PROC_START, name, uid); + addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_PROC_START, name, uid); } public void noteProcessCrashLocked(String name, int uid) { + noteProcessCrashLocked(name, uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteProcessCrashLocked(String name, int uid, + long elapsedRealtimeMs, long uptimeMs) { uid = mapUid(uid); if (isOnBattery()) { - Uid u = getUidStatsLocked(uid); + Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs); u.getProcessStatsLocked(name).incNumCrashesLocked(); } } public void noteProcessAnrLocked(String name, int uid) { + noteProcessAnrLocked(name, uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteProcessAnrLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs) { uid = mapUid(uid); if (isOnBattery()) { - Uid u = getUidStatsLocked(uid); + Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs); u.getProcessStatsLocked(name).incNumAnrsLocked(); } } public void noteUidProcessStateLocked(int uid, int state) { + noteUidProcessStateLocked(uid, state, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteUidProcessStateLocked(int uid, int state, + long elapsedRealtimeMs, long uptimeMs) { int parentUid = mapUid(uid); if (uid != parentUid) { // Isolated UIDs process state is already rolled up into parent, so no need to track @@ -4032,10 +4135,16 @@ public class BatteryStatsImpl extends BatteryStats { // and isolated uids rather than only the parent uid. FrameworkStatsLog.write(FrameworkStatsLog.UID_PROCESS_STATE_CHANGED, uid, ActivityManager.processStateAmToProto(state)); - getUidStatsLocked(uid).updateUidProcessStateLocked(state); + getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) + .updateUidProcessStateLocked(state, elapsedRealtimeMs, uptimeMs); } public void noteProcessFinishLocked(String name, int uid) { + noteProcessFinishLocked(name, uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteProcessFinishLocked(String name, int uid, + long elapsedRealtimeMs, long uptimeMs) { uid = mapUid(uid); if (!mActiveEvents.updateState(HistoryItem.EVENT_PROC_FINISH, name, uid, 0)) { return; @@ -4043,82 +4152,120 @@ public class BatteryStatsImpl extends BatteryStats { if (!mRecordAllHistory) { return; } - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); - addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PROC_FINISH, name, uid); + addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_PROC_FINISH, + name, uid); } public void noteSyncStartLocked(String name, int uid) { + noteSyncStartLocked(name, uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteSyncStartLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs) { uid = mapUid(uid); - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); - getUidStatsLocked(uid).noteStartSyncLocked(name, elapsedRealtime); + getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) + .noteStartSyncLocked(name, elapsedRealtimeMs); if (!mActiveEvents.updateState(HistoryItem.EVENT_SYNC_START, name, uid, 0)) { return; } - addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_SYNC_START, name, uid); + addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_SYNC_START, name, uid); } public void noteSyncFinishLocked(String name, int uid) { + noteSyncFinishLocked(name, uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteSyncFinishLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs) { uid = mapUid(uid); - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); - getUidStatsLocked(uid).noteStopSyncLocked(name, elapsedRealtime); + getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) + .noteStopSyncLocked(name, elapsedRealtimeMs); if (!mActiveEvents.updateState(HistoryItem.EVENT_SYNC_FINISH, name, uid, 0)) { return; } - addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_SYNC_FINISH, name, uid); + addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_SYNC_FINISH, + name, uid); } public void noteJobStartLocked(String name, int uid) { + noteJobStartLocked(name, uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteJobStartLocked(String name, int uid, long elapsedRealtimeMs, long uptimeMs) { uid = mapUid(uid); - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); - getUidStatsLocked(uid).noteStartJobLocked(name, elapsedRealtime); + getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) + .noteStartJobLocked(name, elapsedRealtimeMs); if (!mActiveEvents.updateState(HistoryItem.EVENT_JOB_START, name, uid, 0)) { return; } - addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_JOB_START, name, uid); + addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_JOB_START, name, uid); } public void noteJobFinishLocked(String name, int uid, int stopReason) { + noteJobFinishLocked(name, uid, stopReason, + mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteJobFinishLocked(String name, int uid, int stopReason, + long elapsedRealtimeMs, long uptimeMs) { uid = mapUid(uid); - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); - getUidStatsLocked(uid).noteStopJobLocked(name, elapsedRealtime, stopReason); + getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) + .noteStopJobLocked(name, elapsedRealtimeMs, stopReason); if (!mActiveEvents.updateState(HistoryItem.EVENT_JOB_FINISH, name, uid, 0)) { return; } - addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_JOB_FINISH, name, uid); + addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_JOB_FINISH, name, uid); } public void noteJobsDeferredLocked(int uid, int numDeferred, long sinceLast) { + noteJobsDeferredLocked(uid, numDeferred, sinceLast, + mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteJobsDeferredLocked(int uid, int numDeferred, long sinceLast, + long elapsedRealtimeMs, long uptimeMs) { uid = mapUid(uid); - getUidStatsLocked(uid).noteJobsDeferredLocked(numDeferred, sinceLast); + getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) + .noteJobsDeferredLocked(numDeferred, sinceLast); } public void noteAlarmStartLocked(String name, WorkSource workSource, int uid) { - noteAlarmStartOrFinishLocked(HistoryItem.EVENT_ALARM_START, name, workSource, uid); + noteAlarmStartLocked(name, workSource, uid, + mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteAlarmStartLocked(String name, WorkSource workSource, int uid, + long elapsedRealtimeMs, long uptimeMs) { + noteAlarmStartOrFinishLocked(HistoryItem.EVENT_ALARM_START, name, workSource, uid, + elapsedRealtimeMs, uptimeMs); } public void noteAlarmFinishLocked(String name, WorkSource workSource, int uid) { - noteAlarmStartOrFinishLocked(HistoryItem.EVENT_ALARM_FINISH, name, workSource, uid); + noteAlarmFinishLocked(name, workSource, uid, + mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteAlarmFinishLocked(String name, WorkSource workSource, int uid, + long elapsedRealtimeMs, long uptimeMs) { + noteAlarmStartOrFinishLocked(HistoryItem.EVENT_ALARM_FINISH, name, workSource, uid, + elapsedRealtimeMs, uptimeMs); } private void noteAlarmStartOrFinishLocked(int historyItem, String name, WorkSource workSource, int uid) { + noteAlarmStartOrFinishLocked(historyItem, name, workSource, uid, + mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + private void noteAlarmStartOrFinishLocked(int historyItem, String name, WorkSource workSource, + int uid, long elapsedRealtimeMs, long uptimeMs) { if (!mRecordAllHistory) { return; } - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); - if (workSource != null) { for (int i = 0; i < workSource.size(); ++i) { uid = mapUid(workSource.getUid(i)); if (mActiveEvents.updateState(historyItem, name, uid, 0)) { - addHistoryEventLocked(elapsedRealtime, uptime, historyItem, name, uid); + addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, historyItem, name, uid); } } @@ -4127,7 +4274,7 @@ public class BatteryStatsImpl extends BatteryStats { for (int i = 0; i < workChains.size(); ++i) { uid = mapUid(workChains.get(i).getAttributionUid()); if (mActiveEvents.updateState(historyItem, name, uid, 0)) { - addHistoryEventLocked(elapsedRealtime, uptime, historyItem, name, uid); + addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, historyItem, name, uid); } } } @@ -4135,13 +4282,19 @@ public class BatteryStatsImpl extends BatteryStats { uid = mapUid(uid); if (mActiveEvents.updateState(historyItem, name, uid, 0)) { - addHistoryEventLocked(elapsedRealtime, uptime, historyItem, name, uid); + addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, historyItem, name, uid); } } } public void noteWakupAlarmLocked(String packageName, int uid, WorkSource workSource, String tag) { + noteWakupAlarmLocked(packageName, uid, workSource, tag, + mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteWakupAlarmLocked(String packageName, int uid, WorkSource workSource, + String tag, long elapsedRealtimeMs, long uptimeMs) { if (workSource != null) { for (int i = 0; i < workSource.size(); ++i) { uid = workSource.getUid(i); @@ -4149,7 +4302,8 @@ public class BatteryStatsImpl extends BatteryStats { if (isOnBattery()) { BatteryStatsImpl.Uid.Pkg pkg = getPackageStatsLocked(uid, - workSourceName != null ? workSourceName : packageName); + workSourceName != null ? workSourceName : packageName, + elapsedRealtimeMs, uptimeMs); pkg.noteWakeupAlarmLocked(tag); } } @@ -4161,14 +4315,16 @@ public class BatteryStatsImpl extends BatteryStats { uid = wc.getAttributionUid(); if (isOnBattery()) { - BatteryStatsImpl.Uid.Pkg pkg = getPackageStatsLocked(uid, packageName); + BatteryStatsImpl.Uid.Pkg pkg = getPackageStatsLocked(uid, packageName, + elapsedRealtimeMs, uptimeMs); pkg.noteWakeupAlarmLocked(tag); } } } } else { if (isOnBattery()) { - BatteryStatsImpl.Uid.Pkg pkg = getPackageStatsLocked(uid, packageName); + BatteryStatsImpl.Uid.Pkg pkg = getPackageStatsLocked(uid, packageName, + elapsedRealtimeMs, uptimeMs); pkg.noteWakeupAlarmLocked(tag); } } @@ -4228,7 +4384,8 @@ public class BatteryStatsImpl extends BatteryStats { public void setPretendScreenOff(boolean pretendScreenOff) { if (mPretendScreenOff != pretendScreenOff) { mPretendScreenOff = pretendScreenOff; - noteScreenStateLocked(pretendScreenOff ? Display.STATE_OFF : Display.STATE_ON); + noteScreenStateLocked(pretendScreenOff ? Display.STATE_OFF : Display.STATE_ON, + mClocks.elapsedRealtime(), mClocks.uptimeMillis(), System.currentTimeMillis()); } } @@ -4236,19 +4393,25 @@ public class BatteryStatsImpl extends BatteryStats { private int mInitialAcquireWakeUid = -1; public void noteStartWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, - int type, boolean unimportantForLogging, long elapsedRealtime, long uptime) { + int type, boolean unimportantForLogging) { + noteStartWakeLocked(uid, pid, wc, name, historyName, type, unimportantForLogging, + mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteStartWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, + int type, boolean unimportantForLogging, long elapsedRealtimeMs, long uptimeMs) { uid = mapUid(uid); if (type == WAKE_TYPE_PARTIAL) { // Only care about partial wake locks, since full wake locks // will be canceled when the user puts the screen to sleep. - aggregateLastWakeupUptimeLocked(uptime); + aggregateLastWakeupUptimeLocked(elapsedRealtimeMs, uptimeMs); if (historyName == null) { historyName = name; } if (mRecordAllHistory) { if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_START, historyName, uid, 0)) { - addHistoryEventLocked(elapsedRealtime, uptime, + addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_WAKE_LOCK_START, historyName, uid); } } @@ -4260,7 +4423,7 @@ public class BatteryStatsImpl extends BatteryStats { mHistoryCur.wakelockTag.string = mInitialAcquireWakeName = historyName; mHistoryCur.wakelockTag.uid = mInitialAcquireWakeUid = uid; mWakeLockImportant = !unimportantForLogging; - addHistoryRecordLocked(elapsedRealtime, uptime); + addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); } else if (!mWakeLockImportant && !unimportantForLogging && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE) { if (mHistoryLastWritten.wakelockTag != null) { @@ -4269,7 +4432,7 @@ public class BatteryStatsImpl extends BatteryStats { mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag; mHistoryCur.wakelockTag.string = mInitialAcquireWakeName = historyName; mHistoryCur.wakelockTag.uid = mInitialAcquireWakeUid = uid; - addHistoryRecordLocked(elapsedRealtime, uptime); + addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); } mWakeLockImportant = true; } @@ -4285,7 +4448,8 @@ public class BatteryStatsImpl extends BatteryStats { requestWakelockCpuUpdate(); } - getUidStatsLocked(uid).noteStartWakeLocked(pid, name, type, elapsedRealtime); + getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) + .noteStartWakeLocked(pid, name, type, elapsedRealtimeMs); if (wc != null) { FrameworkStatsLog.write(FrameworkStatsLog.WAKELOCK_STATE_CHANGED, wc.getUids(), @@ -4300,7 +4464,13 @@ public class BatteryStatsImpl extends BatteryStats { } public void noteStopWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, - int type, long elapsedRealtime, long uptime) { + int type) { + noteStopWakeLocked(uid, pid, wc, name, historyName, type, + mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteStopWakeLocked(int uid, int pid, WorkChain wc, String name, String historyName, + int type, long elapsedRealtimeMs, long uptimeMs) { uid = mapUid(uid); if (type == WAKE_TYPE_PARTIAL) { mWakeLockNesting--; @@ -4310,7 +4480,7 @@ public class BatteryStatsImpl extends BatteryStats { } if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_FINISH, historyName, uid, 0)) { - addHistoryEventLocked(elapsedRealtime, uptime, + addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_WAKE_LOCK_FINISH, historyName, uid); } } @@ -4320,7 +4490,7 @@ public class BatteryStatsImpl extends BatteryStats { + Integer.toHexString(mHistoryCur.states)); mInitialAcquireWakeName = null; mInitialAcquireWakeUid = -1; - addHistoryRecordLocked(elapsedRealtime, uptime); + addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); } } if (uid >= 0) { @@ -4331,7 +4501,8 @@ public class BatteryStatsImpl extends BatteryStats { requestWakelockCpuUpdate(); } - getUidStatsLocked(uid).noteStopWakeLocked(pid, name, type, elapsedRealtime); + getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) + .noteStopWakeLocked(pid, name, type, elapsedRealtimeMs); if (wc != null) { FrameworkStatsLog.write(FrameworkStatsLog.WAKELOCK_STATE_CHANGED, wc.getUids(), wc.getTags(), getPowerManagerWakeLockLevel(type), name, @@ -4377,12 +4548,17 @@ public class BatteryStatsImpl extends BatteryStats { public void noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name, String historyName, int type, boolean unimportantForLogging) { - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); + noteStartWakeFromSourceLocked(ws, pid, name, historyName, type, unimportantForLogging, + mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name, + String historyName, int type, boolean unimportantForLogging, + long elapsedRealtimeMs, long uptimeMs) { final int N = ws.size(); for (int i=0; i<N; i++) { noteStartWakeLocked(ws.getUid(i), pid, null, name, historyName, type, - unimportantForLogging, elapsedRealtime, uptime); + unimportantForLogging, elapsedRealtimeMs, uptimeMs); } List<WorkChain> wcs = ws.getWorkChains(); @@ -4390,7 +4566,7 @@ public class BatteryStatsImpl extends BatteryStats { for (int i = 0; i < wcs.size(); ++i) { final WorkChain wc = wcs.get(i); noteStartWakeLocked(wc.getAttributionUid(), pid, wc, name, historyName, type, - unimportantForLogging, elapsedRealtime, uptime); + unimportantForLogging, elapsedRealtimeMs, uptimeMs); } } } @@ -4398,9 +4574,15 @@ public class BatteryStatsImpl extends BatteryStats { public void noteChangeWakelockFromSourceLocked(WorkSource ws, int pid, String name, String historyName, int type, WorkSource newWs, int newPid, String newName, String newHistoryName, int newType, boolean newUnimportantForLogging) { - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); + noteChangeWakelockFromSourceLocked(ws, pid, name, historyName, type, newWs, newPid, + newName, newHistoryName, newType, newUnimportantForLogging, + mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + public void noteChangeWakelockFromSourceLocked(WorkSource ws, int pid, String name, + String historyName, int type, WorkSource newWs, int newPid, String newName, + String newHistoryName, int newType, boolean newUnimportantForLogging, + long elapsedRealtimeMs, long uptimeMs) { List<WorkChain>[] wcs = WorkSource.diffChains(ws, newWs); // For correct semantics, we start the need worksources first, so that we won't @@ -4411,7 +4593,7 @@ public class BatteryStatsImpl extends BatteryStats { final int NN = newWs.size(); for (int i=0; i<NN; i++) { noteStartWakeLocked(newWs.getUid(i), newPid, null, newName, newHistoryName, newType, - newUnimportantForLogging, elapsedRealtime, uptime); + newUnimportantForLogging, elapsedRealtimeMs, uptimeMs); } if (wcs != null) { List<WorkChain> newChains = wcs[0]; @@ -4419,8 +4601,8 @@ public class BatteryStatsImpl extends BatteryStats { for (int i = 0; i < newChains.size(); ++i) { final WorkChain newChain = newChains.get(i); noteStartWakeLocked(newChain.getAttributionUid(), newPid, newChain, newName, - newHistoryName, newType, newUnimportantForLogging, elapsedRealtime, - uptime); + newHistoryName, newType, newUnimportantForLogging, elapsedRealtimeMs, + uptimeMs); } } } @@ -4428,8 +4610,8 @@ public class BatteryStatsImpl extends BatteryStats { // Then the stops : final int NO = ws.size(); for (int i=0; i<NO; i++) { - noteStopWakeLocked(ws.getUid(i), pid, null, name, historyName, type, elapsedRealtime, - uptime); + noteStopWakeLocked(ws.getUid(i), pid, null, name, historyName, type, elapsedRealtimeMs, + uptimeMs); } if (wcs != null) { List<WorkChain> goneChains = wcs[1]; @@ -4437,7 +4619,7 @@ public class BatteryStatsImpl extends BatteryStats { for (int i = 0; i < goneChains.size(); ++i) { final WorkChain goneChain = goneChains.get(i); noteStopWakeLocked(goneChain.getAttributionUid(), pid, goneChain, name, - historyName, type, elapsedRealtime, uptime); + historyName, type, elapsedRealtimeMs, uptimeMs); } } } @@ -4445,12 +4627,16 @@ public class BatteryStatsImpl extends BatteryStats { public void noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name, String historyName, int type) { - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); + noteStopWakeFromSourceLocked(ws, pid, name, historyName, type, + mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name, + String historyName, int type, long elapsedRealtimeMs, long uptimeMs) { final int N = ws.size(); for (int i=0; i<N; i++) { - noteStopWakeLocked(ws.getUid(i), pid, null, name, historyName, type, elapsedRealtime, - uptime); + noteStopWakeLocked(ws.getUid(i), pid, null, name, historyName, type, elapsedRealtimeMs, + uptimeMs); } List<WorkChain> wcs = ws.getWorkChains(); @@ -4458,22 +4644,35 @@ public class BatteryStatsImpl extends BatteryStats { for (int i = 0; i < wcs.size(); ++i) { final WorkChain wc = wcs.get(i); noteStopWakeLocked(wc.getAttributionUid(), pid, wc, name, historyName, type, - elapsedRealtime, uptime); + elapsedRealtimeMs, uptimeMs); } } } public void noteLongPartialWakelockStart(String name, String historyName, int uid) { + noteLongPartialWakelockStart(name, historyName, uid, + mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteLongPartialWakelockStart(String name, String historyName, int uid, + long elapsedRealtimeMs, long uptimeMs) { uid = mapUid(uid); - noteLongPartialWakeLockStartInternal(name, historyName, uid); + noteLongPartialWakeLockStartInternal(name, historyName, uid, elapsedRealtimeMs, uptimeMs); } public void noteLongPartialWakelockStartFromSource(String name, String historyName, WorkSource workSource) { + noteLongPartialWakelockStartFromSource(name, historyName, workSource, + mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteLongPartialWakelockStartFromSource(String name, String historyName, + WorkSource workSource, long elapsedRealtimeMs, long uptimeMs) { final int N = workSource.size(); for (int i = 0; i < N; ++i) { final int uid = mapUid(workSource.getUid(i)); - noteLongPartialWakeLockStartInternal(name, historyName, uid); + noteLongPartialWakeLockStartInternal(name, historyName, uid, + elapsedRealtimeMs, uptimeMs); } final List<WorkChain> workChains = workSource.getWorkChains(); @@ -4481,14 +4680,14 @@ public class BatteryStatsImpl extends BatteryStats { for (int i = 0; i < workChains.size(); ++i) { final WorkChain workChain = workChains.get(i); final int uid = workChain.getAttributionUid(); - noteLongPartialWakeLockStartInternal(name, historyName, uid); + noteLongPartialWakeLockStartInternal(name, historyName, uid, + elapsedRealtimeMs, uptimeMs); } } } - private void noteLongPartialWakeLockStartInternal(String name, String historyName, int uid) { - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); + private void noteLongPartialWakeLockStartInternal(String name, String historyName, int uid, + long elapsedRealtimeMs, long uptimeMs) { if (historyName == null) { historyName = name; } @@ -4496,21 +4695,34 @@ public class BatteryStatsImpl extends BatteryStats { 0)) { return; } - addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_LONG_WAKE_LOCK_START, + addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_LONG_WAKE_LOCK_START, historyName, uid); } public void noteLongPartialWakelockFinish(String name, String historyName, int uid) { + noteLongPartialWakelockFinish(name, historyName, uid, + mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteLongPartialWakelockFinish(String name, String historyName, int uid, + long elapsedRealtimeMs, long uptimeMs) { uid = mapUid(uid); - noteLongPartialWakeLockFinishInternal(name, historyName, uid); + noteLongPartialWakeLockFinishInternal(name, historyName, uid, elapsedRealtimeMs, uptimeMs); } public void noteLongPartialWakelockFinishFromSource(String name, String historyName, WorkSource workSource) { + noteLongPartialWakelockFinishFromSource(name, historyName, workSource, + mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteLongPartialWakelockFinishFromSource(String name, String historyName, + WorkSource workSource, long elapsedRealtimeMs, long uptimeMs) { final int N = workSource.size(); for (int i = 0; i < N; ++i) { final int uid = mapUid(workSource.getUid(i)); - noteLongPartialWakeLockFinishInternal(name, historyName, uid); + noteLongPartialWakeLockFinishInternal(name, historyName, uid, + elapsedRealtimeMs, uptimeMs); } final List<WorkChain> workChains = workSource.getWorkChains(); @@ -4518,14 +4730,14 @@ public class BatteryStatsImpl extends BatteryStats { for (int i = 0; i < workChains.size(); ++i) { final WorkChain workChain = workChains.get(i); final int uid = workChain.getAttributionUid(); - noteLongPartialWakeLockFinishInternal(name, historyName, uid); + noteLongPartialWakeLockFinishInternal(name, historyName, uid, + elapsedRealtimeMs, uptimeMs); } } } - private void noteLongPartialWakeLockFinishInternal(String name, String historyName, int uid) { - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); + private void noteLongPartialWakeLockFinishInternal(String name, String historyName, int uid, + long elapsedRealtimeMs, long uptimeMs) { if (historyName == null) { historyName = name; } @@ -4533,33 +4745,35 @@ public class BatteryStatsImpl extends BatteryStats { 0)) { return; } - addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH, + addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH, historyName, uid); } - void aggregateLastWakeupUptimeLocked(long uptimeMs) { + void aggregateLastWakeupUptimeLocked(long elapsedRealtimeMs, long uptimeMs) { if (mLastWakeupReason != null) { - long deltaUptime = uptimeMs - mLastWakeupUptimeMs; + long deltaUptimeMs = uptimeMs - mLastWakeupUptimeMs; SamplingTimer timer = getWakeupReasonTimerLocked(mLastWakeupReason); - timer.add(deltaUptime * 1000, 1); // time in in microseconds + timer.add(deltaUptimeMs * 1000, 1, elapsedRealtimeMs); // time in in microseconds FrameworkStatsLog.write(FrameworkStatsLog.KERNEL_WAKEUP_REPORTED, mLastWakeupReason, - /* duration_usec */ deltaUptime * 1000); + /* duration_usec */ deltaUptimeMs * 1000); mLastWakeupReason = null; } } public void noteWakeupReasonLocked(String reason) { - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); + noteWakeupReasonLocked(reason, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteWakeupReasonLocked(String reason, long elapsedRealtimeMs, long uptimeMs) { if (DEBUG_HISTORY) Slog.v(TAG, "Wakeup reason \"" + reason +"\": " + Integer.toHexString(mHistoryCur.states)); - aggregateLastWakeupUptimeLocked(uptime); + aggregateLastWakeupUptimeLocked(elapsedRealtimeMs, uptimeMs); mHistoryCur.wakeReasonTag = mHistoryCur.localWakeReasonTag; mHistoryCur.wakeReasonTag.string = reason; mHistoryCur.wakeReasonTag.uid = 0; mLastWakeupReason = reason; - mLastWakeupUptimeMs = uptime; - addHistoryRecordLocked(elapsedRealtime, uptime); + mLastWakeupUptimeMs = uptimeMs; + addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); } public boolean startAddingCpuLocked() { @@ -4567,21 +4781,23 @@ public class BatteryStatsImpl extends BatteryStats { return mOnBatteryInternal; } - public void finishAddingCpuLocked(int totalUTime, int totalSTime, int statUserTime, - int statSystemTime, int statIOWaitTime, int statIrqTime, - int statSoftIrqTime, int statIdleTime) { - if (DEBUG) Slog.d(TAG, "Adding cpu: tuser=" + totalUTime + " tsys=" + totalSTime - + " user=" + statUserTime + " sys=" + statSystemTime - + " io=" + statIOWaitTime + " irq=" + statIrqTime - + " sirq=" + statSoftIrqTime + " idle=" + statIdleTime); - mCurStepCpuUserTime += totalUTime; - mCurStepCpuSystemTime += totalSTime; - mCurStepStatUserTime += statUserTime; - mCurStepStatSystemTime += statSystemTime; - mCurStepStatIOWaitTime += statIOWaitTime; - mCurStepStatIrqTime += statIrqTime; - mCurStepStatSoftIrqTime += statSoftIrqTime; - mCurStepStatIdleTime += statIdleTime; + public void finishAddingCpuLocked(int totalUTimeMs, int totalSTimeMs, int statUserTimeMs, + int statSystemTimeMs, int statIOWaitTimeMs, int statIrqTimeMs, + int statSoftIrqTimeMs, int statIdleTimeMs) { + if (DEBUG) { + Slog.d(TAG, "Adding cpu: tuser=" + totalUTimeMs + " tsys=" + totalSTimeMs + + " user=" + statUserTimeMs + " sys=" + statSystemTimeMs + + " io=" + statIOWaitTimeMs + " irq=" + statIrqTimeMs + + " sirq=" + statSoftIrqTimeMs + " idle=" + statIdleTimeMs); + } + mCurStepCpuUserTimeMs += totalUTimeMs; + mCurStepCpuSystemTimeMs += totalSTimeMs; + mCurStepStatUserTimeMs += statUserTimeMs; + mCurStepStatSystemTimeMs += statSystemTimeMs; + mCurStepStatIOWaitTimeMs += statIOWaitTimeMs; + mCurStepStatIrqTimeMs += statIrqTimeMs; + mCurStepStatSoftIrqTimeMs += statSoftIrqTimeMs; + mCurStepStatIdleTimeMs += statIdleTimeMs; } public void noteProcessDiedLocked(int uid, int pid) { @@ -4592,65 +4808,76 @@ public class BatteryStatsImpl extends BatteryStats { } } - public long getProcessWakeTime(int uid, int pid, long realtime) { + public long getProcessWakeTime(int uid, int pid, long realtimeMs) { uid = mapUid(uid); Uid u = mUidStats.get(uid); if (u != null) { Uid.Pid p = u.mPids.get(pid); if (p != null) { - return p.mWakeSumMs + (p.mWakeNesting > 0 ? (realtime - p.mWakeStartMs) : 0); + return p.mWakeSumMs + (p.mWakeNesting > 0 ? (realtimeMs - p.mWakeStartMs) : 0); } } return 0; } - public void reportExcessiveCpuLocked(int uid, String proc, long overTime, long usedTime) { + public void reportExcessiveCpuLocked(int uid, String proc, long overTimeMs, long usedTimeMs) { uid = mapUid(uid); Uid u = mUidStats.get(uid); if (u != null) { - u.reportExcessiveCpuLocked(proc, overTime, usedTime); + u.reportExcessiveCpuLocked(proc, overTimeMs, usedTimeMs); } } int mSensorNesting; public void noteStartSensorLocked(int uid, int sensor) { + noteStartSensorLocked(uid, sensor, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteStartSensorLocked(int uid, int sensor, long elapsedRealtimeMs, long uptimeMs) { uid = mapUid(uid); - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); if (mSensorNesting == 0) { mHistoryCur.states |= HistoryItem.STATE_SENSOR_ON_FLAG; if (DEBUG_HISTORY) Slog.v(TAG, "Start sensor to: " + Integer.toHexString(mHistoryCur.states)); - addHistoryRecordLocked(elapsedRealtime, uptime); + addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); } mSensorNesting++; - getUidStatsLocked(uid).noteStartSensor(sensor, elapsedRealtime); + getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) + .noteStartSensor(sensor, elapsedRealtimeMs); } public void noteStopSensorLocked(int uid, int sensor) { + noteStopSensorLocked(uid, sensor, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteStopSensorLocked(int uid, int sensor, long elapsedRealtimeMs, long uptimeMs) { uid = mapUid(uid); - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); mSensorNesting--; if (mSensorNesting == 0) { mHistoryCur.states &= ~HistoryItem.STATE_SENSOR_ON_FLAG; if (DEBUG_HISTORY) Slog.v(TAG, "Stop sensor to: " + Integer.toHexString(mHistoryCur.states)); - addHistoryRecordLocked(elapsedRealtime, uptime); + addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); } - getUidStatsLocked(uid).noteStopSensor(sensor, elapsedRealtime); + getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) + .noteStopSensor(sensor, elapsedRealtimeMs); } int mGpsNesting; public void noteGpsChangedLocked(WorkSource oldWs, WorkSource newWs) { + noteGpsChangedLocked(oldWs, newWs, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteGpsChangedLocked(WorkSource oldWs, WorkSource newWs, + long elapsedRealtimeMs, long uptimeMs) { for (int i = 0; i < newWs.size(); ++i) { - noteStartGpsLocked(newWs.getUid(i), null); + noteStartGpsLocked(newWs.getUid(i), null, elapsedRealtimeMs, uptimeMs); } for (int i = 0; i < oldWs.size(); ++i) { - noteStopGpsLocked((oldWs.getUid(i)), null); + noteStopGpsLocked((oldWs.getUid(i)), null, elapsedRealtimeMs, uptimeMs); } List<WorkChain>[] wcs = WorkSource.diffChains(oldWs, newWs); @@ -4658,28 +4885,27 @@ public class BatteryStatsImpl extends BatteryStats { if (wcs[0] != null) { final List<WorkChain> newChains = wcs[0]; for (int i = 0; i < newChains.size(); ++i) { - noteStartGpsLocked(-1, newChains.get(i)); + noteStartGpsLocked(-1, newChains.get(i), elapsedRealtimeMs, uptimeMs); } } if (wcs[1] != null) { final List<WorkChain> goneChains = wcs[1]; for (int i = 0; i < goneChains.size(); ++i) { - noteStopGpsLocked(-1, goneChains.get(i)); + noteStopGpsLocked(-1, goneChains.get(i), elapsedRealtimeMs, uptimeMs); } } } } - private void noteStartGpsLocked(int uid, WorkChain workChain) { + private void noteStartGpsLocked(int uid, WorkChain workChain, + long elapsedRealtimeMs, long uptimeMs) { uid = getAttributionUid(uid, workChain); - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); if (mGpsNesting == 0) { mHistoryCur.states |= HistoryItem.STATE_GPS_ON_FLAG; if (DEBUG_HISTORY) Slog.v(TAG, "Start GPS to: " + Integer.toHexString(mHistoryCur.states)); - addHistoryRecordLocked(elapsedRealtime, uptime); + addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); } mGpsNesting++; @@ -4692,20 +4918,19 @@ public class BatteryStatsImpl extends BatteryStats { FrameworkStatsLog.GPS_SCAN_STATE_CHANGED__STATE__ON); } - getUidStatsLocked(uid).noteStartGps(elapsedRealtime); + getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs).noteStartGps(elapsedRealtimeMs); } - private void noteStopGpsLocked(int uid, WorkChain workChain) { + private void noteStopGpsLocked(int uid, WorkChain workChain, + long elapsedRealtimeMs, long uptimeMs) { uid = getAttributionUid(uid, workChain); - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); mGpsNesting--; if (mGpsNesting == 0) { mHistoryCur.states &= ~HistoryItem.STATE_GPS_ON_FLAG; if (DEBUG_HISTORY) Slog.v(TAG, "Stop GPS to: " + Integer.toHexString(mHistoryCur.states)); - addHistoryRecordLocked(elapsedRealtime, uptime); - stopAllGpsSignalQualityTimersLocked(-1); + addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); + stopAllGpsSignalQualityTimersLocked(-1, elapsedRealtimeMs); mGpsSignalQualityBin = -1; } @@ -4717,29 +4942,31 @@ public class BatteryStatsImpl extends BatteryStats { workChain.getTags(), FrameworkStatsLog.GPS_SCAN_STATE_CHANGED__STATE__OFF); } - getUidStatsLocked(uid).noteStopGps(elapsedRealtime); + getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs).noteStopGps(elapsedRealtimeMs); } public void noteGpsSignalQualityLocked(int signalLevel) { + noteGpsSignalQualityLocked(signalLevel, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteGpsSignalQualityLocked(int signalLevel, long elapsedRealtimeMs, long uptimeMs) { if (mGpsNesting == 0) { return; } if (signalLevel < 0 || signalLevel >= GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS) { - stopAllGpsSignalQualityTimersLocked(-1); + stopAllGpsSignalQualityTimersLocked(-1, elapsedRealtimeMs); return; } - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); if (mGpsSignalQualityBin != signalLevel) { if (mGpsSignalQualityBin >= 0) { - mGpsSignalQualityTimer[mGpsSignalQualityBin].stopRunningLocked(elapsedRealtime); + mGpsSignalQualityTimer[mGpsSignalQualityBin].stopRunningLocked(elapsedRealtimeMs); } if(!mGpsSignalQualityTimer[signalLevel].isRunningLocked()) { - mGpsSignalQualityTimer[signalLevel].startRunningLocked(elapsedRealtime); + mGpsSignalQualityTimer[signalLevel].startRunningLocked(elapsedRealtimeMs); } mHistoryCur.states2 = (mHistoryCur.states2&~HistoryItem.STATE2_GPS_SIGNAL_QUALITY_MASK) | (signalLevel << HistoryItem.STATE2_GPS_SIGNAL_QUALITY_SHIFT); - addHistoryRecordLocked(elapsedRealtime, uptime); + addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); mGpsSignalQualityBin = signalLevel; } return; @@ -4747,6 +4974,13 @@ public class BatteryStatsImpl extends BatteryStats { @GuardedBy("this") public void noteScreenStateLocked(int state) { + noteScreenStateLocked(state, mClocks.elapsedRealtime(), mClocks.uptimeMillis(), + System.currentTimeMillis()); + } + + @GuardedBy("this") + public void noteScreenStateLocked(int state, + long elapsedRealtimeMs, long uptimeMs, long currentTimeMs) { state = mPretendScreenOff ? Display.STATE_OFF : state; // Battery stats relies on there being 4 states. To accommodate this, new states beyond the @@ -4763,7 +4997,7 @@ public class BatteryStatsImpl extends BatteryStats { } if (mScreenState != state) { - recordDailyStatsIfNeededLocked(true); + recordDailyStatsIfNeededLocked(true, currentTimeMs); final int oldState = mScreenState; mScreenState = state; if (DEBUG) Slog.v(TAG, "Screen state: oldState=" + Display.stateToString(oldState) @@ -4779,56 +5013,55 @@ public class BatteryStatsImpl extends BatteryStats { } } - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); - boolean updateHistory = false; if (isScreenDoze(state) && !isScreenDoze(oldState)) { mHistoryCur.states |= HistoryItem.STATE_SCREEN_DOZE_FLAG; - mScreenDozeTimer.startRunningLocked(elapsedRealtime); + mScreenDozeTimer.startRunningLocked(elapsedRealtimeMs); updateHistory = true; } else if (isScreenDoze(oldState) && !isScreenDoze(state)) { mHistoryCur.states &= ~HistoryItem.STATE_SCREEN_DOZE_FLAG; - mScreenDozeTimer.stopRunningLocked(elapsedRealtime); + mScreenDozeTimer.stopRunningLocked(elapsedRealtimeMs); updateHistory = true; } if (isScreenOn(state)) { mHistoryCur.states |= HistoryItem.STATE_SCREEN_ON_FLAG; if (DEBUG_HISTORY) Slog.v(TAG, "Screen on to: " + Integer.toHexString(mHistoryCur.states)); - mScreenOnTimer.startRunningLocked(elapsedRealtime); + mScreenOnTimer.startRunningLocked(elapsedRealtimeMs); if (mScreenBrightnessBin >= 0) { - mScreenBrightnessTimer[mScreenBrightnessBin].startRunningLocked(elapsedRealtime); + mScreenBrightnessTimer[mScreenBrightnessBin] + .startRunningLocked(elapsedRealtimeMs); } updateHistory = true; } else if (isScreenOn(oldState)) { mHistoryCur.states &= ~HistoryItem.STATE_SCREEN_ON_FLAG; if (DEBUG_HISTORY) Slog.v(TAG, "Screen off to: " + Integer.toHexString(mHistoryCur.states)); - mScreenOnTimer.stopRunningLocked(elapsedRealtime); + mScreenOnTimer.stopRunningLocked(elapsedRealtimeMs); if (mScreenBrightnessBin >= 0) { - mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(elapsedRealtime); + mScreenBrightnessTimer[mScreenBrightnessBin] + .stopRunningLocked(elapsedRealtimeMs); } updateHistory = true; } if (updateHistory) { if (DEBUG_HISTORY) Slog.v(TAG, "Screen state to: " + Display.stateToString(state)); - addHistoryRecordLocked(elapsedRealtime, uptime); + addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); } mExternalSync.scheduleCpuSyncDueToScreenStateChange( mOnBatteryTimeBase.isRunning(), mOnBatteryScreenOffTimeBase.isRunning()); if (isScreenOn(state)) { updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), state, - mClocks.uptimeMillis() * 1000, elapsedRealtime * 1000); + uptimeMs * 1000, elapsedRealtimeMs * 1000); // Fake a wake lock, so we consider the device waked as long as the screen is on. noteStartWakeLocked(-1, -1, null, "screen", null, WAKE_TYPE_PARTIAL, false, - elapsedRealtime, uptime); + elapsedRealtimeMs, uptimeMs); } else if (isScreenOn(oldState)) { noteStopWakeLocked(-1, -1, null, "screen", "screen", WAKE_TYPE_PARTIAL, - elapsedRealtime, uptime); + elapsedRealtimeMs, uptimeMs); updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), state, - mClocks.uptimeMillis() * 1000, elapsedRealtime * 1000); + uptimeMs * 1000, elapsedRealtimeMs * 1000); } // Update discharge amounts. if (mOnBatteryInternal) { @@ -4839,23 +5072,27 @@ public class BatteryStatsImpl extends BatteryStats { @UnsupportedAppUsage public void noteScreenBrightnessLocked(int brightness) { + noteScreenBrightnessLocked(brightness, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteScreenBrightnessLocked(int brightness, long elapsedRealtimeMs, long uptimeMs) { // Bin the brightness. int bin = brightness / (256/NUM_SCREEN_BRIGHTNESS_BINS); if (bin < 0) bin = 0; else if (bin >= NUM_SCREEN_BRIGHTNESS_BINS) bin = NUM_SCREEN_BRIGHTNESS_BINS-1; if (mScreenBrightnessBin != bin) { - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_BRIGHTNESS_MASK) | (bin << HistoryItem.STATE_BRIGHTNESS_SHIFT); if (DEBUG_HISTORY) Slog.v(TAG, "Screen brightness " + bin + " to: " + Integer.toHexString(mHistoryCur.states)); - addHistoryRecordLocked(elapsedRealtime, uptime); + addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); if (mScreenState == Display.STATE_ON) { if (mScreenBrightnessBin >= 0) { - mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(elapsedRealtime); + mScreenBrightnessTimer[mScreenBrightnessBin] + .stopRunningLocked(elapsedRealtimeMs); } - mScreenBrightnessTimer[bin].startRunningLocked(elapsedRealtime); + mScreenBrightnessTimer[bin] + .startRunningLocked(elapsedRealtimeMs); } mScreenBrightnessBin = bin; } @@ -4863,36 +5100,50 @@ public class BatteryStatsImpl extends BatteryStats { @UnsupportedAppUsage public void noteUserActivityLocked(int uid, int event) { + noteUserActivityLocked(uid, event, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteUserActivityLocked(int uid, int event, long elapsedRealtimeMs, long uptimeMs) { if (mOnBatteryInternal) { uid = mapUid(uid); - getUidStatsLocked(uid).noteUserActivityLocked(event); + getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs).noteUserActivityLocked(event); } } public void noteWakeUpLocked(String reason, int reasonUid) { - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); - addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_SCREEN_WAKE_UP, + noteWakeUpLocked(reason, reasonUid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteWakeUpLocked(String reason, int reasonUid, + long elapsedRealtimeMs, long uptimeMs) { + addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_SCREEN_WAKE_UP, reason, reasonUid); } public void noteInteractiveLocked(boolean interactive) { + noteInteractiveLocked(interactive, mClocks.elapsedRealtime()); + } + + public void noteInteractiveLocked(boolean interactive, long elapsedRealtimeMs) { if (mInteractive != interactive) { - final long elapsedRealtime = mClocks.elapsedRealtime(); mInteractive = interactive; if (DEBUG) Slog.v(TAG, "Interactive: " + interactive); if (interactive) { - mInteractiveTimer.startRunningLocked(elapsedRealtime); + mInteractiveTimer.startRunningLocked(elapsedRealtimeMs); } else { - mInteractiveTimer.stopRunningLocked(elapsedRealtime); + mInteractiveTimer.stopRunningLocked(elapsedRealtimeMs); } } } public void noteConnectivityChangedLocked(int type, String extra) { - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); - addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_CONNECTIVITY_CHANGED, + noteConnectivityChangedLocked(type, extra, + mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteConnectivityChangedLocked(int type, String extra, + long elapsedRealtimeMs, long uptimeMs) { + addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_CONNECTIVITY_CHANGED, extra, type); mNumConnectivityChange++; } @@ -4902,15 +5153,19 @@ public class BatteryStatsImpl extends BatteryStats { uid = mapUid(uid); addHistoryEventLocked(elapsedRealtimeMillis, uptimeMillis, HistoryItem.EVENT_WAKEUP_AP, "", uid); - getUidStatsLocked(uid).noteMobileRadioApWakeupLocked(); + getUidStatsLocked(uid, elapsedRealtimeMillis, uptimeMillis).noteMobileRadioApWakeupLocked(); } /** * Updates the radio power state and returns true if an external stats collection should occur. */ public boolean noteMobileRadioPowerStateLocked(int powerState, long timestampNs, int uid) { - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); + return noteMobileRadioPowerStateLocked(powerState, timestampNs, uid, + mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public boolean noteMobileRadioPowerStateLocked(int powerState, long timestampNs, int uid, + long elapsedRealtimeMs, long uptimeMs) { if (mMobileRadioPowerState != powerState) { long realElapsedRealtimeMs; final boolean active = @@ -4918,31 +5173,31 @@ public class BatteryStatsImpl extends BatteryStats { || powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH; if (active) { if (uid > 0) { - noteMobileRadioApWakeupLocked(elapsedRealtime, uptime, uid); + noteMobileRadioApWakeupLocked(elapsedRealtimeMs, uptimeMs, uid); } - mMobileRadioActiveStartTime = realElapsedRealtimeMs = timestampNs / (1000 * 1000); + mMobileRadioActiveStartTimeMs = realElapsedRealtimeMs = timestampNs / (1000 * 1000); mHistoryCur.states |= HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG; } else { realElapsedRealtimeMs = timestampNs / (1000*1000); - long lastUpdateTimeMs = mMobileRadioActiveStartTime; + long lastUpdateTimeMs = mMobileRadioActiveStartTimeMs; if (realElapsedRealtimeMs < lastUpdateTimeMs) { Slog.wtf(TAG, "Data connection inactive timestamp " + realElapsedRealtimeMs + " is before start time " + lastUpdateTimeMs); - realElapsedRealtimeMs = elapsedRealtime; - } else if (realElapsedRealtimeMs < elapsedRealtime) { - mMobileRadioActiveAdjustedTime.addCountLocked(elapsedRealtime + realElapsedRealtimeMs = elapsedRealtimeMs; + } else if (realElapsedRealtimeMs < elapsedRealtimeMs) { + mMobileRadioActiveAdjustedTime.addCountLocked(elapsedRealtimeMs - realElapsedRealtimeMs); } mHistoryCur.states &= ~HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG; } if (DEBUG_HISTORY) Slog.v(TAG, "Mobile network active " + active + " to: " + Integer.toHexString(mHistoryCur.states)); - addHistoryRecordLocked(elapsedRealtime, uptime); + addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); mMobileRadioPowerState = powerState; if (active) { - mMobileRadioActiveTimer.startRunningLocked(elapsedRealtime); - mMobileRadioActivePerAppTimer.startRunningLocked(elapsedRealtime); + mMobileRadioActiveTimer.startRunningLocked(elapsedRealtimeMs); + mMobileRadioActivePerAppTimer.startRunningLocked(elapsedRealtimeMs); } else { mMobileRadioActiveTimer.stopRunningLocked(realElapsedRealtimeMs); mMobileRadioActivePerAppTimer.stopRunningLocked(realElapsedRealtimeMs); @@ -4954,25 +5209,27 @@ public class BatteryStatsImpl extends BatteryStats { } public void notePowerSaveModeLocked(boolean enabled) { + notePowerSaveModeLocked(enabled, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void notePowerSaveModeLocked(boolean enabled, long elapsedRealtimeMs, long uptimeMs) { if (mPowerSaveModeEnabled != enabled) { int stepState = enabled ? STEP_LEVEL_MODE_POWER_SAVE : 0; mModStepMode |= (mCurStepMode&STEP_LEVEL_MODE_POWER_SAVE) ^ stepState; mCurStepMode = (mCurStepMode&~STEP_LEVEL_MODE_POWER_SAVE) | stepState; - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); mPowerSaveModeEnabled = enabled; if (enabled) { mHistoryCur.states2 |= HistoryItem.STATE2_POWER_SAVE_FLAG; if (DEBUG_HISTORY) Slog.v(TAG, "Power save mode enabled to: " + Integer.toHexString(mHistoryCur.states2)); - mPowerSaveModeEnabledTimer.startRunningLocked(elapsedRealtime); + mPowerSaveModeEnabledTimer.startRunningLocked(elapsedRealtimeMs); } else { mHistoryCur.states2 &= ~HistoryItem.STATE2_POWER_SAVE_FLAG; if (DEBUG_HISTORY) Slog.v(TAG, "Power save mode disabled to: " + Integer.toHexString(mHistoryCur.states2)); - mPowerSaveModeEnabledTimer.stopRunningLocked(elapsedRealtime); + mPowerSaveModeEnabledTimer.stopRunningLocked(elapsedRealtimeMs); } - addHistoryRecordLocked(elapsedRealtime, uptime); + addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); FrameworkStatsLog.write(FrameworkStatsLog.BATTERY_SAVER_MODE_STATE_CHANGED, enabled ? FrameworkStatsLog.BATTERY_SAVER_MODE_STATE_CHANGED__STATE__ON @@ -4981,8 +5238,12 @@ public class BatteryStatsImpl extends BatteryStats { } public void noteDeviceIdleModeLocked(final int mode, String activeReason, int activeUid) { - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); + noteDeviceIdleModeLocked(mode, activeReason, activeUid, + mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteDeviceIdleModeLocked(final int mode, String activeReason, int activeUid, + long elapsedRealtimeMs, long uptimeMs) { boolean nowIdling = mode == DEVICE_IDLE_MODE_DEEP; if (mDeviceIdling && !nowIdling && activeReason == null) { // We don't go out of general idling mode until explicitly taken out of @@ -4996,7 +5257,7 @@ public class BatteryStatsImpl extends BatteryStats { nowLightIdling = true; } if (activeReason != null && (mDeviceIdling || mDeviceLightIdling)) { - addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_ACTIVE, + addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_ACTIVE, activeReason, activeUid); } if (mDeviceIdling != nowIdling || mDeviceLightIdling != nowLightIdling) { @@ -5012,17 +5273,17 @@ public class BatteryStatsImpl extends BatteryStats { mModStepMode |= (mCurStepMode&STEP_LEVEL_MODE_DEVICE_IDLE) ^ stepState; mCurStepMode = (mCurStepMode&~STEP_LEVEL_MODE_DEVICE_IDLE) | stepState; if (nowIdling) { - mDeviceIdlingTimer.startRunningLocked(elapsedRealtime); + mDeviceIdlingTimer.startRunningLocked(elapsedRealtimeMs); } else { - mDeviceIdlingTimer.stopRunningLocked(elapsedRealtime); + mDeviceIdlingTimer.stopRunningLocked(elapsedRealtimeMs); } } if (mDeviceLightIdling != nowLightIdling) { mDeviceLightIdling = nowLightIdling; if (nowLightIdling) { - mDeviceLightIdlingTimer.startRunningLocked(elapsedRealtime); + mDeviceLightIdlingTimer.startRunningLocked(elapsedRealtimeMs); } else { - mDeviceLightIdlingTimer.stopRunningLocked(elapsedRealtime); + mDeviceLightIdlingTimer.stopRunningLocked(elapsedRealtimeMs); } } if (mDeviceIdleMode != mode) { @@ -5030,24 +5291,24 @@ public class BatteryStatsImpl extends BatteryStats { | (mode << HistoryItem.STATE2_DEVICE_IDLE_SHIFT); if (DEBUG_HISTORY) Slog.v(TAG, "Device idle mode changed to: " + Integer.toHexString(mHistoryCur.states2)); - addHistoryRecordLocked(elapsedRealtime, uptime); - long lastDuration = elapsedRealtime - mLastIdleTimeStart; - mLastIdleTimeStart = elapsedRealtime; + addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); + long lastDuration = elapsedRealtimeMs - mLastIdleTimeStartMs; + mLastIdleTimeStartMs = elapsedRealtimeMs; if (mDeviceIdleMode == DEVICE_IDLE_MODE_LIGHT) { - if (lastDuration > mLongestLightIdleTime) { - mLongestLightIdleTime = lastDuration; + if (lastDuration > mLongestLightIdleTimeMs) { + mLongestLightIdleTimeMs = lastDuration; } - mDeviceIdleModeLightTimer.stopRunningLocked(elapsedRealtime); + mDeviceIdleModeLightTimer.stopRunningLocked(elapsedRealtimeMs); } else if (mDeviceIdleMode == DEVICE_IDLE_MODE_DEEP) { - if (lastDuration > mLongestFullIdleTime) { - mLongestFullIdleTime = lastDuration; + if (lastDuration > mLongestFullIdleTimeMs) { + mLongestFullIdleTimeMs = lastDuration; } - mDeviceIdleModeFullTimer.stopRunningLocked(elapsedRealtime); + mDeviceIdleModeFullTimer.stopRunningLocked(elapsedRealtimeMs); } if (mode == DEVICE_IDLE_MODE_LIGHT) { - mDeviceIdleModeLightTimer.startRunningLocked(elapsedRealtime); + mDeviceIdleModeLightTimer.startRunningLocked(elapsedRealtimeMs); } else if (mode == DEVICE_IDLE_MODE_DEEP) { - mDeviceIdleModeFullTimer.startRunningLocked(elapsedRealtime); + mDeviceIdleModeFullTimer.startRunningLocked(elapsedRealtimeMs); } mDeviceIdleMode = mode; FrameworkStatsLog.write(FrameworkStatsLog.DEVICE_IDLE_MODE_STATE_CHANGED, mode); @@ -5055,10 +5316,14 @@ public class BatteryStatsImpl extends BatteryStats { } public void notePackageInstalledLocked(String pkgName, long versionCode) { - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); + notePackageInstalledLocked(pkgName, versionCode, + mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void notePackageInstalledLocked(String pkgName, long versionCode, + long elapsedRealtimeMs, long uptimeMs) { // XXX need to figure out what to do with long version codes. - addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PACKAGE_INSTALLED, + addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_PACKAGE_INSTALLED, pkgName, (int)versionCode); PackageChange pc = new PackageChange(); pc.mPackageName = pkgName; @@ -5068,10 +5333,13 @@ public class BatteryStatsImpl extends BatteryStats { } public void notePackageUninstalledLocked(String pkgName) { - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); - addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PACKAGE_UNINSTALLED, - pkgName, 0); + notePackageUninstalledLocked(pkgName, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void notePackageUninstalledLocked(String pkgName, + long elapsedRealtimeMs, long uptimeMs) { + addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, + HistoryItem.EVENT_PACKAGE_UNINSTALLED, pkgName, 0); PackageChange pc = new PackageChange(); pc.mPackageName = pkgName; pc.mUpdate = true; @@ -5086,42 +5354,49 @@ public class BatteryStatsImpl extends BatteryStats { } void stopAllGpsSignalQualityTimersLocked(int except) { - final long elapsedRealtime = mClocks.elapsedRealtime(); + stopAllGpsSignalQualityTimersLocked(except, mClocks.elapsedRealtime()); + } + + void stopAllGpsSignalQualityTimersLocked(int except, long elapsedRealtimeMs) { for (int i = 0; i < GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) { if (i == except) { continue; } while (mGpsSignalQualityTimer[i].isRunningLocked()) { - mGpsSignalQualityTimer[i].stopRunningLocked(elapsedRealtime); + mGpsSignalQualityTimer[i].stopRunningLocked(elapsedRealtimeMs); } } } @UnsupportedAppUsage public void notePhoneOnLocked() { + notePhoneOnLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void notePhoneOnLocked(long elapsedRealtimeMs, long uptimeMs) { if (!mPhoneOn) { - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); mHistoryCur.states2 |= HistoryItem.STATE2_PHONE_IN_CALL_FLAG; if (DEBUG_HISTORY) Slog.v(TAG, "Phone on to: " + Integer.toHexString(mHistoryCur.states)); - addHistoryRecordLocked(elapsedRealtime, uptime); + addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); mPhoneOn = true; - mPhoneOnTimer.startRunningLocked(elapsedRealtime); + mPhoneOnTimer.startRunningLocked(elapsedRealtimeMs); } } @UnsupportedAppUsage public void notePhoneOffLocked() { + notePhoneOffLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void notePhoneOffLocked(long elapsedRealtimeMs, long uptimeMs) { if (mPhoneOn) { - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); mHistoryCur.states2 &= ~HistoryItem.STATE2_PHONE_IN_CALL_FLAG; if (DEBUG_HISTORY) Slog.v(TAG, "Phone off to: " + Integer.toHexString(mHistoryCur.states)); - addHistoryRecordLocked(elapsedRealtime, uptime); + addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); mPhoneOn = false; - mPhoneOnTimer.stopRunningLocked(elapsedRealtime); + mPhoneOnTimer.stopRunningLocked(elapsedRealtimeMs); } } @@ -5133,7 +5408,8 @@ public class BatteryStatsImpl extends BatteryStats { public void onReceive(Context context, Intent intent) { final boolean state = intent.getBooleanExtra(UsbManager.USB_CONNECTED, false); synchronized (BatteryStatsImpl.this) { - noteUsbConnectionStateLocked(state); + noteUsbConnectionStateLocked(state, mClocks.elapsedRealtime(), + mClocks.uptimeMillis()); } } }, usbStateFilter); @@ -5142,12 +5418,14 @@ public class BatteryStatsImpl extends BatteryStats { final Intent usbState = context.registerReceiver(null, usbStateFilter); final boolean initState = usbState != null && usbState.getBooleanExtra( UsbManager.USB_CONNECTED, false); - noteUsbConnectionStateLocked(initState); + noteUsbConnectionStateLocked(initState, mClocks.elapsedRealtime(), + mClocks.uptimeMillis()); } } } - private void noteUsbConnectionStateLocked(boolean connected) { + private void noteUsbConnectionStateLocked(boolean connected, long elapsedRealtimeMs, + long uptimeMs) { int newState = connected ? USB_DATA_CONNECTED : USB_DATA_DISCONNECTED; if (mUsbDataState != newState) { mUsbDataState = newState; @@ -5156,18 +5434,17 @@ public class BatteryStatsImpl extends BatteryStats { } else { mHistoryCur.states2 &= ~HistoryItem.STATE2_USB_DATA_LINK_FLAG; } - addHistoryRecordLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); } } - void stopAllPhoneSignalStrengthTimersLocked(int except) { - final long elapsedRealtime = mClocks.elapsedRealtime(); + void stopAllPhoneSignalStrengthTimersLocked(int except, long elapsedRealtimeMs) { for (int i = 0; i < CellSignalStrength.getNumSignalStrengthLevels(); i++) { if (i == except) { continue; } while (mPhoneSignalStrengthsTimer[i].isRunningLocked()) { - mPhoneSignalStrengthsTimer[i].stopRunningLocked(elapsedRealtime); + mPhoneSignalStrengthsTimer[i].stopRunningLocked(elapsedRealtimeMs); } } } @@ -5185,7 +5462,8 @@ public class BatteryStatsImpl extends BatteryStats { return state; } - private void updateAllPhoneStateLocked(int state, int simState, int strengthBin) { + private void updateAllPhoneStateLocked(int state, int simState, int strengthBin, + long elapsedRealtimeMs, long uptimeMs) { boolean scanning = false; boolean newHistory = false; @@ -5193,9 +5471,6 @@ public class BatteryStatsImpl extends BatteryStats { mPhoneSimStateRaw = simState; mPhoneSignalStrengthBinRaw = strengthBin; - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); - if (simState == TelephonyManager.SIM_STATE_ABSENT) { // In this case we will always be STATE_OUT_OF_SERVICE, so need // to infer that we are scanning from other data. @@ -5223,7 +5498,7 @@ public class BatteryStatsImpl extends BatteryStats { newHistory = true; if (DEBUG_HISTORY) Slog.v(TAG, "Phone started scanning to: " + Integer.toHexString(mHistoryCur.states)); - mPhoneSignalScanningTimer.startRunningLocked(elapsedRealtime); + mPhoneSignalScanningTimer.startRunningLocked(elapsedRealtimeMs); FrameworkStatsLog.write(FrameworkStatsLog.PHONE_SERVICE_STATE_CHANGED, state, simState, strengthBin); } @@ -5236,7 +5511,7 @@ public class BatteryStatsImpl extends BatteryStats { if (DEBUG_HISTORY) Slog.v(TAG, "Phone stopped scanning to: " + Integer.toHexString(mHistoryCur.states)); newHistory = true; - mPhoneSignalScanningTimer.stopRunningLocked(elapsedRealtime); + mPhoneSignalScanningTimer.stopRunningLocked(elapsedRealtimeMs); FrameworkStatsLog.write(FrameworkStatsLog.PHONE_SERVICE_STATE_CHANGED, state, simState, strengthBin); } @@ -5254,13 +5529,14 @@ public class BatteryStatsImpl extends BatteryStats { if (mPhoneSignalStrengthBin != strengthBin) { if (mPhoneSignalStrengthBin >= 0) { mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].stopRunningLocked( - elapsedRealtime); + elapsedRealtimeMs); } if (strengthBin >= 0) { if (!mPhoneSignalStrengthsTimer[strengthBin].isRunningLocked()) { - mPhoneSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtime); + mPhoneSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtimeMs); } - mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_MASK) + mHistoryCur.states = + (mHistoryCur.states & ~HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_MASK) | (strengthBin << HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_SHIFT); if (DEBUG_HISTORY) Slog.v(TAG, "Signal strength " + strengthBin + " to: " + Integer.toHexString(mHistoryCur.states)); @@ -5268,13 +5544,13 @@ public class BatteryStatsImpl extends BatteryStats { FrameworkStatsLog.write( FrameworkStatsLog.PHONE_SIGNAL_STRENGTH_CHANGED, strengthBin); } else { - stopAllPhoneSignalStrengthTimersLocked(-1); + stopAllPhoneSignalStrengthTimersLocked(-1, elapsedRealtimeMs); } mPhoneSignalStrengthBin = strengthBin; } if (newHistory) { - addHistoryRecordLocked(elapsedRealtime, uptime); + addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); } } @@ -5283,18 +5559,37 @@ public class BatteryStatsImpl extends BatteryStats { * @param state phone state from ServiceState.getState() */ public void notePhoneStateLocked(int state, int simState) { - updateAllPhoneStateLocked(state, simState, mPhoneSignalStrengthBinRaw); + notePhoneStateLocked(state, simState, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void notePhoneStateLocked(int state, int simState, + long elapsedRealtimeMs, long uptimeMs) { + updateAllPhoneStateLocked(state, simState, mPhoneSignalStrengthBinRaw, + elapsedRealtimeMs, uptimeMs); } @UnsupportedAppUsage public void notePhoneSignalStrengthLocked(SignalStrength signalStrength) { + notePhoneSignalStrengthLocked(signalStrength, + mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void notePhoneSignalStrengthLocked(SignalStrength signalStrength, + long elapsedRealtimeMs, long uptimeMs) { // Bin the strength. int bin = signalStrength.getLevel(); - updateAllPhoneStateLocked(mPhoneServiceStateRaw, mPhoneSimStateRaw, bin); + updateAllPhoneStateLocked(mPhoneServiceStateRaw, mPhoneSimStateRaw, bin, + elapsedRealtimeMs, uptimeMs); } @UnsupportedAppUsage public void notePhoneDataConnectionStateLocked(int dataType, boolean hasData, int serviceType) { + notePhoneDataConnectionStateLocked(dataType, hasData, serviceType, + mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void notePhoneDataConnectionStateLocked(int dataType, boolean hasData, int serviceType, + long elapsedRealtimeMs, long uptimeMs) { // BatteryStats uses 0 to represent no network type. // Telephony does not have a concept of no network type, and uses 0 to represent unknown. // Unknown is included in DATA_CONNECTION_OTHER. @@ -5318,312 +5613,374 @@ public class BatteryStatsImpl extends BatteryStats { } if (DEBUG) Log.i(TAG, "Phone Data Connection -> " + dataType + " = " + hasData); if (mPhoneDataConnectionType != bin) { - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_DATA_CONNECTION_MASK) | (bin << HistoryItem.STATE_DATA_CONNECTION_SHIFT); if (DEBUG_HISTORY) Slog.v(TAG, "Data connection " + bin + " to: " + Integer.toHexString(mHistoryCur.states)); - addHistoryRecordLocked(elapsedRealtime, uptime); + addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); if (mPhoneDataConnectionType >= 0) { mPhoneDataConnectionsTimer[mPhoneDataConnectionType].stopRunningLocked( - elapsedRealtime); + elapsedRealtimeMs); } mPhoneDataConnectionType = bin; - mPhoneDataConnectionsTimer[bin].startRunningLocked(elapsedRealtime); + mPhoneDataConnectionsTimer[bin].startRunningLocked(elapsedRealtimeMs); } } public void noteWifiOnLocked() { + noteWifiOnLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteWifiOnLocked(long elapsedRealtimeMs, long uptimeMs) { if (!mWifiOn) { - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); mHistoryCur.states2 |= HistoryItem.STATE2_WIFI_ON_FLAG; if (DEBUG_HISTORY) Slog.v(TAG, "WIFI on to: " + Integer.toHexString(mHistoryCur.states)); - addHistoryRecordLocked(elapsedRealtime, uptime); + addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); mWifiOn = true; - mWifiOnTimer.startRunningLocked(elapsedRealtime); + mWifiOnTimer.startRunningLocked(elapsedRealtimeMs); scheduleSyncExternalStatsLocked("wifi-off", ExternalStatsSync.UPDATE_WIFI); } } public void noteWifiOffLocked() { - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); + noteWifiOffLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteWifiOffLocked(long elapsedRealtimeMs, long uptimeMs) { if (mWifiOn) { mHistoryCur.states2 &= ~HistoryItem.STATE2_WIFI_ON_FLAG; if (DEBUG_HISTORY) Slog.v(TAG, "WIFI off to: " + Integer.toHexString(mHistoryCur.states)); - addHistoryRecordLocked(elapsedRealtime, uptime); + addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); mWifiOn = false; - mWifiOnTimer.stopRunningLocked(elapsedRealtime); + mWifiOnTimer.stopRunningLocked(elapsedRealtimeMs); scheduleSyncExternalStatsLocked("wifi-on", ExternalStatsSync.UPDATE_WIFI); } } @UnsupportedAppUsage public void noteAudioOnLocked(int uid) { + noteAudioOnLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteAudioOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { uid = mapUid(uid); - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); if (mAudioOnNesting == 0) { mHistoryCur.states |= HistoryItem.STATE_AUDIO_ON_FLAG; if (DEBUG_HISTORY) Slog.v(TAG, "Audio on to: " + Integer.toHexString(mHistoryCur.states)); - addHistoryRecordLocked(elapsedRealtime, uptime); - mAudioOnTimer.startRunningLocked(elapsedRealtime); + addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); + mAudioOnTimer.startRunningLocked(elapsedRealtimeMs); } mAudioOnNesting++; - getUidStatsLocked(uid).noteAudioTurnedOnLocked(elapsedRealtime); + getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) + .noteAudioTurnedOnLocked(elapsedRealtimeMs); } @UnsupportedAppUsage public void noteAudioOffLocked(int uid) { + noteAudioOffLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteAudioOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { if (mAudioOnNesting == 0) { return; } uid = mapUid(uid); - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); if (--mAudioOnNesting == 0) { mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG; if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: " + Integer.toHexString(mHistoryCur.states)); - addHistoryRecordLocked(elapsedRealtime, uptime); - mAudioOnTimer.stopRunningLocked(elapsedRealtime); + addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); + mAudioOnTimer.stopRunningLocked(elapsedRealtimeMs); } - getUidStatsLocked(uid).noteAudioTurnedOffLocked(elapsedRealtime); + getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) + .noteAudioTurnedOffLocked(elapsedRealtimeMs); } @UnsupportedAppUsage public void noteVideoOnLocked(int uid) { + noteVideoOnLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteVideoOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { uid = mapUid(uid); - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); if (mVideoOnNesting == 0) { mHistoryCur.states2 |= HistoryItem.STATE2_VIDEO_ON_FLAG; if (DEBUG_HISTORY) Slog.v(TAG, "Video on to: " + Integer.toHexString(mHistoryCur.states)); - addHistoryRecordLocked(elapsedRealtime, uptime); - mVideoOnTimer.startRunningLocked(elapsedRealtime); + addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); + mVideoOnTimer.startRunningLocked(elapsedRealtimeMs); } mVideoOnNesting++; - getUidStatsLocked(uid).noteVideoTurnedOnLocked(elapsedRealtime); + getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) + .noteVideoTurnedOnLocked(elapsedRealtimeMs); } @UnsupportedAppUsage public void noteVideoOffLocked(int uid) { + noteVideoOffLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteVideoOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { if (mVideoOnNesting == 0) { return; } uid = mapUid(uid); - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); if (--mVideoOnNesting == 0) { mHistoryCur.states2 &= ~HistoryItem.STATE2_VIDEO_ON_FLAG; if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: " + Integer.toHexString(mHistoryCur.states)); - addHistoryRecordLocked(elapsedRealtime, uptime); - mVideoOnTimer.stopRunningLocked(elapsedRealtime); + addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); + mVideoOnTimer.stopRunningLocked(elapsedRealtimeMs); } - getUidStatsLocked(uid).noteVideoTurnedOffLocked(elapsedRealtime); + getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) + .noteVideoTurnedOffLocked(elapsedRealtimeMs); } public void noteResetAudioLocked() { + noteResetAudioLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteResetAudioLocked(long elapsedRealtimeMs, long uptimeMs) { if (mAudioOnNesting > 0) { - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); mAudioOnNesting = 0; mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG; if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: " + Integer.toHexString(mHistoryCur.states)); - addHistoryRecordLocked(elapsedRealtime, uptime); - mAudioOnTimer.stopAllRunningLocked(elapsedRealtime); + addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); + mAudioOnTimer.stopAllRunningLocked(elapsedRealtimeMs); for (int i=0; i<mUidStats.size(); i++) { BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); - uid.noteResetAudioLocked(elapsedRealtime); + uid.noteResetAudioLocked(elapsedRealtimeMs); } } } public void noteResetVideoLocked() { + noteResetVideoLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteResetVideoLocked(long elapsedRealtimeMs, long uptimeMs) { if (mVideoOnNesting > 0) { - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); mVideoOnNesting = 0; mHistoryCur.states2 &= ~HistoryItem.STATE2_VIDEO_ON_FLAG; if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: " + Integer.toHexString(mHistoryCur.states)); - addHistoryRecordLocked(elapsedRealtime, uptime); - mVideoOnTimer.stopAllRunningLocked(elapsedRealtime); + addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); + mVideoOnTimer.stopAllRunningLocked(elapsedRealtimeMs); for (int i=0; i<mUidStats.size(); i++) { BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); - uid.noteResetVideoLocked(elapsedRealtime); + uid.noteResetVideoLocked(elapsedRealtimeMs); } } } public void noteActivityResumedLocked(int uid) { + noteActivityResumedLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteActivityResumedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { uid = mapUid(uid); - getUidStatsLocked(uid).noteActivityResumedLocked(mClocks.elapsedRealtime()); + getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) + .noteActivityResumedLocked(elapsedRealtimeMs); } public void noteActivityPausedLocked(int uid) { + noteActivityPausedLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteActivityPausedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { uid = mapUid(uid); - getUidStatsLocked(uid).noteActivityPausedLocked(mClocks.elapsedRealtime()); + getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) + .noteActivityPausedLocked(elapsedRealtimeMs); } public void noteVibratorOnLocked(int uid, long durationMillis) { + noteVibratorOnLocked(uid, durationMillis, + mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteVibratorOnLocked(int uid, long durationMillis, + long elapsedRealtimeMs, long uptimeMs) { uid = mapUid(uid); - getUidStatsLocked(uid).noteVibratorOnLocked(durationMillis); + getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) + .noteVibratorOnLocked(durationMillis, elapsedRealtimeMs); } public void noteVibratorOffLocked(int uid) { + noteVibratorOffLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteVibratorOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { uid = mapUid(uid); - getUidStatsLocked(uid).noteVibratorOffLocked(); + getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) + .noteVibratorOffLocked(elapsedRealtimeMs); } public void noteFlashlightOnLocked(int uid) { + noteFlashlightOnLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteFlashlightOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { uid = mapUid(uid); - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); if (mFlashlightOnNesting++ == 0) { mHistoryCur.states2 |= HistoryItem.STATE2_FLASHLIGHT_FLAG; if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight on to: " + Integer.toHexString(mHistoryCur.states2)); - addHistoryRecordLocked(elapsedRealtime, uptime); - mFlashlightOnTimer.startRunningLocked(elapsedRealtime); + addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); + mFlashlightOnTimer.startRunningLocked(elapsedRealtimeMs); } - getUidStatsLocked(uid).noteFlashlightTurnedOnLocked(elapsedRealtime); + getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) + .noteFlashlightTurnedOnLocked(elapsedRealtimeMs); } public void noteFlashlightOffLocked(int uid) { + noteFlashlightOffLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteFlashlightOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { if (mFlashlightOnNesting == 0) { return; } uid = mapUid(uid); - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); if (--mFlashlightOnNesting == 0) { mHistoryCur.states2 &= ~HistoryItem.STATE2_FLASHLIGHT_FLAG; if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight off to: " + Integer.toHexString(mHistoryCur.states2)); - addHistoryRecordLocked(elapsedRealtime, uptime); - mFlashlightOnTimer.stopRunningLocked(elapsedRealtime); + addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); + mFlashlightOnTimer.stopRunningLocked(elapsedRealtimeMs); } - getUidStatsLocked(uid).noteFlashlightTurnedOffLocked(elapsedRealtime); + getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) + .noteFlashlightTurnedOffLocked(elapsedRealtimeMs); } public void noteCameraOnLocked(int uid) { + noteCameraOnLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteCameraOnLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { uid = mapUid(uid); - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); if (mCameraOnNesting++ == 0) { mHistoryCur.states2 |= HistoryItem.STATE2_CAMERA_FLAG; if (DEBUG_HISTORY) Slog.v(TAG, "Camera on to: " + Integer.toHexString(mHistoryCur.states2)); - addHistoryRecordLocked(elapsedRealtime, uptime); - mCameraOnTimer.startRunningLocked(elapsedRealtime); + addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); + mCameraOnTimer.startRunningLocked(elapsedRealtimeMs); } - getUidStatsLocked(uid).noteCameraTurnedOnLocked(elapsedRealtime); + getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) + .noteCameraTurnedOnLocked(elapsedRealtimeMs); } public void noteCameraOffLocked(int uid) { + noteCameraOffLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteCameraOffLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { if (mCameraOnNesting == 0) { return; } uid = mapUid(uid); - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); if (--mCameraOnNesting == 0) { mHistoryCur.states2 &= ~HistoryItem.STATE2_CAMERA_FLAG; if (DEBUG_HISTORY) Slog.v(TAG, "Camera off to: " + Integer.toHexString(mHistoryCur.states2)); - addHistoryRecordLocked(elapsedRealtime, uptime); - mCameraOnTimer.stopRunningLocked(elapsedRealtime); + addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); + mCameraOnTimer.stopRunningLocked(elapsedRealtimeMs); } - getUidStatsLocked(uid).noteCameraTurnedOffLocked(elapsedRealtime); + getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) + .noteCameraTurnedOffLocked(elapsedRealtimeMs); } public void noteResetCameraLocked() { + noteResetCameraLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteResetCameraLocked(long elapsedRealtimeMs, long uptimeMs) { if (mCameraOnNesting > 0) { - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); mCameraOnNesting = 0; mHistoryCur.states2 &= ~HistoryItem.STATE2_CAMERA_FLAG; if (DEBUG_HISTORY) Slog.v(TAG, "Camera off to: " + Integer.toHexString(mHistoryCur.states2)); - addHistoryRecordLocked(elapsedRealtime, uptime); - mCameraOnTimer.stopAllRunningLocked(elapsedRealtime); + addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); + mCameraOnTimer.stopAllRunningLocked(elapsedRealtimeMs); for (int i=0; i<mUidStats.size(); i++) { BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); - uid.noteResetCameraLocked(elapsedRealtime); + uid.noteResetCameraLocked(elapsedRealtimeMs); } } } public void noteResetFlashlightLocked() { + noteResetFlashlightLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteResetFlashlightLocked(long elapsedRealtimeMs, long uptimeMs) { if (mFlashlightOnNesting > 0) { - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); mFlashlightOnNesting = 0; mHistoryCur.states2 &= ~HistoryItem.STATE2_FLASHLIGHT_FLAG; if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight off to: " + Integer.toHexString(mHistoryCur.states2)); - addHistoryRecordLocked(elapsedRealtime, uptime); - mFlashlightOnTimer.stopAllRunningLocked(elapsedRealtime); + addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); + mFlashlightOnTimer.stopAllRunningLocked(elapsedRealtimeMs); for (int i=0; i<mUidStats.size(); i++) { BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); - uid.noteResetFlashlightLocked(elapsedRealtime); + uid.noteResetFlashlightLocked(elapsedRealtimeMs); } } } private void noteBluetoothScanStartedLocked(WorkChain workChain, int uid, - boolean isUnoptimized) { + boolean isUnoptimized, long elapsedRealtimeMs, long uptimeMs) { uid = getAttributionUid(uid, workChain); - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); if (mBluetoothScanNesting == 0) { mHistoryCur.states2 |= HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG; if (DEBUG_HISTORY) Slog.v(TAG, "BLE scan started for: " + Integer.toHexString(mHistoryCur.states2)); - addHistoryRecordLocked(elapsedRealtime, uptime); - mBluetoothScanTimer.startRunningLocked(elapsedRealtime); + addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); + mBluetoothScanTimer.startRunningLocked(elapsedRealtimeMs); } mBluetoothScanNesting++; - getUidStatsLocked(uid).noteBluetoothScanStartedLocked(elapsedRealtime, isUnoptimized); + getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) + .noteBluetoothScanStartedLocked(elapsedRealtimeMs, isUnoptimized); } public void noteBluetoothScanStartedFromSourceLocked(WorkSource ws, boolean isUnoptimized) { + noteBluetoothScanStartedFromSourceLocked(ws, isUnoptimized, + mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteBluetoothScanStartedFromSourceLocked(WorkSource ws, boolean isUnoptimized, + long elapsedRealtimeMs, long uptimeMs) { final int N = ws.size(); for (int i = 0; i < N; i++) { - noteBluetoothScanStartedLocked(null, ws.getUid(i), isUnoptimized); + noteBluetoothScanStartedLocked(null, ws.getUid(i), isUnoptimized, + elapsedRealtimeMs, uptimeMs); } final List<WorkChain> workChains = ws.getWorkChains(); if (workChains != null) { for (int i = 0; i < workChains.size(); ++i) { - noteBluetoothScanStartedLocked(workChains.get(i), -1, isUnoptimized); + noteBluetoothScanStartedLocked(workChains.get(i), -1, isUnoptimized, + elapsedRealtimeMs, uptimeMs); } } } private void noteBluetoothScanStoppedLocked(WorkChain workChain, int uid, - boolean isUnoptimized) { + boolean isUnoptimized, long elapsedRealtimeMs, long uptimeMs) { uid = getAttributionUid(uid, workChain); - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); mBluetoothScanNesting--; if (mBluetoothScanNesting == 0) { mHistoryCur.states2 &= ~HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG; if (DEBUG_HISTORY) Slog.v(TAG, "BLE scan stopped for: " + Integer.toHexString(mHistoryCur.states2)); - addHistoryRecordLocked(elapsedRealtime, uptime); - mBluetoothScanTimer.stopRunningLocked(elapsedRealtime); + addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); + mBluetoothScanTimer.stopRunningLocked(elapsedRealtimeMs); } - getUidStatsLocked(uid).noteBluetoothScanStoppedLocked(elapsedRealtime, isUnoptimized); + getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) + .noteBluetoothScanStoppedLocked(elapsedRealtimeMs, isUnoptimized); } private int getAttributionUid(int uid, WorkChain workChain) { @@ -5635,41 +5992,58 @@ public class BatteryStatsImpl extends BatteryStats { } public void noteBluetoothScanStoppedFromSourceLocked(WorkSource ws, boolean isUnoptimized) { + noteBluetoothScanStoppedFromSourceLocked(ws, isUnoptimized, + mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteBluetoothScanStoppedFromSourceLocked(WorkSource ws, boolean isUnoptimized, + long elapsedRealtimeMs, long uptimeMs) { final int N = ws.size(); for (int i = 0; i < N; i++) { - noteBluetoothScanStoppedLocked(null, ws.getUid(i), isUnoptimized); + noteBluetoothScanStoppedLocked(null, ws.getUid(i), isUnoptimized, + elapsedRealtimeMs, uptimeMs); } final List<WorkChain> workChains = ws.getWorkChains(); if (workChains != null) { for (int i = 0; i < workChains.size(); ++i) { - noteBluetoothScanStoppedLocked(workChains.get(i), -1, isUnoptimized); + noteBluetoothScanStoppedLocked(workChains.get(i), -1, isUnoptimized, + elapsedRealtimeMs, uptimeMs); } } } public void noteResetBluetoothScanLocked() { + noteResetBluetoothScanLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteResetBluetoothScanLocked(long elapsedRealtimeMs, long uptimeMs) { if (mBluetoothScanNesting > 0) { - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); mBluetoothScanNesting = 0; mHistoryCur.states2 &= ~HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG; if (DEBUG_HISTORY) Slog.v(TAG, "BLE can stopped for: " + Integer.toHexString(mHistoryCur.states2)); - addHistoryRecordLocked(elapsedRealtime, uptime); - mBluetoothScanTimer.stopAllRunningLocked(elapsedRealtime); + addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); + mBluetoothScanTimer.stopAllRunningLocked(elapsedRealtimeMs); for (int i=0; i<mUidStats.size(); i++) { BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); - uid.noteResetBluetoothScanLocked(elapsedRealtime); + uid.noteResetBluetoothScanLocked(elapsedRealtimeMs); } } } public void noteBluetoothScanResultsFromSourceLocked(WorkSource ws, int numNewResults) { + noteBluetoothScanResultsFromSourceLocked(ws, numNewResults, + mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteBluetoothScanResultsFromSourceLocked(WorkSource ws, int numNewResults, + long elapsedRealtimeMs, long uptimeMs) { final int N = ws.size(); for (int i = 0; i < N; i++) { int uid = mapUid(ws.getUid(i)); - getUidStatsLocked(uid).noteBluetoothScanResultsLocked(numNewResults); + getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) + .noteBluetoothScanResultsLocked(numNewResults); } final List<WorkChain> workChains = ws.getWorkChains(); @@ -5677,7 +6051,8 @@ public class BatteryStatsImpl extends BatteryStats { for (int i = 0; i < workChains.size(); ++i) { final WorkChain wc = workChains.get(i); int uid = mapUid(wc.getAttributionUid()); - getUidStatsLocked(uid).noteBluetoothScanResultsLocked(numNewResults); + getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) + .noteBluetoothScanResultsLocked(numNewResults); } } } @@ -5687,55 +6062,62 @@ public class BatteryStatsImpl extends BatteryStats { uid = mapUid(uid); addHistoryEventLocked(elapsedRealtimeMillis, uptimeMillis, HistoryItem.EVENT_WAKEUP_AP, "", uid); - getUidStatsLocked(uid).noteWifiRadioApWakeupLocked(); + getUidStatsLocked(uid, elapsedRealtimeMillis, uptimeMillis).noteWifiRadioApWakeupLocked(); } public void noteWifiRadioPowerState(int powerState, long timestampNs, int uid) { - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); + noteWifiRadioPowerState(powerState, timestampNs, uid, + mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteWifiRadioPowerState(int powerState, long timestampNs, int uid, + long elapsedRealtimeMs, long uptimeMs) { if (mWifiRadioPowerState != powerState) { final boolean active = powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM || powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH; if (active) { if (uid > 0) { - noteWifiRadioApWakeupLocked(elapsedRealtime, uptime, uid); + noteWifiRadioApWakeupLocked(elapsedRealtimeMs, uptimeMs, uid); } mHistoryCur.states |= HistoryItem.STATE_WIFI_RADIO_ACTIVE_FLAG; - mWifiActiveTimer.startRunningLocked(elapsedRealtime); + mWifiActiveTimer.startRunningLocked(elapsedRealtimeMs); } else { mHistoryCur.states &= ~HistoryItem.STATE_WIFI_RADIO_ACTIVE_FLAG; - mWifiActiveTimer.stopRunningLocked( - timestampNs / (1000 * 1000)); + mWifiActiveTimer.stopRunningLocked(timestampNs / (1000 * 1000)); } if (DEBUG_HISTORY) Slog.v(TAG, "Wifi network active " + active + " to: " + Integer.toHexString(mHistoryCur.states)); - addHistoryRecordLocked(elapsedRealtime, uptime); + addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); mWifiRadioPowerState = powerState; } } public void noteWifiRunningLocked(WorkSource ws) { + noteWifiRunningLocked(ws, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteWifiRunningLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs) { if (!mGlobalWifiRunning) { - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); mHistoryCur.states2 |= HistoryItem.STATE2_WIFI_RUNNING_FLAG; if (DEBUG_HISTORY) Slog.v(TAG, "WIFI running to: " + Integer.toHexString(mHistoryCur.states)); - addHistoryRecordLocked(elapsedRealtime, uptime); + addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); mGlobalWifiRunning = true; - mGlobalWifiRunningTimer.startRunningLocked(elapsedRealtime); + mGlobalWifiRunningTimer.startRunningLocked(elapsedRealtimeMs); int N = ws.size(); for (int i=0; i<N; i++) { int uid = mapUid(ws.getUid(i)); - getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime); + getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) + .noteWifiRunningLocked(elapsedRealtimeMs); } List<WorkChain> workChains = ws.getWorkChains(); if (workChains != null) { for (int i = 0; i < workChains.size(); ++i) { int uid = mapUid(workChains.get(i).getAttributionUid()); - getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime); + getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) + .noteWifiRunningLocked(elapsedRealtimeMs); } } @@ -5746,33 +6128,42 @@ public class BatteryStatsImpl extends BatteryStats { } public void noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs) { + noteWifiRunningChangedLocked(oldWs, newWs, + mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs, + long elapsedRealtimeMs, long uptimeMs) { if (mGlobalWifiRunning) { - final long elapsedRealtime = mClocks.elapsedRealtime(); int N = oldWs.size(); for (int i=0; i<N; i++) { int uid = mapUid(oldWs.getUid(i)); - getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime); + getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) + .noteWifiStoppedLocked(elapsedRealtimeMs); } List<WorkChain> workChains = oldWs.getWorkChains(); if (workChains != null) { for (int i = 0; i < workChains.size(); ++i) { int uid = mapUid(workChains.get(i).getAttributionUid()); - getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime); + getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) + .noteWifiStoppedLocked(elapsedRealtimeMs); } } N = newWs.size(); for (int i=0; i<N; i++) { int uid = mapUid(newWs.getUid(i)); - getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime); + getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) + .noteWifiRunningLocked(elapsedRealtimeMs); } workChains = newWs.getWorkChains(); if (workChains != null) { for (int i = 0; i < workChains.size(); ++i) { int uid = mapUid(workChains.get(i).getAttributionUid()); - getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime); + getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) + .noteWifiRunningLocked(elapsedRealtimeMs); } } } else { @@ -5781,26 +6172,30 @@ public class BatteryStatsImpl extends BatteryStats { } public void noteWifiStoppedLocked(WorkSource ws) { + noteWifiStoppedLocked(ws, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteWifiStoppedLocked(WorkSource ws, long elapsedRealtimeMs, long uptimeMs) { if (mGlobalWifiRunning) { - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); mHistoryCur.states2 &= ~HistoryItem.STATE2_WIFI_RUNNING_FLAG; if (DEBUG_HISTORY) Slog.v(TAG, "WIFI stopped to: " + Integer.toHexString(mHistoryCur.states)); - addHistoryRecordLocked(elapsedRealtime, uptime); + addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); mGlobalWifiRunning = false; - mGlobalWifiRunningTimer.stopRunningLocked(elapsedRealtime); + mGlobalWifiRunningTimer.stopRunningLocked(elapsedRealtimeMs); int N = ws.size(); for (int i=0; i<N; i++) { int uid = mapUid(ws.getUid(i)); - getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime); + getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) + .noteWifiStoppedLocked(elapsedRealtimeMs); } List<WorkChain> workChains = ws.getWorkChains(); if (workChains != null) { for (int i = 0; i < workChains.size(); ++i) { int uid = mapUid(workChains.get(i).getAttributionUid()); - getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime); + getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) + .noteWifiStoppedLocked(elapsedRealtimeMs); } } @@ -5811,71 +6206,79 @@ public class BatteryStatsImpl extends BatteryStats { } public void noteWifiStateLocked(int wifiState, String accessPoint) { + noteWifiStateLocked(wifiState, accessPoint, mClocks.elapsedRealtime()); + } + + public void noteWifiStateLocked(int wifiState, String accessPoint, long elapsedRealtimeMs) { if (DEBUG) Log.i(TAG, "WiFi state -> " + wifiState); if (mWifiState != wifiState) { - final long elapsedRealtime = mClocks.elapsedRealtime(); if (mWifiState >= 0) { - mWifiStateTimer[mWifiState].stopRunningLocked(elapsedRealtime); + mWifiStateTimer[mWifiState].stopRunningLocked(elapsedRealtimeMs); } mWifiState = wifiState; - mWifiStateTimer[wifiState].startRunningLocked(elapsedRealtime); + mWifiStateTimer[wifiState].startRunningLocked(elapsedRealtimeMs); scheduleSyncExternalStatsLocked("wifi-state", ExternalStatsSync.UPDATE_WIFI); } } public void noteWifiSupplicantStateChangedLocked(int supplState, boolean failedAuth) { + noteWifiSupplicantStateChangedLocked(supplState, failedAuth, + mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteWifiSupplicantStateChangedLocked(int supplState, boolean failedAuth, + long elapsedRealtimeMs, long uptimeMs) { if (DEBUG) Log.i(TAG, "WiFi suppl state -> " + supplState); if (mWifiSupplState != supplState) { - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); if (mWifiSupplState >= 0) { - mWifiSupplStateTimer[mWifiSupplState].stopRunningLocked(elapsedRealtime); + mWifiSupplStateTimer[mWifiSupplState].stopRunningLocked(elapsedRealtimeMs); } mWifiSupplState = supplState; - mWifiSupplStateTimer[supplState].startRunningLocked(elapsedRealtime); + mWifiSupplStateTimer[supplState].startRunningLocked(elapsedRealtimeMs); mHistoryCur.states2 = (mHistoryCur.states2&~HistoryItem.STATE2_WIFI_SUPPL_STATE_MASK) | (supplState << HistoryItem.STATE2_WIFI_SUPPL_STATE_SHIFT); if (DEBUG_HISTORY) Slog.v(TAG, "Wifi suppl state " + supplState + " to: " + Integer.toHexString(mHistoryCur.states2)); - addHistoryRecordLocked(elapsedRealtime, uptime); + addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); } } - void stopAllWifiSignalStrengthTimersLocked(int except) { - final long elapsedRealtime = mClocks.elapsedRealtime(); + void stopAllWifiSignalStrengthTimersLocked(int except, long elapsedRealtimeMs) { for (int i = 0; i < NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { if (i == except) { continue; } while (mWifiSignalStrengthsTimer[i].isRunningLocked()) { - mWifiSignalStrengthsTimer[i].stopRunningLocked(elapsedRealtime); + mWifiSignalStrengthsTimer[i].stopRunningLocked(elapsedRealtimeMs); } } } public void noteWifiRssiChangedLocked(int newRssi) { + noteWifiRssiChangedLocked(newRssi, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteWifiRssiChangedLocked(int newRssi, long elapsedRealtimeMs, long uptimeMs) { int strengthBin = WifiManager.calculateSignalLevel(newRssi, NUM_WIFI_SIGNAL_STRENGTH_BINS); if (DEBUG) Log.i(TAG, "WiFi rssi -> " + newRssi + " bin=" + strengthBin); if (mWifiSignalStrengthBin != strengthBin) { - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); if (mWifiSignalStrengthBin >= 0) { mWifiSignalStrengthsTimer[mWifiSignalStrengthBin].stopRunningLocked( - elapsedRealtime); + elapsedRealtimeMs); } if (strengthBin >= 0) { if (!mWifiSignalStrengthsTimer[strengthBin].isRunningLocked()) { - mWifiSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtime); + mWifiSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtimeMs); } mHistoryCur.states2 = (mHistoryCur.states2&~HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_MASK) | (strengthBin << HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_SHIFT); if (DEBUG_HISTORY) Slog.v(TAG, "Wifi signal strength " + strengthBin + " to: " + Integer.toHexString(mHistoryCur.states2)); - addHistoryRecordLocked(elapsedRealtime, uptime); + addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); } else { - stopAllWifiSignalStrengthTimersLocked(-1); + stopAllWifiSignalStrengthTimersLocked(-1, elapsedRealtimeMs); } mWifiSignalStrengthBin = strengthBin; } @@ -5885,121 +6288,155 @@ public class BatteryStatsImpl extends BatteryStats { @UnsupportedAppUsage public void noteFullWifiLockAcquiredLocked(int uid) { - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); + noteFullWifiLockAcquiredLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteFullWifiLockAcquiredLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { if (mWifiFullLockNesting == 0) { mHistoryCur.states |= HistoryItem.STATE_WIFI_FULL_LOCK_FLAG; if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock on to: " + Integer.toHexString(mHistoryCur.states)); - addHistoryRecordLocked(elapsedRealtime, uptime); + addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); } mWifiFullLockNesting++; - getUidStatsLocked(uid).noteFullWifiLockAcquiredLocked(elapsedRealtime); + getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) + .noteFullWifiLockAcquiredLocked(elapsedRealtimeMs); } @UnsupportedAppUsage public void noteFullWifiLockReleasedLocked(int uid) { - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); + noteFullWifiLockReleasedLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteFullWifiLockReleasedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { mWifiFullLockNesting--; if (mWifiFullLockNesting == 0) { mHistoryCur.states &= ~HistoryItem.STATE_WIFI_FULL_LOCK_FLAG; if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock off to: " + Integer.toHexString(mHistoryCur.states)); - addHistoryRecordLocked(elapsedRealtime, uptime); + addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); } - getUidStatsLocked(uid).noteFullWifiLockReleasedLocked(elapsedRealtime); + getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) + .noteFullWifiLockReleasedLocked(elapsedRealtimeMs); } int mWifiScanNesting = 0; public void noteWifiScanStartedLocked(int uid) { - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); + noteWifiScanStartedLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteWifiScanStartedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { if (mWifiScanNesting == 0) { mHistoryCur.states |= HistoryItem.STATE_WIFI_SCAN_FLAG; if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan started for: " + Integer.toHexString(mHistoryCur.states)); - addHistoryRecordLocked(elapsedRealtime, uptime); + addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); } mWifiScanNesting++; - getUidStatsLocked(uid).noteWifiScanStartedLocked(elapsedRealtime); + getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) + .noteWifiScanStartedLocked(elapsedRealtimeMs); } public void noteWifiScanStoppedLocked(int uid) { - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); + noteWifiScanStoppedLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteWifiScanStoppedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { mWifiScanNesting--; if (mWifiScanNesting == 0) { mHistoryCur.states &= ~HistoryItem.STATE_WIFI_SCAN_FLAG; if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan stopped for: " + Integer.toHexString(mHistoryCur.states)); - addHistoryRecordLocked(elapsedRealtime, uptime); + addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); } - getUidStatsLocked(uid).noteWifiScanStoppedLocked(elapsedRealtime); + getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) + .noteWifiScanStoppedLocked(elapsedRealtimeMs); } public void noteWifiBatchedScanStartedLocked(int uid, int csph) { + noteWifiBatchedScanStartedLocked(uid, csph, + mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteWifiBatchedScanStartedLocked(int uid, int csph, + long elapsedRealtimeMs, long uptimeMs) { uid = mapUid(uid); - final long elapsedRealtime = mClocks.elapsedRealtime(); - getUidStatsLocked(uid).noteWifiBatchedScanStartedLocked(csph, elapsedRealtime); + getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) + .noteWifiBatchedScanStartedLocked(csph, elapsedRealtimeMs); } public void noteWifiBatchedScanStoppedLocked(int uid) { + noteWifiBatchedScanStoppedLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteWifiBatchedScanStoppedLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { uid = mapUid(uid); - final long elapsedRealtime = mClocks.elapsedRealtime(); - getUidStatsLocked(uid).noteWifiBatchedScanStoppedLocked(elapsedRealtime); + getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) + .noteWifiBatchedScanStoppedLocked(elapsedRealtimeMs); } int mWifiMulticastNesting = 0; @UnsupportedAppUsage public void noteWifiMulticastEnabledLocked(int uid) { + noteWifiMulticastEnabledLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteWifiMulticastEnabledLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { uid = mapUid(uid); - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); if (mWifiMulticastNesting == 0) { mHistoryCur.states |= HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG; if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast on to: " + Integer.toHexString(mHistoryCur.states)); - addHistoryRecordLocked(elapsedRealtime, uptime); + addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); // Start Wifi Multicast overall timer if (!mWifiMulticastWakelockTimer.isRunningLocked()) { if (DEBUG_HISTORY) Slog.v(TAG, "WiFi Multicast Overall Timer Started"); - mWifiMulticastWakelockTimer.startRunningLocked(elapsedRealtime); + mWifiMulticastWakelockTimer.startRunningLocked(elapsedRealtimeMs); } } mWifiMulticastNesting++; - getUidStatsLocked(uid).noteWifiMulticastEnabledLocked(elapsedRealtime); + getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) + .noteWifiMulticastEnabledLocked(elapsedRealtimeMs); } @UnsupportedAppUsage public void noteWifiMulticastDisabledLocked(int uid) { + noteWifiMulticastDisabledLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteWifiMulticastDisabledLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { uid = mapUid(uid); - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); mWifiMulticastNesting--; if (mWifiMulticastNesting == 0) { mHistoryCur.states &= ~HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG; if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast off to: " + Integer.toHexString(mHistoryCur.states)); - addHistoryRecordLocked(elapsedRealtime, uptime); + addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); // Stop Wifi Multicast overall timer if (mWifiMulticastWakelockTimer.isRunningLocked()) { if (DEBUG_HISTORY) Slog.v(TAG, "Multicast Overall Timer Stopped"); - mWifiMulticastWakelockTimer.stopRunningLocked(elapsedRealtime); + mWifiMulticastWakelockTimer.stopRunningLocked(elapsedRealtimeMs); } } - getUidStatsLocked(uid).noteWifiMulticastDisabledLocked(elapsedRealtime); + getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs) + .noteWifiMulticastDisabledLocked(elapsedRealtimeMs); } public void noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws) { + noteFullWifiLockAcquiredFromSourceLocked(ws, + mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws, + long elapsedRealtimeMs, long uptimeMs) { int N = ws.size(); for (int i=0; i<N; i++) { final int uid = mapUid(ws.getUid(i)); - noteFullWifiLockAcquiredLocked(uid); + noteFullWifiLockAcquiredLocked(uid, elapsedRealtimeMs, uptimeMs); } final List<WorkChain> workChains = ws.getWorkChains(); @@ -6007,16 +6444,22 @@ public class BatteryStatsImpl extends BatteryStats { for (int i = 0; i < workChains.size(); ++i) { final WorkChain workChain = workChains.get(i); final int uid = mapUid(workChain.getAttributionUid()); - noteFullWifiLockAcquiredLocked(uid); + noteFullWifiLockAcquiredLocked(uid, elapsedRealtimeMs, uptimeMs); } } } public void noteFullWifiLockReleasedFromSourceLocked(WorkSource ws) { + noteFullWifiLockReleasedFromSourceLocked(ws, + mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteFullWifiLockReleasedFromSourceLocked(WorkSource ws, + long elapsedRealtimeMs, long uptimeMs) { int N = ws.size(); for (int i=0; i<N; i++) { final int uid = mapUid(ws.getUid(i)); - noteFullWifiLockReleasedLocked(uid); + noteFullWifiLockReleasedLocked(uid, elapsedRealtimeMs, uptimeMs); } final List<WorkChain> workChains = ws.getWorkChains(); @@ -6024,16 +6467,21 @@ public class BatteryStatsImpl extends BatteryStats { for (int i = 0; i < workChains.size(); ++i) { final WorkChain workChain = workChains.get(i); final int uid = mapUid(workChain.getAttributionUid()); - noteFullWifiLockReleasedLocked(uid); + noteFullWifiLockReleasedLocked(uid, elapsedRealtimeMs, uptimeMs); } } } public void noteWifiScanStartedFromSourceLocked(WorkSource ws) { + noteWifiScanStartedFromSourceLocked(ws, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteWifiScanStartedFromSourceLocked(WorkSource ws, + long elapsedRealtimeMs, long uptimeMs) { int N = ws.size(); for (int i=0; i<N; i++) { final int uid = mapUid(ws.getUid(i)); - noteWifiScanStartedLocked(uid); + noteWifiScanStartedLocked(uid, elapsedRealtimeMs, uptimeMs); } final List<WorkChain> workChains = ws.getWorkChains(); @@ -6041,16 +6489,21 @@ public class BatteryStatsImpl extends BatteryStats { for (int i = 0; i < workChains.size(); ++i) { final WorkChain workChain = workChains.get(i); final int uid = mapUid(workChain.getAttributionUid()); - noteWifiScanStartedLocked(uid); + noteWifiScanStartedLocked(uid, elapsedRealtimeMs, uptimeMs); } } } public void noteWifiScanStoppedFromSourceLocked(WorkSource ws) { + noteWifiScanStoppedFromSourceLocked(ws, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteWifiScanStoppedFromSourceLocked(WorkSource ws, + long elapsedRealtimeMs, long uptimeMs) { int N = ws.size(); for (int i=0; i<N; i++) { final int uid = mapUid(ws.getUid(i)); - noteWifiScanStoppedLocked(uid); + noteWifiScanStoppedLocked(uid, elapsedRealtimeMs, uptimeMs); } final List<WorkChain> workChains = ws.getWorkChains(); @@ -6058,35 +6511,48 @@ public class BatteryStatsImpl extends BatteryStats { for (int i = 0; i < workChains.size(); ++i) { final WorkChain workChain = workChains.get(i); final int uid = mapUid(workChain.getAttributionUid()); - noteWifiScanStoppedLocked(uid); + noteWifiScanStoppedLocked(uid, elapsedRealtimeMs, uptimeMs); } } } public void noteWifiBatchedScanStartedFromSourceLocked(WorkSource ws, int csph) { + noteWifiBatchedScanStartedFromSourceLocked(ws, csph, + mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteWifiBatchedScanStartedFromSourceLocked(WorkSource ws, int csph, + long elapsedRealtimeMs, long uptimeMs) { int N = ws.size(); for (int i=0; i<N; i++) { - noteWifiBatchedScanStartedLocked(ws.getUid(i), csph); + noteWifiBatchedScanStartedLocked(ws.getUid(i), csph, elapsedRealtimeMs, uptimeMs); } final List<WorkChain> workChains = ws.getWorkChains(); if (workChains != null) { for (int i = 0; i < workChains.size(); ++i) { - noteWifiBatchedScanStartedLocked(workChains.get(i).getAttributionUid(), csph); + noteWifiBatchedScanStartedLocked(workChains.get(i).getAttributionUid(), csph, + elapsedRealtimeMs, uptimeMs); } } } public void noteWifiBatchedScanStoppedFromSourceLocked(WorkSource ws) { + noteWifiBatchedScanStoppedFromSourceLocked(ws, + mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + public void noteWifiBatchedScanStoppedFromSourceLocked(WorkSource ws, + long elapsedRealtimeMs, long uptimeMs) { int N = ws.size(); for (int i=0; i<N; i++) { - noteWifiBatchedScanStoppedLocked(ws.getUid(i)); + noteWifiBatchedScanStoppedLocked(ws.getUid(i), elapsedRealtimeMs, uptimeMs); } final List<WorkChain> workChains = ws.getWorkChains(); if (workChains != null) { for (int i = 0; i < workChains.size(); ++i) { - noteWifiBatchedScanStoppedLocked(workChains.get(i).getAttributionUid()); + noteWifiBatchedScanStoppedLocked(workChains.get(i).getAttributionUid(), + elapsedRealtimeMs, uptimeMs); } } } @@ -6147,9 +6613,16 @@ public class BatteryStatsImpl extends BatteryStats { */ public void noteBinderCallStats(int workSourceUid, long incrementalCallCount, Collection<BinderCallsStats.CallStat> callStats, int[] binderThreadNativeTids) { + noteBinderCallStats(workSourceUid, incrementalCallCount, callStats, binderThreadNativeTids, + mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public void noteBinderCallStats(int workSourceUid, long incrementalCallCount, + Collection<BinderCallsStats.CallStat> callStats, int[] binderThreadNativeTids, + long elapsedRealtimeMs, long uptimeMs) { synchronized (this) { - getUidStatsLocked(workSourceUid).noteBinderCallStatsLocked(incrementalCallCount, - callStats); + getUidStatsLocked(workSourceUid, elapsedRealtimeMs, uptimeMs) + .noteBinderCallStatsLocked(incrementalCallCount, callStats); mSystemServerCpuThreadReader.setBinderThreadNativeTids(binderThreadNativeTids); } } @@ -6182,17 +6655,17 @@ public class BatteryStatsImpl extends BatteryStats { for (int i = 0; i < mUidStats.size(); i++) { Uid uid = mUidStats.valueAt(i); - long totalTimeForUid = 0; + long totalTimeForUidUs = 0; int totalCallCountForUid = 0; ArraySet<BinderCallStats> binderCallStats = uid.mBinderCallStats; for (int j = binderCallStats.size() - 1; j >= 0; j--) { BinderCallStats stats = binderCallStats.valueAt(j); totalCallCountForUid += stats.callCount; if (stats.recordedCallCount > 0) { - totalTimeForUid += + totalTimeForUidUs += stats.callCount * stats.recordedCpuTimeMicros / stats.recordedCallCount; } else if (totalRecordedCallCount > 0) { - totalTimeForUid += + totalTimeForUidUs += stats.callCount * totalRecordedCallTimeMicros / totalRecordedCallCount; } } @@ -6200,13 +6673,13 @@ public class BatteryStatsImpl extends BatteryStats { if (totalCallCountForUid < uid.mBinderCallCount && totalRecordedCallCount > 0) { // Estimate remaining calls, which were not tracked because of binder call // stats sampling - totalTimeForUid += + totalTimeForUidUs += (uid.mBinderCallCount - totalCallCountForUid) * totalRecordedCallTimeMicros / totalRecordedCallCount; } - uid.mSystemServiceTimeUs = totalTimeForUid; - totalSystemServiceTimeMicros += totalTimeForUid; + uid.mSystemServiceTimeUs = totalTimeForUidUs; + totalSystemServiceTimeMicros += totalTimeForUidUs; } for (int i = 0; i < mUidStats.size(); i++) { @@ -6296,9 +6769,9 @@ public class BatteryStatsImpl extends BatteryStats { @Override public long getLongestDeviceIdleModeTime(int mode) { switch (mode) { case DEVICE_IDLE_MODE_LIGHT: - return mLongestLightIdleTime; + return mLongestLightIdleTimeMs; case DEVICE_IDLE_MODE_DEEP: - return mLongestFullIdleTime; + return mLongestFullIdleTimeMs; } return 0; } @@ -6328,12 +6801,12 @@ public class BatteryStatsImpl extends BatteryStats { } @Override public long getGpsSignalQualityTime(int strengthBin, - long elapsedRealtimeUs, int which) { + long elapsedRealtimeUs, int which) { if (strengthBin < 0 || strengthBin >= GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS) { return 0; } return mGpsSignalQualityTimer[strengthBin].getTotalTimeLocked( - elapsedRealtimeUs, which); + elapsedRealtimeUs, which); } @Override public long getGpsBatteryDrainMaMs() { @@ -6344,11 +6817,11 @@ public class BatteryStatsImpl extends BatteryStats { } double energyUsedMaMs = 0.0; final int which = STATS_SINCE_CHARGED; - final long rawRealtime = SystemClock.elapsedRealtime() * 1000; + final long rawRealtimeUs = SystemClock.elapsedRealtime() * 1000; for(int i=0; i < GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) { energyUsedMaMs - += mPowerProfile.getAveragePower(PowerProfile.POWER_GPS_SIGNAL_QUALITY_BASED, i) - * (getGpsSignalQualityTime(i, rawRealtime, which) / 1000); + += mPowerProfile.getAveragePower(PowerProfile.POWER_GPS_SIGNAL_QUALITY_BASED, i) + * (getGpsSignalQualityTime(i, rawRealtimeUs, which) / 1000); } return (long) energyUsedMaMs; } @@ -6562,18 +7035,18 @@ public class BatteryStatsImpl extends BatteryStats { } @Override public long getStartClockTime() { - final long currentTime = System.currentTimeMillis(); - if ((currentTime > MILLISECONDS_IN_YEAR - && mStartClockTime < (currentTime - MILLISECONDS_IN_YEAR)) - || (mStartClockTime > currentTime)) { + final long currentTimeMs = System.currentTimeMillis(); + if ((currentTimeMs > MILLISECONDS_IN_YEAR + && mStartClockTimeMs < (currentTimeMs - MILLISECONDS_IN_YEAR)) + || (mStartClockTimeMs > currentTimeMs)) { // If the start clock time has changed by more than a year, then presumably // the previous time was completely bogus. So we are going to figure out a // new time based on how much time has elapsed since we started counting. - recordCurrentTimeChangeLocked(currentTime, mClocks.elapsedRealtime(), + recordCurrentTimeChangeLocked(currentTimeMs, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); - return currentTime - (mClocks.elapsedRealtime() - (mRealtimeStart / 1000)); + return currentTimeMs - (mClocks.elapsedRealtime() - (mRealtimeStartUs / 1000)); } - return mStartClockTime; + return mStartClockTimeMs; } @Override public String getStartPlatformVersion() { @@ -6597,29 +7070,32 @@ public class BatteryStatsImpl extends BatteryStats { return mUidStats; } - private static <T extends TimeBaseObs> boolean resetIfNotNull(T t, boolean detachIfReset) { + private static <T extends TimeBaseObs> boolean resetIfNotNull(T t, boolean detachIfReset, + long elapsedRealtimeUs) { if (t != null) { - return t.reset(detachIfReset); + return t.reset(detachIfReset, elapsedRealtimeUs); } return true; } - private static <T extends TimeBaseObs> boolean resetIfNotNull(T[] t, boolean detachIfReset) { + private static <T extends TimeBaseObs> boolean resetIfNotNull(T[] t, boolean detachIfReset, + long elapsedRealtimeUs) { if (t != null) { boolean ret = true; for (int i = 0; i < t.length; i++) { - ret &= resetIfNotNull(t[i], detachIfReset); + ret &= resetIfNotNull(t[i], detachIfReset, elapsedRealtimeUs); } return ret; } return true; } - private static <T extends TimeBaseObs> boolean resetIfNotNull(T[][] t, boolean detachIfReset) { + private static <T extends TimeBaseObs> boolean resetIfNotNull(T[][] t, boolean detachIfReset, + long elapsedRealtimeUs) { if (t != null) { boolean ret = true; for (int i = 0; i < t.length; i++) { - ret &= resetIfNotNull(t[i], detachIfReset); + ret &= resetIfNotNull(t[i], detachIfReset, elapsedRealtimeUs); } return ret; } @@ -6627,9 +7103,9 @@ public class BatteryStatsImpl extends BatteryStats { } private static boolean resetIfNotNull(ControllerActivityCounterImpl counter, - boolean detachIfReset) { + boolean detachIfReset, long elapsedRealtimeUs) { if (counter != null) { - counter.reset(detachIfReset); + counter.reset(detachIfReset, elapsedRealtimeUs); } return true; } @@ -6812,10 +7288,10 @@ public class BatteryStatsImpl extends BatteryStats { /** * The CPU times we had at the last history details update. */ - long mLastStepUserTime; - long mLastStepSystemTime; - long mCurStepUserTime; - long mCurStepSystemTime; + long mLastStepUserTimeMs; + long mLastStepSystemTimeMs; + long mCurStepUserTimeMs; + long mCurStepSystemTimeMs; LongSamplingCounter mUserCpuTime; LongSamplingCounter mSystemCpuTime; @@ -6915,17 +7391,19 @@ public class BatteryStatsImpl extends BatteryStats { private double mProportionalSystemServiceUsage; public Uid(BatteryStatsImpl bsi, int uid) { + this(bsi, uid, bsi.mClocks.elapsedRealtime(), bsi.mClocks.uptimeMillis()); + } + + public Uid(BatteryStatsImpl bsi, int uid, long elapsedRealtimeMs, long uptimeMs) { mBsi = bsi; mUid = uid; /* Observer list of TimeBase object in Uid is short */ mOnBatteryBackgroundTimeBase = new TimeBase(false); - mOnBatteryBackgroundTimeBase.init(mBsi.mClocks.uptimeMillis() * 1000, - mBsi.mClocks.elapsedRealtime() * 1000); + mOnBatteryBackgroundTimeBase.init(uptimeMs * 1000, elapsedRealtimeMs * 1000); /* Observer list of TimeBase object in Uid is short */ mOnBatteryScreenOffBackgroundTimeBase = new TimeBase(false); - mOnBatteryScreenOffBackgroundTimeBase.init(mBsi.mClocks.uptimeMillis() * 1000, - mBsi.mClocks.elapsedRealtime() * 1000); + mOnBatteryScreenOffBackgroundTimeBase.init(uptimeMs * 1000, elapsedRealtimeMs * 1000); mUserCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); mSystemCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); @@ -7520,13 +7998,13 @@ public class BatteryStatsImpl extends BatteryStats { return mVibratorOnTimer; } - public void noteVibratorOnLocked(long durationMillis) { - createVibratorOnTimerLocked().addDuration(mBsi, durationMillis); + public void noteVibratorOnLocked(long durationMillis, long elapsedRealtimeMs) { + createVibratorOnTimerLocked().addDuration(mBsi, durationMillis, elapsedRealtimeMs); } - public void noteVibratorOffLocked() { + public void noteVibratorOffLocked(long elapsedRealtimeMs) { if (mVibratorOnTimer != null) { - mVibratorOnTimer.abortLastDuration(mBsi); + mVibratorOnTimer.abortLastDuration(mBsi, elapsedRealtimeMs); } } @@ -7962,58 +8440,58 @@ public class BatteryStatsImpl extends BatteryStats { * inactive so can be dropped. */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) - public boolean reset(long uptime, long realtime) { + public boolean reset(long uptimeUs, long realtimeUs) { boolean active = false; - mOnBatteryBackgroundTimeBase.init(uptime, realtime); - mOnBatteryScreenOffBackgroundTimeBase.init(uptime, realtime); + mOnBatteryBackgroundTimeBase.init(uptimeUs, realtimeUs); + mOnBatteryScreenOffBackgroundTimeBase.init(uptimeUs, realtimeUs); if (mWifiRunningTimer != null) { - active |= !mWifiRunningTimer.reset(false); + active |= !mWifiRunningTimer.reset(false, realtimeUs); active |= mWifiRunning; } if (mFullWifiLockTimer != null) { - active |= !mFullWifiLockTimer.reset(false); + active |= !mFullWifiLockTimer.reset(false, realtimeUs); active |= mFullWifiLockOut; } if (mWifiScanTimer != null) { - active |= !mWifiScanTimer.reset(false); + active |= !mWifiScanTimer.reset(false, realtimeUs); active |= mWifiScanStarted; } if (mWifiBatchedScanTimer != null) { for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) { if (mWifiBatchedScanTimer[i] != null) { - active |= !mWifiBatchedScanTimer[i].reset(false); + active |= !mWifiBatchedScanTimer[i].reset(false, realtimeUs); } } active |= (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED); } if (mWifiMulticastTimer != null) { - active |= !mWifiMulticastTimer.reset(false); + active |= !mWifiMulticastTimer.reset(false, realtimeUs); active |= (mWifiMulticastWakelockCount > 0); } - active |= !resetIfNotNull(mAudioTurnedOnTimer, false); - active |= !resetIfNotNull(mVideoTurnedOnTimer, false); - active |= !resetIfNotNull(mFlashlightTurnedOnTimer, false); - active |= !resetIfNotNull(mCameraTurnedOnTimer, false); - active |= !resetIfNotNull(mForegroundActivityTimer, false); - active |= !resetIfNotNull(mForegroundServiceTimer, false); - active |= !resetIfNotNull(mAggregatedPartialWakelockTimer, false); - active |= !resetIfNotNull(mBluetoothScanTimer, false); - active |= !resetIfNotNull(mBluetoothUnoptimizedScanTimer, false); + active |= !resetIfNotNull(mAudioTurnedOnTimer, false, realtimeUs); + active |= !resetIfNotNull(mVideoTurnedOnTimer, false, realtimeUs); + active |= !resetIfNotNull(mFlashlightTurnedOnTimer, false, realtimeUs); + active |= !resetIfNotNull(mCameraTurnedOnTimer, false, realtimeUs); + active |= !resetIfNotNull(mForegroundActivityTimer, false, realtimeUs); + active |= !resetIfNotNull(mForegroundServiceTimer, false, realtimeUs); + active |= !resetIfNotNull(mAggregatedPartialWakelockTimer, false, realtimeUs); + active |= !resetIfNotNull(mBluetoothScanTimer, false, realtimeUs); + active |= !resetIfNotNull(mBluetoothUnoptimizedScanTimer, false, realtimeUs); - resetIfNotNull(mBluetoothScanResultCounter, false); - resetIfNotNull(mBluetoothScanResultBgCounter, false); + resetIfNotNull(mBluetoothScanResultCounter, false, realtimeUs); + resetIfNotNull(mBluetoothScanResultBgCounter, false, realtimeUs); if (mProcessStateTimer != null) { for (int i = 0; i < NUM_PROCESS_STATE; i++) { - active |= !resetIfNotNull(mProcessStateTimer[i], false); + active |= !resetIfNotNull(mProcessStateTimer[i], false, realtimeUs); } active |= (mProcessState != ActivityManager.PROCESS_STATE_NONEXISTENT); } if (mVibratorOnTimer != null) { - if (mVibratorOnTimer.reset(false)) { + if (mVibratorOnTimer.reset(false, realtimeUs)) { mVibratorOnTimer.detach(); mVibratorOnTimer = null; } else { @@ -8021,80 +8499,81 @@ public class BatteryStatsImpl extends BatteryStats { } } - resetIfNotNull(mUserActivityCounters, false); + resetIfNotNull(mUserActivityCounters, false, realtimeUs); - resetIfNotNull(mNetworkByteActivityCounters, false); - resetIfNotNull(mNetworkPacketActivityCounters, false); - resetIfNotNull(mMobileRadioActiveTime, false); - resetIfNotNull(mMobileRadioActiveCount, false); + resetIfNotNull(mNetworkByteActivityCounters, false, realtimeUs); + resetIfNotNull(mNetworkPacketActivityCounters, false, realtimeUs); + resetIfNotNull(mMobileRadioActiveTime, false, realtimeUs); + resetIfNotNull(mMobileRadioActiveCount, false, realtimeUs); - resetIfNotNull(mWifiControllerActivity, false); - resetIfNotNull(mBluetoothControllerActivity, false); - resetIfNotNull(mModemControllerActivity, false); + resetIfNotNull(mWifiControllerActivity, false, realtimeUs); + resetIfNotNull(mBluetoothControllerActivity, false, realtimeUs); + resetIfNotNull(mModemControllerActivity, false, realtimeUs); - resetIfNotNull(mUserCpuTime, false); - resetIfNotNull(mSystemCpuTime, false); + resetIfNotNull(mUserCpuTime, false, realtimeUs); + resetIfNotNull(mSystemCpuTime, false, realtimeUs); - resetIfNotNull(mCpuClusterSpeedTimesUs, false); + resetIfNotNull(mCpuClusterSpeedTimesUs, false, realtimeUs); - resetIfNotNull(mCpuFreqTimeMs, false); - resetIfNotNull(mScreenOffCpuFreqTimeMs, false); + resetIfNotNull(mCpuFreqTimeMs, false, realtimeUs /* unused */); + resetIfNotNull(mScreenOffCpuFreqTimeMs, false, realtimeUs /* unused */); - resetIfNotNull(mCpuActiveTimeMs, false); - resetIfNotNull(mCpuClusterTimesMs, false); + resetIfNotNull(mCpuActiveTimeMs, false, realtimeUs /* unused */); + resetIfNotNull(mCpuClusterTimesMs, false, realtimeUs /* unused */); - resetIfNotNull(mProcStateTimeMs, false); + resetIfNotNull(mProcStateTimeMs, false, realtimeUs /* unused */); - resetIfNotNull(mProcStateScreenOffTimeMs, false); + resetIfNotNull(mProcStateScreenOffTimeMs, false, realtimeUs /* unused */); - resetIfNotNull(mMobileRadioApWakeupCount, false); + resetIfNotNull(mMobileRadioApWakeupCount, false, realtimeUs); - resetIfNotNull(mWifiRadioApWakeupCount, false); + resetIfNotNull(mWifiRadioApWakeupCount, false, realtimeUs); final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap(); for (int iw=wakeStats.size()-1; iw>=0; iw--) { Wakelock wl = wakeStats.valueAt(iw); - if (wl.reset()) { + if (wl.reset(realtimeUs)) { wakeStats.removeAt(iw); } else { active = true; } } - mWakelockStats.cleanup(); + final long realtimeMs = realtimeUs / 1000; + mWakelockStats.cleanup(realtimeMs); final ArrayMap<String, DualTimer> syncStats = mSyncStats.getMap(); for (int is=syncStats.size()-1; is>=0; is--) { DualTimer timer = syncStats.valueAt(is); - if (timer.reset(false)) { + if (timer.reset(false, realtimeUs)) { syncStats.removeAt(is); timer.detach(); } else { active = true; } } - mSyncStats.cleanup(); + mSyncStats.cleanup(realtimeMs); final ArrayMap<String, DualTimer> jobStats = mJobStats.getMap(); for (int ij=jobStats.size()-1; ij>=0; ij--) { DualTimer timer = jobStats.valueAt(ij); - if (timer.reset(false)) { + if (timer.reset(false, realtimeUs)) { jobStats.removeAt(ij); timer.detach(); } else { active = true; } } - mJobStats.cleanup(); + mJobStats.cleanup(realtimeMs); mJobCompletions.clear(); - resetIfNotNull(mJobsDeferredEventCount, false); - resetIfNotNull(mJobsDeferredCount, false); - resetIfNotNull(mJobsFreshnessTimeMs, false); - resetIfNotNull(mJobsFreshnessBuckets, false); + resetIfNotNull(mJobsDeferredEventCount, false, realtimeUs); + resetIfNotNull(mJobsDeferredCount, false, realtimeUs); + resetIfNotNull(mJobsFreshnessTimeMs, false, realtimeUs /* unused */); + resetIfNotNull(mJobsFreshnessBuckets, false, realtimeUs); for (int ise = mSensorStats.size() - 1; ise >= 0; ise--) { Sensor s = mSensorStats.valueAt(ise); - if (s.reset()) { + if (s.reset(realtimeUs)) { mSensorStats.removeAt(ise); } else { active = true; @@ -8128,8 +8607,8 @@ public class BatteryStatsImpl extends BatteryStats { mProportionalSystemServiceUsage = 0; - mLastStepUserTime = mLastStepSystemTime = 0; - mCurStepUserTime = mCurStepSystemTime = 0; + mLastStepUserTimeMs = mLastStepSystemTimeMs = 0; + mCurStepUserTimeMs = mCurStepSystemTimeMs = 0; return !active; @@ -8943,13 +9422,13 @@ public class BatteryStatsImpl extends BatteryStats { return new DualTimer(mBsi.mClocks, mUid, type, pool, timeBase, bgTimeBase, in); } - boolean reset() { + boolean reset(long elapsedRealtimeUs) { boolean wlactive = false; - wlactive |= !resetIfNotNull(mTimerFull,false); - wlactive |= !resetIfNotNull(mTimerPartial,false); - wlactive |= !resetIfNotNull(mTimerWindow,false); - wlactive |= !resetIfNotNull(mTimerDraw,false); + wlactive |= !resetIfNotNull(mTimerFull, false, elapsedRealtimeUs); + wlactive |= !resetIfNotNull(mTimerPartial, false, elapsedRealtimeUs); + wlactive |= !resetIfNotNull(mTimerWindow, false, elapsedRealtimeUs); + wlactive |= !resetIfNotNull(mTimerDraw, false, elapsedRealtimeUs); if (!wlactive) { detachIfNotNull(mTimerFull); @@ -9040,8 +9519,8 @@ public class BatteryStatsImpl extends BatteryStats { return new DualTimer(mBsi.mClocks, mUid, 0, pool, timeBase, bgTimeBase, in); } - boolean reset() { - if (mTimer.reset(true)) { + boolean reset(long elapsedRealtimeUs) { + if (mTimer.reset(true, elapsedRealtimeUs)) { mTimer = null; return true; } @@ -9103,17 +9582,17 @@ public class BatteryStatsImpl extends BatteryStats { /** * Total time (in ms) spent executing in user code. */ - long mUserTime; + long mUserTimeMs; /** * Total time (in ms) spent executing in kernel code. */ - long mSystemTime; + long mSystemTimeMs; /** * Amount of time (in ms) the process was running in the foreground. */ - long mForegroundTime; + long mForegroundTimeMs; /** * Number of times the process has been started. @@ -9138,14 +9617,16 @@ public class BatteryStatsImpl extends BatteryStats { mBsi.mOnBatteryTimeBase.add(this); } - public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) { + public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, + long baseRealtimeUs) { } - public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { + public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, + long baseRealtimeUs) { } @Override - public boolean reset(boolean detachIfReset) { + public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { if (detachIfReset) { this.detach(); } @@ -9169,14 +9650,14 @@ public class BatteryStatsImpl extends BatteryStats { return null; } - public void addExcessiveCpu(long overTime, long usedTime) { + public void addExcessiveCpu(long overTimeMs, long usedTimeMs) { if (mExcessivePower == null) { mExcessivePower = new ArrayList<ExcessivePower>(); } ExcessivePower ew = new ExcessivePower(); ew.type = ExcessivePower.TYPE_CPU; - ew.overTime = overTime; - ew.usedTime = usedTime; + ew.overTime = overTimeMs; + ew.usedTime = usedTimeMs; mExcessivePower.add(ew); } @@ -9219,9 +9700,9 @@ public class BatteryStatsImpl extends BatteryStats { } void writeToParcelLocked(Parcel out) { - out.writeLong(mUserTime); - out.writeLong(mSystemTime); - out.writeLong(mForegroundTime); + out.writeLong(mUserTimeMs); + out.writeLong(mSystemTimeMs); + out.writeLong(mForegroundTimeMs); out.writeInt(mStarts); out.writeInt(mNumCrashes); out.writeInt(mNumAnrs); @@ -9229,9 +9710,9 @@ public class BatteryStatsImpl extends BatteryStats { } void readFromParcelLocked(Parcel in) { - mUserTime = in.readLong(); - mSystemTime = in.readLong(); - mForegroundTime = in.readLong(); + mUserTimeMs = in.readLong(); + mSystemTimeMs = in.readLong(); + mForegroundTimeMs = in.readLong(); mStarts = in.readInt(); mNumCrashes = in.readInt(); mNumAnrs = in.readInt(); @@ -9239,20 +9720,20 @@ public class BatteryStatsImpl extends BatteryStats { } @UnsupportedAppUsage - public void addCpuTimeLocked(int utime, int stime) { - addCpuTimeLocked(utime, stime, mBsi.mOnBatteryTimeBase.isRunning()); + public void addCpuTimeLocked(int utimeMs, int stimeMs) { + addCpuTimeLocked(utimeMs, stimeMs, mBsi.mOnBatteryTimeBase.isRunning()); } - public void addCpuTimeLocked(int utime, int stime, boolean isRunning) { + public void addCpuTimeLocked(int utimeMs, int stimeMs, boolean isRunning) { if (isRunning) { - mUserTime += utime; - mSystemTime += stime; + mUserTimeMs += utimeMs; + mSystemTimeMs += stimeMs; } } @UnsupportedAppUsage - public void addForegroundTimeLocked(long ttime) { - mForegroundTime += ttime; + public void addForegroundTimeLocked(long ttimeMs) { + mForegroundTimeMs += ttimeMs; } @UnsupportedAppUsage @@ -9276,19 +9757,19 @@ public class BatteryStatsImpl extends BatteryStats { @Override @UnsupportedAppUsage public long getUserTime(int which) { - return mUserTime; + return mUserTimeMs; } @Override @UnsupportedAppUsage public long getSystemTime(int which) { - return mSystemTime; + return mSystemTimeMs; } @Override @UnsupportedAppUsage public long getForegroundTime(int which) { - return mForegroundTime; + return mForegroundTimeMs; } @Override @@ -9333,14 +9814,16 @@ public class BatteryStatsImpl extends BatteryStats { mBsi.mOnBatteryScreenOffTimeBase.add(this); } - public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) { + public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, + long baseRealtimeUs) { } - public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { + public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, + long baseRealtimeUs) { } @Override - public boolean reset(boolean detachIfReset) { + public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { if (detachIfReset) { this.detach(); } @@ -9430,13 +9913,13 @@ public class BatteryStatsImpl extends BatteryStats { /** * Total time (ms in battery uptime) the service has been left started. */ - protected long mStartTime; + protected long mStartTimeMs; /** * If service has been started and not yet stopped, this is * when it was started. */ - protected long mRunningSince; + protected long mRunningSinceMs; /** * True if we are currently running. @@ -9451,13 +9934,13 @@ public class BatteryStatsImpl extends BatteryStats { /** * Total time (ms in battery uptime) the service has been left launched. */ - protected long mLaunchedTime; + protected long mLaunchedTimeMs; /** * If service has been launched and not yet exited, this is * when it was launched (ms in battery uptime). */ - protected long mLaunchedSince; + protected long mLaunchedSinceMs; /** * True if we are currently launched. @@ -9477,16 +9960,16 @@ public class BatteryStatsImpl extends BatteryStats { mBsi.mOnBatteryTimeBase.add(this); } - public void onTimeStarted(long elapsedRealtime, long baseUptime, - long baseRealtime) { + public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, + long baseRealtimeUs) { } - public void onTimeStopped(long elapsedRealtime, long baseUptime, - long baseRealtime) { + public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, + long baseRealtimeUs) { } @Override - public boolean reset(boolean detachIfReset) { + public boolean reset(boolean detachIfReset, long elapsedRealtimeUs) { if (detachIfReset) { this.detach(); } @@ -9495,59 +9978,68 @@ public class BatteryStatsImpl extends BatteryStats { /** * Remove this Serv as a listener from the time base. - */ + Ms*/ @Override public void detach() { mBsi.mOnBatteryTimeBase.remove(this); } public void readFromParcelLocked(Parcel in) { - mStartTime = in.readLong(); - mRunningSince = in.readLong(); + mStartTimeMs = in.readLong(); + mRunningSinceMs = in.readLong(); mRunning = in.readInt() != 0; mStarts = in.readInt(); - mLaunchedTime = in.readLong(); - mLaunchedSince = in.readLong(); + mLaunchedTimeMs = in.readLong(); + mLaunchedSinceMs = in.readLong(); mLaunched = in.readInt() != 0; mLaunches = in.readInt(); } public void writeToParcelLocked(Parcel out) { - out.writeLong(mStartTime); - out.writeLong(mRunningSince); + out.writeLong(mStartTimeMs); + out.writeLong(mRunningSinceMs); out.writeInt(mRunning ? 1 : 0); out.writeInt(mStarts); - out.writeLong(mLaunchedTime); - out.writeLong(mLaunchedSince); + out.writeLong(mLaunchedTimeMs); + out.writeLong(mLaunchedSinceMs); out.writeInt(mLaunched ? 1 : 0); out.writeInt(mLaunches); } - public long getLaunchTimeToNowLocked(long batteryUptime) { - if (!mLaunched) return mLaunchedTime; - return mLaunchedTime + batteryUptime - mLaunchedSince; + public long getLaunchTimeToNowLocked(long batteryUptimeMs) { + if (!mLaunched) return mLaunchedTimeMs; + return mLaunchedTimeMs + batteryUptimeMs - mLaunchedSinceMs; } - public long getStartTimeToNowLocked(long batteryUptime) { - if (!mRunning) return mStartTime; - return mStartTime + batteryUptime - mRunningSince; + public long getStartTimeToNowLocked(long batteryUptimeMs) { + if (!mRunning) return mStartTimeMs; + return mStartTimeMs + batteryUptimeMs - mRunningSinceMs; } @UnsupportedAppUsage public void startLaunchedLocked() { + startLaunchedLocked(mBsi.mClocks.uptimeMillis()); + } + + public void startLaunchedLocked(long uptimeMs) { if (!mLaunched) { mLaunches++; - mLaunchedSince = mBsi.getBatteryUptimeLocked(); + mLaunchedSinceMs = mBsi.getBatteryUptimeLocked(uptimeMs) / 1000; mLaunched = true; } } @UnsupportedAppUsage public void stopLaunchedLocked() { + stopLaunchedLocked(mBsi.mClocks.uptimeMillis()); + } + + public void stopLaunchedLocked(long uptimeMs) { if (mLaunched) { - long time = mBsi.getBatteryUptimeLocked() - mLaunchedSince; - if (time > 0) { - mLaunchedTime += time; + long timeMs = mBsi.getBatteryUptimeLocked(uptimeMs) / 1000 + - mLaunchedSinceMs; + if (timeMs > 0) { + mLaunchedTimeMs += timeMs; } else { mLaunches--; } @@ -9557,19 +10049,28 @@ public class BatteryStatsImpl extends BatteryStats { @UnsupportedAppUsage public void startRunningLocked() { + startRunningLocked(mBsi.mClocks.uptimeMillis()); + } + + public void startRunningLocked(long uptimeMs) { if (!mRunning) { mStarts++; - mRunningSince = mBsi.getBatteryUptimeLocked(); + mRunningSinceMs = mBsi.getBatteryUptimeLocked(uptimeMs) / 1000; mRunning = true; } } @UnsupportedAppUsage public void stopRunningLocked() { + stopRunningLocked(mBsi.mClocks.uptimeMillis()); + } + + public void stopRunningLocked(long uptimeMs) { if (mRunning) { - long time = mBsi.getBatteryUptimeLocked() - mRunningSince; - if (time > 0) { - mStartTime += time; + long timeMs = mBsi.getBatteryUptimeLocked(uptimeMs) / 1000 + - mRunningSinceMs; + if (timeMs > 0) { + mStartTimeMs += timeMs; } else { mStarts--; } @@ -9619,6 +10120,12 @@ public class BatteryStatsImpl extends BatteryStats { @GuardedBy("mBsi") public void updateUidProcessStateLocked(int procState) { + updateUidProcessStateLocked(procState, + mBsi.mClocks.elapsedRealtime(), mBsi.mClocks.uptimeMillis()); + } + + public void updateUidProcessStateLocked(int procState, + long elapsedRealtimeMs, long uptimeMs) { int uidRunningState; // Make special note of Foreground Services final boolean userAwareService = @@ -9629,10 +10136,7 @@ public class BatteryStatsImpl extends BatteryStats { return; } - final long elapsedRealtimeMs = mBsi.mClocks.elapsedRealtime(); if (mProcessState != uidRunningState) { - final long uptimeMs = mBsi.mClocks.uptimeMillis(); - if (mProcessState != ActivityManager.PROCESS_STATE_NONEXISTENT) { mProcessStateTimer[mProcessState].stopRunningLocked(elapsedRealtimeMs); @@ -9789,28 +10293,28 @@ public class BatteryStatsImpl extends BatteryStats { } public void noteStartSyncLocked(String name, long elapsedRealtimeMs) { - DualTimer t = mSyncStats.startObject(name); + DualTimer t = mSyncStats.startObject(name, elapsedRealtimeMs); if (t != null) { t.startRunningLocked(elapsedRealtimeMs); } } public void noteStopSyncLocked(String name, long elapsedRealtimeMs) { - DualTimer t = mSyncStats.stopObject(name); + DualTimer t = mSyncStats.stopObject(name, elapsedRealtimeMs); if (t != null) { t.stopRunningLocked(elapsedRealtimeMs); } } public void noteStartJobLocked(String name, long elapsedRealtimeMs) { - DualTimer t = mJobStats.startObject(name); + DualTimer t = mJobStats.startObject(name, elapsedRealtimeMs); if (t != null) { t.startRunningLocked(elapsedRealtimeMs); } } public void noteStopJobLocked(String name, long elapsedRealtimeMs, int stopReason) { - DualTimer t = mJobStats.stopObject(name); + DualTimer t = mJobStats.stopObject(name, elapsedRealtimeMs); if (t != null) { t.stopRunningLocked(elapsedRealtimeMs); } @@ -9873,7 +10377,7 @@ public class BatteryStatsImpl extends BatteryStats { } public void noteStartWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) { - Wakelock wl = mWakelockStats.startObject(name); + Wakelock wl = mWakelockStats.startObject(name, elapsedRealtimeMs); if (wl != null) { getWakelockTimerLocked(wl, type).startRunningLocked(elapsedRealtimeMs); } @@ -9889,7 +10393,7 @@ public class BatteryStatsImpl extends BatteryStats { } public void noteStopWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) { - Wakelock wl = mWakelockStats.stopObject(name); + Wakelock wl = mWakelockStats.stopObject(name, elapsedRealtimeMs); if (wl != null) { StopwatchTimer wlt = getWakelockTimerLocked(wl, type); wlt.stopRunningLocked(elapsedRealtimeMs); @@ -9910,10 +10414,10 @@ public class BatteryStatsImpl extends BatteryStats { } } - public void reportExcessiveCpuLocked(String proc, long overTime, long usedTime) { + public void reportExcessiveCpuLocked(String proc, long overTimeMs, long usedTimeMs) { Proc p = getProcessStatsLocked(proc); if (p != null) { - p.addExcessiveCpu(overTime, usedTime); + p.addExcessiveCpu(overTimeMs, usedTimeMs); } } @@ -10041,16 +10545,16 @@ public class BatteryStatsImpl extends BatteryStats { mDischargeDeepDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase); mDischargeCounter = new LongSamplingCounter(mOnBatteryTimeBase); mOnBattery = mOnBatteryInternal = false; - long uptime = mClocks.uptimeMillis() * 1000; - long realtime = mClocks.elapsedRealtime() * 1000; - initTimes(uptime, realtime); + long uptimeUs = mClocks.uptimeMillis() * 1000; + long realtimeUs = mClocks.elapsedRealtime() * 1000; + initTimes(uptimeUs, realtimeUs); mStartPlatformVersion = mEndPlatformVersion = Build.ID; mDischargeStartLevel = 0; mDischargeUnplugLevel = 0; mDischargePlugLevel = -1; mDischargeCurrentLevel = 0; mCurrentBatteryLevel = 0; - initDischarge(); + initDischarge(realtimeUs); clearHistoryLocked(); updateDailyDeadlineLocked(); mPlatformIdleStateCallback = cb; @@ -10110,9 +10614,9 @@ public class BatteryStatsImpl extends BatteryStats { mCallback = cb; } - public void setRadioScanningTimeoutLocked(long timeout) { + public void setRadioScanningTimeoutLocked(long timeoutUs) { if (mPhoneSignalScanningTimer != null) { - mPhoneSignalScanningTimer.setTimeout(timeout); + mPhoneSignalScanningTimer.setTimeout(timeoutUs); } } @@ -10122,9 +10626,9 @@ public class BatteryStatsImpl extends BatteryStats { public void updateDailyDeadlineLocked() { // Get the current time. - long currentTime = mDailyStartTime = System.currentTimeMillis(); + long currentTimeMs = mDailyStartTimeMs = System.currentTimeMillis(); Calendar calDeadline = Calendar.getInstance(); - calDeadline.setTimeInMillis(currentTime); + calDeadline.setTimeInMillis(currentTimeMs); // Move time up to the next day, ranging from 1am to 3pm. calDeadline.set(Calendar.DAY_OF_YEAR, calDeadline.get(Calendar.DAY_OF_YEAR) + 1); @@ -10132,25 +10636,24 @@ public class BatteryStatsImpl extends BatteryStats { calDeadline.set(Calendar.SECOND, 0); calDeadline.set(Calendar.MINUTE, 0); calDeadline.set(Calendar.HOUR_OF_DAY, 1); - mNextMinDailyDeadline = calDeadline.getTimeInMillis(); + mNextMinDailyDeadlineMs = calDeadline.getTimeInMillis(); calDeadline.set(Calendar.HOUR_OF_DAY, 3); - mNextMaxDailyDeadline = calDeadline.getTimeInMillis(); + mNextMaxDailyDeadlineMs = calDeadline.getTimeInMillis(); } - public void recordDailyStatsIfNeededLocked(boolean settled) { - long currentTime = System.currentTimeMillis(); - if (currentTime >= mNextMaxDailyDeadline) { + public void recordDailyStatsIfNeededLocked(boolean settled, long currentTimeMs) { + if (currentTimeMs >= mNextMaxDailyDeadlineMs) { recordDailyStatsLocked(); - } else if (settled && currentTime >= mNextMinDailyDeadline) { + } else if (settled && currentTimeMs >= mNextMinDailyDeadlineMs) { recordDailyStatsLocked(); - } else if (currentTime < (mDailyStartTime-(1000*60*60*24))) { + } else if (currentTimeMs < (mDailyStartTimeMs - (1000 * 60 * 60 * 24))) { recordDailyStatsLocked(); } } public void recordDailyStatsLocked() { DailyItem item = new DailyItem(); - item.mStartTime = mDailyStartTime; + item.mStartTime = mDailyStartTimeMs; item.mEndTime = System.currentTimeMillis(); boolean hasData = false; if (mDailyDischargeStepTracker.mNumStepDurations > 0) { @@ -10175,7 +10678,7 @@ public class BatteryStatsImpl extends BatteryStats { updateDailyDeadlineLocked(); if (hasData) { - final long startTime = SystemClock.uptimeMillis(); + final long startTimeMs = SystemClock.uptimeMillis(); mDailyItems.add(item); while (mDailyItems.size() > MAX_DAILY_ITEMS) { mDailyItems.remove(0); @@ -10185,12 +10688,12 @@ public class BatteryStatsImpl extends BatteryStats { XmlSerializer out = new FastXmlSerializer(); out.setOutput(memStream, StandardCharsets.UTF_8.name()); writeDailyItemsLocked(out); - final long initialTime = SystemClock.uptimeMillis() - startTime; + final long initialTimeMs = SystemClock.uptimeMillis() - startTimeMs; BackgroundThread.getHandler().post(new Runnable() { @Override public void run() { synchronized (mCheckinFile) { - final long startTime2 = SystemClock.uptimeMillis(); + final long startTimeMs2 = SystemClock.uptimeMillis(); FileOutputStream stream = null; try { stream = mDailyFile.startWrite(); @@ -10199,7 +10702,7 @@ public class BatteryStatsImpl extends BatteryStats { mDailyFile.finishWrite(stream); com.android.internal.logging.EventLogTags.writeCommitSysConfigFile( "batterystats-daily", - initialTime + SystemClock.uptimeMillis() - startTime2); + initialTimeMs + SystemClock.uptimeMillis() - startTimeMs2); } catch (IOException e) { Slog.w("BatteryStats", "Error writing battery daily items", e); @@ -10431,17 +10934,17 @@ public class BatteryStatsImpl extends BatteryStats { @Override public long getCurrentDailyStartTime() { - return mDailyStartTime; + return mDailyStartTimeMs; } @Override public long getNextMinDailyDeadline() { - return mNextMinDailyDeadline; + return mNextMinDailyDeadlineMs; } @Override public long getNextMaxDailyDeadline() { - return mNextMaxDailyDeadline; + return mNextMaxDailyDeadlineMs; } @Override @@ -10554,12 +11057,12 @@ public class BatteryStatsImpl extends BatteryStats { if (p == null) { return false; } - final long lastRealtime = out.time; - final long lastWalltime = out.currentTime; + final long lastRealtimeMs = out.time; + final long lastWalltimeMs = out.currentTime; readHistoryDelta(p, out); if (out.cmd != HistoryItem.CMD_CURRENT_TIME - && out.cmd != HistoryItem.CMD_RESET && lastWalltime != 0) { - out.currentTime = lastWalltime + (out.time - lastRealtime); + && out.cmd != HistoryItem.CMD_RESET && lastWalltimeMs != 0) { + out.currentTime = lastWalltimeMs + (out.time - lastRealtimeMs); } return true; } @@ -10574,7 +11077,7 @@ public class BatteryStatsImpl extends BatteryStats { @Override public long getHistoryBaseTime() { - return mHistoryBaseTime; + return mHistoryBaseTimeMs; } @Override @@ -10604,17 +11107,17 @@ public class BatteryStatsImpl extends BatteryStats { return state == Display.STATE_DOZE || state == Display.STATE_DOZE_SUSPEND; } - void initTimes(long uptime, long realtime) { - mStartClockTime = System.currentTimeMillis(); - mOnBatteryTimeBase.init(uptime, realtime); - mOnBatteryScreenOffTimeBase.init(uptime, realtime); - mRealtime = 0; - mUptime = 0; - mRealtimeStart = realtime; - mUptimeStart = uptime; + void initTimes(long uptimeUs, long realtimeUs) { + mStartClockTimeMs = System.currentTimeMillis(); + mOnBatteryTimeBase.init(uptimeUs, realtimeUs); + mOnBatteryScreenOffTimeBase.init(uptimeUs, realtimeUs); + mRealtimeUs = 0; + mUptimeUs = 0; + mRealtimeStartUs = realtimeUs; + mUptimeStartUs = uptimeUs; } - void initDischarge() { + void initDischarge(long elapsedRealtimeUs) { mLowDischargeAmountSinceCharge = 0; mHighDischargeAmountSinceCharge = 0; mDischargeAmountScreenOn = 0; @@ -10625,26 +11128,26 @@ public class BatteryStatsImpl extends BatteryStats { mDischargeAmountScreenDozeSinceCharge = 0; mDischargeStepTracker.init(); mChargeStepTracker.init(); - mDischargeScreenOffCounter.reset(false); - mDischargeScreenDozeCounter.reset(false); - mDischargeLightDozeCounter.reset(false); - mDischargeDeepDozeCounter.reset(false); - mDischargeCounter.reset(false); + mDischargeScreenOffCounter.reset(false, elapsedRealtimeUs); + mDischargeScreenDozeCounter.reset(false, elapsedRealtimeUs); + mDischargeLightDozeCounter.reset(false, elapsedRealtimeUs); + mDischargeDeepDozeCounter.reset(false, elapsedRealtimeUs); + mDischargeCounter.reset(false, elapsedRealtimeUs); } public void resetAllStatsCmdLocked() { - resetAllStatsLocked(); final long mSecUptime = mClocks.uptimeMillis(); - long uptime = mSecUptime * 1000; + long uptimeUs = mSecUptime * 1000; long mSecRealtime = mClocks.elapsedRealtime(); - long realtime = mSecRealtime * 1000; + long realtimeUs = mSecRealtime * 1000; + resetAllStatsLocked(mSecUptime, mSecRealtime); mDischargeStartLevel = mHistoryCur.batteryLevel; pullPendingStateUpdatesLocked(); addHistoryRecordLocked(mSecRealtime, mSecUptime); mDischargeCurrentLevel = mDischargeUnplugLevel = mDischargePlugLevel = mCurrentBatteryLevel = mHistoryCur.batteryLevel; - mOnBatteryTimeBase.reset(uptime, realtime); - mOnBatteryScreenOffTimeBase.reset(uptime, realtime); + mOnBatteryTimeBase.reset(uptimeUs, realtimeUs); + mOnBatteryScreenOffTimeBase.reset(uptimeUs, realtimeUs); if ((mHistoryCur.states&HistoryItem.STATE_BATTERY_PLUGGED_FLAG) == 0) { if (isScreenOn(mScreenState)) { mDischargeScreenOnUnplugLevel = mHistoryCur.batteryLevel; @@ -10666,15 +11169,15 @@ public class BatteryStatsImpl extends BatteryStats { initActiveHistoryEventsLocked(mSecRealtime, mSecUptime); } - private void resetAllStatsLocked() { - final long uptimeMillis = mClocks.uptimeMillis(); - final long elapsedRealtimeMillis = mClocks.elapsedRealtime(); + private void resetAllStatsLocked(long uptimeMillis, long elapsedRealtimeMillis) { + final long uptimeUs = uptimeMillis * 1000; + final long elapsedRealtimeUs = elapsedRealtimeMillis * 1000; mStartCount = 0; - initTimes(uptimeMillis * 1000, elapsedRealtimeMillis * 1000); - mScreenOnTimer.reset(false); - mScreenDozeTimer.reset(false); + initTimes(uptimeUs, elapsedRealtimeUs); + mScreenOnTimer.reset(false, uptimeUs); + mScreenDozeTimer.reset(false, elapsedRealtimeUs); for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { - mScreenBrightnessTimer[i].reset(false); + mScreenBrightnessTimer[i].reset(false, elapsedRealtimeUs); } if (mPowerProfile != null) { @@ -10684,60 +11187,60 @@ public class BatteryStatsImpl extends BatteryStats { } mMinLearnedBatteryCapacity = -1; mMaxLearnedBatteryCapacity = -1; - mInteractiveTimer.reset(false); - mPowerSaveModeEnabledTimer.reset(false); - mLastIdleTimeStart = elapsedRealtimeMillis; - mLongestLightIdleTime = 0; - mLongestFullIdleTime = 0; - mDeviceIdleModeLightTimer.reset(false); - mDeviceIdleModeFullTimer.reset(false); - mDeviceLightIdlingTimer.reset(false); - mDeviceIdlingTimer.reset(false); - mPhoneOnTimer.reset(false); - mAudioOnTimer.reset(false); - mVideoOnTimer.reset(false); - mFlashlightOnTimer.reset(false); - mCameraOnTimer.reset(false); - mBluetoothScanTimer.reset(false); + mInteractiveTimer.reset(false, elapsedRealtimeUs); + mPowerSaveModeEnabledTimer.reset(false, elapsedRealtimeUs); + mLastIdleTimeStartMs = elapsedRealtimeMillis; + mLongestLightIdleTimeMs = 0; + mLongestFullIdleTimeMs = 0; + mDeviceIdleModeLightTimer.reset(false, elapsedRealtimeUs); + mDeviceIdleModeFullTimer.reset(false, elapsedRealtimeUs); + mDeviceLightIdlingTimer.reset(false, elapsedRealtimeUs); + mDeviceIdlingTimer.reset(false, elapsedRealtimeUs); + mPhoneOnTimer.reset(false, elapsedRealtimeUs); + mAudioOnTimer.reset(false, elapsedRealtimeUs); + mVideoOnTimer.reset(false, elapsedRealtimeUs); + mFlashlightOnTimer.reset(false, elapsedRealtimeUs); + mCameraOnTimer.reset(false, elapsedRealtimeUs); + mBluetoothScanTimer.reset(false, elapsedRealtimeUs); for (int i = 0; i < CellSignalStrength.getNumSignalStrengthLevels(); i++) { - mPhoneSignalStrengthsTimer[i].reset(false); + mPhoneSignalStrengthsTimer[i].reset(false, elapsedRealtimeUs); } - mPhoneSignalScanningTimer.reset(false); + mPhoneSignalScanningTimer.reset(false, elapsedRealtimeUs); for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { - mPhoneDataConnectionsTimer[i].reset(false); + mPhoneDataConnectionsTimer[i].reset(false, elapsedRealtimeUs); } for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) { - mNetworkByteActivityCounters[i].reset(false); - mNetworkPacketActivityCounters[i].reset(false); - } - mMobileRadioActiveTimer.reset(false); - mMobileRadioActivePerAppTimer.reset(false); - mMobileRadioActiveAdjustedTime.reset(false); - mMobileRadioActiveUnknownTime.reset(false); - mMobileRadioActiveUnknownCount.reset(false); - mWifiOnTimer.reset(false); - mGlobalWifiRunningTimer.reset(false); + mNetworkByteActivityCounters[i].reset(false, elapsedRealtimeUs); + mNetworkPacketActivityCounters[i].reset(false, elapsedRealtimeUs); + } + mMobileRadioActiveTimer.reset(false, elapsedRealtimeUs); + mMobileRadioActivePerAppTimer.reset(false, elapsedRealtimeUs); + mMobileRadioActiveAdjustedTime.reset(false, elapsedRealtimeUs); + mMobileRadioActiveUnknownTime.reset(false, elapsedRealtimeUs); + mMobileRadioActiveUnknownCount.reset(false, elapsedRealtimeUs); + mWifiOnTimer.reset(false, elapsedRealtimeUs); + mGlobalWifiRunningTimer.reset(false, elapsedRealtimeUs); for (int i=0; i<NUM_WIFI_STATES; i++) { - mWifiStateTimer[i].reset(false); + mWifiStateTimer[i].reset(false, elapsedRealtimeUs); } for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { - mWifiSupplStateTimer[i].reset(false); + mWifiSupplStateTimer[i].reset(false, elapsedRealtimeUs); } for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { - mWifiSignalStrengthsTimer[i].reset(false); + mWifiSignalStrengthsTimer[i].reset(false, elapsedRealtimeUs); } - mWifiMulticastWakelockTimer.reset(false); - mWifiActiveTimer.reset(false); - mWifiActivity.reset(false); + mWifiMulticastWakelockTimer.reset(false, elapsedRealtimeUs); + mWifiActiveTimer.reset(false, elapsedRealtimeUs); + mWifiActivity.reset(false, elapsedRealtimeUs); for (int i=0; i< GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) { - mGpsSignalQualityTimer[i].reset(false); + mGpsSignalQualityTimer[i].reset(false, elapsedRealtimeUs); } - mBluetoothActivity.reset(false); - mModemActivity.reset(false); + mBluetoothActivity.reset(false, elapsedRealtimeUs); + mModemActivity.reset(false, elapsedRealtimeUs); mNumConnectivityChange = 0; for (int i=0; i<mUidStats.size(); i++) { - if (mUidStats.valueAt(i).reset(uptimeMillis * 1000, elapsedRealtimeMillis * 1000)) { + if (mUidStats.valueAt(i).reset(uptimeUs, elapsedRealtimeUs)) { mUidStats.valueAt(i).detachFromTimeBase(); mUidStats.remove(mUidStats.keyAt(i)); i--; @@ -10780,25 +11283,25 @@ public class BatteryStatsImpl extends BatteryStats { mTmpRailStats.reset(); - resetIfNotNull(mSystemServerThreadCpuTimesUs, false); - resetIfNotNull(mBinderThreadCpuTimesUs, false); + resetIfNotNull(mSystemServerThreadCpuTimesUs, false, elapsedRealtimeUs); + resetIfNotNull(mBinderThreadCpuTimesUs, false, elapsedRealtimeUs); mLastHistoryStepDetails = null; - mLastStepCpuUserTime = mLastStepCpuSystemTime = 0; - mCurStepCpuUserTime = mCurStepCpuSystemTime = 0; - mLastStepCpuUserTime = mCurStepCpuUserTime = 0; - mLastStepCpuSystemTime = mCurStepCpuSystemTime = 0; - mLastStepStatUserTime = mCurStepStatUserTime = 0; - mLastStepStatSystemTime = mCurStepStatSystemTime = 0; - mLastStepStatIOWaitTime = mCurStepStatIOWaitTime = 0; - mLastStepStatIrqTime = mCurStepStatIrqTime = 0; - mLastStepStatSoftIrqTime = mCurStepStatSoftIrqTime = 0; - mLastStepStatIdleTime = mCurStepStatIdleTime = 0; + mLastStepCpuUserTimeMs = mLastStepCpuSystemTimeMs = 0; + mCurStepCpuUserTimeMs = mCurStepCpuSystemTimeMs = 0; + mLastStepCpuUserTimeMs = mCurStepCpuUserTimeMs = 0; + mLastStepCpuSystemTimeMs = mCurStepCpuSystemTimeMs = 0; + mLastStepStatUserTimeMs = mCurStepStatUserTimeMs = 0; + mLastStepStatSystemTimeMs = mCurStepStatSystemTimeMs = 0; + mLastStepStatIOWaitTimeMs = mCurStepStatIOWaitTimeMs = 0; + mLastStepStatIrqTimeMs = mCurStepStatIrqTimeMs = 0; + mLastStepStatSoftIrqTimeMs = mCurStepStatSoftIrqTimeMs = 0; + mLastStepStatIdleTimeMs = mCurStepStatIdleTimeMs = 0; mNumAllUidCpuTimeReads = 0; mNumUidsRemoved = 0; - initDischarge(); + initDischarge(elapsedRealtimeUs); clearHistoryLocked(); mBatteryStatsHistory.resetAllFiles(); @@ -10915,6 +11418,14 @@ public class BatteryStatsImpl extends BatteryStats { * @param info The energy information from the WiFi controller. */ public void updateWifiState(@Nullable final WifiActivityEnergyInfo info) { + updateWifiState(info, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + /** + * @see #updateWifiState(WifiActivityEnergyInfo) + */ + public void updateWifiState(@Nullable final WifiActivityEnergyInfo info, + long elapsedRealtimeMs, long uptimeMs) { if (DEBUG_ENERGY) { Slog.d(TAG, "Updating wifi stats: " + Arrays.toString(mWifiIfaces)); } @@ -10939,7 +11450,6 @@ public class BatteryStatsImpl extends BatteryStats { return; } - final long elapsedRealtimeMs = mClocks.elapsedRealtime(); SparseLongArray rxPackets = new SparseLongArray(); SparseLongArray txPackets = new SparseLongArray(); long totalTxPackets = 0; @@ -10961,7 +11471,7 @@ public class BatteryStatsImpl extends BatteryStats { continue; } - final Uid u = getUidStatsLocked(mapUid(entry.uid)); + final Uid u = getUidStatsLocked(mapUid(entry.uid), elapsedRealtimeMs, uptimeMs); if (entry.rxBytes != 0) { u.noteNetworkActivityLocked(NETWORK_WIFI_RX_DATA, entry.rxBytes, entry.rxPackets); @@ -11127,7 +11637,8 @@ public class BatteryStatsImpl extends BatteryStats { // Distribute the remaining Tx power appropriately between all apps that transmitted // packets. for (int i = 0; i < txPackets.size(); i++) { - final Uid uid = getUidStatsLocked(txPackets.keyAt(i)); + final Uid uid = getUidStatsLocked(txPackets.keyAt(i), + elapsedRealtimeMs, uptimeMs); final long myTxTimeMs = (txPackets.valueAt(i) * leftOverTxTimeMs) / totalTxPackets; if (DEBUG_ENERGY) { @@ -11140,7 +11651,8 @@ public class BatteryStatsImpl extends BatteryStats { // Distribute the remaining Rx power appropriately between all apps that received // packets. for (int i = 0; i < rxPackets.size(); i++) { - final Uid uid = getUidStatsLocked(rxPackets.keyAt(i)); + final Uid uid = getUidStatsLocked(rxPackets.keyAt(i), + elapsedRealtimeMs, uptimeMs); final long myRxTimeMs = (rxPackets.valueAt(i) * leftOverRxTimeMs) / totalRxPackets; if (DEBUG_ENERGY) { @@ -11179,7 +11691,7 @@ public class BatteryStatsImpl extends BatteryStats { monitoredRailChargeConsumedMaMs); mHistoryCur.wifiRailChargeMah += (monitoredRailChargeConsumedMaMs / MILLISECONDS_IN_HOUR); - addHistoryRecordLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); mTmpRailStats.resetWifiTotalEnergyUsed(); } } @@ -11210,13 +11722,21 @@ public class BatteryStatsImpl extends BatteryStats { * Distribute Cell radio energy info and network traffic to apps. */ public void updateMobileRadioState(@Nullable final ModemActivityInfo activityInfo) { + updateMobileRadioState(activityInfo, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + /** + * @see #updateMobileRadioState(ModemActivityInfo) + */ + public void updateMobileRadioState(@Nullable final ModemActivityInfo activityInfo, + long elapsedRealtimeMs, long uptimeMs) { if (DEBUG_ENERGY) { Slog.d(TAG, "Updating mobile radio stats with " + activityInfo); } ModemActivityInfo deltaInfo = getDeltaModemActivityInfo(activityInfo); // Add modem tx power to history. - addModemTxPowerToHistory(deltaInfo); + addModemTxPowerToHistory(deltaInfo, elapsedRealtimeMs, uptimeMs); // Grab a separate lock to acquire the network stats, which may do I/O. NetworkStats delta = null; @@ -11279,12 +11799,11 @@ public class BatteryStatsImpl extends BatteryStats { monitoredRailChargeConsumedMaMs); mHistoryCur.modemRailChargeMah += (monitoredRailChargeConsumedMaMs / MILLISECONDS_IN_HOUR); - addHistoryRecordLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); mTmpRailStats.resetCellularTotalEnergyUsed(); } } - final long elapsedRealtimeMs = mClocks.elapsedRealtime(); - long radioTime = mMobileRadioActivePerAppTimer.getTimeSinceMarkLocked( + long radioTimeUs = mMobileRadioActivePerAppTimer.getTimeSinceMarkLocked( elapsedRealtimeMs * 1000); mMobileRadioActivePerAppTimer.setMark(elapsedRealtimeMs); @@ -11308,7 +11827,7 @@ public class BatteryStatsImpl extends BatteryStats { totalRxPackets += entry.rxPackets; totalTxPackets += entry.txPackets; - final Uid u = getUidStatsLocked(mapUid(entry.uid)); + final Uid u = getUidStatsLocked(mapUid(entry.uid), elapsedRealtimeMs, uptimeMs); u.noteNetworkActivityLocked(NETWORK_MOBILE_RX_DATA, entry.rxBytes, entry.rxPackets); u.noteNetworkActivityLocked(NETWORK_MOBILE_TX_DATA, entry.txBytes, @@ -11339,16 +11858,17 @@ public class BatteryStatsImpl extends BatteryStats { continue; } - final Uid u = getUidStatsLocked(mapUid(entry.uid)); + final Uid u = getUidStatsLocked(mapUid(entry.uid), + elapsedRealtimeMs, uptimeMs); // Distribute total radio active time in to this app. final long appPackets = entry.rxPackets + entry.txPackets; - final long appRadioTime = (radioTime * appPackets) / totalPackets; - u.noteMobileRadioActiveTimeLocked(appRadioTime); + final long appRadioTimeUs = (radioTimeUs * appPackets) / totalPackets; + u.noteMobileRadioActiveTimeLocked(appRadioTimeUs); // Remove this app from the totals, so that we don't lose any time // due to rounding. - radioTime -= appRadioTime; + radioTimeUs -= appRadioTimeUs; totalPackets -= appPackets; if (deltaInfo != null) { @@ -11373,9 +11893,9 @@ public class BatteryStatsImpl extends BatteryStats { } } - if (radioTime > 0) { + if (radioTimeUs > 0) { // Whoops, there is some radio time we can't blame on an app! - mMobileRadioActiveUnknownTime.addCountLocked(radioTime); + mMobileRadioActiveUnknownTime.addCountLocked(radioTimeUs); mMobileRadioActiveUnknownCount.addCountLocked(1); } @@ -11391,7 +11911,8 @@ public class BatteryStatsImpl extends BatteryStats { * time at the highest power level. * @param activityInfo */ - private synchronized void addModemTxPowerToHistory(final ModemActivityInfo activityInfo) { + private synchronized void addModemTxPowerToHistory(final ModemActivityInfo activityInfo, + long elapsedRealtimeMs, long uptimeMs) { if (activityInfo == null) { return; } @@ -11399,8 +11920,6 @@ public class BatteryStatsImpl extends BatteryStats { if (txPowerInfo == null || txPowerInfo.size() != ModemActivityInfo.TX_POWER_LEVELS) { return; } - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); int levelMaxTimeSpent = 0; for (int i = 1; i < txPowerInfo.size(); i++) { if (txPowerInfo.get(i).getTimeInMillis() > txPowerInfo.get(levelMaxTimeSpent) @@ -11410,7 +11929,7 @@ public class BatteryStatsImpl extends BatteryStats { } if (levelMaxTimeSpent == ModemActivityInfo.TX_POWER_LEVELS - 1) { mHistoryCur.states2 |= HistoryItem.STATE2_CELLULAR_HIGH_TX_POWER_FLAG; - addHistoryRecordLocked(elapsedRealtime, uptime); + addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); } } @@ -11446,6 +11965,14 @@ public class BatteryStatsImpl extends BatteryStats { * @param info The energy information from the bluetooth controller. */ public void updateBluetoothStateLocked(@Nullable final BluetoothActivityEnergyInfo info) { + updateBluetoothStateLocked(info, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + /** + * @see #updateBluetoothStateLocked(BluetoothActivityEnergyInfo) + */ + public void updateBluetoothStateLocked(@Nullable final BluetoothActivityEnergyInfo info, + long elapsedRealtimeMs, long uptimeMs) { if (DEBUG_ENERGY) { Slog.d(TAG, "Updating bluetooth stats: " + info); } @@ -11456,7 +11983,6 @@ public class BatteryStatsImpl extends BatteryStats { mHasBluetoothReporting = true; - final long elapsedRealtimeMs = mClocks.elapsedRealtime(); final long rxTimeMs = info.getControllerRxTimeMillis() - mLastBluetoothActivityInfo.rxTimeMs; final long txTimeMs = @@ -11560,7 +12086,7 @@ public class BatteryStatsImpl extends BatteryStats { mNetworkByteActivityCounters[NETWORK_BT_TX_DATA].addCountLocked(txBytes); // Add to the UID counters. - final Uid u = getUidStatsLocked(mapUid(traffic.getUid())); + final Uid u = getUidStatsLocked(mapUid(traffic.getUid()), elapsedRealtimeMs, uptimeMs); u.noteNetworkActivityLocked(NETWORK_BT_RX_DATA, rxBytes, 0); u.noteNetworkActivityLocked(NETWORK_BT_TX_DATA, txBytes, 0); @@ -11579,7 +12105,7 @@ public class BatteryStatsImpl extends BatteryStats { final long txBytes = traffic.getTxBytes() - mLastBluetoothActivityInfo.uidTxBytes.get(uid); - final Uid u = getUidStatsLocked(mapUid(uid)); + final Uid u = getUidStatsLocked(mapUid(uid), elapsedRealtimeMs, uptimeMs); final ControllerActivityCounterImpl counter = u.getOrCreateBluetoothControllerActivityLocked(); @@ -11623,6 +12149,13 @@ public class BatteryStatsImpl extends BatteryStats { * instead of fetching it anew. */ public void updateRpmStatsLocked() { + updateRpmStatsLocked(mClocks.elapsedRealtime() * 1000); + } + + /** + * @see #updateRpmStatsLocked() + */ + public void updateRpmStatsLocked(long elapsedRealtimeUs) { if (mPlatformIdleStateCallback == null) return; long now = SystemClock.elapsedRealtime(); if (now - mLastRpmStatsUpdateTimeMs >= RPM_STATS_UPDATE_FREQ_MS) { @@ -11637,9 +12170,9 @@ public class BatteryStatsImpl extends BatteryStats { final String pName = pstate.getKey(); final long pTimeUs = pstate.getValue().mTimeMs * 1000; final int pCount = pstate.getValue().mCount; - getRpmTimerLocked(pName).update(pTimeUs, pCount); + getRpmTimerLocked(pName).update(pTimeUs, pCount, elapsedRealtimeUs); if (SCREEN_OFF_RPM_STATS_ENABLED) { - getScreenOffRpmTimerLocked(pName).update(pTimeUs, pCount); + getScreenOffRpmTimerLocked(pName).update(pTimeUs, pCount, elapsedRealtimeUs); } // Update values for each voter of this platform state. @@ -11648,9 +12181,9 @@ public class BatteryStatsImpl extends BatteryStats { final String vName = pName + "." + voter.getKey(); final long vTimeUs = voter.getValue().mTimeMs * 1000; final int vCount = voter.getValue().mCount; - getRpmTimerLocked(vName).update(vTimeUs, vCount); + getRpmTimerLocked(vName).update(vTimeUs, vCount, elapsedRealtimeUs); if (SCREEN_OFF_RPM_STATS_ENABLED) { - getScreenOffRpmTimerLocked(vName).update(vTimeUs, vCount); + getScreenOffRpmTimerLocked(vName).update(vTimeUs, vCount, elapsedRealtimeUs); } } } @@ -11664,9 +12197,9 @@ public class BatteryStatsImpl extends BatteryStats { final String name = subsysName + "." + sstate.getKey(); final long timeUs = sstate.getValue().mTimeMs * 1000; final int count = sstate.getValue().mCount; - getRpmTimerLocked(name).update(timeUs, count); + getRpmTimerLocked(name).update(timeUs, count, elapsedRealtimeUs); if (SCREEN_OFF_RPM_STATS_ENABLED) { - getScreenOffRpmTimerLocked(name).update(timeUs, count); + getScreenOffRpmTimerLocked(name).update(timeUs, count, elapsedRealtimeUs); } } } @@ -11686,6 +12219,13 @@ public class BatteryStatsImpl extends BatteryStats { * Read and distribute kernel wake lock use across apps. */ public void updateKernelWakelocksLocked() { + updateKernelWakelocksLocked(mClocks.elapsedRealtime() * 1000); + } + + /** + * @see #updateKernelWakelocksLocked() + */ + public void updateKernelWakelocksLocked(long elapsedRealtimeUs) { final KernelWakelockStats wakelockStats = mKernelWakelockReader.readKernelWakelockStats( mTmpWakelockStats); if (wakelockStats == null) { @@ -11704,7 +12244,7 @@ public class BatteryStatsImpl extends BatteryStats { mKernelWakelockStats.put(name, kwlt); } - kwlt.update(kws.mTotalTime, kws.mCount); + kwlt.update(kws.mTotalTime, kws.mCount, elapsedRealtimeUs); kwlt.setUpdateVersion(kws.mVersion); } @@ -11714,7 +12254,7 @@ public class BatteryStatsImpl extends BatteryStats { for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { SamplingTimer st = ent.getValue(); if (st.getUpdateVersion() != wakelockStats.kernelWakelockVersion) { - st.endSample(); + st.endSample(elapsedRealtimeUs); numWakelocksSetStale++; } } @@ -11742,6 +12282,10 @@ public class BatteryStatsImpl extends BatteryStats { * Reads the newest memory stats from the kernel. */ public void updateKernelMemoryBandwidthLocked() { + updateKernelMemoryBandwidthLocked(mClocks.elapsedRealtime() * 1000); + } + + public void updateKernelMemoryBandwidthLocked(long elapsedRealtimeUs) { mKernelMemoryBandwidthStats.updateStats(); LongSparseLongArray bandwidthEntries = mKernelMemoryBandwidthStats.getBandwidthEntries(); final int bandwidthEntryCount = bandwidthEntries.size(); @@ -11754,12 +12298,12 @@ public class BatteryStatsImpl extends BatteryStats { timer = new SamplingTimer(mClocks, mOnBatteryTimeBase); mKernelMemoryStats.put(bandwidthEntries.keyAt(i), timer); } - timer.update(bandwidthEntries.valueAt(i), 1); + timer.update(bandwidthEntries.valueAt(i), 1, elapsedRealtimeUs); if (DEBUG_MEMORY) { Slog.d(TAG, String.format("Added entry %d and updated timer to: " - + "mUnpluggedReportedTotalTime %d size %d", bandwidthEntries.keyAt(i), + + "mUnpluggedReportedTotalTimeUs %d size %d", bandwidthEntries.keyAt(i), mKernelMemoryStats.get( - bandwidthEntries.keyAt(i)).mUnpluggedReportedTotalTime, + bandwidthEntries.keyAt(i)).mUnpluggedReportedTotalTimeUs, mKernelMemoryStats.size())); } } @@ -11898,8 +12442,8 @@ public class BatteryStatsImpl extends BatteryStats { } if (DEBUG_BINDER_STATS) { Slog.d(TAG, "System server threads per CPU cluster (binder threads/total threads/%)"); - long binderThreadTime = 0; - long totalThreadTime = 0; + long binderThreadTimeMs = 0; + long totalThreadTimeMs = 0; int cpuIndex = 0; for (int cluster = 0; cluster < numCpuClusters; cluster++) { StringBuilder sb = new StringBuilder(); @@ -11909,26 +12453,27 @@ public class BatteryStatsImpl extends BatteryStats { if (speed != 0) { sb.append(", "); } - long totalCount = mSystemServerThreadCpuTimesUs[cluster][speed].getCountLocked( - 0) / 1000; - long binderCount = mBinderThreadCpuTimesUs[cluster][speed].getCountLocked(0) + long totalCountMs = + mSystemServerThreadCpuTimesUs[cluster][speed].getCountLocked(0) / 1000; + long binderCountMs = mBinderThreadCpuTimesUs[cluster][speed].getCountLocked(0) / 1000; sb.append(String.format("%d/%d(%.1f%%)", - binderCount, - totalCount, - totalCount != 0 ? (double) binderCount * 100 / totalCount : 0)); + binderCountMs, + totalCountMs, + totalCountMs != 0 ? (double) binderCountMs * 100 / totalCountMs : 0)); - totalThreadTime += totalCount; - binderThreadTime += binderCount; + totalThreadTimeMs += totalCountMs; + binderThreadTimeMs += binderCountMs; index++; } cpuIndex += mPowerProfile.getNumCoresInCpuCluster(cluster); Slog.d(TAG, sb.toString()); } - Slog.d(TAG, "Total system server thread time (ms): " + totalThreadTime); + Slog.d(TAG, "Total system server thread time (ms): " + totalThreadTimeMs); Slog.d(TAG, String.format("Total Binder thread time (ms): %d (%.1f%%)", - binderThreadTime, - binderThreadTime != 0 ? (double) binderThreadTime * 100 / totalThreadTime : 0)); + binderThreadTimeMs, + binderThreadTimeMs != 0 + ? (double) binderThreadTimeMs * 100 / totalThreadTimeMs : 0)); } } @@ -11985,8 +12530,10 @@ public class BatteryStatsImpl extends BatteryStats { // So, we distribute total time spent by an uid to different cpu freqs based on the // amount of time cpu was running at that freq. final int updatedUidsCount = updatedUids.size(); + final long elapsedRealtimeMs = mClocks.elapsedRealtime(); + final long uptimeMs = mClocks.uptimeMillis(); for (int i = 0; i < updatedUidsCount; ++i) { - final Uid u = getUidStatsLocked(updatedUids.keyAt(i)); + final Uid u = getUidStatsLocked(updatedUids.keyAt(i), elapsedRealtimeMs, uptimeMs); final long appCpuTimeUs = updatedUids.valueAt(i); // Add the cpu speeds to this UID. final int numClusters = mPowerProfile.getNumCpuClusters(); @@ -12031,6 +12578,7 @@ public class BatteryStatsImpl extends BatteryStats { mTempTotalCpuUserTimeUs = mTempTotalCpuSystemTimeUs = 0; final int numWakelocks = partialTimers == null ? 0 : partialTimers.size(); final long startTimeMs = mClocks.uptimeMillis(); + final long elapsedRealtimeMs = mClocks.elapsedRealtime(); mCpuUidUserSysTimeReader.readDelta((uid, timesUs) -> { long userTimeUs = timesUs[0], systemTimeUs = timesUs[1]; @@ -12048,7 +12596,7 @@ public class BatteryStatsImpl extends BatteryStats { mCpuUidUserSysTimeReader.removeUid(uid); return; } - final Uid u = getUidStatsLocked(uid); + final Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, startTimeMs); // Accumulate the total system and user time. mTempTotalCpuUserTimeUs += userTimeUs; @@ -12144,6 +12692,7 @@ public class BatteryStatsImpl extends BatteryStats { final int numClusters = mPowerProfile.getNumCpuClusters(); mWakeLockAllocationsUs = null; final long startTimeMs = mClocks.uptimeMillis(); + final long elapsedRealtimeMs = mClocks.elapsedRealtime(); mCpuUidFreqTimeReader.readDelta((uid, cpuFreqTimeMs) -> { uid = mapUid(uid); if (Process.isIsolated(uid)) { @@ -12156,7 +12705,7 @@ public class BatteryStatsImpl extends BatteryStats { mCpuUidFreqTimeReader.removeUid(uid); return; } - final Uid u = getUidStatsLocked(uid); + final Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, startTimeMs); if (u.mCpuFreqTimeMs == null || u.mCpuFreqTimeMs.getSize() != cpuFreqTimeMs.length) { detachIfNotNull(u.mCpuFreqTimeMs); u.mCpuFreqTimeMs = new LongSamplingCounterArray(mOnBatteryTimeBase); @@ -12257,6 +12806,7 @@ public class BatteryStatsImpl extends BatteryStats { @VisibleForTesting public void readKernelUidCpuActiveTimesLocked(boolean onBattery) { final long startTimeMs = mClocks.uptimeMillis(); + final long elapsedRealtimeMs = mClocks.elapsedRealtime(); mCpuUidActiveTimeReader.readDelta((uid, cpuActiveTimesMs) -> { uid = mapUid(uid); if (Process.isIsolated(uid)) { @@ -12269,7 +12819,7 @@ public class BatteryStatsImpl extends BatteryStats { mCpuUidActiveTimeReader.removeUid(uid); return; } - final Uid u = getUidStatsLocked(uid); + final Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, startTimeMs); u.mCpuActiveTimeMs.addCountLocked(cpuActiveTimesMs, onBattery); }); @@ -12286,6 +12836,7 @@ public class BatteryStatsImpl extends BatteryStats { @VisibleForTesting public void readKernelUidCpuClusterTimesLocked(boolean onBattery) { final long startTimeMs = mClocks.uptimeMillis(); + final long elapsedRealtimeMs = mClocks.elapsedRealtime(); mCpuUidClusterTimeReader.readDelta((uid, cpuClusterTimesMs) -> { uid = mapUid(uid); if (Process.isIsolated(uid)) { @@ -12298,7 +12849,7 @@ public class BatteryStatsImpl extends BatteryStats { mCpuUidClusterTimeReader.removeUid(uid); return; } - final Uid u = getUidStatsLocked(uid); + final Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, startTimeMs); u.mCpuClusterTimesMs.addCountLocked(cpuClusterTimesMs, onBattery); }); @@ -12338,8 +12889,8 @@ public class BatteryStatsImpl extends BatteryStats { m.arg1 = onBattery ? 1 : 0; mHandler.sendMessage(m); - final long uptime = mSecUptime * 1000; - final long realtime = mSecRealtime * 1000; + final long uptimeUs = mSecUptime * 1000; + final long realtimeUs = mSecRealtime * 1000; final int screenState = mScreenState; if (onBattery) { // We will reset our status if we are unplugging after the @@ -12358,14 +12909,14 @@ public class BatteryStatsImpl extends BatteryStats { // stats to be reported in the next checkin. Only do this if we have // a sufficient amount of data to make it interesting. if (getLowDischargeAmountSinceCharge() >= 20) { - final long startTime = SystemClock.uptimeMillis(); + final long startTimeMs = SystemClock.uptimeMillis(); final Parcel parcel = Parcel.obtain(); writeSummaryToParcel(parcel, true); - final long initialTime = SystemClock.uptimeMillis() - startTime; + final long initialTimeMs = SystemClock.uptimeMillis() - startTimeMs; BackgroundThread.getHandler().post(new Runnable() { @Override public void run() { synchronized (mCheckinFile) { - final long startTime2 = SystemClock.uptimeMillis(); + final long startTimeMs2 = SystemClock.uptimeMillis(); FileOutputStream stream = null; try { stream = mCheckinFile.startWrite(); @@ -12373,8 +12924,8 @@ public class BatteryStatsImpl extends BatteryStats { stream.flush(); mCheckinFile.finishWrite(stream); com.android.internal.logging.EventLogTags.writeCommitSysConfigFile( - "batterystats-checkin", - initialTime + SystemClock.uptimeMillis() - startTime2); + "batterystats-checkin", initialTimeMs + + SystemClock.uptimeMillis() - startTimeMs2); } catch (IOException e) { Slog.w("BatteryStats", "Error writing checkin battery statistics", e); @@ -12387,7 +12938,7 @@ public class BatteryStatsImpl extends BatteryStats { }); } doWrite = true; - resetAllStatsLocked(); + resetAllStatsLocked(mSecUptime, mSecRealtime); if (chargeUAh > 0 && level > 0) { // Only use the reported coulomb charge value if it is supported and reported. mEstimatedBatteryCapacity = (int) ((chargeUAh / 1000) / (level / 100.0)); @@ -12434,7 +12985,7 @@ public class BatteryStatsImpl extends BatteryStats { mDischargeAmountScreenOn = 0; mDischargeAmountScreenDoze = 0; mDischargeAmountScreenOff = 0; - updateTimeBasesLocked(true, screenState, uptime, realtime); + updateTimeBasesLocked(true, screenState, uptimeUs, realtimeUs); } else { mLastChargingStateLevel = level; mOnBattery = mOnBatteryInternal = false; @@ -12450,14 +13001,14 @@ public class BatteryStatsImpl extends BatteryStats { mHighDischargeAmountSinceCharge += mDischargeUnplugLevel-level; } updateDischargeScreenLevelsLocked(screenState, screenState); - updateTimeBasesLocked(false, screenState, uptime, realtime); + updateTimeBasesLocked(false, screenState, uptimeUs, realtimeUs); mChargeStepTracker.init(); mLastChargeStepLevel = level; mMaxChargeStepLevel = level; mInitStepMode = mCurStepMode; mModStepMode = 0; } - if (doWrite || (mLastWriteTime + (60 * 1000)) < mSecRealtime) { + if (doWrite || (mLastWriteTimeMs + (60 * 1000)) < mSecRealtime) { if (mStatsFile != null && mBatteryStatsHistory.getActiveFile() != null) { writeAsyncLocked(); } @@ -12477,18 +13028,18 @@ public class BatteryStatsImpl extends BatteryStats { } } - private void recordCurrentTimeChangeLocked(final long currentTime, final long elapsedRealtimeMs, - final long uptimeMs) { + private void recordCurrentTimeChangeLocked(final long currentTimeMs, + final long elapsedRealtimeMs, final long uptimeMs) { if (mRecordingHistory) { - mHistoryCur.currentTime = currentTime; + mHistoryCur.currentTime = currentTimeMs; addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_CURRENT_TIME, mHistoryCur); mHistoryCur.currentTime = 0; } } - private void recordShutdownLocked(final long elapsedRealtimeMs, final long uptimeMs) { + private void recordShutdownLocked(final long currentTimeMs, final long elapsedRealtimeMs) { if (mRecordingHistory) { - mHistoryCur.currentTime = System.currentTimeMillis(); + mHistoryCur.currentTime = currentTimeMs; addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_SHUTDOWN, mHistoryCur); mHistoryCur.currentTime = 0; } @@ -12507,6 +13058,15 @@ public class BatteryStatsImpl extends BatteryStats { public void setBatteryStateLocked(final int status, final int health, final int plugType, final int level, /* not final */ int temp, final int volt, final int chargeUAh, final int chargeFullUAh, final long chargeTimeToFullSeconds) { + setBatteryStateLocked(status, health, plugType, level, temp, volt, chargeUAh, + chargeFullUAh, chargeTimeToFullSeconds, + mClocks.elapsedRealtime(), mClocks.uptimeMillis(), System.currentTimeMillis()); + } + + public void setBatteryStateLocked(final int status, final int health, final int plugType, + final int level, /* not final */ int temp, final int volt, final int chargeUAh, + final int chargeFullUAh, final long chargeTimeToFullSeconds, + final long elapsedRealtimeMs, final long uptimeMs, final long currentTimeMs) { // Temperature is encoded without the signed bit, so clamp any negative temperatures to 0. temp = Math.max(0, temp); @@ -12514,8 +13074,6 @@ public class BatteryStatsImpl extends BatteryStats { status, plugType, level); final boolean onBattery = isOnBattery(plugType, status); - final long uptime = mClocks.uptimeMillis(); - final long elapsedRealtime = mClocks.elapsedRealtime(); if (!mHaveBatteryLevel) { mHaveBatteryLevel = true; // We start out assuming that the device is plugged in (not @@ -12538,20 +13096,20 @@ public class BatteryStatsImpl extends BatteryStats { mLastChargeStepLevel = mLastDischargeStepLevel = level; mLastChargingStateLevel = level; } else if (mCurrentBatteryLevel != level || mOnBattery != onBattery) { - recordDailyStatsIfNeededLocked(level >= 100 && onBattery); + recordDailyStatsIfNeededLocked(level >= 100 && onBattery, currentTimeMs); } int oldStatus = mHistoryCur.batteryStatus; if (onBattery) { mDischargeCurrentLevel = level; if (!mRecordingHistory) { mRecordingHistory = true; - startRecordingHistory(elapsedRealtime, uptime, true); + startRecordingHistory(elapsedRealtimeMs, uptimeMs, true); } } else if (level < 96 && status != BatteryManager.BATTERY_STATUS_UNKNOWN) { if (!mRecordingHistory) { mRecordingHistory = true; - startRecordingHistory(elapsedRealtime, uptime, true); + startRecordingHistory(elapsedRealtimeMs, uptimeMs, true); } } mCurrentBatteryLevel = level; @@ -12581,7 +13139,7 @@ public class BatteryStatsImpl extends BatteryStats { } } mHistoryCur.batteryChargeUAh = chargeUAh; - setOnBatteryLocked(elapsedRealtime, uptime, onBattery, oldStatus, level, chargeUAh); + setOnBatteryLocked(elapsedRealtimeMs, uptimeMs, onBattery, oldStatus, level, chargeUAh); } else { boolean changed = false; if (mHistoryCur.batteryLevel != level) { @@ -12641,9 +13199,9 @@ public class BatteryStatsImpl extends BatteryStats { changed |= setChargingLocked(false); if (mLastDischargeStepLevel != level && mMinDischargeStepLevel > level) { mDischargeStepTracker.addLevelSteps(mLastDischargeStepLevel - level, - modeBits, elapsedRealtime); + modeBits, elapsedRealtimeMs); mDailyDischargeStepTracker.addLevelSteps(mLastDischargeStepLevel - level, - modeBits, elapsedRealtime); + modeBits, elapsedRealtimeMs); mLastDischargeStepLevel = level; mMinDischargeStepLevel = level; mInitStepMode = mCurStepMode; @@ -12681,9 +13239,9 @@ public class BatteryStatsImpl extends BatteryStats { } if (mLastChargeStepLevel != level && mMaxChargeStepLevel < level) { mChargeStepTracker.addLevelSteps(level - mLastChargeStepLevel, - modeBits, elapsedRealtime); + modeBits, elapsedRealtimeMs); mDailyChargeStepTracker.addLevelSteps(level - mLastChargeStepLevel, - modeBits, elapsedRealtime); + modeBits, elapsedRealtimeMs); mMaxChargeStepLevel = level; mInitStepMode = mCurStepMode; mModStepMode = 0; @@ -12691,7 +13249,7 @@ public class BatteryStatsImpl extends BatteryStats { mLastChargeStepLevel = level; } if (changed) { - addHistoryRecordLocked(elapsedRealtime, uptime); + addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs); } } if (!onBattery && @@ -12737,7 +13295,7 @@ public class BatteryStatsImpl extends BatteryStats { public long getAwakeTimeBattery() { // This previously evaluated to mOnBatteryTimeBase.getUptime(getBatteryUptimeLocked()); // for over a decade, but surely that was a mistake. - return getBatteryUptimeLocked(); + return getBatteryUptimeLocked(mClocks.uptimeMillis()); } @UnsupportedAppUsage @@ -12746,35 +13304,35 @@ public class BatteryStatsImpl extends BatteryStats { } @Override - public long computeUptime(long curTime, int which) { - return mUptime + (curTime - mUptimeStart); + public long computeUptime(long curTimeUs, int which) { + return mUptimeUs + (curTimeUs - mUptimeStartUs); } @Override - public long computeRealtime(long curTime, int which) { - return mRealtime + (curTime - mRealtimeStart); + public long computeRealtime(long curTimeUs, int which) { + return mRealtimeUs + (curTimeUs - mRealtimeStartUs); } @Override @UnsupportedAppUsage - public long computeBatteryUptime(long curTime, int which) { - return mOnBatteryTimeBase.computeUptime(curTime, which); + public long computeBatteryUptime(long curTimeUs, int which) { + return mOnBatteryTimeBase.computeUptime(curTimeUs, which); } @Override @UnsupportedAppUsage - public long computeBatteryRealtime(long curTime, int which) { - return mOnBatteryTimeBase.computeRealtime(curTime, which); + public long computeBatteryRealtime(long curTimeUs, int which) { + return mOnBatteryTimeBase.computeRealtime(curTimeUs, which); } @Override - public long computeBatteryScreenOffUptime(long curTime, int which) { - return mOnBatteryScreenOffTimeBase.computeUptime(curTime, which); + public long computeBatteryScreenOffUptime(long curTimeUs, int which) { + return mOnBatteryScreenOffTimeBase.computeUptime(curTimeUs, which); } @Override - public long computeBatteryScreenOffRealtime(long curTime, int which) { - return mOnBatteryScreenOffTimeBase.computeRealtime(curTime, which); + public long computeBatteryScreenOffRealtime(long curTimeUs, int which) { + return mOnBatteryScreenOffTimeBase.computeRealtime(curTimeUs, which); } private long computeTimePerLevel(long[] steps, int numSteps) { @@ -12877,7 +13435,7 @@ public class BatteryStatsImpl extends BatteryStats { /*@hide */ public CellularBatteryStats getCellularBatteryStats() { final int which = STATS_SINCE_CHARGED; - final long rawRealTime = SystemClock.elapsedRealtime() * 1000; + final long rawRealTimeUs = SystemClock.elapsedRealtime() * 1000; final ControllerActivityCounter counter = getModemControllerActivity(); final long sleepTimeMs = counter.getSleepTimeCounter().getCountLocked(which); final long idleTimeMs = counter.getIdleTimeCounter().getCountLocked(which); @@ -12887,13 +13445,13 @@ public class BatteryStatsImpl extends BatteryStats { counter.getMonitoredRailChargeConsumedMaMs().getCountLocked(which); long[] timeInRatMs = new long[BatteryStats.NUM_DATA_CONNECTION_TYPES]; for (int i = 0; i < timeInRatMs.length; i++) { - timeInRatMs[i] = getPhoneDataConnectionTime(i, rawRealTime, which) / 1000; + timeInRatMs[i] = getPhoneDataConnectionTime(i, rawRealTimeUs, which) / 1000; } long[] timeInRxSignalStrengthLevelMs = new long[CellSignalStrength.getNumSignalStrengthLevels()]; for (int i = 0; i < timeInRxSignalStrengthLevelMs.length; i++) { - timeInRxSignalStrengthLevelMs[i] - = getPhoneSignalStrengthTime(i, rawRealTime, which) / 1000; + timeInRxSignalStrengthLevelMs[i] = + getPhoneSignalStrengthTime(i, rawRealTimeUs, which) / 1000; } long[] txTimeMs = new long[Math.min(ModemActivityInfo.TX_POWER_LEVELS, counter.getTxTimeCounters().length)]; @@ -12903,8 +13461,8 @@ public class BatteryStatsImpl extends BatteryStats { totalTxTimeMs += txTimeMs[i]; } - return new CellularBatteryStats(computeBatteryRealtime(rawRealTime, which) / 1000, - getMobileRadioActiveTime(rawRealTime, which) / 1000, + return new CellularBatteryStats(computeBatteryRealtime(rawRealTimeUs, which) / 1000, + getMobileRadioActiveTime(rawRealTimeUs, which) / 1000, getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which), getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which), getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which), @@ -12917,7 +13475,7 @@ public class BatteryStatsImpl extends BatteryStats { /*@hide */ public WifiBatteryStats getWifiBatteryStats() { final int which = STATS_SINCE_CHARGED; - final long rawRealTime = SystemClock.elapsedRealtime() * 1000; + final long rawRealTimeUs = SystemClock.elapsedRealtime() * 1000; final ControllerActivityCounter counter = getWifiControllerActivity(); final long idleTimeMs = counter.getIdleTimeCounter().getCountLocked(which); final long scanTimeMs = counter.getScanTimeCounter().getCountLocked(which); @@ -12936,19 +13494,19 @@ public class BatteryStatsImpl extends BatteryStats { } long[] timeInStateMs = new long[NUM_WIFI_STATES]; for (int i=0; i<NUM_WIFI_STATES; i++) { - timeInStateMs[i] = getWifiStateTime(i, rawRealTime, which) / 1000; + timeInStateMs[i] = getWifiStateTime(i, rawRealTimeUs, which) / 1000; } long[] timeInSupplStateMs = new long[NUM_WIFI_SUPPL_STATES]; for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) { - timeInSupplStateMs[i] = getWifiSupplStateTime(i, rawRealTime, which) / 1000; + timeInSupplStateMs[i] = getWifiSupplStateTime(i, rawRealTimeUs, which) / 1000; } long[] timeSignalStrengthTimeMs = new long[NUM_WIFI_SIGNAL_STRENGTH_BINS]; for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) { - timeSignalStrengthTimeMs[i] = getWifiSignalStrengthTime(i, rawRealTime, which) / 1000; + timeSignalStrengthTimeMs[i] = getWifiSignalStrengthTime(i, rawRealTimeUs, which) / 1000; } return new WifiBatteryStats( - computeBatteryRealtime(rawRealTime, which) / 1000, - getWifiActiveTime(rawRealTime, which) / 1000, + computeBatteryRealtime(rawRealTimeUs, which) / 1000, + getWifiActiveTime(rawRealTimeUs, which) / 1000, getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which), getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which), getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which), @@ -12962,12 +13520,12 @@ public class BatteryStatsImpl extends BatteryStats { public GpsBatteryStats getGpsBatteryStats() { GpsBatteryStats s = new GpsBatteryStats(); final int which = STATS_SINCE_CHARGED; - final long rawRealTime = SystemClock.elapsedRealtime() * 1000; - s.setLoggingDurationMs(computeBatteryRealtime(rawRealTime, which) / 1000); + final long rawRealTimeUs = SystemClock.elapsedRealtime() * 1000; + s.setLoggingDurationMs(computeBatteryRealtime(rawRealTimeUs, which) / 1000); s.setEnergyConsumedMaMs(getGpsBatteryDrainMaMs()); long[] time = new long[GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS]; for (int i=0; i<time.length; i++) { - time[i] = getGpsSignalQualityTime(i, rawRealTime, which) / 1000; + time[i] = getGpsSignalQualityTime(i, rawRealTimeUs, which) / 1000; } s.setTimeInGpsSignalQualityLevel(time); return s; @@ -12988,19 +13546,29 @@ public class BatteryStatsImpl extends BatteryStats { return mDailyPackageChanges; } + /** + * @return battery uptime in microseconds + */ protected long getBatteryUptimeLocked() { - return mOnBatteryTimeBase.getUptime(mClocks.uptimeMillis() * 1000); + return getBatteryUptimeLocked(mClocks.uptimeMillis()); + } + + /** + * @return battery uptime in microseconds + */ + protected long getBatteryUptimeLocked(long uptimeMs) { + return mOnBatteryTimeBase.getUptime(uptimeMs * 1000); } @Override - public long getBatteryUptime(long curTime) { - return mOnBatteryTimeBase.getUptime(curTime); + public long getBatteryUptime(long curTimeUs) { + return mOnBatteryTimeBase.getUptime(curTimeUs); } @Override @UnsupportedAppUsage - public long getBatteryRealtime(long curTime) { - return mOnBatteryTimeBase.getRealtime(curTime); + public long getBatteryRealtime(long curTimeUs) { + return mOnBatteryTimeBase.getRealtime(curTimeUs); } @Override @@ -13188,22 +13756,22 @@ public class BatteryStatsImpl extends BatteryStats { return 0; } - final long uidTimeAtCpuSpeed = systemUid.getTimeAtCpuSpeed(cluster, step, + final long uidTimeAtCpuSpeedUs = systemUid.getTimeAtCpuSpeed(cluster, step, BatteryStats.STATS_SINCE_CHARGED); - if (uidTimeAtCpuSpeed == 0) { + if (uidTimeAtCpuSpeedUs == 0) { return 0; } - final long uidThreadTime = + final long uidThreadTimeUs = threadTimesForCluster[step].getCountLocked(BatteryStats.STATS_SINCE_CHARGED); - if (uidThreadTime == 0) { + if (uidThreadTimeUs == 0) { return 0; } - final long binderThreadTime = mBinderThreadCpuTimesUs[cluster][step].getCountLocked( + final long binderThreadTimeUs = mBinderThreadCpuTimesUs[cluster][step].getCountLocked( BatteryStats.STATS_SINCE_CHARGED); - return uidTimeAtCpuSpeed * binderThreadTime / uidThreadTime; + return uidTimeAtCpuSpeedUs * binderThreadTimeUs / uidThreadTimeUs; } /** @@ -13211,9 +13779,13 @@ public class BatteryStatsImpl extends BatteryStats { */ @UnsupportedAppUsage public Uid getUidStatsLocked(int uid) { + return getUidStatsLocked(uid, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public Uid getUidStatsLocked(int uid, long elapsedRealtimeMs, long uptimeMs) { Uid u = mUidStats.get(uid); if (u == null) { - u = new Uid(this, uid); + u = new Uid(this, uid, elapsedRealtimeMs, uptimeMs); mUidStats.put(uid, u); } return u; @@ -13229,10 +13801,14 @@ public class BatteryStatsImpl extends BatteryStats { } public void onCleanupUserLocked(int userId) { + onCleanupUserLocked(userId, mClocks.elapsedRealtime()); + } + + public void onCleanupUserLocked(int userId, long elapsedRealtimeMs) { final int firstUidForUser = UserHandle.getUid(userId, 0); final int lastUidForUser = UserHandle.getUid(userId, UserHandle.PER_USER_RANGE - 1); mPendingRemovedUids.add( - new UidToRemove(firstUidForUser, lastUidForUser, mClocks.elapsedRealtime())); + new UidToRemove(firstUidForUser, lastUidForUser, elapsedRealtimeMs)); } public void onUserRemovedLocked(int userId) { @@ -13256,12 +13832,19 @@ public class BatteryStatsImpl extends BatteryStats { */ @UnsupportedAppUsage public void removeUidStatsLocked(int uid) { + removeUidStatsLocked(uid, mClocks.elapsedRealtime()); + } + + /** + * @see #removeUidStatsLocked(int) + */ + public void removeUidStatsLocked(int uid, long elapsedRealtimeMs) { final Uid u = mUidStats.get(uid); if (u != null) { u.detachFromTimeBase(); } mUidStats.remove(uid); - mPendingRemovedUids.add(new UidToRemove(uid, mClocks.elapsedRealtime())); + mPendingRemovedUids.add(new UidToRemove(uid, elapsedRealtimeMs)); } /** @@ -13270,8 +13853,16 @@ public class BatteryStatsImpl extends BatteryStats { */ @UnsupportedAppUsage public Uid.Proc getProcessStatsLocked(int uid, String name) { + return getProcessStatsLocked(uid, name, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + /** + * @see #getProcessStatsLocked(int, String) + */ + public Uid.Proc getProcessStatsLocked(int uid, String name, + long elapsedRealtimeMs, long uptimeMs) { uid = mapUid(uid); - Uid u = getUidStatsLocked(uid); + Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs); return u.getProcessStatsLocked(name); } @@ -13281,8 +13872,16 @@ public class BatteryStatsImpl extends BatteryStats { */ @UnsupportedAppUsage public Uid.Pkg getPackageStatsLocked(int uid, String pkg) { + return getPackageStatsLocked(uid, pkg, mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + /** + * @see getPackageStatsLocked(int, String) + */ + public Uid.Pkg getPackageStatsLocked(int uid, String pkg, + long elapsedRealtimeMs, long uptimeMs) { uid = mapUid(uid); - Uid u = getUidStatsLocked(uid); + Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs); return u.getPackageStatsLocked(pkg); } @@ -13292,13 +13891,19 @@ public class BatteryStatsImpl extends BatteryStats { */ @UnsupportedAppUsage public Uid.Pkg.Serv getServiceStatsLocked(int uid, String pkg, String name) { + return getServiceStatsLocked(uid, pkg, name, + mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + } + + public Uid.Pkg.Serv getServiceStatsLocked(int uid, String pkg, String name, + long elapsedRealtimeMs, long uptimeMs) { uid = mapUid(uid); - Uid u = getUidStatsLocked(uid); + Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs); return u.getServiceStatsLocked(pkg, name); } public void shutdownLocked() { - recordShutdownLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis()); + recordShutdownLocked(System.currentTimeMillis(), mClocks.elapsedRealtime()); writeSyncLocked(); mShuttingDown = true; } @@ -13462,7 +14067,7 @@ public class BatteryStatsImpl extends BatteryStats { mNumSingleUidCpuTimeReads = 0; mNumBatchedSingleUidCpuTimeReads = 0; - mCpuTimeReadsTrackingStartTime = mClocks.uptimeMillis(); + mCpuTimeReadsTrackingStartTimeMs = mClocks.uptimeMillis(); } } @@ -13471,7 +14076,7 @@ public class BatteryStatsImpl extends BatteryStats { if (oldDelayMillis != newDelayMillis) { mNumSingleUidCpuTimeReads = 0; mNumBatchedSingleUidCpuTimeReads = 0; - mCpuTimeReadsTrackingStartTime = mClocks.uptimeMillis(); + mCpuTimeReadsTrackingStartTimeMs = mClocks.uptimeMillis(); } } @@ -13569,11 +14174,11 @@ public class BatteryStatsImpl extends BatteryStats { Uid uid = mUidStats.get(u); double proportionalSystemServiceUsage = uid.getProportionalSystemServiceUsage(); - long time = 0; + long timeUs = 0; for (int cluster = 0; cluster < mSystemServerThreadCpuTimesUs.length; cluster++) { int numSpeeds = mSystemServerThreadCpuTimesUs[cluster].length; for (int speed = 0; speed < numSpeeds; speed++) { - time += getSystemServiceTimeAtCpuSpeed(cluster, speed) + timeUs += getSystemServiceTimeAtCpuSpeed(cluster, speed) * proportionalSystemServiceUsage; } } @@ -13581,7 +14186,7 @@ public class BatteryStatsImpl extends BatteryStats { pw.print(" "); pw.print(u); pw.print(": "); - pw.println(time); + pw.println(timeUs / 1000); } } } @@ -13616,7 +14221,7 @@ public class BatteryStatsImpl extends BatteryStats { Slog.d(TAG, "writeSummaryToParcel duration ms:" + (SystemClock.uptimeMillis() - start) + " bytes:" + p.dataSize()); } - mLastWriteTime = mClocks.elapsedRealtime(); + mLastWriteTimeMs = mClocks.elapsedRealtime(); writeParcelToFileLocked(p, mStatsFile, sync); } @@ -13657,18 +14262,18 @@ public class BatteryStatsImpl extends BatteryStats { mWriteLock.lock(); FileOutputStream fos = null; try { - final long startTime = SystemClock.uptimeMillis(); + final long startTimeMs = SystemClock.uptimeMillis(); fos = file.startWrite(); fos.write(p.marshall()); fos.flush(); file.finishWrite(fos); if (DEBUG) { Slog.d(TAG, "commitPendingDataToDisk file:" + file.getBaseFile().getPath() - + " duration ms:" + (SystemClock.uptimeMillis() - startTime) + + " duration ms:" + (SystemClock.uptimeMillis() - startTimeMs) + " bytes:" + p.dataSize()); } com.android.internal.logging.EventLogTags.writeCommitSysConfigFile( - "batterystats", SystemClock.uptimeMillis() - startTime); + "batterystats", SystemClock.uptimeMillis() - startTimeMs); } catch (IOException e) { Slog.w(TAG, "Error writing battery statistics", e); file.failWrite(fos); @@ -13714,7 +14319,7 @@ public class BatteryStatsImpl extends BatteryStats { } } catch (Exception e) { Slog.e(TAG, "Error reading battery statistics", e); - resetAllStatsLocked(); + resetAllStatsLocked(SystemClock.uptimeMillis(), SystemClock.elapsedRealtime()); } finally { stats.recycle(); } @@ -13749,16 +14354,17 @@ public class BatteryStatsImpl extends BatteryStats { if (mHistoryBuffer.dataPosition() > 0 || mBatteryStatsHistory.getFilesNumbers().size() > 1) { mRecordingHistory = true; - final long elapsedRealtime = mClocks.elapsedRealtime(); - final long uptime = mClocks.uptimeMillis(); + final long elapsedRealtimeMs = mClocks.elapsedRealtime(); + final long uptimeMs = mClocks.uptimeMillis(); if (USE_OLD_HISTORY) { - addHistoryRecordLocked(elapsedRealtime, uptime, HistoryItem.CMD_START, mHistoryCur); + addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs, + HistoryItem.CMD_START, mHistoryCur); } - addHistoryBufferLocked(elapsedRealtime, HistoryItem.CMD_START, mHistoryCur); - startRecordingHistory(elapsedRealtime, uptime, false); + addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_START, mHistoryCur); + startRecordingHistory(elapsedRealtimeMs, uptimeMs, false); } - recordDailyStatsIfNeededLocked(false); + recordDailyStatsIfNeededLocked(false, System.currentTimeMillis()); } public int describeContents() { @@ -13799,27 +14405,27 @@ public class BatteryStatsImpl extends BatteryStats { if (DEBUG_HISTORY) { StringBuilder sb = new StringBuilder(128); - sb.append("****************** OLD mHistoryBaseTime: "); - TimeUtils.formatDuration(mHistoryBaseTime, sb); + sb.append("****************** OLD mHistoryBaseTimeMs: "); + TimeUtils.formatDuration(mHistoryBaseTimeMs, sb); Slog.i(TAG, sb.toString()); } - mHistoryBaseTime = historyBaseTime; + mHistoryBaseTimeMs = historyBaseTime; if (DEBUG_HISTORY) { StringBuilder sb = new StringBuilder(128); - sb.append("****************** NEW mHistoryBaseTime: "); - TimeUtils.formatDuration(mHistoryBaseTime, sb); + sb.append("****************** NEW mHistoryBaseTimeMs: "); + TimeUtils.formatDuration(mHistoryBaseTimeMs, sb); Slog.i(TAG, sb.toString()); } // We are just arbitrarily going to insert 1 minute from the sample of // the last run until samples in this run. - if (mHistoryBaseTime > 0) { + if (mHistoryBaseTimeMs > 0) { long oldnow = mClocks.elapsedRealtime(); - mHistoryBaseTime = mHistoryBaseTime - oldnow + 1; + mHistoryBaseTimeMs = mHistoryBaseTimeMs - oldnow + 1; if (DEBUG_HISTORY) { StringBuilder sb = new StringBuilder(128); - sb.append("****************** ADJUSTED mHistoryBaseTime: "); - TimeUtils.formatDuration(mHistoryBaseTime, sb); + sb.append("****************** ADJUSTED mHistoryBaseTimeMs: "); + TimeUtils.formatDuration(mHistoryBaseTimeMs, sb); Slog.i(TAG, sb.toString()); } } @@ -13839,14 +14445,14 @@ public class BatteryStatsImpl extends BatteryStats { void writeHistoryBuffer(Parcel out, boolean inclData, boolean andOldHistory) { if (DEBUG_HISTORY) { StringBuilder sb = new StringBuilder(128); - sb.append("****************** WRITING mHistoryBaseTime: "); - TimeUtils.formatDuration(mHistoryBaseTime, sb); - sb.append(" mLastHistoryElapsedRealtime: "); - TimeUtils.formatDuration(mLastHistoryElapsedRealtime, sb); + sb.append("****************** WRITING mHistoryBaseTimeMs: "); + TimeUtils.formatDuration(mHistoryBaseTimeMs, sb); + sb.append(" mLastHistoryElapsedRealtimeMs: "); + TimeUtils.formatDuration(mLastHistoryElapsedRealtimeMs, sb); Slog.i(TAG, sb.toString()); } out.writeInt(VERSION); - out.writeLong(mHistoryBaseTime + mLastHistoryElapsedRealtime); + out.writeLong(mHistoryBaseTimeMs + mLastHistoryElapsedRealtimeMs); if (!inclData) { out.writeInt(0); out.writeInt(0); @@ -13913,9 +14519,9 @@ public class BatteryStatsImpl extends BatteryStats { } mStartCount = in.readInt(); - mUptime = in.readLong(); - mRealtime = in.readLong(); - mStartClockTime = in.readLong(); + mUptimeUs = in.readLong(); + mRealtimeUs = in.readLong(); + mStartClockTimeMs = in.readLong(); mStartPlatformVersion = in.readString(); mEndPlatformVersion = in.readString(); mOnBatteryTimeBase.readSummaryFromParcel(in); @@ -13955,9 +14561,9 @@ public class BatteryStatsImpl extends BatteryStats { } else { mDailyPackageChanges = null; } - mDailyStartTime = in.readLong(); - mNextMinDailyDeadline = in.readLong(); - mNextMaxDailyDeadline = in.readLong(); + mDailyStartTimeMs = in.readLong(); + mNextMinDailyDeadlineMs = in.readLong(); + mNextMaxDailyDeadlineMs = in.readLong(); mStartCount++; @@ -13971,8 +14577,8 @@ public class BatteryStatsImpl extends BatteryStats { mInteractiveTimer.readSummaryFromParcelLocked(in); mPhoneOn = false; mPowerSaveModeEnabledTimer.readSummaryFromParcelLocked(in); - mLongestLightIdleTime = in.readLong(); - mLongestFullIdleTime = in.readLong(); + mLongestLightIdleTimeMs = in.readLong(); + mLongestFullIdleTimeMs = in.readLong(); mDeviceIdleModeLightTimer.readSummaryFromParcelLocked(in); mDeviceIdleModeFullTimer.readSummaryFromParcelLocked(in); mDeviceLightIdlingTimer.readSummaryFromParcelLocked(in); @@ -14084,9 +14690,11 @@ public class BatteryStatsImpl extends BatteryStats { if (NU > 10000) { throw new ParcelFormatException("File corrupt: too many uids " + NU); } + final long elapsedRealtimeMs = mClocks.elapsedRealtime(); + final long uptimeMs = mClocks.uptimeMillis(); for (int iu = 0; iu < NU; iu++) { int uid = in.readInt(); - Uid u = new Uid(this, uid); + Uid u = new Uid(this, uid, elapsedRealtimeMs, uptimeMs); mUidStats.put(uid, u); u.mOnBatteryBackgroundTimeBase.readSummaryFromParcel(in); @@ -14329,9 +14937,9 @@ public class BatteryStatsImpl extends BatteryStats { for (int ip = 0; ip < NP; ip++) { String procName = in.readString(); Uid.Proc p = u.getProcessStatsLocked(procName); - p.mUserTime = in.readLong(); - p.mSystemTime = in.readLong(); - p.mForegroundTime = in.readLong(); + p.mUserTimeMs = in.readLong(); + p.mSystemTimeMs = in.readLong(); + p.mForegroundTimeMs = in.readLong(); p.mStarts = in.readInt(); p.mNumCrashes = in.readInt(); p.mNumAnrs = in.readInt(); @@ -14364,7 +14972,7 @@ public class BatteryStatsImpl extends BatteryStats { for (int is = 0; is < NS; is++) { String servName = in.readString(); Uid.Pkg.Serv s = u.getServiceStatsLocked(pkgName, servName); - s.mStartTime = in.readLong(); + s.mStartTimeMs = in.readLong(); s.mStarts = in.readInt(); s.mLaunches = in.readInt(); } @@ -14407,7 +15015,7 @@ public class BatteryStatsImpl extends BatteryStats { out.writeInt(mStartCount); out.writeLong(computeUptime(NOW_SYS, STATS_SINCE_CHARGED)); out.writeLong(computeRealtime(NOWREAL_SYS, STATS_SINCE_CHARGED)); - out.writeLong(mStartClockTime); + out.writeLong(mStartClockTimeMs); out.writeString(mStartPlatformVersion); out.writeString(mEndPlatformVersion); mOnBatteryTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS); @@ -14445,9 +15053,9 @@ public class BatteryStatsImpl extends BatteryStats { } else { out.writeInt(0); } - out.writeLong(mDailyStartTime); - out.writeLong(mNextMinDailyDeadline); - out.writeLong(mNextMaxDailyDeadline); + out.writeLong(mDailyStartTimeMs); + out.writeLong(mNextMinDailyDeadlineMs); + out.writeLong(mNextMaxDailyDeadlineMs); mScreenOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); mScreenDozeTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); @@ -14456,8 +15064,8 @@ public class BatteryStatsImpl extends BatteryStats { } mInteractiveTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); mPowerSaveModeEnabledTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); - out.writeLong(mLongestLightIdleTime); - out.writeLong(mLongestFullIdleTime); + out.writeLong(mLongestLightIdleTimeMs); + out.writeLong(mLongestFullIdleTimeMs); mDeviceIdleModeLightTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); mDeviceIdleModeFullTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); mDeviceLightIdlingTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS); @@ -14852,9 +15460,9 @@ public class BatteryStatsImpl extends BatteryStats { for (int ip=0; ip<NP; ip++) { out.writeString(u.mProcessStats.keyAt(ip)); Uid.Proc ps = u.mProcessStats.valueAt(ip); - out.writeLong(ps.mUserTime); - out.writeLong(ps.mSystemTime); - out.writeLong(ps.mForegroundTime); + out.writeLong(ps.mUserTimeMs); + out.writeLong(ps.mSystemTimeMs); + out.writeLong(ps.mForegroundTimeMs); out.writeInt(ps.mStarts); out.writeInt(ps.mNumCrashes); out.writeInt(ps.mNumAnrs); @@ -14880,7 +15488,7 @@ public class BatteryStatsImpl extends BatteryStats { out.writeString(ps.mServiceStats.keyAt(is)); BatteryStatsImpl.Uid.Pkg.Serv ss = ps.mServiceStats.valueAt(is); long time = ss.getStartTimeToNowLocked( - mOnBatteryTimeBase.getUptime(NOW_SYS)); + mOnBatteryTimeBase.getUptime(NOW_SYS) / 1000); out.writeLong(time); out.writeInt(ss.mStarts); out.writeInt(ss.mLaunches); @@ -14904,13 +15512,13 @@ public class BatteryStatsImpl extends BatteryStats { mBatteryStatsHistory.readFromParcel(in); mStartCount = in.readInt(); - mStartClockTime = in.readLong(); + mStartClockTimeMs = in.readLong(); mStartPlatformVersion = in.readString(); mEndPlatformVersion = in.readString(); - mUptime = in.readLong(); - mUptimeStart = in.readLong(); - mRealtime = in.readLong(); - mRealtimeStart = in.readLong(); + mUptimeUs = in.readLong(); + mUptimeStartUs = in.readLong(); + mRealtimeUs = in.readLong(); + mRealtimeStartUs = in.readLong(); mOnBattery = in.readInt() != 0; mEstimatedBatteryCapacity = in.readInt(); mMinLearnedBatteryCapacity = in.readInt(); @@ -14931,8 +15539,8 @@ public class BatteryStatsImpl extends BatteryStats { mPhoneOn = false; mPowerSaveModeEnabledTimer = new StopwatchTimer(mClocks, null, -2, null, mOnBatteryTimeBase, in); - mLongestLightIdleTime = in.readLong(); - mLongestFullIdleTime = in.readLong(); + mLongestLightIdleTimeMs = in.readLong(); + mLongestFullIdleTimeMs = in.readLong(); mDeviceIdleModeLightTimer = new StopwatchTimer(mClocks, null, -14, null, mOnBatteryTimeBase, in); mDeviceIdleModeFullTimer = new StopwatchTimer(mClocks, null, -11, null, @@ -15030,7 +15638,7 @@ public class BatteryStatsImpl extends BatteryStats { mDischargeScreenDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase, in); mDischargeLightDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase, in); mDischargeDeepDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase, in); - mLastWriteTime = in.readLong(); + mLastWriteTimeMs = in.readLong(); mRpmStats.clear(); int NRPMS = in.readInt(); @@ -15096,9 +15704,11 @@ public class BatteryStatsImpl extends BatteryStats { int numUids = in.readInt(); mUidStats.clear(); + final long elapsedRealtimeMs = mClocks.elapsedRealtime(); + final long uptimeMs = mClocks.uptimeMillis(); for (int i = 0; i < numUids; i++) { int uid = in.readInt(); - Uid u = new Uid(this, uid); + Uid u = new Uid(this, uid, elapsedRealtimeMs, uptimeMs); u.readFromParcelLocked(mOnBatteryTimeBase, mOnBatteryScreenOffTimeBase, in); mUidStats.append(uid, u); } @@ -15137,13 +15747,13 @@ public class BatteryStatsImpl extends BatteryStats { mBatteryStatsHistory.writeToParcel(out); out.writeInt(mStartCount); - out.writeLong(mStartClockTime); + out.writeLong(mStartClockTimeMs); out.writeString(mStartPlatformVersion); out.writeString(mEndPlatformVersion); - out.writeLong(mUptime); - out.writeLong(mUptimeStart); - out.writeLong(mRealtime); - out.writeLong(mRealtimeStart); + out.writeLong(mUptimeUs); + out.writeLong(mUptimeStartUs); + out.writeLong(mRealtimeUs); + out.writeLong(mRealtimeStartUs); out.writeInt(mOnBattery ? 1 : 0); out.writeInt(mEstimatedBatteryCapacity); out.writeInt(mMinLearnedBatteryCapacity); @@ -15158,8 +15768,8 @@ public class BatteryStatsImpl extends BatteryStats { } mInteractiveTimer.writeToParcel(out, uSecRealtime); mPowerSaveModeEnabledTimer.writeToParcel(out, uSecRealtime); - out.writeLong(mLongestLightIdleTime); - out.writeLong(mLongestFullIdleTime); + out.writeLong(mLongestLightIdleTimeMs); + out.writeLong(mLongestFullIdleTimeMs); mDeviceIdleModeLightTimer.writeToParcel(out, uSecRealtime); mDeviceIdleModeFullTimer.writeToParcel(out, uSecRealtime); mDeviceLightIdlingTimer.writeToParcel(out, uSecRealtime); @@ -15227,7 +15837,7 @@ public class BatteryStatsImpl extends BatteryStats { mDischargeScreenDozeCounter.writeToParcel(out); mDischargeLightDozeCounter.writeToParcel(out); mDischargeDeepDozeCounter.writeToParcel(out); - out.writeLong(mLastWriteTime); + out.writeLong(mLastWriteTimeMs); out.writeInt(mRpmStats.size()); for (Map.Entry<String, SamplingTimer> ent : mRpmStats.entrySet()) { @@ -15472,7 +16082,7 @@ public class BatteryStatsImpl extends BatteryStats { pw.print("Batched cpu time reads: "); pw.println(mNumBatchedSingleUidCpuTimeReads); pw.print("Batching Duration (min): "); - pw.println((mClocks.uptimeMillis() - mCpuTimeReadsTrackingStartTime) / (60 * 1000)); + pw.println((mClocks.uptimeMillis() - mCpuTimeReadsTrackingStartTimeMs) / (60 * 1000)); pw.print("All UID cpu time reads since the later of device start or stats reset: "); pw.println(mNumAllUidCpuTimeReads); pw.print("UIDs removed since the later of device start or stats reset: "); diff --git a/core/java/com/android/internal/view/BaseIWindow.java b/core/java/com/android/internal/view/BaseIWindow.java index 7f3eb4515654..d5f54a199828 100644 --- a/core/java/com/android/internal/view/BaseIWindow.java +++ b/core/java/com/android/internal/view/BaseIWindow.java @@ -18,13 +18,11 @@ package com.android.internal.view; import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Point; -import android.graphics.Rect; import android.hardware.input.InputManager; import android.os.Bundle; import android.os.ParcelFileDescriptor; import android.os.RemoteException; import android.util.MergedConfiguration; -import android.view.DisplayCutout; import android.view.DragEvent; import android.view.IScrollCaptureController; import android.view.IWindow; @@ -33,6 +31,7 @@ import android.view.InsetsSourceControl; import android.view.InsetsState; import android.view.PointerIcon; import android.view.WindowInsets.Type.InsetsType; +import android.window.ClientWindowFrames; import com.android.internal.os.IResultReceiver; @@ -51,11 +50,9 @@ public class BaseIWindow extends IWindow.Stub { } @Override - public void resized(Rect frame, Rect contentInsets, Rect visibleInsets, - Rect stableInsets, boolean reportDraw, - MergedConfiguration mergedConfiguration, Rect backDropFrame, boolean forceLayout, - boolean alwaysConsumeSystemBars, int displayId, - DisplayCutout.ParcelableWrapper displayCutout) { + public void resized(ClientWindowFrames frames, boolean reportDraw, + MergedConfiguration mergedConfiguration, boolean forceLayout, + boolean alwaysConsumeSystemBars, int displayId) { if (reportDraw) { try { mSession.finishDrawing(this, null /* postDrawTransaction */); diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp index 3f39478ffd43..5c4c5099bf4c 100644 --- a/core/jni/android_media_AudioSystem.cpp +++ b/core/jni/android_media_AudioSystem.cpp @@ -2407,6 +2407,79 @@ static jint android_media_AudioSystem_getDevicesForRoleAndStrategy(JNIEnv *env, return AUDIO_JAVA_SUCCESS; } +static jint android_media_AudioSystem_setDevicesRoleForCapturePreset( + JNIEnv *env, jobject thiz, jint capturePreset, jint role, jintArray jDeviceTypes, + jobjectArray jDeviceAddresses) { + AudioDeviceTypeAddrVector nDevices; + jint results = getVectorOfAudioDeviceTypeAddr(env, jDeviceTypes, jDeviceAddresses, nDevices); + if (results != NO_ERROR) { + return results; + } + int status = check_AudioSystem_Command( + AudioSystem::setDevicesRoleForCapturePreset((audio_source_t)capturePreset, + (device_role_t)role, nDevices)); + return (jint)status; +} + +static jint android_media_AudioSystem_addDevicesRoleForCapturePreset( + JNIEnv *env, jobject thiz, jint capturePreset, jint role, jintArray jDeviceTypes, + jobjectArray jDeviceAddresses) { + AudioDeviceTypeAddrVector nDevices; + jint results = getVectorOfAudioDeviceTypeAddr(env, jDeviceTypes, jDeviceAddresses, nDevices); + if (results != NO_ERROR) { + return results; + } + int status = check_AudioSystem_Command( + AudioSystem::addDevicesRoleForCapturePreset((audio_source_t)capturePreset, + (device_role_t)role, nDevices)); + return (jint)status; +} + +static jint android_media_AudioSystem_removeDevicesRoleForCapturePreset( + JNIEnv *env, jobject thiz, jint capturePreset, jint role, jintArray jDeviceTypes, + jobjectArray jDeviceAddresses) { + AudioDeviceTypeAddrVector nDevices; + jint results = getVectorOfAudioDeviceTypeAddr(env, jDeviceTypes, jDeviceAddresses, nDevices); + if (results != NO_ERROR) { + return results; + } + int status = check_AudioSystem_Command( + AudioSystem::removeDevicesRoleForCapturePreset((audio_source_t)capturePreset, + (device_role_t)role, nDevices)); + return (jint)status; +} + +static jint android_media_AudioSystem_clearDevicesRoleForCapturePreset(JNIEnv *env, jobject thiz, + jint capturePreset, + jint role) { + return (jint)check_AudioSystem_Command( + AudioSystem::clearDevicesRoleForCapturePreset((audio_source_t)capturePreset, + (device_role_t)role)); +} + +static jint android_media_AudioSystem_getDevicesForRoleAndCapturePreset(JNIEnv *env, jobject thiz, + jint capturePreset, + jint role, + jobject jDevices) { + AudioDeviceTypeAddrVector nDevices; + status_t status = check_AudioSystem_Command( + AudioSystem::getDevicesForRoleAndCapturePreset((audio_source_t)capturePreset, + (device_role_t)role, nDevices)); + if (status != NO_ERROR) { + return (jint)status; + } + for (const auto &device : nDevices) { + jobject jAudioDeviceAttributes = NULL; + jint jStatus = createAudioDeviceAttributesFromNative(env, &jAudioDeviceAttributes, &device); + if (jStatus != AUDIO_JAVA_SUCCESS) { + return jStatus; + } + env->CallBooleanMethod(jDevices, gListMethods.add, jAudioDeviceAttributes); + env->DeleteLocalRef(jAudioDeviceAttributes); + } + return AUDIO_JAVA_SUCCESS; +} + static jint android_media_AudioSystem_getDevicesForAttributes(JNIEnv *env, jobject thiz, jobject jaa, jobjectArray jDeviceArray) @@ -2558,6 +2631,16 @@ static const JNINativeMethod gMethods[] = (void *)android_media_AudioSystem_removeDevicesRoleForStrategy}, {"getDevicesForRoleAndStrategy", "(IILjava/util/List;)I", (void *)android_media_AudioSystem_getDevicesForRoleAndStrategy}, + {"setDevicesRoleForCapturePreset", "(II[I[Ljava/lang/String;)I", + (void *)android_media_AudioSystem_setDevicesRoleForCapturePreset}, + {"addDevicesRoleForCapturePreset", "(II[I[Ljava/lang/String;)I", + (void *)android_media_AudioSystem_addDevicesRoleForCapturePreset}, + {"removeDevicesRoleForCapturePreset", "(II[I[Ljava/lang/String;)I", + (void *)android_media_AudioSystem_removeDevicesRoleForCapturePreset}, + {"clearDevicesRoleForCapturePreset", "(II)I", + (void *)android_media_AudioSystem_clearDevicesRoleForCapturePreset}, + {"getDevicesForRoleAndCapturePreset", "(IILjava/util/List;)I", + (void *)android_media_AudioSystem_getDevicesForRoleAndCapturePreset}, {"getDevicesForAttributes", "(Landroid/media/AudioAttributes;[Landroid/media/AudioDeviceAttributes;)I", (void *)android_media_AudioSystem_getDevicesForAttributes}, diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp index c51f334f1f2e..c08363bbb0ba 100644 --- a/core/jni/android_util_Process.cpp +++ b/core/jni/android_util_Process.cpp @@ -19,18 +19,16 @@ // To make sure cpu_set_t is included from sched.h #define _GNU_SOURCE 1 -#include <android-base/properties.h> -#include <android-base/unique_fd.h> -#include <binder/ActivityManager.h> +#include <utils/Log.h> #include <binder/IPCThreadState.h> #include <binder/IServiceManager.h> +#include <utils/String8.h> +#include <utils/Vector.h> #include <meminfo/procmeminfo.h> #include <meminfo/sysmeminfo.h> #include <processgroup/processgroup.h> #include <processgroup/sched_policy.h> -#include <utils/Log.h> -#include <utils/String8.h> -#include <utils/Vector.h> +#include <android-base/unique_fd.h> #include <algorithm> #include <array> @@ -86,8 +84,6 @@ Mutex gKeyCreateMutex; static pthread_key_t gBgKey = -1; #endif -static bool boot_completed = false; - // For both of these, err should be in the errno range (positive), not a status_t (negative) static void signalExceptionForError(JNIEnv* env, int err, int tid) { switch (err) { @@ -584,20 +580,7 @@ void android_os_Process_setThreadPriority(JNIEnv* env, jobject clazz, } #endif - SchedPolicy policy; - bool policy_changed = false; - int rc = 0, curr_pri = getpriority(PRIO_PROCESS, pid); - - if (pri == curr_pri) { - return; - } - - if (!boot_completed) { - boot_completed = android::base::GetBoolProperty("sys.boot_completed", false); - } - - // Do not change sched policy cgroup after boot complete. - rc = androidSetThreadPriorityAndPolicy(pid, pri, !boot_completed); + int rc = androidSetThreadPriority(pid, pri); if (rc != 0) { if (rc == INVALID_OPERATION) { signalExceptionForPriorityError(env, errno, pid); @@ -606,31 +589,6 @@ void android_os_Process_setThreadPriority(JNIEnv* env, jobject clazz, } } - // Only use async approach after boot complete. - if (!boot_completed) { - return; - } - - // Change to background sched policy for the thread if setting to low priority. - if (pri >= ANDROID_PRIORITY_BACKGROUND) { - policy = SP_BACKGROUND; - policy_changed = true; - // Change to sched policy of the process if thread priority is raising from low priority. - } else if (curr_pri >= ANDROID_PRIORITY_BACKGROUND) { - // If we cannot get sched policy of the process, use SP_FOREGROUND as default. - policy = SP_FOREGROUND; - get_sched_policy(getpid(), &policy); - policy_changed = true; - } - - // Sched policy will only change in above 2 cases. - if (policy_changed) { - ActivityManager am; - if (!am.setSchedPolicyCgroup(pid, policy)) { - ALOGE("am.setThreadPriority failed: tid=%d priority=%d policy=%d", pid, pri, policy); - } - } - //ALOGI("Setting priority of %" PRId32 ": %" PRId32 ", getpriority returns %d\n", // pid, pri, getpriority(PRIO_PROCESS, pid)); } diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp index 85b4fe197980..f2b4a1b2b032 100644 --- a/core/jni/android_view_SurfaceControl.cpp +++ b/core/jni/android_view_SurfaceControl.cpp @@ -30,6 +30,7 @@ #include <android_runtime/android_hardware_HardwareBuffer.h> #include <android_runtime/android_view_Surface.h> #include <android_runtime/android_view_SurfaceSession.h> +#include <gui/IScreenCaptureListener.h> #include <gui/ISurfaceComposer.h> #include <gui/Surface.h> #include <gui/SurfaceComposerClient.h> @@ -188,6 +189,11 @@ static struct { static struct { jclass clazz; + jmethodID onScreenCaptureComplete; +} gScreenCaptureListenerClassInfo; + +static struct { + jclass clazz; jmethodID ctor; jfieldID defaultConfig; jfieldID primaryRefreshRateMin; @@ -226,6 +232,54 @@ constexpr ui::Dataspace pickDataspaceFromColorMode(const ui::ColorMode colorMode } } +class ScreenCaptureListenerWrapper : public BnScreenCaptureListener { +public: + explicit ScreenCaptureListenerWrapper(JNIEnv* env, jobject jobject) { + env->GetJavaVM(&mVm); + screenCaptureListenerObject = env->NewGlobalRef(jobject); + LOG_ALWAYS_FATAL_IF(!screenCaptureListenerObject, "Failed to make global ref"); + } + + ~ScreenCaptureListenerWrapper() { + if (screenCaptureListenerObject) { + getenv()->DeleteGlobalRef(screenCaptureListenerObject); + screenCaptureListenerObject = nullptr; + } + } + + status_t onScreenCaptureComplete(const ScreenCaptureResults& captureResults) { + JNIEnv* env = getenv(); + if (captureResults.result != NO_ERROR || captureResults.buffer == nullptr) { + env->CallVoidMethod(screenCaptureListenerObject, + gScreenCaptureListenerClassInfo.onScreenCaptureComplete, nullptr); + return NO_ERROR; + } + jobject jhardwareBuffer = android_hardware_HardwareBuffer_createFromAHardwareBuffer( + env, captureResults.buffer->toAHardwareBuffer()); + const jint namedColorSpace = + fromDataspaceToNamedColorSpaceValue(captureResults.capturedDataspace); + jobject screenshotHardwareBuffer = + env->CallStaticObjectMethod(gScreenshotHardwareBufferClassInfo.clazz, + gScreenshotHardwareBufferClassInfo.builder, + jhardwareBuffer, namedColorSpace, + captureResults.capturedSecureLayers); + env->CallVoidMethod(screenCaptureListenerObject, + gScreenCaptureListenerClassInfo.onScreenCaptureComplete, + screenshotHardwareBuffer); + return NO_ERROR; + } + +private: + jobject screenCaptureListenerObject; + JavaVM* mVm; + + JNIEnv* getenv() { + JNIEnv* env; + mVm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6); + return env; + } +}; + // ---------------------------------------------------------------------------- static jlong nativeCreateTransaction(JNIEnv* env, jclass clazz) { @@ -327,36 +381,28 @@ static DisplayCaptureArgs displayCaptureArgsFromObject(JNIEnv* env, return captureArgs; } -static jobject nativeCaptureDisplay(JNIEnv* env, jclass clazz, jobject displayCaptureArgsObject) { +static jint nativeCaptureDisplay(JNIEnv* env, jclass clazz, jobject displayCaptureArgsObject, + jobject screenCaptureListenerObject) { const DisplayCaptureArgs captureArgs = displayCaptureArgsFromObject(env, displayCaptureArgsObject); if (captureArgs.displayToken == NULL) { - return NULL; - } - - ScreenCaptureResults captureResults; - status_t res = ScreenshotClient::captureDisplay(captureArgs, captureResults); - if (res != NO_ERROR) { - return NULL; + return BAD_VALUE; } - jobject jhardwareBuffer = android_hardware_HardwareBuffer_createFromAHardwareBuffer( - env, captureResults.buffer->toAHardwareBuffer()); - const jint namedColorSpace = - fromDataspaceToNamedColorSpaceValue(captureResults.capturedDataspace); - return env->CallStaticObjectMethod(gScreenshotHardwareBufferClassInfo.clazz, - gScreenshotHardwareBufferClassInfo.builder, jhardwareBuffer, - namedColorSpace, captureResults.capturedSecureLayers); + sp<IScreenCaptureListener> captureListener = + new ScreenCaptureListenerWrapper(env, screenCaptureListenerObject); + return ScreenshotClient::captureDisplay(captureArgs, captureListener); } -static jobject nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject layerCaptureArgsObject) { +static jint nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject layerCaptureArgsObject, + jobject screenCaptureListenerObject) { LayerCaptureArgs captureArgs; getCaptureArgs(env, layerCaptureArgsObject, captureArgs); SurfaceControl* layer = reinterpret_cast<SurfaceControl*>( env->GetLongField(layerCaptureArgsObject, gLayerCaptureArgsClassInfo.layer)); if (layer == nullptr) { - return nullptr; + return BAD_VALUE; } captureArgs.layerHandle = layer->getHandle(); @@ -380,19 +426,9 @@ static jobject nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject layerCaptu env->ReleaseLongArrayElements(excludeObjectArray, const_cast<jlong*>(objects), JNI_ABORT); } - ScreenCaptureResults captureResults; - status_t res = ScreenshotClient::captureLayers(captureArgs, captureResults); - if (res != NO_ERROR) { - return NULL; - } - - jobject jhardwareBuffer = android_hardware_HardwareBuffer_createFromAHardwareBuffer( - env, captureResults.buffer->toAHardwareBuffer()); - const jint namedColorSpace = - fromDataspaceToNamedColorSpaceValue(captureResults.capturedDataspace); - return env->CallStaticObjectMethod(gScreenshotHardwareBufferClassInfo.clazz, - gScreenshotHardwareBufferClassInfo.builder, jhardwareBuffer, - namedColorSpace, captureResults.capturedSecureLayers); + sp<IScreenCaptureListener> captureListener = + new ScreenCaptureListenerWrapper(env, screenCaptureListenerObject); + return ScreenshotClient::captureLayers(captureArgs, captureListener); } static void nativeApplyTransaction(JNIEnv* env, jclass clazz, jlong transactionObj, jboolean sync) { @@ -1505,9 +1541,25 @@ static jlong nativeGetHandle(JNIEnv* env, jclass clazz, jlong nativeObject) { return reinterpret_cast<jlong>(surfaceControl->getHandle().get()); } +static void nativeSetFocusedWindow(JNIEnv* env, jclass clazz, jlong transactionObj, + jobject toTokenObj, jobject focusedTokenObj, jint displayId) { + auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj); + if (toTokenObj == NULL) return; + + sp<IBinder> toToken(ibinderForJavaObject(env, toTokenObj)); + sp<IBinder> focusedToken; + if (focusedTokenObj != NULL) { + focusedToken = ibinderForJavaObject(env, focusedTokenObj); + } + transaction->setFocusedWindow(toToken, focusedToken, systemTime(SYSTEM_TIME_MONOTONIC), + displayId); +} + // ---------------------------------------------------------------------------- +// clang-format off static const JNINativeMethod sSurfaceControlMethods[] = { + // clang-format off {"nativeCreate", "(Landroid/view/SurfaceSession;Ljava/lang/String;IIIIJLandroid/os/Parcel;)J", (void*)nativeCreate }, {"nativeReadFromParcel", "(Landroid/os/Parcel;)J", @@ -1649,12 +1701,10 @@ static const JNINativeMethod sSurfaceControlMethods[] = { {"nativeSetOverrideScalingMode", "(JJI)V", (void*)nativeSetOverrideScalingMode }, {"nativeCaptureDisplay", - "(Landroid/view/SurfaceControl$DisplayCaptureArgs;)" - "Landroid/view/SurfaceControl$ScreenshotHardwareBuffer;", + "(Landroid/view/SurfaceControl$DisplayCaptureArgs;Landroid/view/SurfaceControl$ScreenCaptureListener;)I", (void*)nativeCaptureDisplay }, {"nativeCaptureLayers", - "(Landroid/view/SurfaceControl$LayerCaptureArgs;)" - "Landroid/view/SurfaceControl$ScreenshotHardwareBuffer;", + "(Landroid/view/SurfaceControl$LayerCaptureArgs;Landroid/view/SurfaceControl$ScreenCaptureListener;)I", (void*)nativeCaptureLayers }, {"nativeSetInputWindowInfo", "(JJLandroid/view/InputWindowHandle;)V", (void*)nativeSetInputWindowInfo }, @@ -1686,8 +1736,13 @@ static const JNINativeMethod sSurfaceControlMethods[] = { (void*)nativeSetGlobalShadowSettings }, {"nativeGetHandle", "(J)J", (void*)nativeGetHandle }, - {"nativeSetFixedTransformHint", "(JJI)V", (void*)nativeSetFixedTransformHint}, + {"nativeSetFixedTransformHint", "(JJI)V", + (void*)nativeSetFixedTransformHint}, + {"nativeSetFocusedWindow", "(JLandroid/os/IBinder;Landroid/os/IBinder;I)V", + (void*)nativeSetFocusedWindow}, + // clang-format on }; +// clang-format on int register_android_view_SurfaceControl(JNIEnv* env) { @@ -1856,6 +1911,12 @@ int register_android_view_SurfaceControl(JNIEnv* env) gLayerCaptureArgsClassInfo.childrenOnly = GetFieldIDOrDie(env, layerCaptureArgsClazz, "mChildrenOnly", "Z"); + jclass screenCaptureListenerClazz = + FindClassOrDie(env, "android/view/SurfaceControl$ScreenCaptureListener"); + gScreenCaptureListenerClassInfo.clazz = MakeGlobalRefOrDie(env, screenCaptureListenerClazz); + gScreenCaptureListenerClassInfo.onScreenCaptureComplete = + GetMethodIDOrDie(env, screenCaptureListenerClazz, "onScreenCaptureComplete", + "(Landroid/view/SurfaceControl$ScreenshotHardwareBuffer;)V"); return err; } diff --git a/core/proto/android/providers/settings/secure.proto b/core/proto/android/providers/settings/secure.proto index 3d12d072eb80..7f743ef037a2 100644 --- a/core/proto/android/providers/settings/secure.proto +++ b/core/proto/android/providers/settings/secure.proto @@ -219,6 +219,8 @@ message SecureSettingsProto { optional SettingProto enhanced_voice_privacy_enabled = 23 [ (android.privacy).dest = DEST_AUTOMATIC ]; + optional SettingProto force_bold_text = 85 [ (android.privacy).dest = DEST_AUTOMATIC ]; + message Gesture { optional SettingProto aware_enabled = 1 [ (android.privacy).dest = DEST_AUTOMATIC ]; @@ -615,5 +617,5 @@ message SecureSettingsProto { // Please insert fields in alphabetical order and group them into messages // if possible (to avoid reaching the method limit). - // Next tag = 85; + // Next tag = 86; } diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index cdcb24b6a247..560e3c11d2f4 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -4691,6 +4691,12 @@ <permission android:name="android.permission.HANDLE_CAR_MODE_CHANGES" android:protectionLevel="signature|privileged" /> + <!-- @SystemApi Allows the holder to send category_car notifications. + @hide --> + <permission + android:name="android.permission.SEND_CATEGORY_CAR_NOTIFICATIONS" + android:protectionLevel="signature|privileged" /> + <!-- The system process is explicitly the only one allowed to launch the confirmation UI for full backup/restore --> <uses-permission android:name="android.permission.CONFIRM_FULL_BACKUP"/> @@ -5496,6 +5502,10 @@ android:permission="android.permission.BIND_JOB_SERVICE" > </service> + <service android:name="com.android.server.profcollect.ProfcollectForwardingService$ProfcollectBGJobService" + android:permission="android.permission.BIND_JOB_SERVICE" > + </service> + <service android:name="com.android.server.autofill.AutofillCompatAccessibilityService" android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE" diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 5f2e4f905b1c..550162a242dc 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -2258,7 +2258,7 @@ <!-- Amount of time in ms the user needs to press the relevant keys to trigger the screenshot chord --> - <integer name="config_screenshotChordKeyTimeout">500</integer> + <integer name="config_screenshotChordKeyTimeout">0</integer> <!-- Default width of a vertical scrollbar and height of a horizontal scrollbar. Takes effect only if the scrollbar drawables have no intrinsic size. --> @@ -2783,6 +2783,7 @@ <item>power</item> <item>restart</item> <item>logout</item> + <item>screenshot</item> <item>bugreport</item> </string-array> diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml index e17c312dbffc..6ae6faa5446e 100644 --- a/core/tests/coretests/AndroidManifest.xml +++ b/core/tests/coretests/AndroidManifest.xml @@ -50,6 +50,7 @@ <uses-permission android:name="android.permission.CLEAR_APP_CACHE" /> <uses-permission android:name="android.permission.CLEAR_APP_USER_DATA" /> <uses-permission android:name="android.permission.DELETE_CACHE_FILES" /> + <uses-permission android:name="android.permission.DEVICE_POWER"/> <uses-permission android:name="android.permission.DOWNLOAD_CACHE_NON_PURGEABLE" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/> <uses-permission android:name="android.permission.GET_PACKAGE_SIZE" /> diff --git a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java index 04906788f4cb..88faa0a49c9c 100644 --- a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java +++ b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java @@ -574,16 +574,16 @@ public class PackageManagerTests extends AndroidTestCase { InstallParams(String outFileName, int rawResId) throws PackageParserException { this.pkg = getParsedPackage(outFileName, rawResId); - this.packageURI = Uri.fromFile(new File(pkg.getCodePath())); + this.packageURI = Uri.fromFile(new File(pkg.getPath())); } InstallParams(ParsingPackage pkg) { - this.packageURI = Uri.fromFile(new File(pkg.getCodePath())); + this.packageURI = Uri.fromFile(new File(pkg.getPath())); this.pkg = pkg; } long getApkSize() { - File file = new File(pkg.getCodePath()); + File file = new File(pkg.getPath()); return file.length(); } } @@ -1003,7 +1003,7 @@ public class PackageManagerTests extends AndroidTestCase { try { cleanUpInstall(ip.pkg.getPackageName()); } finally { - File outFile = new File(ip.pkg.getCodePath()); + File outFile = new File(ip.pkg.getPath()); if (outFile != null && outFile.exists()) { outFile.delete(); } diff --git a/core/tests/coretests/src/com/android/internal/content/OverlayConfigIterationRule.java b/core/tests/coretests/src/com/android/internal/content/OverlayConfigIterationRule.java index fbf75dfb4979..a01459f20f6b 100644 --- a/core/tests/coretests/src/com/android/internal/content/OverlayConfigIterationRule.java +++ b/core/tests/coretests/src/com/android/internal/content/OverlayConfigIterationRule.java @@ -146,7 +146,7 @@ public class OverlayConfigIterationRule implements TestRule { when(a.getTargetSdkVersion()).thenReturn(info.targetSdkVersion); when(a.isOverlayIsStatic()).thenReturn(info.isStatic); when(a.getOverlayPriority()).thenReturn(info.priority); - when(a.getBaseCodePath()).thenReturn(info.path.getPath()); + when(a.getBaseApkPath()).thenReturn(info.path.getPath()); f.accept(a, !info.path.getPath().contains("data/overlay")); } return null; diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryInputSuspendTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryInputSuspendTest.java new file mode 100644 index 000000000000..e870d6022058 --- /dev/null +++ b/core/tests/coretests/src/com/android/internal/os/BatteryInputSuspendTest.java @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2020 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.os; + +import static org.junit.Assert.assertTrue; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.os.BatteryManager; +import android.os.Build; +import android.os.ConditionVariable; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.runner.AndroidJUnit4; + +import com.android.compatibility.common.util.SystemUtil; + +import com.google.android.collect.Sets; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.Set; + +@RunWith(AndroidJUnit4.class) +public class BatteryInputSuspendTest { + + public static final Set<String> SUPPORTED_DEVICES = Sets.newArraySet( + "blueline", + "crosshatch", + "coral" + ); + + private ChargerStateMonitor mChargerStateMonitor; + + @Before + public void verifyCharging() { + if (!SUPPORTED_DEVICES.contains(Build.DEVICE)) { + return; + } + + mChargerStateMonitor = new ChargerStateMonitor(); + + assertTrue("Device must be connected to USB", mChargerStateMonitor.isCharging()); + } + + @Test + public void testSuspendInput() { + if (!SUPPORTED_DEVICES.contains(Build.DEVICE)) { + return; + } + + SystemUtil.runShellCommand("dumpsys battery suspend_input"); + + mChargerStateMonitor.waitForChargerState(/* isPluggedIn */false); + } + + @After + public void reenableCharging() { + if (!SUPPORTED_DEVICES.contains(Build.DEVICE)) { + return; + } + + mChargerStateMonitor.reset(); + + SystemUtil.runShellCommand("dumpsys battery reset"); + + mChargerStateMonitor.waitForChargerState(/* isPluggedIn */true); + } + + private static class ChargerStateMonitor { + private final Intent mBatteryMonitor; + private final ConditionVariable mReady = new ConditionVariable(); + private boolean mExpectedChargingState; + + ChargerStateMonitor() { + Context context = InstrumentationRegistry.getInstrumentation().getContext(); + mBatteryMonitor = context.registerReceiver(new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (isCharging(intent) == mExpectedChargingState) { + mReady.open(); + } + } + }, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); + } + + public boolean isCharging() { + return isCharging(mBatteryMonitor); + } + + private boolean isCharging(Intent batteryMonitor) { + return batteryMonitor.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1) != 0; + } + + void waitForChargerState(boolean isPluggedIn) { + mExpectedChargingState = isPluggedIn; + + boolean charging = isCharging(); + if (charging == mExpectedChargingState) { + return; + } + + boolean success = mReady.block(100000); + assertTrue("Timed out waiting for charging state to change", success); + } + + void reset() { + mReady.close(); + } + } +} diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsSamplingTimerTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsSamplingTimerTest.java index 61d20dfb32d9..3b27f1897bd2 100644 --- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsSamplingTimerTest.java +++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsSamplingTimerTest.java @@ -18,6 +18,7 @@ package com.android.internal.os; import android.os.BatteryStats; import android.os.Parcel; +import android.os.SystemClock; import androidx.test.filters.SmallTest; @@ -36,9 +37,9 @@ public class BatteryStatsSamplingTimerTest extends TestCase { timer.onTimeStarted(100, 100, 100); // First update is absorbed. - timer.update(10, 1); + timer.update(10, 1, SystemClock.elapsedRealtime() * 1000); - timer.update(20, 2); + timer.update(20, 2, SystemClock.elapsedRealtime() * 1000); assertEquals(1, timer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); assertEquals(10, timer.getTotalTimeLocked(200, BatteryStats.STATS_SINCE_CHARGED)); @@ -62,7 +63,7 @@ public class BatteryStatsSamplingTimerTest extends TestCase { timeBase); // First once is absorbed. - timer.update(10, 1); + timer.update(10, 1, SystemClock.elapsedRealtime() * 1000); timer.add(10, 1); @@ -71,7 +72,7 @@ public class BatteryStatsSamplingTimerTest extends TestCase { // This is less than we currently have, so we will end the sample. Time isn't running, so // nothing should happen. - timer.update(0, 0); + timer.update(0, 0, SystemClock.elapsedRealtime() * 1000); assertEquals(0, timer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); assertEquals(0, timer.getTotalTimeLocked(200, BatteryStats.STATS_SINCE_CHARGED)); @@ -86,7 +87,7 @@ public class BatteryStatsSamplingTimerTest extends TestCase { // This is less than we currently have, so we should end our sample and continue with the // entire amount updated here. - timer.update(50, 5); + timer.update(50, 5, SystemClock.elapsedRealtime() * 1000); assertEquals(150, timer.getTotalTimeLocked(200, BatteryStats.STATS_SINCE_CHARGED)); assertEquals(15, timer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); @@ -106,7 +107,7 @@ public class BatteryStatsSamplingTimerTest extends TestCase { // This should be absorbed because it is our first update and we don't know what // was being counted before. - timer.update(10, 1); + timer.update(10, 1, SystemClock.elapsedRealtime() * 1000); assertEquals(0, timer.getTotalTimeLocked(10, BatteryStats.STATS_SINCE_CHARGED)); assertEquals(0, timer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); @@ -115,7 +116,7 @@ public class BatteryStatsSamplingTimerTest extends TestCase { timer.onTimeStarted(100, 100, 100); // This should be absorbed. - timer.update(10, 1); + timer.update(10, 1, SystemClock.elapsedRealtime() * 1000); assertEquals(0, timer.getTotalTimeLocked(100, BatteryStats.STATS_SINCE_CHARGED)); assertEquals(0, timer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); @@ -206,13 +207,13 @@ public class BatteryStatsSamplingTimerTest extends TestCase { // Now, just like with a fresh timer, the first update should be absorbed to account for // data being collected when we weren't recording. - unparceledOnBatteryTimer.update(10, 10); + unparceledOnBatteryTimer.update(10, 10, SystemClock.elapsedRealtime() * 1000); assertEquals(10, unparceledOnBatteryTimer.getTotalTimeLocked(0, BatteryStats.STATS_SINCE_CHARGED)); assertEquals(1, unparceledOnBatteryTimer.getCountLocked(BatteryStats.STATS_SINCE_CHARGED)); - unparceledOffBatteryTimer.update(10, 10); + unparceledOffBatteryTimer.update(10, 10, SystemClock.elapsedRealtime() * 1000); assertEquals(10, unparceledOffBatteryTimer.getTotalTimeLocked(0, BatteryStats.STATS_SINCE_CHARGED)); 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 df549c5b51c8..80e066c1e794 100644 --- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsServTest.java +++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsServTest.java @@ -36,22 +36,22 @@ public class BatteryStatsServTest extends TestCase { } void populate() { - mStartTime = 1010; - mRunningSince = 2021; + mStartTimeMs = 1010; + mRunningSinceMs = 2021; mRunning = true; mStarts = 4042; - mLaunchedTime = 5053; - mLaunchedSince = 6064; + mLaunchedTimeMs = 5053; + mLaunchedSinceMs = 6064; mLaunched = true; mLaunches = 8085; } long getStartTime() { - return mStartTime; + return mStartTimeMs; } long getRunningSince() { - return mRunningSince; + return mRunningSinceMs; } void setRunning(boolean val) { @@ -67,11 +67,11 @@ public class BatteryStatsServTest extends TestCase { } long getLaunchedTime() { - return mLaunchedTime; + return mLaunchedTimeMs; } long getLaunchedSince() { - return mLaunchedSince; + return mLaunchedSinceMs; } void setLaunched(boolean val) { @@ -173,7 +173,12 @@ public class BatteryStatsServTest extends TestCase { MockBatteryStatsImpl bsi = new MockBatteryStatsImpl() { @Override public long getBatteryUptimeLocked() { - return 777777L; + return 777777L * 1000; // microseconds + } + + @Override + public long getBatteryUptimeLocked(long uptimeMs) { + return 777777L * 1000; // microseconds } }; @@ -202,7 +207,12 @@ public class BatteryStatsServTest extends TestCase { MockBatteryStatsImpl bsi = new MockBatteryStatsImpl() { @Override public long getBatteryUptimeLocked() { - return 777777L; + return 777777L * 1000; // microseconds + } + + @Override + public long getBatteryUptimeLocked(long uptimeMs) { + return 777777L * 1000; // microseconds } }; @@ -229,7 +239,12 @@ public class BatteryStatsServTest extends TestCase { MockBatteryStatsImpl bsi = new MockBatteryStatsImpl() { @Override public long getBatteryUptimeLocked() { - return 777777L; + return 777777L * 1000; // microseconds + } + + @Override + public long getBatteryUptimeLocked(long uptimeMs) { + return 777777L * 1000; // microseconds } }; TestServ serv = new TestServ(bsi); @@ -259,7 +274,12 @@ public class BatteryStatsServTest extends TestCase { MockBatteryStatsImpl bsi = new MockBatteryStatsImpl() { @Override public long getBatteryUptimeLocked() { - return 777777L; + return 777777L * 1000; // microseconds + } + + @Override + public long getBatteryUptimeLocked(long uptimeMs) { + return 777777L * 1000; // microseconds } }; TestServ serv = new TestServ(bsi); @@ -316,7 +336,12 @@ public class BatteryStatsServTest extends TestCase { MockBatteryStatsImpl bsi = new MockBatteryStatsImpl() { @Override public long getBatteryUptimeLocked() { - return 777777L; + return 777777L * 1000; // microseconds + } + + @Override + public long getBatteryUptimeLocked(long uptimeMs) { + return 777777L * 1000; // microseconds } }; TestServ serv = new TestServ(bsi); @@ -345,7 +370,12 @@ public class BatteryStatsServTest extends TestCase { MockBatteryStatsImpl bsi = new MockBatteryStatsImpl() { @Override public long getBatteryUptimeLocked() { - return 777777L; + return 777777L * 1000; // microseconds + } + + @Override + public long getBatteryUptimeLocked(long uptimeMs) { + return 777777L * 1000; // microseconds } }; TestServ serv = new TestServ(bsi); @@ -374,7 +404,12 @@ public class BatteryStatsServTest extends TestCase { MockBatteryStatsImpl bsi = new MockBatteryStatsImpl() { @Override public long getBatteryUptimeLocked() { - return 777777L; + return 777777L * 1000; // microseconds + } + + @Override + public long getBatteryUptimeLocked(long uptimeMs) { + return 777777L * 1000; // microseconds } }; TestServ serv = new TestServ(bsi); 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 e5441c018875..f016e75a45b1 100644 --- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsTimeBaseTest.java +++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsTimeBaseTest.java @@ -41,29 +41,29 @@ public class BatteryStatsTimeBaseTest extends TestCase { public void populate(long uptime, long realtime, boolean running, long pastUptime, long uptimeStart, long pastRealtime, long realtimeStart, long unpluggedUptime, long unpluggedRealtime) { - mUptime = uptime; - mRealtime = realtime; + mUptimeUs = uptime; + mRealtimeUs = realtime; mRunning = running; - mPastUptime = pastUptime; - mUptimeStart = uptimeStart; - mPastRealtime = pastRealtime; - mRealtimeStart = realtimeStart; - mUnpluggedUptime = unpluggedUptime; - mUnpluggedRealtime = unpluggedRealtime; + mPastUptimeUs = pastUptime; + mUptimeStartUs = uptimeStart; + mPastRealtimeUs = pastRealtime; + mRealtimeStartUs = realtimeStart; + mUnpluggedUptimeUs = unpluggedUptime; + mUnpluggedRealtimeUs = unpluggedRealtime; } public void verify(long uptime, long realtime, boolean running, long pastUptime, long uptimeStart, long pastRealtime, long realtimeStart, long unpluggedUptime, long unpluggedRealtime) { - Assert.assertEquals(uptime, mUptime); - Assert.assertEquals(realtime, mRealtime); + Assert.assertEquals(uptime, mUptimeUs); + Assert.assertEquals(realtime, mRealtimeUs); Assert.assertEquals(running, mRunning); - Assert.assertEquals(pastUptime, mPastUptime); - Assert.assertEquals(uptimeStart, mUptimeStart); - Assert.assertEquals(pastRealtime, mPastRealtime); - Assert.assertEquals(realtimeStart, mRealtimeStart); - Assert.assertEquals(unpluggedUptime, mUnpluggedUptime); - Assert.assertEquals(unpluggedRealtime, mUnpluggedRealtime); + Assert.assertEquals(pastUptime, mPastUptimeUs); + Assert.assertEquals(uptimeStart, mUptimeStartUs); + Assert.assertEquals(pastRealtime, mPastRealtimeUs); + Assert.assertEquals(realtimeStart, mRealtimeStartUs); + Assert.assertEquals(unpluggedUptime, mUnpluggedUptimeUs); + Assert.assertEquals(unpluggedRealtime, mUnpluggedRealtimeUs); } } 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 40e3a5f55ca5..11a01b3a42dc 100644 --- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsTimerTest.java +++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsTimerTest.java @@ -49,7 +49,8 @@ public class BatteryStatsTimerTest extends TestCase { super(clocks, type, timeBase); } - protected long computeRunTimeLocked(long curBatteryRealtime) { + @Override + protected long computeRunTimeLocked(long curBatteryRealtime, long elapsedRealtimeUs) { lastComputeRunTimeRealtime = curBatteryRealtime; return nextComputeRunTime; } @@ -67,19 +68,19 @@ public class BatteryStatsTimerTest extends TestCase { } public long getTotalTime() { - return mTotalTime; + return mTotalTimeUs; } public void setTotalTime(long val) { - mTotalTime = val; + mTotalTimeUs = val; } public long getTimeBeforeMark() { - return mTimeBeforeMark; + return mTimeBeforeMarkUs; } public void setTimeBeforeMark(long val) { - mTimeBeforeMark = val; + mTimeBeforeMarkUs = val; } } diff --git a/core/tests/coretests/src/com/android/internal/util/HexDumpTest.java b/core/tests/coretests/src/com/android/internal/util/HexDumpTest.java index 359bd5e93dae..f1cd89bf49f4 100644 --- a/core/tests/coretests/src/com/android/internal/util/HexDumpTest.java +++ b/core/tests/coretests/src/com/android/internal/util/HexDumpTest.java @@ -16,8 +16,16 @@ package com.android.internal.util; +import static com.android.internal.util.HexDump.hexStringToByteArray; +import static com.android.internal.util.HexDump.toHexString; + import junit.framework.TestCase; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.Arrays; +import java.util.Random; + public final class HexDumpTest extends TestCase { public void testBytesToHexString() { assertEquals("abcdef", HexDump.toHexString( @@ -25,7 +33,143 @@ public final class HexDumpTest extends TestCase { assertEquals("ABCDEF", HexDump.toHexString( new byte[] { (byte) 0xab, (byte) 0xcd, (byte) 0xef }, true)); } - public void testNullArray() { - assertEquals("(null)", HexDump.toHexString(null)); + + public void testNullByteArray() { + assertThrows( + NullPointerException.class, + () -> HexDump.toHexString(null)); + } + + public void testBytesToHexString_allByteValues() { + byte[] bytes = new byte[256]; + for (int i = 0; i < bytes.length; i++) { + bytes[i] = (byte) (i % 256); + } + + StringBuilder sb = new StringBuilder(); + for (char firstChar : "0123456789ABCDEF".toCharArray()) { + for (char secondChar : "0123456789ABCDEF".toCharArray()) { + sb.append(firstChar).append(secondChar); + } + } + String expected = sb.toString(); + + assertEquals(expected, HexDump.toHexString(bytes)); + } + + public void testRoundTrip_fromBytes() { + Random deterministicRandom = new Random(31337); // arbitrary but deterministic + for (int length = 0; length < 100; length++) { + byte[] bytes = new byte[length]; + deterministicRandom.nextBytes(bytes); + byte[] reconstruction = hexStringToByteArray(toHexString(bytes)); + + assertBytesEqual(bytes, reconstruction); + } + } + + public void testRoundTrip_fromString() { + String hexString = "0123456789ABCDEF72f9a3438934c378d34f32a8b932"; + for (int length = 0; length < hexString.length(); length += 2) { + String original = hexString.substring(0, length); + String reconstruction = toHexString(hexStringToByteArray(original)); + assertEquals(original.toUpperCase(), reconstruction); + } + } + + public void testToHexString_offsetLength() { + byte[] bytes = new byte[32]; + for (int i = 0; i < 16; i++) { + bytes[i] = (byte) i; + bytes[16 + i] = (byte) (16 * i); + } + String expected = "000102030405060708090A0B0C0D0E0F00102030405060708090A0B0C0D0E0F0"; + for (int offset = 0; offset < bytes.length; offset++) { + for (int len = 0; len < (bytes.length - offset); len++) { + + byte[] subBytes = new byte[len]; + System.arraycopy(bytes, offset, subBytes, 0, len); + + String actual = toHexString(bytes, offset, len); + assertEquals(expected.substring(2 * offset, 2 * offset + 2 * len), actual); + assertEquals(toHexString(subBytes), actual); + } + } + } + + public void testToHexString_case() { + byte[] bytes = new byte[32]; + for (int i = 0; i < 16; i++) { + bytes[i] = (byte) i; + bytes[16 + i] = (byte) (16 * i); + } + + String expected = "000102030405060708090A0B0C0D0E0F00102030405060708090A0B0C0D0E0F0"; + + assertEquals(expected.toUpperCase(), toHexString(bytes, true)); + assertEquals(expected.toLowerCase(), toHexString(bytes, false)); + + // default is uppercase + assertEquals(expected.toUpperCase(), toHexString(bytes)); + } + + public void testHexStringToByteArray_empty() { + assertBytesEqual(new byte[0], HexDump.hexStringToByteArray("")); + } + + public void testHexStringToByteArray_null() { + assertThrows( + NullPointerException.class, + () -> HexDump.hexStringToByteArray((String) null)); + } + + public void testHexStringToByteArray_invalidCharacters() { + // IllegalArgumentException would probably have been better than RuntimeException, but it + // might be too late to change now. + assertThrows( + RuntimeException.class, + () -> HexDump.hexStringToByteArray("GG")); + assertThrows( + RuntimeException.class, + () -> HexDump.hexStringToByteArray("\0\0")); + assertThrows( + RuntimeException.class, + () -> HexDump.hexStringToByteArray("abcdefgh")); + } + + public void testHexStringToByteArray_oddLength() { + // IllegalArgumentException would probably have been better than + // StringIndexOutOfBoundsException, but it might be too late to change now. + assertThrows( + StringIndexOutOfBoundsException.class, + () -> HexDump.hexStringToByteArray("A")); + assertThrows( + StringIndexOutOfBoundsException.class, + () -> HexDump.hexStringToByteArray("123")); + assertThrows( + StringIndexOutOfBoundsException.class, + () -> HexDump.hexStringToByteArray("ABCDE")); } + + private static void assertBytesEqual(byte[] expected, byte[] actual) { + if (!Arrays.equals(expected, actual)) { + fail("Expected " + Arrays.toString(expected) + ", got " + Arrays.toString(actual)); + } + } + + private static void assertThrows(Class<? extends RuntimeException> clazz, Runnable runnable) { + try { + runnable.run(); + fail(); + } catch (RuntimeException expected) { + assertEquals(toStrackTrace(expected), clazz, expected.getClass()); + } + } + + private static String toStrackTrace(Throwable throwable) { + StringWriter stringWriter = new StringWriter(); + throwable.printStackTrace(new PrintWriter(stringWriter)); + return stringWriter.toString(); + } + } diff --git a/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java b/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java index 1cdc75aa1f40..9d95de7eb60f 100644 --- a/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java +++ b/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java @@ -23,6 +23,8 @@ import static android.app.servertransaction.ActivityLifecycleItem.ON_RESUME; import static android.app.servertransaction.ActivityLifecycleItem.ON_START; import static android.app.servertransaction.ActivityLifecycleItem.ON_STOP; +import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; + import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; @@ -30,7 +32,11 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.after; +import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.timeout; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.Activity; @@ -50,6 +56,7 @@ import android.os.Binder; import android.os.RemoteException; import android.os.UserHandle; import android.platform.test.annotations.Presubmit; +import android.testing.PollingCheck; import android.view.WindowManagerGlobal; import androidx.test.annotation.UiThreadTest; @@ -63,6 +70,8 @@ import org.mockito.Mockito; import org.mockito.MockitoSession; import org.mockito.quality.Strictness; +import java.util.concurrent.TimeUnit; + /** * Test for verifying {@link android.app.ActivityThread} class. * @@ -76,6 +85,7 @@ import org.mockito.quality.Strictness; @MediumTest @Presubmit public class ActivityThreadClientTest { + private static final long WAIT_TIMEOUT_MS = TimeUnit.SECONDS.toMillis(5); @Test @UiThreadTest @@ -152,6 +162,63 @@ public class ActivityThreadClientTest { } } + @Test + public void testLifecycleOfRelaunch() throws Exception { + try (ClientMockSession clientSession = new ClientMockSession()) { + ActivityThread activityThread = clientSession.mockThread(); + ActivityClientRecord r = clientSession.stubActivityRecord(); + final TestActivity[] activity = new TestActivity[1]; + + // Verify for ON_CREATE state. Activity should not be relaunched. + getInstrumentation().runOnMainSync(() -> { + activity[0] = (TestActivity) clientSession.launchActivity(r); + }); + recreateAndVerifyNoRelaunch(activityThread, activity[0]); + + // Verify for ON_START state. Activity should be relaunched. + getInstrumentation().runOnMainSync(() -> clientSession.startActivity(r)); + recreateAndVerifyRelaunched(activityThread, activity[0], r, ON_START); + + // Verify for ON_RESUME state. Activity should be relaunched. + getInstrumentation().runOnMainSync(() -> clientSession.resumeActivity(r)); + recreateAndVerifyRelaunched(activityThread, activity[0], r, ON_RESUME); + + // Verify for ON_PAUSE state. Activity should be relaunched. + getInstrumentation().runOnMainSync(() -> clientSession.pauseActivity(r)); + recreateAndVerifyRelaunched(activityThread, activity[0], r, ON_PAUSE); + + // Verify for ON_STOP state. Activity should be relaunched. + getInstrumentation().runOnMainSync(() -> clientSession.stopActivity(r)); + recreateAndVerifyRelaunched(activityThread, activity[0], r, ON_STOP); + + // Verify for ON_DESTROY state. Activity should not be relaunched. + getInstrumentation().runOnMainSync(() -> clientSession.destroyActivity(r)); + recreateAndVerifyNoRelaunch(activityThread, activity[0]); + } + } + + private void recreateAndVerifyNoRelaunch(ActivityThread activityThread, TestActivity activity) { + clearInvocations(activityThread); + getInstrumentation().runOnMainSync(() -> activity.recreate()); + + verify(activityThread, after(WAIT_TIMEOUT_MS).never()) + .handleRelaunchActivity(any(), any()); + } + + private void recreateAndVerifyRelaunched(ActivityThread activityThread, TestActivity activity, + ActivityClientRecord r, int expectedState) throws Exception { + clearInvocations(activityThread); + getInstrumentation().runOnMainSync(() -> activity.recreate()); + + verify(activityThread, timeout(WAIT_TIMEOUT_MS)).handleRelaunchActivity(any(), any()); + + // Wait for the relaunch to complete. + PollingCheck.check("Waiting for the expected state " + expectedState + " timeout", + WAIT_TIMEOUT_MS, + () -> expectedState == r.getLifecycleState()); + assertEquals(expectedState, r.getLifecycleState()); + } + private class ClientMockSession implements AutoCloseable { private MockitoSession mMockSession; private ActivityThread mThread; @@ -200,6 +267,11 @@ public class ActivityThreadClientTest { false /* getNonConfigInstance */, "test"); } + private ActivityThread mockThread() { + spyOn(mThread); + return mThread; + } + private ActivityClientRecord stubActivityRecord() { ComponentName component = new ComponentName( InstrumentationRegistry.getInstrumentation().getContext(), TestActivity.class); diff --git a/core/tests/powertests/PowerStatsLoadTests/Android.bp b/core/tests/powertests/PowerStatsLoadTests/Android.bp new file mode 100644 index 000000000000..66c91adc6540 --- /dev/null +++ b/core/tests/powertests/PowerStatsLoadTests/Android.bp @@ -0,0 +1,13 @@ +android_test { + name: "PowerStatsLoadTests", + srcs: ["src/**/*.java"], + static_libs: [ + "androidx.test.rules", + "androidx.test.ext.junit", + "compatibility-device-util-axt", + "junit", + ], + libs: ["android.test.runner"], + platform_apis: true, + certificate: "platform", +} diff --git a/core/tests/powertests/PowerStatsLoadTests/AndroidManifest.xml b/core/tests/powertests/PowerStatsLoadTests/AndroidManifest.xml new file mode 100644 index 000000000000..b1c2a639aff4 --- /dev/null +++ b/core/tests/powertests/PowerStatsLoadTests/AndroidManifest.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2020 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. + --> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.frameworks.core.powerstatsloadtests"> + + <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> + <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> + <uses-permission android:name="android.permission.BATTERY_STATS"/> + <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/> + <uses-permission android:name="android.permission.INTERNET"/> + + <instrumentation + android:name="androidx.test.runner.AndroidJUnitRunner" + android:targetPackage="com.android.frameworks.core.powerstatsloadtests" + android:label="Power Stats Load Tests" /> + + <queries> + <!-- The load test resolves http://... intents. Let it do so. --> + <package android:name="com.android.chrome"/> + </queries> +</manifest> diff --git a/core/tests/powertests/PowerStatsLoadTests/src/com/android/frameworks/core/powerstatsloadtests/ConnectivitySetupRule.java b/core/tests/powertests/PowerStatsLoadTests/src/com/android/frameworks/core/powerstatsloadtests/ConnectivitySetupRule.java new file mode 100644 index 000000000000..ca2942647f08 --- /dev/null +++ b/core/tests/powertests/PowerStatsLoadTests/src/com/android/frameworks/core/powerstatsloadtests/ConnectivitySetupRule.java @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2020 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.frameworks.core.powerstatsloadtests; + +import static org.junit.Assert.assertEquals; + +import android.app.Instrumentation; +import android.content.Context; +import android.net.ConnectivityManager; +import android.net.LinkProperties; +import android.net.Network; +import android.net.NetworkCapabilities; +import android.net.NetworkRequest; +import android.net.wifi.WifiManager; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; + +import androidx.test.platform.app.InstrumentationRegistry; + +import com.android.compatibility.common.util.SystemUtil; + +import org.junit.rules.TestRule; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +public class ConnectivitySetupRule implements TestRule { + + private final boolean mWifiEnabled; + private final ConnectivityManager mConnectivityManager; + private final WifiManager mWifiManager; + private boolean mInitialWifiState; + + public ConnectivitySetupRule(boolean wifiEnabled) { + mWifiEnabled = wifiEnabled; + + Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); + Context context = instrumentation.getContext(); + mConnectivityManager = context.getSystemService(ConnectivityManager.class); + mWifiManager = context.getSystemService(WifiManager.class); + } + + @Override + public Statement apply(Statement base, Description description) { + return new Statement() { + @Override + public void evaluate() throws Throwable { + try { + mInitialWifiState = isWiFiConnected(); + setWiFiState(mWifiEnabled); + base.evaluate(); + } finally { + setWiFiState(mInitialWifiState); + } + } + }; + } + + private void setWiFiState(final boolean enable) throws InterruptedException { + boolean wiFiConnected = isWiFiConnected(); + if (enable == wiFiConnected) { + return; + } + + NetworkTracker tracker = new NetworkTracker(!mWifiEnabled); + mConnectivityManager.registerNetworkCallback( + new NetworkRequest.Builder() + .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED).build(), + tracker); + + if (enable) { + SystemUtil.runShellCommand("svc wifi enable"); + //noinspection deprecation + SystemUtil.runWithShellPermissionIdentity(mWifiManager::reconnect, + android.Manifest.permission.NETWORK_SETTINGS); + } else { + SystemUtil.runShellCommand("svc wifi disable"); + } + + tracker.waitForExpectedState(); + + assertEquals("Wifi must be " + (enable ? "connected to" : "disconnected from") + + " an access point for this test.", enable, isWiFiConnected()); + + mConnectivityManager.unregisterNetworkCallback(tracker); + } + + private boolean isWiFiConnected() { + return mWifiManager.isWifiEnabled() && mConnectivityManager.getActiveNetwork() != null + && !mConnectivityManager.isActiveNetworkMetered(); + } + + private class NetworkTracker extends ConnectivityManager.NetworkCallback { + private static final int MSG_CHECK_ACTIVE_NETWORK = 1; + + private final CountDownLatch mReceiveLatch = new CountDownLatch(1); + + private final boolean mExpectedMetered; + + private final Handler mHandler = new Handler(Looper.getMainLooper()) { + @Override + public void handleMessage(Message msg) { + if (msg.what == MSG_CHECK_ACTIVE_NETWORK) { + checkActiveNetwork(); + } + } + }; + + private NetworkTracker(boolean expectedMetered) { + mExpectedMetered = expectedMetered; + } + + @Override + public void onAvailable(Network network, NetworkCapabilities networkCapabilities, + LinkProperties linkProperties, boolean blocked) { + checkActiveNetwork(); + } + + @Override + public void onLost(Network network) { + checkActiveNetwork(); + } + + boolean waitForExpectedState() throws InterruptedException { + checkActiveNetwork(); + return mReceiveLatch.await(60, TimeUnit.SECONDS); + } + + private void checkActiveNetwork() { + if (mReceiveLatch.getCount() == 0) { + return; + } + + if (mConnectivityManager.getActiveNetwork() != null + && mConnectivityManager.isActiveNetworkMetered() == mExpectedMetered) { + mReceiveLatch.countDown(); + } else { + mHandler.sendEmptyMessageDelayed(MSG_CHECK_ACTIVE_NETWORK, 5000); + } + } + } +} diff --git a/core/tests/powertests/PowerStatsLoadTests/src/com/android/frameworks/core/powerstatsloadtests/PowerMetrics.java b/core/tests/powertests/PowerStatsLoadTests/src/com/android/frameworks/core/powerstatsloadtests/PowerMetrics.java new file mode 100644 index 000000000000..88cb719add60 --- /dev/null +++ b/core/tests/powertests/PowerStatsLoadTests/src/com/android/frameworks/core/powerstatsloadtests/PowerMetrics.java @@ -0,0 +1,278 @@ +/* + * Copyright (C) 2020 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.frameworks.core.powerstatsloadtests; + +import android.os.Process; + +import com.android.internal.os.BatterySipper; +import com.android.internal.os.BatteryStatsHelper; + +import java.util.ArrayList; +import java.util.List; + +public class PowerMetrics { + private static final String PACKAGE_CALENDAR_PROVIDER = "com.android.providers.calendar"; + private static final String PACKAGE_MEDIA_PROVIDER = "com.android.providers.media"; + private static final String PACKAGE_SYSTEMUI = "com.android.systemui"; + private static final String[] PACKAGES_SYSTEM = {PACKAGE_MEDIA_PROVIDER, + PACKAGE_CALENDAR_PROVIDER, PACKAGE_SYSTEMUI}; + + enum MetricKind { + POWER, + DURATION, + } + + public static final String METRIC_APP_POWER = "appPower"; + public static final String METRIC_APP_POWER_EXCLUDE_SYSTEM_FROM_TOTAL = "appPowerExcludeSystem"; + public static final String METRIC_APP_POWER_EXCLUDE_SMEARED = "appPowerExcludeSmeared"; + public static final String METRIC_SCREEN_POWER = "screenPower"; + public static final String METRIC_WIFI_POWER = "wifiPower"; + public static final String METRIC_SYSTEM_SERVICE_CPU_POWER = "systemService"; + public static final String METRIC_OTHER_POWER = "otherPower"; + public static final String METRIC_CPU_POWER = "cpuPower"; + public static final String METRIC_RAM_POWER = "ramPower"; + public static final String METRIC_WAKELOCK_POWER = "wakelockPower"; + public static final String METRIC_MOBILE_RADIO_POWER = "mobileRadioPower"; + public static final String METRIC_BLUETOOTH_POWER = "bluetoothPower"; + public static final String METRIC_GPS_POWER = "gpsPower"; + public static final String METRIC_CAMERA_POWER = "cameraPower"; + public static final String METRIC_FLASHLIGHT_POWER = "flashlightPower"; + public static final String METRIC_SENSORS_POWER = "sensorsPower"; + public static final String METRIC_AUDIO_POWER = "audioPower"; + public static final String METRIC_VIDEO_POWER = "videoPower"; + public static final String METRIC_CPU_TIME = "cpuTime"; + public static final String METRIC_CPU_FOREGROUND_TIME = "cpuForegroundTime"; + public static final String METRIC_WAKELOCK_TIME = "wakelockTime"; + public static final String METRIC_WIFI_RUNNING_TIME = "wifiRunningTime"; + public static final String METRIC_BLUETOOTH_RUNNING_TIME = "bluetoothRunningTime"; + public static final String METRIC_GPS_TIME = "gpsTime"; + public static final String METRIC_CAMERA_TIME = "cameraTime"; + public static final String METRIC_FLASHLIGHT_TIME = "flashlightTime"; + public static final String METRIC_AUDIO_TIME = "audioTime"; + public static final String METRIC_VIDEO_TIME = "videoTime"; + + public static class Metric { + public String metricType; + public MetricKind metricKind; + public String title; + public double value; + public double total; + } + + private final double mMinDrainedPower; + private final double mMaxDrainedPower; + + private List<Metric> mMetrics = new ArrayList<>(); + + public PowerMetrics(BatteryStatsHelper batteryStatsHelper, int uid) { + mMinDrainedPower = batteryStatsHelper.getMinDrainedPower(); + mMaxDrainedPower = batteryStatsHelper.getMaxDrainedPower(); + + List<BatterySipper> usageList = batteryStatsHelper.getUsageList(); + + double totalPowerMah = 0; + double totalSmearedPowerMah = 0; + double totalPowerExcludeSystemMah = 0; + double totalScreenPower = 0; + double totalProportionalSmearMah = 0; + double totalCpuPowerMah = 0; + double totalSystemServiceCpuPowerMah = 0; + double totalUsagePowerMah = 0; + double totalWakeLockPowerMah = 0; + double totalMobileRadioPowerMah = 0; + double totalWifiPowerMah = 0; + double totalBluetoothPowerMah = 0; + double totalGpsPowerMah = 0; + double totalCameraPowerMah = 0; + double totalFlashlightPowerMah = 0; + double totalSensorPowerMah = 0; + double totalAudioPowerMah = 0; + double totalVideoPowerMah = 0; + + long totalCpuTimeMs = 0; + long totalCpuFgTimeMs = 0; + long totalWakeLockTimeMs = 0; + long totalWifiRunningTimeMs = 0; + long totalBluetoothRunningTimeMs = 0; + long totalGpsTimeMs = 0; + long totalCameraTimeMs = 0; + long totalFlashlightTimeMs = 0; + long totalAudioTimeMs = 0; + long totalVideoTimeMs = 0; + + BatterySipper uidSipper = null; + for (BatterySipper sipper : usageList) { + if (sipper.drainType == BatterySipper.DrainType.SCREEN) { + totalScreenPower = sipper.sumPower(); + } + + if (isHiddenDrainType(sipper.drainType)) { + continue; + } + + if (sipper.drainType == BatterySipper.DrainType.APP && sipper.getUid() == uid) { + uidSipper = sipper; + } + + totalPowerMah += sipper.sumPower(); + totalSmearedPowerMah += sipper.totalSmearedPowerMah; + totalProportionalSmearMah += sipper.proportionalSmearMah; + + if (!isSystemSipper(sipper)) { + totalPowerExcludeSystemMah += sipper.totalSmearedPowerMah; + } + + totalCpuPowerMah += sipper.cpuPowerMah; + totalSystemServiceCpuPowerMah += sipper.systemServiceCpuPowerMah; + totalUsagePowerMah += sipper.usagePowerMah; + totalWakeLockPowerMah += sipper.wakeLockPowerMah; + totalMobileRadioPowerMah += sipper.mobileRadioPowerMah; + totalWifiPowerMah += sipper.wifiPowerMah; + totalBluetoothPowerMah += sipper.bluetoothPowerMah; + totalGpsPowerMah += sipper.gpsPowerMah; + totalCameraPowerMah += sipper.cameraPowerMah; + totalFlashlightPowerMah += sipper.flashlightPowerMah; + totalSensorPowerMah += sipper.sensorPowerMah; + totalAudioPowerMah += sipper.audioPowerMah; + totalVideoPowerMah += sipper.videoPowerMah; + + totalCpuTimeMs += sipper.cpuTimeMs; + totalCpuFgTimeMs += sipper.cpuFgTimeMs; + totalWakeLockTimeMs += sipper.wakeLockTimeMs; + totalWifiRunningTimeMs += sipper.wifiRunningTimeMs; + totalBluetoothRunningTimeMs += sipper.bluetoothRunningTimeMs; + totalGpsTimeMs += sipper.gpsTimeMs; + totalCameraTimeMs += sipper.cameraTimeMs; + totalFlashlightTimeMs += sipper.flashlightTimeMs; + totalAudioTimeMs += sipper.audioTimeMs; + totalVideoTimeMs += sipper.videoTimeMs; + } + + if (uidSipper == null) { + return; + } + + addMetric(METRIC_APP_POWER, MetricKind.POWER, "Total power", + uidSipper.totalSmearedPowerMah, totalSmearedPowerMah); + addMetric(METRIC_APP_POWER_EXCLUDE_SYSTEM_FROM_TOTAL, MetricKind.POWER, + "Total power excluding system", + uidSipper.totalSmearedPowerMah, totalPowerExcludeSystemMah); + addMetric(METRIC_SCREEN_POWER, MetricKind.POWER, "Screen, smeared", + uidSipper.screenPowerMah, totalScreenPower); + addMetric(METRIC_OTHER_POWER, MetricKind.POWER, "Other, smeared", + uidSipper.proportionalSmearMah, totalProportionalSmearMah); + addMetric(METRIC_APP_POWER_EXCLUDE_SMEARED, MetricKind.POWER, "Excluding smeared", + uidSipper.totalPowerMah, totalPowerMah); + addMetric(METRIC_CPU_POWER, MetricKind.POWER, "CPU", + uidSipper.cpuPowerMah, totalCpuPowerMah); + addMetric(METRIC_SYSTEM_SERVICE_CPU_POWER, MetricKind.POWER, "System services", + uidSipper.systemServiceCpuPowerMah, totalSystemServiceCpuPowerMah); + addMetric(METRIC_RAM_POWER, MetricKind.POWER, "RAM", + uidSipper.usagePowerMah, totalUsagePowerMah); + addMetric(METRIC_WAKELOCK_POWER, MetricKind.POWER, "Wake lock", + uidSipper.wakeLockPowerMah, totalWakeLockPowerMah); + addMetric(METRIC_MOBILE_RADIO_POWER, MetricKind.POWER, "Mobile radio", + uidSipper.mobileRadioPowerMah, totalMobileRadioPowerMah); + addMetric(METRIC_WIFI_POWER, MetricKind.POWER, "WiFi", + uidSipper.wifiPowerMah, totalWifiPowerMah); + addMetric(METRIC_BLUETOOTH_POWER, MetricKind.POWER, "Bluetooth", + uidSipper.bluetoothPowerMah, totalBluetoothPowerMah); + addMetric(METRIC_GPS_POWER, MetricKind.POWER, "GPS", + uidSipper.gpsPowerMah, totalGpsPowerMah); + addMetric(METRIC_CAMERA_POWER, MetricKind.POWER, "Camera", + uidSipper.cameraPowerMah, totalCameraPowerMah); + addMetric(METRIC_FLASHLIGHT_POWER, MetricKind.POWER, "Flashlight", + uidSipper.flashlightPowerMah, totalFlashlightPowerMah); + addMetric(METRIC_SENSORS_POWER, MetricKind.POWER, "Sensors", + uidSipper.sensorPowerMah, totalSensorPowerMah); + addMetric(METRIC_AUDIO_POWER, MetricKind.POWER, "Audio", + uidSipper.audioPowerMah, totalAudioPowerMah); + addMetric(METRIC_VIDEO_POWER, MetricKind.POWER, "Video", + uidSipper.videoPowerMah, totalVideoPowerMah); + + addMetric(METRIC_CPU_TIME, MetricKind.DURATION, "CPU time", + uidSipper.cpuTimeMs, totalCpuTimeMs); + addMetric(METRIC_CPU_FOREGROUND_TIME, MetricKind.DURATION, "CPU foreground time", + uidSipper.cpuFgTimeMs, totalCpuFgTimeMs); + addMetric(METRIC_WAKELOCK_TIME, MetricKind.DURATION, "Wake lock time", + uidSipper.wakeLockTimeMs, totalWakeLockTimeMs); + addMetric(METRIC_WIFI_RUNNING_TIME, MetricKind.DURATION, "WiFi running time", + uidSipper.wifiRunningTimeMs, totalWifiRunningTimeMs); + addMetric(METRIC_BLUETOOTH_RUNNING_TIME, MetricKind.DURATION, "Bluetooth time", + uidSipper.bluetoothRunningTimeMs, totalBluetoothRunningTimeMs); + addMetric(METRIC_GPS_TIME, MetricKind.DURATION, "GPS time", + uidSipper.gpsTimeMs, totalGpsTimeMs); + addMetric(METRIC_CAMERA_TIME, MetricKind.DURATION, "Camera time", + uidSipper.cameraTimeMs, totalCameraTimeMs); + addMetric(METRIC_FLASHLIGHT_TIME, MetricKind.DURATION, "Flashlight time", + uidSipper.flashlightTimeMs, totalFlashlightTimeMs); + addMetric(METRIC_AUDIO_TIME, MetricKind.DURATION, "Audio time", + uidSipper.audioTimeMs, totalAudioTimeMs); + addMetric(METRIC_VIDEO_TIME, MetricKind.DURATION, "Video time", + uidSipper.videoTimeMs, totalVideoTimeMs); + } + + public List<Metric> getMetrics() { + return mMetrics; + } + + public double getMinDrainedPower() { + return mMinDrainedPower; + } + + public double getMaxDrainedPower() { + return mMaxDrainedPower; + } + + protected boolean isHiddenDrainType(BatterySipper.DrainType drainType) { + return drainType == BatterySipper.DrainType.IDLE + || drainType == BatterySipper.DrainType.CELL + || drainType == BatterySipper.DrainType.SCREEN + || drainType == BatterySipper.DrainType.UNACCOUNTED + || drainType == BatterySipper.DrainType.OVERCOUNTED + || drainType == BatterySipper.DrainType.BLUETOOTH + || drainType == BatterySipper.DrainType.WIFI; + } + + private boolean isSystemSipper(BatterySipper sipper) { + final int uid = sipper.uidObj == null ? -1 : sipper.getUid(); + if (uid >= Process.ROOT_UID && uid < Process.FIRST_APPLICATION_UID) { + return true; + } else if (sipper.mPackages != null) { + for (final String packageName : sipper.mPackages) { + for (final String systemPackage : PACKAGES_SYSTEM) { + if (systemPackage.equals(packageName)) { + return true; + } + } + } + } + + return false; + } + + private void addMetric(String metricType, MetricKind metricKind, String title, double amount, + double totalAmount) { + Metric metric = new Metric(); + metric.metricType = metricType; + metric.metricKind = metricKind; + metric.title = title; + metric.value = amount; + metric.total = totalAmount; + mMetrics.add(metric); + } +} diff --git a/core/tests/powertests/PowerStatsLoadTests/src/com/android/frameworks/core/powerstatsloadtests/PowerMetricsCollector.java b/core/tests/powertests/PowerStatsLoadTests/src/com/android/frameworks/core/powerstatsloadtests/PowerMetricsCollector.java new file mode 100644 index 000000000000..0cdb404f6aaa --- /dev/null +++ b/core/tests/powertests/PowerStatsLoadTests/src/com/android/frameworks/core/powerstatsloadtests/PowerMetricsCollector.java @@ -0,0 +1,281 @@ +/* + * Copyright (C) 2020 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.frameworks.core.powerstatsloadtests; + +import static org.junit.Assert.fail; + +import android.app.Instrumentation; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.os.BatteryManager; +import android.os.BatteryStats; +import android.os.Bundle; +import android.os.Process; +import android.os.SystemClock; +import android.os.UserManager; +import android.util.Log; +import android.util.TimeUtils; + +import androidx.test.platform.app.InstrumentationRegistry; + +import com.android.internal.os.BatteryStatsHelper; +import com.android.internal.os.LoggingPrintStream; + +import org.junit.rules.TestRule; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; + +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +public class PowerMetricsCollector implements TestRule { + private final String mTag; + private final float mBatteryDrainThresholdPct; + private final int mTimeoutMillis; + + private final Context mContext; + private final UserManager mUserManager; + private final int mUid; + private final BatteryStatsHelper mStatsHelper; + + private long mStartTime; + private volatile float mInitialBatteryLevel; + private volatile float mCurrentBatteryLevel; + private int mIterations; + private PowerMetrics mInitialPowerMetrics; + private PowerMetrics mFinalPowerMetrics; + private List<PowerMetrics.Metric> mPowerMetricsDelta; + + @Override + public Statement apply(Statement base, Description description) { + return new Statement() { + @Override + public void evaluate() throws Throwable { + disableCharger(); + try { + prepareBatteryLevelMonitor(); + mStartTime = SystemClock.uptimeMillis(); + base.evaluate(); + captureFinalPowerStatsData(); + } finally { + enableCharger(); + } + } + }; + } + + public PowerMetricsCollector(String tag, float batteryDrainThresholdPct, int timeoutMillis) { + mTag = tag; + mBatteryDrainThresholdPct = batteryDrainThresholdPct; + mTimeoutMillis = timeoutMillis; + + Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); + mContext = instrumentation.getContext(); + mUid = Process.myUid(); + mUserManager = mContext.getSystemService(UserManager.class); + mStatsHelper = new BatteryStatsHelper(mContext, false /* collectBatteryBroadcast */); + mStatsHelper.create((Bundle) null); + } + + private void disableCharger() { + // TODO(b/167636754): implement this method once the charger suspension API is available + } + + private void enableCharger() { + // TODO(b/167636754): implement this method once the charger suspension API is available + } + + private PowerMetrics readBatteryStatsData() { + mStatsHelper.clearStats(); + mStatsHelper.refreshStats(BatteryStats.STATS_SINCE_CHARGED, + mUserManager.getUserProfiles()); + return new PowerMetrics(mStatsHelper, mUid); + } + + protected void prepareBatteryLevelMonitor() { + Intent batteryStatus = mContext.registerReceiver(new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + handleBatteryStatus(intent); + } + }, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); + + handleBatteryStatus(batteryStatus); + mInitialBatteryLevel = mCurrentBatteryLevel; + } + + protected void handleBatteryStatus(Intent intent) { + if (intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1) != 0) { + fail("Device must remain disconnected from the power source " + + "for the duration of the test"); + } + + int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1); + int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1); + + mCurrentBatteryLevel = level * 100 / (float) scale; + Log.i(mTag, "Battery level = " + mCurrentBatteryLevel); + + // We delay tracking until the battery level drops. If the resolution of + // battery level is 1%, and the initially reported level is 73, we don't know whether + // it's 73.1 or 73.7. Once it drops to 72, we can be confident that the real battery + // level it is very close to 72.0 and can start tracking. + if (mInitialPowerMetrics == null && mCurrentBatteryLevel < mInitialBatteryLevel) { + mInitialBatteryLevel = mCurrentBatteryLevel; + mInitialPowerMetrics = readBatteryStatsData(); + } + } + + private void captureFinalPowerStatsData() { + if (mFinalPowerMetrics != null) { + return; + } + + mFinalPowerMetrics = readBatteryStatsData(); + + mPowerMetricsDelta = new ArrayList<>(); + List<PowerMetrics.Metric> initialPowerMetrics = mInitialPowerMetrics.getMetrics(); + List<PowerMetrics.Metric> finalPowerMetrics = mFinalPowerMetrics.getMetrics(); + for (PowerMetrics.Metric initialMetric : initialPowerMetrics) { + PowerMetrics.Metric finalMetric = null; + for (PowerMetrics.Metric metric : finalPowerMetrics) { + if (metric.title.equals(initialMetric.title)) { + finalMetric = metric; + break; + } + } + + if (finalMetric != null) { + PowerMetrics.Metric delta = new PowerMetrics.Metric(); + delta.metricType = initialMetric.metricType; + delta.metricKind = initialMetric.metricKind; + delta.title = initialMetric.title; + delta.total = finalMetric.total - initialMetric.total; + delta.value = finalMetric.value - initialMetric.value; + mPowerMetricsDelta.add(delta); + } + } + } + + /** + * Returns false if sufficient data has been accumulated. + */ + public boolean checkpoint() { + long elapsedTime = SystemClock.uptimeMillis() - mStartTime; + if (elapsedTime >= mTimeoutMillis) { + Log.i(mTag, "Timeout reached " + TimeUtils.formatDuration(elapsedTime)); + captureFinalPowerStatsData(); + return false; + } + + if (mInitialPowerMetrics == null) { + return true; + } + + if (mInitialBatteryLevel - mCurrentBatteryLevel >= mBatteryDrainThresholdPct) { + Log.i(mTag, + "Battery drain reached " + (mInitialBatteryLevel - mCurrentBatteryLevel) + "%"); + captureFinalPowerStatsData(); + return false; + } + + mIterations++; + return true; + } + + + public int getIterationCount() { + return mIterations; + } + + public void dumpMetrics() { + dumpMetrics(new LoggingPrintStream() { + @Override + protected void log(String line) { + Log.i(mTag, line); + } + }); + } + + public void dumpMetrics(PrintStream out) { + List<PowerMetrics.Metric> initialPowerMetrics = mInitialPowerMetrics.getMetrics(); + List<PowerMetrics.Metric> finalPowerMetrics = mFinalPowerMetrics.getMetrics(); + + out.println("== Power metrics at test start"); + dumpPowerStatsData(out, initialPowerMetrics); + + out.println("== Power metrics at test end"); + dumpPowerStatsData(out, finalPowerMetrics); + + out.println("== Power metrics delta"); + dumpPowerStatsData(out, mPowerMetricsDelta); + } + + protected void dumpPowerStatsData(PrintStream out, List<PowerMetrics.Metric> metrics) { + Locale locale = Locale.getDefault(); + for (PowerMetrics.Metric metric : metrics) { + double proportion = metric.total != 0 ? metric.value * 100 / metric.total : 0; + switch (metric.metricKind) { + case POWER: + out.println( + String.format(locale, " %-30s %7.1f mAh %4.1f%%", metric.title, + metric.value, proportion)); + break; + case DURATION: + out.println( + String.format(locale, " %-30s %,7d ms %4.1f%%", metric.title, + (long) metric.value, proportion)); + break; + } + } + } + + public void dumpMetricAsPercentageOfDrainedPower(String metricType) { + double minDrainedPower = + mFinalPowerMetrics.getMinDrainedPower() - mInitialPowerMetrics.getMinDrainedPower(); + double maxDrainedPower = + mFinalPowerMetrics.getMaxDrainedPower() - mInitialPowerMetrics.getMaxDrainedPower(); + + PowerMetrics.Metric metric = getMetric(metricType); + double metricDelta = metric.value; + + if (maxDrainedPower - minDrainedPower < 0.1f) { + Log.i(mTag, String.format(Locale.getDefault(), + "%s power consumed by the test: %.1f of %.1f mAh (%.1f%%)", + metric.title, metricDelta, maxDrainedPower, + metricDelta / maxDrainedPower * 100)); + } else { + Log.i(mTag, String.format(Locale.getDefault(), + "%s power consumed by the test: %.1f of %.1f - %.1f mAh (%.1f%% - %.1f%%)", + metric.title, metricDelta, minDrainedPower, maxDrainedPower, + metricDelta / minDrainedPower * 100, metricDelta / maxDrainedPower * 100)); + } + } + + public PowerMetrics.Metric getMetric(String metricType) { + for (PowerMetrics.Metric metric : mPowerMetricsDelta) { + if (metric.metricType.equals(metricType)) { + return metric; + } + } + return null; + } +} diff --git a/core/tests/powertests/PowerStatsLoadTests/src/com/android/frameworks/core/powerstatsloadtests/SystemServiceCallLoadTest.java b/core/tests/powertests/PowerStatsLoadTests/src/com/android/frameworks/core/powerstatsloadtests/SystemServiceCallLoadTest.java new file mode 100644 index 000000000000..911ccba3ac78 --- /dev/null +++ b/core/tests/powertests/PowerStatsLoadTests/src/com/android/frameworks/core/powerstatsloadtests/SystemServiceCallLoadTest.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2020 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.frameworks.core.powerstatsloadtests; + +import static org.junit.Assert.assertNotNull; + +import android.app.Instrumentation; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.net.Uri; +import android.util.Log; + +import androidx.test.platform.app.InstrumentationRegistry; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; + +public class SystemServiceCallLoadTest { + private static final String TAG = "SystemServiceCallLoadTest"; + private static final int TIMEOUT_MILLIS = 60 * 60 * 1000; + private static final float BATTERY_DRAIN_THRESHOLD_PCT = 2.99f; + + @Rule + public PowerMetricsCollector mPowerMetricsCollector = new PowerMetricsCollector(TAG, + BATTERY_DRAIN_THRESHOLD_PCT, TIMEOUT_MILLIS); + + private PackageManager mPackageManager; + + @Before + public void setup() { + Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); + mPackageManager = instrumentation.getContext().getPackageManager(); + } + + @Test + public void test() { + while (mPowerMetricsCollector.checkpoint()) { + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.setDataAndType(Uri.parse("http://example.com/"), "text/plain"); + intent.addCategory(Intent.CATEGORY_BROWSABLE); + ResolveInfo resolveInfo = mPackageManager.resolveActivity(intent, 0); + assertNotNull(resolveInfo); + } + + mPowerMetricsCollector.dumpMetrics(); + + Log.i(TAG, "=="); + Log.i(TAG, "Total system server calls made " + mPowerMetricsCollector.getIterationCount()); + + mPowerMetricsCollector.dumpMetricAsPercentageOfDrainedPower( + PowerMetrics.METRIC_SYSTEM_SERVICE_CPU_POWER); + } +} diff --git a/core/tests/powertests/PowerStatsLoadTests/src/com/android/frameworks/core/powerstatsloadtests/WiFiLoadTest.java b/core/tests/powertests/PowerStatsLoadTests/src/com/android/frameworks/core/powerstatsloadtests/WiFiLoadTest.java new file mode 100644 index 000000000000..90627192946d --- /dev/null +++ b/core/tests/powertests/PowerStatsLoadTests/src/com/android/frameworks/core/powerstatsloadtests/WiFiLoadTest.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2020 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.frameworks.core.powerstatsloadtests; + +import android.util.Log; + +import org.junit.Rule; +import org.junit.Test; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; + +public class WiFiLoadTest { + private static final String TAG = "WiFiLoadTest"; + private static final String DOWNLOAD_TEST_URL = + "https://i.ytimg.com/vi/l5mE3Tpjejs/maxresdefault.jpg"; + + private static final int TIMEOUT_MILLIS = 60 * 60 * 1000; + private static final float BATTERY_DRAIN_THRESHOLD_PCT = 0.99f; + + @Rule + public PowerMetricsCollector mPowerMetricsCollector = new PowerMetricsCollector(TAG, + BATTERY_DRAIN_THRESHOLD_PCT, TIMEOUT_MILLIS); + + @Rule + public ConnectivitySetupRule mConnectivitySetupRule = + new ConnectivitySetupRule(/* WiFi enabled */true); + + @Test + public void test() throws IOException { + long totalBytesRead = 0; + URL url = new URL(DOWNLOAD_TEST_URL); + byte[] buffer = new byte[131072]; // Large buffer to minimize CPU usage + + while (mPowerMetricsCollector.checkpoint()) { + try (InputStream inputStream = url.openStream()) { + while (true) { + int count = inputStream.read(buffer); + if (count < 0) { + break; + } + totalBytesRead += count; + } + } + } + + mPowerMetricsCollector.dumpMetrics(); + + Log.i(TAG, "=="); + Log.i(TAG, "WiFi running time: " + (long) mPowerMetricsCollector.getMetric( + PowerMetrics.METRIC_WIFI_RUNNING_TIME).value); + Log.i(TAG, "Total bytes read over WiFi: " + totalBytesRead); + + mPowerMetricsCollector.dumpMetricAsPercentageOfDrainedPower( + PowerMetrics.METRIC_WIFI_POWER); + } +} diff --git a/data/etc/car/com.google.android.car.kitchensink.xml b/data/etc/car/com.google.android.car.kitchensink.xml index 7292e0796bf5..59aa45e1f6e4 100644 --- a/data/etc/car/com.google.android.car.kitchensink.xml +++ b/data/etc/car/com.google.android.car.kitchensink.xml @@ -40,6 +40,7 @@ <permission name="android.permission.REAL_GET_TASKS"/> <permission name="android.permission.READ_LOGS"/> <permission name="android.permission.REBOOT"/> + <permission name="android.permission.SEND_CATEGORY_CAR_NOTIFICATIONS"/> <!-- use for CarServiceTest --> <permission name="android.permission.SET_ACTIVITY_WATCHER"/> <permission name="android.permission.WRITE_SECURE_SETTINGS"/> diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json index a2a2216028ac..e69319896762 100644 --- a/data/etc/services.core.protolog.json +++ b/data/etc/services.core.protolog.json @@ -1393,6 +1393,12 @@ "group": "WM_SHOW_SURFACE_ALLOC", "at": "com\/android\/server\/wm\/BlackFrame.java" }, + "155482615": { + "message": "Focus requested for window=%s", + "level": "VERBOSE", + "group": "WM_DEBUG_FOCUS_LIGHT", + "at": "com\/android\/server\/wm\/InputMonitor.java" + }, "174572959": { "message": "DisplayArea info changed name=%s", "level": "VERBOSE", @@ -2635,6 +2641,12 @@ "group": "WM_DEBUG_REMOTE_ANIMATIONS", "at": "com\/android\/server\/wm\/WallpaperAnimationAdapter.java" }, + "2081291430": { + "message": "Focus not requested for window=%s because it has no surface", + "level": "DEBUG", + "group": "WM_DEBUG_FOCUS_LIGHT", + "at": "com\/android\/server\/wm\/InputMonitor.java" + }, "2083556954": { "message": "Set mOrientationChanging of %s", "level": "VERBOSE", diff --git a/framework-jarjar-rules.txt b/framework-jarjar-rules.txt index 70dedb8179b0..d8af726ffa72 100644 --- a/framework-jarjar-rules.txt +++ b/framework-jarjar-rules.txt @@ -1,6 +1,2 @@ rule android.hidl.** android.internal.hidl.@1 rule android.net.wifi.WifiAnnotations* android.internal.wifi.WifiAnnotations@1 - -# Hide media mainline module implementation classes to avoid collisions with -# app-bundled ExoPlayer classes. -rule com.google.android.exoplayer2.** android.media.internal.exo.@1 diff --git a/libs/WindowManager/Shell/Android.bp b/libs/WindowManager/Shell/Android.bp index 16b87c43fc58..1591b0616262 100644 --- a/libs/WindowManager/Shell/Android.bp +++ b/libs/WindowManager/Shell/Android.bp @@ -105,6 +105,7 @@ android_library { static_libs: [ "protolog-lib", "WindowManager-Shell-proto", + "androidx.appcompat_appcompat", ], manifest: "AndroidManifest.xml", }
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable-hdpi/one_handed_tutorial.png b/libs/WindowManager/Shell/res/drawable-hdpi/one_handed_tutorial.png Binary files differindex 6c1f1cfdea7c..6c1f1cfdea7c 100644 --- a/packages/SystemUI/res/drawable-hdpi/one_handed_tutorial.png +++ b/libs/WindowManager/Shell/res/drawable-hdpi/one_handed_tutorial.png diff --git a/packages/SystemUI/res/xml/one_handed_tutorial.xml b/libs/WindowManager/Shell/res/layout/one_handed_tutorial.xml index dc54caf0f14a..dc54caf0f14a 100644 --- a/packages/SystemUI/res/xml/one_handed_tutorial.xml +++ b/libs/WindowManager/Shell/res/layout/one_handed_tutorial.xml diff --git a/libs/WindowManager/Shell/res/values/config.xml b/libs/WindowManager/Shell/res/values/config.xml index 39efd0768eaa..63b0f6ffbec3 100644 --- a/libs/WindowManager/Shell/res/values/config.xml +++ b/libs/WindowManager/Shell/res/values/config.xml @@ -29,4 +29,7 @@ <!-- Animation duration when using long press on recents to dock --> <integer name="long_press_dock_anim_duration">250</integer> + + <!-- Allow one handed to enable round corner --> + <bool name="config_one_handed_enable_round_corner">true</bool> </resources> diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml index ce690281b491..7fb641a4b06e 100644 --- a/libs/WindowManager/Shell/res/values/dimen.xml +++ b/libs/WindowManager/Shell/res/values/dimen.xml @@ -62,4 +62,8 @@ <dimen name="docked_divider_handle_width">16dp</dimen> <dimen name="docked_divider_handle_height">2dp</dimen> + + <!-- One-Handed Mode --> + <!-- Threshold for dragging distance to enable one-handed mode --> + <dimen name="gestures_onehanded_drag_threshold">20dp</dimen> </resources> diff --git a/libs/WindowManager/Shell/res/values/strings.xml b/libs/WindowManager/Shell/res/values/strings.xml index cad924771cd3..b6668fbe4872 100644 --- a/libs/WindowManager/Shell/res/values/strings.xml +++ b/libs/WindowManager/Shell/res/values/strings.xml @@ -88,4 +88,9 @@ <string name="accessibility_action_divider_top_30">Top 30%</string> <!-- Accessibility action for moving docked stack divider to make the bottom screen full screen [CHAR LIMIT=NONE] --> <string name="accessibility_action_divider_bottom_full">Bottom full screen</string> + + <!-- One-Handed Tutorial title [CHAR LIMIT=60] --> + <string name="one_handed_tutorial_title">Using one-handed mode</string> + <!-- One-Handed Tutorial description [CHAR LIMIT=NONE] --> + <string name="one_handed_tutorial_description">To exit, swipe up from the bottom of the screen or tap anywhere above the app</string> </resources> diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java index 8abe9eeb6a9a..b4620e27e68c 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java @@ -22,7 +22,6 @@ import android.annotation.NonNull; import android.content.Context; import android.content.res.Configuration; import android.graphics.Point; -import android.graphics.Rect; import android.graphics.Region; import android.os.Bundle; import android.os.IBinder; @@ -32,7 +31,6 @@ import android.util.MergedConfiguration; import android.util.Slog; import android.util.SparseArray; import android.view.Display; -import android.view.DisplayCutout; import android.view.DragEvent; import android.view.IScrollCaptureController; import android.view.IWindow; @@ -47,6 +45,7 @@ import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; import android.view.WindowlessWindowManager; +import android.window.ClientWindowFrames; import com.android.internal.os.IResultReceiver; @@ -274,22 +273,20 @@ public class SystemWindows { @Override public int relayout(IWindow window, int seq, WindowManager.LayoutParams attrs, int requestedWidth, int requestedHeight, int viewVisibility, int flags, - long frameNumber, Rect outFrame, Rect outOverscanInsets, Rect outContentInsets, - Rect outVisibleInsets, Rect outStableInsets, - DisplayCutout.ParcelableWrapper cutout, MergedConfiguration mergedConfiguration, + long frameNumber, ClientWindowFrames outFrames, + MergedConfiguration mergedConfiguration, SurfaceControl outSurfaceControl, InsetsState outInsetsState, InsetsSourceControl[] outActiveControls, Point outSurfaceSize, SurfaceControl outBLASTSurfaceControl) { int res = super.relayout(window, seq, attrs, requestedWidth, requestedHeight, - viewVisibility, flags, frameNumber, outFrame, outOverscanInsets, - outContentInsets, outVisibleInsets, outStableInsets, - cutout, mergedConfiguration, outSurfaceControl, outInsetsState, + viewVisibility, flags, frameNumber, outFrames, + mergedConfiguration, outSurfaceControl, outInsetsState, outActiveControls, outSurfaceSize, outBLASTSurfaceControl); if (res != 0) { return res; } DisplayLayout dl = mDisplayController.getDisplayLayout(mDisplayId); - outStableInsets.set(dl.stableInsets()); + outFrames.stableInsets.set(dl.stableInsets()); return 0; } @@ -314,10 +311,9 @@ public class SystemWindows { ContainerWindow() {} @Override - public void resized(Rect frame, Rect contentInsets, Rect visibleInsets, Rect stableInsets, - boolean reportDraw, MergedConfiguration newMergedConfiguration, Rect backDropFrame, - boolean forceLayout, boolean alwaysConsumeSystemBars, int displayId, - DisplayCutout.ParcelableWrapper displayCutout) {} + public void resized(ClientWindowFrames frames, boolean reportDraw, + MergedConfiguration newMergedConfiguration, boolean forceLayout, + boolean alwaysConsumeSystemBars, int displayId) {} @Override public void locationInParentDisplayChanged(Point offset) {} diff --git a/packages/SystemUI/src/com/android/systemui/onehanded/OneHanded.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHanded.java index b7c6262b07e0..9c78fc5e57b8 100644 --- a/packages/SystemUI/src/com/android/systemui/onehanded/OneHanded.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHanded.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package com.android.systemui.onehanded; +package com.android.wm.shell.onehanded; import androidx.annotation.NonNull; -import com.android.systemui.onehanded.OneHandedGestureHandler.OneHandedGestureEventCallback; +import com.android.wm.shell.onehanded.OneHandedGestureHandler.OneHandedGestureEventCallback; import java.io.PrintWriter; diff --git a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedAnimationCallback.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedAnimationCallback.java index 264ace749383..6749f7eec968 100644 --- a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedAnimationCallback.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedAnimationCallback.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.onehanded; +package com.android.wm.shell.onehanded; import android.view.SurfaceControl; diff --git a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedAnimationController.java index 9be1b5a35be6..963909621a1b 100644 --- a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedAnimationController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedAnimationController.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.onehanded; +package com.android.wm.shell.onehanded; import android.animation.Animator; import android.animation.ValueAnimator; diff --git a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java index 90adf838440c..c84b4781d19d 100644 --- a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.onehanded; +package com.android.wm.shell.onehanded; import static android.os.UserHandle.USER_CURRENT; import static android.view.Display.DEFAULT_DISPLAY; @@ -35,9 +35,9 @@ import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; -import com.android.systemui.onehanded.OneHandedGestureHandler.OneHandedGestureEventCallback; import com.android.wm.shell.common.DisplayChangeController; import com.android.wm.shell.common.DisplayController; +import com.android.wm.shell.onehanded.OneHandedGestureHandler.OneHandedGestureEventCallback; import java.io.PrintWriter; @@ -390,7 +390,7 @@ public class OneHandedController implements OneHanded { } } - @androidx.annotation.VisibleForTesting + @VisibleForTesting private void setEnabledGesturalOverlay(boolean enabled) { try { mOverlayManager.setEnabled(ONE_HANDED_MODE_GESTURAL_OVERLAY, enabled, USER_CURRENT); diff --git a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedDisplayAreaOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java index ec40bad06b71..9954618134e8 100644 --- a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedDisplayAreaOrganizer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.android.systemui.onehanded; +package com.android.wm.shell.onehanded; import static android.view.Display.DEFAULT_DISPLAY; -import static com.android.systemui.onehanded.OneHandedAnimationController.TRANSITION_DIRECTION_EXIT; -import static com.android.systemui.onehanded.OneHandedAnimationController.TRANSITION_DIRECTION_TRIGGER; +import static com.android.wm.shell.onehanded.OneHandedAnimationController.TRANSITION_DIRECTION_EXIT; +import static com.android.wm.shell.onehanded.OneHandedAnimationController.TRANSITION_DIRECTION_TRIGGER; import android.content.Context; import android.graphics.Point; diff --git a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedEvents.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedEvents.java index 327ed67d6fc8..79ddd2b11e72 100644 --- a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedEvents.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedEvents.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.onehanded; +package com.android.wm.shell.onehanded; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.UiEvent; diff --git a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedGestureHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedGestureHandler.java index 4a493ba800ba..3b1e6cbe5ccd 100644 --- a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedGestureHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedGestureHandler.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.onehanded; +package com.android.wm.shell.onehanded; import static android.view.Display.DEFAULT_DISPLAY; @@ -38,7 +38,7 @@ import android.window.WindowContainerTransaction; import androidx.annotation.VisibleForTesting; -import com.android.systemui.R; +import com.android.wm.shell.R; import com.android.wm.shell.common.DisplayChangeController; import com.android.wm.shell.common.DisplayController; @@ -210,7 +210,7 @@ public class OneHandedGestureHandler implements OneHandedTransitionCallback, displaySize.y); mInputMonitor = InputManager.getInstance().monitorGestureInput( "onehanded-gesture-offset", DEFAULT_DISPLAY); - mInputEventReceiver = new SysUiInputEventReceiver( + mInputEventReceiver = new EventReceiver( mInputMonitor.getInputChannel(), Looper.getMainLooper()); } } @@ -227,8 +227,8 @@ public class OneHandedGestureHandler implements OneHandedTransitionCallback, mRotation = toRotation; } - private class SysUiInputEventReceiver extends InputEventReceiver { - SysUiInputEventReceiver(InputChannel channel, Looper looper) { + private class EventReceiver extends InputEventReceiver { + EventReceiver(InputChannel channel, Looper looper) { super(channel, looper); } diff --git a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedSettingsUtil.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedSettingsUtil.java index 0598f32c16d5..4d66f2961a29 100644 --- a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedSettingsUtil.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedSettingsUtil.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.onehanded; +package com.android.wm.shell.onehanded; import android.annotation.IntDef; import android.content.ContentResolver; @@ -22,8 +22,6 @@ import android.database.ContentObserver; import android.net.Uri; import android.provider.Settings; -import com.android.systemui.dagger.SysUISingleton; - import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -31,7 +29,6 @@ import java.lang.annotation.RetentionPolicy; /** * APIs for querying or updating one handed settings . */ -@SysUISingleton public final class OneHandedSettingsUtil { private static final String TAG = "OneHandedSettingsUtil"; diff --git a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedSurfaceTransactionHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedSurfaceTransactionHelper.java index bc4a9b49205c..e7010db97d77 100644 --- a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedSurfaceTransactionHelper.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedSurfaceTransactionHelper.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package com.android.systemui.onehanded; +package com.android.wm.shell.onehanded; import android.content.Context; import android.content.res.Resources; import android.graphics.Rect; import android.view.SurfaceControl; -import com.android.systemui.R; +import com.android.wm.shell.R; /** * Abstracts the common operations on {@link SurfaceControl.Transaction} for OneHanded transition. diff --git a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedThread.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedThread.java index b7b814a31a1e..24d33ede5d63 100644 --- a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedThread.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedThread.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.onehanded; +package com.android.wm.shell.onehanded; import android.os.Handler; import android.os.HandlerThread; diff --git a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedTimeoutHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTimeoutHandler.java index 21329ea1b0e6..9c97cd7db71f 100644 --- a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedTimeoutHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTimeoutHandler.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package com.android.systemui.onehanded; +package com.android.wm.shell.onehanded; -import static com.android.systemui.onehanded.OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_MEDIUM_IN_SECONDS; +import static com.android.wm.shell.onehanded.OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_MEDIUM_IN_SECONDS; import android.os.Handler; import android.os.Looper; diff --git a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedTouchHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTouchHandler.java index 3d28a426f4f8..721382d52717 100644 --- a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedTouchHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTouchHandler.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.onehanded; +package com.android.wm.shell.onehanded; import static android.view.Display.DEFAULT_DISPLAY; @@ -127,7 +127,7 @@ public class OneHandedTouchHandler implements OneHandedTransitionCallback { if (mIsEnabled) { mInputMonitor = InputManager.getInstance().monitorGestureInput( "onehanded-touch", DEFAULT_DISPLAY); - mInputEventReceiver = new SysUiInputEventReceiver( + mInputEventReceiver = new EventReceiver( mInputMonitor.getInputChannel(), Looper.getMainLooper()); } } @@ -150,8 +150,8 @@ public class OneHandedTouchHandler implements OneHandedTransitionCallback { pw.println(mLastUpdatedBounds); } - private class SysUiInputEventReceiver extends InputEventReceiver { - SysUiInputEventReceiver(InputChannel channel, Looper looper) { + private class EventReceiver extends InputEventReceiver { + EventReceiver(InputChannel channel, Looper looper) { super(channel, looper); } diff --git a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedTransitionCallback.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTransitionCallback.java index 75eb0ebd5c84..3af7c4b71d0a 100644 --- a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedTransitionCallback.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTransitionCallback.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.onehanded; +package com.android.wm.shell.onehanded; import android.graphics.Rect; diff --git a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedTutorialHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTutorialHandler.java index beccf3dbc8de..b15b5154c2a4 100644 --- a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedTutorialHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTutorialHandler.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.onehanded; +package com.android.wm.shell.onehanded; import android.content.ContentResolver; import android.content.Context; @@ -33,7 +33,7 @@ import android.widget.FrameLayout; import androidx.annotation.NonNull; -import com.android.systemui.R; +import com.android.wm.shell.R; import java.io.PrintWriter; @@ -79,7 +79,7 @@ public class OneHandedTutorialHandler implements OneHandedTransitionCallback { mTargetViewContainer.setClipChildren(false); mTutorialAreaHeight = Math.round(mDisplaySize.y * (SystemProperties.getInt(ONE_HANDED_MODE_OFFSET_PERCENTAGE, 50) / 100.0f)); - mTutorialView = LayoutInflater.from(context).inflate(R.xml.one_handed_tutorial, null); + mTutorialView = LayoutInflater.from(context).inflate(R.layout.one_handed_tutorial, null); mTargetViewContainer.addView(mTutorialView); mCanShowTutorial = (Settings.Secure.getInt(mContentResolver, Settings.Secure.ONE_HANDED_TUTORIAL_SHOW_COUNT, 0) >= MAX_TUTORIAL_SHOW_COUNT) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/WindowManagerProxy.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/WindowManagerProxy.java index 015707ecc6c8..25827cdb9e24 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/WindowManagerProxy.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/WindowManagerProxy.java @@ -194,7 +194,7 @@ class WindowManagerProxy { */ boolean applyEnterSplit(SplitScreenTaskOrganizer tiles, SplitDisplayLayout layout) { // Set launchtile first so that any stack created after - // getAllStackInfos and before reparent (even if unlikely) are placed + // getAllRootTaskInfos and before reparent (even if unlikely) are placed // correctly. mTaskOrganizer.setLaunchRoot(DEFAULT_DISPLAY, tiles.mSecondary.token); List<ActivityManager.RunningTaskInfo> rootTasks = diff --git a/libs/WindowManager/Shell/tests/unittest/Android.bp b/libs/WindowManager/Shell/tests/unittest/Android.bp index 692e2fa88fc3..937b00b3a0fd 100644 --- a/libs/WindowManager/Shell/tests/unittest/Android.bp +++ b/libs/WindowManager/Shell/tests/unittest/Android.bp @@ -25,6 +25,7 @@ android_test { "androidx.test.ext.junit", "mockito-target-extended-minus-junit4", "truth-prebuilt", + "testables", ], libs: [ "android.test.mock", diff --git a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedAnimationControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedAnimationControllerTest.java index 7fabf8258198..a8a3a9fd7da2 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedAnimationControllerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedAnimationControllerTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.onehanded; +package com.android.wm.shell.onehanded; import static org.junit.Assert.assertNotNull; diff --git a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java index e42cf529373e..1ce8b5445b37 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedControllerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.onehanded; +package com.android.wm.shell.onehanded; import static com.google.common.truth.Truth.assertThat; @@ -112,10 +112,21 @@ public class OneHandedControllerTest extends OneHandedTestCase { } @Test + public void testRegisterTransitionCallbackAfterInit() { + verify(mMockDisplayAreaOrganizer).registerTransitionCallback(mMockTouchHandler); + verify(mMockDisplayAreaOrganizer).registerTransitionCallback(mMockGestureHandler); + verify(mMockDisplayAreaOrganizer).registerTransitionCallback(mMockTutorialHandler); + } + + @Test public void testRegisterTransitionCallback() { - verify(mMockDisplayAreaOrganizer, atLeastOnce()).registerTransitionCallback(any()); + OneHandedTransitionCallback callback = new OneHandedTransitionCallback() {}; + mOneHandedController.registerTransitionCallback(callback); + + verify(mMockDisplayAreaOrganizer).registerTransitionCallback(callback); } + @Test public void testStopOneHanded_shouldRemoveTimer() { mOneHandedController.stopOneHanded(); @@ -139,7 +150,7 @@ public class OneHandedControllerTest extends OneHandedTestCase { verify(mMockTouchHandler, atLeastOnce()).onOneHandedEnabled(enabled); } - @Ignore("b/161980408, fix it after migration finished") + @Ignore("b/167943723, refactor it and fix it") @Test public void tesSettingsObserver_updateTapAppToExit() { Settings.Secure.putInt(mContext.getContentResolver(), @@ -148,7 +159,7 @@ public class OneHandedControllerTest extends OneHandedTestCase { verify(mOneHandedController).setTaskChangeToExit(true); } - @Ignore("b/161980408, fix it after migration finished") + @Ignore("b/167943723, refactor it and fix it") @Test public void tesSettingsObserver_updateEnabled() { Settings.Secure.putInt(mContext.getContentResolver(), @@ -157,7 +168,7 @@ public class OneHandedControllerTest extends OneHandedTestCase { verify(mOneHandedController).setOneHandedEnabled(true); } - @Ignore("b/161980408, fix it after migration finished") + @Ignore("b/167943723, refactor it and fix it") @Test public void tesSettingsObserver_updateTimeout() { Settings.Secure.putInt(mContext.getContentResolver(), @@ -168,7 +179,7 @@ public class OneHandedControllerTest extends OneHandedTestCase { OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_MEDIUM_IN_SECONDS); } - @Ignore("b/161980408, fix it after migration finished") + @Ignore("b/167943723, refactor it and fix it") @Test public void tesSettingsObserver_updateSwipeToNotification() { Settings.Secure.putInt(mContext.getContentResolver(), diff --git a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedDisplayAreaOrganizerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizerTest.java index a989cd1f9c40..5ff94b6308ef 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedDisplayAreaOrganizerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizerTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.onehanded; +package com.android.wm.shell.onehanded; import static android.view.Display.DEFAULT_DISPLAY; import static android.window.DisplayAreaOrganizer.FEATURE_ONE_HANDED; diff --git a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedEventsTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedEventsTest.java index 36c1174fcdce..492c34e10ed5 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedEventsTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedEventsTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.onehanded; +package com.android.wm.shell.onehanded; import static org.junit.Assert.assertEquals; @@ -22,7 +22,6 @@ import androidx.test.filters.SmallTest; import com.android.internal.logging.UiEventLogger; import com.android.internal.logging.testing.UiEventLoggerFake; -import com.android.systemui.SysuiTestCase; import org.junit.Before; import org.junit.Test; @@ -34,7 +33,7 @@ import java.util.Collection; @RunWith(Parameterized.class) @SmallTest -public class OneHandedEventsTest extends SysuiTestCase { +public class OneHandedEventsTest extends OneHandedTestCase { private UiEventLoggerFake mUiEventLogger; diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedGestureHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedGestureHandlerTest.java new file mode 100644 index 000000000000..fb417c8ca5e8 --- /dev/null +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedGestureHandlerTest.java @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2020 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.wm.shell.onehanded; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.ArgumentMatchers.any; + +import android.testing.AndroidTestingRunner; +import android.testing.TestableLooper; + +import androidx.test.filters.SmallTest; + +import com.android.wm.shell.common.DisplayController; + +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +@SmallTest +@RunWith(AndroidTestingRunner.class) +@TestableLooper.RunWithLooper +public class OneHandedGestureHandlerTest extends OneHandedTestCase { + OneHandedTutorialHandler mTutorialHandler; + OneHandedGestureHandler mGestureHandler; + @Mock + DisplayController mMockDisplayController; + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + mTutorialHandler = new OneHandedTutorialHandler(mContext); + mGestureHandler = new OneHandedGestureHandler(mContext, mMockDisplayController); + } + + @Test + public void testSetGestureEventListener() { + OneHandedGestureHandler.OneHandedGestureEventCallback callback = + new OneHandedGestureHandler.OneHandedGestureEventCallback() { + @Override + public void onStart() {} + + @Override + public void onStop() {} + }; + + mGestureHandler.setGestureEventListener(callback); + assertThat(mGestureHandler.mGestureEventCallback).isEqualTo(callback); + } + + @Ignore("b/167943723, refactor it and fix it") + @Test + public void testReceiveNewConfig_whenThreeButtonModeEnabled() { + mGestureHandler.onOneHandedEnabled(true); + mGestureHandler.onThreeButtonModeEnabled(true); + + assertThat(mGestureHandler.mInputMonitor).isNotNull(); + assertThat(mGestureHandler.mInputEventReceiver).isNotNull(); + } + + @Test + public void testOneHandedDisabled_shouldDisposeInputChannel() { + mGestureHandler.onOneHandedEnabled(false); + + assertThat(mGestureHandler.mInputMonitor).isNull(); + assertThat(mGestureHandler.mInputEventReceiver).isNull(); + } + + @Test + public void testChangeNavBarToNon3Button_shouldDisposeInputChannel() { + mGestureHandler.onOneHandedEnabled(true); + mGestureHandler.onThreeButtonModeEnabled(false); + + assertThat(mGestureHandler.mInputMonitor).isNull(); + assertThat(mGestureHandler.mInputEventReceiver).isNull(); + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedSettingsUtilTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedSettingsUtilTest.java index 990eb634e46f..7c11138a47aa 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedSettingsUtilTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedSettingsUtilTest.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.android.systemui.onehanded; +package com.android.wm.shell.onehanded; -import static com.android.systemui.onehanded.OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_LONG_IN_SECONDS; -import static com.android.systemui.onehanded.OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_MEDIUM_IN_SECONDS; -import static com.android.systemui.onehanded.OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_NEVER; -import static com.android.systemui.onehanded.OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_SHORT_IN_SECONDS; +import static com.android.wm.shell.onehanded.OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_LONG_IN_SECONDS; +import static com.android.wm.shell.onehanded.OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_MEDIUM_IN_SECONDS; +import static com.android.wm.shell.onehanded.OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_NEVER; +import static com.android.wm.shell.onehanded.OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_SHORT_IN_SECONDS; import static com.google.common.truth.Truth.assertThat; @@ -59,24 +59,24 @@ public class OneHandedSettingsUtilTest extends OneHandedTestCase { @Test public void testRegisterSecureKeyObserver() { final Uri result = OneHandedSettingsUtil.registerSettingsKeyObserver( - Settings.Secure.ONE_HANDED_MODE_ENABLED, mContentResolver, mContentObserver); + Settings.Secure.TAPS_APP_TO_EXIT, mContentResolver, mContentObserver); assertThat(result).isNotNull(); OneHandedSettingsUtil.registerSettingsKeyObserver( - Settings.Secure.ONE_HANDED_MODE_ENABLED, mContentResolver, mContentObserver); + Settings.Secure.TAPS_APP_TO_EXIT, mContentResolver, mContentObserver); } @Test public void testUnregisterSecureKeyObserver() { OneHandedSettingsUtil.registerSettingsKeyObserver( - Settings.Secure.ONE_HANDED_MODE_ENABLED, mContentResolver, mContentObserver); + Settings.Secure.TAPS_APP_TO_EXIT, mContentResolver, mContentObserver); OneHandedSettingsUtil.unregisterSettingsKeyObserver(mContentResolver, mContentObserver); assertThat(mOnChanged).isFalse(); Settings.Secure.putInt(mContext.getContentResolver(), - Settings.Secure.ONE_HANDED_MODE_ENABLED, 0); + Settings.Secure.TAPS_APP_TO_EXIT, 0); assertThat(mOnChanged).isFalse(); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedTestCase.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTestCase.java index f111c4896458..c7ae2a09ad67 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedTestCase.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTestCase.java @@ -14,17 +14,21 @@ * limitations under the License. */ -package com.android.systemui.onehanded; +package com.android.wm.shell.onehanded; -import static com.android.systemui.onehanded.OneHandedController.SUPPORT_ONE_HANDED_MODE; -import static com.android.systemui.onehanded.OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_MEDIUM_IN_SECONDS; +import static android.view.Display.DEFAULT_DISPLAY; + +import static com.android.wm.shell.onehanded.OneHandedController.SUPPORT_ONE_HANDED_MODE; +import static com.android.wm.shell.onehanded.OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_MEDIUM_IN_SECONDS; import static org.junit.Assume.assumeTrue; +import android.content.Context; +import android.hardware.display.DisplayManager; import android.os.SystemProperties; import android.provider.Settings; -import com.android.systemui.SysuiTestCase; +import androidx.test.platform.app.InstrumentationRegistry; import org.junit.After; import org.junit.Before; @@ -32,14 +36,26 @@ import org.junit.Before; /** * Base class that does One Handed specific setup. */ -public abstract class OneHandedTestCase extends SysuiTestCase { +public abstract class OneHandedTestCase { static boolean sOrigEnabled; static boolean sOrigTapsAppToExitEnabled; static int sOrigTimeout; static boolean sOrigSwipeToNotification; + protected Context mContext; + @Before public void setupSettings() { + final Context testContext = + InstrumentationRegistry.getInstrumentation().getTargetContext(); + final DisplayManager dm = testContext.getSystemService(DisplayManager.class); + mContext = testContext.createDisplayContext(dm.getDisplay(DEFAULT_DISPLAY)); + + InstrumentationRegistry + .getInstrumentation() + .getUiAutomation() + .adoptShellPermissionIdentity(); + sOrigEnabled = OneHandedSettingsUtil.getSettingsOneHandedModeEnabled( getContext().getContentResolver()); sOrigTimeout = OneHandedSettingsUtil.getSettingsOneHandedModeTimeout( @@ -74,6 +90,15 @@ public abstract class OneHandedTestCase extends SysuiTestCase { Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED, sOrigSwipeToNotification ? 1 : 0); + + InstrumentationRegistry + .getInstrumentation() + .getUiAutomation() + .dropShellPermissionIdentity(); + } + + protected Context getContext() { + return mContext; } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedTimeoutHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTimeoutHandlerTest.java index 7d631319ec5e..e2b70c3bcc70 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedTimeoutHandlerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTimeoutHandlerTest.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package com.android.systemui.onehanded; +package com.android.wm.shell.onehanded; -import static com.android.systemui.onehanded.OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_LONG_IN_SECONDS; -import static com.android.systemui.onehanded.OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_MEDIUM_IN_SECONDS; -import static com.android.systemui.onehanded.OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_NEVER; -import static com.android.systemui.onehanded.OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_SHORT_IN_SECONDS; -import static com.android.systemui.onehanded.OneHandedTimeoutHandler.ONE_HANDED_TIMEOUT_STOP_MSG; +import static com.android.wm.shell.onehanded.OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_LONG_IN_SECONDS; +import static com.android.wm.shell.onehanded.OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_MEDIUM_IN_SECONDS; +import static com.android.wm.shell.onehanded.OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_NEVER; +import static com.android.wm.shell.onehanded.OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_SHORT_IN_SECONDS; +import static com.android.wm.shell.onehanded.OneHandedTimeoutHandler.ONE_HANDED_TIMEOUT_STOP_MSG; import static com.google.common.truth.Truth.assertThat; diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTouchHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTouchHandlerTest.java new file mode 100644 index 000000000000..c69e385b2602 --- /dev/null +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTouchHandlerTest.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2020 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.wm.shell.onehanded; + +import static com.google.common.truth.Truth.assertThat; + +import android.testing.AndroidTestingRunner; +import android.testing.TestableLooper; + +import androidx.test.filters.SmallTest; + +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.MockitoAnnotations; + +@SmallTest +@RunWith(AndroidTestingRunner.class) +@TestableLooper.RunWithLooper +public class OneHandedTouchHandlerTest extends OneHandedTestCase { + OneHandedTouchHandler mTouchHandler; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mTouchHandler = new OneHandedTouchHandler(); + } + + @Test + public void testRegisterTouchEventListener() { + OneHandedTouchHandler.OneHandedTouchEventCallback callback = () -> { + }; + mTouchHandler.registerTouchEventListener(callback); + + assertThat(mTouchHandler.mTouchEventCallback).isEqualTo(callback); + } + + @Test + public void testOneHandedDisabled_shouldDisposeInputChannel() { + mTouchHandler.onOneHandedEnabled(false); + + assertThat(mTouchHandler.mInputMonitor).isNull(); + assertThat(mTouchHandler.mInputEventReceiver).isNull(); + } + + @Ignore("b/167943723, refactor it and fix it") + @Test + public void testOneHandedEnabled_monitorInputChannel() { + mTouchHandler.onOneHandedEnabled(true); + + assertThat(mTouchHandler.mInputMonitor).isNotNull(); + assertThat(mTouchHandler.mInputEventReceiver).isNotNull(); + } +}
\ No newline at end of file diff --git a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedTutorialHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTutorialHandlerTest.java index 8ea5524eb7e6..4a133d39291a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedTutorialHandlerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTutorialHandlerTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.onehanded; +package com.android.wm.shell.onehanded; import static org.mockito.Mockito.verify; @@ -29,13 +29,13 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.Mockito; import org.mockito.MockitoAnnotations; @SmallTest @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper public class OneHandedTutorialHandlerTest extends OneHandedTestCase { + @Mock OneHandedTouchHandler mTouchHandler; OneHandedTutorialHandler mTutorialHandler; OneHandedGestureHandler mGestureHandler; @@ -48,8 +48,7 @@ public class OneHandedTutorialHandlerTest extends OneHandedTestCase { @Before public void setUp() { MockitoAnnotations.initMocks(this); - mTouchHandler = new OneHandedTouchHandler(); - mTutorialHandler = Mockito.spy(new OneHandedTutorialHandler(mContext)); + mTutorialHandler = new OneHandedTutorialHandler(mContext); mGestureHandler = new OneHandedGestureHandler(mContext, mMockDisplayController); mOneHandedController = new OneHandedController( getContext(), diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java index 6fc702e4a068..04bcbfc5f6b8 100644 --- a/location/java/android/location/LocationManager.java +++ b/location/java/android/location/LocationManager.java @@ -164,7 +164,7 @@ public class LocationManager { /** * The fused location provider. * - * <p>This provider combines may combine inputs from several location sources to provide the + * <p>This provider may combine inputs from several location sources to provide the * best possible location fix. It is implicitly used for all API's that involve the * {@link LocationRequest} object. * diff --git a/media/java/android/media/AudioDeviceAttributes.java b/media/java/android/media/AudioDeviceAttributes.java index 0ab62c14ab9f..6c8b50037d3d 100644 --- a/media/java/android/media/AudioDeviceAttributes.java +++ b/media/java/android/media/AudioDeviceAttributes.java @@ -72,6 +72,11 @@ public final class AudioDeviceAttributes implements Parcelable { private final @Role int mRole; /** + * The internal audio device type + */ + private final int mNativeType; + + /** * @hide * Constructor from a valid {@link AudioDeviceInfo} * @param deviceInfo the connected audio device from which to obtain the device-identifying @@ -83,6 +88,7 @@ public final class AudioDeviceAttributes implements Parcelable { mRole = deviceInfo.isSink() ? ROLE_OUTPUT : ROLE_INPUT; mType = deviceInfo.getType(); mAddress = deviceInfo.getAddress(); + mNativeType = deviceInfo.getInternalType(); } /** @@ -101,9 +107,12 @@ public final class AudioDeviceAttributes implements Parcelable { } if (role == ROLE_OUTPUT) { AudioDeviceInfo.enforceValidAudioDeviceTypeOut(type); - } - if (role == ROLE_INPUT) { + mNativeType = AudioDeviceInfo.convertDeviceTypeToInternalDevice(type); + } else if (role == ROLE_INPUT) { AudioDeviceInfo.enforceValidAudioDeviceTypeIn(type); + mNativeType = AudioDeviceInfo.convertDeviceTypeToInternalInputDevice(type); + } else { + mNativeType = AudioSystem.DEVICE_NONE; } mRole = role; @@ -115,6 +124,7 @@ public final class AudioDeviceAttributes implements Parcelable { mRole = (nativeType & AudioSystem.DEVICE_BIT_IN) != 0 ? ROLE_INPUT : ROLE_OUTPUT; mType = AudioDeviceInfo.convertInternalDeviceToDeviceType(nativeType); mAddress = address; + mNativeType = nativeType; } /** @@ -147,6 +157,15 @@ public final class AudioDeviceAttributes implements Parcelable { return mAddress; } + /** + * @hide + * Returns the internal device type of a device + * @return the internal device type + */ + public int getInternalType() { + return mNativeType; + } + @Override public int hashCode() { return Objects.hash(mRole, mType, mAddress); @@ -189,12 +208,14 @@ public final class AudioDeviceAttributes implements Parcelable { dest.writeInt(mRole); dest.writeInt(mType); dest.writeString(mAddress); + dest.writeInt(mNativeType); } private AudioDeviceAttributes(@NonNull Parcel in) { mRole = in.readInt(); mType = in.readInt(); mAddress = in.readString(); + mNativeType = in.readInt(); } public static final @NonNull Parcelable.Creator<AudioDeviceAttributes> CREATOR = diff --git a/media/java/android/media/AudioDeviceInfo.java b/media/java/android/media/AudioDeviceInfo.java index d4fb1be56890..477519c0da32 100644 --- a/media/java/android/media/AudioDeviceInfo.java +++ b/media/java/android/media/AudioDeviceInfo.java @@ -351,6 +351,14 @@ public final class AudioDeviceInfo { } /** + * @hide + * @return the internal device tyoe + */ + public int getInternalType() { + return mPort.type(); + } + + /** * @return The internal device ID. */ public int getId() { @@ -513,10 +521,21 @@ public final class AudioDeviceInfo { return INT_TO_EXT_DEVICE_MAPPING.get(intDevice, TYPE_UNKNOWN); } + /** @hide */ + public static int convertDeviceTypeToInternalInputDevice(int deviceType) { + return EXT_TO_INT_INPUT_DEVICE_MAPPING.get(deviceType, AudioSystem.DEVICE_NONE); + } + private static final SparseIntArray INT_TO_EXT_DEVICE_MAPPING; private static final SparseIntArray EXT_TO_INT_DEVICE_MAPPING; + /** + * EXT_TO_INT_INPUT_DEVICE_MAPPING aims at mapping external device type to internal input device + * type. + */ + private static final SparseIntArray EXT_TO_INT_INPUT_DEVICE_MAPPING; + static { INT_TO_EXT_DEVICE_MAPPING = new SparseIntArray(); INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_EARPIECE, TYPE_BUILTIN_EARPIECE); @@ -601,6 +620,32 @@ public final class AudioDeviceInfo { EXT_TO_INT_DEVICE_MAPPING.put(TYPE_REMOTE_SUBMIX, AudioSystem.DEVICE_OUT_REMOTE_SUBMIX); EXT_TO_INT_DEVICE_MAPPING.put(TYPE_BLE_HEADSET, AudioSystem.DEVICE_OUT_BLE_HEADSET); EXT_TO_INT_DEVICE_MAPPING.put(TYPE_BLE_SPEAKER, AudioSystem.DEVICE_OUT_BLE_SPEAKER); + + // privileges mapping to input device + EXT_TO_INT_INPUT_DEVICE_MAPPING = new SparseIntArray(); + EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_BUILTIN_MIC, AudioSystem.DEVICE_IN_BUILTIN_MIC); + EXT_TO_INT_INPUT_DEVICE_MAPPING.put( + TYPE_BLUETOOTH_SCO, AudioSystem.DEVICE_IN_BLUETOOTH_SCO_HEADSET); + EXT_TO_INT_INPUT_DEVICE_MAPPING.put( + TYPE_WIRED_HEADSET, AudioSystem.DEVICE_IN_WIRED_HEADSET); + EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_HDMI, AudioSystem.DEVICE_IN_HDMI); + EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_TELEPHONY, AudioSystem.DEVICE_IN_TELEPHONY_RX); + EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_DOCK, AudioSystem.DEVICE_IN_ANLG_DOCK_HEADSET); + EXT_TO_INT_INPUT_DEVICE_MAPPING.put( + TYPE_USB_ACCESSORY, AudioSystem.DEVICE_IN_USB_ACCESSORY); + EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_USB_DEVICE, AudioSystem.DEVICE_IN_USB_DEVICE); + EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_USB_HEADSET, AudioSystem.DEVICE_IN_USB_HEADSET); + EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_FM_TUNER, AudioSystem.DEVICE_IN_FM_TUNER); + EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_TV_TUNER, AudioSystem.DEVICE_IN_TV_TUNER); + EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_LINE_ANALOG, AudioSystem.DEVICE_IN_LINE); + EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_LINE_DIGITAL, AudioSystem.DEVICE_IN_SPDIF); + EXT_TO_INT_INPUT_DEVICE_MAPPING.put( + TYPE_BLUETOOTH_A2DP, AudioSystem.DEVICE_IN_BLUETOOTH_A2DP); + EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_IP, AudioSystem.DEVICE_IN_IP); + EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_BUS, AudioSystem.DEVICE_IN_BUS); + EXT_TO_INT_INPUT_DEVICE_MAPPING.put( + TYPE_REMOTE_SUBMIX, AudioSystem.DEVICE_IN_REMOTE_SUBMIX); + EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_BLE_HEADSET, AudioSystem.DEVICE_IN_BLE_HEADSET); } } diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index a16e063fe969..e1e55c25b3fa 100644 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -1949,6 +1949,349 @@ public class AudioManager { } //==================================================================== + // Audio Capture Preset routing + + /** + * @hide + * Set the preferred device for a given capture preset, i.e. the audio routing to be used by + * this capture preset. Note that the device may not be available at the time the preferred + * device is set, but it will be used once made available. + * <p>Use {@link #clearPreferredDevicesForCapturePreset(int)} to cancel setting this preference + * for this capture preset.</p> + * @param capturePreset the audio capture preset whose routing will be affected + * @param device the audio device to route to when available + * @return true if the operation was successful, false otherwise + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) + public boolean setPreferredDeviceForCapturePreset(int capturePreset, + @NonNull AudioDeviceAttributes device) { + return setPreferredDevicesForCapturePreset(capturePreset, Arrays.asList(device)); + } + + /** + * @hide + * Remove all the preferred audio devices previously set + * @param capturePreset the audio capture preset whose routing will be affected + * @return true if the operation was successful, false otherwise (invalid capture preset, or no + * device set for example) + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) + public boolean clearPreferredDevicesForCapturePreset(int capturePreset) { + if (!MediaRecorder.isValidAudioSource(capturePreset)) { + return false; + } + try { + final int status = getService().clearPreferredDevicesForCapturePreset(capturePreset); + return status == AudioSystem.SUCCESS; + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * @hide + * Return the preferred devices for an audio capture preset, previously set with + * {@link #setPreferredDeviceForCapturePreset(int, AudioDeviceAttributes)} + * @param capturePreset the capture preset to query + * @return a list that contains preferred devices for that capture preset. + */ + @NonNull + @SystemApi + @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) + public List<AudioDeviceAttributes> getPreferredDevicesForCapturePreset(int capturePreset) { + if (!MediaRecorder.isValidAudioSource(capturePreset)) { + return new ArrayList<AudioDeviceAttributes>(); + } + try { + return getService().getPreferredDevicesForCapturePreset(capturePreset); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + private boolean setPreferredDevicesForCapturePreset( + int capturePreset, @NonNull List<AudioDeviceAttributes> devices) { + Objects.requireNonNull(devices); + if (!MediaRecorder.isValidAudioSource(capturePreset)) { + return false; + } + if (devices.size() != 1) { + throw new IllegalArgumentException( + "Only support setting one preferred devices for capture preset"); + } + for (AudioDeviceAttributes device : devices) { + Objects.requireNonNull(device); + } + try { + final int status = + getService().setPreferredDevicesForCapturePreset(capturePreset, devices); + return status == AudioSystem.SUCCESS; + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * @hide + * Interface to be notified of changes in the preferred audio devices set for a given capture + * preset. + * <p>Note that this listener will only be invoked whenever + * {@link #setPreferredDeviceForCapturePreset(int, AudioDeviceAttributes)} or + * {@link #clearPreferredDevicesForCapturePreset(int)} causes a change in + * preferred device. It will not be invoked directly after registration with + * {@link #addOnPreferredDevicesForCapturePresetChangedListener( + * Executor, OnPreferredDevicesForCapturePresetChangedListener)} + * to indicate which strategies had preferred devices at the time of registration.</p> + * @see #setPreferredDeviceForCapturePreset(int, AudioDeviceAttributes) + * @see #clearPreferredDevicesForCapturePreset(int) + * @see #getPreferredDevicesForCapturePreset(int) + */ + @SystemApi + public interface OnPreferredDevicesForCapturePresetChangedListener { + /** + * Called on the listener to indicate that the preferred audio devices for the given + * capture preset has changed. + * @param capturePreset the capture preset whose preferred device changed + * @param devices a list of newly set preferred audio devices + */ + void onPreferredDevicesForCapturePresetChanged( + int capturePreset, @NonNull List<AudioDeviceAttributes> devices); + } + + /** + * @hide + * Adds a listener for being notified of changes to the capture-preset-preferred audio device. + * @param executor + * @param listener + * @throws SecurityException if the caller doesn't hold the required permission + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) + public void addOnPreferredDevicesForCapturePresetChangedListener( + @NonNull @CallbackExecutor Executor executor, + @NonNull OnPreferredDevicesForCapturePresetChangedListener listener) + throws SecurityException { + Objects.requireNonNull(executor); + Objects.requireNonNull(listener); + int status = addOnDevRoleForCapturePresetChangedListener( + executor, listener, AudioSystem.DEVICE_ROLE_PREFERRED); + if (status == AudioSystem.ERROR) { + // This must not happen + throw new RuntimeException("Unknown error happened"); + } + if (status == AudioSystem.BAD_VALUE) { + throw new IllegalArgumentException( + "attempt to call addOnPreferredDevicesForCapturePresetChangedListener() " + + "on a previously registered listener"); + } + } + + /** + * @hide + * Removes a previously added listener of changes to the capture-preset-preferred audio device. + * @param listener + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) + public void removeOnPreferredDevicesForCapturePresetChangedListener( + @NonNull OnPreferredDevicesForCapturePresetChangedListener listener) { + Objects.requireNonNull(listener); + int status = removeOnDevRoleForCapturePresetChangedListener( + listener, AudioSystem.DEVICE_ROLE_PREFERRED); + if (status == AudioSystem.ERROR) { + // This must not happen + throw new RuntimeException("Unknown error happened"); + } + if (status == AudioSystem.BAD_VALUE) { + throw new IllegalArgumentException( + "attempt to call removeOnPreferredDevicesForCapturePresetChangedListener() " + + "on an unregistered listener"); + } + } + + private <T> int addOnDevRoleForCapturePresetChangedListener( + @NonNull @CallbackExecutor Executor executor, + @NonNull T listener, int deviceRole) { + Objects.requireNonNull(executor); + Objects.requireNonNull(listener); + DevRoleListeners<T> devRoleListeners = + (DevRoleListeners<T>) mDevRoleForCapturePresetListeners.get(deviceRole); + if (devRoleListeners == null) { + return AudioSystem.ERROR; + } + synchronized (devRoleListeners.mDevRoleListenersLock) { + if (devRoleListeners.hasDevRoleListener(listener)) { + return AudioSystem.BAD_VALUE; + } + // lazy initialization of the list of device role listener + if (devRoleListeners.mListenerInfos == null) { + devRoleListeners.mListenerInfos = new ArrayList<>(); + } + final int oldCbCount = devRoleListeners.mListenerInfos.size(); + devRoleListeners.mListenerInfos.add(new DevRoleListenerInfo<T>(executor, listener)); + if (oldCbCount == 0 && devRoleListeners.mListenerInfos.size() > 0) { + // register binder for callbacks + synchronized (mDevRoleForCapturePresetListenersLock) { + int deviceRoleListenerStatus = mDeviceRoleListenersStatus; + mDeviceRoleListenersStatus |= (1 << deviceRole); + if (deviceRoleListenerStatus != 0) { + // There are already device role changed listeners active. + return AudioSystem.SUCCESS; + } + if (mDevicesRoleForCapturePresetDispatcherStub == null) { + mDevicesRoleForCapturePresetDispatcherStub = + new CapturePresetDevicesRoleDispatcherStub(); + } + try { + getService().registerCapturePresetDevicesRoleDispatcher( + mDevicesRoleForCapturePresetDispatcherStub); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + } + } + return AudioSystem.SUCCESS; + } + + private <T> int removeOnDevRoleForCapturePresetChangedListener( + @NonNull T listener, int deviceRole) { + Objects.requireNonNull(listener); + DevRoleListeners<T> devRoleListeners = + (DevRoleListeners<T>) mDevRoleForCapturePresetListeners.get(deviceRole); + if (devRoleListeners == null) { + return AudioSystem.ERROR; + } + synchronized (devRoleListeners.mDevRoleListenersLock) { + if (!devRoleListeners.removeDevRoleListener(listener)) { + return AudioSystem.BAD_VALUE; + } + if (devRoleListeners.mListenerInfos.size() == 0) { + // unregister binder for callbacks + synchronized (mDevRoleForCapturePresetListenersLock) { + mDeviceRoleListenersStatus ^= (1 << deviceRole); + if (mDeviceRoleListenersStatus != 0) { + // There are some other device role changed listeners active. + return AudioSystem.SUCCESS; + } + try { + getService().unregisterCapturePresetDevicesRoleDispatcher( + mDevicesRoleForCapturePresetDispatcherStub); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + } + } + return AudioSystem.SUCCESS; + } + + private final Map<Integer, Object> mDevRoleForCapturePresetListeners = new HashMap<>(){{ + put(AudioSystem.DEVICE_ROLE_PREFERRED, + new DevRoleListeners<OnPreferredDevicesForCapturePresetChangedListener>()); + }}; + + private class DevRoleListenerInfo<T> { + final @NonNull Executor mExecutor; + final @NonNull T mListener; + DevRoleListenerInfo(Executor executor, T listener) { + mExecutor = executor; + mListener = listener; + } + } + + private class DevRoleListeners<T> { + private final Object mDevRoleListenersLock = new Object(); + @GuardedBy("mDevRoleListenersLock") + private @Nullable ArrayList<DevRoleListenerInfo<T>> mListenerInfos; + + @GuardedBy("mDevRoleListenersLock") + private @Nullable DevRoleListenerInfo<T> getDevRoleListenerInfo(T listener) { + if (mListenerInfos == null) { + return null; + } + for (DevRoleListenerInfo<T> listenerInfo : mListenerInfos) { + if (listenerInfo.mListener == listener) { + return listenerInfo; + } + } + return null; + } + + @GuardedBy("mDevRoleListenersLock") + private boolean hasDevRoleListener(T listener) { + return getDevRoleListenerInfo(listener) != null; + } + + @GuardedBy("mDevRoleListenersLock") + private boolean removeDevRoleListener(T listener) { + final DevRoleListenerInfo<T> infoToRemove = getDevRoleListenerInfo(listener); + if (infoToRemove != null) { + mListenerInfos.remove(infoToRemove); + return true; + } + return false; + } + } + + private final Object mDevRoleForCapturePresetListenersLock = new Object(); + /** + * Record if there is a listener added for device role change. If there is a listener added for + * a specified device role change, the bit at position `1 << device_role` is set. + */ + @GuardedBy("mDevRoleForCapturePresetListenersLock") + private int mDeviceRoleListenersStatus = 0; + @GuardedBy("mDevRoleForCapturePresetListenersLock") + private CapturePresetDevicesRoleDispatcherStub mDevicesRoleForCapturePresetDispatcherStub; + + private final class CapturePresetDevicesRoleDispatcherStub + extends ICapturePresetDevicesRoleDispatcher.Stub { + + @Override + public void dispatchDevicesRoleChanged( + int capturePreset, int role, List<AudioDeviceAttributes> devices) { + final Object listenersObj = mDevRoleForCapturePresetListeners.get(role); + if (listenersObj == null) { + return; + } + switch (role) { + case AudioSystem.DEVICE_ROLE_PREFERRED: { + final DevRoleListeners<OnPreferredDevicesForCapturePresetChangedListener> + listeners = + (DevRoleListeners<OnPreferredDevicesForCapturePresetChangedListener>) + listenersObj; + final ArrayList<DevRoleListenerInfo< + OnPreferredDevicesForCapturePresetChangedListener>> prefDevListeners; + synchronized (listeners.mDevRoleListenersLock) { + if (listeners.mListenerInfos.isEmpty()) { + return; + } + prefDevListeners = (ArrayList<DevRoleListenerInfo< + OnPreferredDevicesForCapturePresetChangedListener>>) + listeners.mListenerInfos.clone(); + } + final long ident = Binder.clearCallingIdentity(); + try { + for (DevRoleListenerInfo< + OnPreferredDevicesForCapturePresetChangedListener> info : + prefDevListeners) { + info.mExecutor.execute(() -> + info.mListener.onPreferredDevicesForCapturePresetChanged( + capturePreset, devices)); + } + } finally { + Binder.restoreCallingIdentity(ident); + } + } break; + default: + break; + } + } + } + + //==================================================================== // Offload query /** * Returns whether offloaded playback of an audio format is supported on the device. @@ -6306,6 +6649,132 @@ public class AudioManager { } } + /** + * Adjusts the volume of the most relevant stream, or the given fallback + * stream. + * <p> + * This method should only be used by applications that replace the + * platform-wide management of audio settings or the main telephony + * application. + * <p> + * This method has no effect if the device implements a fixed volume policy + * as indicated by {@link #isVolumeFixed()}. + * <p>This API checks if the caller has the necessary permissions based on the provided + * component name, uid, and pid values. + * See {@link #adjustSuggestedStreamVolume(int, int, int)}. + * + * @param suggestedStreamType The stream type that will be used if there + * isn't a relevant stream. {@link #USE_DEFAULT_STREAM_TYPE} is + * valid here. + * @param direction The direction to adjust the volume. One of + * {@link #ADJUST_LOWER}, {@link #ADJUST_RAISE}, + * {@link #ADJUST_SAME}, {@link #ADJUST_MUTE}, + * {@link #ADJUST_UNMUTE}, or {@link #ADJUST_TOGGLE_MUTE}. + * @param flags One or more flags. + * @param packageName the package name of client application + * @param uid the uid of client application + * @param pid the pid of client application + * @param targetSdkVersion the target sdk version of client application + * @see #adjustVolume(int, int) + * @see #adjustStreamVolume(int, int, int) + * @see #setStreamVolume(int, int, int) + * @see #isVolumeFixed() + * + * @hide + */ + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) + public void adjustSuggestedStreamVolumeForUid(int suggestedStreamType, int direction, int flags, + @NonNull String packageName, int uid, int pid, int targetSdkVersion) { + try { + getService().adjustSuggestedStreamVolumeForUid(suggestedStreamType, direction, flags, + packageName, uid, pid, UserHandle.getUserHandleForUid(uid), targetSdkVersion); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Adjusts the volume of a particular stream by one step in a direction. + * <p> + * This method should only be used by applications that replace the platform-wide + * management of audio settings or the main telephony application. + * <p>This method has no effect if the device implements a fixed volume policy + * as indicated by {@link #isVolumeFixed()}. + * <p>From N onward, ringer mode adjustments that would toggle Do Not Disturb are not allowed + * unless the app has been granted Do Not Disturb Access. + * See {@link NotificationManager#isNotificationPolicyAccessGranted()}. + * <p>This API checks if the caller has the necessary permissions based on the provided + * component name, uid, and pid values. + * See {@link #adjustStreamVolume(int, int, int)}. + * + * @param streamType The stream type to adjust. One of {@link #STREAM_VOICE_CALL}, + * {@link #STREAM_SYSTEM}, {@link #STREAM_RING}, {@link #STREAM_MUSIC}, + * {@link #STREAM_ALARM} or {@link #STREAM_ACCESSIBILITY}. + * @param direction The direction to adjust the volume. One of + * {@link #ADJUST_LOWER}, {@link #ADJUST_RAISE}, or + * {@link #ADJUST_SAME}. + * @param flags One or more flags. + * @param packageName the package name of client application + * @param uid the uid of client application + * @param pid the pid of client application + * @param targetSdkVersion the target sdk version of client application + * @see #adjustVolume(int, int) + * @see #setStreamVolume(int, int, int) + * @throws SecurityException if the adjustment triggers a Do Not Disturb change + * and the caller is not granted notification policy access. + * + * @hide + */ + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) + public void adjustStreamVolumeForUid(int streamType, int direction, int flags, + @NonNull String packageName, int uid, int pid, int targetSdkVersion) { + try { + getService().adjustStreamVolumeForUid(streamType, direction, flags, packageName, uid, + pid, UserHandle.getUserHandleForUid(uid), targetSdkVersion); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Sets the volume index for a particular stream. + * <p>This method has no effect if the device implements a fixed volume policy + * as indicated by {@link #isVolumeFixed()}. + * <p>From N onward, volume adjustments that would toggle Do Not Disturb are not allowed unless + * the app has been granted Do Not Disturb Access. + * See {@link NotificationManager#isNotificationPolicyAccessGranted()}. + * <p>This API checks if the caller has the necessary permissions based on the provided + * component name, uid, and pid values. + * See {@link #setStreamVolume(int, int, int)}. + * + * @param streamType The stream whose volume index should be set. + * @param index The volume index to set. See + * {@link #getStreamMaxVolume(int)} for the largest valid value. + * @param flags One or more flags. + * @param packageName the package name of client application + * @param uid the uid of client application + * @param pid the pid of client application + * @param targetSdkVersion the target sdk version of client application + * @see #getStreamMaxVolume(int) + * @see #getStreamVolume(int) + * @see #isVolumeFixed() + * @throws SecurityException if the volume change triggers a Do Not Disturb change + * and the caller is not granted notification policy access. + * + * @hide + */ + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) + public void setStreamVolumeForUid(int streamType, int index, int flags, + @NonNull String packageName, int uid, int pid, int targetSdkVersion) { + try { + getService().setStreamVolumeForUid(streamType, index, flags, packageName, uid, pid, + UserHandle.getUserHandleForUid(uid), targetSdkVersion); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** @hide * TODO: make this a @SystemApi */ @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) diff --git a/media/java/android/media/AudioManagerInternal.java b/media/java/android/media/AudioManagerInternal.java index b44d7bba834f..c827932194ae 100644 --- a/media/java/android/media/AudioManagerInternal.java +++ b/media/java/android/media/AudioManagerInternal.java @@ -28,15 +28,6 @@ import com.android.server.LocalServices; */ public abstract class AudioManagerInternal { - public abstract void adjustSuggestedStreamVolumeForUid(int streamType, int direction, - int flags, String callingPackage, int uid, int pid); - - public abstract void adjustStreamVolumeForUid(int streamType, int direction, int flags, - String callingPackage, int uid, int pid); - - public abstract void setStreamVolumeForUid(int streamType, int direction, int flags, - String callingPackage, int uid, int pid); - public abstract void setRingerModeDelegate(RingerModeDelegate delegate); public abstract int getRingerModeInternal(); diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java index 22f625004aaf..279ba0a55be0 100644 --- a/media/java/android/media/AudioSystem.java +++ b/media/java/android/media/AudioSystem.java @@ -27,6 +27,7 @@ import android.media.audiofx.AudioEffect; import android.media.audiopolicy.AudioMix; import android.telephony.TelephonyManager; import android.util.Log; +import android.util.Pair; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -1755,6 +1756,134 @@ public class AudioSystem public static native int getDevicesForRoleAndStrategy( int strategy, int role, @NonNull List<AudioDeviceAttributes> devices); + // use case routing by capture preset + + private static Pair<int[], String[]> populateInputDevicesTypeAndAddress( + @NonNull List<AudioDeviceAttributes> devices) { + int[] types = new int[devices.size()]; + String[] addresses = new String[devices.size()]; + for (int i = 0; i < devices.size(); ++i) { + types[i] = devices.get(i).getInternalType(); + if (types[i] == AudioSystem.DEVICE_NONE) { + types[i] = AudioDeviceInfo.convertDeviceTypeToInternalInputDevice( + devices.get(i).getType()); + } + addresses[i] = devices.get(i).getAddress(); + } + return new Pair<int[], String[]>(types, addresses); + } + + /** + * @hide + * Set devices as role for capture preset. + * @param capturePreset the capture preset to configure + * @param role the role of the devices + * @param devices the list of devices to be set as role for the given capture preset + * @return {@link #SUCCESS} if successfully set + */ + public static int setDevicesRoleForCapturePreset( + int capturePreset, int role, @NonNull List<AudioDeviceAttributes> devices) { + if (devices.isEmpty()) { + return BAD_VALUE; + } + Pair<int[], String[]> typeAddresses = populateInputDevicesTypeAndAddress(devices); + return setDevicesRoleForCapturePreset( + capturePreset, role, typeAddresses.first, typeAddresses.second); + } + + /** + * @hide + * Set devices as role for capture preset. + * @param capturePreset the capture preset to configure + * @param role the role of the devices + * @param types all device types + * @param addresses all device addresses + * @return {@link #SUCCESS} if successfully set + */ + private static native int setDevicesRoleForCapturePreset( + int capturePreset, int role, @NonNull int[] types, @NonNull String[] addresses); + + /** + * @hide + * Add devices as role for capture preset. + * @param capturePreset the capture preset to configure + * @param role the role of the devices + * @param devices the list of devices to be added as role for the given capture preset + * @return {@link #SUCCESS} if successfully add + */ + public static int addDevicesRoleForCapturePreset( + int capturePreset, int role, @NonNull List<AudioDeviceAttributes> devices) { + if (devices.isEmpty()) { + return BAD_VALUE; + } + Pair<int[], String[]> typeAddresses = populateInputDevicesTypeAndAddress(devices); + return addDevicesRoleForCapturePreset( + capturePreset, role, typeAddresses.first, typeAddresses.second); + } + + /** + * @hide + * Add devices as role for capture preset. + * @param capturePreset the capture preset to configure + * @param role the role of the devices + * @param types all device types + * @param addresses all device addresses + * @return {@link #SUCCESS} if successfully set + */ + private static native int addDevicesRoleForCapturePreset( + int capturePreset, int role, @NonNull int[] types, @NonNull String[] addresses); + + /** + * @hide + * Remove devices as role for the capture preset + * @param capturePreset the capture preset to configure + * @param role the role of the devices + * @param devices the devices to be removed + * @return {@link #SUCCESS} if successfully removed + */ + public static int removeDevicesRoleForCapturePreset( + int capturePreset, int role, @NonNull List<AudioDeviceAttributes> devices) { + if (devices.isEmpty()) { + return BAD_VALUE; + } + Pair<int[], String[]> typeAddresses = populateInputDevicesTypeAndAddress(devices); + return removeDevicesRoleForCapturePreset( + capturePreset, role, typeAddresses.first, typeAddresses.second); + } + + /** + * @hide + * Remove devices as role for capture preset. + * @param capturePreset the capture preset to configure + * @param role the role of the devices + * @param types all device types + * @param addresses all device addresses + * @return {@link #SUCCESS} if successfully set + */ + private static native int removeDevicesRoleForCapturePreset( + int capturePreset, int role, @NonNull int[] types, @NonNull String[] addresses); + + /** + * @hide + * Remove all devices as role for the capture preset + * @param capturePreset the capture preset to configure + * @param role the role of the devices + * @return {@link #SUCCESS} if successfully removed + */ + public static native int clearDevicesRoleForCapturePreset(int capturePreset, int role); + + /** + * @hide + * Query previously set devices as role for a capture preset + * @param capturePreset the capture preset to query for + * @param role the role of the devices + * @param devices a list that will contain the devices of role + * @return {@link #SUCCESS} if there is a preferred device and it was successfully retrieved + * and written to the array + */ + public static native int getDevicesForRoleAndCapturePreset( + int capturePreset, int role, @NonNull List<AudioDeviceAttributes> devices); + // Items shared with audio service /** diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl index ef8b0edb1fe5..47e60000cd04 100755 --- a/media/java/android/media/IAudioService.aidl +++ b/media/java/android/media/IAudioService.aidl @@ -17,6 +17,7 @@ package android.media; import android.bluetooth.BluetoothDevice; +import android.content.ComponentName; import android.media.AudioAttributes; import android.media.AudioDeviceAttributes; import android.media.AudioFocusInfo; @@ -26,6 +27,7 @@ import android.media.AudioRoutesInfo; import android.media.IAudioFocusDispatcher; import android.media.IAudioRoutesObserver; import android.media.IAudioServerStateDispatcher; +import android.media.ICapturePresetDevicesRoleDispatcher; import android.media.IPlaybackConfigDispatcher; import android.media.IRecordingConfigDispatcher; import android.media.IRingtonePlayer; @@ -40,6 +42,7 @@ import android.media.audiopolicy.AudioVolumeGroup; import android.media.audiopolicy.IAudioPolicyCallback; import android.media.projection.IMediaProjection; import android.net.Uri; +import android.os.UserHandle; import android.view.KeyEvent; /** @@ -307,4 +310,28 @@ interface IAudioService { // code via IAudioManager.h need to be added to the top section. oneway void setMultiAudioFocusEnabled(in boolean enabled); + + int setPreferredDevicesForCapturePreset( + in int capturePreset, in List<AudioDeviceAttributes> devices); + + int clearPreferredDevicesForCapturePreset(in int capturePreset); + + List<AudioDeviceAttributes> getPreferredDevicesForCapturePreset(in int capturePreset); + + void registerCapturePresetDevicesRoleDispatcher(ICapturePresetDevicesRoleDispatcher dispatcher); + + oneway void unregisterCapturePresetDevicesRoleDispatcher( + ICapturePresetDevicesRoleDispatcher dispatcher); + + oneway void adjustStreamVolumeForUid(int streamType, int direction, int flags, + in String packageName, int uid, int pid, in UserHandle userHandle, + int targetSdkVersion); + + oneway void adjustSuggestedStreamVolumeForUid(int streamType, int direction, int flags, + in String packageName, int uid, int pid, in UserHandle userHandle, + int targetSdkVersion); + + oneway void setStreamVolumeForUid(int streamType, int direction, int flags, + in String packageName, int uid, int pid, in UserHandle userHandle, + int targetSdkVersion); } diff --git a/media/java/android/media/ICapturePresetDevicesRoleDispatcher.aidl b/media/java/android/media/ICapturePresetDevicesRoleDispatcher.aidl new file mode 100644 index 000000000000..5e03e632c4ff --- /dev/null +++ b/media/java/android/media/ICapturePresetDevicesRoleDispatcher.aidl @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2020 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.media.AudioDeviceAttributes; + +/** + * AIDL for AudioService to signal devices role for capture preset updates. + * + * {@hide} + */ +oneway interface ICapturePresetDevicesRoleDispatcher { + + void dispatchDevicesRoleChanged( + int capturePreset, int role, in List<AudioDeviceAttributes> devices); + +} diff --git a/media/java/android/media/MediaMetadata.java b/media/java/android/media/MediaMetadata.java index a23191f36efc..523a072b957a 100644 --- a/media/java/android/media/MediaMetadata.java +++ b/media/java/android/media/MediaMetadata.java @@ -15,8 +15,10 @@ */ package android.media; +import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.StringDef; +import android.annotation.SystemApi; import android.compat.annotation.UnsupportedAppUsage; import android.content.ContentResolver; import android.graphics.Bitmap; @@ -738,15 +740,16 @@ public final class MediaMetadata implements Parcelable { /** * Create a Builder using a {@link MediaMetadata} instance to set - * initial values, but replace bitmaps with a scaled down copy if they - * are larger than maxBitmapSize. + * initial values, but replace bitmaps with a scaled down copy if their width (or height) + * is larger than maxBitmapSize. * * @param source The original metadata to copy. * @param maxBitmapSize The maximum height/width for bitmaps contained * in the metadata. * @hide */ - public Builder(MediaMetadata source, int maxBitmapSize) { + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) + public Builder(@NonNull MediaMetadata source, @IntRange(from = 1) int maxBitmapSize) { this(source); for (String key : mBundle.keySet()) { Object value = mBundle.get(key); diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java index 4198d7917932..1db02beaea1a 100644 --- a/media/java/android/media/MediaRecorder.java +++ b/media/java/android/media/MediaRecorder.java @@ -404,6 +404,32 @@ public class MediaRecorder implements AudioRouting, } } + /** + * @hide + * @param source An audio source to test + * @return true if the source is a valid one + */ + public static boolean isValidAudioSource(int source) { + switch(source) { + case AudioSource.MIC: + case AudioSource.VOICE_UPLINK: + case AudioSource.VOICE_DOWNLINK: + case AudioSource.VOICE_CALL: + case AudioSource.CAMCORDER: + case AudioSource.VOICE_RECOGNITION: + case AudioSource.VOICE_COMMUNICATION: + case AudioSource.REMOTE_SUBMIX: + case AudioSource.UNPROCESSED: + case AudioSource.VOICE_PERFORMANCE: + case AudioSource.ECHO_REFERENCE: + case AudioSource.RADIO_TUNER: + case AudioSource.HOTWORD: + return true; + default: + return false; + } + } + /** @hide */ public static final String toLogFriendlyAudioSource(int source) { switch(source) { diff --git a/media/java/android/media/MediaTranscodeManager.java b/media/java/android/media/MediaTranscodeManager.java index 1c5288b04685..451677f6a8bc 100644 --- a/media/java/android/media/MediaTranscodeManager.java +++ b/media/java/android/media/MediaTranscodeManager.java @@ -27,6 +27,7 @@ import android.content.ContentResolver; import android.content.Context; import android.content.res.AssetFileDescriptor; import android.net.Uri; +import android.os.Bundle; import android.os.ParcelFileDescriptor; import android.os.RemoteException; import android.os.ServiceManager; @@ -814,6 +815,141 @@ public final class MediaTranscodeManager { return new TranscodingRequest(this); } } + + /** + * Helper class for deciding if transcoding is needed, and if so, the track + * formats to use. + */ + public static class MediaFormatResolver { + private static final int BIT_RATE = 20000000; // 20Mbps + + private MediaFormat mSrcVideoFormatHint; + private MediaFormat mSrcAudioFormatHint; + private Bundle mClientCaps; + + /** + * A key describing whether the client supports HEVC-encoded video. + * + * The value associated with this key is a boolean. If unspecified, it's up to + * the MediaFormatResolver to determine the default. + * + * @see #setClientCapabilities(Bundle) + */ + public static final String CAPS_SUPPORTS_HEVC = "support-hevc"; + + /** + * Sets the abilities of the client consuming the media. Must be called + * before {@link #shouldTranscode()} or {@link #resolveVideoFormat()}. + * + * @param clientCaps A Bundle object containing the client's capabilities, such as + * {@link #CAPS_SUPPORTS_HEVC}. + * @return the same VideoFormatResolver instance. + * @hide + */ + @NonNull + public MediaFormatResolver setClientCapabilities(@NonNull Bundle clientCaps) { + mClientCaps = clientCaps; + return this; + } + + /** + * Sets the video format hint about the source. Must be called before + * {@link #shouldTranscode()} or {@link #resolveVideoFormat()}. + * + * @param format A MediaFormat object containing information about the source's + * video track format that could affect the transcoding decision. + * Such information could include video codec types, color spaces, + * whether special format info (eg. slow-motion markers) are present, + * etc.. If a particular information is not present, it will not be + * used to make the decision. + * @return the same MediaFormatResolver instance. + */ + @NonNull + public MediaFormatResolver setSourceVideoFormatHint(@NonNull MediaFormat format) { + mSrcVideoFormatHint = format; + return this; + } + + /** + * Sets the audio format hint about the source. + * + * @param format A MediaFormat object containing information about the source's + * audio track format that could affect the transcoding decision. + * @return the same MediaFormatResolver instance. + * @hide + */ + @NonNull + public MediaFormatResolver setSourceAudioFormatHint(@NonNull MediaFormat format) { + mSrcAudioFormatHint = format; + return this; + } + + /** + * Returns whether the source content should be transcoded. + * + * @return true if the source should be transcoded. + * @throws UnsupportedOperationException if {@link #setClientCapabilities(Bundle)} + * or {@link #setSourceVideoFormatHint(MediaFormat)} was not called. + */ + public boolean shouldTranscode() { + if (mClientCaps == null) { + throw new UnsupportedOperationException( + "Client caps must be set!"); + } + // Video src hint must be provided, audio src hint is not used right now. + if (mSrcVideoFormatHint == null) { + throw new UnsupportedOperationException( + "Source video format hint must be set!"); + } + boolean supportHevc = mClientCaps.getBoolean(CAPS_SUPPORTS_HEVC, false); + if (!supportHevc && MediaFormat.MIMETYPE_VIDEO_HEVC.equals( + mSrcVideoFormatHint.getString(MediaFormat.KEY_MIME))) { + return true; + } + // TODO: add more checks as needed below. + return false; + } + + /** + * Retrieves the video track format to be used on + * {@link Builder#setVideoTrackFormat(MediaFormat)} for this configuration. + * + * @return the video track format to be used if transcoding should be performed, + * and null otherwise. + * @throws UnsupportedOperationException if {@link #setClientCapabilities(Bundle)} + * or {@link #setSourceVideoFormatHint(MediaFormat)} was not called. + */ + @Nullable + public MediaFormat resolveVideoFormat() { + if (!shouldTranscode()) { + return null; + } + // TODO(hkuang): Only modified the video codec type, and use fixed bitrate for now. + // May switch to transcoding profile when it's available. + MediaFormat videoTrackFormat = new MediaFormat(mSrcVideoFormatHint); + videoTrackFormat.setString(MediaFormat.KEY_MIME, MediaFormat.MIMETYPE_VIDEO_AVC); + videoTrackFormat.setInteger(MediaFormat.KEY_BIT_RATE, BIT_RATE); + return videoTrackFormat; + } + + /** + * Retrieves the audio track format to be used for transcoding. + * + * @return the audio track format to be used if transcoding should be performed, and + * null otherwise. + * @throws UnsupportedOperationException if {@link #setClientCapabilities(Bundle)} + * or {@link #setSourceVideoFormatHint(MediaFormat)} was not called. + * @hide + */ + @Nullable + public MediaFormat resolveAudioFormat() { + if (!shouldTranscode()) { + return null; + } + // Audio transcoding is not supported yet, always return null. + return null; + } + } } /** diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java index 549e79353133..624607b61b8f 100644 --- a/media/java/android/media/session/MediaSession.java +++ b/media/java/android/media/session/MediaSession.java @@ -828,9 +828,10 @@ public final class MediaSession { } /** - * Gets the UID of this token. + * Gets the UID of the application that created the media session. * @hide */ + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public int getUid() { return mUid; } diff --git a/media/tests/MediaTranscodingTest/src/com/android/mediatranscodingtest/MediaTranscodeManagerTest.java b/media/tests/MediaTranscodingTest/src/com/android/mediatranscodingtest/MediaTranscodeManagerTest.java index 1a3e3608f37f..33d6d64c7f37 100644 --- a/media/tests/MediaTranscodingTest/src/com/android/mediatranscodingtest/MediaTranscodeManagerTest.java +++ b/media/tests/MediaTranscodingTest/src/com/android/mediatranscodingtest/MediaTranscodeManagerTest.java @@ -24,6 +24,7 @@ import android.media.MediaFormat; import android.media.MediaTranscodeManager; import android.media.MediaTranscodeManager.TranscodingJob; import android.media.MediaTranscodeManager.TranscodingRequest; +import android.media.MediaTranscodeManager.TranscodingRequest.MediaFormatResolver; import android.media.TranscodingTestConfig; import android.net.Uri; import android.os.Bundle; @@ -414,17 +415,27 @@ public class MediaTranscodeManagerTest Uri destinationUri = Uri.parse(ContentResolver.SCHEME_FILE + "://" + mContext.getCacheDir().getAbsolutePath() + "/HevcTranscode.mp4"); + Bundle clientCaps = new Bundle(); + clientCaps.putBoolean(MediaFormatResolver.CAPS_SUPPORTS_HEVC, false); + MediaFormatResolver resolver = new MediaFormatResolver() + .setSourceVideoFormatHint(MediaFormat.createVideoFormat( + MediaFormat.MIMETYPE_VIDEO_HEVC, WIDTH, HEIGHT)) + .setClientCapabilities(clientCaps); + assertTrue(resolver.shouldTranscode()); + MediaFormat videoTrackFormat = resolver.resolveVideoFormat(); + assertNotNull(videoTrackFormat); + TranscodingRequest request = new TranscodingRequest.Builder() .setSourceUri(mSourceHEVCVideoUri) .setDestinationUri(destinationUri) .setType(MediaTranscodeManager.TRANSCODING_TYPE_VIDEO) .setPriority(MediaTranscodeManager.PRIORITY_REALTIME) - .setVideoTrackFormat(createMediaFormat()) + .setVideoTrackFormat(videoTrackFormat) .build(); Executor listenerExecutor = Executors.newSingleThreadExecutor(); - Log.i(TAG, "transcoding to " + createMediaFormat()); + Log.i(TAG, "transcoding to " + videoTrackFormat); TranscodingJob job = mMediaTranscodeManager.enqueueRequest(request, listenerExecutor, transcodingJob -> { diff --git a/non-updatable-api/module-lib-current.txt b/non-updatable-api/module-lib-current.txt index d4c5e7ea375d..f7f42d0a5956 100644 --- a/non-updatable-api/module-lib-current.txt +++ b/non-updatable-api/module-lib-current.txt @@ -35,9 +35,16 @@ package android.graphics { package android.media { public class AudioManager { + method public void adjustStreamVolumeForUid(int, int, int, @NonNull String, int, int, int); + method public void adjustSuggestedStreamVolumeForUid(int, int, int, @NonNull String, int, int, int); + method public void setStreamVolumeForUid(int, int, int, @NonNull String, int, int, int); field public static final int FLAG_FROM_KEY = 4096; // 0x1000 } + public static final class MediaMetadata.Builder { + ctor public MediaMetadata.Builder(@NonNull android.media.MediaMetadata, @IntRange(from=1) int); + } + } package android.media.session { @@ -50,6 +57,10 @@ package android.media.session { field public static final int FLAG_EXCLUSIVE_GLOBAL_PRIORITY = 65536; // 0x10000 } + public static final class MediaSession.Token implements android.os.Parcelable { + method public int getUid(); + } + public final class MediaSessionManager { method public void dispatchMediaKeyEventAsSystemService(@NonNull android.view.KeyEvent); method public boolean dispatchMediaKeyEventAsSystemService(@NonNull android.media.session.MediaSession.Token, @NonNull android.view.KeyEvent); diff --git a/non-updatable-api/system-current.txt b/non-updatable-api/system-current.txt index cc6c3dc97acf..b807d1be6bf0 100644 --- a/non-updatable-api/system-current.txt +++ b/non-updatable-api/system-current.txt @@ -205,6 +205,7 @@ package android { field public static final String REVOKE_RUNTIME_PERMISSIONS = "android.permission.REVOKE_RUNTIME_PERMISSIONS"; field public static final String SCORE_NETWORKS = "android.permission.SCORE_NETWORKS"; field public static final String SECURE_ELEMENT_PRIVILEGED_OPERATION = "android.permission.SECURE_ELEMENT_PRIVILEGED_OPERATION"; + field public static final String SEND_CATEGORY_CAR_NOTIFICATIONS = "android.permission.SEND_CATEGORY_CAR_NOTIFICATIONS"; field public static final String SEND_DEVICE_CUSTOMIZATION_READY = "android.permission.SEND_DEVICE_CUSTOMIZATION_READY"; field public static final String SEND_SHOW_SUSPENDED_APP_DETAILS = "android.permission.SEND_SHOW_SUSPENDED_APP_DETAILS"; field public static final String SEND_SMS_NO_CONFIRMATION = "android.permission.SEND_SMS_NO_CONFIRMATION"; @@ -4139,8 +4140,10 @@ package android.media { public class AudioManager { method @Deprecated public int abandonAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, android.media.AudioAttributes); method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void addOnPreferredDeviceForStrategyChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.OnPreferredDeviceForStrategyChangedListener) throws java.lang.SecurityException; + method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void addOnPreferredDevicesForCapturePresetChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.OnPreferredDevicesForCapturePresetChangedListener) throws java.lang.SecurityException; method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void addOnPreferredDevicesForStrategyChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.OnPreferredDevicesForStrategyChangedListener) throws java.lang.SecurityException; method public void clearAudioServerStateCallback(); + method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean clearPreferredDevicesForCapturePreset(int); method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int dispatchAudioFocusChange(@NonNull android.media.AudioFocusInfo, int, @NonNull android.media.audiopolicy.AudioPolicy); method @IntRange(from=0) public long getAdditionalOutputDeviceDelay(@NonNull android.media.AudioDeviceInfo); method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static java.util.List<android.media.audiopolicy.AudioProductStrategy> getAudioProductStrategies(); @@ -4151,6 +4154,7 @@ package android.media { method @IntRange(from=0) @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getMaxVolumeIndexForAttributes(@NonNull android.media.AudioAttributes); method @IntRange(from=0) @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getMinVolumeIndexForAttributes(@NonNull android.media.AudioAttributes); method @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public android.media.AudioDeviceAttributes getPreferredDeviceForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy); + method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public java.util.List<android.media.AudioDeviceAttributes> getPreferredDevicesForCapturePreset(int); method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public java.util.List<android.media.AudioDeviceAttributes> getPreferredDevicesForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy); method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int[] getSupportedSystemUsages(); method @IntRange(from=0) @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getVolumeIndexForAttributes(@NonNull android.media.AudioAttributes); @@ -4159,6 +4163,7 @@ package android.media { method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int registerAudioPolicy(@NonNull android.media.audiopolicy.AudioPolicy); method public void registerVolumeGroupCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.VolumeGroupCallback); method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void removeOnPreferredDeviceForStrategyChangedListener(@NonNull android.media.AudioManager.OnPreferredDeviceForStrategyChangedListener); + method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void removeOnPreferredDevicesForCapturePresetChangedListener(@NonNull android.media.AudioManager.OnPreferredDevicesForCapturePresetChangedListener); method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void removeOnPreferredDevicesForStrategyChangedListener(@NonNull android.media.AudioManager.OnPreferredDevicesForStrategyChangedListener); method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean removePreferredDeviceForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int requestAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, @NonNull android.media.AudioAttributes, int, int) throws java.lang.IllegalArgumentException; @@ -4168,6 +4173,7 @@ package android.media { method public void setAudioServerStateCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.AudioServerStateCallback); method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setDeviceVolumeBehavior(@NonNull android.media.AudioDeviceAttributes, int); method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setFocusRequestResult(@NonNull android.media.AudioFocusInfo, int, @NonNull android.media.audiopolicy.AudioPolicy); + method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean setPreferredDeviceForCapturePreset(int, @NonNull android.media.AudioDeviceAttributes); method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean setPreferredDeviceForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy, @NonNull android.media.AudioDeviceAttributes); method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean setPreferredDevicesForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy, @NonNull java.util.List<android.media.AudioDeviceAttributes>); method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setSupportedSystemUsages(@NonNull int[]); @@ -4197,6 +4203,10 @@ package android.media { method @Deprecated public void onPreferredDeviceForStrategyChanged(@NonNull android.media.audiopolicy.AudioProductStrategy, @Nullable android.media.AudioDeviceAttributes); } + public static interface AudioManager.OnPreferredDevicesForCapturePresetChangedListener { + method public void onPreferredDevicesForCapturePresetChanged(int, @NonNull java.util.List<android.media.AudioDeviceAttributes>); + } + public static interface AudioManager.OnPreferredDevicesForStrategyChangedListener { method public void onPreferredDevicesForStrategyChanged(@NonNull android.media.audiopolicy.AudioProductStrategy, @NonNull java.util.List<android.media.AudioDeviceAttributes>); } @@ -4325,6 +4335,14 @@ package android.media { method @NonNull public android.media.MediaTranscodeManager.TranscodingRequest.Builder setVideoTrackFormat(@NonNull android.media.MediaFormat); } + public static class MediaTranscodeManager.TranscodingRequest.MediaFormatResolver { + ctor public MediaTranscodeManager.TranscodingRequest.MediaFormatResolver(); + method @Nullable public android.media.MediaFormat resolveVideoFormat(); + method @NonNull public android.media.MediaTranscodeManager.TranscodingRequest.MediaFormatResolver setSourceVideoFormatHint(@NonNull android.media.MediaFormat); + method public boolean shouldTranscode(); + field public static final String CAPS_SUPPORTS_HEVC = "support-hevc"; + } + public class PlayerProxy { method public void pause(); method public void setPan(float); @@ -6795,6 +6813,8 @@ package android.net.wifi.nl80211 { field public static final int BSS_CAPABILITY_CF_POLL_REQUEST = 8; // 0x8 field public static final int BSS_CAPABILITY_CHANNEL_AGILITY = 128; // 0x80 field public static final int BSS_CAPABILITY_DELAYED_BLOCK_ACK = 16384; // 0x4000 + field public static final int BSS_CAPABILITY_DMG_ESS = 3; // 0x3 + field public static final int BSS_CAPABILITY_DMG_IBSS = 1; // 0x1 field public static final int BSS_CAPABILITY_DSSS_OFDM = 8192; // 0x2000 field public static final int BSS_CAPABILITY_ESS = 1; // 0x1 field public static final int BSS_CAPABILITY_IBSS = 2; // 0x2 @@ -6864,7 +6884,7 @@ package android.net.wifi.nl80211 { method @NonNull public java.util.List<android.net.wifi.nl80211.NativeScanResult> getScanResults(@NonNull String, int); method @Nullable public android.net.wifi.nl80211.WifiNl80211Manager.TxPacketCounters getTxPacketCounters(@NonNull String); method @Nullable public static android.net.wifi.nl80211.WifiNl80211Manager.OemSecurityType parseOemSecurityTypeElement(int, int, @NonNull byte[]); - method public boolean registerApCallback(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.nl80211.WifiNl80211Manager.SoftApCallback); + method @Deprecated public boolean registerApCallback(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.nl80211.WifiNl80211Manager.SoftApCallback); method public void sendMgmtFrame(@NonNull String, @NonNull byte[], int, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.nl80211.WifiNl80211Manager.SendMgmtFrameCallback); method public void setOnServiceDeadCallback(@NonNull Runnable); method public boolean setupInterfaceForClientMode(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.nl80211.WifiNl80211Manager.ScanEventCallback, @NonNull android.net.wifi.nl80211.WifiNl80211Manager.ScanEventCallback); @@ -6915,10 +6935,10 @@ package android.net.wifi.nl80211 { field public final int txBitrateMbps; } - public static interface WifiNl80211Manager.SoftApCallback { - method public void onConnectedClientsChanged(@NonNull android.net.wifi.nl80211.NativeWifiClient, boolean); - method public void onFailure(); - method public void onSoftApChannelSwitched(int, int); + @Deprecated public static interface WifiNl80211Manager.SoftApCallback { + method @Deprecated public void onConnectedClientsChanged(@NonNull android.net.wifi.nl80211.NativeWifiClient, boolean); + method @Deprecated public void onFailure(); + method @Deprecated public void onSoftApChannelSwitched(int, int); } public static class WifiNl80211Manager.TxPacketCounters { diff --git a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/ButtonSelectionStateController.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/ButtonSelectionStateController.java index aa6da89e2864..2dc475682fac 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/ButtonSelectionStateController.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/ButtonSelectionStateController.java @@ -16,7 +16,7 @@ package com.android.systemui.car.navigationbar; -import android.app.ActivityManager; +import android.app.ActivityTaskManager.RootTaskInfo; import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -97,27 +97,27 @@ public class ButtonSelectionStateController { * The StackInfo is expected to be supplied in order of recency and StackInfo will only be used * for consideration if it has the same displayId as the CarNavigationButton. * - * @param stackInfoList of the currently running application + * @param taskInfoList of the currently running application * @param validDisplay index of the valid display */ - protected void taskChanged(List<ActivityManager.StackInfo> stackInfoList, int validDisplay) { - ActivityManager.StackInfo validStackInfo = null; - for (ActivityManager.StackInfo stackInfo : stackInfoList) { + protected void taskChanged(List<RootTaskInfo> taskInfoList, int validDisplay) { + RootTaskInfo validTaskInfo = null; + for (RootTaskInfo taskInfo : taskInfoList) { // Find the first stack info with a topActivity in the primary display. // TODO: We assume that CarFacetButton will launch an app only in the primary display. // We need to extend the functionality to handle the multiple display properly. - if (stackInfo.topActivity != null && stackInfo.displayId == validDisplay) { - validStackInfo = stackInfo; + if (taskInfo.topActivity != null && taskInfo.displayId == validDisplay) { + validTaskInfo = taskInfo; break; } } - if (validStackInfo == null) { + if (validTaskInfo == null) { // No stack was found that was on the same display as the buttons thus return return; } - int displayId = validStackInfo.displayId; + int displayId = validTaskInfo.displayId; mSelectedButtons.forEach(carNavigationButton -> { if (carNavigationButton.getDisplayId() == displayId) { @@ -126,7 +126,7 @@ public class ButtonSelectionStateController { }); mSelectedButtons.clear(); - HashSet<CarNavigationButton> selectedButtons = findSelectedButtons(validStackInfo); + HashSet<CarNavigationButton> selectedButtons = findSelectedButtons(validTaskInfo); if (selectedButtons != null) { selectedButtons.forEach(carNavigationButton -> { @@ -141,10 +141,10 @@ public class ButtonSelectionStateController { /** * Defaults to Display.DEFAULT_DISPLAY when no parameter is provided for the validDisplay. * - * @param stackInfoList + * @param taskInfoList */ - protected void taskChanged(List<ActivityManager.StackInfo> stackInfoList) { - taskChanged(stackInfoList, Display.DEFAULT_DISPLAY); + protected void taskChanged(List<RootTaskInfo> taskInfoList) { + taskChanged(taskInfoList, Display.DEFAULT_DISPLAY); } /** @@ -171,12 +171,11 @@ public class ButtonSelectionStateController { mRegisteredViews.add(carNavigationButton); } - private HashSet<CarNavigationButton> findSelectedButtons( - ActivityManager.StackInfo validStackInfo) { - String packageName = validStackInfo.topActivity.getPackageName(); + private HashSet<CarNavigationButton> findSelectedButtons(RootTaskInfo validTaskInfo) { + String packageName = validTaskInfo.topActivity.getPackageName(); HashSet<CarNavigationButton> selectedButtons = - findButtonsByComponentName(validStackInfo.topActivity); + findButtonsByComponentName(validTaskInfo.topActivity); if (selectedButtons == null) { selectedButtons = mButtonsByPackage.get(packageName); } diff --git a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/ButtonSelectionStateListener.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/ButtonSelectionStateListener.java index d6216ba87d95..f74bd4fce312 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/ButtonSelectionStateListener.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/ButtonSelectionStateListener.java @@ -43,9 +43,9 @@ class ButtonSelectionStateListener extends TaskStackChangeListener { public void onTaskStackChanged() { try { mButtonSelectionStateController.taskChanged( - ActivityTaskManager.getService().getAllStackInfos()); + ActivityTaskManager.getService().getAllRootTaskInfos()); } catch (Exception e) { - Log.e(TAG, "Getting StackInfo from activity manager failed", e); + Log.e(TAG, "Getting RootTaskInfo from activity task manager failed", e); } } @@ -53,9 +53,9 @@ class ButtonSelectionStateListener extends TaskStackChangeListener { public void onTaskDisplayChanged(int taskId, int newDisplayId) { try { mButtonSelectionStateController.taskChanged( - ActivityTaskManager.getService().getAllStackInfos()); + ActivityTaskManager.getService().getAllRootTaskInfos()); } catch (Exception e) { - Log.e(TAG, "Getting StackInfo from activity manager failed", e); + Log.e(TAG, "Getting RootTaskInfo from activity task manager failed", e); } } diff --git a/packages/CarSystemUI/src/com/android/systemui/car/sideloaded/SideLoadedAppDetector.java b/packages/CarSystemUI/src/com/android/systemui/car/sideloaded/SideLoadedAppDetector.java index eb32edb27196..f96ee0f73dc0 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/sideloaded/SideLoadedAppDetector.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/sideloaded/SideLoadedAppDetector.java @@ -17,7 +17,7 @@ package com.android.systemui.car.sideloaded; import android.annotation.NonNull; -import android.app.ActivityManager; +import android.app.ActivityTaskManager.RootTaskInfo; import android.content.ComponentName; import android.content.pm.ApplicationInfo; import android.content.pm.InstallSourceInfo; @@ -78,10 +78,10 @@ public class SideLoadedAppDetector { return false; } - boolean isSafe(@NonNull ActivityManager.StackInfo stackInfo) { - ComponentName componentName = stackInfo.topActivity; + boolean isSafe(@NonNull RootTaskInfo taskInfo) { + ComponentName componentName = taskInfo.topActivity; if (componentName == null) { - Log.w(TAG, "Stack info does not have top activity: " + stackInfo.stackId); + Log.w(TAG, "Task info does not have top activity: " + taskInfo.taskId); return false; } return isSafe(componentName.getPackageName()); diff --git a/packages/CarSystemUI/src/com/android/systemui/car/sideloaded/SideLoadedAppListener.java b/packages/CarSystemUI/src/com/android/systemui/car/sideloaded/SideLoadedAppListener.java index c8c1a40b8032..db7718bc166b 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/sideloaded/SideLoadedAppListener.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/sideloaded/SideLoadedAppListener.java @@ -16,8 +16,7 @@ package com.android.systemui.car.sideloaded; -import android.app.ActivityManager; -import android.app.ActivityManager.StackInfo; +import android.app.ActivityTaskManager.RootTaskInfo; import android.app.IActivityTaskManager; import android.app.TaskStackListener; import android.content.ComponentName; @@ -56,15 +55,15 @@ public class SideLoadedAppListener extends TaskStackListener { public void onTaskCreated(int taskId, ComponentName componentName) throws RemoteException { super.onTaskCreated(taskId, componentName); - List<StackInfo> stackInfoList = mActivityTaskManager.getAllStackInfos(); - ActivityManager.StackInfo stackInfo = getStackInfo(stackInfoList, taskId); - if (stackInfo == null) { + List<RootTaskInfo> taskInfoList = mActivityTaskManager.getAllRootTaskInfos(); + RootTaskInfo taskInfo = getStackInfo(taskInfoList, taskId); + if (taskInfo == null) { Log.e(TAG, "Stack info was not available for taskId: " + taskId); return; } - if (!mSideLoadedAppDetector.isSafe(stackInfo)) { - Display display = mDisplayManager.getDisplay(stackInfo.displayId); + if (!mSideLoadedAppDetector.isSafe(taskInfo)) { + Display display = mDisplayManager.getDisplay(taskInfo.displayId); mSideLoadedAppStateController.onUnsafeTaskCreatedOnDisplay(display); } } @@ -75,18 +74,18 @@ public class SideLoadedAppListener extends TaskStackListener { Display[] displays = mDisplayManager.getDisplays(); for (Display display : displays) { - // Note that the stackInfoList is ordered by recency. - List<StackInfo> stackInfoList = - mActivityTaskManager.getAllStackInfosOnDisplay(display.getDisplayId()); + // Note that the taskInfoList is ordered by recency. + List<RootTaskInfo> taskInfoList = + mActivityTaskManager.getAllRootTaskInfosOnDisplay(display.getDisplayId()); - if (stackInfoList == null) { + if (taskInfoList == null) { continue; } - StackInfo stackInfo = getTopVisibleStackInfo(stackInfoList); - if (stackInfo == null) { + RootTaskInfo taskInfo = getTopVisibleStackInfo(taskInfoList); + if (taskInfo == null) { continue; } - if (mSideLoadedAppDetector.isSafe(stackInfo)) { + if (mSideLoadedAppDetector.isSafe(taskInfo)) { mSideLoadedAppStateController.onSafeTaskDisplayedOnDisplay(display); } else { mSideLoadedAppStateController.onUnsafeTaskDisplayedOnDisplay(display); @@ -97,18 +96,17 @@ public class SideLoadedAppListener extends TaskStackListener { /** * Returns stack info for a given taskId. */ - private ActivityManager.StackInfo getStackInfo( - List<ActivityManager.StackInfo> stackInfoList, int taskId) { - if (stackInfoList == null) { + private RootTaskInfo getStackInfo(List<RootTaskInfo> taskInfoList, int taskId) { + if (taskInfoList == null) { return null; } - for (ActivityManager.StackInfo stackInfo : stackInfoList) { - if (stackInfo.taskIds == null) { + for (RootTaskInfo taskInfo : taskInfoList) { + if (taskInfo.childTaskIds == null) { continue; } - for (int stackTaskId : stackInfo.taskIds) { - if (taskId == stackTaskId) { - return stackInfo; + for (int taskTaskId : taskInfo.childTaskIds) { + if (taskId == taskTaskId) { + return taskInfo; } } } @@ -118,11 +116,10 @@ public class SideLoadedAppListener extends TaskStackListener { /** * Returns the first visible stackInfo. */ - private ActivityManager.StackInfo getTopVisibleStackInfo( - List<ActivityManager.StackInfo> stackInfoList) { - for (ActivityManager.StackInfo stackInfo : stackInfoList) { - if (stackInfo.visible) { - return stackInfo; + private RootTaskInfo getTopVisibleStackInfo(List<RootTaskInfo> taskInfoList) { + for (RootTaskInfo taskInfo : taskInfoList) { + if (taskInfo.visible) { + return taskInfo; } } return null; diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/ButtonSelectionStateControllerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/ButtonSelectionStateControllerTest.java index f623c26d12b6..bd017cd2835b 100644 --- a/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/ButtonSelectionStateControllerTest.java +++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/ButtonSelectionStateControllerTest.java @@ -18,7 +18,7 @@ package com.android.systemui.car.navigationbar; import static com.google.common.truth.Truth.assertThat; -import android.app.ActivityManager; +import android.app.ActivityTaskManager.RootTaskInfo; import android.content.ComponentName; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; @@ -71,7 +71,7 @@ public class ButtonSelectionStateControllerTest extends SysuiTestCase { public void onTaskChanged_buttonDetectableByComponentName_selectsAssociatedButton() { CarNavigationButton testButton = mTestView.findViewById(R.id.detectable_by_component_name); mComponentName = new ComponentName(TEST_COMPONENT_NAME_PACKAGE, TEST_COMPONENT_NAME_CLASS); - List<ActivityManager.StackInfo> testStack = createTestStack(mComponentName); + List<RootTaskInfo> testStack = createTestStack(mComponentName); testButton.setSelected(false); mButtonSelectionStateController.taskChanged(testStack, /* validDisplay= */ -1); @@ -82,7 +82,7 @@ public class ButtonSelectionStateControllerTest extends SysuiTestCase { public void onTaskChanged_buttonDetectableByCategory_selectsAssociatedButton() { CarNavigationButton testButton = mTestView.findViewById(R.id.detectable_by_category); mComponentName = new ComponentName(TEST_CATEGORY, TEST_CATEGORY_CLASS); - List<ActivityManager.StackInfo> testStack = createTestStack(mComponentName); + List<RootTaskInfo> testStack = createTestStack(mComponentName); testButton.setSelected(false); mButtonSelectionStateController.taskChanged(testStack, /* validDisplay= */ -1); @@ -93,7 +93,7 @@ public class ButtonSelectionStateControllerTest extends SysuiTestCase { public void onTaskChanged_buttonDetectableByPackage_selectsAssociatedButton() { CarNavigationButton testButton = mTestView.findViewById(R.id.detectable_by_package); mComponentName = new ComponentName(TEST_PACKAGE, TEST_PACKAGE_CLASS); - List<ActivityManager.StackInfo> testStack = createTestStack(mComponentName); + List<RootTaskInfo> testStack = createTestStack(mComponentName); testButton.setSelected(false); mButtonSelectionStateController.taskChanged(testStack, /* validDisplay= */ -1); @@ -104,12 +104,12 @@ public class ButtonSelectionStateControllerTest extends SysuiTestCase { public void onTaskChanged_deselectsPreviouslySelectedButton() { CarNavigationButton oldButton = mTestView.findViewById(R.id.detectable_by_component_name); mComponentName = new ComponentName(TEST_COMPONENT_NAME_PACKAGE, TEST_COMPONENT_NAME_CLASS); - List<ActivityManager.StackInfo> oldStack = createTestStack(mComponentName); + List<RootTaskInfo> oldStack = createTestStack(mComponentName); oldButton.setSelected(false); mButtonSelectionStateController.taskChanged(oldStack, /* validDisplay= */ -1); mComponentName = new ComponentName(TEST_PACKAGE, TEST_PACKAGE_CLASS); - List<ActivityManager.StackInfo> newStack = createTestStack(mComponentName); + List<RootTaskInfo> newStack = createTestStack(mComponentName); mButtonSelectionStateController.taskChanged(newStack, /* validDisplay= */ -1); assertButtonUnselected(oldButton); @@ -125,12 +125,12 @@ public class ButtonSelectionStateControllerTest extends SysuiTestCase { assertThat(button.getAlpha()).isEqualTo(CarNavigationButton.DEFAULT_UNSELECTED_ALPHA); } - private List<ActivityManager.StackInfo> createTestStack(ComponentName componentName) { - ActivityManager.StackInfo validStackInfo = new ActivityManager.StackInfo(); + private List<RootTaskInfo> createTestStack(ComponentName componentName) { + RootTaskInfo validStackInfo = new RootTaskInfo(); validStackInfo.displayId = -1; // No display is assigned to this test view validStackInfo.topActivity = componentName; - List<ActivityManager.StackInfo> testStack = new ArrayList<>(); + List<RootTaskInfo> testStack = new ArrayList<>(); testStack.add(validStackInfo); return testStack; diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/sideloaded/SideLoadedAppDetectorTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/sideloaded/SideLoadedAppDetectorTest.java index 421e2109356d..bf9ac3017436 100644 --- a/packages/CarSystemUI/tests/src/com/android/systemui/car/sideloaded/SideLoadedAppDetectorTest.java +++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/sideloaded/SideLoadedAppDetectorTest.java @@ -23,7 +23,7 @@ import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.when; -import android.app.ActivityManager; +import android.app.ActivityTaskManager.RootTaskInfo; import android.content.ComponentName; import android.content.pm.ApplicationInfo; import android.content.pm.InstallSourceInfo; @@ -79,8 +79,8 @@ public class SideLoadedAppDetectorTest extends SysuiTestCase { @Test public void isSafe_systemApp_returnsTrue() throws Exception { - ActivityManager.StackInfo stackInfo = new ActivityManager.StackInfo(); - stackInfo.topActivity = new ComponentName(APP_PACKAGE_NAME, APP_CLASS_NAME); + RootTaskInfo taskInfo = new RootTaskInfo(); + taskInfo.topActivity = new ComponentName(APP_PACKAGE_NAME, APP_CLASS_NAME); ApplicationInfo applicationInfo = new ApplicationInfo(); applicationInfo.packageName = APP_PACKAGE_NAME; @@ -89,13 +89,13 @@ public class SideLoadedAppDetectorTest extends SysuiTestCase { when(mPackageManager.getApplicationInfoAsUser(eq(APP_PACKAGE_NAME), anyInt(), any())) .thenReturn(applicationInfo); - assertThat(mSideLoadedAppDetector.isSafe(stackInfo)).isTrue(); + assertThat(mSideLoadedAppDetector.isSafe(taskInfo)).isTrue(); } @Test public void isSafe_updatedSystemApp_returnsTrue() throws Exception { - ActivityManager.StackInfo stackInfo = new ActivityManager.StackInfo(); - stackInfo.topActivity = new ComponentName(APP_PACKAGE_NAME, APP_CLASS_NAME); + RootTaskInfo taskInfo = new RootTaskInfo(); + taskInfo.topActivity = new ComponentName(APP_PACKAGE_NAME, APP_CLASS_NAME); ApplicationInfo applicationInfo = new ApplicationInfo(); applicationInfo.packageName = APP_PACKAGE_NAME; @@ -104,7 +104,7 @@ public class SideLoadedAppDetectorTest extends SysuiTestCase { when(mPackageManager.getApplicationInfoAsUser(eq(APP_PACKAGE_NAME), anyInt(), any())) .thenReturn(applicationInfo); - assertThat(mSideLoadedAppDetector.isSafe(stackInfo)).isTrue(); + assertThat(mSideLoadedAppDetector.isSafe(taskInfo)).isTrue(); } @Test @@ -113,8 +113,8 @@ public class SideLoadedAppDetectorTest extends SysuiTestCase { /* initiatingPackageSigningInfo= */null, /* originatingPackageName= */ null, /* installingPackageName= */ null); - ActivityManager.StackInfo stackInfo = new ActivityManager.StackInfo(); - stackInfo.topActivity = new ComponentName(APP_PACKAGE_NAME, APP_CLASS_NAME); + RootTaskInfo taskInfo = new RootTaskInfo(); + taskInfo.topActivity = new ComponentName(APP_PACKAGE_NAME, APP_CLASS_NAME); ApplicationInfo applicationInfo = new ApplicationInfo(); applicationInfo.packageName = APP_PACKAGE_NAME; @@ -123,7 +123,7 @@ public class SideLoadedAppDetectorTest extends SysuiTestCase { .thenReturn(applicationInfo); when(mPackageManager.getInstallSourceInfo(APP_PACKAGE_NAME)).thenReturn(sourceInfo); - assertThat(mSideLoadedAppDetector.isSafe(stackInfo)).isTrue(); + assertThat(mSideLoadedAppDetector.isSafe(taskInfo)).isTrue(); } @Test @@ -132,8 +132,8 @@ public class SideLoadedAppDetectorTest extends SysuiTestCase { /* initiatingPackageSigningInfo= */null, /* originatingPackageName= */ null, /* installingPackageName= */ null); - ActivityManager.StackInfo stackInfo = new ActivityManager.StackInfo(); - stackInfo.topActivity = new ComponentName(APP_PACKAGE_NAME, APP_CLASS_NAME); + RootTaskInfo taskInfo = new RootTaskInfo(); + taskInfo.topActivity = new ComponentName(APP_PACKAGE_NAME, APP_CLASS_NAME); ApplicationInfo applicationInfo = new ApplicationInfo(); applicationInfo.packageName = APP_PACKAGE_NAME; @@ -142,7 +142,7 @@ public class SideLoadedAppDetectorTest extends SysuiTestCase { .thenReturn(applicationInfo); when(mPackageManager.getInstallSourceInfo(APP_PACKAGE_NAME)).thenReturn(sourceInfo); - assertThat(mSideLoadedAppDetector.isSafe(stackInfo)).isFalse(); + assertThat(mSideLoadedAppDetector.isSafe(taskInfo)).isFalse(); } @Test @@ -151,8 +151,8 @@ public class SideLoadedAppDetectorTest extends SysuiTestCase { /* initiatingPackageSigningInfo= */null, /* originatingPackageName= */ null, /* installingPackageName= */ null); - ActivityManager.StackInfo stackInfo = new ActivityManager.StackInfo(); - stackInfo.topActivity = new ComponentName(APP_PACKAGE_NAME, APP_CLASS_NAME); + RootTaskInfo taskInfo = new RootTaskInfo(); + taskInfo.topActivity = new ComponentName(APP_PACKAGE_NAME, APP_CLASS_NAME); ApplicationInfo applicationInfo = new ApplicationInfo(); applicationInfo.packageName = APP_PACKAGE_NAME; @@ -161,6 +161,6 @@ public class SideLoadedAppDetectorTest extends SysuiTestCase { .thenReturn(applicationInfo); when(mPackageManager.getInstallSourceInfo(APP_PACKAGE_NAME)).thenReturn(sourceInfo); - assertThat(mSideLoadedAppDetector.isSafe(stackInfo)).isFalse(); + assertThat(mSideLoadedAppDetector.isSafe(taskInfo)).isFalse(); } } diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/sideloaded/SideLoadedAppListenerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/sideloaded/SideLoadedAppListenerTest.java index 67f222b9e29a..0b5f68f76ebc 100644 --- a/packages/CarSystemUI/tests/src/com/android/systemui/car/sideloaded/SideLoadedAppListenerTest.java +++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/sideloaded/SideLoadedAppListenerTest.java @@ -21,7 +21,7 @@ import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import android.app.ActivityManager.StackInfo; +import android.app.ActivityTaskManager.RootTaskInfo; import android.app.IActivityTaskManager; import android.content.ComponentName; import android.hardware.display.DisplayManager; @@ -81,22 +81,22 @@ public class SideLoadedAppListenerTest extends SysuiTestCase { int displayId = 123; ComponentName componentName = new ComponentName(APP_PACKAGE_NAME, APP_CLASS_NAME); - StackInfo stackInfo1 = createTask(1, /* isVisible= */ true); - stackInfo1.taskIds = new int[] { 11, 22, 33 }; + RootTaskInfo taskInfo1 = createTask(1, /* isVisible= */ true); + taskInfo1.childTaskIds = new int[] { 11, 22, 33 }; - StackInfo stackInfo2 = createTask(2, /* isVisible= */ true); - stackInfo2.taskIds = new int[] { 111, 222, 333, taskId }; - stackInfo2.displayId = displayId; + RootTaskInfo taskInfo2 = createTask(2, /* isVisible= */ true); + taskInfo2.childTaskIds = new int[] { 111, 222, 333, taskId }; + taskInfo2.displayId = displayId; - List<StackInfo> stackInfoList = Arrays.asList(stackInfo1, stackInfo2); + List<RootTaskInfo> taskInfoList = Arrays.asList(taskInfo1, taskInfo2); - when(mActivityTaskManager.getAllStackInfos()).thenReturn(stackInfoList); - when(mSideLoadedAppDetector.isSafe(stackInfo2)).thenReturn(true); + when(mActivityTaskManager.getAllRootTaskInfos()).thenReturn(taskInfoList); + when(mSideLoadedAppDetector.isSafe(taskInfo2)).thenReturn(true); mSideLoadedAppListener.onTaskCreated(taskId, componentName); - verify(mSideLoadedAppDetector, never()).isSafe(stackInfo1); - verify(mSideLoadedAppDetector).isSafe(stackInfo2); + verify(mSideLoadedAppDetector, never()).isSafe(taskInfo1); + verify(mSideLoadedAppDetector).isSafe(taskInfo2); verify(mSideLoadedAppStateController, never()).onUnsafeTaskCreatedOnDisplay(any()); verify(mSideLoadedAppStateController, never()).onSafeTaskDisplayedOnDisplay(any()); @@ -109,23 +109,23 @@ public class SideLoadedAppListenerTest extends SysuiTestCase { int displayId = 123; ComponentName componentName = new ComponentName(APP_PACKAGE_NAME, APP_CLASS_NAME); - StackInfo stackInfo1 = createTask(1, /* isVisible= */ true); - stackInfo1.taskIds = new int[] { 11, 22, 33 }; - StackInfo stackInfo2 = createTask(2, /* isVisible= */ true); - stackInfo2.taskIds = new int[] { 111, 222, 333, taskId }; - stackInfo2.displayId = displayId; - List<StackInfo> stackInfoList = Arrays.asList(stackInfo1, stackInfo2); + RootTaskInfo taskInfo1 = createTask(1, /* isVisible= */ true); + taskInfo1.childTaskIds = new int[] { 11, 22, 33 }; + RootTaskInfo taskInfo2 = createTask(2, /* isVisible= */ true); + taskInfo2.childTaskIds = new int[] { 111, 222, 333, taskId }; + taskInfo2.displayId = displayId; + List<RootTaskInfo> taskInfoList = Arrays.asList(taskInfo1, taskInfo2); Display display = createDisplay(displayId); - when(mActivityTaskManager.getAllStackInfos()).thenReturn(stackInfoList); - when(mSideLoadedAppDetector.isSafe(stackInfo2)).thenReturn(false); + when(mActivityTaskManager.getAllRootTaskInfos()).thenReturn(taskInfoList); + when(mSideLoadedAppDetector.isSafe(taskInfo2)).thenReturn(false); when(mDisplayManager.getDisplay(displayId)).thenReturn(display); mSideLoadedAppListener.onTaskCreated(taskId, componentName); - verify(mSideLoadedAppDetector, never()).isSafe(stackInfo1); - verify(mSideLoadedAppDetector).isSafe(stackInfo2); + verify(mSideLoadedAppDetector, never()).isSafe(taskInfo1); + verify(mSideLoadedAppDetector).isSafe(taskInfo2); verify(mSideLoadedAppStateController).onUnsafeTaskCreatedOnDisplay(display); verify(mSideLoadedAppStateController, never()).onSafeTaskDisplayedOnDisplay(any()); @@ -135,21 +135,21 @@ public class SideLoadedAppListenerTest extends SysuiTestCase { @Test public void onTaskStackChanged_safeTask_callsSafeTaskDisplayed() throws Exception { Display display = createDisplay(123); - StackInfo stackInfo1 = createTask(1, /* isVisible= */ false); - StackInfo stackInfo2 = createTask(2, /* isVisible= */ true); - StackInfo stackInfo3 = createTask(3, /* isVisible= */ true); - List<StackInfo> stackInfoList = Arrays.asList(stackInfo1, stackInfo2, stackInfo3); - - when(mActivityTaskManager.getAllStackInfosOnDisplay(display.getDisplayId())) - .thenReturn(stackInfoList); - when(mSideLoadedAppDetector.isSafe(stackInfo2)).thenReturn(true); + RootTaskInfo taskInfo1 = createTask(1, /* isVisible= */ false); + RootTaskInfo taskInfo2 = createTask(2, /* isVisible= */ true); + RootTaskInfo taskInfo3 = createTask(3, /* isVisible= */ true); + List<RootTaskInfo> taskInfoList = Arrays.asList(taskInfo1, taskInfo2, taskInfo3); + + when(mActivityTaskManager.getAllRootTaskInfosOnDisplay(display.getDisplayId())) + .thenReturn(taskInfoList); + when(mSideLoadedAppDetector.isSafe(taskInfo2)).thenReturn(true); when(mDisplayManager.getDisplays()).thenReturn(new Display[] { display }); mSideLoadedAppListener.onTaskStackChanged(); - verify(mSideLoadedAppDetector, never()).isSafe(stackInfo1); - verify(mSideLoadedAppDetector).isSafe(stackInfo2); - verify(mSideLoadedAppDetector, never()).isSafe(stackInfo3); + verify(mSideLoadedAppDetector, never()).isSafe(taskInfo1); + verify(mSideLoadedAppDetector).isSafe(taskInfo2); + verify(mSideLoadedAppDetector, never()).isSafe(taskInfo3); verify(mSideLoadedAppStateController, never()).onUnsafeTaskCreatedOnDisplay(any()); verify(mSideLoadedAppStateController).onSafeTaskDisplayedOnDisplay(display); @@ -159,21 +159,21 @@ public class SideLoadedAppListenerTest extends SysuiTestCase { @Test public void onTaskStackChanged_unsafeTask_callsUnsafeTaskDisplayed() throws Exception { Display display = createDisplay(123); - StackInfo stackInfo1 = createTask(1, /* isVisible= */ false); - StackInfo stackInfo2 = createTask(2, /* isVisible= */ true); - StackInfo stackInfo3 = createTask(3, /* isVisible= */ true); - List<StackInfo> stackInfoList = Arrays.asList(stackInfo1, stackInfo2, stackInfo3); - - when(mActivityTaskManager.getAllStackInfosOnDisplay(display.getDisplayId())) - .thenReturn(stackInfoList); - when(mSideLoadedAppDetector.isSafe(stackInfo2)).thenReturn(false); + RootTaskInfo taskInfo1 = createTask(1, /* isVisible= */ false); + RootTaskInfo taskInfo2 = createTask(2, /* isVisible= */ true); + RootTaskInfo taskInfo3 = createTask(3, /* isVisible= */ true); + List<RootTaskInfo> taskInfoList = Arrays.asList(taskInfo1, taskInfo2, taskInfo3); + + when(mActivityTaskManager.getAllRootTaskInfosOnDisplay(display.getDisplayId())) + .thenReturn(taskInfoList); + when(mSideLoadedAppDetector.isSafe(taskInfo2)).thenReturn(false); when(mDisplayManager.getDisplays()).thenReturn(new Display[] { display }); mSideLoadedAppListener.onTaskStackChanged(); - verify(mSideLoadedAppDetector, never()).isSafe(stackInfo1); - verify(mSideLoadedAppDetector).isSafe(stackInfo2); - verify(mSideLoadedAppDetector, never()).isSafe(stackInfo3); + verify(mSideLoadedAppDetector, never()).isSafe(taskInfo1); + verify(mSideLoadedAppDetector).isSafe(taskInfo2); + verify(mSideLoadedAppDetector, never()).isSafe(taskInfo3); verify(mSideLoadedAppStateController, never()).onUnsafeTaskCreatedOnDisplay(any()); verify(mSideLoadedAppStateController, never()).onSafeTaskDisplayedOnDisplay(any()); @@ -183,40 +183,40 @@ public class SideLoadedAppListenerTest extends SysuiTestCase { @Test public void onTaskStackChanged_multiDisplay_callsTasksDisplayed() throws Exception { Display display1 = createDisplay(1); - StackInfo stackInfo1 = createTask(1, /* isVisible= */ false); - StackInfo stackInfo2 = createTask(2, /* isVisible= */ true); - StackInfo stackInfo3 = createTask(3, /* isVisible= */ true); - List<StackInfo> display1Stack = Arrays.asList(stackInfo1, stackInfo2, stackInfo3); + RootTaskInfo taskInfo1 = createTask(1, /* isVisible= */ false); + RootTaskInfo taskInfo2 = createTask(2, /* isVisible= */ true); + RootTaskInfo taskInfo3 = createTask(3, /* isVisible= */ true); + List<RootTaskInfo> display1Tasks = Arrays.asList(taskInfo1, taskInfo2, taskInfo3); Display display2 = createDisplay(2); - StackInfo stackInfo4 = createTask(4, /* isVisible= */ true); - List<StackInfo> display2Stack = Collections.singletonList(stackInfo4); + RootTaskInfo taskInfo4 = createTask(4, /* isVisible= */ true); + List<RootTaskInfo> display2Tasks = Collections.singletonList(taskInfo4); Display display3 = createDisplay(3); - StackInfo stackInfo5 = createTask(5, /* isVisible= */ true); - List<StackInfo> display3Stack = Collections.singletonList(stackInfo5); + RootTaskInfo taskInfo5 = createTask(5, /* isVisible= */ true); + List<RootTaskInfo> display3Tasks = Collections.singletonList(taskInfo5); - when(mActivityTaskManager.getAllStackInfosOnDisplay(display1.getDisplayId())) - .thenReturn(display1Stack); - when(mActivityTaskManager.getAllStackInfosOnDisplay(display2.getDisplayId())) - .thenReturn(display2Stack); - when(mActivityTaskManager.getAllStackInfosOnDisplay(display3.getDisplayId())) - .thenReturn(display3Stack); + when(mActivityTaskManager.getAllRootTaskInfosOnDisplay(display1.getDisplayId())) + .thenReturn(display1Tasks); + when(mActivityTaskManager.getAllRootTaskInfosOnDisplay(display2.getDisplayId())) + .thenReturn(display2Tasks); + when(mActivityTaskManager.getAllRootTaskInfosOnDisplay(display3.getDisplayId())) + .thenReturn(display3Tasks); - when(mSideLoadedAppDetector.isSafe(stackInfo2)).thenReturn(true); - when(mSideLoadedAppDetector.isSafe(stackInfo4)).thenReturn(false); - when(mSideLoadedAppDetector.isSafe(stackInfo5)).thenReturn(true); + when(mSideLoadedAppDetector.isSafe(taskInfo2)).thenReturn(true); + when(mSideLoadedAppDetector.isSafe(taskInfo4)).thenReturn(false); + when(mSideLoadedAppDetector.isSafe(taskInfo5)).thenReturn(true); when(mDisplayManager.getDisplays()) .thenReturn(new Display[] { display1, display2, display3}); mSideLoadedAppListener.onTaskStackChanged(); - verify(mSideLoadedAppDetector, never()).isSafe(stackInfo1); - verify(mSideLoadedAppDetector).isSafe(stackInfo2); - verify(mSideLoadedAppDetector, never()).isSafe(stackInfo3); - verify(mSideLoadedAppDetector).isSafe(stackInfo4); - verify(mSideLoadedAppDetector).isSafe(stackInfo5); + verify(mSideLoadedAppDetector, never()).isSafe(taskInfo1); + verify(mSideLoadedAppDetector).isSafe(taskInfo2); + verify(mSideLoadedAppDetector, never()).isSafe(taskInfo3); + verify(mSideLoadedAppDetector).isSafe(taskInfo4); + verify(mSideLoadedAppDetector).isSafe(taskInfo5); verify(mSideLoadedAppStateController, never()).onUnsafeTaskCreatedOnDisplay(any()); verify(mSideLoadedAppStateController).onSafeTaskDisplayedOnDisplay(display1); @@ -234,10 +234,10 @@ public class SideLoadedAppListenerTest extends SysuiTestCase { DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS); } - private StackInfo createTask(int id, boolean isVisible) { - StackInfo stackInfo = new StackInfo(); - stackInfo.stackId = id; - stackInfo.visible = isVisible; - return stackInfo; + private RootTaskInfo createTask(int id, boolean isVisible) { + RootTaskInfo taskInfo = new RootTaskInfo(); + taskInfo.taskId = id; + taskInfo.visible = isVisible; + return taskInfo; } } diff --git a/packages/PackageInstaller/res/values-ar/strings.xml b/packages/PackageInstaller/res/values-ar/strings.xml index 87f89ce192c4..c840374d3f6b 100644 --- a/packages/PackageInstaller/res/values-ar/strings.xml +++ b/packages/PackageInstaller/res/values-ar/strings.xml @@ -57,7 +57,7 @@ <string name="uninstall_application_text_all_users" msgid="575491774380227119">"هل تريد إزالة هذا التطبيق "<b>"لكل"</b>" المستخدمين؟ ستتم إزالة التطبيق وبياناته من "<b>"كل"</b>" المستخدمين على هذا الجهاز."</string> <string name="uninstall_application_text_user" msgid="498072714173920526">"هل تريد إزالة هذا التطبيق للمستخدم <xliff:g id="USERNAME">%1$s</xliff:g>؟"</string> <string name="uninstall_update_text" msgid="863648314632448705">"هل تريد استبدال هذا التطبيق بإصدار المصنع؟ ستتم إزالة جميع البيانات."</string> - <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"هل تريد استبدال هذا التطبيق بإصدار المصنع؟ ستتم إزالة جميع البيانات. وسيؤثر هذا في جميع مستخدمي هذا الجهاز، بما في ذلك من لديهم ملفات شخصية للعمل."</string> + <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"هل تريد إعادة ضبط هذا التطبيق على الإعدادات الأصلية؟ سؤدي ذلك إلى إزالة جميع البيانات، كما سيؤثر على جميع مستخدمي هذا الجهاز، بما في ذلك من لديهم ملفات شخصية للعمل."</string> <string name="uninstall_keep_data" msgid="7002379587465487550">"الاحتفاظ بالحجم <xliff:g id="SIZE">%1$s</xliff:g> من بيانات التطبيق."</string> <string name="uninstalling_notification_channel" msgid="840153394325714653">"عمليات إلغاء التثبيت الجارية"</string> <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"عمليات إلغاء التثبيت غير الناجحة"</string> diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml index 8f71509772fc..7f6237da9ee0 100644 --- a/packages/SettingsLib/res/values-be/strings.xml +++ b/packages/SettingsLib/res/values-be/strings.xml @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"Адладка па Wi-Fi"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Каб праглядаць і выкарыстоўваць даступныя прылады, уключыце адладку па Wi-Fi"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Спалучыць прыладу з дапамогай QR-кода"</string> - <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Спалучаць новыя прылады з дапамогай сканера QR-кода"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Спалучаць новыя прылады з дапамогай сканера QR-кодаў"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Спалучыць прыладу з дапамогай кода спалучэння"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Спалучаць новыя прылады з дапамогай шасцізначнага кода"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Спалучаныя прылады"</string> diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java index c5e66bef9653..a81a05f1147a 100644 --- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java +++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java @@ -116,6 +116,16 @@ public class AccessPoint implements Comparable<AccessPoint> { */ public static final int HIGHER_FREQ_5GHZ = 5900; + /** + * Lower bound on the 60 GHz (802.11ad) WIGIG channels + */ + public static final int LOWER_FREQ_60GHZ = 58320; + + /** + * Upper bound on the 60 GHz (802.11ad) WIGIG channels + */ + public static final int HIGHER_FREQ_60GHZ = 70200; + /** The key which identifies this AccessPoint grouping. */ private String mKey; diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.java index 1ace0b4250b9..15b146deb1cb 100644 --- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.java +++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.java @@ -93,6 +93,7 @@ public class WifiUtils { StringBuilder visibility = new StringBuilder(); StringBuilder scans24GHz = new StringBuilder(); StringBuilder scans5GHz = new StringBuilder(); + StringBuilder scans60GHz = new StringBuilder(); String bssid = null; if (accessPoint.isActive() && info != null) { @@ -115,9 +116,11 @@ public class WifiUtils { int maxRssi5 = INVALID_RSSI; int maxRssi24 = INVALID_RSSI; + int maxRssi60 = INVALID_RSSI; final int maxDisplayedScans = 4; int num5 = 0; // number of scanned BSSID on 5GHz band int num24 = 0; // number of scanned BSSID on 2.4Ghz band + int num60 = 0; // number of scanned BSSID on 60Ghz band int numBlockListed = 0; // TODO: sort list by RSSI or age @@ -152,6 +155,19 @@ public class WifiUtils { verboseScanResultSummary(accessPoint, result, bssid, nowMs)); } + } else if (result.frequency >= AccessPoint.LOWER_FREQ_60GHZ + && result.frequency <= AccessPoint.HIGHER_FREQ_60GHZ) { + // Strictly speaking: [60000, 61000] + num60++; + + if (result.level > maxRssi60) { + maxRssi60 = result.level; + } + if (num60 <= maxDisplayedScans) { + scans60GHz.append( + verboseScanResultSummary(accessPoint, result, bssid, + nowMs)); + } } } visibility.append(" ["); @@ -170,6 +186,14 @@ public class WifiUtils { } visibility.append(scans5GHz.toString()); } + visibility.append(";"); + if (num60 > 0) { + visibility.append("(").append(num60).append(")"); + if (num60 > maxDisplayedScans) { + visibility.append("max=").append(maxRssi60).append(","); + } + visibility.append(scans60GHz.toString()); + } if (numBlockListed > 0) { visibility.append("!").append(numBlockListed); } diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java index fbd88763fff4..dd2aa3bbbdf5 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java @@ -1777,6 +1777,9 @@ class SettingsProtoDumpUtil { Settings.Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED, SecureSettingsProto.Accessibility.HIGH_TEXT_CONTRAST_ENABLED); dumpSetting(s, p, + Settings.Secure.FORCE_BOLD_TEXT, + SecureSettingsProto.FORCE_BOLD_TEXT); + dumpSetting(s, p, Settings.Secure.ACCESSIBILITY_LARGE_POINTER_ICON, SecureSettingsProto.Accessibility.LARGE_POINTER_ICON); dumpSetting(s, p, diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml index 319b44ce216f..190015cebe30 100644 --- a/packages/Shell/AndroidManifest.xml +++ b/packages/Shell/AndroidManifest.xml @@ -217,6 +217,9 @@ <!-- Permission needed for CTS test - UnsupportedErrorDialogTests --> <uses-permission android:name="android.permission.RESET_APP_ERRORS" /> + <!-- Permission needed for CTS test - CtsSystemUiTestCases:PipNotificationTests --> + <uses-permission android:name="android.permission.GET_INTENT_SENDER_INTENT" /> + <!-- Permission needed to run keyguard manager tests in CTS --> <uses-permission android:name="android.permission.CONTROL_KEYGUARD_SECURE_NOTIFICATIONS" /> diff --git a/packages/SimAppDialog/Android.bp b/packages/SimAppDialog/Android.bp index 1c680bb9d25e..176035f73b65 100644 --- a/packages/SimAppDialog/Android.bp +++ b/packages/SimAppDialog/Android.bp @@ -7,8 +7,7 @@ android_app { static_libs: [ "androidx.legacy_legacy-support-v4", - "setupcompat", - "setupdesign", + "setup-wizard-lib", ], resource_dirs: ["res"], diff --git a/packages/SimAppDialog/AndroidManifest.xml b/packages/SimAppDialog/AndroidManifest.xml index e7368f35ed5a..873f6c5bac54 100644 --- a/packages/SimAppDialog/AndroidManifest.xml +++ b/packages/SimAppDialog/AndroidManifest.xml @@ -23,7 +23,7 @@ android:name=".InstallCarrierAppActivity" android:exported="true" android:permission="android.permission.NETWORK_SETTINGS" - android:theme="@style/SudThemeGlif.Light"> + android:theme="@style/SuwThemeGlif.Light"> </activity> </application> </manifest> diff --git a/packages/SimAppDialog/res/layout/install_carrier_app_activity.xml b/packages/SimAppDialog/res/layout/install_carrier_app_activity.xml index 68113dbf5df0..12f9bb6b13ea 100644 --- a/packages/SimAppDialog/res/layout/install_carrier_app_activity.xml +++ b/packages/SimAppDialog/res/layout/install_carrier_app_activity.xml @@ -14,17 +14,18 @@ See the License for the specific language governing permissions and limitations under the License. --> -<com.google.android.setupdesign.GlifLayout +<com.android.setupwizardlib.GlifLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/setup_wizard_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:icon="@drawable/ic_signal_cellular_alt_rounded" - app:sucHeaderText="@string/install_carrier_app_title"> + app:suwHeaderText="@string/install_carrier_app_title" + app:suwFooter="@layout/install_carrier_app_footer"> <LinearLayout - style="@style/SudContentFrame" + style="@style/SuwContentFrame" android:id="@+id/content_frame" android:layout_width="match_parent" android:layout_height="wrap_content" @@ -32,12 +33,12 @@ <TextView android:id="@+id/install_carrier_app_description" - style="@style/SudDescription.Glif" + style="@style/SuwDescription.Glif" android:text="@string/install_carrier_app_description_default" android:layout_width="match_parent" android:layout_height="wrap_content"/> - <com.google.android.setupdesign.view.FillContentLayout + <com.android.setupwizardlib.view.FillContentLayout android:id="@+id/illo_container" android:layout_width="match_parent" android:layout_height="wrap_content" @@ -46,12 +47,12 @@ <ImageView android:src="@drawable/illo_sim_app_dialog" - style="@style/SudContentIllustration" + style="@style/SuwContentIllustration" android:contentDescription="@string/install_carrier_app_image_content_description" android:layout_width="match_parent" android:layout_height="match_parent"/> - </com.google.android.setupdesign.view.FillContentLayout> - </LinearLayout> + </com.android.setupwizardlib.view.FillContentLayout> +</LinearLayout> -</com.google.android.setupdesign.GlifLayout> +</com.android.setupwizardlib.GlifLayout> diff --git a/packages/SimAppDialog/res/layout/install_carrier_app_footer.xml b/packages/SimAppDialog/res/layout/install_carrier_app_footer.xml new file mode 100644 index 000000000000..10dcb77a6584 --- /dev/null +++ b/packages/SimAppDialog/res/layout/install_carrier_app_footer.xml @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + 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. +--> + +<com.android.setupwizardlib.view.ButtonBarLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/footer" + style="@style/SuwGlifButtonBar.Stackable" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <Button + android:id="@+id/skip_button" + style="@style/SuwGlifButton.Secondary" + android:text="@string/install_carrier_app_defer_action" + android:layout_width="wrap_content" + android:layout_height="wrap_content"/> + + <Space + android:layout_width="0dp" + android:layout_height="0dp" + android:layout_weight="1"/> + + <Button + android:id="@+id/download_button" + style="@style/SuwGlifButton.Primary" + android:text="@string/install_carrier_app_download_action" + android:layout_width="wrap_content" + android:layout_height="wrap_content"/> +</com.android.setupwizardlib.view.ButtonBarLayout> diff --git a/packages/SimAppDialog/res/values/styles.xml b/packages/SimAppDialog/res/values/styles.xml deleted file mode 100644 index 824e3802aca1..000000000000 --- a/packages/SimAppDialog/res/values/styles.xml +++ /dev/null @@ -1,26 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2020 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. ---> -<resources> - - <style name="SetupWizardPartnerResource"> - <!-- Disable to use partner overlay theme for outside setupwizard flow. --> - <item name="sucUsePartnerResource">false</item> - <!-- Enable heavy theme style inside setupwizard flow. --> - <item name="sudUsePartnerHeavyTheme">true</item> - </style> - -</resources> diff --git a/packages/SimAppDialog/src/com/android/simappdialog/InstallCarrierAppActivity.java b/packages/SimAppDialog/src/com/android/simappdialog/InstallCarrierAppActivity.java index 0b6f9bb4f9e0..abe82a885a94 100644 --- a/packages/SimAppDialog/src/com/android/simappdialog/InstallCarrierAppActivity.java +++ b/packages/SimAppDialog/src/com/android/simappdialog/InstallCarrierAppActivity.java @@ -17,17 +17,14 @@ package com.android.simappdialog; import android.app.Activity; import android.content.Intent; -import android.content.res.Resources; import android.os.Bundle; import android.sysprop.SetupWizardProperties; import android.text.TextUtils; import android.view.View; +import android.widget.Button; import android.widget.TextView; -import com.google.android.setupcompat.template.FooterBarMixin; -import com.google.android.setupcompat.template.FooterButton; -import com.google.android.setupdesign.GlifLayout; -import com.google.android.setupdesign.util.ThemeResolver; +import com.android.setupwizardlib.util.WizardManagerHelper; /** * Activity that gives a user the choice to download the SIM app or defer until a later time @@ -38,7 +35,7 @@ import com.google.android.setupdesign.util.ThemeResolver; * Can display the carrier app name if its passed into the intent with key * {@link #BUNDLE_KEY_CARRIER_NAME} */ -public class InstallCarrierAppActivity extends Activity { +public class InstallCarrierAppActivity extends Activity implements View.OnClickListener { /** * Key for the carrier app name that will be displayed as the app to download. If unset, a * default description will be used @@ -53,33 +50,20 @@ public class InstallCarrierAppActivity extends Activity { protected void onCreate(Bundle icicle) { // Setup theme for aosp/pixel setTheme( - new ThemeResolver.Builder() - .setDefaultTheme(R.style.SudThemeGlifV3_Light) - .build() - .resolve(SetupWizardProperties.theme().orElse(""), - /* suppressDayNight= */ false)); + WizardManagerHelper.getThemeRes( + SetupWizardProperties.theme().orElse(""), + R.style.SuwThemeGlif_Light + ) + ); super.onCreate(icicle); setContentView(R.layout.install_carrier_app_activity); - GlifLayout layout = findViewById(R.id.setup_wizard_layout); - FooterBarMixin mixin = layout.getMixin(FooterBarMixin.class); - mixin.setSecondaryButton( - new FooterButton.Builder(this) - .setText(R.string.install_carrier_app_defer_action) - .setListener(this::onSkipButtonClick) - .setButtonType(FooterButton.ButtonType.SKIP) - .setTheme(R.style.SudGlifButton_Secondary) - .build()); - - mixin.setPrimaryButton( - new FooterButton.Builder(this) - .setText(R.string.install_carrier_app_download_action) - .setListener(this::onDownloadButtonClick) - .setButtonType(FooterButton.ButtonType.OTHER) - .setTheme(R.style.SudGlifButton_Primary) - .build()); + Button notNowButton = findViewById(R.id.skip_button); + notNowButton.setOnClickListener(this); + Button downloadButton = findViewById(R.id.download_button); + downloadButton.setOnClickListener(this); // Show/hide illo depending on whether one was provided in a resource overlay boolean showIllo = getResources().getBoolean(R.bool.show_sim_app_dialog_illo); @@ -98,17 +82,15 @@ public class InstallCarrierAppActivity extends Activity { } @Override - protected void onApplyThemeResource(Resources.Theme theme, int resid, boolean first) { - theme.applyStyle(R.style.SetupWizardPartnerResource, true); - super.onApplyThemeResource(theme, resid, first); - } - - protected void onSkipButtonClick(View view) { - finish(DEFER_RESULT); - } - - protected void onDownloadButtonClick(View view) { - finish(DOWNLOAD_RESULT); + public void onClick(View v) { + switch (v.getId()) { + case R.id.skip_button: + finish(DEFER_RESULT); + break; + case R.id.download_button: + finish(DOWNLOAD_RESULT); + break; + } } private void finish(int resultCode) { diff --git a/packages/SystemUI/res-keyguard/values-ar/strings.xml b/packages/SystemUI/res-keyguard/values-ar/strings.xml index 6d86a78360d8..65e3f0dbd176 100644 --- a/packages/SystemUI/res-keyguard/values-ar/strings.xml +++ b/packages/SystemUI/res-keyguard/values-ar/strings.xml @@ -112,7 +112,7 @@ <string name="kg_pin_accepted" msgid="1625501841604389716">"تم قبول الرمز"</string> <string name="keyguard_carrier_default" msgid="6359808469637388586">"لا تتوفر خدمة."</string> <string name="accessibility_ime_switch_button" msgid="9082358310194861329">"تبديل أسلوب الإدخال"</string> - <string name="airplane_mode" msgid="2528005343938497866">"وضع الطائرة"</string> + <string name="airplane_mode" msgid="2528005343938497866">"وضع الطيران"</string> <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"يجب رسم النقش بعد إعادة تشغيل الجهاز"</string> <string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"يجب إدخال رقم التعريف الشخصي بعد إعادة تشغيل الجهاز"</string> <string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"يجب إدخال كلمة المرور بعد إعادة تشغيل الجهاز"</string> diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml index 316fa8aac5e6..eae2cbb332df 100644 --- a/packages/SystemUI/res/values-af/strings.xml +++ b/packages/SystemUI/res/values-af/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Wys laeprioriteit-kennisgewingikone"</string> <string name="other" msgid="429768510980739978">"Ander"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Skermverdeler"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Volskerm links"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Links 70%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Links 50%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Links 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Volskerm regs"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Volskerm bo"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Bo 70%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Bo 50%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Bo 30%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Volskerm onder"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Posisie <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Dubbeltik om te wysig."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Dubbeltik om by te voeg."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Skuif <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Skuif <xliff:g id="TILE_NAME">%1$s</xliff:g> na posisie <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Kitsinstellingswysiger."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g>-kennisgewing: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"Program sal dalk nie met verdeelde skerm werk nie."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Program steun nie verdeelde skerm nie."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Program sal dalk nie op \'n sekondêre skerm werk nie."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Program steun nie begin op sekondêre skerms nie."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Maak instellings oop."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Maak kitsinstellings oop."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Maak kitsinstellings toe."</string> diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml index e2a4dc6404d8..e8326a7b3293 100644 --- a/packages/SystemUI/res/values-am/strings.xml +++ b/packages/SystemUI/res/values-am/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"አነስተኛ ቅድሚያ ያላቸው የማሳወቂያ አዶዎችን አሳይ"</string> <string name="other" msgid="429768510980739978">"ሌላ"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"የተከፈለ የማያ ገጽ ከፋይ"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"የግራ ሙሉ ማያ ገጽ"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"ግራ 70%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"ግራ 50%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"ግራ 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"የቀኝ ሙሉ ማያ ገጽ"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"የላይ ሙሉ ማያ ገጽ"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"ከላይ 70%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"ከላይ 50%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"ከላይ 30%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"የታች ሙሉ ማያ ገጽ"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"ቦታ <xliff:g id="POSITION">%1$d</xliff:g>፣ <xliff:g id="TILE_NAME">%2$s</xliff:g>። ለማርትዕ ሁለቴ መታ ያድርጉ።"</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>። ለማከል ሁለቴ መታ ያድርጉ።"</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"<xliff:g id="TILE_NAME">%1$s</xliff:g>ን ይውሰዱ"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"<xliff:g id="TILE_NAME">%1$s</xliff:g>ን ወደ አቀማመጥ <xliff:g id="POSITION">%2$d</xliff:g> አንቀሳቅስ"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"የፈጣን ቅንብሮች አርታዒ።"</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"የ<xliff:g id="ID_1">%1$s</xliff:g> ማሳወቂያ፦ <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"መተግበሪያ ከተከፈለ ማያ ገጽ ጋር ላይሠራ ይችላል"</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"መተግበሪያው የተከፈለ ማያ ገጽን አይደግፍም።"</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"መተግበሪያ በሁለተኛ ማሳያ ላይ ላይሠራ ይችላል።"</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"መተግበሪያ በሁለተኛ ማሳያዎች ላይ ማስጀመርን አይደግፍም።"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"ቅንብሮችን ክፈት።"</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"ፈጣን ቅንብሮችን ክፈት።"</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"ፈጣን ቅንብሮችን ዝጋ።"</string> diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml index b33c6c57f905..b020f17dc612 100644 --- a/packages/SystemUI/res/values-ar/strings.xml +++ b/packages/SystemUI/res/values-ar/strings.xml @@ -232,7 +232,7 @@ <string name="not_default_data_content_description" msgid="6757881730711522517">"لم يتم الضبط على استخدام البيانات"</string> <string name="cell_data_off" msgid="4886198950247099526">"غير مفعّلة"</string> <string name="accessibility_bluetooth_tether" msgid="6327291292208790599">"التوصيل عبر البلوتوث"</string> - <string name="accessibility_airplane_mode" msgid="1899529214045998505">"وضع الطائرة."</string> + <string name="accessibility_airplane_mode" msgid="1899529214045998505">"وضع الطيران."</string> <string name="accessibility_vpn_on" msgid="8037549696057288731">"الشبكة الافتراضية الخاصة (VPN) قيد التفعيل."</string> <string name="accessibility_no_sims" msgid="5711270400476534667">"ليس هناك شريحة SIM."</string> <string name="carrier_network_change_mode" msgid="5174141476991149918">"جارٍ تغيير شبكة مشغِّل شبكة الجوّال."</string> @@ -267,10 +267,10 @@ <string name="accessibility_quick_settings_wifi_changed_on" msgid="1490362586009027611">"تم تفعيل Wifi."</string> <string name="accessibility_quick_settings_mobile" msgid="1817825313718492906">"الجوّال <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string> <string name="accessibility_quick_settings_battery" msgid="533594896310663853">"البطارية <xliff:g id="STATE">%s</xliff:g>."</string> - <string name="accessibility_quick_settings_airplane_off" msgid="1275658769368793228">"إيقاف وضع الطائرة."</string> - <string name="accessibility_quick_settings_airplane_on" msgid="8106176561295294255">"تفعيل وضع الطائرة."</string> - <string name="accessibility_quick_settings_airplane_changed_off" msgid="8880183481476943754">"تم إيقاف وضع الطائرة."</string> - <string name="accessibility_quick_settings_airplane_changed_on" msgid="6327378061894076288">"تم تفعيل وضع الطائرة."</string> + <string name="accessibility_quick_settings_airplane_off" msgid="1275658769368793228">"إيقاف وضع الطيران."</string> + <string name="accessibility_quick_settings_airplane_on" msgid="8106176561295294255">"تفعيل وضع الطيران."</string> + <string name="accessibility_quick_settings_airplane_changed_off" msgid="8880183481476943754">"تم إيقاف وضع الطيران."</string> + <string name="accessibility_quick_settings_airplane_changed_on" msgid="6327378061894076288">"تم تفعيل وضع الطيران."</string> <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"كتم الصوت تمامًا"</string> <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"المنبِّهات فقط"</string> <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"عدم الإزعاج"</string> @@ -664,7 +664,7 @@ <string name="status_bar_ethernet" msgid="5690979758988647484">"إيثرنت"</string> <string name="status_bar_alarm" msgid="87160847643623352">"المنبّه"</string> <string name="status_bar_work" msgid="5238641949837091056">"الملف الشخصي للعمل"</string> - <string name="status_bar_airplane" msgid="4848702508684541009">"وضع الطائرة"</string> + <string name="status_bar_airplane" msgid="4848702508684541009">"وضع الطيران"</string> <string name="add_tile" msgid="6239678623873086686">"إضافة فئة"</string> <string name="broadcast_tile" msgid="5224010633596487481">"إرسال فئة"</string> <string name="zen_alarm_warning_indef" msgid="5252866591716504287">"لن تسمع المنبّه القادم في <xliff:g id="WHEN">%1$s</xliff:g> إلا إذا أوقفت هذا قبل الموعد"</string> @@ -899,17 +899,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"إظهار رموز الإشعارات ذات الأولوية المنخفضة"</string> <string name="other" msgid="429768510980739978">"غير ذلك"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"أداة تقسيم الشاشة"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"عرض النافذة اليسرى بملء الشاشة"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"ضبط حجم النافذة اليسرى ليكون ٧٠%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"ضبط حجم النافذة اليسرى ليكون ٥٠%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"ضبط حجم النافذة اليسرى ليكون ٣٠%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"عرض النافذة اليمنى بملء الشاشة"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"عرض النافذة العلوية بملء الشاشة"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"ضبط حجم النافذة العلوية ليكون ٧٠%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"ضبط حجم النافذة العلوية ليكون ٥٠%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"ضبط حجم النافذة العلوية ليكون ٣٠%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"عرض النافذة السفلية بملء الشاشة"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"الموضع <xliff:g id="POSITION">%1$d</xliff:g>، <xliff:g id="TILE_NAME">%2$s</xliff:g>. انقر مرّتين للتعديل."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. انقر مرّتين للإضافة."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"نقل <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> @@ -918,10 +907,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"نقل <xliff:g id="TILE_NAME">%1$s</xliff:g> إلى الموضع <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"برنامج تعديل الإعدادات السريعة."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"إشعار <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"يمكن ألا يعمل التطبيق مع وضع تقسيم الشاشة."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"التطبيق لا يتيح تقسيم الشاشة."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"قد لا يعمل التطبيق على شاشة عرض ثانوية."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"لا يمكن تشغيل التطبيق على شاشات عرض ثانوية."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"فتح الإعدادات."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"فتح الإعدادات السريعة."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"إغلاق الإعدادات السريعة."</string> diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml index 5a3c659727d3..31077dac8c41 100644 --- a/packages/SystemUI/res/values-as/strings.xml +++ b/packages/SystemUI/res/values-as/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"কম গুৰুত্বপূৰ্ণ জাননীৰ আইকনসমূহ দেখুৱাওক"</string> <string name="other" msgid="429768510980739978">"অন্যান্য"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"স্প্লিট স্ক্ৰীণৰ বিভাজক"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"বাওঁফালৰ স্ক্ৰীণখন সম্পূৰ্ণ স্ক্ৰীণ কৰক"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"বাওঁফালৰ স্ক্ৰীণখন ৭০% কৰক"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"বাওঁফালৰ স্ক্ৰীণখন ৫০% কৰক"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"বাওঁফালৰ স্ক্ৰীণখন ৩০% কৰক"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"সোঁফালৰ স্ক্ৰীণখন সম্পূৰ্ণ স্ক্ৰীণ কৰক"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"শীৰ্ষ স্ক্ৰীণখন সম্পূৰ্ণ স্ক্ৰীণ কৰক"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"শীর্ষ স্ক্ৰীণখন ৭০% কৰক"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"শীর্ষ স্ক্ৰীণখন ৫০% কৰক"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"শীর্ষ স্ক্ৰীণখন ৩০% কৰক"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"তলৰ স্ক্ৰীণখন সম্পূৰ্ণ স্ক্ৰীণ কৰক"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"অৱস্থান <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>। সম্পাদনা কৰিবৰ বাবে দুবাৰ টিপক।"</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>। যোগ কৰিবলৈ দুবাৰ টিপক।"</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"<xliff:g id="TILE_NAME">%1$s</xliff:g> স্থানান্তৰ কৰক"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"<xliff:g id="TILE_NAME">%1$s</xliff:g>ক এই স্থান <xliff:g id="POSITION">%2$d</xliff:g>লৈ যাওক"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ক্ষিপ্ৰ ছেটিংসমূহৰ সম্পাদক।"</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> জাননী: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"বিভাজিত স্ক্ৰীণৰ সৈতে এপে হয়তো কাম নকৰিব।"</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"এপটোৱে বিভাজিত স্ক্ৰীণ সমৰ্থন নকৰে।"</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"গৌণ ডিছপ্লেত এপে সঠিকভাৱে কাম নকৰিব পাৰে।"</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"গৌণ ডিছপ্লেত এপ্ লঞ্চ কৰিব নোৱাৰি।"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"ছেটিংসমূহ খোলক।"</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"ক্ষিপ্ৰ ছেটিংসমূহ খোলক।"</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"ক্ষিপ্ৰ ছেটিংসমূহ বন্ধ কৰক।"</string> diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml index 40df8cd68bac..b5960668e8fe 100644 --- a/packages/SystemUI/res/values-az/strings.xml +++ b/packages/SystemUI/res/values-az/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Aşağı prioritet bildiriş işarələrini göstərin"</string> <string name="other" msgid="429768510980739978">"Digər"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Bölünmüş ekran ayırıcısı"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Sol tam ekran"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Sol 70%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Sol 50%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Sol 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Sağ tam ekran"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Yuxarı tam ekran"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Yuxarı 70%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Yuxarı 50%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Yuxarı 30%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Aşağı tam ekran"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"<xliff:g id="POSITION">%1$d</xliff:g> mövqeyi, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Redaktə etmək üçün iki dəfə tıklayın."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Əlavə etmək üçün iki dəfə tıklayın."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"<xliff:g id="TILE_NAME">%1$s</xliff:g> köçürün"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"<xliff:g id="POSITION">%2$d</xliff:g> pozisiyasına <xliff:g id="TILE_NAME">%1$s</xliff:g> köçürün"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Sürətli ayarlar redaktoru."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> bildiriş: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"Tətbiq bölünmüş ekran ilə işləməyə bilər."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Tətbiq ekran bölünməsini dəstəkləmir."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Tətbiq ikinci ekranda işləməyə bilər."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Tətbiq ikinci ekranda başlamağı dəstəkləmir."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Ayarları açın."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Cəld ayarları açın."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Cəld ayarları bağlayın."</string> diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml index a9725f331856..aa141e637932 100644 --- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml +++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml @@ -884,17 +884,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Prikaži ikone obaveštenja niskog prioriteta"</string> <string name="other" msgid="429768510980739978">"Drugo"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Razdelnik podeljenog ekrana"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Režim celog ekrana za levi ekran"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Levi ekran 70%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Levi ekran 50%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Levi ekran 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Režim celog ekrana za donji ekran"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Režim celog ekrana za gornji ekran"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Gornji ekran 70%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Gornji ekran 50%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Gornji ekran 30%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Režim celog ekrana za donji ekran"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"<xliff:g id="POSITION">%1$d</xliff:g>. pozicija, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Dvaput dodirnite da biste izmenili."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Dvaput dodirnite da biste dodali."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Premesti pločicu <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> @@ -903,10 +892,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Premestite „<xliff:g id="TILE_NAME">%1$s</xliff:g>“ na poziciju <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Uređivač za Brza podešavanja."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Obaveštenja za <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"Aplikacija možda neće funkcionisati sa podeljenim ekranom."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Aplikacija ne podržava podeljeni ekran."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Aplikacija možda neće funkcionisati na sekundarnom ekranu."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Aplikacija ne podržava pokretanje na sekundarnim ekranima."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Otvori Podešavanja."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Otvori Brza podešavanja."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Zatvori Brza podešavanja."</string> diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml index b4c5eba9f77b..194f92b633e4 100644 --- a/packages/SystemUI/res/values-be/strings.xml +++ b/packages/SystemUI/res/values-be/strings.xml @@ -889,17 +889,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Паказваць значкі апавяшчэнняў з нізкім прыярытэтам"</string> <string name="other" msgid="429768510980739978">"Іншае"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Раздзяляльнік падзеленага экрана"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Левы экран – поўнаэкранны рэжым"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Левы экран – 70%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Левы экран – 50%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Левы экран – 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Правы экран – поўнаэкранны рэжым"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Верхні экран – поўнаэкранны рэжым"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Верхні экран – 70%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Верхні экран – 50%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Верхні экран – 30%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Ніжні экран – поўнаэкранны рэжым"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Месца: <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Краніце двойчы, каб рэдагаваць."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Краніце двойчы, каб дадаць."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Перамясціць <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> @@ -908,10 +897,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Перамясціць \"<xliff:g id="TILE_NAME">%1$s</xliff:g>\" у наступнае месца: <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Рэдактар хуткіх налад."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Апавяшчэнне <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"Праграма можа не працаваць у рэжыме дзялення экрана."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Праграма не падтрымлівае функцыю дзялення экрана."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Праграма можа не працаваць на дадатковых экранах."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Праграма не падтрымлівае запуск на дадатковых экранах."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Адкрыць налады."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Адкрыць хуткія налады."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Закрыць хуткія налады."</string> diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml index 52e82869d575..02eea8abe4dd 100644 --- a/packages/SystemUI/res/values-bg/strings.xml +++ b/packages/SystemUI/res/values-bg/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Показване на иконите за известията с нисък приоритет"</string> <string name="other" msgid="429768510980739978">"Друго"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Разделител в режима за разделен екран"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Ляв екран: Показване на цял екран"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Ляв екран: 70%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Ляв екран: 50%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Ляв екран: 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Десен екран: Показване на цял екран"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Горен екран: Показване на цял екран"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Горен екран: 70%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Горен екран: 50%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Горен екран: 30%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Долен екран: Показване на цял екран"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Позиция <xliff:g id="POSITION">%1$d</xliff:g>, „<xliff:g id="TILE_NAME">%2$s</xliff:g>“. Докоснете двукратно, за да редактирате."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"„<xliff:g id="TILE_NAME">%1$s</xliff:g>“. Докоснете двукратно, за да добавите."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Преместване на „<xliff:g id="TILE_NAME">%1$s</xliff:g>“"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Преместете „<xliff:g id="TILE_NAME">%1$s</xliff:g>“ на позиция <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Редактор за бързи настройки."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Известие от <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"Приложението може да не работи в режим на разделен екран."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Приложението не поддържа разделен екран."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Възможно е приложението да не работи на алтернативни дисплеи."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Приложението не поддържа използването на алтернативни дисплеи."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Отваряне на настройките."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Отваряне на бързите настройки."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Затваряне на бързите настройки."</string> diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml index d0de9cf03b38..96a7368b1dfd 100644 --- a/packages/SystemUI/res/values-bn/strings.xml +++ b/packages/SystemUI/res/values-bn/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"কম-গুরুত্বপূর্ণ বিজ্ঞপ্তির আইকন দেখুন"</string> <string name="other" msgid="429768510980739978">"অন্যান্য"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"বিভক্ত-স্ক্রিন বিভাজক"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"বাঁ দিকের অংশ নিয়ে পূর্ণ স্ক্রিন"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"৭০% বাকি আছে"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"৫০% বাকি আছে"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"৩০% বাকি আছে"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"ডান দিকের অংশ নিয়ে পূর্ণ স্ক্রিন"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"উপর দিকের অংশ নিয়ে পূর্ণ স্ক্রিন"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"শীর্ষ ৭০%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"শীর্ষ ৫০%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"শীর্ষ ৩০%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"নীচের অংশ নিয়ে পূর্ণ স্ক্রিন"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"<xliff:g id="POSITION">%1$d</xliff:g> লোকেশন, <xliff:g id="TILE_NAME">%2$s</xliff:g>৷ সম্পাদনা করতে দুবার আলতো চাপুন৷"</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>৷ যোগ করতে দুবার আলতো চাপুন৷"</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"<xliff:g id="TILE_NAME">%1$s</xliff:g> সরান"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"<xliff:g id="TILE_NAME">%1$s</xliff:g> <xliff:g id="POSITION">%2$d</xliff:g>-এ সরান"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"দ্রুত সেটিংস সম্পাদক৷"</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> বিজ্ঞপ্তি: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"অ্যাপ্লিকেশানটি বিভক্ত স্ক্রীনে কাজ নাও করতে পারে৷"</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"অ্যাপ্লিকেশান বিভক্ত-স্ক্রিন সমর্থন করে না৷"</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"সেকেন্ডারি ডিসপ্লেতে অ্যাপটি কাজ নাও করতে পারে।"</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"সেকেন্ডারি ডিসপ্লেতে অ্যাপ লঞ্চ করা যাবে না।"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"সেটিংস খুলুন।"</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"দ্রুত সেটিংস খুলুন৷"</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"দ্রুত সেটিংস বন্ধ করুন৷"</string> diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml index 57b7945c7a8c..0a091aae70b9 100644 --- a/packages/SystemUI/res/values-bs/strings.xml +++ b/packages/SystemUI/res/values-bs/strings.xml @@ -884,17 +884,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Prikaži ikone obavještenja niskog prioriteta"</string> <string name="other" msgid="429768510980739978">"Ostalo"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Razdjelnik ekrana"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Lijevo cijeli ekran"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Lijevo 70%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Lijevo 50%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Lijevo 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Desno cijeli ekran"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Gore cijeli ekran"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Gore 70%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Gore 50%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Gore 30%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Donji ekran kao cijeli ekran"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Pozicija <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Dodirnite dvaput za uređivanje."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g> Dodirnite dvaput za dodavanje."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Pomjeri <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> @@ -903,10 +892,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Premjesti <xliff:g id="TILE_NAME">%1$s</xliff:g> na poziciju <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Uređivanje brzih postavki"</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> obavještenje: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"Aplikacija možda neće raditi na podijeljenom ekranu"</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Aplikacija ne podržava dijeljenje ekrana."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Aplikacija možda neće raditi na sekundarnom ekranu."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Aplikacija ne podržava pokretanje na sekundarnim ekranima."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Otvori postavke."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Otvoriti brze postavke."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Zatvoriti brze postavke."</string> diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml index 0489d18ff36b..d4e8befe3f4d 100644 --- a/packages/SystemUI/res/values-ca/strings.xml +++ b/packages/SystemUI/res/values-ca/strings.xml @@ -707,7 +707,7 @@ <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Desactiva les notificacions"</string> <string name="inline_keep_showing_app" msgid="4393429060390649757">"Vols continuar rebent notificacions d\'aquesta aplicació?"</string> <string name="notification_silence_title" msgid="8608090968400832335">"Silenci"</string> - <string name="notification_alert_title" msgid="3656229781017543655">"Predeterminada"</string> + <string name="notification_alert_title" msgid="3656229781017543655">"Predeterminat"</string> <string name="notification_bubble_title" msgid="8330481035191903164">"Bombolla"</string> <string name="notification_automatic_title" msgid="3745465364578762652">"Automàtic"</string> <string name="notification_channel_summary_low" msgid="4860617986908931158">"Sense so ni vibració"</string> @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Mostra les icones de notificació amb prioritat baixa"</string> <string name="other" msgid="429768510980739978">"Altres"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Divisor de pantalles"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Pantalla esquerra completa"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Pantalla esquerra al 70%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Pantalla esquerra al 50%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Pantalla esquerra al 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Pantalla dreta completa"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Pantalla superior completa"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Pantalla superior al 70%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Pantalla superior al 50%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Pantalla superior al 30%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Pantalla inferior completa"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Posició <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Fes doble toc per editar-la."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Fes doble toc per afegir-ho."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Mou <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Mou <xliff:g id="TILE_NAME">%1$s</xliff:g> a la posició <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor de configuració ràpida."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Notificació de <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"És possible que l\'aplicació no funcioni amb la pantalla dividida."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"L\'aplicació no admet la pantalla dividida."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"És possible que l\'aplicació no funcioni en una pantalla secundària."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"L\'aplicació no es pot obrir en pantalles secundàries."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Obre la configuració."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Obre la configuració ràpida."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Tanca la configuració ràpida."</string> diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml index acb6637b68dc..239a0f6b3d53 100644 --- a/packages/SystemUI/res/values-cs/strings.xml +++ b/packages/SystemUI/res/values-cs/strings.xml @@ -889,17 +889,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Zobrazit ikony oznámení s nízkou prioritou"</string> <string name="other" msgid="429768510980739978">"Jiné"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Čára rozdělující obrazovku"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Levá část na celou obrazovku"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"70 % vlevo"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"50 % vlevo"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"30 % vlevo"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Pravá část na celou obrazovku"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Horní část na celou obrazovku"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"70 % nahoře"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"50 % nahoře"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"30 % nahoře"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Dolní část na celou obrazovku"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Pozice <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Dvojitým klepnutím ji upravíte."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Dlaždici přidáte dvojitým klepnutím."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Přesunout dlaždici <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> @@ -908,10 +897,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Přesunout dlaždici <xliff:g id="TILE_NAME">%1$s</xliff:g> na pozici <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor rychlého nastavení"</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Oznámení aplikace <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"Aplikace v režimu rozdělené obrazovky nemusí fungovat."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Aplikace nepodporuje režim rozdělené obrazovky."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Aplikace na sekundárním displeji nemusí fungovat."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Aplikace nepodporuje spuštění na sekundárních displejích."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Otevřít nastavení."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Otevřít rychlé nastavení."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Zavřít rychlé nastavení."</string> diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml index 886369598f1c..7ce60ea1536a 100644 --- a/packages/SystemUI/res/values-da/strings.xml +++ b/packages/SystemUI/res/values-da/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Vis ikoner for notifikationer med lav prioritet"</string> <string name="other" msgid="429768510980739978">"Andet"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Adskiller til opdelt skærm"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Vis venstre del i fuld skærm"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Venstre 70 %"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Venstre 50 %"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Venstre 30 %"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Vis højre del i fuld skærm"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Vis øverste del i fuld skærm"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Øverste 70 %"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Øverste 50 %"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Øverste 30 %"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Vis nederste del i fuld skærm"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Position <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Tryk to gange for at redigere."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Tryk to gange for at tilføje."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Flyt <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Flyt <xliff:g id="TILE_NAME">%1$s</xliff:g> til position <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Redigeringsværktøj til Kvikmenu."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g>-notifikation: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"Appen fungerer muligvis ikke i opdelt skærm."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Appen understøtter ikke opdelt skærm."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Appen fungerer muligvis ikke på sekundære skærme."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Appen kan ikke åbnes på sekundære skærme."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Åbn Indstillinger."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Åbn Kvikmenu."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Luk Kvikmenu."</string> diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml index 8d990c66ecdf..093e1a20ca97 100644 --- a/packages/SystemUI/res/values-de/strings.xml +++ b/packages/SystemUI/res/values-de/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Symbole für Benachrichtigungen mit einer niedrigen Priorität anzeigen"</string> <string name="other" msgid="429768510980739978">"Sonstiges"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Bildschirmteiler"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Vollbild links"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"70 % links"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"50 % links"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"30 % links"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Vollbild rechts"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Vollbild oben"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"70 % oben"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"50 % oben"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"30 % oben"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Vollbild unten"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Position <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Zum Bearbeiten doppeltippen."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Zum Hinzufügen doppeltippen."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"<xliff:g id="TILE_NAME">%1$s</xliff:g> verschieben"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"<xliff:g id="TILE_NAME">%1$s</xliff:g> auf Position <xliff:g id="POSITION">%2$d</xliff:g> verschieben"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor für Schnelleinstellungen."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Benachrichtigung von <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"Die App funktioniert unter Umständen bei geteiltem Bildschirm nicht."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Das Teilen des Bildschirms wird in dieser App nicht unterstützt."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Die App funktioniert auf einem sekundären Display möglicherweise nicht."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Die App unterstützt den Start auf sekundären Displays nicht."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Einstellungen öffnen."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Schnelleinstellungen öffnen."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Schnelleinstellungen schließen."</string> diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml index 5ca236b2514a..ac1a3ee4601e 100644 --- a/packages/SystemUI/res/values-el/strings.xml +++ b/packages/SystemUI/res/values-el/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Εμφάνιση εικονιδίων ειδοποιήσεων χαμηλής προτεραιότητας"</string> <string name="other" msgid="429768510980739978">"Άλλο"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Διαχωριστικό οθόνης"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Αριστερή πλήρης οθόνη"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Αριστερή 70%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Αριστερή 50%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Αριστερή 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Δεξιά πλήρης οθόνη"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Πάνω πλήρης οθόνη"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Πάνω 70%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Πάνω 50%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Πάνω 30%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Κάτω πλήρης οθόνη"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Θέση <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Πατήστε δύο φορές για επεξεργασία."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Πατήστε δύο φορές για προσθήκη."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Μετακίνηση <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Μετακίνηση <xliff:g id="TILE_NAME">%1$s</xliff:g> στη θέση <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Επεξεργασία γρήγορων ρυθμίσεων."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Ειδοποίηση <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"Δεν είναι δυνατή η λειτουργία της εφαρμογής με διαχωρισμό οθόνης."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Η εφαρμογή δεν υποστηρίζει διαχωρισμό οθόνης."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Η εφαρμογή ίσως να μην λειτουργήσει σε δευτερεύουσα οθόνη."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Η εφαρμογή δεν υποστηρίζει την εκκίνηση σε δευτερεύουσες οθόνες."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Άνοιγμα ρυθμίσεων."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Άνοιγμα γρήγορων ρυθμίσεων."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Κλείσιμο γρήγορων ρυθμίσεων."</string> diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml index 8a7963a1f845..3a76d75ac043 100644 --- a/packages/SystemUI/res/values-en-rAU/strings.xml +++ b/packages/SystemUI/res/values-en-rAU/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Show low-priority notification icons"</string> <string name="other" msgid="429768510980739978">"Other"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Split screen divider"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Left full screen"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Left 70%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Left 50%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Left 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Right full screen"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Top full screen"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Top 70%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Top 50%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Top 30%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Bottom full screen"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Position <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Double tap to edit."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Double tap to add."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Move <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Move <xliff:g id="TILE_NAME">%1$s</xliff:g> to position <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Quick settings editor."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> notification: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"App may not work with split-screen."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"App does not support split-screen."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"App may not work on a secondary display."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"App does not support launch on secondary displays."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Open settings."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Open quick settings."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Close quick settings."</string> diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml index 7b2b25a0e678..ac6519394268 100644 --- a/packages/SystemUI/res/values-en-rCA/strings.xml +++ b/packages/SystemUI/res/values-en-rCA/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Show low-priority notification icons"</string> <string name="other" msgid="429768510980739978">"Other"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Split screen divider"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Left full screen"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Left 70%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Left 50%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Left 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Right full screen"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Top full screen"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Top 70%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Top 50%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Top 30%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Bottom full screen"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Position <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Double tap to edit."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Double tap to add."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Move <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Move <xliff:g id="TILE_NAME">%1$s</xliff:g> to position <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Quick settings editor."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> notification: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"App may not work with split-screen."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"App does not support split-screen."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"App may not work on a secondary display."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"App does not support launch on secondary displays."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Open settings."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Open quick settings."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Close quick settings."</string> diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml index 8a7963a1f845..3a76d75ac043 100644 --- a/packages/SystemUI/res/values-en-rGB/strings.xml +++ b/packages/SystemUI/res/values-en-rGB/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Show low-priority notification icons"</string> <string name="other" msgid="429768510980739978">"Other"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Split screen divider"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Left full screen"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Left 70%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Left 50%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Left 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Right full screen"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Top full screen"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Top 70%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Top 50%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Top 30%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Bottom full screen"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Position <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Double tap to edit."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Double tap to add."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Move <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Move <xliff:g id="TILE_NAME">%1$s</xliff:g> to position <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Quick settings editor."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> notification: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"App may not work with split-screen."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"App does not support split-screen."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"App may not work on a secondary display."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"App does not support launch on secondary displays."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Open settings."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Open quick settings."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Close quick settings."</string> diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml index 8a7963a1f845..3a76d75ac043 100644 --- a/packages/SystemUI/res/values-en-rIN/strings.xml +++ b/packages/SystemUI/res/values-en-rIN/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Show low-priority notification icons"</string> <string name="other" msgid="429768510980739978">"Other"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Split screen divider"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Left full screen"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Left 70%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Left 50%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Left 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Right full screen"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Top full screen"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Top 70%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Top 50%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Top 30%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Bottom full screen"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Position <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Double tap to edit."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Double tap to add."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Move <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Move <xliff:g id="TILE_NAME">%1$s</xliff:g> to position <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Quick settings editor."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> notification: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"App may not work with split-screen."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"App does not support split-screen."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"App may not work on a secondary display."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"App does not support launch on secondary displays."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Open settings."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Open quick settings."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Close quick settings."</string> diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml index 15738f2512f4..211a27c69b7e 100644 --- a/packages/SystemUI/res/values-en-rXC/strings.xml +++ b/packages/SystemUI/res/values-en-rXC/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Show low-priority notification icons"</string> <string name="other" msgid="429768510980739978">"Other"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Split-screen divider"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Left full screen"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Left 70%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Left 50%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Left 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Right full screen"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Top full screen"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Top 70%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Top 50%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Top 30%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Bottom full screen"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Position <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Double tap to edit."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Double tap to add."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Move <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Move <xliff:g id="TILE_NAME">%1$s</xliff:g> to position <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Quick settings editor."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> notification: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"App may not work with split-screen."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"App does not support split-screen."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"App may not work on a secondary display."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"App does not support launch on secondary displays."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Open settings."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Open quick settings."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Close quick settings."</string> diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml index aa81ab8efadd..ccc46266f7fe 100644 --- a/packages/SystemUI/res/values-es-rUS/strings.xml +++ b/packages/SystemUI/res/values-es-rUS/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Mostrar íconos de notificaciones con prioridad baja"</string> <string name="other" msgid="429768510980739978">"Otros"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Divisor de pantalla dividida"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Pantalla izquierda completa"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Izquierda: 70%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Izquierda: 50%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Izquierda: 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Pantalla derecha completa"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Pantalla superior completa"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Superior: 70%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Superior: 50%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Superior: 30%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Pantalla inferior completa"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Posición <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Presiona dos veces para editarla."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Presiona dos veces para agregarlo."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Mover <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Mover <xliff:g id="TILE_NAME">%1$s</xliff:g> a la posición <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor de Configuración rápida"</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Notificación de <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"Es posible que la app no funcione en el modo de pantalla dividida."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"La app no es compatible con la función de pantalla dividida."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Es posible que la app no funcione en una pantalla secundaria."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"La app no puede iniciarse en pantallas secundarias."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Abrir Configuración"</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Abrir la configuración rápida"</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Cerrar configuración rápida"</string> diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml index 863857016388..4e9347cb01e6 100644 --- a/packages/SystemUI/res/values-es/strings.xml +++ b/packages/SystemUI/res/values-es/strings.xml @@ -98,7 +98,7 @@ <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Sonido de tu dispositivo, como música, llamadas y tonos de llamada"</string> <string name="screenrecord_mic_label" msgid="2111264835791332350">"Micrófono"</string> <string name="screenrecord_device_audio_and_mic_label" msgid="1831323771978646841">"Audio y micrófono del dispositivo"</string> - <string name="screenrecord_start" msgid="330991441575775004">"Empezar"</string> + <string name="screenrecord_start" msgid="330991441575775004">"Iniciar"</string> <string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"Grabando pantalla"</string> <string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"Grabando pantalla y audio"</string> <string name="screenrecord_taps_label" msgid="1595690528298857649">"Mostrar toques en la pantalla"</string> @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Mostrar iconos de notificaciones con prioridad baja"</string> <string name="other" msgid="429768510980739978">"Otros"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Dividir la pantalla"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Pantalla izquierda completa"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Izquierda 70%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Izquierda 50%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Izquierda 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Pantalla derecha completa"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Pantalla superior completa"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Superior 70%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Superior 50%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Superior 30%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Pantalla inferior completa"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Posición <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Toca dos veces para cambiarla."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Toca dos veces para añadirlo."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Mover <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Mover <xliff:g id="TILE_NAME">%1$s</xliff:g> a la posición <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor de ajustes rápidos."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Notificación de <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"Es posible que la aplicación no funcione con la pantalla dividida."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"La aplicación no admite la pantalla dividida."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Es posible que la aplicación no funcione en una pantalla secundaria."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"La aplicación no se puede abrir en pantallas secundarias."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Abrir ajustes."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Abrir ajustes rápidos."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Cerrar ajustes rápidos."</string> diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml index f5ffad255cf6..21189f1ea5f6 100644 --- a/packages/SystemUI/res/values-et/strings.xml +++ b/packages/SystemUI/res/values-et/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Kuva madala prioriteediga märguande ikoonid"</string> <string name="other" msgid="429768510980739978">"Muu"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Ekraanijagaja"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Vasak täisekraan"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Vasak: 70%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Vasak: 50%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Vasak: 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Parem täisekraan"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Ülemine täisekraan"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Ülemine: 70%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Ülemine: 50%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Ülemine: 30%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Alumine täisekraan"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Asend <xliff:g id="POSITION">%1$d</xliff:g>, paan <xliff:g id="TILE_NAME">%2$s</xliff:g>. Topeltpuudutage muutmiseks."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Topeltpuudutage lisamiseks."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Paani <xliff:g id="TILE_NAME">%1$s</xliff:g> teisaldamine"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Teisaldage <xliff:g id="TILE_NAME">%1$s</xliff:g> asendisse <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Kiirseadete redigeerija."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Teenuse <xliff:g id="ID_1">%1$s</xliff:g> märguanne: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"Rakendus ei pruugi poolitatud ekraaniga töötada."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Rakendus ei toeta jagatud ekraani."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Rakendus ei pruugi teisesel ekraanil töötada."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Rakendus ei toeta teisestel ekraanidel käivitamist."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Ava seaded."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Ava kiirseaded."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Sule kiirseaded."</string> diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml index 23bcd2c32c76..8a372361daac 100644 --- a/packages/SystemUI/res/values-eu/strings.xml +++ b/packages/SystemUI/res/values-eu/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Erakutsi lehentasun txikiko jakinarazpenen ikonoak"</string> <string name="other" msgid="429768510980739978">"Beste bat"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Pantaila-zatitzailea"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Ezarri ezkerraldea pantaila osoan"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Ezarri ezkerraldea % 70en"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Ezarri ezkerraldea % 50en"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Ezarri ezkerraldea % 30en"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Ezarri eskuinaldea pantaila osoan"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Ezarri goialdea pantaila osoan"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Ezarri goialdea % 70en"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Ezarri goialdea % 50en"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Ezarri goialdea % 30en"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Ezarri behealdea pantaila osoan"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"<xliff:g id="POSITION">%1$d</xliff:g>. posizioa, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Editatzeko, sakatu birritan."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Gehitzeko, sakatu birritan."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Mugitu <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Eraman <xliff:g id="TILE_NAME">%1$s</xliff:g> <xliff:g id="POSITION">%2$d</xliff:g>garren postura"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Ezarpen bizkorren editorea."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> zerbitzuaren jakinarazpena: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"Baliteke aplikazioak ez funtzionatzea pantaila zatituan."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Aplikazioak ez du onartzen pantaila zatitua"</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Baliteke aplikazioak ez funtzionatzea bigarren mailako pantailetan."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Aplikazioa ezin da abiarazi bigarren mailako pantailatan."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Ireki ezarpenak."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Ireki ezarpen bizkorrak."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Itxi ezarpen bizkorrak."</string> diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml index 55d8ab2566c6..7f85959af7aa 100644 --- a/packages/SystemUI/res/values-fa/strings.xml +++ b/packages/SystemUI/res/values-fa/strings.xml @@ -808,7 +808,7 @@ <string name="keyboard_shortcut_group_system_back" msgid="1055709713218453863">"برگشت"</string> <string name="keyboard_shortcut_group_system_notifications" msgid="3615971650562485878">"اعلانها"</string> <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4856808328618265589">"میانبرهای صفحهکلید"</string> - <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"تغییر طرحبندی صفحهکلید"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="952555530383268166">"تغییر جانمایی صفحهکلید"</string> <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"برنامهها"</string> <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"دستیار"</string> <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"مرورگر"</string> @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"نمایش نمادهای اعلان کماهمیت"</string> <string name="other" msgid="429768510980739978">"موارد دیگر"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"تقسیمکننده صفحه"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"تمامصفحه چپ"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"٪۷۰ چپ"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"٪۵۰ چپ"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"٪۳۰ چپ"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"تمامصفحه راست"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"تمامصفحه بالا"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"٪۷۰ بالا"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"٪۵۰ بالا"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"٪۳۰ بالا"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"تمامصفحه پایین"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"موقعیت <xliff:g id="POSITION">%1$d</xliff:g>، <xliff:g id="TILE_NAME">%2$s</xliff:g>. برای ویرایش دو ضربه سریع بزنید."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. برای افزودن دو ضربه سریع بزنید."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"انتقال <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"انتقال <xliff:g id="TILE_NAME">%1$s</xliff:g> به موقعیت <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ویرایشگر تنظیمات سریع."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"اعلان <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"ممکن است برنامه با تقسیم صفحه کار نکند."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"برنامه از تقسیم صفحه پشتیبانی نمیکند."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"ممکن است برنامه در نمایشگر ثانویه کار نکند."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"برنامه از راهاندازی در نمایشگرهای ثانویه پشتیبانی نمیکند."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"باز کردن تنظیمات."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"باز کردن تنظیمات سریع."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"بستن تنظیمات سریع."</string> diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml index f30c44b3ffba..fd9bbd94625c 100644 --- a/packages/SystemUI/res/values-fi/strings.xml +++ b/packages/SystemUI/res/values-fi/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Näytä vähemmän tärkeät ilmoituskuvakkeet"</string> <string name="other" msgid="429768510980739978">"Muu"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Näytön jakaja"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Vasen koko näytölle"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Vasen 70 %"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Vasen 50 %"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Vasen 30 %"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Oikea koko näytölle"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Yläosa koko näytölle"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Yläosa 70 %"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Yläosa 50 %"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Yläosa 30 %"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Alaosa koko näytölle"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Paikka <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Muokkaa kaksoisnapauttamalla."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Lisää kaksoisnapauttamalla."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Siirrä <xliff:g id="TILE_NAME">%1$s</xliff:g>."</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Siirrä <xliff:g id="TILE_NAME">%1$s</xliff:g> kohtaan <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Pika-asetusten muokkausnäkymä"</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Ilmoitus kohteesta <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"Sovellus ei ehkä toimi jaetulla näytöllä."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Sovellus ei tue jaetun näytön tilaa."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Sovellus ei ehkä toimi toissijaisella näytöllä."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Sovellus ei tue käynnistämistä toissijaisilla näytöillä."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Avaa asetukset."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Avaa pika-asetukset."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Sulje pika-asetukset."</string> diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml index f6196dd63695..8817cebdcf4d 100644 --- a/packages/SystemUI/res/values-fr-rCA/strings.xml +++ b/packages/SystemUI/res/values-fr-rCA/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Afficher les icônes de notification de faible priorité"</string> <string name="other" msgid="429768510980739978">"Autre"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Séparateur d\'écran partagé"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Plein écran à la gauche"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"70 % à la gauche"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"50 % à la gauche"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"30 % à la gauche"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Plein écran à la droite"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Plein écran dans le haut"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"70 % dans le haut"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"50 % dans le haut"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"30 % dans le haut"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Plein écran dans le bas"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Position <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Touchez deux fois pour modifier."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Touchez deux fois pour ajouter."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Déplacer <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Déplacer <xliff:g id="TILE_NAME">%1$s</xliff:g> à la position <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Éditeur de paramètres rapides."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Notification <xliff:g id="ID_1">%1$s</xliff:g> : <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"Il est possible que l\'application ne fonctionne pas en mode Écran partagé."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"L\'application n\'est pas compatible avec l\'écran partagé."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Il est possible que l\'application ne fonctionne pas sur un écran secondaire."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"L\'application ne peut pas être lancée sur des écrans secondaires."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Ouvrir les paramètres."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Ouvrir les réglages rapides."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Fermer les réglages rapides."</string> diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml index 0146ce4d9a59..35176c79f987 100644 --- a/packages/SystemUI/res/values-fr/strings.xml +++ b/packages/SystemUI/res/values-fr/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Afficher les icônes de notification à faible priorité"</string> <string name="other" msgid="429768510980739978">"Autre"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Séparateur d\'écran partagé"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Écran de gauche en plein écran"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Écran de gauche à 70 %"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Écran de gauche à 50 %"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Écran de gauche à 30 %"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Écran de droite en plein écran"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Écran du haut en plein écran"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Écran du haut à 70 %"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Écran du haut à 50 %"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Écran du haut à 30 %"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Écran du bas en plein écran"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Position <xliff:g id="POSITION">%1$d</xliff:g>, \"<xliff:g id="TILE_NAME">%2$s</xliff:g>\". Appuyer deux fois pour modifier."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Appuyer deux fois pour ajouter."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Déplacer \"<xliff:g id="TILE_NAME">%1$s</xliff:g>\""</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Déplacer l\'élément \"<xliff:g id="TILE_NAME">%1$s</xliff:g>\" à la position <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Éditeur de configuration rapide."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Notification <xliff:g id="ID_1">%1$s</xliff:g> : <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"Il est possible que l\'application ne fonctionne pas en mode Écran partagé."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Application incompatible avec l\'écran partagé."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Il est possible que l\'application ne fonctionne pas sur un écran secondaire."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"L\'application ne peut pas être lancée sur des écrans secondaires."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Ouvrir les paramètres."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Ouvrir la fenêtre de configuration rapide."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Fermer la fenêtre de configuration rapide."</string> diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml index fd4d3c6a4ad5..7c6279894069 100644 --- a/packages/SystemUI/res/values-gl/strings.xml +++ b/packages/SystemUI/res/values-gl/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Mostrar iconas das notificacións que teñan baixa prioridade"</string> <string name="other" msgid="429768510980739978">"Outros"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Divisor de pantalla dividida"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Pantalla completa á esquerda"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"70 % á esquerda"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"50 % á esquerda"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"30 % á esquerda"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Pantalla completa á dereita"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Pantalla completa arriba"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"70 % arriba"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"50 % arriba"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"30 % arriba"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Pantalla completa abaixo"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Posición <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Toca dúas veces o elemento para editalo."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Toca dúas veces o elemento para engadilo"</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Move <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Mover \"<xliff:g id="TILE_NAME">%1$s</xliff:g>\" á posición <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor de configuración rápida."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Notificación de <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"Pode que a aplicación non funcione coa pantalla dividida."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"A aplicación non é compatible coa función de pantalla dividida."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"É posible que a aplicación non funcione nunha pantalla secundaria."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"A aplicación non se pode iniciar en pantallas secundarias."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Abrir configuración."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Abrir configuración rápida."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Pechar a configuración rápida."</string> diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml index 46f7a2bde43c..af0d7d3e1b10 100644 --- a/packages/SystemUI/res/values-gu/strings.xml +++ b/packages/SystemUI/res/values-gu/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"ઓછી પ્રાધાન્યતાનું નોટિફિકેશન આઇકન બતાવો"</string> <string name="other" msgid="429768510980739978">"અન્ય"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"સ્પ્લિટ-સ્ક્રીન વિભાજક"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"ડાબી પૂર્ણ સ્ક્રીન"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"ડાબે 70%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"ડાબે 50%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"ડાબે 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"જમણી સ્ક્રીન સ્ક્રીન"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"શીર્ષ પૂર્ણ સ્ક્રીન"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"શીર્ષ 70%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"શીર્ષ 50%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"શીર્ષ 30%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"તળિયાની પૂર્ણ સ્ક્રીન"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"સ્થિતિ <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. સંપાદિત કરવા માટે બે વાર ટૅપ કરો."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. ઉમેરવા માટે બે વાર ટૅપ કરો."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"<xliff:g id="TILE_NAME">%1$s</xliff:g> ખસેડો"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"<xliff:g id="POSITION">%2$d</xliff:g> જગ્યા પર <xliff:g id="TILE_NAME">%1$s</xliff:g>ને ખસેડો"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ઝડપી સેટિંગ્સ સંપાદક."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> નોટિફિકેશન: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"વિભાજિત-સ્ક્રીન સાથે ઍપ્લિકેશન કદાચ કામ ન કરે."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"ઍપ્લિકેશન સ્ક્રીન-વિભાજનનું સમર્થન કરતી નથી."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"ઍપ્લિકેશન ગૌણ ડિસ્પ્લે પર કદાચ કામ ન કરે."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"ઍપ્લિકેશન ગૌણ ડિસ્પ્લે પર લૉન્ચનું સમર્થન કરતી નથી."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"સેટિંગ્સ ખોલો."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"ઝડપી સેટિંગ્સ ખોલો."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"ઝડપી સેટિંગ્સ બંધ કરો."</string> diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml index e4a6ed79848d..0a7515d03a65 100644 --- a/packages/SystemUI/res/values-hi/strings.xml +++ b/packages/SystemUI/res/values-hi/strings.xml @@ -881,17 +881,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"कम प्राथमिकता वाली सूचना के आइकॉन दिखाएं"</string> <string name="other" msgid="429768510980739978">"अन्य"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"विभाजित स्क्रीन विभाजक"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"बाईं स्क्रीन को फ़ुल स्क्रीन बनाएं"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"बाईं स्क्रीन को 70% बनाएं"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"बाईं स्क्रीन को 50% बनाएं"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"बाईं स्क्रीन को 30% बनाएं"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"दाईं स्क्रीन को फ़ुल स्क्रीन बनाएं"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"ऊपर की स्क्रीन को फ़ुल स्क्रीन बनाएं"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"ऊपर की स्क्रीन को 70% बनाएं"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"ऊपर की स्क्रीन को 50% बनाएं"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"ऊपर की स्क्रीन को 30% बनाएं"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"नीचे की स्क्रीन को फ़ुल स्क्रीन बनाएं"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"स्थिति <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. में बदलाव करने के लिए दो बार छूएं."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. जोड़ने के लिए दो बार छूएं."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"<xliff:g id="TILE_NAME">%1$s</xliff:g> को ले जाएं"</string> @@ -900,10 +889,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"<xliff:g id="TILE_NAME">%1$s</xliff:g> काे क्रम संख्या <xliff:g id="POSITION">%2$d</xliff:g> पर ले जाएं"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"त्वरित सेटिंग संपादक."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> सूचना: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"हो सकता है कि ऐप्लिकेशन विभाजित स्क्रीन के साथ काम ना करे."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"ऐप विभाजित स्क्रीन का समर्थन नहीं करता है."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"हो सकता है कि ऐप प्राइमरी (मुख्य) डिस्प्ले के अलावा बाकी दूसरे डिस्प्ले पर काम न करे."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"प्राइमरी (मुख्य) डिस्प्ले के अलावा बाकी दूसरे डिस्प्ले पर ऐप लॉन्च नहीं किया जा सकता."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"सेटिंग खोलें."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"क्विक सेटिंग खोलें."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"त्वरित सेटिंग बंद करें."</string> diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml index a27b06694588..27b6909159aa 100644 --- a/packages/SystemUI/res/values-hr/strings.xml +++ b/packages/SystemUI/res/values-hr/strings.xml @@ -884,17 +884,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Prikaži ikone obavijesti niskog prioriteta"</string> <string name="other" msgid="429768510980739978">"Ostalo"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Razdjelnik podijeljenog zaslona"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Lijevi zaslon u cijeli zaslon"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Lijevi zaslon na 70%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Lijevi zaslon na 50%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Lijevi zaslon na 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Desni zaslon u cijeli zaslon"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Gornji zaslon u cijeli zaslon"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Gornji zaslon na 70%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Gornji zaslon na 50%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Gornji zaslon na 30%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Donji zaslon u cijeli zaslon"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Položaj <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Dodirnite dvaput da biste uredili."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Dodirnite dvaput da biste dodali."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Premjesti <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> @@ -903,10 +892,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Premjestite pločicu <xliff:g id="TILE_NAME">%1$s</xliff:g> na položaj <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Uređivač brzih postavki."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> obavijest: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"Aplikacija možda neće funkcionirati s podijeljenim zaslonom."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Aplikacija ne podržava podijeljeni zaslon."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Aplikacija možda neće funkcionirati na sekundarnom zaslonu."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Aplikacija ne podržava pokretanje na sekundarnim zaslonima."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Otvaranje postavki."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Otvaranje brzih postavki."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Zatvaranje brzih postavki."</string> diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml index 0d1f50acc1c7..1f52b2cbe78b 100644 --- a/packages/SystemUI/res/values-hu/strings.xml +++ b/packages/SystemUI/res/values-hu/strings.xml @@ -428,7 +428,7 @@ <string name="quick_settings_nfc_off" msgid="3465000058515424663">"Az NFC ki van kapcsolva"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"Az NFC be van kapcsolva"</string> <string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Képernyő rögzítése"</string> - <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Kezdés"</string> + <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Indítás"</string> <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Leállítás"</string> <string name="media_seamless_remote_device" msgid="177033467332920464">"Eszköz"</string> <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Váltás az alkalmazások között felfelé csúsztatással"</string> @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Alacsony prioritású értesítési ikonok mutatása"</string> <string name="other" msgid="429768510980739978">"Egyéb"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Elválasztó az osztott nézetben"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Bal oldali teljes képernyőre"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Bal oldali 70%-ra"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Bal oldali 50%-ra"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Bal oldali 30%-ra"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Jobb oldali teljes képernyőre"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Felső teljes képernyőre"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Felső 70%-ra"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Felső 50%-ra"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Felső 30%-ra"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Alsó teljes képernyőre"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"<xliff:g id="POSITION">%1$d</xliff:g>. pozíció: <xliff:g id="TILE_NAME">%2$s</xliff:g>. Koppintson duplán a szerkesztéshez."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Koppintson duplán a hozzáadáshoz."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"A(z) <xliff:g id="TILE_NAME">%1$s</xliff:g> áthelyezése"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"<xliff:g id="TILE_NAME">%1$s</xliff:g> áthelyezése a következő pozícióba: <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Gyorsbeállítások szerkesztője"</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g>-értesítések: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"Lehet, hogy az alkalmazás nem működik osztott képernyős nézetben."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Az alkalmazás nem támogatja az osztott képernyős nézetet."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Előfordulhat, hogy az alkalmazás nem működik másodlagos kijelzőn."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Az alkalmazást nem lehet másodlagos kijelzőn elindítani."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Beállítások megnyitása."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Gyorsbeállítások megnyitása."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Gyorsbeállítások bezárása"</string> diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml index f9a10fa1578e..d4a093f78659 100644 --- a/packages/SystemUI/res/values-hy/strings.xml +++ b/packages/SystemUI/res/values-hy/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Ցուցադրել ցածր առաջնահերթության ծանուցումների պատկերակները"</string> <string name="other" msgid="429768510980739978">"Այլ"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Տրոհված էկրանի բաժանիչ"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Ձախ էկրանը՝ լիաէկրան"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Ձախ էկրանը՝ 70%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Ձախ էկրանը՝ 50%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Ձախ էկրանը՝ 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Աջ էկրանը՝ լիաէկրան"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Վերևի էկրանը՝ լիաէկրան"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Վերևի էկրանը՝ 70%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Վերևի էկրանը՝ 50%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Վերևի էկրանը՝ 30%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Ներքևի էկրանը՝ լիաէկրան"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Դիրք <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>: Կրկնակի հպեք՝ փոխելու համար:"</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>: Կրկնակի հպեք՝ ավելացնելու համար:"</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Տեղափոխել <xliff:g id="TILE_NAME">%1$s</xliff:g> սալիկը"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"<xliff:g id="TILE_NAME">%1$s</xliff:g> սալիկը տեղափոխել դիրք <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Արագ կարգավորումների խմբագրիչ:"</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> ծանուցում՝ <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"Հավելվածը չի կարող աշխատել տրոհված էկրանի ռեժիմում:"</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Հավելվածը չի աջակցում էկրանի տրոհումը:"</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Հավելվածը կարող է չաշխատել լրացուցիչ էկրանի վրա"</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Հավելվածը չի աջակցում գործարկումը լրացուցիչ էկրանների վրա"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Բացել կարգավորումները:"</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Բացել արագ կարգավորումները:"</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Փակել արագ կարգավորումները:"</string> diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml index f65be90bb00e..3b89b3d5e9fc 100644 --- a/packages/SystemUI/res/values-in/strings.xml +++ b/packages/SystemUI/res/values-in/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Tampilkan ikon notifikasi prioritas rendah"</string> <string name="other" msgid="429768510980739978">"Lainnya"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Pembagi layar terpisah"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Layar penuh di kiri"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Kiri 70%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Kiri 50%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Kiri 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Layar penuh di kanan"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Layar penuh di atas"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Atas 70%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Atas 50%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Atas 30%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Layar penuh di bawah"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Posisi <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Ketuk dua kali untuk mengedit."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Ketuk dua kali untuk menambahkan."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Pindahkan <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Pindahkan <xliff:g id="TILE_NAME">%1$s</xliff:g> ke posisi <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor setelan cepat."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Notifikasi <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"Aplikasi mungkin tidak berfungsi dengan layar terpisah."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"App tidak mendukung layar terpisah."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Aplikasi mungkin tidak berfungsi pada layar sekunder."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Aplikasi tidak mendukung peluncuran pada layar sekunder."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Buka setelan."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Buka setelan cepat."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Tutup setelan cepat."</string> diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml index 66c91477c1e8..da8a092bcc47 100644 --- a/packages/SystemUI/res/values-is/strings.xml +++ b/packages/SystemUI/res/values-is/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Sýna tákn fyrir tilkynningar með litlum forgangi"</string> <string name="other" msgid="429768510980739978">"Annað"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Skjáskipting"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Vinstri á öllum skjánum"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Vinstri 70%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Vinstri 50%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Vinstri 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Hægri á öllum skjánum"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Efri á öllum skjánum"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Efri 70%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Efri 50%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Efri 30%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Neðri á öllum skjánum"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Staða <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Ýttu tvisvar til að breyta."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Ýttu tvisvar til að bæta við."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Færa <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Færa <xliff:g id="TILE_NAME">%1$s</xliff:g> í stöðu <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Flýtistillingaritill."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> tilkynning: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"Hugsanlega virkar forritið ekki ef skjánum er skipt upp."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Forritið styður ekki að skjánum sé skipt."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Hugsanlegt er að forritið virki ekki á öðrum skjá."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Forrit styður ekki opnun á öðrum skjá."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Opna stillingar."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Opna flýtistillingar."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Loka flýtistillingum."</string> diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml index b0e64a27f154..0ec9c236f761 100644 --- a/packages/SystemUI/res/values-it/strings.xml +++ b/packages/SystemUI/res/values-it/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Mostra icone di notifiche con priorità bassa"</string> <string name="other" msgid="429768510980739978">"Altro"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Strumento per schermo diviso"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Schermata sinistra a schermo intero"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Schermata sinistra al 70%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Schermata sinistra al 50%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Schermata sinistra al 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Schermata destra a schermo intero"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Schermata superiore a schermo intero"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Schermata superiore al 70%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Schermata superiore al 50%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Schermata superiore al 30%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Schermata inferiore a schermo intero"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Posizione <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Tocca due volte per modificare."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Tocca due volte per aggiungere."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Sposta <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Sposta il riquadro <xliff:g id="TILE_NAME">%1$s</xliff:g> nella posizione <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor di impostazioni rapide."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Notifica di <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"L\'app potrebbe non funzionare con lo schermo diviso."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"L\'app non supporta la modalità Schermo diviso."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"L\'app potrebbe non funzionare su un display secondario."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"L\'app non supporta l\'avvio su display secondari."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Apri le impostazioni."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Apri le impostazioni rapide."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Chiudi le impostazioni rapide."</string> diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml index 92fa09b81e39..193c5f61fe3e 100644 --- a/packages/SystemUI/res/values-iw/strings.xml +++ b/packages/SystemUI/res/values-iw/strings.xml @@ -889,17 +889,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"הצגת סמלי התראות בעדיפות נמוכה"</string> <string name="other" msgid="429768510980739978">"אחר"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"מחלק מסך מפוצל"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"מסך שמאלי מלא"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"שמאלה 70%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"שמאלה 50%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"שמאלה 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"מסך ימני מלא"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"מסך עליון מלא"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"עליון 70%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"עליון 50%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"עליון 30%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"מסך תחתון מלא"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"מיקום <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. הקש פעמיים כדי לערוך."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. הקש פעמיים כדי להוסיף."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"הזזת <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> @@ -908,10 +897,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"העברת <xliff:g id="TILE_NAME">%1$s</xliff:g> למיקום <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"עורך הגדרות מהירות."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"התראות <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"ייתכן שהיישום לא יפעל עם מסך מפוצל."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"האפליקציה אינה תומכת במסך מפוצל."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"ייתכן שהאפליקציה לא תפעל במסך משני."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"האפליקציה אינה תומכת בהפעלה במסכים משניים."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"פתיחת הגדרות."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"פתיחה של \'הגדרות מהירות\'."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"סגירה של \'הגדרות מהירות\'."</string> diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml index e427c8f950e5..9aa9e76c1597 100644 --- a/packages/SystemUI/res/values-ja/strings.xml +++ b/packages/SystemUI/res/values-ja/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"優先度の低い通知アイコンを表示"</string> <string name="other" msgid="429768510980739978">"その他"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"分割画面の分割線"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"左全画面"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"左 70%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"左 50%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"左 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"右全画面"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"上部全画面"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"上 70%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"上 50%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"上 30%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"下部全画面"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"ポジション <xliff:g id="POSITION">%1$d</xliff:g> の <xliff:g id="TILE_NAME">%2$s</xliff:g> を編集するにはダブルタップします。"</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g> を追加するにはダブルタップします。"</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"<xliff:g id="TILE_NAME">%1$s</xliff:g> を移動します"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"<xliff:g id="TILE_NAME">%1$s</xliff:g> をポジション <xliff:g id="POSITION">%2$d</xliff:g> に移動"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"クイック設定エディタ"</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> の通知: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"アプリは分割画面では動作しないことがあります。"</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"アプリで分割画面がサポートされていません。"</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"アプリはセカンダリ ディスプレイでは動作しないことがあります。"</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"アプリはセカンダリ ディスプレイでの起動に対応していません。"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"設定を開きます。"</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"クイック設定を開きます。"</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"クイック設定を閉じます。"</string> diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml index b86bf8c32a75..aa6f35d00826 100644 --- a/packages/SystemUI/res/values-ka/strings.xml +++ b/packages/SystemUI/res/values-ka/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"დაბალი პრიორიტეტის მქონე შეტყობინებების ხატულების ჩვენება"</string> <string name="other" msgid="429768510980739978">"სხვა"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"გაყოფილი ეკრანის რეჟიმის გამყოფი"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"მარცხენა ნაწილის სრულ ეკრანზე გაშლა"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"მარცხენა ეკრანი — 70%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"მარცხენა ეკრანი — 50%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"მარცხენა ეკრანი — 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"მარჯვენა ნაწილის სრულ ეკრანზე გაშლა"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"ზედა ნაწილის სრულ ეკრანზე გაშლა"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"ზედა ეკრანი — 70%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"ზედა ეკრანი — 50%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"ზედა ეკრანი — 30%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"ქვედა ნაწილის სრულ ეკრანზე გაშლა"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"პოზიცია <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. რედაქტირებისთვის, შეეხეთ ორმაგად."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. დასამატებლად, შეეხეთ ორმაგად."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"<xliff:g id="TILE_NAME">%1$s</xliff:g>-ის გადატანა"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"<xliff:g id="TILE_NAME">%1$s</xliff:g>-ის გადატანა პოზიციაზე <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"სწრაფი პარამეტრების რედაქტორი."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> შეტყობინება: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"აპმა შეიძლება არ იმუშაოს გაყოფილი ეკრანის რეჟიმში."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"ეკრანის გაყოფა არ არის მხარდაჭერილი აპის მიერ."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"აპმა შეიძლება არ იმუშაოს მეორეულ ეკრანზე."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"აპს არ გააჩნია მეორეული ეკრანის მხარდაჭერა."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"პარამეტრების გახსნა."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"სწრაფი პარამეტრების გახსნა."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"სწრაფი პარამეტრების დახურვა."</string> diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml index 1adaf2bc2755..cafbc2b56732 100644 --- a/packages/SystemUI/res/values-kk/strings.xml +++ b/packages/SystemUI/res/values-kk/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Маңызды емес хабарландыру белгішелерін көрсету"</string> <string name="other" msgid="429768510980739978">"Басқа"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Бөлінген экран бөлгіші"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Сол жағын толық экранға шығару"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"70% сол жақта"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"50% сол жақта"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"30% сол жақта"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Оң жағын толық экранға шығару"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Жоғарғы жағын толық экранға шығару"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"70% жоғарғы жақта"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"50% жоғарғы жақта"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"30% жоғарғы жақта"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Төменгісін толық экранға шығару"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"<xliff:g id="POSITION">%1$d</xliff:g> орны, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Өңдеу үшін екі рет түртіңіз."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Қосу үшін екі рет түртіңіз."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"<xliff:g id="TILE_NAME">%1$s</xliff:g> жылжыту"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"<xliff:g id="TILE_NAME">%1$s</xliff:g> бөлшегін <xliff:g id="POSITION">%2$d</xliff:g>-позицияға жылжыту"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Жылдам параметрлер өңдегіші."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> хабарландыруы: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"Қолданба бөлінген экранда жұмыс істемеуі мүмкін."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Қодланба бөлінген экранды қолдамайды."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Қолданба қосымша дисплейде жұмыс істемеуі мүмкін."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Қолданба қосымша дисплейлерде іске қосуды қолдамайды."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Параметрлерді ашу."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Жылдам параметрлерді ашу."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Жылдам параметрлерді жабу."</string> diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml index 961a37b3cd57..5f16c7645511 100644 --- a/packages/SystemUI/res/values-km/strings.xml +++ b/packages/SystemUI/res/values-km/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"បង្ហាញរូបការជូនដំណឹងដែលមានអាទិភាពទាប"</string> <string name="other" msgid="429768510980739978">"ផ្សេងៗ"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"កម្មវិធីចែកអេក្រង់បំបែក"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"អេក្រង់ពេញខាងឆ្វេង"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"ឆ្វេង 70%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"ឆ្វេង 50%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"ឆ្វេង 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"អេក្រង់ពេញខាងស្តាំ"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"អេក្រង់ពេញខាងលើ"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"ខាងលើ 70%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"ខាងលើ 50%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"ខាងលើ 30%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"អេក្រង់ពេញខាងក្រោម"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"ទីតាំង <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>, ប៉ះពីរដងដើម្បីកែ"</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>, ប៉ះពីរដងដើម្បីបន្ថែម"</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"ផ្លាស់ទី <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"ផ្លាស់ទី <xliff:g id="TILE_NAME">%1$s</xliff:g> ទៅទីតាំង <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"កម្មវិធីកែការកំណត់រហ័ស"</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> ការជូនដំណឹង៖ <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"កម្មវិធីអាចនឹងមិនដំណើរការនៅលើអេក្រង់បំបែកទេ"</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"កម្មវិធីមិនគាំទ្រអេក្រង់បំបែកជាពីរទេ"</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"កម្មវិធីនេះប្រហែលជាមិនដំណើរការនៅលើអេក្រង់បន្ទាប់បន្សំទេ។"</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"កម្មវិធីនេះមិនអាចចាប់ផ្តើមនៅលើអេក្រង់បន្ទាប់បន្សំបានទេ។"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"បើកការកំណត់"</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"បើកការកំណត់រហ័ស"</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"បិទការកំណត់រហ័ស"</string> diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml index 7ec6a9f54a74..dff9ebd1a072 100644 --- a/packages/SystemUI/res/values-kn/strings.xml +++ b/packages/SystemUI/res/values-kn/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"ಕಡಿಮೆ-ಆದ್ಯತೆ ಸೂಚನೆಯ ಐಕಾನ್ಗಳನ್ನು ತೋರಿಸಿ"</string> <string name="other" msgid="429768510980739978">"ಇತರ"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"ಸ್ಪ್ಲಿಟ್-ಪರದೆ ಡಿವೈಡರ್"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"ಎಡ ಪೂರ್ಣ ಪರದೆ"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"70% ಎಡಕ್ಕೆ"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"50% ಎಡಕ್ಕೆ"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"30% ಎಡಕ್ಕೆ"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"ಬಲ ಪೂರ್ಣ ಪರದೆ"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"ಮೇಲಿನ ಪೂರ್ಣ ಪರದೆ"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"70% ಮೇಲಕ್ಕೆ"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"50% ಮೇಲಕ್ಕೆ"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"30% ಮೇಲಕ್ಕೆ"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"ಕೆಳಗಿನ ಪೂರ್ಣ ಪರದೆ"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"ಸ್ಥಳ <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. ಎಡಿಟ್ ಮಾಡಲು ಡಬಲ್ ಟ್ಯಾಪ್ ಮಾಡಿ."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. ಸೇರಿಸಲು ಡಬಲ್ ಟ್ಯಾಪ್ ಮಾಡಿ."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"<xliff:g id="TILE_NAME">%1$s</xliff:g> ಸರಿಸಿ"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"<xliff:g id="TILE_NAME">%1$s</xliff:g> ಅನ್ನು <xliff:g id="POSITION">%2$d</xliff:g> ಗೆ ಸರಿಸಿ"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ತ್ವರಿತ ಸೆಟ್ಟಿಂಗ್ಗಳ ಎಡಿಟರ್."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> ಅಧಿಸೂಚನೆ: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"ವಿಭಜಿಸಿದ ಪರದೆಯಲ್ಲಿ ಅಪ್ಲಿಕೇಶನ್ ಕೆಲಸ ಮಾಡದೇ ಇರಬಹುದು."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"ಅಪ್ಲಿಕೇಶನ್ ಸ್ಪ್ಲಿಟ್ ಸ್ಕ್ರೀನ್ ಅನ್ನು ಬೆಂಬಲಿಸುವುದಿಲ್ಲ."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"ಸೆಕೆಂಡರಿ ಡಿಸ್ಪ್ಲೇಗಳಲ್ಲಿ ಅಪ್ಲಿಕೇಶನ್ ಕಾರ್ಯ ನಿರ್ವಹಿಸದೇ ಇರಬಹುದು."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"ಸೆಕೆಂಡರಿ ಡಿಸ್ಪ್ಲೇಗಳಲ್ಲಿ ಪ್ರಾರಂಭಿಸುವಿಕೆಯನ್ನು ಅಪ್ಲಿಕೇಶನ್ ಬೆಂಬಲಿಸುವುದಿಲ್ಲ."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ತೆರೆಯಿರಿ."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"ತ್ವರಿತ ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ತೆರೆಯಿರಿ."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"ತ್ವರಿತ ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ಮುಚ್ಚಿ."</string> diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml index 840a98e32e23..181888f29161 100644 --- a/packages/SystemUI/res/values-ko/strings.xml +++ b/packages/SystemUI/res/values-ko/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"우선순위가 낮은 알림 아이콘 표시"</string> <string name="other" msgid="429768510980739978">"기타"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"화면 분할기"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"왼쪽 화면 전체화면"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"왼쪽 화면 70%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"왼쪽 화면 50%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"왼쪽 화면 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"오른쪽 화면 전체화면"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"위쪽 화면 전체화면"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"위쪽 화면 70%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"위쪽 화면 50%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"위쪽 화면 30%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"아래쪽 화면 전체화면"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"위치 <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. 수정하려면 두 번 탭하세요."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. 추가하려면 두 번 탭하세요."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"<xliff:g id="TILE_NAME">%1$s</xliff:g> 이동"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"<xliff:g id="TILE_NAME">%1$s</xliff:g> 타일을 위치 <xliff:g id="POSITION">%2$d</xliff:g>(으)로 이동"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"빠른 설정 편집기"</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> 알림: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"앱이 분할 화면에서 작동하지 않을 수 있습니다."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"앱이 화면 분할을 지원하지 않습니다."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"앱이 보조 디스플레이에서 작동하지 않을 수도 있습니다."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"앱이 보조 디스플레이에서의 실행을 지원하지 않습니다."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"설정 열기"</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"빠른 설정 열기"</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"빠른 설정 닫기"</string> diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml index 14ee566d305c..47fc3a8fbf31 100644 --- a/packages/SystemUI/res/values-ky/strings.xml +++ b/packages/SystemUI/res/values-ky/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Анча маанилүү эмес билдирменин сүрөтчөлөрүн көрсөтүү"</string> <string name="other" msgid="429768510980739978">"Башка"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Экранды бөлгүч"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Сол жактагы экранды толук экран режимине өткөрүү"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Сол жактагы экранды 70%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Сол жактагы экранды 50%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Сол жактагы экранды 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Оң жактагы экранды толук экран режимине өткөрүү"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Үстүнкү экранды толук экран режимине өткөрүү"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Үстүнкү экранды 70%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Үстүнкү экранды 50%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Үстүнкү экранды 30%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Ылдыйкы экранды толук экран режимине өткөрүү"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Орду - <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Түзөтүү үчүн эки жолу таптаңыз."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Кошуу үчүн эки жолу таптаңыз."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"<xliff:g id="TILE_NAME">%1$s</xliff:g> дегенди жылдыруу"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"<xliff:g id="TILE_NAME">%1$s</xliff:g> плиткасы <xliff:g id="POSITION">%2$d</xliff:g>-позицияга кошулсун"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Ыкчам жөндөөлөр түзөткүчү."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> эскертмеси: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"Колдонмодо экран бөлүнбөшү мүмкүн."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Колдонмодо экран бөлүнбөйт."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Колдонмо кошумча экранда иштебей коюшу мүмкүн."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Колдонмону кошумча экрандарда иштетүүгө болбойт."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Жөндөөлөрдү ачуу."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Ыкчам жөндөөлөрдү ачуу."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Ыкчам жөндөөлөрдү жабуу."</string> diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml index 553d0da2e295..cb875559011d 100644 --- a/packages/SystemUI/res/values-lo/strings.xml +++ b/packages/SystemUI/res/values-lo/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"ສະແດງໄອຄອນການແຈ້ງເຕືອນຄວາມສຳຄັນຕ່ຳ"</string> <string name="other" msgid="429768510980739978">"ອື່ນໆ"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"ຕົວຂັ້ນການແບ່ງໜ້າຈໍ"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"ເຕັມໜ້າຈໍຊ້າຍ"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"ຊ້າຍ 70%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"ຊ້າຍ 50%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"ຊ້າຍ 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"ເຕັມໜ້າຈໍຂວາ"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"ເຕັມໜ້າຈໍເທິງສຸດ"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"ເທິງສຸດ 70%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"ເທິງສຸດ 50%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"ເທິງສຸດ 30%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"ເຕັມໜ້າຈໍລຸ່ມສຸດ"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"ຕຳແໜ່ງ <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. ແຕະສອງເທື່ອເພື່ອແກ້ໄຂ."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. ແຕະສອງເທື່ອເພື່ອເພີ່ມ."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"ຍ້າຍ <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"ຍ້າຍ <xliff:g id="TILE_NAME">%1$s</xliff:g> ໄປຕຳແໜ່ງ <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ຕົວແກ້ໄຂການຕັ້ງຄ່າດ່ວນ"</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"ການແຈ້ງເຕືອນ <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"ແອັບອາດໃຊ້ບໍ່ໄດ້ກັບການແບ່ງໜ້າຈໍ."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"ແອັບບໍ່ຮອງຮັບໜ້າຈໍແບບແຍກກັນ."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"ແອັບອາດບໍ່ສາມາດໃຊ້ໄດ້ໃນໜ້າຈໍທີສອງ."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"ແອັບບໍ່ຮອງຮັບການເປີດໃນໜ້າຈໍທີສອງ."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"ເປີດການຕັ້ງຄ່າ."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"ເປີດການຕັ້ງຄ່າດ່ວນ."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"ປິດການຕັ້ງຄ່າດ່ວນ."</string> diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml index 28d6e6b35431..ac90c0f58e68 100644 --- a/packages/SystemUI/res/values-lt/strings.xml +++ b/packages/SystemUI/res/values-lt/strings.xml @@ -889,17 +889,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Rodyti mažo prioriteto pranešimų piktogramas"</string> <string name="other" msgid="429768510980739978">"Kita"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Skaidyto ekrano daliklis"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Kairysis ekranas viso ekrano režimu"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Kairysis ekranas 70 %"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Kairysis ekranas 50 %"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Kairysis ekranas 30 %"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Dešinysis ekranas viso ekrano režimu"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Viršutinis ekranas viso ekrano režimu"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Viršutinis ekranas 70 %"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Viršutinis ekranas 50 %"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Viršutinis ekranas 30 %"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Apatinis ekranas viso ekrano režimu"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"<xliff:g id="POSITION">%1$d</xliff:g> padėtis, išklotinės elementas „<xliff:g id="TILE_NAME">%2$s</xliff:g>“. Dukart palieskite, kad redaguotumėte."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"Išklotinės elementas „<xliff:g id="TILE_NAME">%1$s</xliff:g>“. Dukart palieskite, kad pridėtumėte."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Perkelti išklotinės elementą „<xliff:g id="TILE_NAME">%1$s</xliff:g>“"</string> @@ -908,10 +897,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Perkelti išklotinės elementą „<xliff:g id="TILE_NAME">%1$s</xliff:g>“ į <xliff:g id="POSITION">%2$d</xliff:g> padėtį"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Sparčiųjų nustatymų redagavimo priemonė."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"„<xliff:g id="ID_1">%1$s</xliff:g>“ pranešimas: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"Programa gali neveikti naudojant skaidytą ekraną."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Programoje nepalaikomas skaidytas ekranas."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Programa gali neveikti antriniame ekrane."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Programa nepalaiko paleisties antriniuose ekranuose."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Atidaryti nustatymus."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Atidaryti sparčiuosius nustatymus."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Uždaryti sparčiuosius nustatymus."</string> diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml index 223a57fdb640..2f5edd3f0d9f 100644 --- a/packages/SystemUI/res/values-lv/strings.xml +++ b/packages/SystemUI/res/values-lv/strings.xml @@ -884,17 +884,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Rādīt zemas prioritātes paziņojumu ikonas"</string> <string name="other" msgid="429768510980739978">"Citi"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Ekrāna sadalītājs"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Kreisā daļa pa visu ekrānu"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Pa kreisi 70%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Pa kreisi 50%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Pa kreisi 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Labā daļa pa visu ekrānu"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Augšdaļa pa visu ekrānu"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Augšdaļa 70%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Augšdaļa 50%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Augšdaļa 30%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Apakšdaļu pa visu ekrānu"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"<xliff:g id="POSITION">%1$d</xliff:g>. pozīcija, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Lai rediģētu, veiciet dubultskārienu."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Lai pievienotu, veiciet dubultskārienu."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Pārvietot elementu <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> @@ -903,10 +892,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Pārvietot elementu “<xliff:g id="TILE_NAME">%1$s</xliff:g>” uz <xliff:g id="POSITION">%2$d</xliff:g>. pozīciju"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Ātro iestatījumu redaktors."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> paziņojums: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"Iespējams, lietotnē nedarbosies ekrāna sadalīšana."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Lietotnē netiek atbalstīta ekrāna sadalīšana."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Lietotne, iespējams, nedarbosies sekundārajā displejā."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Lietotnē netiek atbalstīta palaišana sekundārajos displejos."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Atvērt iestatījumus."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Atvērt ātros iestatījumus."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Aizvērt ātros iestatījumus."</string> diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml index a591031cabba..de9cf0fb57bf 100644 --- a/packages/SystemUI/res/values-mk/strings.xml +++ b/packages/SystemUI/res/values-mk/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Прикажувај икони за известувања со низок приоритет"</string> <string name="other" msgid="429768510980739978">"Друго"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Разделник на поделен екран"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Левиот на цел екран"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Левиот 70%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Левиот 50%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Левиот 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Десниот на цел екран"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Горниот на цел екран"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Горниот 70%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Горниот 50%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Горниот 30%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Долниот на цел екран"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Место <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Допрете двапати за уредување."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Допрете двапати за додавање."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Преместете <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Преместете <xliff:g id="TILE_NAME">%1$s</xliff:g> на позицијата <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Уредник за брзи поставки."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Известување од <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"Апликацијата можеби нема да работи во поделен екран."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Апликацијата не поддржува поделен екран."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Апликацијата може да не функционира на друг екран."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Апликацијата не поддржува стартување на други екрани."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Отворете ги поставките."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Отворете ги брзите поставки."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Затворете ги брзите поставки."</string> diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml index 47d220df5bde..bd5187456574 100644 --- a/packages/SystemUI/res/values-ml/strings.xml +++ b/packages/SystemUI/res/values-ml/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"പ്രാധാന്യം കുറഞ്ഞ അറിയിപ്പ് ചിഹ്നങ്ങൾ"</string> <string name="other" msgid="429768510980739978">"മറ്റുള്ളവ"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"സ്പ്ലിറ്റ്-സ്ക്രീൻ ഡിവൈഡർ"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"ഇടത് പൂർണ്ണ സ്ക്രീൻ"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"ഇടത് 70%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"ഇടത് 50%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"ഇടത് 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"വലത് പൂർണ്ണ സ്ക്രീൻ"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"മുകളിൽ പൂർണ്ണ സ്ക്രീൻ"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"മുകളിൽ 70%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"മുകളിൽ 50%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"മുകളിൽ 30%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"താഴെ പൂർണ്ണ സ്ക്രീൻ"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"സ്ഥാനം <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. എഡിറ്റുചെയ്യുന്നതിന് രണ്ടുതവണ ടാപ്പുചെയ്യുക."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. ചേർക്കാൻ രണ്ടുതവണ ടാപ്പുചെയ്യുക."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"<xliff:g id="TILE_NAME">%1$s</xliff:g> നീക്കുക"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"<xliff:g id="POSITION">%2$d</xliff:g> സ്ഥാനത്തേയ്ക്ക് <xliff:g id="TILE_NAME">%1$s</xliff:g> നീക്കുക"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ദ്രുത ക്രമീകരണ എഡിറ്റർ."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> അറിയിപ്പ്: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"സ്പ്ലിറ്റ്-സ്ക്രീനിനൊപ്പം ആപ്പ് പ്രവർത്തിച്ചേക്കില്ല."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"സ്പ്ലിറ്റ്-സ്ക്രീനിനെ ആപ്പ് പിന്തുണയ്ക്കുന്നില്ല."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"രണ്ടാം ഡിസ്പ്ലേയിൽ ആപ്പ് പ്രവർത്തിച്ചേക്കില്ല."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"രണ്ടാം ഡിസ്പ്ലേകളിൽ സമാരംഭിക്കുന്നതിനെ ആപ്പ് അനുവദിക്കുന്നില്ല."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"ക്രമീകരണം തുറക്കുക."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"ദ്രുത ക്രമീകരണം തുറക്കുക."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"ദ്രുത ക്രമീകരണം അടയ്ക്കുക."</string> diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml index 202f292503b0..14401030fb21 100644 --- a/packages/SystemUI/res/values-mn/strings.xml +++ b/packages/SystemUI/res/values-mn/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Бага ач холбогдолтой мэдэгдлийн дүрс тэмдгийг харуулах"</string> <string name="other" msgid="429768510980739978">"Бусад"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"\"Дэлгэц хуваах\" хуваагч"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Зүүн талын бүтэн дэлгэц"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Зүүн 70%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Зүүн 50%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Зүүн 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Баруун талын бүтэн дэлгэц"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Дээд талын бүтэн дэлгэц"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Дээд 70%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Дээд 50%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Дээд 30%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Доод бүтэн дэлгэц"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Байршил <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Засахын тулд 2 удаа дарна уу."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Нэмэхийн тулд 2 удаа дарна уу."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"<xliff:g id="TILE_NAME">%1$s</xliff:g>-г зөөх"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"<xliff:g id="TILE_NAME">%1$s</xliff:g>-г байрлал <xliff:g id="POSITION">%2$d</xliff:g> руу зөөх"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Түргэн тохиргоо засварлагч."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> мэдэгдэл: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"Апп хуваагдсан дэлгэцэд ажиллахгүй."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Энэ апп нь дэлгэц хуваах тохиргоог дэмждэггүй."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Апп хоёрдогч дэлгэцэд ажиллахгүй."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Аппыг хоёрдогч дэлгэцэд эхлүүлэх боломжгүй."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Тохиргоог нээнэ үү."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Шуурхай тохиргоог нээнэ үү."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Хурдан тохиргоог хаана уу."</string> diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml index e4120726c66c..32fe7bdecb42 100644 --- a/packages/SystemUI/res/values-mr/strings.xml +++ b/packages/SystemUI/res/values-mr/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"कमी प्राधान्य सूचना आयकन दर्शवा"</string> <string name="other" msgid="429768510980739978">"अन्य"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"विभाजित-स्क्रीन विभाजक"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"डावी फुल स्क्रीन"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"डावी 70%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"डावी 50%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"डावी 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"उजवी फुल स्क्रीन"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"शीर्ष फुल स्क्रीन"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"शीर्ष 70%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"शीर्ष 50%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"शीर्ष 10"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"तळाशी फुल स्क्रीन"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"स्थिती <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. संपादित करण्यासाठी दोनदा टॅप करा."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g> . जोडण्यासाठी दोनदा टॅप करा."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"<xliff:g id="TILE_NAME">%1$s</xliff:g> हलवा"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"<xliff:g id="TILE_NAME">%1$s</xliff:g> <xliff:g id="POSITION">%2$d</xliff:g> स्थानावर हलवा"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"द्रुत सेटिंग्ज संपादक."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> सूचना: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"अॅप कदाचित विभाजित-स्क्रीनसह कार्य करू शकत नाही."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"अॅप स्क्रीन-विभाजनास समर्थन देत नाही."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"दुसऱ्या डिस्प्लेवर अॅप कदाचित चालणार नाही."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"दुसऱ्या डिस्प्लेवर अॅप लाँच होणार नाही."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"सेटिंग्ज उघडा."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"जलद सेटिंग्ज उघडा."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"जलद सेटिंग्ज बंद करा."</string> diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml index 0331d26e4ec7..fe246d1a6129 100644 --- a/packages/SystemUI/res/values-ms/strings.xml +++ b/packages/SystemUI/res/values-ms/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Tunjukkan ikon pemberitahuan keutamaan rendah"</string> <string name="other" msgid="429768510980739978">"Lain-lain"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Pembahagi skrin pisah"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Skrin penuh kiri"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Kiri 70%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Kiri 50%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Kiri 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Skrin penuh kanan"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Skrin penuh atas"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Atas 70%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Atas 50%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Atas 30%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Skrin penuh bawah"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Kedudukan <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Dwiketik untuk mengedit."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Dwiketik untuk menambah."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Alihkan <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Alihkan <xliff:g id="TILE_NAME">%1$s</xliff:g> ke kedudukan <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor tetapan pantas."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Pemberitahuan <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"Apl mungkin tidak berfungsi dengan skrin pisah."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Apl tidak menyokong skrin pisah."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Apl mungkin tidak berfungsi pada paparan kedua."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Apl tidak menyokong pelancaran pada paparan kedua."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Buka tetapan."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Buka tetapan pantas."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Tutup tetapan pantas."</string> diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml index 83272f2a43c4..53c02a54ef7c 100644 --- a/packages/SystemUI/res/values-my/strings.xml +++ b/packages/SystemUI/res/values-my/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"အရေးမကြီးသော အကြောင်းကြားချက် သင်္ကေတများ ပြရန်"</string> <string name="other" msgid="429768510980739978">"အခြား"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"မျက်နှာပြင်ခွဲခြမ်း ပိုင်းခြားပေးသည့်စနစ်"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"ဘယ်ဘက် မျက်နှာပြင်အပြည့်"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"ဘယ်ဘက်မျက်နှာပြင် ၇၀%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"ဘယ်ဘက် မျက်နှာပြင် ၅၀%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"ဘယ်ဘက် မျက်နှာပြင် ၃၀%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"ညာဘက် မျက်နှာပြင်အပြည့်"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"အပေါ်ဘက် မျက်နှာပြင်အပြည့်"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"အပေါ်ဘက် မျက်နှာပြင် ၇၀%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"အပေါ်ဘက် မျက်နှာပြင် ၅၀%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"အပေါ်ဘက် မျက်နှာပြင် ၃၀%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"အောက်ခြေ မျက်နှာပြင်အပြည့်"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"<xliff:g id="POSITION">%1$d</xliff:g>၊ <xliff:g id="TILE_NAME">%2$s</xliff:g> နေရာ။ တည်းဖြတ်ရန် နှစ်ချက်တို့ပါ။"</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>။ ပေါင်းထည့်ရန် နှစ်ချက်တို့ပါ။"</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"<xliff:g id="TILE_NAME">%1$s</xliff:g> ကိုရွှေ့ပါ"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"<xliff:g id="TILE_NAME">%1$s</xliff:g> ကို အနေအထား <xliff:g id="POSITION">%2$d</xliff:g> သို့ ရွှေ့ရန်"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"မြန်ဆန်သည့် ဆက်တင်တည်းဖြတ်စနစ်"</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> အကြောင်းကြားချက် − <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"မျက်နှာပြင် ခွဲခြမ်းပြသမှုဖြင့် အက်ပ်သည် အလုပ်လုပ်မည် မဟုတ်ပါ။"</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"အက်ပ်သည် မျက်နှာပြင်ခွဲပြရန် ပံ့ပိုးထားခြင်းမရှိပါ။"</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"ဤအက်ပ်အနေဖြင့် ဒုတိယဖန်သားပြင်ပေါ်တွင် အလုပ်လုပ်မည် မဟုတ်ပါ။"</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"ဤအက်ပ်အနေဖြင့် ဖွင့်ရန်စနစ်ကို ဒုတိယဖန်သားပြင်မှ အသုံးပြုရန် ပံ့ပိုးမထားပါ။"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"ဆက်တင်များကို ဖွင့်ပါ။"</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"အမြန်ဆက်တင်များကို ဖွင့်ပါ။"</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"အမြန်ဆက်တင်များကို ပိတ်ပါ။"</string> diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml index 01859ef5a13e..5c9f63f3a797 100644 --- a/packages/SystemUI/res/values-nb/strings.xml +++ b/packages/SystemUI/res/values-nb/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Vis ikoner for varsler med lav prioritet"</string> <string name="other" msgid="429768510980739978">"Annet"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Skilleelement for delt skjerm"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Utvid den venstre delen av skjermen til hele skjermen"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Sett størrelsen på den venstre delen av skjermen til 70 %"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Sett størrelsen på den venstre delen av skjermen til 50 %"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Sett størrelsen på den venstre delen av skjermen til 30 %"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Utvid den høyre delen av skjermen til hele skjermen"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Utvid den øverste delen av skjermen til hele skjermen"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Sett størrelsen på den øverste delen av skjermen til 70 %"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Sett størrelsen på den øverste delen av skjermen til 50 %"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Sett størrelsen på den øverste delen av skjermen til 30 %"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Utvid den nederste delen av skjermen til hele skjermen"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Plassering <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Dobbelttrykk for å endre."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Dobbelttrykk for å legge til."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Flytt <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Flytt <xliff:g id="TILE_NAME">%1$s</xliff:g> til posisjon <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Redigeringsvindu for hurtiginnstillinger."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g>-varsel: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"Det kan hende at appen ikke fungerer med delt skjerm."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Appen støtter ikke delt skjerm."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Appen fungerer kanskje ikke på en sekundær skjerm."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Appen kan ikke kjøres på sekundære skjermer."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Åpne innstillingene."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Åpner hurtiginnstillingene."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Lukk hurtiginnstillingene."</string> diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml index 196b4ad2f94e..791e4d3d3f20 100644 --- a/packages/SystemUI/res/values-ne/strings.xml +++ b/packages/SystemUI/res/values-ne/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"कम प्राथमिकताका सूचना आइकनहरू देखाउनुहोस्"</string> <string name="other" msgid="429768510980739978">"अन्य"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"विभाजित-स्क्रिन छुट्याउने"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"बायाँ भाग फुल स्क्रिन"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"बायाँ भाग ७०%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"बायाँ भाग ५०%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"बायाँ भाग ३०%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"दायाँ भाग फुल स्क्रिन"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"माथिल्लो भाग फुल स्क्रिन"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"माथिल्लो भाग ७०%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"माथिल्लो भाग ५०%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"माथिल्लो भाग ३०%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"तल्लो भाग फुल स्क्रिन"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"स्थिति <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>। सम्पादन गर्नाका लागि डबल ट्याप गर्नुहोस्।"</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>। थप्नका लागि डबल ट्याप गर्नुहोस्।"</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"<xliff:g id="TILE_NAME">%1$s</xliff:g> लाई सार्नुहोस्"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"<xliff:g id="TILE_NAME">%1$s</xliff:g> लाई <xliff:g id="POSITION">%2$d</xliff:g> स्थितिमा सार्नुहोस्"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"द्रुत सेटिङ सम्पादक।"</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> को सूचना: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"अनुप्रयोगले विभाजित-स्क्रिनमा काम नगर्न सक्छ।"</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"अनुप्रयोगले विभाजित-स्क्रिनलाई समर्थन गर्दैन।"</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"यो अनुप्रयोगले सहायक प्रदर्शनमा काम नगर्नसक्छ।"</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"अनुप्रयोगले सहायक प्रदर्शनहरूमा लञ्च सुविधालाई समर्थन गर्दैन।"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"सेटिङहरूलाई खोल्नुहोस्।"</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"द्रुत सेटिङहरूलाई खोल्नुहोस्।"</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"द्रुत सेटिङहरूलाई बन्द गर्नुहोस्।"</string> diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml index fa028c336594..b02be5d241d7 100644 --- a/packages/SystemUI/res/values-nl/strings.xml +++ b/packages/SystemUI/res/values-nl/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Pictogrammen voor meldingen met lage prioriteit weergeven"</string> <string name="other" msgid="429768510980739978">"Overig"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Scheiding voor gesplitst scherm"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Linkerscherm op volledig scherm"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Linkerscherm 70%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Linkerscherm 50%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Linkerscherm 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Rechterscherm op volledig scherm"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Bovenste scherm op volledig scherm"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Bovenste scherm 70%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Bovenste scherm 50%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Bovenste scherm 30%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Onderste scherm op volledig scherm"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Positie <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Dubbeltik om te bewerken."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Dubbeltik om toe te voegen."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"<xliff:g id="TILE_NAME">%1$s</xliff:g> verplaatsen"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"<xliff:g id="TILE_NAME">%1$s</xliff:g> verplaatsen naar positie <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor voor \'Snelle instellingen\'."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g>-melding: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"App werkt mogelijk niet met gesplitst scherm."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"App biedt geen ondersteuning voor gesplitst scherm."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"App werkt mogelijk niet op een secundair scherm."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"App kan niet op secundaire displays worden gestart."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Instellingen openen."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Snelle instellingen openen."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Snelle instellingen sluiten."</string> diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml index 4c6ef486436a..c7de8ca38cb2 100644 --- a/packages/SystemUI/res/values-or/strings.xml +++ b/packages/SystemUI/res/values-or/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"କମ୍-ଅଗ୍ରାଧିକାର ବିଜ୍ଞପ୍ତି ଆଇକନ୍ ଦେଖାନ୍ତୁ"</string> <string name="other" msgid="429768510980739978">"ଅନ୍ୟାନ୍ୟ"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"ସ୍ପ୍ଲିଟ୍-ସ୍କ୍ରୀନ ବିଭାଜକ"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"ବାମ ପଟକୁ ପୂର୍ଣ୍ଣ ସ୍କ୍ରୀନ୍ କରନ୍ତୁ"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"ବାମ ପଟକୁ 70% କରନ୍ତୁ"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"ବାମ ପଟକୁ 50% କରନ୍ତୁ"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"ବାମ ପଟେ 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"ଡାହାଣ ପଟକୁ ପୂର୍ଣ୍ଣ ସ୍କ୍ରୀନ୍ କରନ୍ତୁ"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"ଉପର ଆଡ଼କୁ ପୂର୍ଣ୍ଣ ସ୍କ୍ରୀନ୍ କରନ୍ତୁ"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"ଉପର ଆଡ଼କୁ 70% କରନ୍ତୁ"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"ଉପର ଆଡ଼କୁ 50% କରନ୍ତୁ"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"ଉପର ଆଡ଼କୁ 30% କରନ୍ତୁ"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"ତଳ ଅଂଶର ପୂର୍ଣ୍ଣ ସ୍କ୍ରୀନ୍"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"ଅବସ୍ଥାନ <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>। ଏଡିଟ୍ କରିବାକୁ ଡବଲ୍-ଟାପ୍ କରନ୍ତୁ।"</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>। ଯୋଡ଼ିବା ପାଇଁ ଡବଲ୍-ଟାପ୍ କରନ୍ତୁ।"</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"<xliff:g id="TILE_NAME">%1$s</xliff:g> ନିଅନ୍ତୁ"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"<xliff:g id="POSITION">%2$d</xliff:g> ଅବସ୍ଥାନକୁ <xliff:g id="TILE_NAME">%1$s</xliff:g> ଘୁଞ୍ଚାନ୍ତୁ"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ଦ୍ରୁତ ସେଟିଙ୍ଗ ଏଡିଟର୍।"</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> ବିଜ୍ଞପ୍ତି: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"ସ୍ପ୍ଲିଟ୍-ସ୍କ୍ରୀନରେ ଆପ୍ କାମ କରିନପାରେ।"</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"ଆପ୍ ସ୍ପ୍ଲିଟ୍-ସ୍କ୍ରୀନକୁ ସପୋର୍ଟ କରେ ନାହିଁ।"</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"ସେକେଣ୍ଡାରୀ ଡିସପ୍ଲେରେ ଆପ୍ କାମ ନକରିପାରେ।"</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"ସେକେଣ୍ଡାରୀ ଡିସପ୍ଲେରେ ଆପ୍ ଲଞ୍ଚ ସପୋର୍ଟ କରେ ନାହିଁ।"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"ସେଟିଂସ୍ ଖୋଲନ୍ତୁ।"</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"ଦ୍ରୁତ ସେଟିଙ୍ଗ ଖୋଲନ୍ତୁ।"</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"ଦ୍ରୁତ ସେଟିଂସ୍ ବନ୍ଦ କରନ୍ତୁ।"</string> diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml index 98583c0aedca..66333b9e09fe 100644 --- a/packages/SystemUI/res/values-pa/strings.xml +++ b/packages/SystemUI/res/values-pa/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"ਘੱਟ ਤਰਜੀਹ ਵਾਲੇ ਸੂਚਨਾ ਪ੍ਰਤੀਕਾਂ ਨੂੰ ਦਿਖਾਓ"</string> <string name="other" msgid="429768510980739978">"ਹੋਰ"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"ਸਪਲਿਟ-ਸਕ੍ਰੀਨ ਡਿਵਾਈਡਰ"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"ਖੱਬੇ ਪੂਰੀ ਸਕ੍ਰੀਨ"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"ਖੱਬੇ 70%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"ਖੱਬੇ 50%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"ਖੱਬੇ 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"ਸੱਜੇ ਪੂਰੀ ਸਕ੍ਰੀਨ"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"ਉੱਪਰ ਪੂਰੀ ਸਕ੍ਰੀਨ"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"ਉੱਪਰ 70%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"ਉੱਪਰ 50%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"ਉੱਪਰ 30%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"ਹੇਠਾਂ ਪੂਰੀ ਸਕ੍ਰੀਨ"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"ਸਥਿਤੀ <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>। ਸੰਪਾਦਨ ਲਈ ਦੋ ਵਾਰ ਟੈਪ ਕਰੋ।"</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>। ਸ਼ਾਮਲ ਕਰਨ ਲਈ ਦੋ ਵਾਰ ਟੈਪ ਕਰੋ।"</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"<xliff:g id="TILE_NAME">%1$s</xliff:g> ਨੂੰ ਤਬਦੀਲ ਕਰੋ"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"<xliff:g id="TILE_NAME">%1$s</xliff:g> ਨੂੰ <xliff:g id="POSITION">%2$d</xliff:g> ਸਥਾਨ \'ਤੇ ਲਿਜਾਓ"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ਤਤਕਾਲ ਸੈਟਿੰਗਾਂ ਸੰਪਾਦਕ।"</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> ਸੂਚਨਾ: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"ਹੋ ਸਕਦਾ ਹੈ ਕਿ ਐਪ ਸਪਲਿਟ-ਸਕ੍ਰੀਨ ਨਾਲ ਕੰਮ ਨਾ ਕਰੇ।"</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"ਐਪ ਸਪਲਿਟ-ਸਕ੍ਰੀਨ ਨੂੰ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦੀ।"</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"ਹੋ ਸਕਦਾ ਹੈ ਕਿ ਐਪ ਸੈਕੰਡਰੀ ਡਿਸਪਲੇ \'ਤੇ ਕੰਮ ਨਾ ਕਰੇ।"</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"ਐਪ ਸੈਕੰਡਰੀ ਡਿਸਪਲੇਆਂ \'ਤੇ ਲਾਂਚ ਕਰਨ ਦਾ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦੀ"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"ਸੈਟਿੰਗਾਂ ਖੋਲ੍ਹੋ।"</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"ਤਤਕਾਲ ਸੈਟਿੰਗਾਂ ਨੂੰ ਖੋਲ੍ਹੋ।"</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"ਤਤਕਾਲ ਸੈਟਿੰਗਾਂ ਨੂੰ ਬੰਦ ਕਰੋ।"</string> diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml index 4d5a2ae88949..c68e3ac46932 100644 --- a/packages/SystemUI/res/values-pl/strings.xml +++ b/packages/SystemUI/res/values-pl/strings.xml @@ -889,17 +889,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Pokazuj ikony powiadomień o niskim priorytecie"</string> <string name="other" msgid="429768510980739978">"Inne"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Linia dzielenia ekranu"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Lewa część ekranu na pełnym ekranie"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"70% lewej części ekranu"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"50% lewej części ekranu"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"30% lewej części ekranu"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Prawa część ekranu na pełnym ekranie"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Górna część ekranu na pełnym ekranie"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"70% górnej części ekranu"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"50% górnej części ekranu"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"30% górnej części ekranu"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Dolna część ekranu na pełnym ekranie"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Położenie <xliff:g id="POSITION">%1$d</xliff:g>, kafelek <xliff:g id="TILE_NAME">%2$s</xliff:g>. Kliknij dwukrotnie, by edytować."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"Kafelek <xliff:g id="TILE_NAME">%1$s</xliff:g>. Kliknij dwukrotnie, by dodać."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Przenieś kafelek <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> @@ -908,10 +897,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Przenieś kafelek <xliff:g id="TILE_NAME">%1$s</xliff:g> w położenie <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Edytor szybkich ustawień."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Powiadomienie z aplikacji <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"Aplikacja może nie działać przy podzielonym ekranie."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Aplikacja nie obsługuje dzielonego ekranu."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Aplikacja może nie działać na dodatkowym ekranie."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Aplikacja nie obsługuje uruchamiania na dodatkowych ekranach."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Otwórz ustawienia."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Otwórz szybkie ustawienia."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Zamknij szybkie ustawienia."</string> @@ -1016,7 +1001,7 @@ <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Przenieś w lewy dolny róg"</string> <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Przenieś w prawy dolny róg"</string> <string name="bubble_dismiss_text" msgid="1314082410868930066">"Zamknij dymek"</string> - <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Nie wyświetlaj rozmowy jako dymku"</string> + <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Nie wyświetlaj rozmowy jako dymka"</string> <string name="bubbles_user_education_title" msgid="5547017089271445797">"Czatuj, korzystając z dymków"</string> <string name="bubbles_user_education_description" msgid="1160281719576715211">"Nowe rozmowy będą wyświetlane jako pływające ikony lub dymki. Kliknij, by otworzyć dymek. Przeciągnij, by go przenieść."</string> <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Zarządzaj dymkami w dowolnym momencie"</string> diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml index ef5c9cee6ee4..ff2ecd38547f 100644 --- a/packages/SystemUI/res/values-pt-rBR/strings.xml +++ b/packages/SystemUI/res/values-pt-rBR/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Mostrar ícones de notificações de baixa prioridade"</string> <string name="other" msgid="429768510980739978">"Outros"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Divisor de tela"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Lado esquerdo em tela cheia"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Esquerda a 70%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Esquerda a 50%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Esquerda a 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Lado direito em tela cheia"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Parte superior em tela cheia"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Parte superior a 70%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Parte superior a 50%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Parte superior a 30%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Parte inferior em tela cheia"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Posição <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Toque duas vezes para editar."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Toque duas vezes para adicionar."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Move <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Mover <xliff:g id="TILE_NAME">%1$s</xliff:g> para a posição <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor de configurações rápidas."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Notificação do <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"É possível que o app não funcione com o recurso de divisão de tela."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"O app não é compatível com a divisão de tela."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"É possível que o app não funcione em uma tela secundária."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"O app não é compatível com a inicialização em telas secundárias."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Abrir configurações."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Abrir as configurações rápidas."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Fechar as configurações rápidas."</string> diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml index 541f12c32e02..c39a5eb54868 100644 --- a/packages/SystemUI/res/values-pt-rPT/strings.xml +++ b/packages/SystemUI/res/values-pt-rPT/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Mostrar ícones de notificações de prioridade baixa"</string> <string name="other" msgid="429768510980739978">"Outro"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Divisor do ecrã dividido"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Ecrã esquerdo inteiro"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"70% no ecrã esquerdo"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"50% no ecrã esquerdo"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"30% no ecrã esquerdo"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Ecrã direito inteiro"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Ecrã superior inteiro"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"70% no ecrã superior"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"50% no ecrã superior"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"30% no ecrã superior"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Ecrã inferior inteiro"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Posição <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Toque duas vezes para editar."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Toque duas vezes para adicionar."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Mover <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Mover <xliff:g id="TILE_NAME">%1$s</xliff:g> para a posição <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor de definições rápidas."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Notificação do <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"A app pode não funcionar com o ecrã dividido."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"A app não é compatível com o ecrã dividido."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"A app pode não funcionar num ecrã secundário."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"A app não é compatível com o início em ecrãs secundários."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Abrir as definições."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Abrir as definições rápidas."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Fechar as definições rápidas."</string> diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml index ef5c9cee6ee4..ff2ecd38547f 100644 --- a/packages/SystemUI/res/values-pt/strings.xml +++ b/packages/SystemUI/res/values-pt/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Mostrar ícones de notificações de baixa prioridade"</string> <string name="other" msgid="429768510980739978">"Outros"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Divisor de tela"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Lado esquerdo em tela cheia"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Esquerda a 70%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Esquerda a 50%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Esquerda a 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Lado direito em tela cheia"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Parte superior em tela cheia"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Parte superior a 70%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Parte superior a 50%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Parte superior a 30%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Parte inferior em tela cheia"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Posição <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Toque duas vezes para editar."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Toque duas vezes para adicionar."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Move <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Mover <xliff:g id="TILE_NAME">%1$s</xliff:g> para a posição <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor de configurações rápidas."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Notificação do <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"É possível que o app não funcione com o recurso de divisão de tela."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"O app não é compatível com a divisão de tela."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"É possível que o app não funcione em uma tela secundária."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"O app não é compatível com a inicialização em telas secundárias."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Abrir configurações."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Abrir as configurações rápidas."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Fechar as configurações rápidas."</string> diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml index 3e2373deb67d..b793bcd33e4c 100644 --- a/packages/SystemUI/res/values-ro/strings.xml +++ b/packages/SystemUI/res/values-ro/strings.xml @@ -884,17 +884,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Afișați pictogramele de notificare cu prioritate redusă"</string> <string name="other" msgid="429768510980739978">"Altele"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Separator pentru ecranul împărțit"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Partea stângă pe ecran complet"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Partea stângă: 70%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Partea stângă: 50%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Partea stângă: 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Partea dreaptă pe ecran complet"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Partea de sus pe ecran complet"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Partea de sus: 70%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Partea de sus: 50%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Partea de sus: 30%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Partea de jos pe ecran complet"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Poziția <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Atingeți de două ori pentru a edita."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Atingeți de două ori pentru a adăuga."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Mutați <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> @@ -903,10 +892,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Mutați <xliff:g id="TILE_NAME">%1$s</xliff:g> pe poziția <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editorul pentru setări rapide."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Notificare <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"Este posibil ca aplicația să nu funcționeze cu ecranul împărțit."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Aplicația nu acceptă ecranul împărțit."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Este posibil ca aplicația să nu funcționeze pe un ecran secundar."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Aplicația nu acceptă lansare pe ecrane secundare."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Deschideți setările."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Deschideți setările rapide."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Închideți setările rapide."</string> diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml index 7747724eab80..7560f5309824 100644 --- a/packages/SystemUI/res/values-ru/strings.xml +++ b/packages/SystemUI/res/values-ru/strings.xml @@ -889,17 +889,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Показывать значки уведомлений с низким приоритетом"</string> <string name="other" msgid="429768510980739978">"Другое"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Разделитель экрана"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Левый во весь экран"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Левый на 70%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Левый на 50%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Левый на 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Правый во весь экран"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Верхний во весь экран"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Верхний на 70%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Верхний на 50%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Верхний на 30%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Нижний во весь экран"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Позиция <xliff:g id="POSITION">%1$d</xliff:g>, кнопка \"<xliff:g id="TILE_NAME">%2$s</xliff:g>\". Чтобы изменить, нажмите дважды."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"Кнопка \"<xliff:g id="TILE_NAME">%1$s</xliff:g>\". Чтобы добавить, нажмите дважды."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Переместить кнопку \"<xliff:g id="TILE_NAME">%1$s</xliff:g>\""</string> @@ -908,10 +897,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Переместить значок <xliff:g id="TILE_NAME">%1$s</xliff:g> на позицию <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Редактор быстрых настроек."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Уведомление <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"Приложение не поддерживает разделение экрана."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Приложение не поддерживает разделение экрана."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Приложение может не работать на дополнительном экране"</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Приложение не поддерживает запуск на дополнительных экранах"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Открыть настройки."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Развернуть быстрые настройки."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Скрыть быстрые настройки."</string> diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml index b8813f2ef53c..02f9c23cecf9 100644 --- a/packages/SystemUI/res/values-si/strings.xml +++ b/packages/SystemUI/res/values-si/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"අඩු ප්රමුඛතා දැනුම්දීම් අයිකන පෙන්වන්න"</string> <string name="other" msgid="429768510980739978">"වෙනත්"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"බෙදුම්-තිර වෙන්කරණය"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"වම් පූර්ණ තිරය"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"වම් 70%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"වම් 50%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"වම් 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"දකුණු පූර්ණ තිරය"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"ඉහළම පූර්ණ තිරය"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"ඉහළම 70%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"ඉහළම 50%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"ඉහළම 30%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"පහළ පූර්ණ තිරය"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"ස්ථානය <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. වෙනස් කිරීමට දෙවරක් තට්ටු කරන්න."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. එක් කිරීමට දෙවරක් තට්ටු කරන්න."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"<xliff:g id="TILE_NAME">%1$s</xliff:g> ගෙන යන්න"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"<xliff:g id="TILE_NAME">%1$s</xliff:g> තත්ත්වයට <xliff:g id="POSITION">%2$d</xliff:g> ගෙන යන්න"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ඉක්මන් සැකසුම් සංස්කාරකය."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> දැනුම්දීම: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"යෙදුම බෙදුම්-තිරය සමග ක්රියා නොකළ හැකිය."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"යෙදුම බෙදුණු-තිරය සඳහා සහාය නොදක්වයි."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"යෙදුම ද්විතියික සංදර්ශකයක ක්රියා නොකළ හැකිය."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"යෙදුම ද්විතීයික සංදර්ශක මත දියත් කිරීම සඳහා සහාය නොදක්වයි."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"සැකසීම් විවෘත කරන්න."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"ඉක්මන් සැකසීම් විවෘත කරන්න."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"ඉක්මන් සැකසීම් වසන්න."</string> diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml index 0f9cb5f4616c..54a32ddd1cbf 100644 --- a/packages/SystemUI/res/values-sk/strings.xml +++ b/packages/SystemUI/res/values-sk/strings.xml @@ -889,17 +889,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Zobraziť ikony upozornení s nízkou prioritou"</string> <string name="other" msgid="429768510980739978">"Ďalšie"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Rozdeľovač obrazovky"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Ľavá – na celú obrazovku"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Ľavá – 70 %"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Ľavá – 50 %"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Ľavá – 30 %"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Pravá– na celú obrazovku"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Horná – na celú obrazovku"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Horná – 70 %"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Horná – 50 %"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Horná – 30 %"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Dolná – na celú obrazovku"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Pozícia <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Upravíte ju dvojitým klepnutím."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Pridáte ju dvojitým klepnutím."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Presunúť dlaždicu <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> @@ -908,10 +897,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Presunúť <xliff:g id="TILE_NAME">%1$s</xliff:g> na pozíciu <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor rýchlych nastavení"</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Upozornenie <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"Aplikácia nemusí fungovať so zapnutou rozdelenou obrazovkou."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Aplikácia nepodporuje rozdelenú obrazovku."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Aplikácia nemusí fungovať na sekundárnej obrazovke."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Aplikácia nepodporuje spúšťanie na sekundárnych obrazovkách."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Otvoriť nastavenia"</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Otvoriť rýchle nastavenia"</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Zavrieť rýchle nastavenia"</string> diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml index 18db332b63ec..32fce7d58c9c 100644 --- a/packages/SystemUI/res/values-sl/strings.xml +++ b/packages/SystemUI/res/values-sl/strings.xml @@ -889,17 +889,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Pokaži ikone obvestil z nizko stopnjo prednosti"</string> <string name="other" msgid="429768510980739978">"Drugo"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Razdelilnik zaslonov"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Levi v celozaslonski način"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Levi 70 %"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Levi 50 %"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Levi 30 %"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Desni v celozaslonski način"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Zgornji v celozaslonski način"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Zgornji 70 %"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Zgornji 50 %"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Zgornji 30 %"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Spodnji v celozaslonski način"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Položaj <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Če želite urediti, se dvakrat dotaknite."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Če želite dodati, se dvakrat dotaknite."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Premik tega: <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> @@ -908,10 +897,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Premakni ploščico <xliff:g id="TILE_NAME">%1$s</xliff:g> na položaj <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Urejevalnik hitrih nastavitev."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Obvestilo za <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"Aplikacija morda ne deluje v načinu razdeljenega zaslona."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Aplikacija ne podpira načina razdeljenega zaslona."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Aplikacija morda ne bo delovala na sekundarnem zaslonu."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Aplikacija ne podpira zagona na sekundarnih zaslonih."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Odpri nastavitve."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Odpri hitre nastavitve."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Zapri hitre nastavitve."</string> diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml index 57ab1c384ca9..c907bc23cf32 100644 --- a/packages/SystemUI/res/values-sq/strings.xml +++ b/packages/SystemUI/res/values-sq/strings.xml @@ -480,7 +480,7 @@ <string name="guest_wipe_session_title" msgid="7147965814683990944">"Mirë se erdhe, i ftuar!"</string> <string name="guest_wipe_session_message" msgid="3393823610257065457">"Dëshiron ta vazhdosh sesionin tënd?"</string> <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Fillo nga e para"</string> - <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Po, vazhdo!"</string> + <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Po, vazhdo"</string> <string name="guest_notification_title" msgid="4434456703930764167">"Përdorues vizitor"</string> <string name="guest_notification_text" msgid="4202692942089571351">"Për të fshirë aplikacionet dhe të dhënat, hiqe përdoruesin vizitor"</string> <string name="guest_notification_remove_action" msgid="4153019027696868099">"HIQ VIZITORIN"</string> @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Shfaq ikonat e njoftimeve me përparësi të ulët"</string> <string name="other" msgid="429768510980739978">"Të tjera"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Ndarësi i ekranit të ndarë"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Ekrani i plotë majtas"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Majtas 70%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Majtas 50%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Majtas 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Ekrani i plotë djathtas"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Ekrani i plotë lart"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Lart 70%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Lart 50%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Lart 30%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Ekrani i plotë poshtë"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Pozicioni <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Trokit dy herë për ta redaktuar."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Trokit dy herë për ta shtuar."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Zhvendose <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Zhvendos <xliff:g id="TILE_NAME">%1$s</xliff:g> te pozicioni <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Redaktori i cilësimeve të shpejta."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Njoftim nga <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"Aplikacioni mund të mos funksionojë me ekranin e ndarë."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Aplikacioni nuk mbështet ekranin e ndarë."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Aplikacioni mund të mos funksionojë në një ekran dytësor."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Aplikacioni nuk mbështet nisjen në ekrane dytësore."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Hap cilësimet."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Hap cilësimet e shpejta."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Mbyll cilësimet e shpejta."</string> diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml index ec763f675d4c..8b7ce1f35cb3 100644 --- a/packages/SystemUI/res/values-sr/strings.xml +++ b/packages/SystemUI/res/values-sr/strings.xml @@ -884,17 +884,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Прикажи иконе обавештења ниског приоритета"</string> <string name="other" msgid="429768510980739978">"Друго"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Разделник подељеног екрана"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Режим целог екрана за леви екран"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Леви екран 70%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Леви екран 50%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Леви екран 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Режим целог екрана за доњи екран"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Режим целог екрана за горњи екран"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Горњи екран 70%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Горњи екран 50%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Горњи екран 30%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Режим целог екрана за доњи екран"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"<xliff:g id="POSITION">%1$d</xliff:g>. позиција, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Двапут додирните да бисте изменили."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Двапут додирните да бисте додали."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Премести плочицу <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> @@ -903,10 +892,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Преместите „<xliff:g id="TILE_NAME">%1$s</xliff:g>“ на позицију <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Уређивач за Брза подешавања."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Обавештења за <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"Апликација можда неће функционисати са подељеним екраном."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Апликација не подржава подељени екран."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Апликација можда неће функционисати на секундарном екрану."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Апликација не подржава покретање на секундарним екранима."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Отвори Подешавања."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Отвори Брза подешавања."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Затвори Брза подешавања."</string> diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml index a0a563d81d46..c4b7977ae5a6 100644 --- a/packages/SystemUI/res/values-sv/strings.xml +++ b/packages/SystemUI/res/values-sv/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Visa ikoner för aviseringar med låg prioritet"</string> <string name="other" msgid="429768510980739978">"Annat"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Avdelare för delad skärm"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Helskärm på vänster skärm"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Vänster 70 %"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Vänster 50 %"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Vänster 30 %"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Helskärm på höger skärm"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Helskärm på övre skärm"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Övre 70 %"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Övre 50 %"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Övre 30 %"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Helskärm på nedre skärm"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Position <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Tryck snabbt två gånger för att redigera positionen."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Lägg till genom att trycka snabbt två gånger."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Flytta <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Flytta <xliff:g id="TILE_NAME">%1$s</xliff:g> till position <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Redigerare för snabbinställningar."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g>-avisering: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"Appen kanske inte fungerar med delad skärm."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Appen har inte stöd för delad skärm."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Appen kanske inte fungerar på en sekundär skärm."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Appen kan inte köras på en sekundär skärm."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Öppna inställningarna."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Öppna snabbinställningarna."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Stäng snabbinställningarna"</string> diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml index 7e264a4a312a..b483fa8f0791 100644 --- a/packages/SystemUI/res/values-sw/strings.xml +++ b/packages/SystemUI/res/values-sw/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Onyesha aikoni za arifa zisizo muhimu"</string> <string name="other" msgid="429768510980739978">"Nyingine"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Kitenganishi cha skrini inayogawanywa"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Skrini nzima ya kushoto"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Kushoto 70%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Kushoto 50%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Kushoto 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Skrini nzima ya kulia"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Skrini nzima ya juu"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Juu 70%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Juu 50%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Juu 30%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Skrini nzima ya chini"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Nafasi ya <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Gusa mara mbili ili ubadilishe."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Gusa mara mbili ili uongeze."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Hamisha <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Sogeza <xliff:g id="TILE_NAME">%1$s</xliff:g> kwenye nafasi ya <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Kihariri cha Mipangilio ya haraka."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Arifa kutoka <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"Huenda programu isifanye kazi kwenye skrini inayogawanywa."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Programu haiwezi kutumia skrini iliyogawanywa."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Huenda programu isifanye kazi kwenye dirisha lingine."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Programu hii haiwezi kufunguliwa kwenye madirisha mengine."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Fungua mipangilio."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Fungua mipangilio ya haraka."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Funga mipangilio ya haraka."</string> diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml index e0f20ceea353..2c025e72cdf4 100644 --- a/packages/SystemUI/res/values-ta/strings.xml +++ b/packages/SystemUI/res/values-ta/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"குறைந்த முன்னுரிமை உள்ள அறிவிப்பு ஐகான்களைக் காட்டு"</string> <string name="other" msgid="429768510980739978">"மற்றவை"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"திரையைப் பிரிக்கும் பிரிப்பான்"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"இடது புறம் முழுத் திரை"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"இடது புறம் 70%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"இடது புறம் 50%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"இடது புறம் 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"வலது புறம் முழுத் திரை"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"மேற்புறம் முழுத் திரை"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"மேலே 70%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"மேலே 50%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"மேலே 30%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"கீழ்ப்புறம் முழுத் திரை"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"நிலை <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. திருத்த, இருமுறை தட்டவும்."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. சேர்க்க, இருமுறை தட்டவும்."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"<xliff:g id="TILE_NAME">%1$s</xliff:g>ஐ நகர்த்தவும்"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"நிலைப்பாடு <xliff:g id="POSITION">%2$d</xliff:g>க்கு <xliff:g id="TILE_NAME">%1$s</xliff:g>ஐ நகர்த்தும்"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"விரைவு அமைப்புகள் திருத்தி."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> அறிவிப்பு: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"திரைப் பிரிப்பில் ஆப்ஸ் வேலைசெய்யாமல் போகக்கூடும்."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"திரையைப் பிரிப்பதைப் ஆப்ஸ் ஆதரிக்கவில்லை."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"இரண்டாம்நிலைத் திரையில் ஆப்ஸ் வேலை செய்யாமல் போகக்கூடும்."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"இரண்டாம்நிலைத் திரைகளில் பயன்பாட்டைத் தொடங்க முடியாது."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"அமைப்புகளைத் திற."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"விரைவு அமைப்புகளைத் திற."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"விரைவு அமைப்புகளை மூடு."</string> diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml index 3e94b72b02fe..a49bb9b46512 100644 --- a/packages/SystemUI/res/values-te/strings.xml +++ b/packages/SystemUI/res/values-te/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"తక్కువ ప్రాధాన్యత నోటిఫికేషన్ చిహ్నాలను చూపించు"</string> <string name="other" msgid="429768510980739978">"ఇతరం"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"విభజన స్క్రీన్ విభాగిని"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"ఎడమవైపు పూర్తి స్క్రీన్"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"ఎడమవైపు 70%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"ఎడమవైపు 50%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"ఎడమవైపు 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"కుడివైపు పూర్తి స్క్రీన్"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"ఎగువ పూర్తి స్క్రీన్"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"ఎగువ 70%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"ఎగువ 50%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"ఎగువ 30%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"దిగువ పూర్తి స్క్రీన్"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"స్థానం <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. సవరించడానికి రెండుసార్లు నొక్కండి."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. జోడించడానికి రెండుసార్లు నొక్కండి."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"<xliff:g id="TILE_NAME">%1$s</xliff:g>ని తరలిస్తుంది"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"స్థానం <xliff:g id="POSITION">%2$d</xliff:g>కి <xliff:g id="TILE_NAME">%1$s</xliff:g>ని తరలించండి"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"శీఘ్ర సెట్టింగ్ల ఎడిటర్."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> నోటిఫికేషన్: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"స్క్రీన్ విభజనతో యాప్ పని చేయకపోవచ్చు."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"అనువర్తనంలో స్క్రీన్ విభజనకు మద్దతు లేదు."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"ప్రత్యామ్నాయ డిస్ప్లేలో యాప్ పని చేయకపోవచ్చు."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"ప్రత్యామ్నాయ డిస్ప్లేల్లో ప్రారంభానికి యాప్ మద్దతు లేదు."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"సెట్టింగ్లను తెరవండి."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"శీఘ్ర సెట్టింగ్లను తెరవండి."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"శీఘ్ర సెట్టింగ్లను మూసివేయండి."</string> diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml index 088b62421b92..8fd844203d9f 100644 --- a/packages/SystemUI/res/values-th/strings.xml +++ b/packages/SystemUI/res/values-th/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"แสดงไอคอนการแจ้งเตือนลำดับความสำคัญต่ำ"</string> <string name="other" msgid="429768510980739978">"อื่นๆ"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"เส้นแบ่งหน้าจอ"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"เต็มหน้าจอทางซ้าย"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"ซ้าย 70%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"ซ้าย 50%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"ซ้าย 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"เต็มหน้าจอทางขวา"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"เต็มหน้าจอด้านบน"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"ด้านบน 70%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"ด้านบน 50%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"ด้านบน 30%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"เต็มหน้าจอด้านล่าง"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"ตำแหน่ง <xliff:g id="POSITION">%1$d</xliff:g> <xliff:g id="TILE_NAME">%2$s</xliff:g> แตะ 2 ครั้งเพื่อแก้ไข"</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g> แตะ 2 ครั้งเพื่อเพิ่ม"</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"ย้าย <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"ย้าย <xliff:g id="TILE_NAME">%1$s</xliff:g> ไปยังตำแหน่ง <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ตัวแก้ไขการตั้งค่าด่วน"</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> การแจ้งเตือน: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"แอปอาจใช้ไม่ได้กับโหมดแยกหน้าจอ"</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"แอปไม่สนับสนุนการแยกหน้าจอ"</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"แอปอาจไม่ทำงานในจอแสดงผลรอง"</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"แอปไม่รองรับการเรียกใช้ในจอแสดงผลรอง"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"เปิดการตั้งค่า"</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"เปิดการตั้งค่าด่วน"</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"ปิดการตั้งค่าด่วน"</string> diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml index e787b17417bb..5951ba223c5d 100644 --- a/packages/SystemUI/res/values-tl/strings.xml +++ b/packages/SystemUI/res/values-tl/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Ipakita ang mga icon ng notification na may mababang priority"</string> <string name="other" msgid="429768510980739978">"Iba pa"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Divider ng split-screen"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"I-full screen ang nasa kaliwa"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Gawing 70% ang nasa kaliwa"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Gawing 50% ang nasa kaliwa"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Gawing 30% ang nasa kaliwa"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"I-full screen ang nasa kanan"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"I-full screen ang nasa itaas"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Gawing 70% ang nasa itaas"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Gawing 50% ang nasa itaas"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Gawing 30% ang nasa itaas"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"I-full screen ang nasa ibaba"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Posisyon <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. I-double tap upang i-edit."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. I-double tap upang idagdag."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Ilipat ang <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Ilipat ang <xliff:g id="TILE_NAME">%1$s</xliff:g> sa posisyong <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor ng Mga mabilisang setting."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Notification sa <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"Maaaring hindi gumana ang app sa split-screen."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Hindi sinusuportahan ng app ang split-screen."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Maaaring hindi gumana ang app sa pangalawang display."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Hindi sinusuportahan ng app ang paglulunsad sa mga pangalawang display."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Buksan ang mga setting."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Buksan ang mga mabilisang setting."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Isara ang mga mabilisang setting."</string> diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml index e33944517393..2d2ccadd65d8 100644 --- a/packages/SystemUI/res/values-tr/strings.xml +++ b/packages/SystemUI/res/values-tr/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Düşük öncelikli bildirim simgelerini göster"</string> <string name="other" msgid="429768510980739978">"Diğer"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Bölünmüş ekran ayırıcı"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Solda tam ekran"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Solda %70"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Solda %50"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Solda %30"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Sağda tam ekran"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Üstte tam ekran"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Üstte %70"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Üstte %50"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Üstte %30"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Altta tam ekran"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"<xliff:g id="POSITION">%1$d</xliff:g>. konum, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Düzenlemek için iki kez dokunun."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Eklemek için iki kez dokunun."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"<xliff:g id="TILE_NAME">%1$s</xliff:g> kutusunu taşı"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"<xliff:g id="TILE_NAME">%1$s</xliff:g> öğesini <xliff:g id="POSITION">%2$d</xliff:g> konumuna taşı"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Hızlı ayar düzenleyicisi."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> bildirimi: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"Uygulama bölünmüş ekranda çalışmayabilir."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Uygulama bölünmüş ekranı desteklemiyor."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Uygulama ikincil ekranda çalışmayabilir."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Uygulama ikincil ekranlarda başlatılmayı desteklemiyor."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Ayarları aç."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Hızlı ayarları aç."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Hızlı ayarları kapat."</string> diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml index f5419f1d1290..1a8ce7b6ad76 100644 --- a/packages/SystemUI/res/values-uk/strings.xml +++ b/packages/SystemUI/res/values-uk/strings.xml @@ -889,17 +889,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Показувати значки сповіщень із низьким пріоритетом"</string> <string name="other" msgid="429768510980739978">"Інше"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Розділювач екрана"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Ліве вікно на весь екран"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Ліве вікно на 70%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Ліве вікно на 50%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Ліве вікно на 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Праве вікно на весь екран"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Верхнє вікно на весь екран"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Верхнє вікно на 70%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Верхнє вікно на 50%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Верхнє вікно на 30%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Нижнє вікно на весь екран"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Позиція <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Двічі торкніться, щоб змінити."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Двічі торкніться, щоб додати."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Перемістити <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> @@ -908,10 +897,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Перемістити <xliff:g id="TILE_NAME">%1$s</xliff:g> на позицію <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Редактор швидких налаштувань."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Сповіщення <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"Додаток може не працювати в режимі розділеного екрана."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Додаток не підтримує розділення екрана."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Додаток може не працювати на додатковому екрані."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Додаток не підтримує запуск на додаткових екранах."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Відкрити налаштування."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Відкрити швидкі налаштування."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Закрити швидкі налаштування."</string> diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml index 2abf3500ff4a..4f091d6bde09 100644 --- a/packages/SystemUI/res/values-ur/strings.xml +++ b/packages/SystemUI/res/values-ur/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"کم ترجیحی اطلاع کے آئیکنز دکھائیں"</string> <string name="other" msgid="429768510980739978">"دیگر"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"سپلٹ اسکرین تقسیم کار"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"بائیں فل اسکرین"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"بائیں %70"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"بائیں %50"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"بائیں %30"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"دائیں فل اسکرین"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"بالائی فل اسکرین"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"اوپر %70"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"اوپر %50"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"اوپر %30"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"نچلی فل اسکرین"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"پوزیشن <xliff:g id="POSITION">%1$d</xliff:g>، <xliff:g id="TILE_NAME">%2$s</xliff:g>۔ ترمیم کرنے کیلئے دو بار تھپتھپائیں۔"</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>۔ شامل کرنے کیلئے دو بار تھپتھپائیں۔"</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"<xliff:g id="TILE_NAME">%1$s</xliff:g> کو منتقل کریں"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"<xliff:g id="TILE_NAME">%1$s</xliff:g> کو پوزیشن <xliff:g id="POSITION">%2$d</xliff:g> میں منتقل کریں"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"فوری ترتیبات کا ایڈیٹر۔"</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> اطلاع: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"ممکن ہے کہ ایپ سپلٹ اسکرین کے ساتھ کام نہ کرے۔"</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"ایپ سپلٹ اسکرین کو سپورٹ نہیں کرتی۔"</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"ممکن ہے ایپ ثانوی ڈسپلے پر کام نہ کرے۔"</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"ایپ ثانوی ڈسپلیز پر شروعات کا تعاون نہیں کرتی۔"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"ترتیبات کھولیں۔"</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"فوری ترتیبات کھولیں۔"</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"فوری ترتیبات بند کریں۔"</string> diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml index 61b10a4ed24c..26a691a147ce 100644 --- a/packages/SystemUI/res/values-uz/strings.xml +++ b/packages/SystemUI/res/values-uz/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Muhim boʻlmagan bildirishnoma ikonkalarini koʻrsatish"</string> <string name="other" msgid="429768510980739978">"Boshqa"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Ekranni ikkiga bo‘lish chizig‘i"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Chapda to‘liq ekran"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Chapda 70%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Chapda 50%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Chapda 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"O‘ngda to‘liq ekran"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Tepada to‘liq ekran"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Tepada 70%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Tepada 50%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Tepada 30%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Pastda to‘liq ekran"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"<xliff:g id="POSITION">%1$d</xliff:g>-joy, “<xliff:g id="TILE_NAME">%2$s</xliff:g>” tugmasi. Tahrirlash uchun ustiga ikki marta bosing."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"“<xliff:g id="TILE_NAME">%1$s</xliff:g>” tugmasi. Qo‘shish uchun ustiga ikki marta bosing."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"“<xliff:g id="TILE_NAME">%1$s</xliff:g>” tugmasini ko‘chirish"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"<xliff:g id="POSITION">%2$d</xliff:g>-joyga buni ko‘chirish: <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Tezkor sozlamalar muharriri"</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> bildirishnomasi: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"Ilova ekranni ikkiga bo‘lish rejimini qo‘llab-quvvatlamaydi."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Bu ilova ekranni bo‘lish xususiyatini qo‘llab-quvvatlamaydi."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Bu ilova qo‘shimcha ekranda ishlamasligi mumkin."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Bu ilova qo‘shimcha ekranlarda ishga tushmaydi."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Sozlamalarni ochish."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Tezkor sozlamalarni ochish."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Tezkor sozlamalarni yopish."</string> diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml index 6107270f10c5..bea99a9aa82e 100644 --- a/packages/SystemUI/res/values-vi/strings.xml +++ b/packages/SystemUI/res/values-vi/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Hiển thị biểu tượng thông báo có mức ưu tiên thấp"</string> <string name="other" msgid="429768510980739978">"Khác"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Bộ chia chia đôi màn hình"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Toàn màn hình bên trái"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Trái 70%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Trái 50%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Trái 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Toàn màn hình bên phải"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Toàn màn hình phía trên"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Trên 70%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Trên 50%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Trên 30%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Toàn màn hình phía dưới"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Vị trí <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Nhấn đúp để chỉnh sửa."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Nhấn đúp để thêm."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Di chuyển <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Di chuyển <xliff:g id="TILE_NAME">%1$s</xliff:g> đến vị trí <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Trình chỉnh sửa cài đặt nhanh."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Thông báo của <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"Ứng dụng có thể không hoạt động với tính năng chia đôi màn hình."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Ứng dụng không hỗ trợ chia đôi màn hình."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Ứng dụng có thể không hoạt động trên màn hình phụ."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Ứng dụng không hỗ trợ khởi chạy trên màn hình phụ."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Mở phần cài đặt."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Mở cài đặt nhanh."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Đóng cài đặt nhanh."</string> diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml index ffd19956f471..8e73f36a74d3 100644 --- a/packages/SystemUI/res/values-zh-rCN/strings.xml +++ b/packages/SystemUI/res/values-zh-rCN/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"显示低优先级的通知图标"</string> <string name="other" msgid="429768510980739978">"其他"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"分屏分隔线"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"左侧全屏"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"左侧 70%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"左侧 50%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"左侧 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"右侧全屏"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"顶部全屏"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"顶部 70%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"顶部 50%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"顶部 30%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"底部全屏"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"位置 <xliff:g id="POSITION">%1$d</xliff:g>,<xliff:g id="TILE_NAME">%2$s</xliff:g>。点按两次即可修改。"</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>。点按两次即可添加。"</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"移动<xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"将“<xliff:g id="TILE_NAME">%1$s</xliff:g>”移动到位置 <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"快捷设置编辑器。"</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g>通知:<xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"应用可能无法在分屏模式下正常运行。"</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"应用不支持分屏。"</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"应用可能无法在辅显示屏上正常运行。"</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"应用不支持在辅显示屏上启动。"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"打开设置。"</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"开启快捷设置。"</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"关闭快捷设置。"</string> diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml index 1575427f155b..08bf63b116cc 100644 --- a/packages/SystemUI/res/values-zh-rHK/strings.xml +++ b/packages/SystemUI/res/values-zh-rHK/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"顯示低優先順序通知圖示"</string> <string name="other" msgid="429768510980739978">"其他"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"分割畫面分隔線"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"左邊全螢幕"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"左邊 70%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"左邊 50%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"左邊 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"右邊全螢幕"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"頂部全螢幕"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"頂部 70%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"頂部 50%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"頂部 30%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"底部全螢幕"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"位置 <xliff:g id="POSITION">%1$d</xliff:g>,<xliff:g id="TILE_NAME">%2$s</xliff:g>。輕按兩下即可編輯。"</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>。輕按兩下即可新增。"</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"移動 <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"將「<xliff:g id="TILE_NAME">%1$s</xliff:g>」移去位置 <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"快速設定編輯工具。"</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> 通知:<xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"應用程式可能無法在分割畫面中運作。"</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"應用程式不支援分割畫面。"</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"應用程式可能無法在次要顯示屏上運作。"</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"應用程式無法在次要顯示屏上啟動。"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"開啟設定。"</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"開啟快速設定。"</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"關閉快速設定。"</string> diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml index bbd83551c0f9..3e7d2e481630 100644 --- a/packages/SystemUI/res/values-zh-rTW/strings.xml +++ b/packages/SystemUI/res/values-zh-rTW/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"顯示低優先順序通知圖示"</string> <string name="other" msgid="429768510980739978">"其他"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"分割畫面分隔線"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"以全螢幕顯示左側畫面"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"以 70% 的螢幕空間顯示左側畫面"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"以 50% 的螢幕空間顯示左側畫面"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"以 30% 的螢幕空間顯示左側畫面"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"以全螢幕顯示右側畫面"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"以全螢幕顯示頂端畫面"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"以 70% 的螢幕空間顯示頂端畫面"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"以 50% 的螢幕空間顯示頂端畫面"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"以 30% 的螢幕空間顯示頂端畫面"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"以全螢幕顯示底部畫面"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"位置 <xliff:g id="POSITION">%1$d</xliff:g>,<xliff:g id="TILE_NAME">%2$s</xliff:g>。輕觸兩下即可編輯。"</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>。輕觸兩下即可新增。"</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"移動 <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"將 <xliff:g id="TILE_NAME">%1$s</xliff:g> 移到位置 <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"快速設定編輯器。"</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> 通知:<xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"應用程式可能無法在分割畫面中運作。"</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"這個應用程式不支援分割畫面。"</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"應用程式可能無法在次要顯示器上運作。"</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"應用程式無法在次要顯示器上啟動。"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"開啟設定。"</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"開啟快速設定。"</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"關閉快速設定。"</string> diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml index 63b4c613a06a..f93ff1d85db8 100644 --- a/packages/SystemUI/res/values-zu/strings.xml +++ b/packages/SystemUI/res/values-zu/strings.xml @@ -879,17 +879,6 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Bonisa izithonjana zesaziso zokubaluleka okuncane"</string> <string name="other" msgid="429768510980739978">"Okunye"</string> - <string name="accessibility_divider" msgid="2830785970889237307">"Isihlukanisi sokuhlukanisa isikrini"</string> - <string name="accessibility_action_divider_left_full" msgid="7598733539422375847">"Isikrini esigcwele esingakwesokunxele"</string> - <string name="accessibility_action_divider_left_70" msgid="4919312892541727761">"Kwesokunxele ngo-70%"</string> - <string name="accessibility_action_divider_left_50" msgid="3664701169564893826">"Kwesokunxele ngo-50%"</string> - <string name="accessibility_action_divider_left_30" msgid="4358145268046362088">"Kwesokunxele ngo-30%"</string> - <string name="accessibility_action_divider_right_full" msgid="8576057422864896305">"Isikrini esigcwele esingakwesokudla"</string> - <string name="accessibility_action_divider_top_full" msgid="4243901660795169777">"Isikrini esigcwele esiphezulu"</string> - <string name="accessibility_action_divider_top_70" msgid="6941226213260515072">"Okuphezulu okungu-70%"</string> - <string name="accessibility_action_divider_top_50" msgid="6275211443706497621">"Okuphezulu okungu-50%"</string> - <string name="accessibility_action_divider_top_30" msgid="5780597635887574916">"Okuphezulu okungu-30%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="7352434720610115395">"Ngaphansi kwesikrini esigcwele"</string> <string name="accessibility_qs_edit_tile_label" msgid="9079791448815232967">"Isimo esingu-<xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Thepha kabili ukuze uhlele."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8292218072049068613">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Thepha kabili ukuze ungeze."</string> <string name="accessibility_qs_edit_move_tile" msgid="6027997446473163426">"Hambisa i-<xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> @@ -898,10 +887,6 @@ <string name="accessibility_qs_edit_tile_move" msgid="4841770637244326837">"Hambisa i-<xliff:g id="TILE_NAME">%1$s</xliff:g> ukuze ubeke i-<xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Isihleli sezilungiselelo ezisheshayo."</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> isaziso: <xliff:g id="ID_2">%2$s</xliff:g>"</string> - <string name="dock_forced_resizable" msgid="4689301323912928801">"Izinhlelo zokusebenza kungenzeka zingasebenzi ngesikrini esihlukanisiwe."</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="7284915968096153808">"Uhlelo lokusebenza alusekeli isikrini esihlukanisiwe."</string> - <string name="forced_resizable_secondary_display" msgid="522558907654394940">"Uhlelo lokusebenza kungenzeka lungasebenzi kusibonisi sesibili."</string> - <string name="activity_launch_on_secondary_display_failed_text" msgid="8446727617187998208">"Uhlelo lokusebenza alusekeli ukuqalisa kuzibonisi zesibili."</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Vula izilungiselelo."</string> <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Vula izilungiselelo ezisheshayo."</string> <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Vala izilungiselelo ezisheshayo."</string> diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml index 1c3fba2abacd..ab09a967bc26 100644 --- a/packages/SystemUI/res/values/config.xml +++ b/packages/SystemUI/res/values/config.xml @@ -560,9 +560,6 @@ <!-- If the config font scale is >= this value, potentially adjust the number of columns--> <item name="controls_max_columns_adjust_above_font_scale" translatable="false" format="float" type="dimen">1.25</item> - <!-- Allow one handed to enable round corner --> - <bool name="config_one_handed_enable_round_corner">true</bool> - <!-- Show a separate icon for low and high volume on the volume dialog --> <bool name="config_showLowMediaVolumeIcon">false</bool> </resources> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 76c61fb6e1e5..875fe1471b1c 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -1366,8 +1366,4 @@ <dimen name="config_rounded_mask_size">@*android:dimen/rounded_corner_radius</dimen> <dimen name="config_rounded_mask_size_top">@*android:dimen/rounded_corner_radius_top</dimen> <dimen name="config_rounded_mask_size_bottom">@*android:dimen/rounded_corner_radius_bottom</dimen> - - <!-- One-Handed Mode --> - <!-- Threshold for dragging distance to enable one-handed mode --> - <dimen name="gestures_onehanded_drag_threshold">20dp</dimen> </resources> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index e58bf3bad795..cca70f9aa518 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -2799,9 +2799,4 @@ <string name="udfps_hbm_enable_command" translatable="false"></string> <!-- Device-specific payload for disabling the high-brightness mode --> <string name="udfps_hbm_disable_command" translatable="false"></string> - - <!-- One-Handed Tutorial title [CHAR LIMIT=60] --> - <string name="one_handed_tutorial_title">Using one-handed mode</string> - <!-- One-Handed Tutorial description [CHAR LIMIT=NONE] --> - <string name="one_handed_tutorial_description">To exit, swipe up from the bottom of the screen or tap anywhere above the app</string> </resources> diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/InputChannelCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/InputChannelCompat.java index 2b1fce8a4cf5..ffde84128549 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/InputChannelCompat.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/InputChannelCompat.java @@ -41,16 +41,6 @@ public class InputChannelCompat { } /** - * Creates a dispatcher from the extras received as part on onInitialize - */ - public static InputEventReceiver fromBundle(Bundle params, String key, - Looper looper, Choreographer choreographer, InputEventListener listener) { - - InputChannel channel = params.getParcelable(key); - return new InputEventReceiver(channel, looper, choreographer, listener); - } - - /** * Version of addBatch method which preserves time accuracy in nanoseconds instead of * converting the time to milliseconds. * @param src old MotionEvent where the target should be appended @@ -69,11 +59,9 @@ public class InputChannelCompat { public static class InputEventReceiver { private final BatchedInputEventReceiver mReceiver; - private final InputChannel mInputChannel; public InputEventReceiver(InputChannel inputChannel, Looper looper, Choreographer choreographer, final InputEventListener listener) { - mInputChannel = inputChannel; mReceiver = new BatchedInputEventReceiver(inputChannel, looper, choreographer) { @Override @@ -85,40 +73,17 @@ public class InputChannelCompat { } /** - * @see BatchedInputEventReceiver#dispose() + * @see BatchedInputEventReceiver#setBatchingEnabled() */ - public void dispose() { - mReceiver.dispose(); - mInputChannel.dispose(); - } - } - - /** - * @see InputEventSender - */ - public static class InputEventDispatcher { - - private final InputChannel mInputChannel; - private final InputEventSender mSender; - - public InputEventDispatcher(InputChannel inputChannel, Looper looper) { - mInputChannel = inputChannel; - mSender = new InputEventSender(inputChannel, looper) { }; - } - - /** - * @see InputEventSender#sendInputEvent(int, InputEvent) - */ - public void dispatch(InputEvent ev) { - mSender.sendInputEvent(ev.getSequenceNumber(), ev); + public void setBatchingEnabled(boolean batchingEnabled) { + mReceiver.setBatchingEnabled(batchingEnabled); } /** - * @see InputEventSender#dispose() + * @see BatchedInputEventReceiver#dispose() */ public void dispose() { - mSender.dispose(); - mInputChannel.dispose(); + mReceiver.dispose(); } } } diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java index d64bf77ad9d5..067ac9ec7b1e 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java @@ -153,12 +153,9 @@ public class WindowManagerWrapper { } } + @Deprecated public void setPipVisibility(final boolean visible) { - try { - WindowManagerGlobal.getWindowManagerService().setPipVisibility(visible); - } catch (RemoteException e) { - Log.e(TAG, "Unable to reach window manager", e); - } + // To be removed } /** diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java index 1027329b8d3c..76090f87223e 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -36,6 +36,7 @@ import android.annotation.MainThread; import android.annotation.NonNull; import android.app.ActivityManager; import android.app.ActivityTaskManager; +import android.app.ActivityTaskManager.RootTaskInfo; import android.app.AlarmManager; import android.app.PendingIntent; import android.app.UserSwitchObserver; @@ -2783,7 +2784,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab @Override public void onTaskStackChangedBackground() { try { - ActivityManager.StackInfo info = ActivityTaskManager.getService().getStackInfo( + RootTaskInfo info = ActivityTaskManager.getService().getRootTaskInfo( WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_ASSISTANT); if (info == null) { return; diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java index 128af3702c49..68e404e36bba 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java @@ -43,6 +43,7 @@ class MagnificationModeSwitch { private static final int DURATION_MS = 5000; private static final int START_DELAY_MS = 3000; + private final Runnable mAnimationTask; private final Context mContext; private final WindowManager mWindowManager; @@ -70,6 +71,14 @@ class MagnificationModeSwitch { applyResourcesValues(); mImageView.setImageResource(getIconResId(mMagnificationMode)); mImageView.setOnTouchListener(this::onTouch); + + mAnimationTask = () -> { + mImageView.animate() + .alpha(0f) + .setDuration(DURATION_MS) + .withEndAction(() -> removeButton()) + .start(); + }; } private void applyResourcesValues() { @@ -147,13 +156,8 @@ class MagnificationModeSwitch { // Dismiss the magnification switch button after the button is displayed for a period of // time. mImageView.animate().cancel(); - mImageView.animate() - .alpha(0f) - .setStartDelay(START_DELAY_MS) - .setDuration(DURATION_MS) - .withEndAction( - () -> removeButton()) - .start(); + mImageView.removeCallbacks(mAnimationTask); + mImageView.postDelayed(mAnimationTask, START_DELAY_MS); } void onConfigurationChanged(int configDiff) { diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java b/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java index 27863ba6c857..62bc425b2bd2 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java @@ -694,6 +694,7 @@ class Bubble implements BubbleViewProvider { pw.print(" showInShade: "); pw.println(showInShade()); pw.print(" showDot: "); pw.println(showDot()); pw.print(" showFlyout: "); pw.println(showFlyout()); + pw.print(" lastActivity: "); pw.println(getLastActivity()); pw.print(" desiredHeight: "); pw.println(getDesiredHeightString()); pw.print(" suppressNotif: "); pw.println(shouldSuppressNotification()); pw.print(" autoExpand: "); pw.println(shouldAutoExpand()); diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java index c81b7cefbbd7..4b4e275e5cbd 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java @@ -196,7 +196,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi private INotificationManager mINotificationManager; // Callback that updates BubbleOverflowActivity on data change. - @Nullable private Runnable mOverflowCallback = null; + @Nullable private BubbleData.Listener mOverflowListener = null; // Only load overflow data from disk once private boolean mOverflowDataLoaded = false; @@ -722,8 +722,8 @@ public class BubbleController implements ConfigurationController.ConfigurationLi mInflateSynchronously = inflateSynchronously; } - void setOverflowCallback(Runnable updateOverflow) { - mOverflowCallback = updateOverflow; + void setOverflowListener(BubbleData.Listener listener) { + mOverflowListener = listener; } /** @@ -1327,9 +1327,10 @@ public class BubbleController implements ConfigurationController.ConfigurationLi // Lazy load overflow bubbles from disk loadOverflowBubblesFromDisk(); + // Update bubbles in overflow. - if (mOverflowCallback != null) { - mOverflowCallback.run(); + if (mOverflowListener != null) { + mOverflowListener.applyUpdate(update); } // Collapsing? Do this first before remaining steps. @@ -1438,21 +1439,6 @@ public class BubbleController implements ConfigurationController.ConfigurationLi cb.invalidateNotifications("BubbleData.Listener.applyUpdate"); } updateStack(); - - if (DEBUG_BUBBLE_CONTROLLER) { - Log.d(TAG, "\n[BubbleData] bubbles:"); - Log.d(TAG, BubbleDebugConfig.formatBubblesString(mBubbleData.getBubbles(), - mBubbleData.getSelectedBubble())); - - if (mStackView != null) { - Log.d(TAG, "\n[BubbleStackView]"); - Log.d(TAG, BubbleDebugConfig.formatBubblesString(mStackView.getBubblesOnScreen(), - mStackView.getExpandedBubble())); - } - Log.d(TAG, "\n[BubbleData] overflow:"); - Log.d(TAG, BubbleDebugConfig.formatBubblesString(mBubbleData.getOverflowBubbles(), - null) + "\n"); - } } }; diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java index 5c6d16d4bbee..a747db680b2e 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java @@ -75,6 +75,8 @@ public class BubbleData { @Nullable Bubble selectedBubble; @Nullable Bubble addedBubble; @Nullable Bubble updatedBubble; + @Nullable Bubble addedOverflowBubble; + @Nullable Bubble removedOverflowBubble; // Pair with Bubble and @DismissReason Integer final List<Pair<Bubble, Integer>> removedBubbles = new ArrayList<>(); @@ -93,10 +95,12 @@ public class BubbleData { || addedBubble != null || updatedBubble != null || !removedBubbles.isEmpty() + || addedOverflowBubble != null + || removedOverflowBubble != null || orderChanged; } - void bubbleRemoved(Bubble bubbleToRemove, @DismissReason int reason) { + void bubbleRemoved(Bubble bubbleToRemove, @DismissReason int reason) { removedBubbles.add(new Pair<>(bubbleToRemove, reason)); } } @@ -486,8 +490,9 @@ public class BubbleData { b.stopInflation(); } mLogger.logOverflowRemove(b, reason); - mStateChange.bubbleRemoved(b, reason); mOverflowBubbles.remove(b); + mStateChange.bubbleRemoved(b, reason); + mStateChange.removedOverflowBubble = b; } return; } @@ -532,6 +537,7 @@ public class BubbleData { } mLogger.logOverflowAdd(bubble, reason); mOverflowBubbles.add(0, bubble); + mStateChange.addedOverflowBubble = bubble; bubble.stopInflation(); if (mOverflowBubbles.size() == mMaxOverflowBubbles + 1) { // Remove oldest bubble. @@ -542,6 +548,7 @@ public class BubbleData { mStateChange.bubbleRemoved(oldest, BubbleController.DISMISS_OVERFLOW_MAX_REACHED); mLogger.log(bubble, BubbleLogger.Event.BUBBLE_OVERFLOW_REMOVE_MAX_REACHED); mOverflowBubbles.remove(oldest); + mStateChange.removedOverflowBubble = oldest; } } @@ -821,11 +828,19 @@ public class BubbleData { : "null"); pw.print("expanded: "); pw.println(mExpanded); - pw.print("count: "); + + pw.print("stack bubble count: "); pw.println(mBubbles.size()); for (Bubble bubble : mBubbles) { bubble.dump(fd, pw, args); } + + pw.print("overflow bubble count: "); + pw.println(mOverflowBubbles.size()); + for (Bubble bubble : mOverflowBubbles) { + bubble.dump(fd, pw, args); + } + pw.print("summaryKeys: "); pw.println(mSuppressedGroupKeys.size()); for (String key : mSuppressedGroupKeys.keySet()) { diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflowActivity.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflowActivity.java index 9926f2ef9b64..160addc405fa 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflowActivity.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflowActivity.java @@ -108,14 +108,10 @@ public class BubbleOverflowActivity extends Activity { mEmptyStateSubtitle = findViewById(R.id.bubble_overflow_empty_subtitle); mEmptyStateImage = findViewById(R.id.bubble_overflow_empty_state_image); - updateDimensions(); - onDataChanged(mBubbleController.getOverflowBubbles()); - mBubbleController.setOverflowCallback(() -> { - onDataChanged(mBubbleController.getOverflowBubbles()); - }); + updateOverflow(); } - void updateDimensions() { + void updateOverflow() { Resources res = getResources(); final int columns = res.getInteger(R.integer.bubbles_overflow_columns); mRecyclerView.setLayoutManager( @@ -137,6 +133,22 @@ public class BubbleOverflowActivity extends Activity { mAdapter = new BubbleOverflowAdapter(getApplicationContext(), mOverflowBubbles, mBubbleController::promoteBubbleFromOverflow, viewWidth, viewHeight); mRecyclerView.setAdapter(mAdapter); + + mOverflowBubbles.clear(); + mOverflowBubbles.addAll(mBubbleController.getOverflowBubbles()); + mAdapter.notifyDataSetChanged(); + updateEmptyStateVisibility(); + + mBubbleController.setOverflowListener(mDataListener); + updateTheme(); + } + + void updateEmptyStateVisibility() { + if (mOverflowBubbles.isEmpty()) { + mEmptyState.setVisibility(View.VISIBLE); + } else { + mEmptyState.setVisibility(View.GONE); + } } /** @@ -168,22 +180,40 @@ public class BubbleOverflowActivity extends Activity { mEmptyStateSubtitle.setTextColor(textColor); } - void onDataChanged(List<Bubble> bubbles) { - mOverflowBubbles.clear(); - mOverflowBubbles.addAll(bubbles); - mAdapter.notifyDataSetChanged(); + private final BubbleData.Listener mDataListener = new BubbleData.Listener() { - if (mOverflowBubbles.isEmpty()) { - mEmptyState.setVisibility(View.VISIBLE); - } else { - mEmptyState.setVisibility(View.GONE); - } + @Override + public void applyUpdate(BubbleData.Update update) { + + Bubble toRemove = update.removedOverflowBubble; + if (toRemove != null) { + if (DEBUG_OVERFLOW) { + Log.d(TAG, "remove: " + toRemove); + } + toRemove.cleanupViews(); + final int i = mOverflowBubbles.indexOf(toRemove); + mOverflowBubbles.remove(toRemove); + mAdapter.notifyItemRemoved(i); + } + + Bubble toAdd = update.addedOverflowBubble; + if (toAdd != null) { + if (DEBUG_OVERFLOW) { + Log.d(TAG, "add: " + toAdd); + } + mOverflowBubbles.add(0, toAdd); + mAdapter.notifyItemInserted(0); + } + + updateEmptyStateVisibility(); - if (DEBUG_OVERFLOW) { - Log.d(TAG, "Updated overflow bubbles:\n" + BubbleDebugConfig.formatBubblesString( - mOverflowBubbles, /*selected*/ null)); + if (DEBUG_OVERFLOW) { + Log.d(TAG, BubbleDebugConfig.formatBubblesString( + mBubbleController.getOverflowBubbles(), + null)); + } } - } + }; @Override public void onStart() { @@ -198,8 +228,7 @@ public class BubbleOverflowActivity extends Activity { @Override public void onResume() { super.onResume(); - updateDimensions(); - updateTheme(); + updateOverflow(); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java index 64df2b99ee22..c1b68824d20f 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java @@ -276,6 +276,10 @@ public class BubbleStackView extends FrameLayout /** Description of current animation controller state. */ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { pw.println("Stack view state:"); + + String bubblesOnScreen = BubbleDebugConfig.formatBubblesString( + getBubblesOnScreen(), getExpandedBubble()); + pw.print(" bubbles on screen: "); pw.println(bubblesOnScreen); pw.print(" gestureInProgress: "); pw.println(mIsGestureInProgress); pw.print(" showingDismiss: "); pw.println(mDismissView.isShowing()); pw.print(" isExpansionAnimating: "); pw.println(mIsExpansionAnimating); diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt index 31830b94e8e4..40662536e57e 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt @@ -263,6 +263,7 @@ internal class ControlHolder( val context = itemView.context val fg = context.getResources().getColorStateList(ri.foreground, context.getTheme()) + icon.imageTintList = null ci.customIcon?.let { icon.setImageIcon(it) } ?: run { diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt index 371031020b14..2b529f9a6cde 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt @@ -104,6 +104,7 @@ class ControlsUiControllerImpl @Inject constructor ( private var hidden = true private lateinit var dismissGlobalActions: Runnable private val popupThemedContext = ContextThemeWrapper(context, R.style.Control_ListPopupWindow) + private var retainCache = false private val collator = Collator.getInstance(context.resources.configuration.locales[0]) private val localeComparator = compareBy<SelectionItem, CharSequence>(collator) { @@ -149,6 +150,7 @@ class ControlsUiControllerImpl @Inject constructor ( this.parent = parent this.dismissGlobalActions = dismissGlobalActions hidden = false + retainCache = false allStructures = controlsController.get().getFavorites() selectedStructure = loadPreference(allStructures) @@ -235,6 +237,8 @@ class ControlsUiControllerImpl @Inject constructor ( } putIntentExtras(i, si) startActivity(context, i) + + retainCache = true } private fun putIntentExtras(intent: Intent, si: StructureInfo) { @@ -497,7 +501,7 @@ class ControlsUiControllerImpl @Inject constructor ( controlsListingController.get().removeCallback(listingCallback) - RenderInfo.clearCache() + if (!retainCache) RenderInfo.clearCache() } override fun onRefreshState(componentName: ComponentName, controls: List<Control>) { diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java index 3e64749c0dce..9c90510099a2 100644 --- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java +++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java @@ -19,6 +19,7 @@ import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; import static android.view.WindowManager.ScreenshotSource.SCREENSHOT_GLOBAL_ACTIONS; import static android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN; +import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON; import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST; import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED; @@ -548,7 +549,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, if (!mDeviceProvisioned && !action.showBeforeProvisioning()) { return false; } - return true; + return action.shouldShow(); } /** @@ -961,6 +962,8 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, @VisibleForTesting class ScreenshotAction extends SinglePressAction implements LongPressAction { + final String KEY_SYSTEM_NAV_2BUTTONS = "system_nav_2buttons"; + public ScreenshotAction() { super(R.drawable.ic_screenshot, R.string.global_action_screenshot); } @@ -993,6 +996,19 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, } @Override + public boolean shouldShow() { + // Include screenshot in power menu for legacy nav because it is not accessible + // through Recents in that mode + return is2ButtonNavigationEnabled(); + } + + boolean is2ButtonNavigationEnabled() { + return NAV_BAR_MODE_2BUTTON == mContext.getResources().getInteger( + com.android.internal.R.integer.config_navBarInteractionMode); + } + + + @Override public boolean onLongPress() { if (FeatureFlagUtils.isEnabled(mContext, FeatureFlagUtils.SCREENRECORD_LONG_PRESS)) { mUiEventLogger.log(GlobalActionsEvent.GA_SCREENSHOT_LONG_PRESS); @@ -1615,6 +1631,10 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, * @return */ CharSequence getMessage(); + + default boolean shouldShow() { + return true; + } } /** diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt index e5a9ac10389f..f150381f4070 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt @@ -42,7 +42,7 @@ class MediaCarouselController @Inject constructor( private val mediaHostStatesManager: MediaHostStatesManager, private val activityStarter: ActivityStarter, @Main executor: DelayableExecutor, - mediaManager: MediaDataManager, + private val mediaManager: MediaDataManager, configurationController: ConfigurationController, falsingManager: FalsingManager ) { @@ -109,6 +109,7 @@ class MediaCarouselController @Inject constructor( private val pageIndicator: PageIndicator private val visualStabilityCallback: VisualStabilityManager.Callback private var needsReordering: Boolean = false + private var keysNeedRemoval = mutableSetOf<String>() private var isRtl: Boolean = false set(value) { if (value != field) { @@ -161,6 +162,10 @@ class MediaCarouselController @Inject constructor( needsReordering = false reorderAllPlayers() } + + keysNeedRemoval.forEach { removePlayer(it) } + keysNeedRemoval.clear() + // Let's reset our scroll position mediaCarouselScrollHandler.scrollToStart() } @@ -168,13 +173,19 @@ class MediaCarouselController @Inject constructor( true /* persistent */) mediaManager.addListener(object : MediaDataManager.Listener { override fun onMediaDataLoaded(key: String, oldKey: String?, data: MediaData) { - if (!data.active && !Utils.useMediaResumption(context)) { - // This view is inactive, let's remove this! This happens e.g when dismissing / - // timing out a view. We still have the data around because resumption could - // be on, but we should save the resources and release this. - onMediaDataRemoved(key) + addOrUpdatePlayer(key, oldKey, data) + val canRemove = data.isPlaying?.let { !it } ?: data.isClearable + if (canRemove && !Utils.useMediaResumption(context)) { + // This view isn't playing, let's remove this! This happens e.g when + // dismissing/timing out a view. We still have the data around because + // resumption could be on, but we should save the resources and release this. + if (visualStabilityManager.isReorderingAllowed) { + onMediaDataRemoved(key) + } else { + keysNeedRemoval.add(key) + } } else { - addOrUpdatePlayer(key, oldKey, data) + keysNeedRemoval.remove(key) } } @@ -236,12 +247,12 @@ class MediaCarouselController @Inject constructor( var newPlayer = mediaControlPanelFactory.get() newPlayer.attach(PlayerViewHolder.create(LayoutInflater.from(context), mediaContent)) newPlayer.mediaViewController.sizeChangedListener = this::updateCarouselDimensions - MediaPlayerData.addMediaPlayer(key, data, newPlayer) val lp = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) newPlayer.view?.player?.setLayoutParams(lp) newPlayer.bind(data) newPlayer.setListening(currentlyExpanded) + MediaPlayerData.addMediaPlayer(key, data, newPlayer) updatePlayerToState(newPlayer, noAnimation = true) reorderAllPlayers() } else { @@ -271,6 +282,9 @@ class MediaCarouselController @Inject constructor( removed.onDestroy() mediaCarouselScrollHandler.onPlayersChanged() updatePageIndicator() + + // Inform the media manager of a potentially late dismissal + mediaManager.dismissMediaData(key, 0L) } } @@ -478,12 +492,11 @@ class MediaCarouselController @Inject constructor( internal object MediaPlayerData { private data class MediaSortKey( val data: MediaData, - val updateTime: Long = 0, - val isPlaying: Boolean = false + val updateTime: Long = 0 ) private val comparator = - compareByDescending<MediaSortKey> { it.isPlaying } + compareByDescending<MediaSortKey> { it.data.isPlaying } .thenByDescending { it.data.isLocalSession } .thenByDescending { !it.data.resumption } .thenByDescending { it.updateTime } @@ -493,7 +506,7 @@ internal object MediaPlayerData { fun addMediaPlayer(key: String, data: MediaData, player: MediaControlPanel) { removeMediaPlayer(key) - val sortKey = MediaSortKey(data, System.currentTimeMillis(), player.isPlaying()) + val sortKey = MediaSortKey(data, System.currentTimeMillis()) mediaData.put(key, sortKey) mediaPlayers.put(sortKey, player) } diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaData.kt b/packages/SystemUI/src/com/android/systemui/media/MediaData.kt index d6a02687c905..40a879abde34 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaData.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaData.kt @@ -94,7 +94,17 @@ data class MediaData( * Notification key for cancelling a media player after a timeout (when not using resumption.) */ val notificationKey: String? = null, - var hasCheckedForResume: Boolean = false + var hasCheckedForResume: Boolean = false, + + /** + * If apps do not report PlaybackState, set as null to imply 'undetermined' + */ + val isPlaying: Boolean? = null, + + /** + * Set from the notification and used as fallback when PlaybackState cannot be determined + */ + val isClearable: Boolean = true ) /** State of a media action. */ diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataFilter.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataFilter.kt index 0664a41f841d..1f580a953d09 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaDataFilter.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataFilter.kt @@ -136,14 +136,8 @@ class MediaDataFilter @Inject constructor( /** * Are there any media entries we should display? - * If resumption is enabled, this will include inactive players - * If resumption is disabled, we only want to show active players */ - fun hasAnyMedia() = if (mediaResumeListener.isResumptionEnabled()) { - userEntries.isNotEmpty() - } else { - hasActiveMedia() - } + fun hasAnyMedia() = userEntries.isNotEmpty() /** * Add a listener for filtered [MediaData] changes diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt index b2ad19b5f42f..cb6b22c2321f 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt @@ -47,6 +47,7 @@ import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.dump.DumpManager import com.android.systemui.plugins.ActivityStarter +import com.android.systemui.statusbar.NotificationMediaManager.isPlayingState import com.android.systemui.statusbar.notification.MediaNotificationProcessor import com.android.systemui.statusbar.notification.row.HybridGroupManager import com.android.systemui.util.Assert @@ -350,6 +351,16 @@ class MediaDataManager( } fun dismissMediaData(key: String, delay: Long) { + backgroundExecutor.execute { + mediaEntries[key]?.let { mediaData -> + if (mediaData.isLocalSession) { + mediaData.token?.let { + val mediaController = mediaControllerFactory.create(it) + mediaController.transportControls.stop() + } + } + } + } foregroundExecutor.executeDelayed({ removeEntry(key) }, delay) } @@ -500,6 +511,7 @@ class MediaDataManager( val isLocalSession = mediaController.playbackInfo?.playbackType == MediaController.PlaybackInfo.PLAYBACK_TYPE_LOCAL ?: true + val isPlaying = mediaController.playbackState?.let { isPlayingState(it.state) } ?: null foregroundExecutor.execute { val resumeAction: Runnable? = mediaEntries[key]?.resumeAction @@ -509,7 +521,8 @@ class MediaDataManager( smallIconDrawable, artist, song, artWorkIcon, actionIcons, actionsToShowCollapsed, sbn.packageName, token, notif.contentIntent, null, active, resumeAction = resumeAction, isLocalSession = isLocalSession, - notificationKey = key, hasCheckedForResume = hasCheckedForResume)) + notificationKey = key, hasCheckedForResume = hasCheckedForResume, + isPlaying = isPlaying, isClearable = sbn.isClearable())) } } diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaResumeListener.kt b/packages/SystemUI/src/com/android/systemui/media/MediaResumeListener.kt index c00b5e92f93d..5b59214afdc9 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaResumeListener.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaResumeListener.kt @@ -125,8 +125,6 @@ class MediaResumeListener @Inject constructor( }, Settings.Secure.MEDIA_CONTROLS_RESUME_BLOCKED) } - fun isResumptionEnabled() = useMediaResumption - private fun loadSavedComponents() { // Make sure list is empty (if we switched users) resumeComponents.clear() diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java index 92d2f421d6ee..dfc82f120c90 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java @@ -38,11 +38,11 @@ import android.provider.DeviceConfig; import android.util.DisplayMetrics; import android.util.Log; import android.util.TypedValue; +import android.view.Choreographer; import android.view.ISystemGestureExclusionListener; import android.view.InputChannel; import android.view.InputDevice; import android.view.InputEvent; -import android.view.InputEventReceiver; import android.view.InputMonitor; import android.view.KeyCharacterMap; import android.view.KeyEvent; @@ -67,6 +67,7 @@ import com.android.systemui.recents.OverviewProxyService; import com.android.systemui.settings.CurrentUserTracker; import com.android.systemui.shared.plugins.PluginManager; import com.android.systemui.shared.system.ActivityManagerWrapper; +import com.android.systemui.shared.system.InputChannelCompat; import com.android.systemui.shared.system.QuickStepContract; import com.android.systemui.shared.system.SysUiStatsLog; import com.android.systemui.shared.system.TaskStackChangeListener; @@ -169,7 +170,7 @@ public class EdgeBackGestureHandler extends CurrentUserTracker implements Displa private boolean mGestureBlockingActivityRunning; private InputMonitor mInputMonitor; - private InputEventReceiver mInputEventReceiver; + private InputChannelCompat.InputEventReceiver mInputEventReceiver; private NavigationEdgeBackPlugin mEdgeBackPlugin; private int mLeftInset; @@ -383,8 +384,9 @@ public class EdgeBackGestureHandler extends CurrentUserTracker implements Displa // Register input event receiver mInputMonitor = InputManager.getInstance().monitorGestureInput( "edge-swipe", mDisplayId); - mInputEventReceiver = new SysUiInputEventReceiver( - mInputMonitor.getInputChannel(), Looper.getMainLooper()); + mInputEventReceiver = new InputChannelCompat.InputEventReceiver( + mInputMonitor.getInputChannel(), Looper.getMainLooper(), + Choreographer.getInstance(), this::onInputEvent); // Add a nav bar panel window setEdgeBackPlugin(new NavigationBarEdgePanel(mContext)); @@ -520,6 +522,7 @@ public class EdgeBackGestureHandler extends CurrentUserTracker implements Displa if (action == MotionEvent.ACTION_DOWN) { // Verify if this is in within the touch region and we aren't in immersive mode, and // either the bouncer is showing or the notification panel is hidden + mInputEventReceiver.setBatchingEnabled(false); mIsOnLeftEdge = ev.getX() <= mEdgeWidthLeft + mLeftInset; mLogGesture = false; mInRejectedExclusion = false; @@ -571,6 +574,7 @@ public class EdgeBackGestureHandler extends CurrentUserTracker implements Displa mThresholdCrossed = true; // Capture inputs mInputMonitor.pilferPointers(); + mInputEventReceiver.setBatchingEnabled(true); } else { logGesture(SysUiStatsLog.BACK_GESTURE__TYPE__INCOMPLETE_FAR_FROM_EDGE); } @@ -672,15 +676,4 @@ public class EdgeBackGestureHandler extends CurrentUserTracker implements Displa } proto.edgeBackGestureHandler.allowGesture = mAllowGesture; } - - class SysUiInputEventReceiver extends InputEventReceiver { - SysUiInputEventReceiver(InputChannel channel, Looper looper) { - super(channel, looper); - } - - public void onInputEvent(InputEvent event) { - EdgeBackGestureHandler.this.onInputEvent(event); - finishInputEvent(event, true); - } - } } diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java b/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java index b464e8adea59..89b5c38d94a7 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java +++ b/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java @@ -22,8 +22,8 @@ import static android.util.TypedValue.COMPLEX_UNIT_DIP; import static android.view.Surface.ROTATION_0; import static android.view.Surface.ROTATION_180; -import android.app.ActivityManager; import android.app.ActivityTaskManager; +import android.app.ActivityTaskManager.RootTaskInfo; import android.content.ComponentName; import android.content.Context; import android.content.res.Resources; @@ -328,14 +328,14 @@ public class PipBoundsHandler { return false; } - // Bail early if the pinned stack is staled. - final ActivityManager.StackInfo pinnedStackInfo; + // Bail early if the pinned task is staled. + final RootTaskInfo pinnedTaskInfo; try { - pinnedStackInfo = ActivityTaskManager.getService() - .getStackInfo(WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED); - if (pinnedStackInfo == null) return false; + pinnedTaskInfo = ActivityTaskManager.getService() + .getRootTaskInfo(WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED); + if (pinnedTaskInfo == null) return false; } catch (RemoteException e) { - Log.e(TAG, "Failed to get StackInfo for pinned stack", e); + Log.e(TAG, "Failed to get RootTaskInfo for pinned task", e); return false; } @@ -362,7 +362,7 @@ public class PipBoundsHandler { getInsetBounds(outInsetBounds); outBounds.set(postChangeStackBounds); - t.setBounds(pinnedStackInfo.stackToken, outBounds); + t.setBounds(pinnedTaskInfo.token, outBounds); return true; } diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java index 5793cddd7d26..a5ee3a0cd4e0 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java +++ b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java @@ -99,6 +99,36 @@ public class PipTaskOrganizer extends TaskOrganizer implements ShellTaskOrganize private static final int MSG_FINISH_RESIZE = 4; private static final int MSG_RESIZE_USER = 5; + // Not a complete set of states but serves what we want right now. + private enum State { + UNDEFINED(0), + TASK_APPEARED(1), + ENTERING_PIP(2), + EXITING_PIP(3); + + private final int mStateValue; + + State(int value) { + mStateValue = value; + } + + private boolean isInPip() { + return mStateValue >= TASK_APPEARED.mStateValue + && mStateValue != EXITING_PIP.mStateValue; + } + + /** + * Resize request can be initiated in other component, ignore if we are no longer in PIP, + * still waiting for animation or we're exiting from it. + * + * @return {@code true} if the resize request should be blocked/ignored. + */ + private boolean shouldBlockResizeRequest() { + return mStateValue < ENTERING_PIP.mStateValue + || mStateValue == EXITING_PIP.mStateValue; + } + } + private final Context mContext; private final Handler mMainHandler; private final Handler mUpdateHandler; @@ -200,8 +230,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements ShellTaskOrganize private ActivityManager.RunningTaskInfo mTaskInfo; private WindowContainerToken mToken; private SurfaceControl mLeash; - private boolean mInPip; - private boolean mExitingPip; + private State mState = State.UNDEFINED; private @PipAnimationController.AnimationType int mOneShotAnimationType = ANIM_TYPE_BOUNDS; private PipSurfaceTransactionHelper.SurfaceControlTransactionFactory mSurfaceControlTransactionFactory; @@ -253,11 +282,11 @@ public class PipTaskOrganizer extends TaskOrganizer implements ShellTaskOrganize } public boolean isInPip() { - return mInPip; + return mState.isInPip(); } public boolean isDeferringEnterPipAnimation() { - return mInPip && mShouldDeferEnteringPip; + return mState.isInPip() && mShouldDeferEnteringPip; } /** @@ -286,9 +315,9 @@ public class PipTaskOrganizer extends TaskOrganizer implements ShellTaskOrganize * @param animationDurationMs duration in millisecond for the exiting PiP transition */ public void exitPip(int animationDurationMs) { - if (!mInPip || mExitingPip || mToken == null) { + if (!mState.isInPip() || mState == State.EXITING_PIP || mToken == null) { Log.wtf(TAG, "Not allowed to exitPip in current state" - + " mInPip=" + mInPip + " mExitingPip=" + mExitingPip + " mToken=" + mToken); + + " mState=" + mState + " mToken=" + mToken); return; } @@ -303,6 +332,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements ShellTaskOrganize ? TRANSITION_DIRECTION_LEAVE_PIP_TO_SPLIT_SCREEN : TRANSITION_DIRECTION_LEAVE_PIP; if (orientationDiffers) { + mState = State.EXITING_PIP; // Send started callback though animation is ignored. sendOnPipTransitionStarted(direction); // Don't bother doing an animation if the display rotation differs or if it's in @@ -311,7 +341,6 @@ public class PipTaskOrganizer extends TaskOrganizer implements ShellTaskOrganize mTaskOrganizer.applyTransaction(wct); // Send finished callback though animation is ignored. sendOnPipTransitionFinished(direction); - mInPip = false; } else { final SurfaceControl.Transaction tx = mSurfaceControlTransactionFactory.getTransaction(); @@ -333,11 +362,10 @@ public class PipTaskOrganizer extends TaskOrganizer implements ShellTaskOrganize scheduleAnimateResizePip(mLastReportedBounds, destinationBounds, null /* sourceHintRect */, direction, animationDurationMs, null /* updateBoundsCallback */); - mInPip = false; + mState = State.EXITING_PIP; } }); } - mExitingPip = true; } private void applyWindowingModeChangeOnExit(WindowContainerTransaction wct, int direction) { @@ -356,9 +384,9 @@ public class PipTaskOrganizer extends TaskOrganizer implements ShellTaskOrganize * Removes PiP immediately. */ public void removePip() { - if (!mInPip || mExitingPip || mToken == null) { + if (!mState.isInPip() || mToken == null) { Log.wtf(TAG, "Not allowed to removePip in current state" - + " mInPip=" + mInPip + " mExitingPip=" + mExitingPip + " mToken=" + mToken); + + " mState=" + mState + " mToken=" + mToken); return; } @@ -370,7 +398,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements ShellTaskOrganize .setDuration(mEnterExitAnimationDuration) .start()); mInitialState.remove(mToken.asBinder()); - mExitingPip = true; + mState = State.EXITING_PIP; } private void removePipImmediately() { @@ -392,8 +420,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements ShellTaskOrganize Objects.requireNonNull(info, "Requires RunningTaskInfo"); mTaskInfo = info; mToken = mTaskInfo.token; - mInPip = true; - mExitingPip = false; + mState = State.TASK_APPEARED; mLeash = leash; mInitialState.put(mToken.asBinder(), new Configuration(mTaskInfo.configuration)); mPictureInPictureParams = mTaskInfo.pictureInPictureParams; @@ -423,6 +450,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements ShellTaskOrganize scheduleAnimateResizePip(currentBounds, destinationBounds, sourceHintRect, TRANSITION_DIRECTION_TO_PIP, mEnterExitAnimationDuration, null /* updateBoundsCallback */); + mState = State.ENTERING_PIP; } else if (mOneShotAnimationType == ANIM_TYPE_ALPHA) { enterPipWithAlphaAnimation(destinationBounds, mEnterExitAnimationDuration); mOneShotAnimationType = ANIM_TYPE_BOUNDS; @@ -468,6 +496,9 @@ public class PipTaskOrganizer extends TaskOrganizer implements ShellTaskOrganize .setPipAnimationCallback(mPipAnimationCallback) .setDuration(durationMs) .start()); + // mState is set right after the animation is kicked off to block any resize + // requests such as offsetPip that may have been called prior to the transition. + mState = State.ENTERING_PIP; } }); } @@ -560,7 +591,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements ShellTaskOrganize */ @Override public void onTaskVanished(ActivityManager.RunningTaskInfo info) { - if (!mInPip) { + if (!mState.isInPip()) { return; } final WindowContainerToken token = info.token; @@ -571,8 +602,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements ShellTaskOrganize } mShouldDeferEnteringPip = false; mPictureInPictureParams = null; - mInPip = false; - mExitingPip = false; + mState = State.UNDEFINED; mPipUiEventLoggerLogger.setTaskInfo(null); } @@ -600,7 +630,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements ShellTaskOrganize @Override public void onFixedRotationFinished(int displayId) { - if (mShouldDeferEnteringPip && mInPip) { + if (mShouldDeferEnteringPip && mState.isInPip()) { final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds( mTaskInfo.topActivity, getAspectRatioOrDefault(mPictureInPictureParams), null /* bounds */, getMinimalSize(mTaskInfo.topActivityInfo)); @@ -623,7 +653,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements ShellTaskOrganize mPipAnimationController.getCurrentAnimator(); if (animator == null || !animator.isRunning() || animator.getTransitionDirection() != TRANSITION_DIRECTION_TO_PIP) { - if (mInPip && fromRotation) { + if (mState.isInPip() && fromRotation) { // If we are rotating while there is a current animation, immediately cancel the // animation (remove the listeners so we don't trigger the normal finish resize // call that should only happen on the update thread) @@ -712,10 +742,10 @@ public class PipTaskOrganizer extends TaskOrganizer implements ShellTaskOrganize private void scheduleAnimateResizePip(Rect currentBounds, Rect destinationBounds, Rect sourceHintRect, @PipAnimationController.TransitionDirection int direction, int durationMs, Consumer<Rect> updateBoundsCallback) { - if (!mInPip) { + if (!mState.isInPip()) { // TODO: tend to use shouldBlockResizeRequest here as well but need to consider // the fact that when in exitPip, scheduleAnimateResizePip is executed in the window - // container transaction callback and we want to set the mExitingPip immediately. + // container transaction callback and we want to set the mState immediately. return; } @@ -772,7 +802,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements ShellTaskOrganize private void scheduleFinishResizePip(Rect destinationBounds, @PipAnimationController.TransitionDirection int direction, Consumer<Rect> updateBoundsCallback) { - if (shouldBlockResizeRequest()) { + if (mState.shouldBlockResizeRequest()) { return; } @@ -791,7 +821,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements ShellTaskOrganize mSurfaceTransactionHelper .crop(tx, mLeash, destinationBounds) .resetScale(tx, mLeash, destinationBounds) - .round(tx, mLeash, mInPip); + .round(tx, mLeash, mState.isInPip()); return tx; } @@ -800,7 +830,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements ShellTaskOrganize */ public void scheduleOffsetPip(Rect originalBounds, int offset, int duration, Consumer<Rect> updateBoundsCallback) { - if (shouldBlockResizeRequest()) { + if (mState.shouldBlockResizeRequest()) { return; } if (mShouldDeferEnteringPip) { @@ -845,7 +875,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements ShellTaskOrganize final SurfaceControl.Transaction tx = mSurfaceControlTransactionFactory.getTransaction(); mSurfaceTransactionHelper .crop(tx, mLeash, destinationBounds) - .round(tx, mLeash, mInPip); + .round(tx, mLeash, mState.isInPip()); tx.apply(); } @@ -983,16 +1013,6 @@ public class PipTaskOrganizer extends TaskOrganizer implements ShellTaskOrganize } /** - * Resize request can be initiated in other component, ignore if we are no longer in PIP - * or we're exiting from it. - * - * @return {@code true} if the resize request should be blocked/ignored. - */ - private boolean shouldBlockResizeRequest() { - return !mInPip || mExitingPip; - } - - /** * Sync with {@link SplitScreen} on destination bounds if PiP is going to split screen. * * @param destinationBoundsOut contain the updated destination bounds if applicable @@ -1026,7 +1046,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements ShellTaskOrganize pw.println(innerPrefix + "mToken=" + mToken + " binder=" + (mToken != null ? mToken.asBinder() : null)); pw.println(innerPrefix + "mLeash=" + mLeash); - pw.println(innerPrefix + "mInPip=" + mInPip); + pw.println(innerPrefix + "mState=" + mState); pw.println(innerPrefix + "mOneShotAnimationType=" + mOneShotAnimationType); pw.println(innerPrefix + "mPictureInPictureParams=" + mPictureInPictureParams); pw.println(innerPrefix + "mLastReportedBounds=" + mLastReportedBounds); diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipController.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipController.java index 6998e90b3a7c..4f225e2f9590 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipController.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipController.java @@ -25,6 +25,7 @@ import static com.android.systemui.pip.PipAnimationController.isOutPipDirection; import android.annotation.Nullable; import android.app.ActivityManager; import android.app.ActivityTaskManager; +import android.app.ActivityTaskManager.RootTaskInfo; import android.app.IActivityManager; import android.app.RemoteAction; import android.content.ComponentName; @@ -324,9 +325,9 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac configController.addCallback(mOverlayChangedListener); try { - ActivityManager.StackInfo stackInfo = ActivityTaskManager.getService().getStackInfo( + RootTaskInfo taskInfo = ActivityTaskManager.getService().getRootTaskInfo( WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED); - if (stackInfo != null) { + if (taskInfo != null) { // If SystemUI restart, and it already existed a pinned stack, // register the pip input consumer to ensure touch can send to it. mInputConsumerController.registerInputConsumer(true /* withSfVsync */); diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java index 873ba26b39ab..d308172689db 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java @@ -19,8 +19,8 @@ package com.android.systemui.pip.phone; import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; -import android.app.ActivityManager.StackInfo; import android.app.ActivityTaskManager; +import android.app.ActivityTaskManager.RootTaskInfo; import android.app.RemoteAction; import android.content.Context; import android.content.pm.ParceledListSlice; @@ -312,10 +312,10 @@ public class PipMenuActivityController { // Fetch the pinned stack bounds Rect stackBounds = null; try { - StackInfo pinnedStackInfo = ActivityTaskManager.getService().getStackInfo( + RootTaskInfo pinnedTaskInfo = ActivityTaskManager.getService().getRootTaskInfo( WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED); - if (pinnedStackInfo != null) { - stackBounds = pinnedStackInfo.bounds; + if (pinnedTaskInfo != null) { + stackBounds = pinnedTaskInfo.bounds; } } catch (RemoteException e) { Log.e(TAG, "Error showing PIP menu", e); diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuView.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuView.java index 993bfe04f9a3..c66f442c4c0d 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuView.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuView.java @@ -475,12 +475,10 @@ public class PipMenuView extends FrameLayout { final Pair<ComponentName, Integer> topPipActivityInfo = PipUtils.getTopPipActivity(mContext, ActivityManager.getService()); if (topPipActivityInfo.first != null) { - final UserHandle user = UserHandle.of(topPipActivityInfo.second); final Intent settingsIntent = new Intent(ACTION_PICTURE_IN_PICTURE_SETTINGS, Uri.fromParts("package", topPipActivityInfo.first.getPackageName(), null)); - settingsIntent.putExtra(Intent.EXTRA_USER_HANDLE, user); settingsIntent.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK); - mContext.startActivity(settingsIntent); + mContext.startActivityAsUser(settingsIntent, UserHandle.CURRENT); } } diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java index 50d20d3572d1..08d9b2ae21b0 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java @@ -15,7 +15,7 @@ */ package com.android.systemui.pip.phone; -import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.PIP_USER_RESIZE; +import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.PIP_PINCH_RESIZE; import static com.android.internal.policy.TaskResizingAlgorithm.CTRL_BOTTOM; import static com.android.internal.policy.TaskResizingAlgorithm.CTRL_LEFT; import static com.android.internal.policy.TaskResizingAlgorithm.CTRL_NONE; @@ -46,6 +46,7 @@ import android.view.InputEvent; import android.view.InputEventReceiver; import android.view.InputMonitor; import android.view.MotionEvent; +import android.view.ScaleGestureDetector; import android.view.ViewConfiguration; import com.android.internal.policy.TaskResizingAlgorithm; @@ -67,6 +68,8 @@ import java.util.function.Function; public class PipResizeGestureHandler { private static final String TAG = "PipResizeGestureHandler"; + private static final float PINCH_THRESHOLD = 0.05f; + private static final float STARTING_SCALE_FACTOR = 1.0f; private static final int INVALID_SYSUI_STATE_MASK = SYSUI_STATE_GLOBAL_ACTIONS_SHOWING @@ -83,6 +86,7 @@ public class PipResizeGestureHandler { private final int mDisplayId; private final Executor mMainExecutor; private final SysUiState mSysUiState; + private final ScaleGestureDetector mScaleGestureDetector; private final Region mTmpRegion = new Region(); private final PointF mDownPoint = new PointF(); @@ -105,8 +109,10 @@ public class PipResizeGestureHandler { private boolean mAllowGesture; private boolean mIsAttached; private boolean mIsEnabled; - private boolean mEnableUserResize; + private boolean mEnablePinchResize; private boolean mThresholdCrossed; + private boolean mUsingPinchToZoom = false; + private float mScaleFactor = STARTING_SCALE_FACTOR; private InputMonitor mInputMonitor; private InputEventReceiver mInputEventReceiver; @@ -136,17 +142,73 @@ public class PipResizeGestureHandler { context.getDisplay().getRealSize(mMaxSize); reloadResources(); - mEnableUserResize = DeviceConfig.getBoolean( + mScaleGestureDetector = new ScaleGestureDetector(context, + new ScaleGestureDetector.OnScaleGestureListener() { + @Override + public boolean onScale(ScaleGestureDetector detector) { + mScaleFactor *= detector.getScaleFactor(); + + if (!mThresholdCrossed + && (mScaleFactor > (STARTING_SCALE_FACTOR + PINCH_THRESHOLD) + || mScaleFactor < (STARTING_SCALE_FACTOR - PINCH_THRESHOLD))) { + mThresholdCrossed = true; + mInputMonitor.pilferPointers(); + } + if (mThresholdCrossed) { + int height = Math.min(mMaxSize.y, Math.max(mMinSize.y, + (int) (mScaleFactor * mLastDownBounds.height()))); + int width = Math.min(mMaxSize.x, Math.max(mMinSize.x, + (int) (mScaleFactor * mLastDownBounds.width()))); + int top, bottom, left, right; + + if ((mCtrlType & CTRL_TOP) != 0) { + top = mLastDownBounds.bottom - height; + bottom = mLastDownBounds.bottom; + } else { + top = mLastDownBounds.top; + bottom = mLastDownBounds.top + height; + } + + if ((mCtrlType & CTRL_LEFT) != 0) { + left = mLastDownBounds.right - width; + right = mLastDownBounds.right; + } else { + left = mLastDownBounds.left; + right = mLastDownBounds.left + width; + } + + mLastResizeBounds.set(left, top, right, bottom); + mPipTaskOrganizer.scheduleUserResizePip(mLastDownBounds, + mLastResizeBounds, + null); + } + return true; + } + + @Override + public boolean onScaleBegin(ScaleGestureDetector detector) { + setCtrlTypeForPinchToZoom(); + return true; + } + + @Override + public void onScaleEnd(ScaleGestureDetector detector) { + mScaleFactor = STARTING_SCALE_FACTOR; + finishResize(); + } + }); + + mEnablePinchResize = DeviceConfig.getBoolean( DeviceConfig.NAMESPACE_SYSTEMUI, - PIP_USER_RESIZE, - /* defaultValue = */ true); + PIP_PINCH_RESIZE, + /* defaultValue = */ false); deviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_SYSTEMUI, mMainExecutor, new DeviceConfig.OnPropertiesChangedListener() { @Override public void onPropertiesChanged(DeviceConfig.Properties properties) { - if (properties.getKeyset().contains(PIP_USER_RESIZE)) { - mEnableUserResize = properties.getBoolean( - PIP_USER_RESIZE, /* defaultValue = */ true); + if (properties.getKeyset().contains(PIP_PINCH_RESIZE)) { + mEnablePinchResize = properties.getBoolean( + PIP_PINCH_RESIZE, /* defaultValue = */ false); } } }); @@ -193,7 +255,7 @@ public class PipResizeGestureHandler { } private void updateIsEnabled() { - boolean isEnabled = mIsAttached && mEnableUserResize; + boolean isEnabled = mIsAttached; if (isEnabled == mIsEnabled) { return; } @@ -211,7 +273,11 @@ public class PipResizeGestureHandler { private void onInputEvent(InputEvent ev) { if (ev instanceof MotionEvent) { - onMotionEvent((MotionEvent) ev); + if (mUsingPinchToZoom) { + mScaleGestureDetector.onTouchEvent((MotionEvent) ev); + } else { + onDragCornerResize((MotionEvent) ev); + } } } @@ -254,8 +320,51 @@ public class PipResizeGestureHandler { } public boolean willStartResizeGesture(MotionEvent ev) { - return mEnableUserResize && isInValidSysUiState() - && isWithinTouchRegion((int) ev.getRawX(), (int) ev.getRawY()); + if (isInValidSysUiState()) { + switch (ev.getActionMasked()) { + case MotionEvent.ACTION_DOWN: + // Always pass the DOWN event to the ScaleGestureDetector + mScaleGestureDetector.onTouchEvent(ev); + if (isWithinTouchRegion((int) ev.getRawX(), (int) ev.getRawY())) { + return true; + } + break; + + case MotionEvent.ACTION_POINTER_DOWN: + if (mEnablePinchResize && ev.getPointerCount() == 2) { + mUsingPinchToZoom = true; + return true; + } + break; + + default: + break; + } + } + return false; + } + + private void setCtrlTypeForPinchToZoom() { + final Rect currentPipBounds = mMotionHelper.getBounds(); + mLastDownBounds.set(mMotionHelper.getBounds()); + + Rect movementBounds = mMovementBoundsSupplier.apply(currentPipBounds); + mDisplayBounds.set(movementBounds.left, + movementBounds.top, + movementBounds.right + currentPipBounds.width(), + movementBounds.bottom + currentPipBounds.height()); + + if (currentPipBounds.left == mDisplayBounds.left) { + mCtrlType |= CTRL_RIGHT; + } else { + mCtrlType |= CTRL_LEFT; + } + + if (currentPipBounds.top > mDisplayBounds.top + mDisplayBounds.height()) { + mCtrlType |= CTRL_TOP; + } else { + mCtrlType |= CTRL_BOTTOM; + } } private void setCtrlType(int x, int y) { @@ -295,7 +404,7 @@ public class PipResizeGestureHandler { return (mSysUiState.getFlags() & INVALID_SYSUI_STATE_MASK) == 0; } - private void onMotionEvent(MotionEvent ev) { + private void onDragCornerResize(MotionEvent ev) { int action = ev.getActionMasked(); float x = ev.getX(); float y = ev.getY(); @@ -345,28 +454,33 @@ public class PipResizeGestureHandler { break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: - if (!mLastResizeBounds.isEmpty()) { - mUserResizeBounds.set(mLastResizeBounds); - mPipTaskOrganizer.scheduleFinishResizePip(mLastResizeBounds, - (Rect bounds) -> { - new Handler(Looper.getMainLooper()).post(() -> { - mMotionHelper.synchronizePinnedStackBounds(); - mUpdateMovementBoundsRunnable.run(); - resetState(); - }); - }); - mPipUiEventLogger.log( - PipUiEventLogger.PipUiEventEnum.PICTURE_IN_PICTURE_RESIZE); - } else { - resetState(); - } + finishResize(); break; } } } + private void finishResize() { + if (!mLastResizeBounds.isEmpty()) { + mUserResizeBounds.set(mLastResizeBounds); + mPipTaskOrganizer.scheduleFinishResizePip(mLastResizeBounds, + (Rect bounds) -> { + new Handler(Looper.getMainLooper()).post(() -> { + mMotionHelper.synchronizePinnedStackBounds(); + mUpdateMovementBoundsRunnable.run(); + resetState(); + }); + }); + mPipUiEventLogger.log( + PipUiEventLogger.PipUiEventEnum.PICTURE_IN_PICTURE_RESIZE); + } else { + resetState(); + } + } + private void resetState() { mCtrlType = CTRL_NONE; + mUsingPinchToZoom = false; mAllowGesture = false; mThresholdCrossed = false; } @@ -397,7 +511,7 @@ public class PipResizeGestureHandler { pw.println(innerPrefix + "mAllowGesture=" + mAllowGesture); pw.println(innerPrefix + "mIsAttached=" + mIsAttached); pw.println(innerPrefix + "mIsEnabled=" + mIsEnabled); - pw.println(innerPrefix + "mEnableUserResize=" + mEnableUserResize); + pw.println(innerPrefix + "mEnablePinchResize=" + mEnablePinchResize); pw.println(innerPrefix + "mThresholdCrossed=" + mThresholdCrossed); } diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java index 9693f235a4ff..97b3484292c6 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java @@ -650,8 +650,7 @@ public class PipTouchHandler { } MotionEvent ev = (MotionEvent) inputEvent; - if (ev.getActionMasked() == MotionEvent.ACTION_DOWN - && mPipResizeGestureHandler.willStartResizeGesture(ev)) { + if (mPipResizeGestureHandler.willStartResizeGesture(ev)) { // Initialize the touch state for the gesture, but immediately reset to invalidate the // gesture mTouchState.onTouchEvent(ev); diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipUtils.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipUtils.java index 4cfec0193b54..baa8f118f362 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipUtils.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipUtils.java @@ -19,8 +19,8 @@ package com.android.systemui.pip.phone; import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; -import android.app.ActivityManager.StackInfo; import android.app.ActivityTaskManager; +import android.app.ActivityTaskManager.RootTaskInfo; import android.app.IActivityManager; import android.content.ComponentName; import android.content.Context; @@ -40,15 +40,15 @@ public class PipUtils { IActivityManager activityManager) { try { final String sysUiPackageName = context.getPackageName(); - final StackInfo pinnedStackInfo = ActivityTaskManager.getService().getStackInfo( + final RootTaskInfo pinnedTaskInfo = ActivityTaskManager.getService().getRootTaskInfo( WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED); - if (pinnedStackInfo != null && pinnedStackInfo.taskIds != null && - pinnedStackInfo.taskIds.length > 0) { - for (int i = pinnedStackInfo.taskNames.length - 1; i >= 0; i--) { + if (pinnedTaskInfo != null && pinnedTaskInfo.childTaskIds != null + && pinnedTaskInfo.childTaskIds.length > 0) { + for (int i = pinnedTaskInfo.childTaskNames.length - 1; i >= 0; i--) { ComponentName cn = ComponentName.unflattenFromString( - pinnedStackInfo.taskNames[i]); + pinnedTaskInfo.childTaskNames[i]); if (cn != null && !cn.getPackageName().equals(sysUiPackageName)) { - return new Pair<>(cn, pinnedStackInfo.taskUserIds[i]); + return new Pair<>(cn, pinnedTaskInfo.childTaskUserIds[i]); } } } diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipController.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipController.java index 3b3235f1e63c..12a545aa4b02 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipController.java +++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipController.java @@ -21,8 +21,8 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import android.app.ActivityManager.RunningTaskInfo; -import android.app.ActivityManager.StackInfo; import android.app.ActivityTaskManager; +import android.app.ActivityTaskManager.RootTaskInfo; import android.app.IActivityTaskManager; import android.app.RemoteAction; import android.content.BroadcastReceiver; @@ -289,7 +289,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac // 1. Configuration changed due to the language change (RTL <-> RTL) // 2. SystemUI restarts after the crash mPipBounds = mDefaultPipBounds; - resizePinnedStack(getPinnedStackInfo() == null ? STATE_NO_PIP : STATE_PIP); + resizePinnedStack(getPinnedTaskInfo() == null ? STATE_NO_PIP : STATE_PIP); } /** @@ -505,15 +505,15 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac return mState != STATE_NO_PIP; } - private StackInfo getPinnedStackInfo() { - StackInfo stackInfo = null; + private RootTaskInfo getPinnedTaskInfo() { + RootTaskInfo taskInfo = null; try { - stackInfo = ActivityTaskManager.getService().getStackInfo( + taskInfo = ActivityTaskManager.getService().getRootTaskInfo( WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED); } catch (RemoteException e) { - Log.e(TAG, "getStackInfo failed", e); + Log.e(TAG, "getRootTaskInfo failed", e); } - return stackInfo; + return taskInfo; } private void handleMediaResourceGranted(String[] packageNames) { @@ -611,14 +611,14 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac if (getState() != STATE_NO_PIP) { boolean hasPip = false; - StackInfo stackInfo = getPinnedStackInfo(); - if (stackInfo == null || stackInfo.taskIds == null) { + RootTaskInfo taskInfo = getPinnedTaskInfo(); + if (taskInfo == null || taskInfo.childTaskIds == null) { Log.w(TAG, "There is nothing in pinned stack"); closePipInternal(false); return; } - for (int i = stackInfo.taskIds.length - 1; i >= 0; --i) { - if (stackInfo.taskIds[i] == mPipTaskId) { + for (int i = taskInfo.childTaskIds.length - 1; i >= 0; --i) { + if (taskInfo.childTaskIds[i] == mPipTaskId) { // PIP task is still alive. hasPip = true; break; @@ -642,16 +642,16 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac public void onActivityPinned(String packageName, int userId, int taskId, int stackId) { if (DEBUG) Log.d(TAG, "onActivityPinned()"); - StackInfo stackInfo = getPinnedStackInfo(); - if (stackInfo == null) { + RootTaskInfo taskInfo = getPinnedTaskInfo(); + if (taskInfo == null) { Log.w(TAG, "Cannot find pinned stack"); return; } - if (DEBUG) Log.d(TAG, "PINNED_STACK:" + stackInfo); - mPinnedStackId = stackInfo.stackId; - mPipTaskId = stackInfo.taskIds[stackInfo.taskIds.length - 1]; + if (DEBUG) Log.d(TAG, "PINNED_STACK:" + taskInfo); + mPinnedStackId = taskInfo.taskId; + mPipTaskId = taskInfo.childTaskIds[taskInfo.childTaskIds.length - 1]; mPipComponentName = ComponentName.unflattenFromString( - stackInfo.taskNames[stackInfo.taskNames.length - 1]); + taskInfo.childTaskNames[taskInfo.childTaskNames.length - 1]); // Set state to STATE_PIP so we show it when the pinned stack animation ends. mState = STATE_PIP; mMediaSessionManager.addOnActiveSessionsChangedListener( diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt index e57478eb0988..4d6d71c06085 100644 --- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt +++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt @@ -72,6 +72,8 @@ class PrivacyItemController @Inject constructor( private const val ALL_INDICATORS = SystemUiDeviceConfigFlags.PROPERTY_PERMISSIONS_HUB_ENABLED private const val MIC_CAMERA = SystemUiDeviceConfigFlags.PROPERTY_MIC_CAMERA_ENABLED + private const val DEFAULT_ALL_INDICATORS = false + private const val DEFAULT_MIC_CAMERA = true } @VisibleForTesting @@ -81,12 +83,12 @@ class PrivacyItemController @Inject constructor( private fun isAllIndicatorsEnabled(): Boolean { return deviceConfigProxy.getBoolean(DeviceConfig.NAMESPACE_PRIVACY, - ALL_INDICATORS, false) + ALL_INDICATORS, DEFAULT_ALL_INDICATORS) } private fun isMicCameraEnabled(): Boolean { return deviceConfigProxy.getBoolean(DeviceConfig.NAMESPACE_PRIVACY, - MIC_CAMERA, false) + MIC_CAMERA, DEFAULT_MIC_CAMERA) } private var currentUserIds = emptyList<Int>() @@ -118,12 +120,13 @@ class PrivacyItemController @Inject constructor( // Running on the ui executor so can iterate on callbacks if (properties.keyset.contains(ALL_INDICATORS)) { - allIndicatorsAvailable = properties.getBoolean(ALL_INDICATORS, false) + allIndicatorsAvailable = properties.getBoolean(ALL_INDICATORS, + DEFAULT_ALL_INDICATORS) callbacks.forEach { it.get()?.onFlagAllChanged(allIndicatorsAvailable) } } if (properties.keyset.contains(MIC_CAMERA)) { - micCameraAvailable = properties.getBoolean(MIC_CAMERA, false) + micCameraAvailable = properties.getBoolean(MIC_CAMERA, DEFAULT_MIC_CAMERA) callbacks.forEach { it.get()?.onFlagMicCameraChanged(micCameraAvailable) } } internalUiExecutor.updateListeningState() diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java index cba938f5e1a6..2a976f546ba4 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java +++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java @@ -75,8 +75,6 @@ import com.android.systemui.navigationbar.NavigationBar; import com.android.systemui.navigationbar.NavigationBarController; import com.android.systemui.navigationbar.NavigationBarView; import com.android.systemui.navigationbar.NavigationModeController; -import com.android.systemui.onehanded.OneHanded; -import com.android.systemui.onehanded.OneHandedEvents; import com.android.systemui.pip.Pip; import com.android.systemui.pip.PipAnimationController; import com.android.systemui.recents.OverviewProxyService.OverviewProxyListener; @@ -93,6 +91,8 @@ import com.android.systemui.statusbar.NotificationShadeWindowController; import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.phone.StatusBarWindowCallback; import com.android.systemui.statusbar.policy.CallbackController; +import com.android.wm.shell.onehanded.OneHanded; +import com.android.wm.shell.onehanded.OneHandedEvents; import com.android.wm.shell.splitscreen.SplitScreen; import java.io.FileDescriptor; diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java index 7dd4edd233bd..2b4fa2a23a07 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java @@ -574,7 +574,8 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset private void saveScreenshot(Bitmap screenshot, Consumer<Uri> finisher, Rect screenRect, Insets screenInsets, boolean showFlash) { if (mScreenshotLayout.isAttachedToWindow()) { - if (!mDismissAnimation.isRunning()) { // if we didn't already dismiss for another reason + // if we didn't already dismiss for another reason + if (mDismissAnimation == null || !mDismissAnimation.isRunning()) { mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_REENTERED); } dismissScreenshot("new screenshot requested", true); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java index 8f3033edecbb..7bac007ae478 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java @@ -188,7 +188,7 @@ public class NotificationShelf extends ActivatableNotificationView implements viewState.openedAmount = openedAmount; viewState.clipTopAmount = 0; viewState.alpha = 1; - viewState.belowSpeedBump = mAmbientState.getSpeedBumpIndex() == 0; + viewState.belowSpeedBump = mHostLayoutController.getSpeedBumpIndex() == 0; viewState.hideSensitive = false; viewState.xTranslation = getTranslationX(); if (mNotGoneIndex != -1) { @@ -352,7 +352,7 @@ public class NotificationShelf extends ActivatableNotificationView implements } setBackgroundTop(backgroundTop); setFirstElementRoundness(firstElementRoundness); - mShelfIcons.setSpeedBumpIndex(mAmbientState.getSpeedBumpIndex()); + mShelfIcons.setSpeedBumpIndex(mHostLayoutController.getSpeedBumpIndex()); mShelfIcons.calculateIconTranslations(); mShelfIcons.applyIconStates(); for (int i = 0; i < mHostLayoutController.getChildCount(); i++) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java index 6f7b32b3ac74..363a08566fd3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java @@ -26,6 +26,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManager; import android.app.ActivityTaskManager; +import android.app.ActivityTaskManager.RootTaskInfo; import android.app.AppGlobals; import android.app.Notification; import android.app.NotificationManager; @@ -161,16 +162,16 @@ public class InstantAppNotifier extends SystemUI () -> { ArraySet<Pair<String, Integer>> notifs = new ArraySet<>(mCurrentNotifs); try { - final ActivityManager.StackInfo focusedStack = - ActivityTaskManager.getService().getFocusedStackInfo(); - if (focusedStack != null) { + final RootTaskInfo focusedTask = + ActivityTaskManager.getService().getFocusedRootTaskInfo(); + if (focusedTask != null) { final int windowingMode = - focusedStack.configuration.windowConfiguration + focusedTask.configuration.windowConfiguration .getWindowingMode(); if (windowingMode == WINDOWING_MODE_FULLSCREEN || windowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY || windowingMode == WINDOWING_MODE_FREEFORM) { - checkAndPostForStack(focusedStack, notifs, noMan, pm); + checkAndPostForStack(focusedTask, notifs, noMan, pm); } } if (mDockedStackExists) { @@ -205,10 +206,8 @@ public class InstantAppNotifier extends SystemUI @NonNull NotificationManager noMan, @NonNull IPackageManager pm) { try { - final ActivityManager.StackInfo info = - ActivityTaskManager.getService() - .getStackInfo( - WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_UNDEFINED); + final RootTaskInfo info = ActivityTaskManager.getService().getRootTaskInfo( + WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_UNDEFINED); checkAndPostForStack(info, notifs, noMan, pm); } catch (RemoteException e) { e.rethrowFromSystemServer(); @@ -221,7 +220,7 @@ public class InstantAppNotifier extends SystemUI * exists, this method removes it from {@code notifs} in the arguments. */ private void checkAndPostForStack( - @Nullable ActivityManager.StackInfo info, + @Nullable RootTaskInfo info, @NonNull ArraySet<Pair<String, Integer>> notifs, @NonNull NotificationManager noMan, @NonNull IPackageManager pm) { @@ -241,7 +240,7 @@ public class InstantAppNotifier extends SystemUI info.userId, appInfo, noMan, - info.taskIds[info.taskIds.length - 1]); + info.childTaskIds[info.childTaskIds.length - 1]); } } } catch (RemoteException e) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java index 90492b5d606d..fdfd72489e93 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java @@ -18,6 +18,7 @@ package com.android.systemui.statusbar.notification.collection; import static android.service.notification.NotificationListenerService.REASON_APP_CANCEL; import static android.service.notification.NotificationListenerService.REASON_APP_CANCEL_ALL; +import static android.service.notification.NotificationListenerService.REASON_CANCEL; import static android.service.notification.NotificationListenerService.REASON_CANCEL_ALL; import static android.service.notification.NotificationListenerService.REASON_CHANNEL_BANNED; import static android.service.notification.NotificationListenerService.REASON_CLICK; @@ -459,8 +460,7 @@ public class NotifCollection implements Dumpable { + ": has not been marked for removal")); } - if (isDismissedByUser(entry)) { - // User-dismissed notifications cannot be lifetime-extended + if (cannotBeLifetimeExtended(entry)) { cancelLifetimeExtension(entry); } else { updateLifetimeExtension(entry); @@ -583,7 +583,7 @@ public class NotifCollection implements Dumpable { } private void cancelLocalDismissal(NotificationEntry entry) { - if (isDismissedByUser(entry)) { + if (entry.getDismissState() != NOT_DISMISSED) { entry.setDismissState(NOT_DISMISSED); if (entry.getSbn().getNotification().isGroupSummary()) { for (NotificationEntry otherEntry : mNotificationSet.values()) { @@ -669,12 +669,16 @@ public class NotifCollection implements Dumpable { * immediately removed from the collection, but can sometimes stick around due to lifetime * extenders. */ - private static boolean isCanceled(NotificationEntry entry) { + private boolean isCanceled(NotificationEntry entry) { return entry.mCancellationReason != REASON_NOT_CANCELED; } - private static boolean isDismissedByUser(NotificationEntry entry) { - return entry.getDismissState() != NOT_DISMISSED; + private boolean cannotBeLifetimeExtended(NotificationEntry entry) { + final boolean locallyDismissedByUser = entry.getDismissState() != NOT_DISMISSED; + final boolean systemServerReportedUserCancel = + entry.mCancellationReason == REASON_CLICK + || entry.mCancellationReason == REASON_CANCEL; + return locallyDismissedByUser || systemServerReportedUserCancel; } /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java index 2b545c56c8bf..df63fec62e4e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java @@ -673,7 +673,6 @@ public class ShadeListBuilder implements Dumpable { GroupEntry parent = (GroupEntry) entry; for (NotificationEntry child : parent.getChildren()) { child.getAttachState().setSection(section); - child.getAttachState().setSection(section); } parent.sortChildren(sChildComparator); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ConversationCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ConversationCoordinator.kt index 3aaa9acdb897..f0eb084ea8ef 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ConversationCoordinator.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ConversationCoordinator.kt @@ -22,6 +22,8 @@ import com.android.systemui.statusbar.notification.collection.NotifPipeline import com.android.systemui.statusbar.notification.collection.NotificationEntry import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner +import com.android.systemui.statusbar.notification.collection.render.NodeController +import com.android.systemui.statusbar.notification.dagger.PeopleHeader import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_NON_PERSON import javax.inject.Inject @@ -33,7 +35,8 @@ import javax.inject.Inject */ @SysUISingleton class ConversationCoordinator @Inject constructor( - private val peopleNotificationIdentifier: PeopleNotificationIdentifier + private val peopleNotificationIdentifier: PeopleNotificationIdentifier, + @PeopleHeader peopleHeaderController: NodeController ) : Coordinator { private val notificationPromoter = object : NotifPromoter(TAG) { @@ -43,9 +46,9 @@ class ConversationCoordinator @Inject constructor( } val sectioner = object : NotifSectioner("People") { - override fun isInSection(entry: ListEntry): Boolean { - return isConversation(entry.representativeEntry!!) - } + override fun isInSection(entry: ListEntry): Boolean = + isConversation(entry.representativeEntry!!) + override fun getHeaderNodeController() = peopleHeaderController } override fun attach(pipeline: NotifPipeline) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.java index 24e912ed0cc3..be1383fb6b8a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.java @@ -30,6 +30,8 @@ import com.android.systemui.statusbar.notification.collection.listbuilder.plugga import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner; import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener; import com.android.systemui.statusbar.notification.collection.notifcollection.NotifLifetimeExtender; +import com.android.systemui.statusbar.notification.collection.render.NodeController; +import com.android.systemui.statusbar.notification.dagger.IncomingHeader; import com.android.systemui.statusbar.notification.interruption.HeadsUpViewBinder; import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider; import com.android.systemui.statusbar.policy.HeadsUpManager; @@ -61,6 +63,7 @@ public class HeadsUpCoordinator implements Coordinator { private final HeadsUpViewBinder mHeadsUpViewBinder; private final NotificationInterruptStateProvider mNotificationInterruptStateProvider; private final NotificationRemoteInputManager mRemoteInputManager; + private final NodeController mIncomingHeaderController; // tracks the current HeadUpNotification reported by HeadsUpManager private @Nullable NotificationEntry mCurrentHun; @@ -73,11 +76,13 @@ public class HeadsUpCoordinator implements Coordinator { HeadsUpManager headsUpManager, HeadsUpViewBinder headsUpViewBinder, NotificationInterruptStateProvider notificationInterruptStateProvider, - NotificationRemoteInputManager remoteInputManager) { + NotificationRemoteInputManager remoteInputManager, + @IncomingHeader NodeController incomingHeaderController) { mHeadsUpManager = headsUpManager; mHeadsUpViewBinder = headsUpViewBinder; mNotificationInterruptStateProvider = notificationInterruptStateProvider; mRemoteInputManager = remoteInputManager; + mIncomingHeaderController = incomingHeaderController; } @Override @@ -196,6 +201,12 @@ public class HeadsUpCoordinator implements Coordinator { public boolean isInSection(ListEntry entry) { return isCurrentlyShowingHun(entry); } + + @Nullable + @Override + public NodeController getHeaderNodeController() { + return mIncomingHeaderController; + } }; private final OnHeadsUpChangedListener mOnHeadsUpChangedListener = diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinator.java index 0f08e0ff491c..133ddfebe84f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinator.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinator.java @@ -16,6 +16,8 @@ package com.android.systemui.statusbar.notification.collection.coordinator; +import android.annotation.Nullable; + import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.notification.collection.ListEntry; @@ -24,6 +26,9 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter; import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner; import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider; +import com.android.systemui.statusbar.notification.collection.render.NodeController; +import com.android.systemui.statusbar.notification.dagger.AlertingHeader; +import com.android.systemui.statusbar.notification.dagger.SilentHeader; import javax.inject.Inject; @@ -40,13 +45,19 @@ public class RankingCoordinator implements Coordinator { private final StatusBarStateController mStatusBarStateController; private final HighPriorityProvider mHighPriorityProvider; + private final NodeController mSilentHeaderController; + private final NodeController mAlertingHeaderController; @Inject public RankingCoordinator( StatusBarStateController statusBarStateController, - HighPriorityProvider highPriorityProvider) { + HighPriorityProvider highPriorityProvider, + @AlertingHeader NodeController alertingHeaderController, + @SilentHeader NodeController silentHeaderController) { mStatusBarStateController = statusBarStateController; mHighPriorityProvider = highPriorityProvider; + mAlertingHeaderController = alertingHeaderController; + mSilentHeaderController = silentHeaderController; } @Override @@ -70,6 +81,12 @@ public class RankingCoordinator implements Coordinator { public boolean isInSection(ListEntry entry) { return mHighPriorityProvider.isHighPriority(entry); } + + @Nullable + @Override + public NodeController getHeaderNodeController() { + return mAlertingHeaderController; + } }; private final NotifSectioner mSilentNotifSectioner = new NotifSectioner("Silent") { @@ -77,6 +94,12 @@ public class RankingCoordinator implements Coordinator { public boolean isInSection(ListEntry entry) { return !mHighPriorityProvider.isHighPriority(entry); } + + @Nullable + @Override + public NodeController getHeaderNodeController() { + return mSilentHeaderController; + } }; /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/OnUserInteractionCallbackImplLegacy.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/OnUserInteractionCallbackImplLegacy.java index cce8cdc64d30..610cd33383e9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/OnUserInteractionCallbackImplLegacy.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/OnUserInteractionCallbackImplLegacy.java @@ -26,6 +26,7 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.notifcollection.DismissedByUserStats; +import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager; import com.android.systemui.statusbar.notification.logging.NotificationLogger; import com.android.systemui.statusbar.notification.row.OnUserInteractionCallback; import com.android.systemui.statusbar.policy.HeadsUpManager; @@ -38,17 +39,20 @@ public class OnUserInteractionCallbackImplLegacy implements OnUserInteractionCal private final HeadsUpManager mHeadsUpManager; private final StatusBarStateController mStatusBarStateController; private final VisualStabilityManager mVisualStabilityManager; + private final GroupMembershipManager mGroupMembershipManager; public OnUserInteractionCallbackImplLegacy( NotificationEntryManager notificationEntryManager, HeadsUpManager headsUpManager, StatusBarStateController statusBarStateController, - VisualStabilityManager visualStabilityManager + VisualStabilityManager visualStabilityManager, + GroupMembershipManager groupMembershipManager ) { mNotificationEntryManager = notificationEntryManager; mHeadsUpManager = headsUpManager; mStatusBarStateController = statusBarStateController; mVisualStabilityManager = visualStabilityManager; + mGroupMembershipManager = groupMembershipManager; } /** @@ -69,6 +73,13 @@ public class OnUserInteractionCallbackImplLegacy implements OnUserInteractionCal dismissalSurface = NotificationStats.DISMISSAL_AOD; } + if (mGroupMembershipManager.isOnlyChildInGroup(entry)) { + NotificationEntry groupSummary = mGroupMembershipManager.getLogicalGroupSummary(entry); + if (groupSummary.isClearable()) { + onDismiss(groupSummary, cancellationReason); + } + } + mNotificationEntryManager.performRemoveNotification( entry.getSbn(), new DismissedByUserStats( @@ -82,6 +93,7 @@ public class OnUserInteractionCallbackImplLegacy implements OnUserInteractionCal NotificationLogger.getNotificationLocation(entry))), cancellationReason ); + } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/NotifSection.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/NotifSection.kt index c09122ea3c26..c9fc9929f0d3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/NotifSection.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/NotifSection.kt @@ -17,6 +17,7 @@ package com.android.systemui.statusbar.notification.collection.listbuilder import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner +import com.android.systemui.statusbar.notification.collection.render.NodeController data class NotifSection( val sectioner: NotifSectioner, @@ -24,4 +25,7 @@ data class NotifSection( ) { val label: String get() = "Section($index, \"${sectioner.name}\")" + + val headerController: NodeController? + get() = sectioner.headerNodeController } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/pluggable/NotifSectioner.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/pluggable/NotifSectioner.java index b57f504189f1..c8982d35c4a0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/pluggable/NotifSectioner.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/pluggable/NotifSectioner.java @@ -16,8 +16,12 @@ package com.android.systemui.statusbar.notification.collection.listbuilder.pluggable; +import android.annotation.Nullable; + import com.android.systemui.statusbar.notification.collection.ListEntry; import com.android.systemui.statusbar.notification.collection.ShadeListBuilder; +import com.android.systemui.statusbar.notification.collection.render.NodeController; +import com.android.systemui.statusbar.notification.collection.render.NodeSpec; /** * Pluggable for participating in notif sectioning. See {@link ShadeListBuilder#setSections}. @@ -34,4 +38,12 @@ public abstract class NotifSectioner extends Pluggable<NotifSectioner> { * notification. The first section to return true determines the section of the notification. */ public abstract boolean isInSection(ListEntry entry); + + /** + * Returns an optional {@link NodeSpec} for the section header. If {@code null}, no header will + * be used for the section. + */ + public @Nullable NodeController getHeaderNodeController() { + return null; + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NodeController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NodeController.kt index 67f7b1c09df3..727ce20cd72c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NodeController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NodeController.kt @@ -39,9 +39,7 @@ interface NodeController { throw RuntimeException("Not supported") } - fun getChildCount(): Int { - throw RuntimeException("Not supported") - } + fun getChildCount(): Int = 0 fun addChildAt(child: NodeController, index: Int) { throw RuntimeException("Not supported") diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/SectionHeaderController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/SectionHeaderController.kt new file mode 100644 index 000000000000..498b8e884b17 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/SectionHeaderController.kt @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2020 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.systemui.statusbar.notification.collection.render + +import android.annotation.StringRes +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.android.systemui.R +import com.android.systemui.statusbar.notification.dagger.HeaderClick +import com.android.systemui.statusbar.notification.dagger.HeaderText +import com.android.systemui.statusbar.notification.dagger.NodeLabel +import com.android.systemui.statusbar.notification.dagger.SectionHeaderScope +import com.android.systemui.statusbar.notification.stack.SectionHeaderView +import javax.inject.Inject + +interface SectionHeaderController { + fun reinflateView(parent: ViewGroup) + val headerView: SectionHeaderView? + fun setOnClearAllClickListener(listener: View.OnClickListener) +} + +@SectionHeaderScope +internal class SectionHeaderNodeControllerImpl @Inject constructor( + @NodeLabel override val nodeLabel: String, + private val layoutInflater: LayoutInflater, + @HeaderText @StringRes private val headerTextResId: Int, + @HeaderClick private val onHeaderClickListener: View.OnClickListener +) : NodeController, SectionHeaderController { + + private var _view: SectionHeaderView? = null + private var clearAllClickListener: View.OnClickListener? = null + + override fun reinflateView(parent: ViewGroup) { + var oldPos = -1 + _view?.let { _view -> + _view.transientContainer?.removeView(_view) + if (_view.parent === parent) { + oldPos = parent.indexOfChild(_view) + parent.removeView(_view) + } + } + val inflated = layoutInflater.inflate( + R.layout.status_bar_notification_section_header, + parent, + false /* attachToRoot */) + as SectionHeaderView + inflated.setHeaderText(headerTextResId) + inflated.setOnHeaderClickListener(onHeaderClickListener) + clearAllClickListener?.let { inflated.setOnClearAllClickListener(it) } + if (oldPos != -1) { + parent.addView(inflated, oldPos) + } + _view = inflated + } + + override val headerView: SectionHeaderView? + get() = _view + + override fun setOnClearAllClickListener(listener: View.OnClickListener) { + clearAllClickListener = listener + _view?.setOnClearAllClickListener(listener) + } + + override val view: View + get() = _view!! +}
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDiffer.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDiffer.kt index 019520f18982..22ca4961320c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDiffer.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDiffer.kt @@ -65,9 +65,7 @@ class ShadeViewDiffer( * * For debugging purposes. */ - fun getViewLabel(view: View): String { - return views[view]?.label ?: view.toString() - } + fun getViewLabel(view: View): String = views[view]?.label ?: view.toString() private fun detachChildren( parentNode: ShadeNode, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewManager.kt index 5243854ea412..44a5c958c408 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewManager.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewManager.kt @@ -42,45 +42,35 @@ class ShadeViewManager constructor( private val rootController = RootNodeController(listContainer, View(context)) private val viewDiffer = ShadeViewDiffer(rootController, logger) - fun attach(listBuilder: ShadeListBuilder) { - listBuilder.setOnRenderListListener(::onNewNotifTree) - } + fun attach(listBuilder: ShadeListBuilder) = + listBuilder.setOnRenderListListener(::onNewNotifTree) - private fun onNewNotifTree(tree: List<ListEntry>) { - viewDiffer.applySpec(buildTree(tree)) - } + private fun onNewNotifTree(tree: List<ListEntry>) = viewDiffer.applySpec(buildTree(tree)) private fun buildTree(notifList: List<ListEntry>): NodeSpec { - val root = NodeSpecImpl(null, rootController) - - for (entry in notifList) { - // TODO: Add section header logic here - root.children.add(buildNotifNode(entry, root)) + val root = NodeSpecImpl(null, rootController).apply { + // Insert first section header, if present + notifList.firstOrNull()?.section?.headerController?.let { + children.add(NodeSpecImpl(this, it)) + } + notifList.asSequence().zipWithNext().forEach { (prev, entry) -> + // Insert new header if the section has changed between two entries + entry.section.takeIf { it != prev.section }?.headerController?.let { + children.add(NodeSpecImpl(this, it)) + } + children.add(buildNotifNode(entry, this)) + } } - notificationIconAreaController.updateNotificationIcons(notifList) return root } private fun buildNotifNode(entry: ListEntry, parent: NodeSpec): NodeSpec { return when (entry) { - is NotificationEntry -> { - NodeSpecImpl(parent, viewBarn.requireView(entry)) - } - is GroupEntry -> { - val groupNode = NodeSpecImpl( - parent, - viewBarn.requireView(checkNotNull(entry.summary))) - - for (childEntry in entry.children) { - groupNode.children.add(buildNotifNode(childEntry, groupNode)) - } - - groupNode - } - else -> { - throw RuntimeException("Unexpected entry: $entry") - } + is NotificationEntry -> NodeSpecImpl(parent, viewBarn.requireView(entry)) + is GroupEntry -> NodeSpecImpl(parent, viewBarn.requireView(checkNotNull(entry.summary))) + .apply { entry.children.forEach { children.add(buildNotifNode(it, this)) } } + else -> throw RuntimeException("Unexpected entry: $entry") } } } @@ -91,12 +81,11 @@ class ShadeViewManagerFactory @Inject constructor( private val viewBarn: NotifViewBarn, private val notificationIconAreaController: NotificationIconAreaController ) { - fun create(listContainer: NotificationListContainer): ShadeViewManager { - return ShadeViewManager( - context, - listContainer, - logger, - viewBarn, - notificationIconAreaController) - } + fun create(listContainer: NotificationListContainer) = + ShadeViewManager( + context, + listContainer, + logger, + viewBarn, + notificationIconAreaController) } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationSectionHeadersModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationSectionHeadersModule.kt new file mode 100644 index 000000000000..179d49cb55a1 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationSectionHeadersModule.kt @@ -0,0 +1,195 @@ +/* + * Copyright (C) 2020 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.systemui.statusbar.notification.dagger + +import android.annotation.StringRes +import android.content.Intent +import android.provider.Settings +import android.view.View +import com.android.systemui.R +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.plugins.ActivityStarter +import com.android.systemui.statusbar.notification.collection.render.NodeController +import com.android.systemui.statusbar.notification.collection.render.SectionHeaderController +import com.android.systemui.statusbar.notification.collection.render.SectionHeaderNodeControllerImpl +import dagger.Binds +import dagger.BindsInstance +import dagger.Module +import dagger.Provides +import dagger.Subcomponent +import javax.inject.Provider +import javax.inject.Qualifier +import javax.inject.Scope + +@Module(subcomponents = [SectionHeaderControllerSubcomponent::class]) +object NotificationSectionHeadersModule { + + @Provides + @HeaderClick + @JvmStatic fun providesOnHeaderClickListener( + activityStarter: ActivityStarter + ) = View.OnClickListener { + activityStarter.startActivity( + Intent(Settings.ACTION_NOTIFICATION_SETTINGS), + true /* onlyProvisioned */, + true /* dismissShade */, + Intent.FLAG_ACTIVITY_SINGLE_TOP) + } + + @Provides + @IncomingHeader + @SysUISingleton + @JvmStatic fun providesIncomingHeaderSubcomponent( + builder: Provider<SectionHeaderControllerSubcomponent.Builder> + ) = builder.get() + .nodeLabel("incoming header") + .headerText(R.string.notification_section_header_incoming) + .build() + + @Provides + @AlertingHeader + @SysUISingleton + @JvmStatic fun providesAlertingHeaderSubcomponent( + builder: Provider<SectionHeaderControllerSubcomponent.Builder> + ) = builder.get() + .nodeLabel("alerting header") + .headerText(R.string.notification_section_header_alerting) + .build() + + @Provides + @PeopleHeader + @SysUISingleton + @JvmStatic fun providesPeopleHeaderSubcomponent( + builder: Provider<SectionHeaderControllerSubcomponent.Builder> + ) = builder.get() + .nodeLabel("people header") + .headerText(R.string.notification_section_header_conversations) + .build() + + @Provides + @SilentHeader + @SysUISingleton + @JvmStatic fun providesSilentHeaderSubcomponent( + builder: Provider<SectionHeaderControllerSubcomponent.Builder> + ) = builder.get() + .nodeLabel("silent header") + .headerText(R.string.notification_section_header_gentle) + .build() + + @Provides + @SilentHeader + @JvmStatic fun providesSilentHeaderNodeController( + @SilentHeader subcomponent: SectionHeaderControllerSubcomponent + ) = subcomponent.nodeController + + @Provides + @SilentHeader + @JvmStatic fun providesSilentHeaderController( + @SilentHeader subcomponent: SectionHeaderControllerSubcomponent + ) = subcomponent.headerController + + @Provides + @AlertingHeader + @JvmStatic fun providesAlertingHeaderNodeController( + @AlertingHeader subcomponent: SectionHeaderControllerSubcomponent + ) = subcomponent.nodeController + + @Provides + @AlertingHeader + @JvmStatic fun providesAlertingHeaderController( + @AlertingHeader subcomponent: SectionHeaderControllerSubcomponent + ) = subcomponent.headerController + + @Provides + @PeopleHeader + @JvmStatic fun providesPeopleHeaderNodeController( + @PeopleHeader subcomponent: SectionHeaderControllerSubcomponent + ) = subcomponent.nodeController + + @Provides + @PeopleHeader + @JvmStatic fun providesPeopleHeaderController( + @PeopleHeader subcomponent: SectionHeaderControllerSubcomponent + ) = subcomponent.headerController + + @Provides + @IncomingHeader + @JvmStatic fun providesIncomingHeaderNodeController( + @IncomingHeader subcomponent: SectionHeaderControllerSubcomponent + ) = subcomponent.nodeController + + @Provides + @IncomingHeader + @JvmStatic fun providesIncomingHeaderController( + @IncomingHeader subcomponent: SectionHeaderControllerSubcomponent + ) = subcomponent.headerController +} + +@Subcomponent(modules = [ SectionHeaderBindingModule::class ]) +@SectionHeaderScope +interface SectionHeaderControllerSubcomponent { + + val nodeController: NodeController + val headerController: SectionHeaderController + + @Subcomponent.Builder + interface Builder { + fun build(): SectionHeaderControllerSubcomponent + @BindsInstance fun nodeLabel(@NodeLabel nodeLabel: String): Builder + @BindsInstance fun headerText(@HeaderText @StringRes headerText: Int): Builder + } +} + +@Module +private abstract class SectionHeaderBindingModule { + @Binds abstract fun bindsNodeController(impl: SectionHeaderNodeControllerImpl): NodeController + @Binds abstract fun bindsSectionHeaderController( + impl: SectionHeaderNodeControllerImpl + ): SectionHeaderController +} + +@Qualifier +@Retention(AnnotationRetention.BINARY) +annotation class HeaderText + +@Qualifier +@Retention(AnnotationRetention.BINARY) +annotation class IncomingHeader + +@Qualifier +@Retention(AnnotationRetention.BINARY) +annotation class AlertingHeader + +@Qualifier +@Retention(AnnotationRetention.BINARY) +annotation class SilentHeader + +@Qualifier +@Retention(AnnotationRetention.BINARY) +annotation class PeopleHeader + +@Qualifier +@Retention(AnnotationRetention.BINARY) +annotation class NodeLabel + +@Qualifier +@Retention(AnnotationRetention.BINARY) +annotation class HeaderClick + +@Scope +@Retention(AnnotationRetention.BINARY) +annotation class SectionHeaderScope
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java index e2aae64ce220..23270630c7da 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java @@ -88,7 +88,7 @@ import dagger.Provides; /** * Dagger Module for classes found within the com.android.systemui.statusbar.notification package. */ -@Module +@Module(includes = { NotificationSectionHeadersModule.class }) public interface NotificationsModule { /** Provides an instance of {@link NotificationEntryManager} */ @SysUISingleton @@ -205,9 +205,11 @@ public interface NotificationsModule { Context context, NotificationGutsManager notificationGutsManager, NotificationEntryManager notificationEntryManager, - MetricsLogger metricsLogger) { + MetricsLogger metricsLogger, + GroupMembershipManager groupMembershipManager) { return new NotificationBlockingHelperManager( - context, notificationGutsManager, notificationEntryManager, metricsLogger); + context, notificationGutsManager, notificationEntryManager, metricsLogger, + groupMembershipManager); } /** Provides an instance of {@link GroupMembershipManager} */ @@ -273,7 +275,8 @@ public interface NotificationsModule { Lazy<NotifCollection> notifCollection, Lazy<VisualStabilityCoordinator> visualStabilityCoordinator, NotificationEntryManager entryManager, - VisualStabilityManager visualStabilityManager) { + VisualStabilityManager visualStabilityManager, + Lazy<GroupMembershipManager> groupMembershipManagerLazy) { return featureFlags.isNewNotifPipelineRenderingEnabled() ? new OnUserInteractionCallbackImpl( pipeline.get(), @@ -285,7 +288,8 @@ public interface NotificationsModule { entryManager, headsUpManager, statusBarStateController, - visualStabilityManager); + visualStabilityManager, + groupMembershipManagerLazy.get()); } /** */ diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java index 89f720535402..adda049951ac 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java @@ -817,13 +817,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView return mNotificationParent != null; } - /** - * @return whether this notification is the only child in the group summary - */ - public boolean isOnlyChildInGroup() { - return mGroupMembershipManager.isOnlyChildInGroup(mEntry); - } - public ExpandableNotificationRow getNotificationParent() { return mNotificationParent; } @@ -1425,14 +1418,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView } public void performDismiss(boolean fromAccessibility) { - if (isOnlyChildInGroup()) { - NotificationEntry groupSummary = mGroupMembershipManager.getLogicalGroupSummary(mEntry); - if (groupSummary.isClearable()) { - // If this is the only child in the group, dismiss the group, but don't try to show - // the blocking helper affordance! - groupSummary.getRow().performDismiss(fromAccessibility); - } - } dismiss(fromAccessibility); if (mEntry.isClearable()) { if (mOnUserInteractionCallback != null) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBlockingHelperManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBlockingHelperManager.java index 921232568755..ab78d197da0b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBlockingHelperManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBlockingHelperManager.java @@ -28,6 +28,8 @@ import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin; import com.android.systemui.statusbar.notification.NotificationEntryManager; +import com.android.systemui.statusbar.notification.collection.NotificationEntry; +import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager; import com.android.systemui.statusbar.notification.dagger.NotificationsModule; import com.android.systemui.statusbar.notification.logging.NotificationCounters; @@ -48,6 +50,7 @@ public class NotificationBlockingHelperManager { private final NotificationGutsManager mNotificationGutsManager; private final NotificationEntryManager mNotificationEntryManager; private final MetricsLogger mMetricsLogger; + private final GroupMembershipManager mGroupMembershipManager; /** Row that the blocking helper will be shown in (via {@link NotificationGuts}. */ private ExpandableNotificationRow mBlockingHelperRow; private Set<String> mNonBlockablePkgs; @@ -65,7 +68,8 @@ public class NotificationBlockingHelperManager { Context context, NotificationGutsManager notificationGutsManager, NotificationEntryManager notificationEntryManager, - MetricsLogger metricsLogger) { + MetricsLogger metricsLogger, + GroupMembershipManager groupMembershipManager) { mContext = context; mNotificationGutsManager = notificationGutsManager; mNotificationEntryManager = notificationEntryManager; @@ -73,6 +77,7 @@ public class NotificationBlockingHelperManager { mNonBlockablePkgs = new HashSet<>(); Collections.addAll(mNonBlockablePkgs, mContext.getResources().getStringArray( com.android.internal.R.array.config_nonBlockableNotificationPackages)); + mGroupMembershipManager = groupMembershipManager; } /** @@ -92,11 +97,12 @@ public class NotificationBlockingHelperManager { // - The row is blockable (i.e. not non-blockable) // - The dismissed row is a valid group (>1 or 0 children from the same channel) // or the only child in the group - if ((row.getEntry().getUserSentiment() == USER_SENTIMENT_NEGATIVE || DEBUG) + final NotificationEntry entry = row.getEntry(); + if ((entry.getUserSentiment() == USER_SENTIMENT_NEGATIVE || DEBUG) && mIsShadeExpanded && !row.getIsNonblockable() - && ((!row.isChildInGroup() || row.isOnlyChildInGroup()) - && row.getNumUniqueChannels() <= 1)) { + && ((!row.isChildInGroup() || mGroupMembershipManager.isOnlyChildInGroup(entry)) + && row.getNumUniqueChannels() <= 1)) { // Dismiss any current blocking helper before continuing forward (only one can be shown // at a given time). dismissCurrentBlockingHelper(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java index 0302b2b450e2..8050fea562a7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java @@ -30,7 +30,6 @@ import com.android.systemui.statusbar.notification.row.ActivatableNotificationVi import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.row.ExpandableView; import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm.SectionProvider; -import com.android.systemui.statusbar.policy.HeadsUpManager; import java.util.ArrayList; @@ -50,7 +49,6 @@ public class AmbientState { private ActivatableNotificationView mActivatedChild; private float mOverScrollTopAmount; private float mOverScrollBottomAmount; - private int mSpeedBumpIndex = -1; private boolean mDozing; private boolean mHideSensitive; private float mStackTranslation; @@ -245,14 +243,6 @@ public class AmbientState { return top ? mOverScrollTopAmount : mOverScrollBottomAmount; } - public int getSpeedBumpIndex() { - return mSpeedBumpIndex; - } - - public void setSpeedBumpIndex(int shelfIndex) { - mSpeedBumpIndex = shelfIndex; - } - public SectionProvider getSectionProvider() { return mSectionProvider; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt index ff7793d506fd..4f7e14ba4a4c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt @@ -18,23 +18,21 @@ package com.android.systemui.statusbar.notification.stack import android.annotation.ColorInt import android.annotation.IntDef import android.annotation.LayoutRes -import android.content.Intent -import android.provider.Settings import android.util.Log import android.view.LayoutInflater import android.view.View import com.android.internal.annotations.VisibleForTesting import com.android.systemui.R import com.android.systemui.media.KeyguardMediaController -import com.android.systemui.plugins.ActivityStarter import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.statusbar.StatusBarState import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager -import com.android.systemui.statusbar.notification.people.DataListener -import com.android.systemui.statusbar.notification.people.PeopleHubViewAdapter -import com.android.systemui.statusbar.notification.people.PeopleHubViewBoundary -import com.android.systemui.statusbar.notification.people.PersonViewModel -import com.android.systemui.statusbar.notification.people.Subscription +import com.android.systemui.statusbar.notification.collection.render.SectionHeaderController +import com.android.systemui.statusbar.notification.collection.render.ShadeViewManager +import com.android.systemui.statusbar.notification.dagger.AlertingHeader +import com.android.systemui.statusbar.notification.dagger.IncomingHeader +import com.android.systemui.statusbar.notification.dagger.PeopleHeader +import com.android.systemui.statusbar.notification.dagger.SilentHeader import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow import com.android.systemui.statusbar.notification.row.ExpandableView import com.android.systemui.statusbar.notification.row.StackScrollerDecorView @@ -46,19 +44,25 @@ import com.android.systemui.util.takeUntil import javax.inject.Inject /** - * Manages the boundaries of the two notification sections (high priority and low priority). Also - * shows/hides the headers for those sections where appropriate. + * Manages the boundaries of the notification sections (incoming, conversations, high priority, and + * low priority). + * + * In the legacy notification pipeline, this is responsible for correctly positioning all section + * headers after the [NotificationStackScrollLayout] has had notifications added/removed/changed. In + * the new pipeline, this is handled as part of the [ShadeViewManager]. * * TODO: Move remaining sections logic from NSSL into this class. */ class NotificationSectionsManager @Inject internal constructor( - private val activityStarter: ActivityStarter, private val statusBarStateController: StatusBarStateController, private val configurationController: ConfigurationController, - private val peopleHubViewAdapter: PeopleHubViewAdapter, private val keyguardMediaController: KeyguardMediaController, private val sectionsFeatureManager: NotificationSectionsFeatureManager, - private val logger: NotificationSectionsLogger + private val logger: NotificationSectionsLogger, + @IncomingHeader private val incomingHeaderController: SectionHeaderController, + @PeopleHeader private val peopleHeaderController: SectionHeaderController, + @AlertingHeader private val alertingHeaderController: SectionHeaderController, + @SilentHeader private val silentHeaderController: SectionHeaderController ) : SectionProvider { private val configurationListener = object : ConfigurationController.ConfigurationListener { @@ -67,46 +71,25 @@ class NotificationSectionsManager @Inject internal constructor( } } - private val peopleHubViewBoundary: PeopleHubViewBoundary = object : PeopleHubViewBoundary { - override fun setVisible(isVisible: Boolean) { - if (peopleHubVisible != isVisible) { - peopleHubVisible = isVisible - if (initialized) { - updateSectionBoundaries("PeopleHub visibility changed") - } - } - } - - override val associatedViewForClickAnimation: View - get() = peopleHeaderView!! - - override val personViewAdapters: Sequence<DataListener<PersonViewModel?>> - get() = peopleHeaderView!!.personViewAdapters - } - private lateinit var parent: NotificationStackScrollLayout private var initialized = false private var onClearSilentNotifsClickListener: View.OnClickListener? = null - @get:VisibleForTesting - var silentHeaderView: SectionHeaderView? = null - private set - - @get:VisibleForTesting - var alertingHeaderView: SectionHeaderView? = null - private set + @VisibleForTesting + val silentHeaderView: SectionHeaderView? + get() = silentHeaderController.headerView - @get:VisibleForTesting - var incomingHeaderView: SectionHeaderView? = null - private set + @VisibleForTesting + val alertingHeaderView: SectionHeaderView? + get() = alertingHeaderController.headerView - @get:VisibleForTesting - var peopleHeaderView: PeopleHubView? = null - private set + @VisibleForTesting + val incomingHeaderView: SectionHeaderView? + get() = incomingHeaderController.headerView - @set:VisibleForTesting - var peopleHubVisible = false - private var peopleHubSubscription: Subscription? = null + @VisibleForTesting + val peopleHeaderView: SectionHeaderView? + get() = peopleHeaderController.headerView @get:VisibleForTesting var mediaControlsView: MediaHeaderView? = null @@ -150,34 +133,10 @@ class NotificationSectionsManager @Inject internal constructor( * Reinflates the entire notification header, including all decoration views. */ fun reinflateViews(layoutInflater: LayoutInflater) { - silentHeaderView = reinflateView( - silentHeaderView, layoutInflater, R.layout.status_bar_notification_section_header - ).apply { - setHeaderText(R.string.notification_section_header_gentle) - setOnHeaderClickListener { onGentleHeaderClick() } - setOnClearAllClickListener { onClearGentleNotifsClick(it) } - } - alertingHeaderView = reinflateView( - alertingHeaderView, layoutInflater, R.layout.status_bar_notification_section_header - ).apply { - setHeaderText(R.string.notification_section_header_alerting) - setOnHeaderClickListener { onGentleHeaderClick() } - } - peopleHubSubscription?.unsubscribe() - peopleHubSubscription = null - peopleHeaderView = reinflateView(peopleHeaderView, layoutInflater, R.layout.people_strip) - .apply { - setOnHeaderClickListener(View.OnClickListener { onGentleHeaderClick() }) - } - if (ENABLE_SNOOZED_CONVERSATION_HUB) { - peopleHubSubscription = peopleHubViewAdapter.bindView(peopleHubViewBoundary) - } - incomingHeaderView = reinflateView( - incomingHeaderView, layoutInflater, R.layout.status_bar_notification_section_header - ).apply { - setHeaderText(R.string.notification_section_header_incoming) - setOnHeaderClickListener { onGentleHeaderClick() } - } + silentHeaderController.reinflateView(parent) + alertingHeaderController.reinflateView(parent) + peopleHeaderController.reinflateView(parent) + incomingHeaderController.reinflateView(parent) mediaControlsView = reinflateView(mediaControlsView, layoutInflater, R.layout.keyguard_media_header) .also(keyguardMediaController::attach) @@ -296,7 +255,6 @@ class NotificationSectionsManager @Inject internal constructor( // target, but won't be once they are moved / removed after the pass has completed. val showHeaders = statusBarStateController.state != StatusBarState.KEYGUARD - val usingPeopleFiltering = sectionsFeatureManager.isFilteringEnabled() val usingMediaControls = sectionsFeatureManager.isMediaControlsEnabled() val mediaState = mediaControlsView?.let(::expandableViewHeaderState) @@ -319,7 +277,6 @@ class NotificationSectionsManager @Inject internal constructor( ).filterNotNull() var peopleNotifsPresent = false - var lastNotifIndex = 0 var nextBucket: Int? = null var inIncomingSection = false @@ -373,30 +330,9 @@ class NotificationSectionsManager @Inject internal constructor( // Check if there are any people notifications peopleNotifsPresent = peopleNotifsPresent || row.entry.bucket == BUCKET_PEOPLE - - if (nextBucket == null) { - lastNotifIndex = i - } nextBucket = row.entry.bucket } - if (showHeaders && usingPeopleFiltering && peopleHubVisible) { - peopleState?.targetPosition = peopleState?.targetPosition - // Insert the people header even if there are no people visible, in order to - // show the hub. Put it directly above the next header. - ?: alertingState?.targetPosition - ?: gentleState?.targetPosition - // Put it at the end of the list. - ?: lastNotifIndex - - // Offset the target to account for the current position of the people header. - peopleState?.targetPosition = peopleState?.currentPosition?.let { current -> - peopleState.targetPosition?.let { target -> - if (current < target) target - 1 else target - } - } - } - mediaState?.targetPosition = if (usingMediaControls) 0 else null logger.logStr("New header target positions:") @@ -420,14 +356,6 @@ class NotificationSectionsManager @Inject internal constructor( .hasActiveClearableNotifications(NotificationStackScrollLayout.ROWS_GENTLE) setAreThereDismissableGentleNotifs(hasActiveClearableNotifications) } - peopleHeaderView?.run { - canSwipe = showHeaders && peopleHubVisible && !peopleNotifsPresent - peopleState?.targetPosition?.let { targetPosition -> - if (targetPosition != peopleState.currentPosition) { - resetTranslation() - } - } - } } private sealed class SectionBounds { @@ -513,31 +441,13 @@ class NotificationSectionsManager @Inject internal constructor( } } - private fun onGentleHeaderClick() { - val intent = Intent(Settings.ACTION_NOTIFICATION_SETTINGS) - activityStarter.startActivity( - intent, - true, - true, - Intent.FLAG_ACTIVITY_SINGLE_TOP) - } - - private fun onClearGentleNotifsClick(v: View) { - onClearSilentNotifsClickListener?.onClick(v) - } - /** Listener for when the "clear all" button is clicked on the gentle notification header. */ fun setOnClearSilentNotifsClickListener(listener: View.OnClickListener) { onClearSilentNotifsClickListener = listener } - fun hidePeopleRow() { - peopleHubVisible = false - updateSectionBoundaries("PeopleHub dismissed") - } - fun setHeaderForegroundColor(@ColorInt color: Int) { - peopleHeaderView?.setTextColor(color) + peopleHeaderView?.setForegroundColor(color) silentHeaderView?.setForegroundColor(color) alertingHeaderView?.setForegroundColor(color) } @@ -545,7 +455,6 @@ class NotificationSectionsManager @Inject internal constructor( companion object { private const val TAG = "NotifSectionsManager" private const val DEBUG = false - private const val ENABLE_SNOOZED_CONVERSATION_HUB = false } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java index c24d3fcadbf9..b33aa5739273 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java @@ -248,6 +248,9 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable private boolean mChangePositionInProgress; private boolean mChildTransferInProgress; + private int mSpeedBumpIndex = -1; + private boolean mSpeedBumpIndexDirty = true; + /** * The raw amount of the overScroll on the top, which is not rubber-banded. */ @@ -444,7 +447,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable private int mMaxDisplayedNotifications = -1; private int mStatusBarHeight; private int mMinInteractionHeight; - private boolean mNoAmbient; private final Rect mClipRect = new Rect(); private boolean mIsClipped; private Rect mRequestedClipBounds; @@ -1010,7 +1012,33 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable } public int getSpeedBumpIndex() { - return mAmbientState.getSpeedBumpIndex(); + if (mSpeedBumpIndexDirty) { + mSpeedBumpIndexDirty = false; + int speedBumpIndex = 0; + int currentIndex = 0; + final int n = getChildCount(); + for (int i = 0; i < n; i++) { + View view = getChildAt(i); + if (view.getVisibility() == View.GONE + || !(view instanceof ExpandableNotificationRow)) { + continue; + } + ExpandableNotificationRow row = (ExpandableNotificationRow) view; + currentIndex++; + boolean beforeSpeedBump; + if (mHighPriorityBeforeSpeedBump) { + beforeSpeedBump = row.getEntry().getBucket() < BUCKET_SILENT; + } else { + beforeSpeedBump = !row.getEntry().isAmbient(); + } + if (beforeSpeedBump) { + speedBumpIndex = currentIndex; + } + } + + mSpeedBumpIndex = speedBumpIndex; + } + return mSpeedBumpIndex; } @Override @@ -1066,12 +1094,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable } } - @ShadeViewRefactor(RefactorComponent.ADAPTER) - private void setSpeedBumpIndex(int newIndex, boolean noAmbient) { - mAmbientState.setSpeedBumpIndex(newIndex); - mNoAmbient = noAmbient; - } - @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER) public void setChildLocationsChangedListener( NotificationLogger.OnChildLocationsChangedListener listener) { @@ -1135,7 +1157,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable } else { mAmbientState.setScrollY(mOwnScrollY); } - mStackScrollAlgorithm.resetViewStates(mAmbientState); + mStackScrollAlgorithm.resetViewStates(mAmbientState, getSpeedBumpIndex()); if (!isCurrentlyAnimating() && !mNeedsAnimation) { applyCurrentState(); } else { @@ -5785,32 +5807,11 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable * @param open Should the fling open or close the overscroll view. */ void flingTopOverscroll(float velocity, boolean open); - } + } @ShadeViewRefactor(RefactorComponent.SHADE_VIEW) private void updateSpeedBumpIndex() { - int speedBumpIndex = 0; - int currentIndex = 0; - final int N = getChildCount(); - for (int i = 0; i < N; i++) { - View view = getChildAt(i); - if (view.getVisibility() == View.GONE || !(view instanceof ExpandableNotificationRow)) { - continue; - } - ExpandableNotificationRow row = (ExpandableNotificationRow) view; - currentIndex++; - boolean beforeSpeedBump; - if (mHighPriorityBeforeSpeedBump) { - beforeSpeedBump = row.getEntry().getBucket() < BUCKET_SILENT; - } else { - beforeSpeedBump = !row.getEntry().isAmbient(); - } - if (beforeSpeedBump) { - speedBumpIndex = currentIndex; - } - } - boolean noAmbient = speedBumpIndex == N; - setSpeedBumpIndex(speedBumpIndex, noAmbient); + mSpeedBumpIndexDirty = true; } /** Updates the indices of the boundaries between sections. */ diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java index 8d792ab6aa58..c10362d00a13 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java @@ -18,6 +18,8 @@ package com.android.systemui.statusbar.notification.stack; import static com.android.systemui.Dependency.ALLOW_NOTIFICATION_LONG_PRESS_NAME; import static com.android.systemui.statusbar.StatusBarState.KEYGUARD; +import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.ROWS_GENTLE; +import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.ROWS_HIGH_PRIORITY; import android.content.res.Resources; import android.graphics.Point; @@ -61,6 +63,8 @@ import com.android.systemui.statusbar.notification.collection.legacy.Notificatio import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy.NotificationGroup; import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy.OnGroupChangeListener; import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager; +import com.android.systemui.statusbar.notification.collection.render.SectionHeaderController; +import com.android.systemui.statusbar.notification.dagger.SilentHeader; import com.android.systemui.statusbar.notification.logging.NotificationLogger; import com.android.systemui.statusbar.notification.row.ActivatableNotificationView; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; @@ -117,6 +121,7 @@ public class NotificationStackScrollLayoutController { private final NotificationLockscreenUserManager mLockscreenUserManager; // TODO: StatusBar should be encapsulated behind a Controller private final StatusBar mStatusBar; + private final SectionHeaderController mSilentHeaderController; private NotificationStackScrollLayout mView; private boolean mFadeNotificationsOnDismiss; @@ -359,10 +364,6 @@ public class NotificationStackScrollLayoutController { row.performDismissWithBlockingHelper(false /* fromAccessibility */); } - if (view instanceof PeopleHubView) { - mNotificationSectionsManager.hidePeopleRow(); - } - if (!isBlockingHelperShown) { mView.addSwipedOutView(view); } @@ -523,7 +524,8 @@ public class NotificationStackScrollLayoutController { StatusBar statusBar, ScrimController scrimController, NotificationGroupManagerLegacy legacyGroupManager, - GroupExpansionManager groupManager) { + GroupExpansionManager groupManager, + @SilentHeader SectionHeaderController silentHeaderController) { mAllowLongPress = allowLongPress; mNotificationGutsManager = notificationGutsManager; mHeadsUpManager = headsUpManager; @@ -559,6 +561,7 @@ public class NotificationStackScrollLayoutController { mStatusBar.requestNotificationUpdate("onGroupsChanged"); } }); + mSilentHeaderController = silentHeaderController; } public void attach(NotificationStackScrollLayout view) { @@ -624,6 +627,7 @@ public class NotificationStackScrollLayoutController { mOnAttachStateChangeListener.onViewAttachedToWindow(mView); } mView.addOnAttachStateChangeListener(mOnAttachStateChangeListener); + mSilentHeaderController.setOnClearAllClickListener(v -> clearSilentNotifications()); } public void addOnExpandedHeightChangedListener(BiConsumer<Float, Float> listener) { @@ -713,6 +717,10 @@ public class NotificationStackScrollLayoutController { return mView.getWakeUpHeight(); } + public int getSpeedBumpIndex() { + return mView.getSpeedBumpIndex(); + } + public void setHideAmount(float linearAmount, float amount) { mView.setHideAmount(linearAmount, amount); } @@ -1134,6 +1142,12 @@ public class NotificationStackScrollLayoutController { } } + public void clearSilentNotifications() { + // Leave the shade open if there will be other notifs left over to clear + final boolean closeShade = !hasActiveClearableNotifications(ROWS_HIGH_PRIORITY); + mView.clearNotifications(ROWS_GENTLE, closeShade); + } + private class NotificationListContainerImpl implements NotificationListContainer { @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/SectionHeaderView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/SectionHeaderView.java index 5777ba120ef0..99ec7548fb9d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/SectionHeaderView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/SectionHeaderView.java @@ -97,7 +97,7 @@ public class SectionHeaderView extends StackScrollerDecorView { /** * Fired whenever the user clicks on the body of the header (e.g. no sub-buttons or anything). */ - void setOnHeaderClickListener(View.OnClickListener listener) { + public void setOnHeaderClickListener(View.OnClickListener listener) { mLabelClickListener = listener; mLabelView.setOnClickListener(listener); } @@ -112,7 +112,7 @@ public class SectionHeaderView extends StackScrollerDecorView { } /** Fired when the user clicks on the "X" button on the far right of the header. */ - void setOnClearAllClickListener(View.OnClickListener listener) { + public void setOnClearAllClickListener(View.OnClickListener listener) { mOnClearClickListener = listener; mClearAllButton.setOnClickListener(listener); } @@ -122,7 +122,8 @@ public class SectionHeaderView extends StackScrollerDecorView { return true; } - void setHeaderText(@StringRes int resId) { + /** Sets text to be displayed in the header */ + public void setHeaderText(@StringRes int resId) { mLabelTextId = resId; mLabelView.setText(resId); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java index 541c7845a5d3..95edfe37fee7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java @@ -91,7 +91,7 @@ public class StackScrollAlgorithm { /** * Updates the state of all children in the hostview based on this algorithm. */ - public void resetViewStates(AmbientState ambientState) { + public void resetViewStates(AmbientState ambientState, int speedBumpIndex) { // The state of the local variables are saved in an algorithmState to easily subdivide it // into multiple phases. StackScrollAlgorithmState algorithmState = mTempAlgorithmState; @@ -110,7 +110,7 @@ public class StackScrollAlgorithm { updateDimmedActivatedHideSensitive(ambientState, algorithmState); updateClipping(algorithmState, ambientState); - updateSpeedBumpState(algorithmState, ambientState); + updateSpeedBumpState(algorithmState, speedBumpIndex); updateShelfState(ambientState); getNotificationChildrenStates(algorithmState, ambientState); } @@ -136,9 +136,9 @@ public class StackScrollAlgorithm { } private void updateSpeedBumpState(StackScrollAlgorithmState algorithmState, - AmbientState ambientState) { + int speedBumpIndex) { int childCount = algorithmState.visibleChildren.size(); - int belowSpeedBump = ambientState.getSpeedBumpIndex(); + int belowSpeedBump = speedBumpIndex; for (int i = 0; i < childCount; i++) { ExpandableView child = algorithmState.visibleChildren.get(i); ExpandableViewState childViewState = child.getViewState(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java index f80656706f37..737cdeba797a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java @@ -281,17 +281,10 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit // TODO: Some of this code may be able to move to NotificationEntryManager. removeHUN(row); - NotificationEntry parentToCancel = null; - if (shouldAutoCancel(entry.getSbn()) && mGroupMembershipManager.isOnlyChildInGroup(entry)) { - NotificationEntry summarySbn = mGroupMembershipManager.getLogicalGroupSummary(entry); - if (shouldAutoCancel(summarySbn.getSbn())) { - parentToCancel = summarySbn; - } - } - final NotificationEntry parentToCancelFinal = parentToCancel; + final Runnable runnable = () -> handleNotificationClickAfterPanelCollapsed( entry, row, controller, intent, - isActivityIntent, wasOccluded, parentToCancelFinal); + isActivityIntent, wasOccluded); if (showOverLockscreen) { mShadeController.addPostCollapseAction(runnable); @@ -312,8 +305,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit RemoteInputController controller, PendingIntent intent, boolean isActivityIntent, - boolean wasOccluded, - NotificationEntry parentToCancelFinal) { + boolean wasOccluded) { String notificationKey = entry.getKey(); mLogger.logHandleClickAfterPanelCollapsed(notificationKey); @@ -373,22 +365,23 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit NotificationLogger.getNotificationLocation(entry); final NotificationVisibility nv = NotificationVisibility.obtain(notificationKey, rank, count, true, location); + + // NMS will officially remove notification if the notification has FLAG_AUTO_CANCEL: mClickNotifier.onNotificationClick(notificationKey, nv); - if (!canBubble) { - if (parentToCancelFinal != null) { - // TODO: (b/145659174) remove - this cancels the parent if the notification clicked - // on will auto-cancel and is the only child in the group. This won't be - // necessary in the new pipeline due to group pruning in ShadeListBuilder. - removeNotification(parentToCancelFinal); - } + // TODO (b/162832756): delete these notification removals when migrating to the new + // pipeline; this is taken care of in {@link NotifCollection#tryRemoveNotification} + // which cancels lifetime extenders if the notification was dismissed by the user (ie: + // clicked or manually dismissed) + if (!canBubble && !mFeatureFlags.isNewNotifPipelineRenderingEnabled()) { if (shouldAutoCancel(entry.getSbn()) || mRemoteInputManager.isNotificationKeptForRemoteInputHistory( notificationKey)) { - // Automatically remove all notifications that we may have kept around longer + // manually call notification removal in order to cancel any lifetime extenders removeNotification(row.getEntry()); } } + mIsCollapsingToShowActivityOverLockscreen = false; } diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java index c7a9af3642e5..98c0b1e99fc4 100644 --- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java +++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java @@ -38,10 +38,6 @@ import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.keyguard.ScreenLifecycle; import com.android.systemui.model.SysUiState; import com.android.systemui.navigationbar.NavigationModeController; -import com.android.systemui.onehanded.OneHanded; -import com.android.systemui.onehanded.OneHandedEvents; -import com.android.systemui.onehanded.OneHandedGestureHandler.OneHandedGestureEventCallback; -import com.android.systemui.onehanded.OneHandedTransitionCallback; import com.android.systemui.pip.Pip; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.TaskStackChangeListener; @@ -51,6 +47,10 @@ import com.android.systemui.tracing.ProtoTracer; import com.android.systemui.tracing.nano.SystemUiTraceProto; import com.android.wm.shell.common.DisplayImeController; import com.android.wm.shell.nano.WmShellTraceProto; +import com.android.wm.shell.onehanded.OneHanded; +import com.android.wm.shell.onehanded.OneHandedEvents; +import com.android.wm.shell.onehanded.OneHandedGestureHandler.OneHandedGestureEventCallback; +import com.android.wm.shell.onehanded.OneHandedTransitionCallback; import com.android.wm.shell.protolog.ShellProtoLogImpl; import com.android.wm.shell.splitscreen.SplitScreen; @@ -248,10 +248,9 @@ public final class WMShell extends SystemUI implements ProtoTraceable<SystemUiTr @Override public void setImeWindowStatus(int displayId, IBinder token, int vis, int backDisposition, boolean showImeSwitcher) { - if (displayId != DEFAULT_DISPLAY && (vis & InputMethodService.IME_VISIBLE) == 0) { - return; + if (displayId == DEFAULT_DISPLAY && (vis & InputMethodService.IME_VISIBLE) != 0) { + oneHanded.stopOneHanded(OneHandedEvents.EVENT_ONE_HANDED_TRIGGER_POP_IME_OUT); } - oneHanded.stopOneHanded(OneHandedEvents.EVENT_ONE_HANDED_TRIGGER_POP_IME_OUT); } }); diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java index adb9186d6705..1f8cf95169d8 100644 --- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java +++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java @@ -24,7 +24,6 @@ import android.view.IWindowManager; import com.android.internal.logging.UiEventLogger; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Main; -import com.android.systemui.onehanded.OneHanded; import com.android.systemui.pip.Pip; import com.android.systemui.pip.PipSurfaceTransactionHelper; import com.android.systemui.pip.PipUiEventLogger; @@ -36,6 +35,7 @@ import com.android.wm.shell.animation.FlingAnimationUtils; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.SystemWindows; import com.android.wm.shell.common.TransactionPool; +import com.android.wm.shell.onehanded.OneHanded; import com.android.wm.shell.splitscreen.SplitScreen; import dagger.BindsOptionalOf; diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java index 3a249d68d969..16fb2cacc950 100644 --- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java +++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java @@ -24,8 +24,6 @@ import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.model.SysUiState; -import com.android.systemui.onehanded.OneHanded; -import com.android.systemui.onehanded.OneHandedController; import com.android.systemui.pip.Pip; import com.android.systemui.pip.PipBoundsHandler; import com.android.systemui.pip.PipSurfaceTransactionHelper; @@ -40,6 +38,8 @@ import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayImeController; import com.android.wm.shell.common.SystemWindows; import com.android.wm.shell.common.TransactionPool; +import com.android.wm.shell.onehanded.OneHanded; +import com.android.wm.shell.onehanded.OneHandedController; import com.android.wm.shell.splitscreen.SplitScreen; import com.android.wm.shell.splitscreen.SplitScreenController; diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java index cdbc647f152b..64e067396059 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java @@ -231,7 +231,6 @@ public class MagnificationModeSwitchTest extends SysuiTestCase { private void assertShowButtonAnimation() { verify(mViewPropertyAnimator).cancel(); verify(mViewPropertyAnimator).setDuration(anyLong()); - verify(mViewPropertyAnimator).setStartDelay(anyLong()); verify(mViewPropertyAnimator).alpha(anyFloat()); verify(mViewPropertyAnimator).start(); } @@ -239,11 +238,15 @@ public class MagnificationModeSwitchTest extends SysuiTestCase { private void initMockImageViewAndAnimator() { when(mViewPropertyAnimator.setDuration(anyLong())).thenReturn(mViewPropertyAnimator); when(mViewPropertyAnimator.alpha(anyFloat())).thenReturn(mViewPropertyAnimator); - when(mViewPropertyAnimator.setStartDelay(anyLong())).thenReturn(mViewPropertyAnimator); when(mViewPropertyAnimator.withEndAction(any(Runnable.class))).thenReturn( mViewPropertyAnimator); when(mSpyImageView.animate()).thenReturn(mViewPropertyAnimator); + doAnswer(invocation -> { + Runnable run = invocation.getArgument(0); + run.run(); + return null; + }).when(mSpyImageView).postDelayed(any(), anyLong()); } private void resetMockImageViewAndAnimator() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java index 909acead9553..b4af786c5579 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java @@ -49,6 +49,7 @@ import android.testing.TestableLooper; import android.util.FeatureFlagUtils; import android.view.IWindowManager; import android.view.View; +import android.view.WindowManagerPolicyConstants; import android.widget.FrameLayout; import androidx.test.filters.SmallTest; @@ -241,6 +242,28 @@ public class GlobalActionsDialogTest extends SysuiTestCase { verifyLogPosted(GlobalActionsDialog.GlobalActionsEvent.GA_SCREENSHOT_LONG_PRESS); } + @Test + public void testShouldShowScreenshot() { + mContext.getOrCreateTestableResources().addOverride( + com.android.internal.R.integer.config_navBarInteractionMode, + WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON); + + GlobalActionsDialog.ScreenshotAction screenshotAction = + mGlobalActionsDialog.makeScreenshotActionForTesting(); + assertThat(screenshotAction.shouldShow()).isTrue(); + } + + @Test + public void testShouldNotShowScreenshot() { + mContext.getOrCreateTestableResources().addOverride( + com.android.internal.R.integer.config_navBarInteractionMode, + WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON); + + GlobalActionsDialog.ScreenshotAction screenshotAction = + mGlobalActionsDialog.makeScreenshotActionForTesting(); + assertThat(screenshotAction.shouldShow()).isFalse(); + } + private void verifyLogPosted(GlobalActionsDialog.GlobalActionsEvent event) { mTestableLooper.processAllMessages(); verify(mUiEventLogger, times(1)) diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java index 89538ac8bc9f..609b8474d134 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java @@ -74,7 +74,7 @@ public class MediaDataCombineLatestTest extends SysuiTestCase { mMediaData = new MediaData(USER_ID, true, BG_COLOR, APP, null, ARTIST, TITLE, null, new ArrayList<>(), new ArrayList<>(), PACKAGE, null, null, null, true, null, true, - false, KEY, false); + false, KEY, false, false, false); mDeviceData = new MediaDeviceData(true, null, DEVICE_NAME); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaPlayerDataTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaPlayerDataTest.kt index da1ec9869d87..ef8d322ca2ec 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaPlayerDataTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaPlayerDataTest.kt @@ -25,7 +25,6 @@ import org.junit.Ignore import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mockito.mock -import org.mockito.Mockito.`when` as whenever @SmallTest @RunWith(AndroidTestingRunner::class) @@ -34,6 +33,8 @@ public class MediaPlayerDataTest : SysuiTestCase() { companion object { val LOCAL = true val RESUMPTION = true + val PLAYING = true + val UNDETERMINED = null } @Before @@ -44,15 +45,13 @@ public class MediaPlayerDataTest : SysuiTestCase() { @Test fun addPlayingThenRemote() { val playerIsPlaying = mock(MediaControlPanel::class.java) - whenever(playerIsPlaying.isPlaying).thenReturn(true) - val dataIsPlaying = createMediaData("app1", LOCAL, !RESUMPTION) + val dataIsPlaying = createMediaData("app1", PLAYING, LOCAL, !RESUMPTION) val playerIsRemote = mock(MediaControlPanel::class.java) - whenever(playerIsRemote.isPlaying).thenReturn(false) - val dataIsRemote = createMediaData("app2", !LOCAL, !RESUMPTION) + val dataIsRemote = createMediaData("app2", PLAYING, !LOCAL, !RESUMPTION) - MediaPlayerData.addMediaPlayer("1", dataIsPlaying, playerIsPlaying) MediaPlayerData.addMediaPlayer("2", dataIsRemote, playerIsRemote) + MediaPlayerData.addMediaPlayer("1", dataIsPlaying, playerIsPlaying) val players = MediaPlayerData.players() assertThat(players).hasSize(2) @@ -63,18 +62,16 @@ public class MediaPlayerDataTest : SysuiTestCase() { @Ignore("Flaky") fun switchPlayersPlaying() { val playerIsPlaying1 = mock(MediaControlPanel::class.java) - whenever(playerIsPlaying1.isPlaying).thenReturn(true) - val dataIsPlaying1 = createMediaData("app1", LOCAL, !RESUMPTION) + var dataIsPlaying1 = createMediaData("app1", PLAYING, LOCAL, !RESUMPTION) val playerIsPlaying2 = mock(MediaControlPanel::class.java) - whenever(playerIsPlaying2.isPlaying).thenReturn(false) - val dataIsPlaying2 = createMediaData("app2", LOCAL, !RESUMPTION) + var dataIsPlaying2 = createMediaData("app2", !PLAYING, LOCAL, !RESUMPTION) MediaPlayerData.addMediaPlayer("1", dataIsPlaying1, playerIsPlaying1) MediaPlayerData.addMediaPlayer("2", dataIsPlaying2, playerIsPlaying2) - whenever(playerIsPlaying1.isPlaying).thenReturn(false) - whenever(playerIsPlaying2.isPlaying).thenReturn(true) + dataIsPlaying1 = createMediaData("app1", !PLAYING, LOCAL, !RESUMPTION) + dataIsPlaying2 = createMediaData("app2", PLAYING, LOCAL, !RESUMPTION) MediaPlayerData.addMediaPlayer("1", dataIsPlaying1, playerIsPlaying1) MediaPlayerData.addMediaPlayer("2", dataIsPlaying2, playerIsPlaying2) @@ -87,38 +84,43 @@ public class MediaPlayerDataTest : SysuiTestCase() { @Test fun fullOrderTest() { val playerIsPlaying = mock(MediaControlPanel::class.java) - whenever(playerIsPlaying.isPlaying).thenReturn(true) - val dataIsPlaying = createMediaData("app1", LOCAL, !RESUMPTION) + val dataIsPlaying = createMediaData("app1", PLAYING, LOCAL, !RESUMPTION) val playerIsPlayingAndRemote = mock(MediaControlPanel::class.java) - whenever(playerIsPlayingAndRemote.isPlaying).thenReturn(true) - val dataIsPlayingAndRemote = createMediaData("app2", !LOCAL, !RESUMPTION) + val dataIsPlayingAndRemote = createMediaData("app2", PLAYING, !LOCAL, !RESUMPTION) val playerIsStoppedAndLocal = mock(MediaControlPanel::class.java) - whenever(playerIsStoppedAndLocal.isPlaying).thenReturn(false) - val dataIsStoppedAndLocal = createMediaData("app3", LOCAL, !RESUMPTION) + val dataIsStoppedAndLocal = createMediaData("app3", !PLAYING, LOCAL, !RESUMPTION) val playerIsStoppedAndRemote = mock(MediaControlPanel::class.java) - whenever(playerIsStoppedAndLocal.isPlaying).thenReturn(false) - val dataIsStoppedAndRemote = createMediaData("app4", !LOCAL, !RESUMPTION) + val dataIsStoppedAndRemote = createMediaData("app4", !PLAYING, !LOCAL, !RESUMPTION) val playerCanResume = mock(MediaControlPanel::class.java) - whenever(playerCanResume.isPlaying).thenReturn(false) - val dataCanResume = createMediaData("app5", LOCAL, RESUMPTION) + val dataCanResume = createMediaData("app5", !PLAYING, LOCAL, RESUMPTION) + + val playerUndetermined = mock(MediaControlPanel::class.java) + val dataUndetermined = createMediaData("app6", UNDETERMINED, LOCAL, RESUMPTION) MediaPlayerData.addMediaPlayer("3", dataIsStoppedAndLocal, playerIsStoppedAndLocal) MediaPlayerData.addMediaPlayer("5", dataIsStoppedAndRemote, playerIsStoppedAndRemote) MediaPlayerData.addMediaPlayer("4", dataCanResume, playerCanResume) MediaPlayerData.addMediaPlayer("1", dataIsPlaying, playerIsPlaying) MediaPlayerData.addMediaPlayer("2", dataIsPlayingAndRemote, playerIsPlayingAndRemote) + MediaPlayerData.addMediaPlayer("6", dataUndetermined, playerUndetermined) val players = MediaPlayerData.players() - assertThat(players).hasSize(5) + assertThat(players).hasSize(6) assertThat(players).containsExactly(playerIsPlaying, playerIsPlayingAndRemote, - playerIsStoppedAndLocal, playerCanResume, playerIsStoppedAndRemote).inOrder() + playerIsStoppedAndLocal, playerCanResume, playerIsStoppedAndRemote, + playerUndetermined).inOrder() } - private fun createMediaData(app: String, isLocalSession: Boolean, resumption: Boolean) = + private fun createMediaData( + app: String, + isPlaying: Boolean?, + isLocalSession: Boolean, + resumption: Boolean + ) = MediaData(0, false, 0, app, null, null, null, null, emptyList(), emptyList<Int>(), "", - null, null, null, true, null, isLocalSession, resumption, null, false) + null, null, null, true, null, isLocalSession, resumption, null, false, isPlaying) } diff --git a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedGestureHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedGestureHandlerTest.java deleted file mode 100644 index 41af53b1c522..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedGestureHandlerTest.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (C) 2020 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.systemui.onehanded; - -import static com.google.common.truth.Truth.assertThat; - -import static org.mockito.Mockito.atLeast; -import static org.mockito.Mockito.atLeastOnce; -import static org.mockito.Mockito.verify; - -import android.testing.AndroidTestingRunner; -import android.testing.TestableLooper; - -import androidx.test.filters.SmallTest; - -import com.android.wm.shell.common.DisplayController; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.MockitoAnnotations; - -@SmallTest -@RunWith(AndroidTestingRunner.class) -@TestableLooper.RunWithLooper -public class OneHandedGestureHandlerTest extends OneHandedTestCase { - OneHandedTouchHandler mTouchHandler; - OneHandedTutorialHandler mTutorialHandler; - OneHandedGestureHandler mGestureHandler; - OneHandedController mOneHandedController; - @Mock - DisplayController mMockDisplayController; - @Mock - OneHandedDisplayAreaOrganizer mMockDisplayAreaOrganizer; - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - mTouchHandler = new OneHandedTouchHandler(); - mTutorialHandler = new OneHandedTutorialHandler(mContext); - mGestureHandler = Mockito.spy( - new OneHandedGestureHandler(mContext, mMockDisplayController)); - mOneHandedController = new OneHandedController( - getContext(), - mMockDisplayController, - mMockDisplayAreaOrganizer, - mTouchHandler, - mTutorialHandler, - mGestureHandler); - mOneHandedController.setThreeButtonModeEnabled(true); - } - - @Test - public void testOneHandedManager_registerForDisplayAreaOrganizer() { - verify(mMockDisplayAreaOrganizer, atLeastOnce()) - .registerTransitionCallback(mGestureHandler); - } - - @Test - public void testOneHandedManager_setGestureEventListener() { - OneHandedGestureHandler.OneHandedGestureEventCallback callback = - new OneHandedGestureHandler.OneHandedGestureEventCallback() { - @Override - public void onStart() {} - - @Override - public void onStop() {} - }; - mOneHandedController.registerGestureCallback(callback); - - verify(mGestureHandler).setGestureEventListener(callback); - assertThat(mGestureHandler.mGestureEventCallback).isEqualTo(callback); - } - - @Test - public void testReceiveNewConfig_whenSetOneHandedEnabled() { - // 1st called at init - verify(mGestureHandler, atLeastOnce()).onOneHandedEnabled(true); - mOneHandedController.setOneHandedEnabled(true); - // 2nd called by setOneHandedEnabled() - verify(mGestureHandler, atLeast(2)).onOneHandedEnabled(true); - } - - @Test - public void testOneHandedDisabled_shouldDisposeInputChannel() { - mOneHandedController.setOneHandedEnabled(false); - mOneHandedController.setSwipeToNotificationEnabled(false); - - assertThat(mGestureHandler.mInputMonitor).isNull(); - assertThat(mGestureHandler.mInputEventReceiver).isNull(); - } - - @Test - public void testChangeNavBarToNon3Button_shouldDisposeInputChannel() { - // 1st called at init - verify(mGestureHandler, atLeastOnce()).onOneHandedEnabled(true); - mOneHandedController.setOneHandedEnabled(true); - // 2nd called by setOneHandedEnabled() - verify(mGestureHandler, atLeast(2)).onOneHandedEnabled(true); - - mGestureHandler.onThreeButtonModeEnabled(false); - - assertThat(mGestureHandler.mInputMonitor).isNull(); - assertThat(mGestureHandler.mInputEventReceiver).isNull(); - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedTouchHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedTouchHandlerTest.java deleted file mode 100644 index 1e408313a36e..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedTouchHandlerTest.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2020 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.systemui.onehanded; - -import static com.google.common.truth.Truth.assertThat; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.atLeast; -import static org.mockito.Mockito.atLeastOnce; -import static org.mockito.Mockito.verify; - -import android.testing.AndroidTestingRunner; -import android.testing.TestableLooper; - -import androidx.test.filters.SmallTest; - -import com.android.wm.shell.common.DisplayController; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.MockitoAnnotations; - -@SmallTest -@RunWith(AndroidTestingRunner.class) -@TestableLooper.RunWithLooper -public class OneHandedTouchHandlerTest extends OneHandedTestCase { - OneHandedTouchHandler mTouchHandler; - OneHandedTutorialHandler mTutorialHandler; - OneHandedGestureHandler mGestureHandler; - OneHandedController mOneHandedController; - @Mock - DisplayController mMockDisplayController; - @Mock - OneHandedDisplayAreaOrganizer mMockDisplayAreaOrganizer; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - mTouchHandler = Mockito.spy(new OneHandedTouchHandler()); - mGestureHandler = new OneHandedGestureHandler(mContext, mMockDisplayController); - mOneHandedController = new OneHandedController( - getContext(), - mMockDisplayController, - mMockDisplayAreaOrganizer, - mTouchHandler, - mTutorialHandler, - mGestureHandler); - } - - @Test - public void testOneHandedManager_registerForDisplayAreaOrganizer() { - verify(mMockDisplayAreaOrganizer).registerTransitionCallback(mTouchHandler); - } - - @Test - public void testOneHandedManager_registerTouchEventListener() { - verify(mTouchHandler).registerTouchEventListener(any()); - assertThat(mTouchHandler.mTouchEventCallback).isNotNull(); - } - - @Test - public void testOneHandedDisabled_shouldDisposeInputChannel() { - mOneHandedController.setOneHandedEnabled(false); - assertThat(mTouchHandler.mInputMonitor).isNull(); - assertThat(mTouchHandler.mInputEventReceiver).isNull(); - } - - @Test - public void testOneHandedEnabled_monitorInputChannel() { - mOneHandedController.setOneHandedEnabled(true); - assertThat(mTouchHandler.mInputMonitor).isNotNull(); - assertThat(mTouchHandler.mInputEventReceiver).isNotNull(); - } - - @Test - public void testReceiveNewConfig_whenSetOneHandedEnabled() { - // Called at init - verify(mTouchHandler, atLeastOnce()).onOneHandedEnabled(true); - mOneHandedController.setOneHandedEnabled(true); - // Called by setOneHandedEnabled() - verify(mTouchHandler, atLeast(2)).onOneHandedEnabled(true); - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerFlagsTest.kt b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerFlagsTest.kt index 4ba29e6e02a6..25fb7d300b8f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerFlagsTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerFlagsTest.kt @@ -96,22 +96,24 @@ class PrivacyItemControllerFlagsTest : SysuiTestCase() { } @Test - fun testNotListeningByDefault() { + fun testNotListeningAllByDefault() { assertFalse(privacyItemController.allIndicatorsAvailable) - assertFalse(privacyItemController.micCameraAvailable) + } - verify(appOpsController, never()).addCallback(any(), any()) + @Test + fun testMicCameraListeningByDefault() { + assertTrue(privacyItemController.micCameraAvailable) } @Test fun testMicCameraChanged() { - changeMicCamera(true) + changeMicCamera(false) // default is true executor.runAllReady() - verify(callback).onFlagMicCameraChanged(true) + verify(callback).onFlagMicCameraChanged(false) verify(callback, never()).onFlagAllChanged(anyBoolean()) - assertTrue(privacyItemController.micCameraAvailable) + assertFalse(privacyItemController.micCameraAvailable) assertFalse(privacyItemController.allIndicatorsAvailable) } @@ -124,20 +126,19 @@ class PrivacyItemControllerFlagsTest : SysuiTestCase() { verify(callback, never()).onFlagMicCameraChanged(anyBoolean()) assertTrue(privacyItemController.allIndicatorsAvailable) - assertFalse(privacyItemController.micCameraAvailable) } @Test fun testBothChanged() { changeAll(true) - changeMicCamera(true) + changeMicCamera(false) executor.runAllReady() verify(callback, atLeastOnce()).onFlagAllChanged(true) - verify(callback, atLeastOnce()).onFlagMicCameraChanged(true) + verify(callback, atLeastOnce()).onFlagMicCameraChanged(false) assertTrue(privacyItemController.allIndicatorsAvailable) - assertTrue(privacyItemController.micCameraAvailable) + assertFalse(privacyItemController.micCameraAvailable) } @Test @@ -157,18 +158,11 @@ class PrivacyItemControllerFlagsTest : SysuiTestCase() { } @Test - fun testAll_listening() { - changeAll(true) - executor.runAllReady() - - verify(appOpsController).addCallback(eq(PrivacyItemController.OPS), any()) - } - - @Test fun testAllFalse_notListening() { changeAll(true) executor.runAllReady() changeAll(false) + changeMicCamera(false) executor.runAllReady() verify(appOpsController).removeCallback(any(), any()) @@ -176,8 +170,8 @@ class PrivacyItemControllerFlagsTest : SysuiTestCase() { @Test fun testSomeListening_stillListening() { + // Mic and camera are true by default changeAll(true) - changeMicCamera(true) executor.runAllReady() changeAll(false) executor.runAllReady() @@ -186,7 +180,8 @@ class PrivacyItemControllerFlagsTest : SysuiTestCase() { } @Test - fun testAllDeleted_stopListening() { + fun testAllDeleted_micCameraFalse_stopListening() { + changeMicCamera(false) changeAll(true) executor.runAllReady() changeAll(null) @@ -196,13 +191,13 @@ class PrivacyItemControllerFlagsTest : SysuiTestCase() { } @Test - fun testMicDeleted_stopListening() { + fun testMicDeleted_stillListening() { changeMicCamera(true) executor.runAllReady() changeMicCamera(null) executor.runAllReady() - verify(appOpsController).removeCallback(any(), any()) + verify(appOpsController, never()).removeCallback(any(), any()) } private fun changeMicCamera(value: Boolean?) = changeProperty(MIC_CAMERA, value) diff --git a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt index fb42baaa0cb5..f152a74da0d5 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt @@ -273,6 +273,7 @@ class PrivacyItemControllerTest : SysuiTestCase() { @Test fun testNotListeningWhenIndicatorsDisabled() { changeAll(false) + changeMicCamera(false) privacyItemController.addCallback(callback) executor.runAllReady() verify(appOpsController, never()).addCallback(eq(PrivacyItemController.OPS), diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifCollectionTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifCollectionTest.java index 359faba48f08..ce0f1220fc88 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifCollectionTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifCollectionTest.java @@ -442,7 +442,7 @@ public class NotifCollectionTest extends SysuiTestCase { } @Test - public void testDismissingLifetimeExtendedSummaryDoesNotDismissChildren() { + public void testRetractingLifetimeExtendedSummaryDoesNotDismissChildren() { // GIVEN A notif group with one summary and two children mCollection.addNotificationLifetimeExtender(mExtender1); CollectionEvent notif1 = postNotif( @@ -460,15 +460,16 @@ public class NotifCollectionTest extends SysuiTestCase { NotificationEntry entry2 = mCollectionListener.getEntry(notif2.key); NotificationEntry entry3 = mCollectionListener.getEntry(notif3.key); - // GIVEN that the summary and one child are retracted, but both are lifetime-extended + // GIVEN that the summary and one child are retracted by the app, but both are + // lifetime-extended mExtender1.shouldExtendLifetime = true; - mNoMan.retractNotif(notif1.sbn, REASON_CANCEL); - mNoMan.retractNotif(notif2.sbn, REASON_CANCEL); + mNoMan.retractNotif(notif1.sbn, REASON_APP_CANCEL); + mNoMan.retractNotif(notif2.sbn, REASON_APP_CANCEL); assertEquals( new ArraySet<>(List.of(entry1, entry2, entry3)), new ArraySet<>(mCollection.getAllNotifs())); - // WHEN the summary is dismissed by the user + // WHEN the summary is retracted by the app mCollection.dismissNotification(entry1, defaultStats(entry1)); // THEN the summary is removed, but both children stick around @@ -480,6 +481,28 @@ public class NotifCollectionTest extends SysuiTestCase { } @Test + public void testNMSReportsUserDismissalAlwaysRemovesNotif() throws RemoteException { + // GIVEN notifications are lifetime extended + mExtender1.shouldExtendLifetime = true; + CollectionEvent notif = postNotif(buildNotif(TEST_PACKAGE, 1, "myTag")); + CollectionEvent notif2 = postNotif(buildNotif(TEST_PACKAGE, 2, "myTag")); + NotificationEntry entry = mCollectionListener.getEntry(notif.key); + NotificationEntry entry2 = mCollectionListener.getEntry(notif2.key); + assertEquals( + new ArraySet<>(List.of(entry, entry2)), + new ArraySet<>(mCollection.getAllNotifs())); + + // WHEN the notifications are reported to be dismissed by the user by NMS + mNoMan.retractNotif(notif.sbn, REASON_CANCEL); + mNoMan.retractNotif(notif2.sbn, REASON_CLICK); + + // THEN the notifications are removed b/c they were dismissed by the user + assertEquals( + new ArraySet<>(List.of()), + new ArraySet<>(mCollection.getAllNotifs())); + } + + @Test public void testDismissNotificationCallsDismissInterceptors() throws RemoteException { // GIVEN a collection with notifications with multiple dismiss interceptors mInterceptor1.shouldInterceptDismissal = true; @@ -833,13 +856,13 @@ public class NotifCollectionTest extends SysuiTestCase { NotifEvent notif2 = mNoMan.postNotif(buildNotif(TEST_PACKAGE2, 88)); NotificationEntry entry2 = mCollectionListener.getEntry(notif2.key); - // WHEN a notification is removed - mNoMan.retractNotif(notif2.sbn, REASON_CLICK); + // WHEN a notification is removed by the app + mNoMan.retractNotif(notif2.sbn, REASON_APP_CANCEL); // THEN each extender is asked whether to extend, even if earlier ones return true - verify(mExtender1).shouldExtendLifetime(entry2, REASON_CLICK); - verify(mExtender2).shouldExtendLifetime(entry2, REASON_CLICK); - verify(mExtender3).shouldExtendLifetime(entry2, REASON_CLICK); + verify(mExtender1).shouldExtendLifetime(entry2, REASON_APP_CANCEL); + verify(mExtender2).shouldExtendLifetime(entry2, REASON_APP_CANCEL); + verify(mExtender3).shouldExtendLifetime(entry2, REASON_APP_CANCEL); // THEN the entry is not removed assertTrue(mCollection.getAllNotifs().contains(entry2)); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ConversationCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ConversationCoordinatorTest.kt index 09c9bcd967bd..711f0bab5068 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ConversationCoordinatorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ConversationCoordinatorTest.kt @@ -26,6 +26,7 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner +import com.android.systemui.statusbar.notification.collection.render.NodeController import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_PERSON import org.junit.Assert.assertFalse @@ -47,12 +48,10 @@ class ConversationCoordinatorTest : SysuiTestCase() { private lateinit var promoter: NotifPromoter private lateinit var peopleSectioner: NotifSectioner - @Mock - private lateinit var pipeline: NotifPipeline - @Mock - private lateinit var peopleNotificationIdentifier: PeopleNotificationIdentifier - @Mock - private lateinit var channel: NotificationChannel + @Mock private lateinit var pipeline: NotifPipeline + @Mock private lateinit var peopleNotificationIdentifier: PeopleNotificationIdentifier + @Mock private lateinit var channel: NotificationChannel + @Mock private lateinit var headerController: NodeController private lateinit var entry: NotificationEntry private lateinit var coordinator: ConversationCoordinator @@ -60,7 +59,7 @@ class ConversationCoordinatorTest : SysuiTestCase() { @Before fun setUp() { MockitoAnnotations.initMocks(this) - coordinator = ConversationCoordinator(peopleNotificationIdentifier) + coordinator = ConversationCoordinator(peopleNotificationIdentifier, headerController) whenever(channel.isImportantConversation).thenReturn(true) coordinator.attach(pipeline) diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.java index fa992a5d5dbb..7e771cecaf66 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.java @@ -39,6 +39,7 @@ import com.android.systemui.statusbar.notification.collection.listbuilder.plugga import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner; import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener; import com.android.systemui.statusbar.notification.collection.notifcollection.NotifLifetimeExtender; +import com.android.systemui.statusbar.notification.collection.render.NodeController; import com.android.systemui.statusbar.notification.interruption.HeadsUpViewBinder; import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider; import com.android.systemui.statusbar.notification.row.NotifBindPipeline.BindCallback; @@ -73,6 +74,7 @@ public class HeadsUpCoordinatorTest extends SysuiTestCase { @Mock private NotificationRemoteInputManager mRemoteInputManager; @Mock private RemoteInputController mRemoteInputController; @Mock private NotifLifetimeExtender.OnEndLifetimeExtensionCallback mEndLifetimeExtension; + @Mock private NodeController mHeaderController; private NotificationEntry mEntry; @@ -85,8 +87,8 @@ public class HeadsUpCoordinatorTest extends SysuiTestCase { mHeadsUpManager, mHeadsUpViewBinder, mNotificationInterruptStateProvider, - mRemoteInputManager - ); + mRemoteInputManager, + mHeaderController); mCoordinator.attach(mNotifPipeline); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinatorTest.java index 3a7d28ab56ec..1031d6befc36 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinatorTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinatorTest.java @@ -38,6 +38,7 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntryB import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter; import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner; import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider; +import com.android.systemui.statusbar.notification.collection.render.NodeController; import org.junit.Before; import org.junit.Test; @@ -54,6 +55,8 @@ public class RankingCoordinatorTest extends SysuiTestCase { @Mock private StatusBarStateController mStatusBarStateController; @Mock private HighPriorityProvider mHighPriorityProvider; @Mock private NotifPipeline mNotifPipeline; + @Mock private NodeController mAlertingHeaderController; + @Mock private NodeController mSilentHeaderController; @Captor private ArgumentCaptor<NotifFilter> mNotifFilterCaptor; @@ -67,8 +70,9 @@ public class RankingCoordinatorTest extends SysuiTestCase { @Before public void setup() { MockitoAnnotations.initMocks(this); - RankingCoordinator rankingCoordinator = - new RankingCoordinator(mStatusBarStateController, mHighPriorityProvider); + RankingCoordinator rankingCoordinator = new RankingCoordinator( + mStatusBarStateController, mHighPriorityProvider, mAlertingHeaderController, + mSilentHeaderController); mEntry = new NotificationEntryBuilder().build(); rankingCoordinator.attach(mNotifPipeline); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationBlockingHelperManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationBlockingHelperManagerTest.java index 5aeb43fbd959..edb8776bcb02 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationBlockingHelperManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationBlockingHelperManagerTest.java @@ -49,6 +49,7 @@ import com.android.systemui.SysuiTestCase; import com.android.systemui.bubbles.BubbleController; import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin; import com.android.systemui.statusbar.notification.NotificationEntryManager; +import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager; import org.junit.Before; import org.junit.Test; @@ -71,6 +72,7 @@ public class NotificationBlockingHelperManagerTest extends SysuiTestCase { @Mock private NotificationEntryManager mEntryManager; @Mock private NotificationMenuRow mMenuRow; @Mock private NotificationMenuRowPlugin.MenuItem mMenuItem; + @Mock private GroupMembershipManager mGroupMembershipManager; @Before public void setUp() { @@ -89,7 +91,8 @@ public class NotificationBlockingHelperManagerTest extends SysuiTestCase { mHelper = new NotificationTestHelper(mContext, mDependency, TestableLooper.get(this)); mBlockingHelperManager = new NotificationBlockingHelperManager( - mContext, mGutsManager, mEntryManager, mock(MetricsLogger.class)); + mContext, mGutsManager, mEntryManager, mock(MetricsLogger.class), + mGroupMembershipManager); // By default, have the shade visible/expanded. mBlockingHelperManager.setNotificationShadeExpanded(1f); } @@ -185,6 +188,7 @@ public class NotificationBlockingHelperManagerTest extends SysuiTestCase { .build(); assertFalse(childRow.getIsNonblockable()); + when(mGroupMembershipManager.isOnlyChildInGroup(childRow.getEntry())).thenReturn(true); assertTrue(mBlockingHelperManager.perhapsShowBlockingHelper(childRow, mMenuRow)); verify(mGutsManager).openGuts(childRow, 0, 0, mMenuItem); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java index 7ca24789a29b..8cd71031a8f8 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java @@ -53,6 +53,7 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager; import com.android.systemui.statusbar.notification.collection.NotificationEntry; +import com.android.systemui.statusbar.notification.collection.render.SectionHeaderController; import com.android.systemui.statusbar.notification.people.PeopleHubViewAdapter; import com.android.systemui.statusbar.notification.row.ActivatableNotificationViewController; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; @@ -63,6 +64,7 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Answers; import org.mockito.Mock; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; @@ -87,6 +89,10 @@ public class NotificationSectionsManagerTest extends SysuiTestCase { @Mock private NotificationRowComponent mNotificationRowComponent; @Mock private ActivatableNotificationViewController mActivatableNotificationViewController; @Mock private NotificationSectionsLogger mLogger; + @Mock private SectionHeaderController mIncomingHeaderController; + @Mock private SectionHeaderController mPeopleHeaderController; + @Mock private SectionHeaderController mAlertingHeaderController; + @Mock private SectionHeaderController mSilentHeaderController; private NotificationSectionsManager mSectionsManager; @@ -109,15 +115,21 @@ public class NotificationSectionsManagerTest extends SysuiTestCase { }); when(mNotificationRowComponent.getActivatableNotificationViewController()) .thenReturn(mActivatableNotificationViewController); + when(mIncomingHeaderController.getHeaderView()).thenReturn(mock(SectionHeaderView.class)); + when(mPeopleHeaderController.getHeaderView()).thenReturn(mock(SectionHeaderView.class)); + when(mAlertingHeaderController.getHeaderView()).thenReturn(mock(SectionHeaderView.class)); + when(mSilentHeaderController.getHeaderView()).thenReturn(mock(SectionHeaderView.class)); mSectionsManager = new NotificationSectionsManager( - mActivityStarterDelegate, mStatusBarStateController, mConfigurationController, - mPeopleHubAdapter, mKeyguardMediaController, mSectionsFeatureManager, - mLogger + mLogger, + mIncomingHeaderController, + mPeopleHeaderController, + mAlertingHeaderController, + mSilentHeaderController ); // Required in order for the header inflation to work properly when(mNssl.generateLayoutParams(any(AttributeSet.class))) @@ -241,8 +253,9 @@ public class NotificationSectionsManagerTest extends SysuiTestCase { mSectionsManager.updateSectionBoundaries(); clearInvocations(mNssl); + SectionHeaderView silentHeaderView = mSectionsManager.getSilentHeaderView(); ViewGroup transientParent = mock(ViewGroup.class); - mSectionsManager.getSilentHeaderView().setTransientContainer(transientParent); + when(silentHeaderView.getTransientContainer()).thenReturn(transientParent); // WHEN the LO section reappears setStackState( @@ -252,8 +265,8 @@ public class NotificationSectionsManagerTest extends SysuiTestCase { // THEN the header is first removed from the transient parent before being added to the // NSSL. - verify(transientParent).removeTransientView(mSectionsManager.getSilentHeaderView()); - verify(mNssl).addView(mSectionsManager.getSilentHeaderView(), 1); + verify(transientParent).removeTransientView(silentHeaderView); + verify(mNssl).addView(silentHeaderView, 1); } @Test @@ -358,23 +371,6 @@ public class NotificationSectionsManagerTest extends SysuiTestCase { } @Test - public void testPeopleFiltering_keepPeopleHeaderWhenSectionEmpty() { - mSectionsManager.setPeopleHubVisible(true); - enablePeopleFiltering(); - - setStackState( - PEOPLE_HEADER, - ALERTING_HEADER, - ALERTING, - GENTLE_HEADER, - GENTLE); - mSectionsManager.updateSectionBoundaries(); - - verify(mNssl, never()).removeView(mSectionsManager.getPeopleHeaderView()); - verify(mNssl).changeViewPosition(mSectionsManager.getPeopleHeaderView(), 0); - } - - @Test public void testPeopleFiltering_AlertingHunWhilePeopleVisible() { enablePeopleFiltering(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java index f48e6ea7941e..de59ac319bd9 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java @@ -451,8 +451,8 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { @Test public void testAddNotificationUpdatesSpeedBumpIndex() { - // initial state == -1 - assertEquals(-1, mStackScroller.getSpeedBumpIndex()); + // initial state calculated == 0 + assertEquals(0, mStackScroller.getSpeedBumpIndex()); // add notification that's before the speed bump ExpandableNotificationRow row = mock(ExpandableNotificationRow.class); @@ -467,8 +467,8 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { @Test public void testAddAmbientNotificationNoSpeedBumpUpdate() { - // initial state == -1 - assertEquals(-1, mStackScroller.getSpeedBumpIndex()); + // initial state calculated == 0 + assertEquals(0, mStackScroller.getSpeedBumpIndex()); // add notification that's after the speed bump ExpandableNotificationRow row = mock(ExpandableNotificationRow.class); @@ -483,8 +483,8 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { @Test public void testRemoveNotificationUpdatesSpeedBump() { - // initial state == -1 - assertEquals(-1, mStackScroller.getSpeedBumpIndex()); + // initial state calculated == 0 + assertEquals(0, mStackScroller.getSpeedBumpIndex()); // add 3 notification that are after the speed bump ExpandableNotificationRow row = mock(ExpandableNotificationRow.class); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollerControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollerControllerTest.java index 32c682878c28..ef11f81971b3 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollerControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollerControllerTest.java @@ -49,6 +49,7 @@ import com.android.systemui.statusbar.NotificationLockscreenUserManager.UserChan import com.android.systemui.statusbar.SysuiStatusBarStateController; import com.android.systemui.statusbar.notification.DynamicPrivacyController; import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy; +import com.android.systemui.statusbar.notification.collection.render.SectionHeaderController; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.row.NotificationGutsManager; import com.android.systemui.statusbar.phone.HeadsUpManagerPhone; @@ -76,50 +77,30 @@ import org.mockito.MockitoAnnotations; @RunWith(AndroidTestingRunner.class) public class NotificationStackScrollerControllerTest extends SysuiTestCase { - @Mock - private NotificationGutsManager mNotificationGutsManager; - @Mock - private HeadsUpManagerPhone mHeadsUpManager; - @Mock - private NotificationRoundnessManager mNotificationRoundnessManager; - @Mock - private TunerService mTunerService; - @Mock - private DynamicPrivacyController mDynamicPrivacyController; - @Mock - private ConfigurationController mConfigurationController; - @Mock - private NotificationStackScrollLayout mNotificationStackScrollLayout; - @Mock - private ZenModeController mZenModeController; - @Mock - private KeyguardMediaController mKeyguardMediaController; - @Mock - private SysuiStatusBarStateController mSysuiStatusBarStateController; - @Mock - private KeyguardBypassController mKeyguardBypassController; - @Mock - private SysuiColorExtractor mColorExtractor; - @Mock - private NotificationLockscreenUserManager mNotificationLockscreenUserManager; - @Mock - private MetricsLogger mMetricsLogger; - @Mock - private FalsingManager mFalsingManager; - @Mock - private NotificationSectionsManager mNotificationSectionsManager; - @Mock - private Resources mResources; + @Mock private NotificationGutsManager mNotificationGutsManager; + @Mock private HeadsUpManagerPhone mHeadsUpManager; + @Mock private NotificationRoundnessManager mNotificationRoundnessManager; + @Mock private TunerService mTunerService; + @Mock private DynamicPrivacyController mDynamicPrivacyController; + @Mock private ConfigurationController mConfigurationController; + @Mock private NotificationStackScrollLayout mNotificationStackScrollLayout; + @Mock private ZenModeController mZenModeController; + @Mock private KeyguardMediaController mKeyguardMediaController; + @Mock private SysuiStatusBarStateController mSysuiStatusBarStateController; + @Mock private KeyguardBypassController mKeyguardBypassController; + @Mock private SysuiColorExtractor mColorExtractor; + @Mock private NotificationLockscreenUserManager mNotificationLockscreenUserManager; + @Mock private MetricsLogger mMetricsLogger; + @Mock private FalsingManager mFalsingManager; + @Mock private NotificationSectionsManager mNotificationSectionsManager; + @Mock private Resources mResources; @Mock(answer = Answers.RETURNS_SELF) private NotificationSwipeHelper.Builder mNotificationSwipeHelperBuilder; - @Mock - private NotificationSwipeHelper mNotificationSwipeHelper; - @Mock - private StatusBar mStatusBar; - @Mock - private ScrimController mScrimController; - @Mock - private NotificationGroupManagerLegacy mLegacyGroupManager; + @Mock private NotificationSwipeHelper mNotificationSwipeHelper; + @Mock private StatusBar mStatusBar; + @Mock private ScrimController mScrimController; + @Mock private NotificationGroupManagerLegacy mLegacyGroupManager; + @Mock private SectionHeaderController mSilentHeaderController; @Captor ArgumentCaptor<StatusBarStateController.StateListener> mStateListenerArgumentCaptor; @@ -154,7 +135,8 @@ public class NotificationStackScrollerControllerTest extends SysuiTestCase { mStatusBar, mScrimController, mLegacyGroupManager, - mLegacyGroupManager + mLegacyGroupManager, + mSilentHeaderController ); when(mNotificationStackScrollLayout.isAttachedToWindow()).thenReturn(true); diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java index 51cc5f175444..bcc36396e1d8 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java @@ -30,15 +30,15 @@ import com.android.systemui.SysuiTestCase; import com.android.systemui.keyguard.ScreenLifecycle; import com.android.systemui.model.SysUiState; import com.android.systemui.navigationbar.NavigationModeController; -import com.android.systemui.onehanded.OneHanded; -import com.android.systemui.onehanded.OneHandedGestureHandler; -import com.android.systemui.onehanded.OneHandedTransitionCallback; import com.android.systemui.pip.Pip; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.TaskStackChangeListener; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.tracing.ProtoTracer; import com.android.wm.shell.common.DisplayImeController; +import com.android.wm.shell.onehanded.OneHanded; +import com.android.wm.shell.onehanded.OneHandedGestureHandler; +import com.android.wm.shell.onehanded.OneHandedTransitionCallback; import com.android.wm.shell.splitscreen.SplitScreen; import org.junit.Before; diff --git a/packages/Tethering/common/TetheringLib/Android.bp b/packages/Tethering/common/TetheringLib/Android.bp index c8becce7be82..bf643cdcecc5 100644 --- a/packages/Tethering/common/TetheringLib/Android.bp +++ b/packages/Tethering/common/TetheringLib/Android.bp @@ -16,19 +16,9 @@ java_sdk_library { name: "framework-tethering", defaults: ["framework-module-defaults"], + impl_library_visibility: ["//frameworks/base/packages/Tethering:__subpackages__"], - // Allow access to the stubs from anywhere. - visibility: ["//visibility:public"], - - // Restrict access to implementation library. - impl_library_visibility: [ - "//visibility:override", // Ignore the visibility property. - "//frameworks/base/packages/Tethering:__subpackages__", - ], - - srcs: [ - ":framework-tethering-srcs", - ], + srcs: [":framework-tethering-srcs"], jarjar_rules: "jarjar-rules.txt", installable: true, diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_notifications_alert.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_notifications_alert.xml new file mode 100644 index 000000000000..e66d9204769d --- /dev/null +++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_notifications_alert.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2020 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. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:height="24dp" + android:viewportHeight="24" + android:viewportWidth="24" + android:width="24dp" > + <path + android:fillColor="@android:color/white" + android:pathData="M5.85,3.01C3.72,4.82,2.5,7.46,2.5,10.25C2.5,10.66,2.84,11,3.25,11S4,10.66,4,10.25c0-2.35,1.03-4.57,2.82-6.1 C7.14,3.88,7.17,3.41,6.91,3.1C6.64,2.78,6.17,2.74,5.85,3.01z" /> + <path + android:fillColor="@android:color/white" + android:pathData="M21.5,10.25c0-2.79-1.22-5.43-3.35-7.24c-0.32-0.27-0.79-0.23-1.06,0.08c-0.27,0.32-0.23,0.79,0.08,1.06 C18.97,5.68,20,7.9,20,10.25c0,0.41,0.34,0.75,0.75,0.75S21.5,10.66,21.5,10.25z" /> + <path + android:fillColor="@android:color/white" + android:pathData="M12,2.5c-0.83,0-1.5,0.67-1.5,1.5v0.7C7.91,5.36,6,7.71,6,10.5V15c0,0.55-0.45,1-1,1s-1,0.45-1,1v2h16v-2 c0-0.55-0.45-1-1-1s-1-0.45-1-1v-4.5c0-2.79-1.91-5.14-4.5-5.8V4C13.5,3.17,12.83,2.5,12,2.5z M16.5,10.5V15 c0,1.21,0.86,2.22,2,2.45v0.05h-13v-0.05c1.14-0.23,2-1.24,2-2.45v-4.5C7.5,8.02,9.52,6,12,6S16.5,8.02,16.5,10.5z" /> + <path + android:fillColor="@android:color/white" + android:pathData="M14,20h-4c0,1.1,0.9,2,2,2S14,21.1,14,20z" /> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_notifications_alert.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_notifications_alert.xml new file mode 100644 index 000000000000..2f5bdb0ecbe3 --- /dev/null +++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_notifications_alert.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2020 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. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:height="24dp" + android:viewportHeight="24" + android:viewportWidth="24" + android:width="24dp" > + <path + android:fillColor="@android:color/white" + android:pathData="M4.12,9.67C4.42,7.73,5.38,6,6.77,4.73C7.19,4.35,7.2,3.7,6.8,3.3c-0.39-0.39-1-0.39-1.4-0.03 C3.7,4.84,2.52,6.96,2.15,9.34c-0.1,0.61,0.37,1.16,0.99,1.16C3.63,10.5,4.04,10.15,4.12,9.67z" /> + <path + android:fillColor="@android:color/white" + android:pathData="M18.6,3.28c-0.4-0.37-1.02-0.36-1.4,0.02c-0.4,0.4-0.38,1.04,0.03,1.42c1.38,1.27,2.35,3,2.65,4.94 c0.08,0.49,0.5,0.84,0.98,0.84c0.61,0,1.09-0.55,0.99-1.16C21.47,6.96,20.29,4.84,18.6,3.28z" /> + <path + android:fillColor="@android:color/white" + android:pathData="M12,22c1.1,0,2-0.9,2-2h-4C10,21.1,10.9,22,12,22z" /> + <path + android:fillColor="@android:color/white" + android:pathData="M18,16v-5c0-3.07-1.64-5.64-4.5-6.32V4c0-0.83-0.67-1.5-1.5-1.5S10.5,3.17,10.5,4v0.68C7.63,5.36,6,7.92,6,11v5 l-2.15,2.15c-0.19,0.2-0.19,0.51,0.01,0.71C3.95,18.95,4.07,19,4.2,19h15.6c0.45,0,0.67-0.54,0.35-0.85L18,16z" /> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_notifications_alert.xml b/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_notifications_alert.xml new file mode 100644 index 000000000000..c92bdf6dc62a --- /dev/null +++ b/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_notifications_alert.xml @@ -0,0 +1,21 @@ +<!-- + Copyright (C) 2020 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. +--> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M6.81,3.81L5.75,2.75C3.45,4.76,2,7.71,2,11h1.5C3.5,8.13,4.79,5.55,6.81,3.81z"/> + <path android:fillColor="@android:color/white" android:pathData="M18.25,2.75l-1.06,1.06C19.21,5.55,20.5,8.13,20.5,11H22C22,7.71,20.55,4.76,18.25,2.75z"/> + <path android:fillColor="@android:color/white" android:pathData="M18,10.5c0-4.38-2.72-5.57-4.5-5.89V4c0-1.59-1.43-1.5-1.5-1.5c-0.05,0-1.5-0.09-1.5,1.5v0.62C8.72,4.94,6,6.14,6,10.5v7 H4V19h16v-1.5h-2V10.5z M16.5,17.5h-9v-7C7.5,7.57,8.94,5.95,12,6c3.07-0.05,4.5,1.55,4.5,4.5V17.5z"/> + <path android:fillColor="@android:color/white" android:pathData="M12,22c0.07,0,2,0.12,2-2h-4C10,22.12,11.91,22,12,22z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_notifications_alert.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_notifications_alert.xml new file mode 100644 index 000000000000..8f854e74f551 --- /dev/null +++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_notifications_alert.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2020 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. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:height="24dp" + android:viewportHeight="24" + android:viewportWidth="24" + android:width="24dp" > + <path + android:fillColor="@android:color/white" + android:pathData="M14,20h-4c0,1.1,0.9,2,2,2S14,21.1,14,20z" /> + <path + android:fillColor="@android:color/white" + android:pathData="M12,2.5c-0.69,0-1.25,0.56-1.25,1.25v0.77C8.04,5.11,6,7.51,6,10.4V17H4.75C4.34,17,4,17.34,4,17.75s0.34,0.75,0.75,0.75 h14.5c0.41,0,0.75-0.34,0.75-0.75S19.66,17,19.25,17H18v-6.6c0-2.88-2.04-5.29-4.75-5.87V3.75C13.25,3.06,12.69,2.5,12,2.5z M16.5,10.4V17h-9v-6.6c0-2.48,2.02-4.5,4.5-4.5S16.5,7.91,16.5,10.4z" /> + <path + android:fillColor="@android:color/white" + android:pathData="M5.85,3.01C3.72,4.82,2.5,7.46,2.5,10.25C2.5,10.66,2.84,11,3.25,11S4,10.66,4,10.25c0-2.35,1.03-4.57,2.82-6.1 C7.14,3.88,7.17,3.41,6.91,3.1C6.64,2.78,6.17,2.74,5.85,3.01z" /> + <path + android:fillColor="@android:color/white" + android:pathData="M18.15,3.01c-0.32-0.27-0.79-0.23-1.06,0.08c-0.27,0.32-0.23,0.79,0.08,1.06C18.97,5.68,20,7.9,20,10.25 c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75C21.5,7.46,20.28,4.82,18.15,3.01z" /> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_notifications_alert.xml b/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_notifications_alert.xml new file mode 100644 index 000000000000..e022c63fdf06 --- /dev/null +++ b/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_notifications_alert.xml @@ -0,0 +1,21 @@ +<!-- + Copyright (C) 2020 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. +--> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M6.47,4.81c0.37-0.38,0.35-0.99-0.03-1.37c-0.4-0.4-1.05-0.39-1.44,0.02c-1.62,1.72-2.7,3.95-2.95,6.43 C2,10.48,2.46,11,3.05,11h0.01c0.51,0,0.93-0.38,0.98-0.88C4.24,8.07,5.13,6.22,6.47,4.81z"/> + <path android:fillColor="@android:color/white" android:pathData="M18.99,3.47c-0.39-0.41-1.04-0.42-1.44-0.02c-0.38,0.38-0.39,0.98-0.03,1.37c1.34,1.41,2.23,3.26,2.43,5.3 c0.05,0.5,0.48,0.88,0.98,0.88h0.01c0.59,0,1.05-0.52,0.99-1.11C21.69,7.42,20.61,5.19,18.99,3.47z"/> + <path android:fillColor="@android:color/white" android:pathData="M19,17h-1v-6c0-3.07-1.63-5.64-4.5-6.32V4c0-0.83-0.67-1.5-1.5-1.5c-0.83,0-1.5,0.67-1.5,1.5v0.68C7.64,5.36,6,7.92,6,11 v6H5c-0.55,0-1,0.45-1,1c0,0.55,0.45,1,1,1h14c0.55,0,1-0.45,1-1C20,17.45,19.55,17,19,17z"/> + <path android:fillColor="@android:color/white" android:pathData="M12,22c1.1,0,2-0.9,2-2h-4C10,21.1,10.9,22,12,22z"/> +</vector>
\ No newline at end of file diff --git a/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_notifications_alert.xml b/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_notifications_alert.xml new file mode 100644 index 000000000000..1e25d27f0eb3 --- /dev/null +++ b/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_notifications_alert.xml @@ -0,0 +1,21 @@ +<!-- + Copyright (C) 2020 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. +--> +<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M18,6.5L16.5,5H13V3h-2v2H7.5L6,6.5v11H4V19h16v-1.5h-2V6.5z M7.5,17.5v-11h9v11H7.5z"/> + <path android:fillColor="@android:color/white" android:pathData="M12,22c1.1,0,2-0.9,2-2h-4C10,21.1,10.9,22,12,22z"/> + <path android:fillColor="@android:color/white" android:pathData="M6.81,3.81L5.75,2.75C3.45,4.76,2,7.71,2,11h1.5C3.5,8.13,4.79,5.55,6.81,3.81z"/> + <path android:fillColor="@android:color/white" android:pathData="M18.25,2.75l-1.06,1.06C19.21,5.55,20.5,8.13,20.5,11H22C22,7.71,20.55,4.76,18.25,2.75z"/> +</vector>
\ No newline at end of file diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java index b6f2a47dd5e2..c583dcc2b1be 100644 --- a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java +++ b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java @@ -37,6 +37,7 @@ import android.util.SparseArray; import android.view.Display; import android.view.MagnificationSpec; import android.view.View; +import android.view.accessibility.MagnificationAnimationCallback; import android.view.animation.DecelerateInterpolator; import com.android.internal.R; @@ -63,7 +64,7 @@ public class FullScreenMagnificationController { private static final boolean DEBUG = false; private static final String LOG_TAG = "FullScreenMagnificationController"; - private static final Runnable STUB_RUNNABLE = () -> { + private static final MagnificationAnimationCallback STUB_ANIMATION_CALLBACK = success -> { }; public static final float MIN_SCALE = 1.0f; public static final float MAX_SCALE = 8.0f; @@ -304,18 +305,19 @@ public class FullScreenMagnificationController { } } - void sendSpecToAnimation(MagnificationSpec spec, Runnable endCallback) { + void sendSpecToAnimation(MagnificationSpec spec, + MagnificationAnimationCallback animationCallback) { if (DEBUG) { Slog.i(LOG_TAG, - "sendSpecToAnimation(spec = " + spec + ", endCallback = " + endCallback - + ")"); + "sendSpecToAnimation(spec = " + spec + ", animationCallback = " + + animationCallback + ")"); } if (Thread.currentThread().getId() == mMainThreadId) { - mSpecAnimationBridge.updateSentSpecMainThread(spec, endCallback); + mSpecAnimationBridge.updateSentSpecMainThread(spec, animationCallback); } else { final Message m = PooledLambda.obtainMessage( SpecAnimationBridge::updateSentSpecMainThread, - mSpecAnimationBridge, spec, endCallback); + mSpecAnimationBridge, spec, animationCallback); mControllerCtx.getHandler().sendMessage(m); } } @@ -415,11 +417,11 @@ public class FullScreenMagnificationController { @GuardedBy("mLock") boolean reset(boolean animate) { - return reset(transformToStubRunnable(animate)); + return reset(transformToStubCallback(animate)); } @GuardedBy("mLock") - boolean reset(Runnable endCallback) { + boolean reset(MagnificationAnimationCallback animationCallback) { if (!mRegistered) { return false; } @@ -430,7 +432,7 @@ public class FullScreenMagnificationController { onMagnificationChangedLocked(); } mIdOfLastServiceToMagnify = INVALID_ID; - sendSpecToAnimation(spec, endCallback); + sendSpecToAnimation(spec, animationCallback); return changed; } @@ -458,24 +460,23 @@ public class FullScreenMagnificationController { final float centerX = normPivotX + offsetX; final float centerY = normPivotY + offsetY; mIdOfLastServiceToMagnify = id; - return setScaleAndCenter(scale, centerX, centerY, transformToStubRunnable(animate), id); + return setScaleAndCenter(scale, centerX, centerY, transformToStubCallback(animate), id); } @GuardedBy("mLock") boolean setScaleAndCenter(float scale, float centerX, float centerY, - Runnable endCallback, int id) { + MagnificationAnimationCallback animationCallback, int id) { if (!mRegistered) { return false; } if (DEBUG) { Slog.i(LOG_TAG, "setScaleAndCenterLocked(scale = " + scale + ", centerX = " + centerX - + ", centerY = " + centerY + ", endCallback = " + endCallback - + ", id = " + id - + ")"); + + ", centerY = " + centerY + ", endCallback = " + + animationCallback + ", id = " + id + ")"); } final boolean changed = updateMagnificationSpecLocked(scale, centerX, centerY); - sendSpecToAnimation(mCurrentMagnificationSpec, endCallback); + sendSpecToAnimation(mCurrentMagnificationSpec, animationCallback); if (isMagnifying() && (id != INVALID_ID)) { mIdOfLastServiceToMagnify = id; } @@ -875,7 +876,7 @@ public class FullScreenMagnificationController { * the spec did not change */ public boolean reset(int displayId, boolean animate) { - return reset(displayId, animate ? STUB_RUNNABLE : null); + return reset(displayId, animate ? STUB_ANIMATION_CALLBACK : null); } /** @@ -883,18 +884,19 @@ public class FullScreenMagnificationController { * transition. * * @param displayId The logical display id. - * @param endCallback Called when the animation is ended or the spec did not change. + * @param animationCallback Called when the animation result is valid. * {@code null} to transition immediately * @return {@code true} if the magnification spec changed, {@code false} if * the spec did not change */ - public boolean reset(int displayId, Runnable endCallback) { + public boolean reset(int displayId, + MagnificationAnimationCallback animationCallback) { synchronized (mLock) { final DisplayMagnification display = mDisplays.get(displayId); if (display == null) { return false; } - return display.reset(endCallback); + return display.reset(animationCallback); } } @@ -946,7 +948,7 @@ public class FullScreenMagnificationController { return false; } return display.setScaleAndCenter(Float.NaN, centerX, centerY, - animate ? STUB_RUNNABLE : null, id); + animate ? STUB_ANIMATION_CALLBACK : null, id); } } @@ -970,7 +972,7 @@ public class FullScreenMagnificationController { public boolean setScaleAndCenter(int displayId, float scale, float centerX, float centerY, boolean animate, int id) { return setScaleAndCenter(displayId, scale, centerX, centerY, - transformToStubRunnable(animate), id); + transformToStubCallback(animate), id); } /** @@ -984,20 +986,20 @@ public class FullScreenMagnificationController { * center and scale, or {@link Float#NaN} to leave unchanged * @param centerY the screen-relative Y coordinate around which to * center and scale, or {@link Float#NaN} to leave unchanged - * @param endCallback called when the transition is finished successfully or the spec did not - * change. {@code null} to transition immediately. + * @param animationCallback Called when the animation result is valid. + * {@code null} to transition immediately * @param id the ID of the service requesting the change * @return {@code true} if the magnification spec changed, {@code false} if * the spec did not change */ public boolean setScaleAndCenter(int displayId, float scale, float centerX, float centerY, - Runnable endCallback, int id) { + MagnificationAnimationCallback animationCallback, int id) { synchronized (mLock) { final DisplayMagnification display = mDisplays.get(displayId); if (display == null) { return false; } - return display.setScaleAndCenter(scale, centerX, centerY, endCallback, id); + return display.setScaleAndCenter(scale, centerX, centerY, animationCallback, id); } } @@ -1230,7 +1232,7 @@ public class FullScreenMagnificationController { private final ValueAnimator mValueAnimator; // Called when the callee wants animating and the sent spec matches the target spec. - private Runnable mEndCallback; + private MagnificationAnimationCallback mAnimationCallback; private final Object mLock; private final int mDisplayId; @@ -1268,33 +1270,35 @@ public class FullScreenMagnificationController { } } - void updateSentSpecMainThread(MagnificationSpec spec, Runnable endCallback) { + void updateSentSpecMainThread(MagnificationSpec spec, + MagnificationAnimationCallback animationCallback) { if (mValueAnimator.isRunning()) { - // Avoid AnimationEnd Callback. - mEndCallback = null; mValueAnimator.cancel(); } - mEndCallback = endCallback; + mAnimationCallback = animationCallback; // If the current and sent specs don't match, update the sent spec. synchronized (mLock) { final boolean changed = !mSentMagnificationSpec.equals(spec); if (changed) { - if (mEndCallback != null) { + if (mAnimationCallback != null) { animateMagnificationSpecLocked(spec); } else { setMagnificationSpecLocked(spec); } } else { - sendEndCallbackMainThread(); + sendEndCallbackMainThread(true); } } } - private void sendEndCallbackMainThread() { - if (mEndCallback != null) { - mEndCallback.run(); - mEndCallback = null; + private void sendEndCallbackMainThread(boolean success) { + if (mAnimationCallback != null) { + if (DEBUG) { + Slog.d(LOG_TAG, "sendEndCallbackMainThread: " + success); + } + mAnimationCallback.onResult(success); + mAnimationCallback = null; } } @@ -1337,17 +1341,16 @@ public class FullScreenMagnificationController { @Override public void onAnimationStart(Animator animation) { - } @Override public void onAnimationEnd(Animator animation) { - sendEndCallbackMainThread(); + sendEndCallbackMainThread(true); } @Override public void onAnimationCancel(Animator animation) { - + sendEndCallbackMainThread(false); } @Override @@ -1481,7 +1484,7 @@ public class FullScreenMagnificationController { } @Nullable - private static Runnable transformToStubRunnable(boolean animate) { - return animate ? STUB_RUNNABLE : null; + private static MagnificationAnimationCallback transformToStubCallback(boolean animate) { + return animate ? STUB_ANIMATION_CALLBACK : null; } } diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java index 65ac7844ec2b..d92706d2dd19 100644 --- a/services/core/java/com/android/server/BatteryService.java +++ b/services/core/java/com/android/server/BatteryService.java @@ -39,6 +39,7 @@ import android.os.BatteryManagerInternal; import android.os.BatteryProperty; import android.os.BatteryStats; import android.os.Binder; +import android.os.Build; import android.os.Bundle; import android.os.DropBoxManager; import android.os.FileUtils; @@ -59,6 +60,7 @@ import android.os.UEventObserver; import android.os.UserHandle; import android.provider.Settings; import android.service.battery.BatteryServiceDumpProto; +import android.sysprop.PowerProperties; import android.util.EventLog; import android.util.MutableInt; import android.util.Slog; @@ -182,6 +184,7 @@ public final class BatteryService extends SystemService { private int mChargeStartLevel; private boolean mUpdatesStopped; + private boolean mBatteryInputSuspended; private Led mLed; @@ -234,6 +237,8 @@ public final class BatteryService extends SystemService { invalidChargerObserver.startObserving( "DEVPATH=/devices/virtual/switch/invalid_charger"); } + + mBatteryInputSuspended = PowerProperties.battery_input_suspended().orElse(false); } @Override @@ -876,6 +881,10 @@ public final class BatteryService extends SystemService { pw.println(" reset [-f]"); pw.println(" Unfreeze battery state, returning to current hardware values."); pw.println(" -f: force a battery change broadcast be sent, prints new sequence."); + if (Build.IS_DEBUGGABLE) { + pw.println(" disable_charge"); + pw.println(" Suspend charging even if plugged in. "); + } } static final int OPTION_FORCE_UPDATE = 1<<0; @@ -997,6 +1006,20 @@ public final class BatteryService extends SystemService { } finally { Binder.restoreCallingIdentity(ident); } + if (mBatteryInputSuspended) { + PowerProperties.battery_input_suspended(false); + mBatteryInputSuspended = false; + } + } break; + case "suspend_input": { + if (!Build.IS_DEBUGGABLE) { + throw new SecurityException( + "battery suspend_input is only supported on debuggable builds"); + } + getContext().enforceCallingOrSelfPermission( + android.Manifest.permission.DEVICE_POWER, null); + PowerProperties.battery_input_suspended(true); + mBatteryInputSuspended = true; } break; default: return shell.handleDefaultCommands(cmd); diff --git a/services/core/java/com/android/server/NetworkScorerAppManager.java b/services/core/java/com/android/server/NetworkScorerAppManager.java index 3bcb36fd0e00..4de40755419f 100644 --- a/services/core/java/com/android/server/NetworkScorerAppManager.java +++ b/services/core/java/com/android/server/NetworkScorerAppManager.java @@ -19,6 +19,7 @@ package com.android.server; import android.Manifest.permission; import android.annotation.Nullable; import android.content.ComponentName; +import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.PermissionChecker; @@ -404,7 +405,8 @@ public class NetworkScorerAppManager { } public int getSecureInt(Context context, String name, int defaultValue) { - return Settings.Secure.getInt(context.getContentResolver(), name, defaultValue); + final ContentResolver cr = context.getContentResolver(); + return Settings.Secure.getIntForUser(cr, name, defaultValue, cr.getUserId()); } } } diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java index 27c5d4a53956..eb18da2d2e13 100644 --- a/services/core/java/com/android/server/StorageManagerService.java +++ b/services/core/java/com/android/server/StorageManagerService.java @@ -4687,14 +4687,19 @@ class StorageManagerService extends IStorageManager.Stub } } - public void onAppOpsChanged(int code, int uid, @Nullable String packageName, int mode) { + public void onAppOpsChanged(int code, int uid, @Nullable String packageName, int mode, + int previousMode) { final long token = Binder.clearCallingIdentity(); try { // When using FUSE, we may need to kill the app if the op changes switch(code) { case OP_REQUEST_INSTALL_PACKAGES: - // Always kill regardless of op change, to remount apps /storage - killAppForOpChange(code, uid); + if (previousMode == MODE_ALLOWED || mode == MODE_ALLOWED) { + // If we transition to/from MODE_ALLOWED, kill the app to make + // sure it has the correct view of /storage. Changing between + // MODE_DEFAULT / MODE_ERRORED is a no-op + killAppForOpChange(code, uid); + } return; case OP_MANAGE_EXTERNAL_STORAGE: if (mode != MODE_ALLOWED) { diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index 343e05d982fd..c441bd60f784 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -768,9 +768,7 @@ public final class ActiveServices { FrameworkStatsLog.write(FrameworkStatsLog.SERVICE_STATE_CHANGED, r.appInfo.uid, r.name.getPackageName(), r.name.getClassName(), FrameworkStatsLog.SERVICE_STATE_CHANGED__STATE__START); - synchronized (r.stats.getBatteryStats()) { - r.stats.startRunningLocked(); - } + mAm.mBatteryStatsService.noteServiceStartRunning(r.stats); String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false); if (error != null) { return new ComponentName("!!", error); @@ -809,9 +807,7 @@ public final class ActiveServices { FrameworkStatsLog.write(FrameworkStatsLog.SERVICE_STATE_CHANGED, service.appInfo.uid, service.name.getPackageName(), service.name.getClassName(), FrameworkStatsLog.SERVICE_STATE_CHANGED__STATE__STOP); - synchronized (service.stats.getBatteryStats()) { - service.stats.stopRunningLocked(); - } + mAm.mBatteryStatsService.noteServiceStopRunning(service.stats); service.startRequested = false; if (service.tracker != null) { service.tracker.setStarted(false, mAm.mProcessStats.getMemFactorLocked(), @@ -970,9 +966,7 @@ public final class ActiveServices { FrameworkStatsLog.write(FrameworkStatsLog.SERVICE_STATE_CHANGED, r.appInfo.uid, r.name.getPackageName(), r.name.getClassName(), FrameworkStatsLog.SERVICE_STATE_CHANGED__STATE__STOP); - synchronized (r.stats.getBatteryStats()) { - r.stats.stopRunningLocked(); - } + mAm.mBatteryStatsService.noteServiceStopRunning(r.stats); r.startRequested = false; if (r.tracker != null) { r.tracker.setStarted(false, mAm.mProcessStats.getMemFactorLocked(), @@ -2518,7 +2512,8 @@ public final class ActiveServices { synchronized (stats) { ss = stats.getServiceStatsLocked( sInfo.applicationInfo.uid, name.getPackageName(), - name.getClassName()); + name.getClassName(), SystemClock.elapsedRealtime(), + SystemClock.uptimeMillis()); } r = new ServiceRecord(mAm, ss, className, name, definingPackageName, definingUid, filter, sInfo, callingFromFg, res); @@ -3056,9 +3051,7 @@ public final class ActiveServices { } FrameworkStatsLog.write(FrameworkStatsLog.SERVICE_LAUNCH_REPORTED, r.appInfo.uid, r.name.getPackageName(), r.name.getClassName()); - synchronized (r.stats.getBatteryStats()) { - r.stats.startLaunchedLocked(); - } + mAm.mBatteryStatsService.noteServiceStartLaunch(r.stats); mAm.notifyPackageUse(r.serviceInfo.packageName, PackageManager.NOTIFY_PACKAGE_USE_SERVICE); app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE); @@ -3402,9 +3395,7 @@ public final class ActiveServices { smap.mDelayedStartList.remove(r); if (r.app != null) { - synchronized (r.stats.getBatteryStats()) { - r.stats.stopLaunchedLocked(); - } + mAm.mBatteryStatsService.noteServiceStopLaunch(r.stats); r.app.stopService(r); r.app.updateBoundClientUids(); if (r.whitelistManager) { @@ -3940,9 +3931,7 @@ public final class ActiveServices { // Clear app state from services. for (int i = app.numberOfRunningServices() - 1; i >= 0; i--) { ServiceRecord sr = app.getRunningServiceAt(i); - synchronized (sr.stats.getBatteryStats()) { - sr.stats.stopLaunchedLocked(); - } + mAm.mBatteryStatsService.noteServiceStopLaunch(sr.stats); if (sr.app != app && sr.app != null && !sr.app.isPersistent()) { sr.app.stopService(sr); sr.app.updateBoundClientUids(); diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index a5d2011483bc..7e6649660aa9 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -133,7 +133,6 @@ import static com.android.server.wm.ActivityTaskManagerService.DUMP_STARTER_CMD; import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_NONE; import static com.android.server.wm.ActivityTaskManagerService.relaunchReasonToString; - import android.Manifest; import android.Manifest.permission; import android.annotation.BroadcastBehavior; @@ -143,8 +142,8 @@ import android.annotation.UserIdInt; import android.app.Activity; import android.app.ActivityManager; import android.app.ActivityManager.RunningTaskInfo; -import android.app.ActivityManager.StackInfo; import android.app.ActivityManagerInternal; +import android.app.ActivityTaskManager.RootTaskInfo; import android.app.ActivityThread; import android.app.AppGlobals; import android.app.AppOpsManager; @@ -342,7 +341,6 @@ import com.android.server.PackageWatchdog; import com.android.server.ServiceThread; import com.android.server.SystemConfig; import com.android.server.SystemService; -import com.android.server.SystemService.TargetUser; import com.android.server.SystemServiceManager; import com.android.server.ThreadPriorityBooster; import com.android.server.UserspaceRebootLogger; @@ -2835,14 +2833,16 @@ public class ActivityManagerService extends IActivityManager.Stub } final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); - synchronized(bstats) { - synchronized(mPidsSelfLocked) { - if (haveNewCpuStats) { - if (bstats.startAddingCpuLocked()) { - int totalUTime = 0; - int totalSTime = 0; - final int N = mProcessCpuTracker.countStats(); - for (int i=0; i<N; i++) { + synchronized (bstats) { + if (haveNewCpuStats) { + if (bstats.startAddingCpuLocked()) { + int totalUTime = 0; + int totalSTime = 0; + final int statsCount = mProcessCpuTracker.countStats(); + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + synchronized (mPidsSelfLocked) { + for (int i = 0; i < statsCount; i++) { ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); if (!st.working) { continue; @@ -2854,7 +2854,8 @@ public class ActivityManagerService extends IActivityManager.Stub BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; if (ps == null || !ps.isActive()) { pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( - pr.info.uid, pr.processName); + pr.info.uid, pr.processName, + elapsedRealtime, uptime); } ps.addCpuTimeLocked(st.rel_utime, st.rel_stime); pr.curCpuTime += st.rel_utime + st.rel_stime; @@ -2865,20 +2866,22 @@ public class ActivityManagerService extends IActivityManager.Stub BatteryStatsImpl.Uid.Proc ps = st.batteryStats; if (ps == null || !ps.isActive()) { st.batteryStats = ps = bstats.getProcessStatsLocked( - bstats.mapUid(st.uid), st.name); + bstats.mapUid(st.uid), st.name, + elapsedRealtime, uptime); } ps.addCpuTimeLocked(st.rel_utime, st.rel_stime); } } - final int userTime = mProcessCpuTracker.getLastUserTime(); - final int systemTime = mProcessCpuTracker.getLastSystemTime(); - final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime(); - final int irqTime = mProcessCpuTracker.getLastIrqTime(); - final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime(); - final int idleTime = mProcessCpuTracker.getLastIdleTime(); - bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime, - systemTime, iowaitTime, irqTime, softIrqTime, idleTime); } + + final int userTime = mProcessCpuTracker.getLastUserTime(); + final int systemTime = mProcessCpuTracker.getLastSystemTime(); + final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime(); + final int irqTime = mProcessCpuTracker.getLastIrqTime(); + final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime(); + final int idleTime = mProcessCpuTracker.getLastIdleTime(); + bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime, + systemTime, iowaitTime, irqTime, softIrqTime, idleTime); } } @@ -3076,18 +3079,8 @@ public class ActivityManagerService extends IActivityManager.Stub Slog.d(TAG_SWITCH, "updateBatteryStats: comp=" + activity + "res=" + resumed); } - final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); - FrameworkStatsLog.write(FrameworkStatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED, - uid, activity.getPackageName(), activity.getShortClassName(), - resumed ? FrameworkStatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED__STATE__FOREGROUND : - FrameworkStatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED__STATE__BACKGROUND); - synchronized (stats) { - if (resumed) { - stats.noteActivityResumedLocked(uid); - } else { - stats.noteActivityPausedLocked(uid); - } - } + mBatteryStatsService.updateBatteryStatsOnActivityUsage(activity.getPackageName(), + activity.getShortClassName(), uid, userId, resumed); } /** @@ -3626,10 +3619,7 @@ public class ActivityManagerService extends IActivityManager.Stub } } - BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); - synchronized (stats) { - stats.noteProcessDiedLocked(app.info.uid, pid); - } + mBatteryStatsService.noteProcessDied(app.info.uid, pid); if (!app.killed) { if (!fromBinderDied) { @@ -6418,8 +6408,8 @@ public class ActivityManagerService extends IActivityManager.Stub } @Override - public List<StackInfo> getAllStackInfos() { - return mActivityTaskManager.getAllStackInfos(); + public List<RootTaskInfo> getAllRootTaskInfos() { + return mActivityTaskManager.getAllRootTaskInfos(); } @Override @@ -7300,53 +7290,6 @@ public class ActivityManagerService extends IActivityManager.Stub return uidRecord != null && !uidRecord.setIdle; } - /** - * Change the sched policy cgroup of a thread. - * - * <p>It is intended to be used in jni call of {@link Process#setThreadPriority(int, int)}. - * When a process is changing the priority of its threads, the sched policy of that - * thread may need to be changed accordingly - if the priority is changed to below - * or equal to {@link android.os.Process#THREAD_PRIORITY_BACKGROUND} or raising from it. - * However, because of the limitation of sepolicy, the thread priority change will - * fail for some processes. To solve it, we add this binder call in Activity Manager, - * so that the jni call of {@link Process#setThreadPriority(int, int)} could use it. - * - * @param tid tid of the thread to be changed. - * @param group The sched policy group to be changed to. - * - * @throws IllegalArgumentException if group is invalid. - * @throws SecurityException if no permission. - * - * @return Returns {@code true} if the sched policy is changed successfully; - * {@code false} otherwise. - */ - @Override - public boolean setSchedPolicyCgroup(final int tid, final int group) { - final int pid = Binder.getCallingPid(); - final int tgid = Process.getThreadGroupLeader(tid); - final int pgroup = Process.getProcessGroup(pid); - - // tid is not in the thread group of caller - if (pid != tgid) { - return false; - } - - // sched group is higher than its main process - if (group > pgroup) { - return false; - } - - try { - Process.setThreadGroup(tid, group); - return true; - } catch (IllegalArgumentException e) { - Slog.w(TAG, "Failed to set thread group, argument invalid:\n" + e); - } catch (SecurityException e) { - Slog.w(TAG, "Failed to set thread group, no permission:\n" + e); - } - return false; - } - @Override public void setPersistentVrThread(int tid) { mActivityTaskManager.setPersistentVrThread(tid); @@ -14582,10 +14525,7 @@ public class ActivityManagerService extends IActivityManager.Stub timeFormatPreferenceMsgValue, 0); mHandler.sendMessage(updateTimePreferenceMsg); } - BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); - synchronized (stats) { - stats.noteCurrentTimeChangedLocked(); - } + mBatteryStatsService.noteCurrentTimeChanged(); break; case Intent.ACTION_CLEAR_DNS_CACHE: mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); @@ -15385,8 +15325,8 @@ public class ActivityManagerService extends IActivityManager.Stub } @Override - public StackInfo getFocusedStackInfo() throws RemoteException { - return mActivityTaskManager.getFocusedStackInfo(); + public RootTaskInfo getFocusedRootTaskInfo() throws RemoteException { + return mActivityTaskManager.getFocusedRootTaskInfo(); } @Override @@ -15957,7 +15897,6 @@ public class ActivityManagerService extends IActivityManager.Stub updateCpuStatsNow(); synchronized (this) { - BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); boolean doCpuKills = true; if (mLastPowerCheckUptime == 0) { doCpuKills = false; @@ -16004,10 +15943,8 @@ public class ActivityManagerService extends IActivityManager.Stub cpuLimit = mConstants.POWER_CHECK_MAX_CPU_4; } if (((cputimeUsed * 100) / uptimeSince) >= cpuLimit) { - synchronized (stats) { - stats.reportExcessiveCpuLocked(app.info.uid, app.processName, + mBatteryStatsService.reportExcessiveCpu(app.info.uid, app.processName, uptimeSince, cputimeUsed); - } app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince + " dur=" + checkDur + " limit=" + cpuLimit, ApplicationExitInfo.REASON_EXCESSIVE_RESOURCE_USAGE, @@ -17513,19 +17450,7 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public void updateForegroundTimeIfOnBattery( String packageName, int uid, long cpuTimeDiff) { - synchronized (ActivityManagerService.this) { - if (!mBatteryStatsService.isOnBattery()) { - return; - } - final BatteryStatsImpl bsi = mBatteryStatsService.getActiveStatistics(); - synchronized (bsi) { - final BatteryStatsImpl.Uid.Proc ps = - bsi.getProcessStatsLocked(uid, packageName); - if (ps != null) { - ps.addForegroundTimeLocked(cpuTimeDiff); - } - } - } + mBatteryStatsService.updateForegroundTimeIfOnBattery(packageName, uid, cpuTimeDiff); } @Override diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java index a512cca7bac4..9ce8b11a7351 100644 --- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java +++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java @@ -28,6 +28,7 @@ import static android.view.Display.INVALID_DISPLAY; import android.app.ActivityManager; import android.app.ActivityOptions; import android.app.ActivityTaskManager; +import android.app.ActivityTaskManager.RootTaskInfo; import android.app.AppGlobals; import android.app.BroadcastOptions; import android.app.IActivityController; @@ -2586,7 +2587,7 @@ final class ActivityManagerShellCommand extends ShellCommand { case "list": return runStackList(pw); case "info": - return runStackInfo(pw); + return runRootTaskInfo(pw); case "move-top-activity-to-pinned-stack": return runMoveTopActivityToPinnedStack(pw); case "remove": @@ -2668,17 +2669,17 @@ final class ActivityManagerShellCommand extends ShellCommand { } int runStackList(PrintWriter pw) throws RemoteException { - List<ActivityManager.StackInfo> stacks = mTaskInterface.getAllStackInfos(); - for (ActivityManager.StackInfo info : stacks) { + List<RootTaskInfo> tasks = mTaskInterface.getAllRootTaskInfos(); + for (RootTaskInfo info : tasks) { pw.println(info); } return 0; } - int runStackInfo(PrintWriter pw) throws RemoteException { + int runRootTaskInfo(PrintWriter pw) throws RemoteException { int windowingMode = Integer.parseInt(getNextArgRequired()); int activityType = Integer.parseInt(getNextArgRequired()); - ActivityManager.StackInfo info = mTaskInterface.getStackInfo(windowingMode, activityType); + RootTaskInfo info = mTaskInterface.getRootTaskInfo(windowingMode, activityType); pw.println(info); return 0; } diff --git a/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java b/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java index 39f79ca2f13b..692b3f11a5f8 100644 --- a/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java +++ b/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java @@ -376,7 +376,8 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync { for (int uid : uidsToRemove) { FrameworkStatsLog.write(FrameworkStatsLog.ISOLATED_UID_CHANGED, -1, uid, FrameworkStatsLog.ISOLATED_UID_CHANGED__EVENT__REMOVED); - mStats.removeIsolatedUidLocked(uid); + mStats.removeIsolatedUidLocked(uid, SystemClock.elapsedRealtime(), + SystemClock.uptimeMillis()); } mStats.clearPendingRemovedUids(); } @@ -473,11 +474,15 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync { final WifiActivityEnergyInfo wifiInfo = awaitControllerInfo(wifiReceiver); final BluetoothActivityEnergyInfo bluetoothInfo = awaitControllerInfo(bluetoothReceiver); final ModemActivityInfo modemInfo = awaitControllerInfo(modemReceiver); + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + final long elapsedRealtimeUs = elapsedRealtime * 1000; + final long uptimeUs = uptime * 1000; synchronized (mStats) { mStats.addHistoryEventLocked( - SystemClock.elapsedRealtime(), - SystemClock.uptimeMillis(), + elapsedRealtime, + uptime, BatteryStats.HistoryItem.EVENT_COLLECT_EXTERNAL_STATS, reason, 0); @@ -490,17 +495,17 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync { } if ((updateFlags & UPDATE_ALL) != 0) { - mStats.updateKernelWakelocksLocked(); - mStats.updateKernelMemoryBandwidthLocked(); + mStats.updateKernelWakelocksLocked(elapsedRealtimeUs); + mStats.updateKernelMemoryBandwidthLocked(elapsedRealtimeUs); } if ((updateFlags & UPDATE_RPM) != 0) { - mStats.updateRpmStatsLocked(); + mStats.updateRpmStatsLocked(elapsedRealtimeUs); } if (bluetoothInfo != null) { if (bluetoothInfo.isValid()) { - mStats.updateBluetoothStateLocked(bluetoothInfo); + mStats.updateBluetoothStateLocked(bluetoothInfo, elapsedRealtime, uptime); } else { Slog.w(TAG, "bluetooth info is invalid: " + bluetoothInfo); } @@ -512,7 +517,7 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync { if (wifiInfo != null) { if (wifiInfo.isValid()) { - mStats.updateWifiState(extractDeltaLocked(wifiInfo)); + mStats.updateWifiState(extractDeltaLocked(wifiInfo), elapsedRealtime, uptime); } else { Slog.w(TAG, "wifi info is invalid: " + wifiInfo); } @@ -520,7 +525,7 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync { if (modemInfo != null) { if (modemInfo.isValid()) { - mStats.updateMobileRadioState(modemInfo); + mStats.updateMobileRadioState(modemInfo, elapsedRealtime, uptime); } else { Slog.w(TAG, "modem info is invalid: " + modemInfo); } diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java index d72998ba95f1..f42753287e35 100644 --- a/services/core/java/com/android/server/am/BatteryStatsService.java +++ b/services/core/java/com/android/server/am/BatteryStatsService.java @@ -25,6 +25,7 @@ import android.os.BatteryStats; import android.os.BatteryStatsInternal; import android.os.Binder; import android.os.Handler; +import android.os.HandlerThread; import android.os.IBinder; import android.os.Parcel; import android.os.ParcelFileDescriptor; @@ -62,7 +63,9 @@ import com.android.internal.os.RpmStats; import com.android.internal.util.DumpUtils; import com.android.internal.util.FrameworkStatsLog; import com.android.internal.util.ParseUtils; +import com.android.internal.util.function.pooled.PooledLambda; import com.android.server.LocalServices; +import com.android.server.Watchdog; import java.io.File; import java.io.FileDescriptor; @@ -76,6 +79,7 @@ import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.Collection; import java.util.List; +import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; @@ -86,7 +90,8 @@ import java.util.concurrent.Future; public final class BatteryStatsService extends IBatteryStats.Stub implements PowerManagerInternal.LowPowerModeListener, BatteryStatsImpl.PlatformIdleStateCallback, - BatteryStatsImpl.RailEnergyDataCallback { + BatteryStatsImpl.RailEnergyDataCallback, + Watchdog.Monitor { static final String TAG = "BatteryStatsService"; static final boolean DBG = false; @@ -110,6 +115,10 @@ public final class BatteryStatsService extends IBatteryStats.Stub private CharBuffer mUtf16BufferStat = CharBuffer.allocate(MAX_LOW_POWER_STATS_SIZE); private static final int MAX_LOW_POWER_STATS_SIZE = 4096; + private final HandlerThread mHandlerThread; + private final Handler mHandler; + private final Object mLock = new Object(); + /** * Replaces the information in the given rpmStats with up-to-date information. */ @@ -190,6 +199,9 @@ public final class BatteryStatsService extends IBatteryStats.Stub return (umi != null) ? umi.getUserIds() : null; } }; + mHandlerThread = new HandlerThread("batterystats-handler"); + mHandlerThread.start(); + mHandler = new Handler(mHandlerThread.getLooper()); mStats = new BatteryStatsImpl(systemDir, handler, this, this, mUserManagerUserInfoProvider); mWorker = new BatteryExternalStatsWorker(context, mStats); @@ -206,6 +218,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub public void systemServicesReady() { mStats.systemServicesReady(mContext); + Watchdog.getInstance().addMonitor(this); } private final class LocalService extends BatteryStatsInternal { @@ -228,8 +241,20 @@ public final class BatteryStatsService extends IBatteryStats.Stub @Override public void noteBinderCallStats(int workSourceUid, long incrementatCallCount, Collection<BinderCallsStats.CallStat> callStats, int[] binderThreadNativeTids) { - mStats.noteBinderCallStats(workSourceUid, incrementatCallCount, callStats, - binderThreadNativeTids); + synchronized (BatteryStatsService.this.mLock) { + mHandler.sendMessage(PooledLambda.obtainMessage( + mStats::noteBinderCallStats, workSourceUid, incrementatCallCount, + callStats, binderThreadNativeTids, + SystemClock.elapsedRealtime(), SystemClock.uptimeMillis())); + } + } + } + + @Override + public void monitor() { + synchronized (mLock) { + } + synchronized (mStats) { } } @@ -250,6 +275,19 @@ public final class BatteryStatsService extends IBatteryStats.Stub awaitUninterruptibly(mWorker.scheduleSync(reason, flags)); } + private void awaitCompletion() { + synchronized (mLock) { + final CountDownLatch latch = new CountDownLatch(1); + mHandler.post(() -> { + latch.countDown(); + }); + try { + latch.await(); + } catch (InterruptedException e) { + } + } + } + /** * At the time when the constructor runs, the power manager has not yet been * initialized. So we initialize the low power observer later. @@ -259,8 +297,8 @@ public final class BatteryStatsService extends IBatteryStats.Stub powerMgr.registerLowPowerModeObserver(this); synchronized (mStats) { mStats.notePowerSaveModeLocked( - powerMgr.getLowPowerState(ServiceType.BATTERY_STATS) - .batterySaverEnabled); + powerMgr.getLowPowerState(ServiceType.BATTERY_STATS).batterySaverEnabled, + SystemClock.elapsedRealtime(), SystemClock.uptimeMillis()); } (new WakeupReasonThread()).start(); } @@ -268,6 +306,9 @@ public final class BatteryStatsService extends IBatteryStats.Stub public void shutdown() { Slog.w("BatteryStats", "Writing battery stats before shutdown..."); + // Drain the handler queue to make sure we've handled all pending works. + awaitCompletion(); + syncStats("shutdown", BatteryExternalStatsWorker.UPDATE_ALL); synchronized (mStats) { @@ -293,9 +334,16 @@ public final class BatteryStatsService extends IBatteryStats.Stub } @Override - public void onLowPowerModeChanged(PowerSaveState result) { - synchronized (mStats) { - mStats.notePowerSaveModeLocked(result.batterySaverEnabled); + public void onLowPowerModeChanged(final PowerSaveState result) { + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.notePowerSaveModeLocked(result.batterySaverEnabled, + elapsedRealtime, uptime); + } + }); } } @@ -313,7 +361,12 @@ public final class BatteryStatsService extends IBatteryStats.Stub * object to update with the latest info, then write to disk. */ public void scheduleWriteToDisk() { - mWorker.scheduleWrite(); + synchronized (mLock) { + // We still schedule it on the handler so we'll have all existing pending works done. + mHandler.post(() -> { + mWorker.scheduleWrite(); + }); + } } // These are for direct use by the activity manager... @@ -321,70 +374,124 @@ public final class BatteryStatsService extends IBatteryStats.Stub /** * Remove a UID from the BatteryStats and BatteryStats' external dependencies. */ - void removeUid(int uid) { - synchronized (mStats) { - mStats.removeUidStatsLocked(uid); + void removeUid(final int uid) { + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.removeUidStatsLocked(uid, elapsedRealtime); + } + }); } } - void onCleanupUser(int userId) { - synchronized (mStats) { - mStats.onCleanupUserLocked(userId); + void onCleanupUser(final int userId) { + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.onCleanupUserLocked(userId, elapsedRealtime); + } + }); } } - void onUserRemoved(int userId) { - synchronized (mStats) { - mStats.onUserRemovedLocked(userId); + void onUserRemoved(final int userId) { + synchronized (mLock) { + mHandler.post(() -> { + synchronized (mStats) { + mStats.onUserRemovedLocked(userId); + } + }); } } - void addIsolatedUid(int isolatedUid, int appUid) { - synchronized (mStats) { - mStats.addIsolatedUidLocked(isolatedUid, appUid); + void addIsolatedUid(final int isolatedUid, final int appUid) { + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.addIsolatedUidLocked(isolatedUid, appUid, elapsedRealtime, uptime); + } + }); } } - void removeIsolatedUid(int isolatedUid, int appUid) { - synchronized (mStats) { - mStats.scheduleRemoveIsolatedUidLocked(isolatedUid, appUid); + void removeIsolatedUid(final int isolatedUid, final int appUid) { + synchronized (mLock) { + mHandler.post(() -> { + synchronized (mStats) { + mStats.scheduleRemoveIsolatedUidLocked(isolatedUid, appUid); + } + }); } } - void noteProcessStart(String name, int uid) { - synchronized (mStats) { - mStats.noteProcessStartLocked(name, uid); - FrameworkStatsLog.write(FrameworkStatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED, uid, name, - FrameworkStatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED__STATE__STARTED); + void noteProcessStart(final String name, final int uid) { + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteProcessStartLocked(name, uid, elapsedRealtime, uptime); + } + }); } + FrameworkStatsLog.write(FrameworkStatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED, uid, name, + FrameworkStatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED__STATE__STARTED); } void noteProcessCrash(String name, int uid) { - synchronized (mStats) { - mStats.noteProcessCrashLocked(name, uid); - FrameworkStatsLog.write(FrameworkStatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED, uid, name, - FrameworkStatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED__STATE__CRASHED); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteProcessCrashLocked(name, uid, elapsedRealtime, uptime); + } + }); } + FrameworkStatsLog.write(FrameworkStatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED, uid, name, + FrameworkStatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED__STATE__CRASHED); } void noteProcessAnr(String name, int uid) { - synchronized (mStats) { - mStats.noteProcessAnrLocked(name, uid); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteProcessAnrLocked(name, uid, elapsedRealtime, uptime); + } + }); } } void noteProcessFinish(String name, int uid) { - synchronized (mStats) { - mStats.noteProcessFinishLocked(name, uid); - FrameworkStatsLog.write(FrameworkStatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED, uid, name, - FrameworkStatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED__STATE__FINISHED); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteProcessFinishLocked(name, uid, elapsedRealtime, uptime); + } + }); } + FrameworkStatsLog.write(FrameworkStatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED, uid, name, + FrameworkStatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED__STATE__FINISHED); } /** @param state Process state from ActivityManager.java. */ void noteUidProcessState(int uid, int state) { - synchronized (mStats) { - mStats.noteUidProcessStateLocked(uid, state); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteUidProcessStateLocked(uid, state, elapsedRealtime, uptime); + } + }); } } @@ -396,6 +503,9 @@ public final class BatteryStatsService extends IBatteryStats.Stub //Slog.i("foo", "SENDING BATTERY INFO:"); //mStats.dumpLocked(new LogPrinter(Log.INFO, "foo", Log.LOG_ID_SYSTEM)); Parcel out = Parcel.obtain(); + // Drain the handler queue to make sure we've handled all pending works, so we'll get + // an accurate stats. + awaitCompletion(); syncStats("get-stats", BatteryExternalStatsWorker.UPDATE_ALL); synchronized (mStats) { mStats.writeToParcel(out, 0); @@ -411,6 +521,9 @@ public final class BatteryStatsService extends IBatteryStats.Stub //Slog.i("foo", "SENDING BATTERY INFO:"); //mStats.dumpLocked(new LogPrinter(Log.INFO, "foo", Log.LOG_ID_SYSTEM)); Parcel out = Parcel.obtain(); + // Drain the handler queue to make sure we've handled all pending works, so we'll get + // an accurate stats. + awaitCompletion(); syncStats("get-stats", BatteryExternalStatsWorker.UPDATE_ALL); synchronized (mStats) { mStats.writeToParcel(out, 0); @@ -446,579 +559,1015 @@ public final class BatteryStatsService extends IBatteryStats.Stub } } - public void noteEvent(int code, String name, int uid) { + public void noteEvent(final int code, final String name, final int uid) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteEventLocked(code, name, uid); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteEventLocked(code, name, uid, elapsedRealtime, uptime); + } + }); } } - public void noteSyncStart(String name, int uid) { + public void noteSyncStart(final String name, final int uid) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteSyncStartLocked(name, uid); - FrameworkStatsLog.write_non_chained(FrameworkStatsLog.SYNC_STATE_CHANGED, uid, null, - name, FrameworkStatsLog.SYNC_STATE_CHANGED__STATE__ON); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteSyncStartLocked(name, uid, elapsedRealtime, uptime); + } + FrameworkStatsLog.write_non_chained(FrameworkStatsLog.SYNC_STATE_CHANGED, uid, null, + name, FrameworkStatsLog.SYNC_STATE_CHANGED__STATE__ON); + }); } } - public void noteSyncFinish(String name, int uid) { + public void noteSyncFinish(final String name, final int uid) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteSyncFinishLocked(name, uid); - FrameworkStatsLog.write_non_chained(FrameworkStatsLog.SYNC_STATE_CHANGED, uid, null, - name, FrameworkStatsLog.SYNC_STATE_CHANGED__STATE__OFF); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteSyncFinishLocked(name, uid, elapsedRealtime, uptime); + } + FrameworkStatsLog.write_non_chained(FrameworkStatsLog.SYNC_STATE_CHANGED, uid, null, + name, FrameworkStatsLog.SYNC_STATE_CHANGED__STATE__OFF); + }); } } /** A scheduled job was started. */ - public void noteJobStart(String name, int uid) { + public void noteJobStart(final String name, final int uid) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteJobStartLocked(name, uid); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteJobStartLocked(name, uid, elapsedRealtime, uptime); + } + }); } } /** A scheduled job was finished. */ - public void noteJobFinish(String name, int uid, int stopReason) { + public void noteJobFinish(final String name, final int uid, final int stopReason) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteJobFinishLocked(name, uid, stopReason); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteJobFinishLocked(name, uid, stopReason, elapsedRealtime, uptime); + } + }); } } - void noteJobsDeferred(int uid, int numDeferred, long sinceLast) { + void noteJobsDeferred(final int uid, final int numDeferred, final long sinceLast) { // No need to enforce calling permission, as it is called from an internal interface - synchronized (mStats) { - mStats.noteJobsDeferredLocked(uid, numDeferred, sinceLast); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteJobsDeferredLocked(uid, numDeferred, sinceLast, + elapsedRealtime, uptime); + } + }); } } - public void noteWakupAlarm(String name, int uid, WorkSource workSource, String tag) { + public void noteWakupAlarm(final String name, final int uid, final WorkSource workSource, + final String tag) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteWakupAlarmLocked(name, uid, workSource, tag); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteWakupAlarmLocked(name, uid, workSource, tag, + elapsedRealtime, uptime); + } + }); } } - public void noteAlarmStart(String name, WorkSource workSource, int uid) { + public void noteAlarmStart(final String name, final WorkSource workSource, final int uid) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteAlarmStartLocked(name, workSource, uid); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteAlarmStartLocked(name, workSource, uid, elapsedRealtime, uptime); + } + }); } } - public void noteAlarmFinish(String name, WorkSource workSource, int uid) { + public void noteAlarmFinish(final String name, final WorkSource workSource, final int uid) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteAlarmFinishLocked(name, workSource, uid); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteAlarmFinishLocked(name, workSource, uid, elapsedRealtime, uptime); + } + }); } } - public void noteStartWakelock(int uid, int pid, String name, String historyName, int type, - boolean unimportantForLogging) { + public void noteStartWakelock(final int uid, final int pid, final String name, + final String historyName, final int type, final boolean unimportantForLogging) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteStartWakeLocked(uid, pid, null, name, historyName, type, - unimportantForLogging, SystemClock.elapsedRealtime(), - SystemClock.uptimeMillis()); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteStartWakeLocked(uid, pid, null, name, historyName, type, + unimportantForLogging, elapsedRealtime, uptime); + } + }); } } - public void noteStopWakelock(int uid, int pid, String name, String historyName, int type) { + public void noteStopWakelock(final int uid, final int pid, final String name, + final String historyName, final int type) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteStopWakeLocked(uid, pid, null, name, historyName, type, - SystemClock.elapsedRealtime(), SystemClock.uptimeMillis()); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteStopWakeLocked(uid, pid, null, name, historyName, type, + elapsedRealtime, uptime); + } + }); } } - public void noteStartWakelockFromSource(WorkSource ws, int pid, String name, - String historyName, int type, boolean unimportantForLogging) { + public void noteStartWakelockFromSource(final WorkSource ws, final int pid, final String name, + final String historyName, final int type, final boolean unimportantForLogging) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteStartWakeFromSourceLocked(ws, pid, name, historyName, - type, unimportantForLogging); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteStartWakeFromSourceLocked(ws, pid, name, historyName, + type, unimportantForLogging, elapsedRealtime, uptime); + } + }); } } - public void noteChangeWakelockFromSource(WorkSource ws, int pid, String name, - String historyName, int type, WorkSource newWs, int newPid, String newName, - String newHistoryName, int newType, boolean newUnimportantForLogging) { + public void noteChangeWakelockFromSource(final WorkSource ws, final int pid, final String name, + final String historyName, final int type, final WorkSource newWs, final int newPid, + final String newName, final String newHistoryName, final int newType, + final boolean newUnimportantForLogging) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteChangeWakelockFromSourceLocked(ws, pid, name, historyName, type, - newWs, newPid, newName, newHistoryName, newType, newUnimportantForLogging); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteChangeWakelockFromSourceLocked(ws, pid, name, historyName, type, + newWs, newPid, newName, newHistoryName, newType, + newUnimportantForLogging, elapsedRealtime, uptime); + } + }); } } - public void noteStopWakelockFromSource(WorkSource ws, int pid, String name, String historyName, - int type) { + public void noteStopWakelockFromSource(final WorkSource ws, final int pid, final String name, + final String historyName, final int type) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteStopWakeFromSourceLocked(ws, pid, name, historyName, type); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteStopWakeFromSourceLocked(ws, pid, name, historyName, type, + elapsedRealtime, uptime); + } + }); } } @Override - public void noteLongPartialWakelockStart(String name, String historyName, int uid) { + public void noteLongPartialWakelockStart(final String name, final String historyName, + final int uid) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteLongPartialWakelockStart(name, historyName, uid); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteLongPartialWakelockStart(name, historyName, uid, + elapsedRealtime, uptime); + } + }); } } @Override - public void noteLongPartialWakelockStartFromSource(String name, String historyName, - WorkSource workSource) { + public void noteLongPartialWakelockStartFromSource(final String name, final String historyName, + final WorkSource workSource) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteLongPartialWakelockStartFromSource(name, historyName, workSource); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteLongPartialWakelockStartFromSource(name, historyName, workSource, + elapsedRealtime, uptime); + } + }); } } @Override - public void noteLongPartialWakelockFinish(String name, String historyName, int uid) { + public void noteLongPartialWakelockFinish(final String name, final String historyName, + final int uid) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteLongPartialWakelockFinish(name, historyName, uid); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteLongPartialWakelockFinish(name, historyName, uid, + elapsedRealtime, uptime); + } + }); } } @Override - public void noteLongPartialWakelockFinishFromSource(String name, String historyName, - WorkSource workSource) { + public void noteLongPartialWakelockFinishFromSource(final String name, final String historyName, + final WorkSource workSource) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteLongPartialWakelockFinishFromSource(name, historyName, workSource); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteLongPartialWakelockFinishFromSource(name, historyName, workSource, + elapsedRealtime, uptime); + } + }); } } - public void noteStartSensor(int uid, int sensor) { + public void noteStartSensor(final int uid, final int sensor) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteStartSensorLocked(uid, sensor); - FrameworkStatsLog.write_non_chained(FrameworkStatsLog.SENSOR_STATE_CHANGED, uid, null, - sensor, FrameworkStatsLog.SENSOR_STATE_CHANGED__STATE__ON); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteStartSensorLocked(uid, sensor, elapsedRealtime, uptime); + } + FrameworkStatsLog.write_non_chained(FrameworkStatsLog.SENSOR_STATE_CHANGED, uid, + null, sensor, FrameworkStatsLog.SENSOR_STATE_CHANGED__STATE__ON); + }); } } - public void noteStopSensor(int uid, int sensor) { + public void noteStopSensor(final int uid, final int sensor) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteStopSensorLocked(uid, sensor); - FrameworkStatsLog.write_non_chained(FrameworkStatsLog.SENSOR_STATE_CHANGED, uid, null, - sensor, FrameworkStatsLog.SENSOR_STATE_CHANGED__STATE__OFF); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteStopSensorLocked(uid, sensor, elapsedRealtime, uptime); + } + FrameworkStatsLog.write_non_chained(FrameworkStatsLog.SENSOR_STATE_CHANGED, uid, + null, sensor, FrameworkStatsLog.SENSOR_STATE_CHANGED__STATE__OFF); + }); } } - public void noteVibratorOn(int uid, long durationMillis) { + public void noteVibratorOn(final int uid, final long durationMillis) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteVibratorOnLocked(uid, durationMillis); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteVibratorOnLocked(uid, durationMillis, elapsedRealtime, uptime); + } + }); } } - public void noteVibratorOff(int uid) { + public void noteVibratorOff(final int uid) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteVibratorOffLocked(uid); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteVibratorOffLocked(uid, elapsedRealtime, uptime); + } + }); } } @Override - public void noteGpsChanged(WorkSource oldWs, WorkSource newWs) { + public void noteGpsChanged(final WorkSource oldWs, final WorkSource newWs) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteGpsChangedLocked(oldWs, newWs); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteGpsChangedLocked(oldWs, newWs, elapsedRealtime, uptime); + } + }); } } - public void noteGpsSignalQuality(int signalLevel) { - synchronized (mStats) { - mStats.noteGpsSignalQualityLocked(signalLevel); + public void noteGpsSignalQuality(final int signalLevel) { + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteGpsSignalQualityLocked(signalLevel, elapsedRealtime, uptime); + } + }); } } - public void noteScreenState(int state) { + public void noteScreenState(final int state) { enforceCallingPermission(); - if (DBG) Slog.d(TAG, "begin noteScreenState"); - synchronized (mStats) { - FrameworkStatsLog.write(FrameworkStatsLog.SCREEN_STATE_CHANGED, state); - - mStats.noteScreenStateLocked(state); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + final long currentTime = System.currentTimeMillis(); + mHandler.post(() -> { + if (DBG) Slog.d(TAG, "begin noteScreenState"); + synchronized (mStats) { + mStats.noteScreenStateLocked(state, elapsedRealtime, uptime, currentTime); + } + FrameworkStatsLog.write(FrameworkStatsLog.SCREEN_STATE_CHANGED, state); + if (DBG) Slog.d(TAG, "end noteScreenState"); + }); } - if (DBG) Slog.d(TAG, "end noteScreenState"); } - public void noteScreenBrightness(int brightness) { + public void noteScreenBrightness(final int brightness) { enforceCallingPermission(); - synchronized (mStats) { - FrameworkStatsLog.write(FrameworkStatsLog.SCREEN_BRIGHTNESS_CHANGED, brightness); - mStats.noteScreenBrightnessLocked(brightness); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteScreenBrightnessLocked(brightness, elapsedRealtime, uptime); + } + FrameworkStatsLog.write(FrameworkStatsLog.SCREEN_BRIGHTNESS_CHANGED, brightness); + }); } } - public void noteUserActivity(int uid, int event) { + public void noteUserActivity(final int uid, final int event) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteUserActivityLocked(uid, event); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteUserActivityLocked(uid, event, elapsedRealtime, uptime); + } + }); } } - public void noteWakeUp(String reason, int reasonUid) { + public void noteWakeUp(final String reason, final int reasonUid) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteWakeUpLocked(reason, reasonUid); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteWakeUpLocked(reason, reasonUid, elapsedRealtime, uptime); + } + }); } } - public void noteInteractive(boolean interactive) { + public void noteInteractive(final boolean interactive) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteInteractiveLocked(interactive); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteInteractiveLocked(interactive, elapsedRealtime); + } + }); } } - public void noteConnectivityChanged(int type, String extra) { + public void noteConnectivityChanged(final int type, final String extra) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteConnectivityChangedLocked(type, extra); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteConnectivityChangedLocked(type, extra, elapsedRealtime, uptime); + } + }); } } - public void noteMobileRadioPowerState(int powerState, long timestampNs, int uid) { + public void noteMobileRadioPowerState(final int powerState, final long timestampNs, + final int uid) { enforceCallingPermission(); - final boolean update; - synchronized (mStats) { - update = mStats.noteMobileRadioPowerStateLocked(powerState, timestampNs, uid); - } + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + final boolean update; + synchronized (mStats) { + update = mStats.noteMobileRadioPowerStateLocked(powerState, timestampNs, uid, + elapsedRealtime, uptime); + } - if (update) { - mWorker.scheduleSync("modem-data", BatteryExternalStatsWorker.UPDATE_RADIO); + if (update) { + mWorker.scheduleSync("modem-data", BatteryExternalStatsWorker.UPDATE_RADIO); + } + }); } } public void notePhoneOn() { enforceCallingPermission(); - synchronized (mStats) { - mStats.notePhoneOnLocked(); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.notePhoneOnLocked(elapsedRealtime, uptime); + } + }); } } public void notePhoneOff() { enforceCallingPermission(); - synchronized (mStats) { - mStats.notePhoneOffLocked(); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.notePhoneOffLocked(elapsedRealtime, uptime); + } + }); } } - public void notePhoneSignalStrength(SignalStrength signalStrength) { + public void notePhoneSignalStrength(final SignalStrength signalStrength) { enforceCallingPermission(); - synchronized (mStats) { - mStats.notePhoneSignalStrengthLocked(signalStrength); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.notePhoneSignalStrengthLocked(signalStrength, elapsedRealtime, uptime); + } + }); } } - public void notePhoneDataConnectionState(int dataType, boolean hasData, int serviceType) { + public void notePhoneDataConnectionState(final int dataType, final boolean hasData, + final int serviceType) { enforceCallingPermission(); - synchronized (mStats) { - mStats.notePhoneDataConnectionStateLocked(dataType, hasData, serviceType); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.notePhoneDataConnectionStateLocked(dataType, hasData, serviceType, + elapsedRealtime, uptime); + } + }); } } - public void notePhoneState(int state) { + public void notePhoneState(final int state) { enforceCallingPermission(); - int simState = mContext.getSystemService(TelephonyManager.class).getSimState(); - synchronized (mStats) { - mStats.notePhoneStateLocked(state, simState); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + int simState = mContext.getSystemService(TelephonyManager.class).getSimState(); + synchronized (mStats) { + mStats.notePhoneStateLocked(state, simState, elapsedRealtime, uptime); + } + }); } } public void noteWifiOn() { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteWifiOnLocked(); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteWifiOnLocked(elapsedRealtime, uptime); + } + FrameworkStatsLog.write(FrameworkStatsLog.WIFI_ENABLED_STATE_CHANGED, + FrameworkStatsLog.WIFI_ENABLED_STATE_CHANGED__STATE__ON); + }); } - FrameworkStatsLog.write(FrameworkStatsLog.WIFI_ENABLED_STATE_CHANGED, - FrameworkStatsLog.WIFI_ENABLED_STATE_CHANGED__STATE__ON); } public void noteWifiOff() { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteWifiOffLocked(); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteWifiOffLocked(elapsedRealtime, uptime); + } + FrameworkStatsLog.write(FrameworkStatsLog.WIFI_ENABLED_STATE_CHANGED, + FrameworkStatsLog.WIFI_ENABLED_STATE_CHANGED__STATE__OFF); + }); } - FrameworkStatsLog.write(FrameworkStatsLog.WIFI_ENABLED_STATE_CHANGED, - FrameworkStatsLog.WIFI_ENABLED_STATE_CHANGED__STATE__OFF); } - public void noteStartAudio(int uid) { + public void noteStartAudio(final int uid) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteAudioOnLocked(uid); - FrameworkStatsLog.write_non_chained(FrameworkStatsLog.AUDIO_STATE_CHANGED, uid, null, - FrameworkStatsLog.AUDIO_STATE_CHANGED__STATE__ON); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteAudioOnLocked(uid, elapsedRealtime, uptime); + } + FrameworkStatsLog.write_non_chained(FrameworkStatsLog.AUDIO_STATE_CHANGED, uid, + null, FrameworkStatsLog.AUDIO_STATE_CHANGED__STATE__ON); + }); } } - public void noteStopAudio(int uid) { + public void noteStopAudio(final int uid) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteAudioOffLocked(uid); - FrameworkStatsLog.write_non_chained(FrameworkStatsLog.AUDIO_STATE_CHANGED, uid, null, - FrameworkStatsLog.AUDIO_STATE_CHANGED__STATE__OFF); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteAudioOffLocked(uid, elapsedRealtime, uptime); + } + FrameworkStatsLog.write_non_chained(FrameworkStatsLog.AUDIO_STATE_CHANGED, uid, + null, FrameworkStatsLog.AUDIO_STATE_CHANGED__STATE__OFF); + }); } } - public void noteStartVideo(int uid) { + public void noteStartVideo(final int uid) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteVideoOnLocked(uid); - FrameworkStatsLog.write_non_chained(FrameworkStatsLog.MEDIA_CODEC_STATE_CHANGED, uid, - null, FrameworkStatsLog.MEDIA_CODEC_STATE_CHANGED__STATE__ON); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteVideoOnLocked(uid, elapsedRealtime, uptime); + } + FrameworkStatsLog.write_non_chained(FrameworkStatsLog.MEDIA_CODEC_STATE_CHANGED, + uid, null, FrameworkStatsLog.MEDIA_CODEC_STATE_CHANGED__STATE__ON); + }); } } - public void noteStopVideo(int uid) { + public void noteStopVideo(final int uid) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteVideoOffLocked(uid); - FrameworkStatsLog.write_non_chained(FrameworkStatsLog.MEDIA_CODEC_STATE_CHANGED, uid, - null, FrameworkStatsLog.MEDIA_CODEC_STATE_CHANGED__STATE__OFF); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteVideoOffLocked(uid, elapsedRealtime, uptime); + } + FrameworkStatsLog.write_non_chained(FrameworkStatsLog.MEDIA_CODEC_STATE_CHANGED, + uid, null, FrameworkStatsLog.MEDIA_CODEC_STATE_CHANGED__STATE__OFF); + }); } } public void noteResetAudio() { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteResetAudioLocked(); - FrameworkStatsLog.write_non_chained(FrameworkStatsLog.AUDIO_STATE_CHANGED, -1, null, - FrameworkStatsLog.AUDIO_STATE_CHANGED__STATE__RESET); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteResetAudioLocked(elapsedRealtime, uptime); + } + FrameworkStatsLog.write_non_chained(FrameworkStatsLog.AUDIO_STATE_CHANGED, -1, null, + FrameworkStatsLog.AUDIO_STATE_CHANGED__STATE__RESET); + }); } } public void noteResetVideo() { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteResetVideoLocked(); - FrameworkStatsLog.write_non_chained(FrameworkStatsLog.MEDIA_CODEC_STATE_CHANGED, -1, - null, FrameworkStatsLog.MEDIA_CODEC_STATE_CHANGED__STATE__RESET); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteResetVideoLocked(elapsedRealtime, uptime); + } + FrameworkStatsLog.write_non_chained(FrameworkStatsLog.MEDIA_CODEC_STATE_CHANGED, -1, + null, FrameworkStatsLog.MEDIA_CODEC_STATE_CHANGED__STATE__RESET); + }); } } - public void noteFlashlightOn(int uid) { + public void noteFlashlightOn(final int uid) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteFlashlightOnLocked(uid); - FrameworkStatsLog.write_non_chained(FrameworkStatsLog.FLASHLIGHT_STATE_CHANGED, uid, - null, FrameworkStatsLog.FLASHLIGHT_STATE_CHANGED__STATE__ON); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteFlashlightOnLocked(uid, elapsedRealtime, uptime); + } + FrameworkStatsLog.write_non_chained(FrameworkStatsLog.FLASHLIGHT_STATE_CHANGED, uid, + null, FrameworkStatsLog.FLASHLIGHT_STATE_CHANGED__STATE__ON); + }); } } - public void noteFlashlightOff(int uid) { + public void noteFlashlightOff(final int uid) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteFlashlightOffLocked(uid); - FrameworkStatsLog.write_non_chained(FrameworkStatsLog.FLASHLIGHT_STATE_CHANGED, uid, - null, FrameworkStatsLog.FLASHLIGHT_STATE_CHANGED__STATE__OFF); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteFlashlightOffLocked(uid, elapsedRealtime, uptime); + } + FrameworkStatsLog.write_non_chained(FrameworkStatsLog.FLASHLIGHT_STATE_CHANGED, uid, + null, FrameworkStatsLog.FLASHLIGHT_STATE_CHANGED__STATE__OFF); + }); } } - public void noteStartCamera(int uid) { + public void noteStartCamera(final int uid) { enforceCallingPermission(); if (DBG) Slog.d(TAG, "begin noteStartCamera"); - synchronized (mStats) { - mStats.noteCameraOnLocked(uid); - FrameworkStatsLog.write_non_chained(FrameworkStatsLog.CAMERA_STATE_CHANGED, uid, null, - FrameworkStatsLog.CAMERA_STATE_CHANGED__STATE__ON); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteCameraOnLocked(uid, elapsedRealtime, uptime); + } + FrameworkStatsLog.write_non_chained(FrameworkStatsLog.CAMERA_STATE_CHANGED, uid, + null, FrameworkStatsLog.CAMERA_STATE_CHANGED__STATE__ON); + }); } if (DBG) Slog.d(TAG, "end noteStartCamera"); } - public void noteStopCamera(int uid) { + public void noteStopCamera(final int uid) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteCameraOffLocked(uid); - FrameworkStatsLog.write_non_chained(FrameworkStatsLog.CAMERA_STATE_CHANGED, uid, null, - FrameworkStatsLog.CAMERA_STATE_CHANGED__STATE__OFF); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteCameraOffLocked(uid, elapsedRealtime, uptime); + } + FrameworkStatsLog.write_non_chained(FrameworkStatsLog.CAMERA_STATE_CHANGED, uid, + null, FrameworkStatsLog.CAMERA_STATE_CHANGED__STATE__OFF); + }); } } public void noteResetCamera() { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteResetCameraLocked(); - FrameworkStatsLog.write_non_chained(FrameworkStatsLog.CAMERA_STATE_CHANGED, -1, null, - FrameworkStatsLog.CAMERA_STATE_CHANGED__STATE__RESET); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteResetCameraLocked(elapsedRealtime, uptime); + } + FrameworkStatsLog.write_non_chained(FrameworkStatsLog.CAMERA_STATE_CHANGED, -1, + null, FrameworkStatsLog.CAMERA_STATE_CHANGED__STATE__RESET); + }); } } public void noteResetFlashlight() { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteResetFlashlightLocked(); - FrameworkStatsLog.write_non_chained(FrameworkStatsLog.FLASHLIGHT_STATE_CHANGED, -1, - null, FrameworkStatsLog.FLASHLIGHT_STATE_CHANGED__STATE__RESET); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteResetFlashlightLocked(elapsedRealtime, uptime); + } + FrameworkStatsLog.write_non_chained(FrameworkStatsLog.FLASHLIGHT_STATE_CHANGED, -1, + null, FrameworkStatsLog.FLASHLIGHT_STATE_CHANGED__STATE__RESET); + }); } } @Override - public void noteWifiRadioPowerState(int powerState, long tsNanos, int uid) { - enforceCallingPermission(); - - // There was a change in WiFi power state. - // Collect data now for the past activity. - synchronized (mStats) { - if (mStats.isOnBattery()) { - final String type = (powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH || - powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM) ? "active" - : "inactive"; - mWorker.scheduleSync("wifi-data: " + type, BatteryExternalStatsWorker.UPDATE_WIFI); - } - mStats.noteWifiRadioPowerState(powerState, tsNanos, uid); + public void noteWifiRadioPowerState(final int powerState, final long tsNanos, final int uid) { + enforceCallingPermission(); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + // There was a change in WiFi power state. + // Collect data now for the past activity. + synchronized (mStats) { + if (mStats.isOnBattery()) { + final String type = + (powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH + || powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM) + ? "active" : "inactive"; + mWorker.scheduleSync("wifi-data: " + type, + BatteryExternalStatsWorker.UPDATE_WIFI); + } + mStats.noteWifiRadioPowerState(powerState, tsNanos, uid, + elapsedRealtime, uptime); + } + }); } } - public void noteWifiRunning(WorkSource ws) { + public void noteWifiRunning(final WorkSource ws) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteWifiRunningLocked(ws); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteWifiRunningLocked(ws, elapsedRealtime, uptime); + } + // TODO: Log WIFI_RUNNING_STATE_CHANGED in a better spot to include Hotspot too. + FrameworkStatsLog.write(FrameworkStatsLog.WIFI_RUNNING_STATE_CHANGED, + ws, FrameworkStatsLog.WIFI_RUNNING_STATE_CHANGED__STATE__ON); + }); } - // TODO: Log WIFI_RUNNING_STATE_CHANGED in a better spot to include Hotspot too. - FrameworkStatsLog.write(FrameworkStatsLog.WIFI_RUNNING_STATE_CHANGED, - ws, FrameworkStatsLog.WIFI_RUNNING_STATE_CHANGED__STATE__ON); } - public void noteWifiRunningChanged(WorkSource oldWs, WorkSource newWs) { + public void noteWifiRunningChanged(final WorkSource oldWs, final WorkSource newWs) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteWifiRunningChangedLocked(oldWs, newWs); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteWifiRunningChangedLocked(oldWs, newWs, elapsedRealtime, uptime); + } + FrameworkStatsLog.write(FrameworkStatsLog.WIFI_RUNNING_STATE_CHANGED, + newWs, FrameworkStatsLog.WIFI_RUNNING_STATE_CHANGED__STATE__ON); + FrameworkStatsLog.write(FrameworkStatsLog.WIFI_RUNNING_STATE_CHANGED, + oldWs, FrameworkStatsLog.WIFI_RUNNING_STATE_CHANGED__STATE__OFF); + }); } - FrameworkStatsLog.write(FrameworkStatsLog.WIFI_RUNNING_STATE_CHANGED, - newWs, FrameworkStatsLog.WIFI_RUNNING_STATE_CHANGED__STATE__ON); - FrameworkStatsLog.write(FrameworkStatsLog.WIFI_RUNNING_STATE_CHANGED, - oldWs, FrameworkStatsLog.WIFI_RUNNING_STATE_CHANGED__STATE__OFF); } - public void noteWifiStopped(WorkSource ws) { + public void noteWifiStopped(final WorkSource ws) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteWifiStoppedLocked(ws); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteWifiStoppedLocked(ws, elapsedRealtime, uptime); + } + FrameworkStatsLog.write(FrameworkStatsLog.WIFI_RUNNING_STATE_CHANGED, + ws, FrameworkStatsLog.WIFI_RUNNING_STATE_CHANGED__STATE__OFF); + }); } - FrameworkStatsLog.write(FrameworkStatsLog.WIFI_RUNNING_STATE_CHANGED, - ws, FrameworkStatsLog.WIFI_RUNNING_STATE_CHANGED__STATE__OFF); } - public void noteWifiState(int wifiState, String accessPoint) { + public void noteWifiState(final int wifiState, final String accessPoint) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteWifiStateLocked(wifiState, accessPoint); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteWifiStateLocked(wifiState, accessPoint, elapsedRealtime); + } + }); } } - public void noteWifiSupplicantStateChanged(int supplState, boolean failedAuth) { + public void noteWifiSupplicantStateChanged(final int supplState, final boolean failedAuth) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteWifiSupplicantStateChangedLocked(supplState, failedAuth); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteWifiSupplicantStateChangedLocked(supplState, failedAuth, + elapsedRealtime, uptime); + } + }); } } - public void noteWifiRssiChanged(int newRssi) { + public void noteWifiRssiChanged(final int newRssi) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteWifiRssiChangedLocked(newRssi); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteWifiRssiChangedLocked(newRssi, elapsedRealtime, uptime); + } + }); } } - public void noteFullWifiLockAcquired(int uid) { + public void noteFullWifiLockAcquired(final int uid) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteFullWifiLockAcquiredLocked(uid); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteFullWifiLockAcquiredLocked(uid, elapsedRealtime, uptime); + } + }); } } - public void noteFullWifiLockReleased(int uid) { + public void noteFullWifiLockReleased(final int uid) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteFullWifiLockReleasedLocked(uid); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteFullWifiLockReleasedLocked(uid, elapsedRealtime, uptime); + } + }); } } - public void noteWifiScanStarted(int uid) { + public void noteWifiScanStarted(final int uid) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteWifiScanStartedLocked(uid); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteWifiScanStartedLocked(uid, elapsedRealtime, uptime); + } + }); } } - public void noteWifiScanStopped(int uid) { + public void noteWifiScanStopped(final int uid) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteWifiScanStoppedLocked(uid); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteWifiScanStoppedLocked(uid, elapsedRealtime, uptime); + } + }); } } - public void noteWifiMulticastEnabled(int uid) { + public void noteWifiMulticastEnabled(final int uid) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteWifiMulticastEnabledLocked(uid); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteWifiMulticastEnabledLocked(uid, elapsedRealtime, uptime); + } + }); } } - public void noteWifiMulticastDisabled(int uid) { + public void noteWifiMulticastDisabled(final int uid) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteWifiMulticastDisabledLocked(uid); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteWifiMulticastDisabledLocked(uid, elapsedRealtime, uptime); + } + }); } } - public void noteFullWifiLockAcquiredFromSource(WorkSource ws) { + public void noteFullWifiLockAcquiredFromSource(final WorkSource ws) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteFullWifiLockAcquiredFromSourceLocked(ws); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteFullWifiLockAcquiredFromSourceLocked(ws, elapsedRealtime, uptime); + } + }); } } - public void noteFullWifiLockReleasedFromSource(WorkSource ws) { + public void noteFullWifiLockReleasedFromSource(final WorkSource ws) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteFullWifiLockReleasedFromSourceLocked(ws); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteFullWifiLockReleasedFromSourceLocked(ws, elapsedRealtime, uptime); + } + }); } } - public void noteWifiScanStartedFromSource(WorkSource ws) { + public void noteWifiScanStartedFromSource(final WorkSource ws) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteWifiScanStartedFromSourceLocked(ws); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteWifiScanStartedFromSourceLocked(ws, elapsedRealtime, uptime); + } + }); } } - public void noteWifiScanStoppedFromSource(WorkSource ws) { + public void noteWifiScanStoppedFromSource(final WorkSource ws) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteWifiScanStoppedFromSourceLocked(ws); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteWifiScanStoppedFromSourceLocked(ws, elapsedRealtime, uptime); + } + }); } } - public void noteWifiBatchedScanStartedFromSource(WorkSource ws, int csph) { + public void noteWifiBatchedScanStartedFromSource(final WorkSource ws, final int csph) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteWifiBatchedScanStartedFromSourceLocked(ws, csph); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteWifiBatchedScanStartedFromSourceLocked(ws, csph, + elapsedRealtime, uptime); + } + }); } } - public void noteWifiBatchedScanStoppedFromSource(WorkSource ws) { + public void noteWifiBatchedScanStoppedFromSource(final WorkSource ws) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteWifiBatchedScanStoppedFromSourceLocked(ws); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteWifiBatchedScanStoppedFromSourceLocked(ws, elapsedRealtime, uptime); + } + }); } } @Override - public void noteNetworkInterfaceType(String iface, int networkType) { + public void noteNetworkInterfaceType(final String iface, final int networkType) { enforceCallingPermission(); - mStats.noteNetworkInterfaceType(iface, networkType); + synchronized (mLock) { + mHandler.post(() -> { + mStats.noteNetworkInterfaceType(iface, networkType); + }); + } } @Override @@ -1027,66 +1576,119 @@ public final class BatteryStatsService extends IBatteryStats.Stub // During device boot, qtaguid isn't enabled until after the inital // loading of battery stats. Now that they're enabled, take our initial // snapshot for future delta calculation. - mWorker.scheduleSync("network-stats-enabled", - BatteryExternalStatsWorker.UPDATE_RADIO | BatteryExternalStatsWorker.UPDATE_WIFI); + synchronized (mLock) { + // Still schedule it on the handler to make sure we have existing pending works done + mHandler.post(() -> { + mWorker.scheduleSync("network-stats-enabled", + BatteryExternalStatsWorker.UPDATE_RADIO + | BatteryExternalStatsWorker.UPDATE_WIFI); + }); + } } @Override - public void noteDeviceIdleMode(int mode, String activeReason, int activeUid) { + public void noteDeviceIdleMode(final int mode, final String activeReason, final int activeUid) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteDeviceIdleModeLocked(mode, activeReason, activeUid); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteDeviceIdleModeLocked(mode, activeReason, activeUid, + elapsedRealtime, uptime); + } + }); } } - public void notePackageInstalled(String pkgName, long versionCode) { + public void notePackageInstalled(final String pkgName, final long versionCode) { enforceCallingPermission(); - synchronized (mStats) { - mStats.notePackageInstalledLocked(pkgName, versionCode); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.notePackageInstalledLocked(pkgName, versionCode, + elapsedRealtime, uptime); + } + }); } } - public void notePackageUninstalled(String pkgName) { + public void notePackageUninstalled(final String pkgName) { enforceCallingPermission(); - synchronized (mStats) { - mStats.notePackageUninstalledLocked(pkgName); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.notePackageUninstalledLocked(pkgName, elapsedRealtime, uptime); + } + }); } } @Override - public void noteBleScanStarted(WorkSource ws, boolean isUnoptimized) { + public void noteBleScanStarted(final WorkSource ws, final boolean isUnoptimized) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteBluetoothScanStartedFromSourceLocked(ws, isUnoptimized); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteBluetoothScanStartedFromSourceLocked(ws, isUnoptimized, + elapsedRealtime, uptime); + } + }); } } @Override - public void noteBleScanStopped(WorkSource ws, boolean isUnoptimized) { + public void noteBleScanStopped(final WorkSource ws, final boolean isUnoptimized) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteBluetoothScanStoppedFromSourceLocked(ws, isUnoptimized); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteBluetoothScanStoppedFromSourceLocked(ws, isUnoptimized, + uptime, elapsedRealtime); + } + }); } } @Override public void noteResetBleScan() { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteResetBluetoothScanLocked(); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteResetBluetoothScanLocked(elapsedRealtime, uptime); + } + }); } } @Override - public void noteBleScanResults(WorkSource ws, int numNewResults) { + public void noteBleScanResults(final WorkSource ws, final int numNewResults) { enforceCallingPermission(); - synchronized (mStats) { - mStats.noteBluetoothScanResultsFromSourceLocked(ws, numNewResults); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteBluetoothScanResultsFromSourceLocked(ws, numNewResults, + elapsedRealtime, uptime); + } + }); } } @Override - public void noteWifiControllerActivity(WifiActivityEnergyInfo info) { + public void noteWifiControllerActivity(final WifiActivityEnergyInfo info) { enforceCallingPermission(); if (info == null || !info.isValid()) { @@ -1094,24 +1696,36 @@ public final class BatteryStatsService extends IBatteryStats.Stub return; } - mStats.updateWifiState(info); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + mStats.updateWifiState(info, elapsedRealtime, uptime); + }); + } } @Override - public void noteBluetoothControllerActivity(BluetoothActivityEnergyInfo info) { + public void noteBluetoothControllerActivity(final BluetoothActivityEnergyInfo info) { enforceCallingPermission(); if (info == null || !info.isValid()) { Slog.e(TAG, "invalid bluetooth data given: " + info); return; } - synchronized (mStats) { - mStats.updateBluetoothStateLocked(info); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.updateBluetoothStateLocked(info, elapsedRealtime, uptime); + } + }); } } @Override - public void noteModemControllerActivity(ModemActivityInfo info) { + public void noteModemControllerActivity(final ModemActivityInfo info) { enforceCallingPermission(); if (info == null || !info.isValid()) { @@ -1119,7 +1733,13 @@ public final class BatteryStatsService extends IBatteryStats.Stub return; } - mStats.updateMobileRadioState(info); + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + mStats.updateMobileRadioState(info, elapsedRealtime, uptime); + }); + } } public boolean isOnBattery() { @@ -1132,32 +1752,43 @@ public final class BatteryStatsService extends IBatteryStats.Stub final int chargeFullUAh, final long chargeTimeToFullSeconds) { enforceCallingPermission(); - // BatteryService calls us here and we may update external state. It would be wrong - // to block such a low level service like BatteryService on external stats like WiFi. - mWorker.scheduleRunnable(() -> { - synchronized (mStats) { - final boolean onBattery = BatteryStatsImpl.isOnBattery(plugType, status); - if (mStats.isOnBattery() == onBattery) { - // The battery state has not changed, so we don't need to sync external - // stats immediately. - mStats.setBatteryStateLocked(status, health, plugType, level, temp, volt, - chargeUAh, chargeFullUAh, chargeTimeToFullSeconds); - return; - } - } + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + final long currentTime = System.currentTimeMillis(); + // We still schedule this task over the handler thread to make sure we've had + // all existing pending work handled before setting the battery state + mHandler.post(() -> { + // BatteryService calls us here and we may update external state. It would be wrong + // to block such a low level service like BatteryService on external stats like WiFi + mWorker.scheduleRunnable(() -> { + synchronized (mStats) { + final boolean onBattery = BatteryStatsImpl.isOnBattery(plugType, status); + if (mStats.isOnBattery() == onBattery) { + // The battery state has not changed, so we don't need to sync external + // stats immediately. + mStats.setBatteryStateLocked(status, health, plugType, level, temp, + volt, chargeUAh, chargeFullUAh, chargeTimeToFullSeconds, + elapsedRealtime, uptime, currentTime); + return; + } + } - // Sync external stats first as the battery has changed states. If we don't sync - // before changing the state, we may not collect the relevant data later. - // Order here is guaranteed since we're scheduling from the same thread and we are - // using a single threaded executor. - mWorker.scheduleSync("battery-state", BatteryExternalStatsWorker.UPDATE_ALL); - mWorker.scheduleRunnable(() -> { - synchronized (mStats) { - mStats.setBatteryStateLocked(status, health, plugType, level, temp, volt, - chargeUAh, chargeFullUAh, chargeTimeToFullSeconds); - } + // Sync external stats first as the battery has changed states. If we don't sync + // before changing the state, we may not collect the relevant data later. + // Order here is guaranteed since we're scheduling from the same thread and we + // are using a single threaded executor. + mWorker.scheduleSync("battery-state", BatteryExternalStatsWorker.UPDATE_ALL); + mWorker.scheduleRunnable(() -> { + synchronized (mStats) { + mStats.setBatteryStateLocked(status, health, plugType, level, temp, + volt, chargeUAh, chargeFullUAh, chargeTimeToFullSeconds, + elapsedRealtime, uptime, currentTime); + } + }); + }); }); - }); + } } public long getAwakeTimeBattery() { @@ -1205,8 +1836,12 @@ public final class BatteryStatsService extends IBatteryStats.Stub try { String reason; while ((reason = waitWakeup()) != null) { + // Wait for the completion of pending works if there is any + awaitCompletion(); + synchronized (mStats) { - mStats.noteWakeupReasonLocked(reason); + mStats.noteWakeupReasonLocked(reason, + SystemClock.elapsedRealtime(), SystemClock.uptimeMillis()); } } } catch (RuntimeException e) { @@ -1273,12 +1908,16 @@ public final class BatteryStatsService extends IBatteryStats.Stub } private void dumpSettings(PrintWriter pw) { + // Wait for the completion of pending works if there is any + awaitCompletion(); synchronized (mStats) { mStats.dumpConstantsLocked(pw); } } private void dumpCpuStats(PrintWriter pw) { + // Wait for the completion of pending works if there is any + awaitCompletion(); synchronized (mStats) { mStats.dumpCpuStatsLocked(pw); } @@ -1292,14 +1931,20 @@ public final class BatteryStatsService extends IBatteryStats.Stub return -1; } if ("full-wake-history".equals(args[i]) || "full-history".equals(args[i])) { + // Wait for the completion of pending works if there is any + awaitCompletion(); synchronized (mStats) { mStats.setRecordAllHistoryLocked(enable); } } else if ("no-auto-reset".equals(args[i])) { + // Wait for the completion of pending works if there is any + awaitCompletion(); synchronized (mStats) { mStats.setNoAutoReset(enable); } } else if ("pretend-screen-off".equals(args[i])) { + // Wait for the completion of pending works if there is any + awaitCompletion(); synchronized (mStats) { mStats.setPretendScreenOff(enable); } @@ -1350,6 +1995,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub return; } final long events = ParseUtils.parseLong(args[i], 0); + awaitCompletion(); synchronized (mStats) { mStats.createFakeHistoryEvents(events); pw.println("Battery history create events started."); @@ -1365,6 +2011,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub } else if ("--daily".equals(arg)) { flags |= BatteryStats.DUMP_DAILY_ONLY; } else if ("--reset".equals(arg)) { + awaitCompletion(); synchronized (mStats) { mStats.resetAllStatsCmdLocked(); pw.println("Battery stats reset."); @@ -1372,6 +2019,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub } mWorker.scheduleSync("dump", BatteryExternalStatsWorker.UPDATE_ALL); } else if ("--write".equals(arg)) { + awaitCompletion(); syncStats("dump", BatteryExternalStatsWorker.UPDATE_ALL); synchronized (mStats) { mStats.writeSyncLocked(); @@ -1379,12 +2027,14 @@ public final class BatteryStatsService extends IBatteryStats.Stub noOutput = true; } } else if ("--new-daily".equals(arg)) { + awaitCompletion(); synchronized (mStats) { mStats.recordDailyStatsLocked(); pw.println("New daily stats written."); noOutput = true; } } else if ("--read-daily".equals(arg)) { + awaitCompletion(); synchronized (mStats) { mStats.readDailyStatsLocked(); pw.println("Last daily stats read."); @@ -1441,6 +2091,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub if (BatteryStatsHelper.checkWifiOnly(mContext)) { flags |= BatteryStats.DUMP_DEVICE_WIFI_ONLY; } + awaitCompletion(); // Fetch data from external sources and update the BatteryStatsImpl object with them. syncStats("dump", BatteryExternalStatsWorker.UPDATE_ALL); } finally { @@ -1489,6 +2140,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub } } if (DBG) Slog.d(TAG, "begin dumpProtoLocked from UID " + Binder.getCallingUid()); + awaitCompletion(); synchronized (mStats) { mStats.dumpProtoLocked(mContext, fd, apps, flags, historyStart); if (writeData) { @@ -1528,6 +2180,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub } } if (DBG) Slog.d(TAG, "begin dumpCheckinLocked from UID " + Binder.getCallingUid()); + awaitCompletion(); synchronized (mStats) { mStats.dumpCheckinLocked(mContext, pw, apps, flags, historyStart); if (writeData) { @@ -1537,6 +2190,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub if (DBG) Slog.d(TAG, "end dumpCheckinLocked"); } else { if (DBG) Slog.d(TAG, "begin dumpLocked from UID " + Binder.getCallingUid()); + awaitCompletion(); synchronized (mStats) { mStats.dumpLocked(mContext, pw, flags, reqUid, historyStart); if (writeData) { @@ -1552,6 +2206,8 @@ public final class BatteryStatsService extends IBatteryStats.Stub * @hide */ public CellularBatteryStats getCellularBatteryStats() { + // Wait for the completion of pending works if there is any + awaitCompletion(); synchronized (mStats) { return mStats.getCellularBatteryStats(); } @@ -1562,6 +2218,8 @@ public final class BatteryStatsService extends IBatteryStats.Stub * @hide */ public WifiBatteryStats getWifiBatteryStats() { + // Wait for the completion of pending works if there is any + awaitCompletion(); synchronized (mStats) { return mStats.getWifiBatteryStats(); } @@ -1572,6 +2230,8 @@ public final class BatteryStatsService extends IBatteryStats.Stub * @hide */ public GpsBatteryStats getGpsBatteryStats() { + // Wait for the completion of pending works if there is any + awaitCompletion(); synchronized (mStats) { return mStats.getGpsBatteryStats(); } @@ -1588,6 +2248,8 @@ public final class BatteryStatsService extends IBatteryStats.Stub } long ident = Binder.clearCallingIdentity(); try { + // Wait for the completion of pending works if there is any + awaitCompletion(); if (shouldCollectExternalStats()) { syncStats("get-health-stats-for-uids", BatteryExternalStatsWorker.UPDATE_ALL); } @@ -1614,6 +2276,8 @@ public final class BatteryStatsService extends IBatteryStats.Stub long ident = Binder.clearCallingIdentity(); int i=-1; try { + // Wait for the completion of pending works if there is any + awaitCompletion(); if (shouldCollectExternalStats()) { syncStats("get-health-stats-for-uids", BatteryExternalStatsWorker.UPDATE_ALL); } @@ -1685,4 +2349,124 @@ public final class BatteryStatsService extends IBatteryStats.Stub Binder.restoreCallingIdentity(ident); } } + + void updateForegroundTimeIfOnBattery(final String packageName, final int uid, + final long cpuTimeDiff) { + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + if (!isOnBattery()) { + return; + } + synchronized (mStats) { + final BatteryStatsImpl.Uid.Proc ps = + mStats.getProcessStatsLocked(uid, packageName, elapsedRealtime, uptime); + if (ps != null) { + ps.addForegroundTimeLocked(cpuTimeDiff); + } + } + }); + } + } + + void noteCurrentTimeChanged() { + synchronized (mLock) { + final long currentTime = System.currentTimeMillis(); + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteCurrentTimeChangedLocked(currentTime, elapsedRealtime, uptime); + } + }); + } + } + + void updateBatteryStatsOnActivityUsage(final String packageName, final String className, + final int uid, final int userId, final boolean resumed) { + synchronized (mLock) { + final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + FrameworkStatsLog.write(FrameworkStatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED, + uid, packageName, className, + resumed + ? FrameworkStatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED__STATE__FOREGROUND + : FrameworkStatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED__STATE__BACKGROUND); + synchronized (mStats) { + if (resumed) { + mStats.noteActivityResumedLocked(uid, elapsedRealtime, uptime); + } else { + mStats.noteActivityPausedLocked(uid, elapsedRealtime, uptime); + } + } + }); + } + } + + void noteProcessDied(final int uid, final int pid) { + synchronized (mLock) { + mHandler.post(() -> { + synchronized (mStats) { + mStats.noteProcessDiedLocked(uid, pid); + } + }); + } + } + + void reportExcessiveCpu(final int uid, final String processName, final long uptimeSince, + long cputimeUsed) { + synchronized (mLock) { + mHandler.post(() -> { + synchronized (mStats) { + mStats.reportExcessiveCpuLocked(uid, processName, uptimeSince, cputimeUsed); + } + }); + } + } + + void noteServiceStartRunning(final BatteryStatsImpl.Uid.Pkg.Serv stats) { + synchronized (mLock) { + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + stats.startRunningLocked(uptime); + } + }); + } + } + + void noteServiceStopRunning(final BatteryStatsImpl.Uid.Pkg.Serv stats) { + synchronized (mLock) { + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + stats.stopRunningLocked(uptime); + } + }); + } + } + + void noteServiceStartLaunch(final BatteryStatsImpl.Uid.Pkg.Serv stats) { + synchronized (mLock) { + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + stats.startLaunchedLocked(uptime); + } + }); + } + } + + void noteServiceStopLaunch(final BatteryStatsImpl.Uid.Pkg.Serv stats) { + synchronized (mLock) { + final long uptime = SystemClock.uptimeMillis(); + mHandler.post(() -> { + synchronized (mStats) { + stats.stopLaunchedLocked(uptime); + } + }); + } + } } diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java index c5047e5eed03..966038986791 100644 --- a/services/core/java/com/android/server/am/CachedAppOptimizer.java +++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java @@ -479,6 +479,21 @@ public final class CachedAppOptimizer { private static native void enableFreezerInternal(boolean enable); /** + * Informs binder that a process is about to be frozen. If freezer is enabled on a process via + * this method, this method will synchronously dispatch all pending transactions to the + * specified pid. This method will not add significant latencies when unfreezing. + * After freezing binder calls, binder will block all transaction to the frozen pid, and return + * an error to the sending process. + * + * @param pid the target pid for which binder transactions are to be frozen + * @param freeze specifies whether to flush transactions and then freeze (true) or unfreeze + * binder for the specificed pid. + * + * @throws RuntimeException in case a flush/freeze operation could not complete successfully. + */ + private static native void freezeBinder(int pid, boolean freeze); + + /** * Determines whether the freezer is supported by this system */ public static boolean isFreezerSupported() { @@ -727,6 +742,13 @@ public final class CachedAppOptimizer { } if (!app.frozen) { + try { + freezeBinder(app.pid, false); + } catch (RuntimeException e) { + // TODO: it might be preferable to kill the target pid in this case + Slog.e(TAG_AM, "Unable to unfreeze binder for " + app.pid + " " + app.processName); + } + if (DEBUG_FREEZER) { Slog.d(TAG_AM, "sync unfroze " + app.pid + " " + app.processName); } @@ -1039,6 +1061,14 @@ public final class CachedAppOptimizer { return; } + try { + freezeBinder(pid, true); + } catch (RuntimeException e) { + // TODO: it might be preferable to kill the target pid in this case + Slog.e(TAG_AM, "Unable to freeze binder for " + pid + " " + name); + return; + } + if (pid == 0 || proc.frozen) { // Already frozen or not a real process, either one being // launched or one being killed diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java index dfe8af155a04..b56b09d707af 100644 --- a/services/core/java/com/android/server/appop/AppOpsService.java +++ b/services/core/java/com/android/server/appop/AppOpsService.java @@ -2206,6 +2206,7 @@ public class AppOpsService extends IAppOpsService.Stub { updatePermissionRevokedCompat(uid, code, mode); } + int previousMode; synchronized (this) { final int defaultMode = AppOpsManager.opToDefaultMode(code); @@ -2214,12 +2215,14 @@ public class AppOpsService extends IAppOpsService.Stub { if (mode == defaultMode) { return; } + previousMode = AppOpsManager.MODE_DEFAULT; uidState = new UidState(uid); uidState.opModes = new SparseIntArray(); uidState.opModes.put(code, mode); mUidStates.put(uid, uidState); scheduleWriteLocked(); } else if (uidState.opModes == null) { + previousMode = AppOpsManager.MODE_DEFAULT; if (mode != defaultMode) { uidState.opModes = new SparseIntArray(); uidState.opModes.put(code, mode); @@ -2229,6 +2232,7 @@ public class AppOpsService extends IAppOpsService.Stub { if (uidState.opModes.indexOfKey(code) >= 0 && uidState.opModes.get(code) == mode) { return; } + previousMode = uidState.opModes.get(code); if (mode == defaultMode) { uidState.opModes.delete(code); if (uidState.opModes.size() <= 0) { @@ -2243,7 +2247,7 @@ public class AppOpsService extends IAppOpsService.Stub { } notifyOpChangedForAllPkgsInUid(code, uid, false, permissionPolicyCallback); - notifyOpChangedSync(code, uid, null, mode); + notifyOpChangedSync(code, uid, null, mode, previousMode); } /** @@ -2420,11 +2424,12 @@ public class AppOpsService extends IAppOpsService.Stub { } } - private void notifyOpChangedSync(int code, int uid, @NonNull String packageName, int mode) { + private void notifyOpChangedSync(int code, int uid, @NonNull String packageName, int mode, + int previousMode) { final StorageManagerInternal storageManagerInternal = LocalServices.getService(StorageManagerInternal.class); if (storageManagerInternal != null) { - storageManagerInternal.onAppOpsChanged(code, uid, packageName, mode); + storageManagerInternal.onAppOpsChanged(code, uid, packageName, mode, previousMode); } } @@ -2458,11 +2463,13 @@ public class AppOpsService extends IAppOpsService.Stub { return; } + int previousMode = AppOpsManager.MODE_DEFAULT; synchronized (this) { UidState uidState = getUidStateLocked(uid, false); Op op = getOpLocked(code, uid, packageName, null, bypass, true); if (op != null) { if (op.mode != mode) { + previousMode = op.mode; op.mode = mode; if (uidState != null) { uidState.evalForegroundOps(mOpModeWatchers); @@ -2499,7 +2506,7 @@ public class AppOpsService extends IAppOpsService.Stub { this, repCbs, code, uid, packageName)); } - notifyOpChangedSync(code, uid, packageName, mode); + notifyOpChangedSync(code, uid, packageName, mode, previousMode); } private void notifyOpChanged(ArraySet<ModeCallback> callbacks, int code, @@ -2542,7 +2549,7 @@ public class AppOpsService extends IAppOpsService.Stub { } private static ArrayList<ChangeRec> addChange(ArrayList<ChangeRec> reports, - int op, int uid, String packageName) { + int op, int uid, String packageName, int previousMode) { boolean duplicate = false; if (reports == null) { reports = new ArrayList<>(); @@ -2557,7 +2564,7 @@ public class AppOpsService extends IAppOpsService.Stub { } } if (!duplicate) { - reports.add(new ChangeRec(op, uid, packageName)); + reports.add(new ChangeRec(op, uid, packageName, previousMode)); } return reports; @@ -2565,7 +2572,7 @@ public class AppOpsService extends IAppOpsService.Stub { private static HashMap<ModeCallback, ArrayList<ChangeRec>> addCallbacks( HashMap<ModeCallback, ArrayList<ChangeRec>> callbacks, - int op, int uid, String packageName, ArraySet<ModeCallback> cbs) { + int op, int uid, String packageName, int previousMode, ArraySet<ModeCallback> cbs) { if (cbs == null) { return callbacks; } @@ -2576,7 +2583,7 @@ public class AppOpsService extends IAppOpsService.Stub { for (int i=0; i<N; i++) { ModeCallback cb = cbs.valueAt(i); ArrayList<ChangeRec> reports = callbacks.get(cb); - ArrayList<ChangeRec> changed = addChange(reports, op, uid, packageName); + ArrayList<ChangeRec> changed = addChange(reports, op, uid, packageName, previousMode); if (changed != reports) { callbacks.put(cb, changed); } @@ -2588,11 +2595,13 @@ public class AppOpsService extends IAppOpsService.Stub { final int op; final int uid; final String pkg; + final int previous_mode; - ChangeRec(int _op, int _uid, String _pkg) { + ChangeRec(int _op, int _uid, String _pkg, int _previous_mode) { op = _op; uid = _uid; pkg = _pkg; + previous_mode = _previous_mode; } } @@ -2628,18 +2637,19 @@ public class AppOpsService extends IAppOpsService.Stub { for (int j = uidOpCount - 1; j >= 0; j--) { final int code = opModes.keyAt(j); if (AppOpsManager.opAllowsReset(code)) { + int previousMode = opModes.valueAt(j); opModes.removeAt(j); if (opModes.size() <= 0) { uidState.opModes = null; } for (String packageName : getPackagesForUid(uidState.uid)) { callbacks = addCallbacks(callbacks, code, uidState.uid, packageName, - mOpModeWatchers.get(code)); + previousMode, mOpModeWatchers.get(code)); callbacks = addCallbacks(callbacks, code, uidState.uid, packageName, - mPackageModeWatchers.get(packageName)); + previousMode, mPackageModeWatchers.get(packageName)); allChanges = addChange(allChanges, code, uidState.uid, - packageName); + packageName, previousMode); } } } @@ -2670,16 +2680,18 @@ public class AppOpsService extends IAppOpsService.Stub { Op curOp = pkgOps.valueAt(j); if (AppOpsManager.opAllowsReset(curOp.op) && curOp.mode != AppOpsManager.opToDefaultMode(curOp.op)) { + int previousMode = curOp.mode; curOp.mode = AppOpsManager.opToDefaultMode(curOp.op); changed = true; uidChanged = true; final int uid = curOp.uidState.uid; callbacks = addCallbacks(callbacks, curOp.op, uid, packageName, - mOpModeWatchers.get(curOp.op)); + previousMode, mOpModeWatchers.get(curOp.op)); callbacks = addCallbacks(callbacks, curOp.op, uid, packageName, - mPackageModeWatchers.get(packageName)); + previousMode, mPackageModeWatchers.get(packageName)); - allChanges = addChange(allChanges, curOp.op, uid, packageName); + allChanges = addChange(allChanges, curOp.op, uid, packageName, + previousMode); curOp.removeAttributionsWithNoTime(); if (curOp.mAttributions.isEmpty()) { pkgOps.removeAt(j); @@ -2720,7 +2732,7 @@ public class AppOpsService extends IAppOpsService.Stub { for (int i = 0; i < numChanges; i++) { ChangeRec change = allChanges.get(i); notifyOpChangedSync(change.op, change.uid, change.pkg, - AppOpsManager.opToDefaultMode(change.op)); + AppOpsManager.opToDefaultMode(change.op), change.previous_mode); } } } @@ -3926,7 +3938,7 @@ public class AppOpsService extends IAppOpsService.Stub { if (!isAttributionTagValid) { String msg = "attributionTag " + attributionTag + " not declared in" - + "manifest of " + packageName; + + " manifest of " + packageName; try { if (mPlatformCompat.isChangeEnabledByPackageName( SECURITY_EXCEPTION_ON_INVALID_ATTRIBUTION_TAG_CHANGE, packageName, diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java index 5447605a36d1..1615998f7787 100644 --- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java +++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java @@ -28,6 +28,7 @@ import android.media.AudioDeviceAttributes; import android.media.AudioRoutesInfo; import android.media.AudioSystem; import android.media.IAudioRoutesObserver; +import android.media.ICapturePresetDevicesRoleDispatcher; import android.media.IStrategyPreferredDevicesDispatcher; import android.media.MediaMetrics; import android.os.Binder; @@ -546,6 +547,25 @@ import java.util.concurrent.atomic.AtomicBoolean; mDeviceInventory.unregisterStrategyPreferredDevicesDispatcher(dispatcher); } + /*package*/ int setPreferredDevicesForCapturePresetSync(int capturePreset, + @NonNull List<AudioDeviceAttributes> devices) { + return mDeviceInventory.setPreferredDevicesForCapturePresetSync(capturePreset, devices); + } + + /*package*/ int clearPreferredDevicesForCapturePresetSync(int capturePreset) { + return mDeviceInventory.clearPreferredDevicesForCapturePresetSync(capturePreset); + } + + /*package*/ void registerCapturePresetDevicesRoleDispatcher( + @NonNull ICapturePresetDevicesRoleDispatcher dispatcher) { + mDeviceInventory.registerCapturePresetDevicesRoleDispatcher(dispatcher); + } + + /*package*/ void unregisterCapturePresetDevicesRoleDispatcher( + @NonNull ICapturePresetDevicesRoleDispatcher dispatcher) { + mDeviceInventory.unregisterCapturePresetDevicesRoleDispatcher(dispatcher); + } + //--------------------------------------------------------------------- // Communication with (to) AudioService //TODO check whether the AudioService methods are candidates to move here @@ -694,6 +714,17 @@ import java.util.concurrent.atomic.AtomicBoolean; sendIMsgNoDelay(MSG_I_SAVE_REMOVE_PREF_DEVICES_FOR_STRATEGY, SENDMSG_QUEUE, strategy); } + /*package*/ void postSaveSetPreferredDevicesForCapturePreset( + int capturePreset, List<AudioDeviceAttributes> devices) { + sendILMsgNoDelay( + MSG_IL_SAVE_PREF_DEVICES_FOR_CAPTURE_PRESET, SENDMSG_QUEUE, capturePreset, devices); + } + + /*package*/ void postSaveClearPreferredDevicesForCapturePreset(int capturePreset) { + sendIMsgNoDelay( + MSG_I_SAVE_CLEAR_PREF_DEVICES_FOR_CAPTURE_PRESET, SENDMSG_QUEUE, capturePreset); + } + //--------------------------------------------------------------------- // Method forwarding between the helper classes (BtHelper, AudioDeviceInventory) // only call from a "handle"* method or "on"* method @@ -1098,6 +1129,17 @@ import java.util.concurrent.atomic.AtomicBoolean; case MSG_CHECK_MUTE_MUSIC: checkMessagesMuteMusic(0); break; + case MSG_IL_SAVE_PREF_DEVICES_FOR_CAPTURE_PRESET: { + final int capturePreset = msg.arg1; + final List<AudioDeviceAttributes> devices = + (List<AudioDeviceAttributes>) msg.obj; + mDeviceInventory.onSaveSetPreferredDevicesForCapturePreset( + capturePreset, devices); + } break; + case MSG_I_SAVE_CLEAR_PREF_DEVICES_FOR_CAPTURE_PRESET: { + final int capturePreset = msg.arg1; + mDeviceInventory.onSaveClearPreferredDevicesForCapturePreset(capturePreset); + } break; default: Log.wtf(TAG, "Invalid message " + msg.what); } @@ -1174,6 +1216,9 @@ import java.util.concurrent.atomic.AtomicBoolean; private static final int MSG_CHECK_MUTE_MUSIC = 36; private static final int MSG_REPORT_NEW_ROUTES_A2DP = 37; + private static final int MSG_IL_SAVE_PREF_DEVICES_FOR_CAPTURE_PRESET = 38; + private static final int MSG_I_SAVE_CLEAR_PREF_DEVICES_FOR_CAPTURE_PRESET = 39; + private static boolean isMessageHandledUnderWakelock(int msgId) { switch(msgId) { diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java index fbf07cc591ff..33a8a30243de 100644 --- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java +++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java @@ -31,6 +31,7 @@ import android.media.AudioPort; import android.media.AudioRoutesInfo; import android.media.AudioSystem; import android.media.IAudioRoutesObserver; +import android.media.ICapturePresetDevicesRoleDispatcher; import android.media.IStrategyPreferredDevicesDispatcher; import android.media.MediaMetrics; import android.os.Binder; @@ -140,6 +141,10 @@ public class AudioDeviceInventory { private final ArrayMap<Integer, List<AudioDeviceAttributes>> mPreferredDevices = new ArrayMap<>(); + // List of preferred devices of capture preset + private final ArrayMap<Integer, List<AudioDeviceAttributes>> mPreferredDevicesForCapturePreset = + new ArrayMap<>(); + // the wrapper for AudioSystem static methods, allows us to spy AudioSystem private final @NonNull AudioSystemAdapter mAudioSystem; @@ -154,6 +159,10 @@ public class AudioDeviceInventory { final RemoteCallbackList<IStrategyPreferredDevicesDispatcher> mPrefDevDispatchers = new RemoteCallbackList<IStrategyPreferredDevicesDispatcher>(); + // Monitoring of devices for role and capture preset + final RemoteCallbackList<ICapturePresetDevicesRoleDispatcher> mDevRoleCapturePresetDispatchers = + new RemoteCallbackList<ICapturePresetDevicesRoleDispatcher>(); + /*package*/ AudioDeviceInventory(@NonNull AudioDeviceBroker broker) { mDeviceBroker = broker; mAudioSystem = AudioSystemAdapter.getDefaultAdapter(); @@ -243,6 +252,9 @@ public class AudioDeviceInventory { pw.println(" " + prefix + " type:0x" + Integer.toHexString(keyType) + " (" + AudioSystem.getDeviceName(keyType) + ") addr:" + valueAddress); }); + mPreferredDevicesForCapturePreset.forEach((capturePreset, devices) -> { + pw.println(" " + prefix + "capturePreset:" + capturePreset + + " devices:" + devices); }); } //------------------------------------------------------------ @@ -270,6 +282,9 @@ public class AudioDeviceInventory { mAudioSystem.setDevicesRoleForStrategy( strategy, AudioSystem.DEVICE_ROLE_PREFERRED, devices); }); } + synchronized (mPreferredDevicesForCapturePreset) { + // TODO: call audiosystem to restore + } } // only public for mocking/spying @@ -613,6 +628,20 @@ public class AudioDeviceInventory { dispatchPreferredDevice(strategy, new ArrayList<AudioDeviceAttributes>()); } + /*package*/ void onSaveSetPreferredDevicesForCapturePreset( + int capturePreset, @NonNull List<AudioDeviceAttributes> devices) { + mPreferredDevicesForCapturePreset.put(capturePreset, devices); + dispatchDevicesRoleForCapturePreset( + capturePreset, AudioSystem.DEVICE_ROLE_PREFERRED, devices); + } + + /*package*/ void onSaveClearPreferredDevicesForCapturePreset(int capturePreset) { + mPreferredDevicesForCapturePreset.remove(capturePreset); + dispatchDevicesRoleForCapturePreset( + capturePreset, AudioSystem.DEVICE_ROLE_PREFERRED, + new ArrayList<AudioDeviceAttributes>()); + } + //------------------------------------------------------------ // @@ -651,6 +680,41 @@ public class AudioDeviceInventory { mPrefDevDispatchers.unregister(dispatcher); } + /*package*/ int setPreferredDevicesForCapturePresetSync( + int capturePreset, @NonNull List<AudioDeviceAttributes> devices) { + final long identity = Binder.clearCallingIdentity(); + final int status = mAudioSystem.setDevicesRoleForCapturePreset( + capturePreset, AudioSystem.DEVICE_ROLE_PREFERRED, devices); + Binder.restoreCallingIdentity(identity); + + if (status == AudioSystem.SUCCESS) { + mDeviceBroker.postSaveSetPreferredDevicesForCapturePreset(capturePreset, devices); + } + return status; + } + + /*package*/ int clearPreferredDevicesForCapturePresetSync(int capturePreset) { + final long identity = Binder.clearCallingIdentity(); + final int status = mAudioSystem.clearDevicesRoleForCapturePreset( + capturePreset, AudioSystem.DEVICE_ROLE_PREFERRED); + Binder.restoreCallingIdentity(identity); + + if (status == AudioSystem.SUCCESS) { + mDeviceBroker.postSaveClearPreferredDevicesForCapturePreset(capturePreset); + } + return status; + } + + /*package*/ void registerCapturePresetDevicesRoleDispatcher( + @NonNull ICapturePresetDevicesRoleDispatcher dispatcher) { + mDevRoleCapturePresetDispatchers.register(dispatcher); + } + + /*package*/ void unregisterCapturePresetDevicesRoleDispatcher( + @NonNull ICapturePresetDevicesRoleDispatcher dispatcher) { + mDevRoleCapturePresetDispatchers.unregister(dispatcher); + } + /** * Implements the communication with AudioSystem to (dis)connect a device in the native layers * @param connect true if connection @@ -1306,6 +1370,19 @@ public class AudioDeviceInventory { mPrefDevDispatchers.finishBroadcast(); } + private void dispatchDevicesRoleForCapturePreset( + int capturePreset, int role, @NonNull List<AudioDeviceAttributes> devices) { + final int nbDispatchers = mDevRoleCapturePresetDispatchers.beginBroadcast(); + for (int i = 0; i < nbDispatchers; ++i) { + try { + mDevRoleCapturePresetDispatchers.getBroadcastItem(i).dispatchDevicesRoleChanged( + capturePreset, role, devices); + } catch (RemoteException e) { + } + } + mDevRoleCapturePresetDispatchers.finishBroadcast(); + } + //---------------------------------------------------------- // For tests only diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index 4378490d19c5..f63c2ee5ee94 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -84,6 +84,7 @@ import android.media.IAudioFocusDispatcher; import android.media.IAudioRoutesObserver; import android.media.IAudioServerStateDispatcher; import android.media.IAudioService; +import android.media.ICapturePresetDevicesRoleDispatcher; import android.media.IPlaybackConfigDispatcher; import android.media.IRecordingConfigDispatcher; import android.media.IRingtonePlayer; @@ -1987,6 +1988,94 @@ public class AudioService extends IAudioService.Stub mDeviceBroker.unregisterStrategyPreferredDevicesDispatcher(dispatcher); } + /** + * @see AudioManager#setPreferredDeviceForCapturePreset(int, AudioDeviceAttributes) + */ + public int setPreferredDevicesForCapturePreset( + int capturePreset, List<AudioDeviceAttributes> devices) { + if (devices == null) { + return AudioSystem.ERROR; + } + enforceModifyAudioRoutingPermission(); + final String logString = String.format( + "setPreferredDevicesForCapturePreset u/pid:%d/%d source:%d dev:%s", + Binder.getCallingUid(), Binder.getCallingPid(), capturePreset, + devices.stream().map(e -> e.toString()).collect(Collectors.joining(","))); + sDeviceLogger.log(new AudioEventLogger.StringEvent(logString).printLog(TAG)); + if (devices.stream().anyMatch(device -> + device.getRole() == AudioDeviceAttributes.ROLE_OUTPUT)) { + Log.e(TAG, "Unsupported output routing in " + logString); + return AudioSystem.ERROR; + } + + final int status = mDeviceBroker.setPreferredDevicesForCapturePresetSync( + capturePreset, devices); + if (status != AudioSystem.SUCCESS) { + Log.e(TAG, String.format("Error %d in %s)", status, logString)); + } + + return status; + } + + /** @see AudioManager#clearPreferredDevicesForCapturePreset(int) */ + public int clearPreferredDevicesForCapturePreset(int capturePreset) { + enforceModifyAudioRoutingPermission(); + final String logString = String.format( + "removePreferredDeviceForCapturePreset source:%d", capturePreset); + sDeviceLogger.log(new AudioEventLogger.StringEvent(logString).printLog(TAG)); + + final int status = mDeviceBroker.clearPreferredDevicesForCapturePresetSync(capturePreset); + if (status != AudioSystem.SUCCESS) { + Log.e(TAG, String.format("Error %d in %s", status, logString)); + } + return status; + } + + /** + * @see AudioManager#getPreferredDevicesForCapturePreset(int) + */ + public List<AudioDeviceAttributes> getPreferredDevicesForCapturePreset(int capturePreset) { + enforceModifyAudioRoutingPermission(); + List<AudioDeviceAttributes> devices = new ArrayList<>(); + final long identity = Binder.clearCallingIdentity(); + final int status = AudioSystem.getDevicesForRoleAndCapturePreset( + capturePreset, AudioSystem.DEVICE_ROLE_PREFERRED, devices); + Binder.restoreCallingIdentity(identity); + if (status != AudioSystem.SUCCESS) { + Log.e(TAG, String.format("Error %d in getPreferredDeviceForCapturePreset(%d)", + status, capturePreset)); + return new ArrayList<AudioDeviceAttributes>(); + } else { + return devices; + } + } + + /** + * @see AudioManager#addOnPreferredDevicesForCapturePresetChangedListener( + * Executor, OnPreferredDevicesForCapturePresetChangedListener) + */ + public void registerCapturePresetDevicesRoleDispatcher( + @Nullable ICapturePresetDevicesRoleDispatcher dispatcher) { + if (dispatcher == null) { + return; + } + enforceModifyAudioRoutingPermission(); + mDeviceBroker.registerCapturePresetDevicesRoleDispatcher(dispatcher); + } + + /** + * @see AudioManager#removeOnPreferredDevicesForCapturePresetChangedListener( + * AudioManager.OnPreferredDevicesForCapturePresetChangedListener) + */ + public void unregisterCapturePresetDevicesRoleDispatcher( + @Nullable ICapturePresetDevicesRoleDispatcher dispatcher) { + if (dispatcher == null) { + return; + } + enforceModifyAudioRoutingPermission(); + mDeviceBroker.unregisterCapturePresetDevicesRoleDispatcher(dispatcher); + } + /** @see AudioManager#getDevicesForAttributes(AudioAttributes) */ public @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributes( @NonNull AudioAttributes attributes) { @@ -4097,6 +4186,62 @@ public class AudioService extends IAudioService.Stub } } + /** @see AudioManager#adjustSuggestedStreamVolumeForUid(int, int, int, String, int, int, int) */ + @Override + public void adjustSuggestedStreamVolumeForUid(int streamType, int direction, int flags, + @NonNull String packageName, int uid, int pid, UserHandle userHandle, + int targetSdkVersion) { + if (Binder.getCallingUid() != Process.SYSTEM_UID) { + throw new SecurityException("Should only be called from system process"); + } + + final boolean hasModifyAudioSettings = + mContext.checkPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS, pid, uid) + == PackageManager.PERMISSION_GRANTED; + // direction and stream type swap here because the public + // adjustSuggested has a different order than the other methods. + adjustSuggestedStreamVolume(direction, streamType, flags, packageName, packageName, uid, + hasModifyAudioSettings, VOL_ADJUST_NORMAL); + } + + /** @see AudioManager#adjustStreamVolumeForUid(int, int, int, String, int, int, int) */ + @Override + public void adjustStreamVolumeForUid(int streamType, int direction, int flags, + @NonNull String packageName, int uid, int pid, UserHandle userHandle, + int targetSdkVersion) { + if (Binder.getCallingUid() != Process.SYSTEM_UID) { + throw new SecurityException("Should only be called from system process"); + } + + if (direction != AudioManager.ADJUST_SAME) { + sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_ADJUST_VOL_UID, streamType, + direction/*val1*/, flags/*val2*/, + new StringBuilder(packageName).append(" uid:").append(uid) + .toString())); + } + final boolean hasModifyAudioSettings = + mContext.checkPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS, pid, uid) + == PackageManager.PERMISSION_GRANTED; + adjustStreamVolume(streamType, direction, flags, packageName, packageName, uid, + hasModifyAudioSettings, VOL_ADJUST_NORMAL); + } + + /** @see AudioManager#setStreamVolumeForUid(int, int, int, String, int, int, int) */ + @Override + public void setStreamVolumeForUid(int streamType, int index, int flags, + @NonNull String packageName, int uid, int pid, UserHandle userHandle, + int targetSdkVersion) { + if (Binder.getCallingUid() != Process.SYSTEM_UID) { + throw new SecurityException("Should only be called from system process"); + } + + final boolean hasModifyAudioSettings = + mContext.checkPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS, pid, uid) + == PackageManager.PERMISSION_GRANTED; + setStreamVolume(streamType, index, flags, packageName, packageName, uid, + hasModifyAudioSettings); + } + //========================================================================================== // Sound Effects //========================================================================================== @@ -7982,43 +8127,6 @@ public class AudioService extends IAudioService.Stub } @Override - public void adjustSuggestedStreamVolumeForUid(int streamType, int direction, int flags, - String callingPackage, int uid, int pid) { - final boolean hasModifyAudioSettings = - mContext.checkPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS, pid, uid) - == PackageManager.PERMISSION_GRANTED; - // direction and stream type swap here because the public - // adjustSuggested has a different order than the other methods. - adjustSuggestedStreamVolume(direction, streamType, flags, callingPackage, - callingPackage, uid, hasModifyAudioSettings, VOL_ADJUST_NORMAL); - } - - @Override - public void adjustStreamVolumeForUid(int streamType, int direction, int flags, - String callingPackage, int uid, int pid) { - if (direction != AudioManager.ADJUST_SAME) { - sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_ADJUST_VOL_UID, streamType, - direction/*val1*/, flags/*val2*/, new StringBuilder(callingPackage) - .append(" uid:").append(uid).toString())); - } - final boolean hasModifyAudioSettings = - mContext.checkPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS, pid, uid) - == PackageManager.PERMISSION_GRANTED; - adjustStreamVolume(streamType, direction, flags, callingPackage, - callingPackage, uid, hasModifyAudioSettings, VOL_ADJUST_NORMAL); - } - - @Override - public void setStreamVolumeForUid(int streamType, int direction, int flags, - String callingPackage, int uid, int pid) { - final boolean hasModifyAudioSettings = - mContext.checkPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS, pid, uid) - == PackageManager.PERMISSION_GRANTED; - setStreamVolume(streamType, direction, flags, callingPackage, callingPackage, uid, - hasModifyAudioSettings); - } - - @Override public int getRingerModeInternal() { return AudioService.this.getRingerModeInternal(); } diff --git a/services/core/java/com/android/server/audio/AudioSystemAdapter.java b/services/core/java/com/android/server/audio/AudioSystemAdapter.java index a0e1ca78a5e7..ae64990fd8d0 100644 --- a/services/core/java/com/android/server/audio/AudioSystemAdapter.java +++ b/services/core/java/com/android/server/audio/AudioSystemAdapter.java @@ -101,6 +101,40 @@ public class AudioSystemAdapter { } /** + * Same as (@link AudioSystem#setDevicesRoleForCapturePreset(int, List)) + * @param capturePreset + * @param role + * @param devices + * @return + */ + public int setDevicesRoleForCapturePreset(int capturePreset, int role, + @NonNull List<AudioDeviceAttributes> devices) { + return AudioSystem.setDevicesRoleForCapturePreset(capturePreset, role, devices); + } + + /** + * Same as {@link AudioSystem#removeDevicesRoleForCapturePreset(int, int)} + * @param capturePreset + * @param role + * @param devicesToRemove + * @return + */ + public int removeDevicesRoleForCapturePreset( + int capturePreset, int role, @NonNull List<AudioDeviceAttributes> devicesToRemove) { + return AudioSystem.removeDevicesRoleForCapturePreset(capturePreset, role, devicesToRemove); + } + + /** + * Same as {@link AudioSystem#} + * @param capturePreset + * @param role + * @return + */ + public int clearDevicesRoleForCapturePreset(int capturePreset, int role) { + return AudioSystem.clearDevicesRoleForCapturePreset(capturePreset, role); + } + + /** * Same as {@link AudioSystem#setParameters(String)} * @param keyValuePairs * @return diff --git a/services/core/java/com/android/server/audio/MediaFocusControl.java b/services/core/java/com/android/server/audio/MediaFocusControl.java index bbc29b0bf89b..f02bb8ffe17f 100644 --- a/services/core/java/com/android/server/audio/MediaFocusControl.java +++ b/services/core/java/com/android/server/audio/MediaFocusControl.java @@ -19,6 +19,7 @@ package com.android.server.audio; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.AppOpsManager; +import android.content.ContentResolver; import android.content.Context; import android.media.AudioAttributes; import android.media.AudioFocusInfo; @@ -94,8 +95,9 @@ public class MediaFocusControl implements PlayerFocusEnforcer { mContext = cntxt; mAppOps = (AppOpsManager)mContext.getSystemService(Context.APP_OPS_SERVICE); mFocusEnforcer = pfe; - mMultiAudioFocusEnabled = Settings.System.getInt(mContext.getContentResolver(), - Settings.System.MULTI_AUDIO_FOCUS_ENABLED, 0) != 0; + final ContentResolver cr = mContext.getContentResolver(); + mMultiAudioFocusEnabled = Settings.System.getIntForUser(cr, + Settings.System.MULTI_AUDIO_FOCUS_ENABLED, 0, cr.getUserId()) != 0; } protected void dump(PrintWriter pw) { @@ -1081,8 +1083,9 @@ public class MediaFocusControl implements PlayerFocusEnforcer { public void updateMultiAudioFocus(boolean enabled) { Log.d(TAG, "updateMultiAudioFocus( " + enabled + " )"); mMultiAudioFocusEnabled = enabled; - Settings.System.putInt(mContext.getContentResolver(), - Settings.System.MULTI_AUDIO_FOCUS_ENABLED, enabled ? 1 : 0); + final ContentResolver cr = mContext.getContentResolver(); + Settings.System.putIntForUser(cr, + Settings.System.MULTI_AUDIO_FOCUS_ENABLED, enabled ? 1 : 0, cr.getUserId()); if (!mFocusStack.isEmpty()) { final FocusRequester fr = mFocusStack.peek(); fr.handleFocusLoss(AudioManager.AUDIOFOCUS_LOSS, null, false); diff --git a/services/core/java/com/android/server/biometrics/sensors/AcquisitionClient.java b/services/core/java/com/android/server/biometrics/sensors/AcquisitionClient.java index 73fc17aa26f1..9898d7676178 100644 --- a/services/core/java/com/android/server/biometrics/sensors/AcquisitionClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/AcquisitionClient.java @@ -98,7 +98,11 @@ public abstract class AcquisitionClient<T> extends ClientMonitor<T> implements I } if (finish) { - mCallback.onClientFinished(this, false /* success */); + if (mCallback == null) { + Slog.e(TAG, "Callback is null, perhaps the client hasn't been started yet?"); + } else { + mCallback.onClientFinished(this, false /* success */); + } } } diff --git a/services/core/java/com/android/server/biometrics/sensors/ClientMonitor.java b/services/core/java/com/android/server/biometrics/sensors/ClientMonitor.java index e585b48d49b6..3c9dddd0b905 100644 --- a/services/core/java/com/android/server/biometrics/sensors/ClientMonitor.java +++ b/services/core/java/com/android/server/biometrics/sensors/ClientMonitor.java @@ -176,6 +176,9 @@ public abstract class ClientMonitor<T> extends LoggableMonitor implements IBinde // TODO(b/157790417): Move this to the scheduler void binderDiedInternal(boolean clearListener) { + Slog.e(TAG, "Binder died, owner: " + getOwnerString() + + ", operation: " + this.getClass().getName()); + if (isAlreadyDone()) { Slog.w(TAG, "Binder died but client is finished, ignoring"); return; diff --git a/services/core/java/com/android/server/biometrics/sensors/face/Face10.java b/services/core/java/com/android/server/biometrics/sensors/face/Face10.java index c134a3faca4f..d2c35feccc11 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/Face10.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/Face10.java @@ -510,8 +510,15 @@ class Face10 implements IHwBinder.DeathRecipient { if (mCurrentChallengeOwner != null) { Slog.w(TAG, "Current challenge owner: " + mCurrentChallengeOwner + ", interrupted by: " + opPackageName); + final ClientMonitorCallbackConverter listener = + mCurrentChallengeOwner.getListener(); + if (listener == null) { + Slog.w(TAG, "Null listener, skip sending interruption callback"); + return; + } + try { - mCurrentChallengeOwner.getListener().onChallengeInterrupted(mSensorId); + listener.onChallengeInterrupted(mSensorId); } catch (RemoteException e) { Slog.e(TAG, "Unable to notify challenge interrupted", e); } @@ -524,7 +531,7 @@ class Face10 implements IHwBinder.DeathRecipient { @Override public void onClientStarted(@NonNull ClientMonitor<?> clientMonitor) { if (client != clientMonitor) { - Slog.e(TAG, "scheduleGenerateChallenge, mismatched client." + Slog.e(TAG, "scheduleGenerateChallenge onClientStarted, mismatched client." + " Expecting: " + client + ", received: " + clientMonitor); return; } diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java index 36d69c93c1cb..f42e18acc821 100644 --- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java +++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java @@ -17,8 +17,8 @@ package com.android.server.display; import android.annotation.Nullable; -import android.app.ActivityManager.StackInfo; import android.app.ActivityTaskManager; +import android.app.ActivityTaskManager.RootTaskInfo; import android.app.IActivityTaskManager; import android.app.TaskStackListener; import android.content.Context; @@ -846,7 +846,7 @@ class AutomaticBrightnessController { public void run() { try { // The foreground app is the top activity of the focused tasks stack. - final StackInfo info = mActivityTaskManager.getFocusedStackInfo(); + final RootTaskInfo info = mActivityTaskManager.getFocusedRootTaskInfo(); if (info == null || info.topActivity == null) { return; } diff --git a/services/core/java/com/android/server/display/BrightnessTracker.java b/services/core/java/com/android/server/display/BrightnessTracker.java index eea1980012a4..9e82d4fe6233 100644 --- a/services/core/java/com/android/server/display/BrightnessTracker.java +++ b/services/core/java/com/android/server/display/BrightnessTracker.java @@ -20,6 +20,7 @@ import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.ActivityManager; import android.app.ActivityTaskManager; +import android.app.ActivityTaskManager.RootTaskInfo; import android.content.BroadcastReceiver; import android.content.ContentResolver; import android.content.Context; @@ -377,14 +378,14 @@ public class BrightnessTracker { } try { - final ActivityManager.StackInfo focusedStack = mInjector.getFocusedStack(); - if (focusedStack != null && focusedStack.topActivity != null) { - builder.setUserId(focusedStack.userId); - builder.setPackageName(focusedStack.topActivity.getPackageName()); + final RootTaskInfo focusedTask = mInjector.getFocusedStack(); + if (focusedTask != null && focusedTask.topActivity != null) { + builder.setUserId(focusedTask.userId); + builder.setPackageName(focusedTask.topActivity.getPackageName()); } else { // Ignore the event because we can't determine user / package. if (DEBUG) { - Slog.d(TAG, "Ignoring event due to null focusedStack."); + Slog.d(TAG, "Ignoring event due to null focusedTask."); } return; } @@ -1104,8 +1105,8 @@ public class BrightnessTracker { } } - public ActivityManager.StackInfo getFocusedStack() throws RemoteException { - return ActivityTaskManager.getService().getFocusedStackInfo(); + public RootTaskInfo getFocusedStack() throws RemoteException { + return ActivityTaskManager.getService().getFocusedRootTaskInfo(); } public void scheduleIdleJob(Context context) { diff --git a/services/core/java/com/android/server/display/ColorFade.java b/services/core/java/com/android/server/display/ColorFade.java index ad3cd67ad65b..73f788901dc9 100644 --- a/services/core/java/com/android/server/display/ColorFade.java +++ b/services/core/java/com/android/server/display/ColorFade.java @@ -493,6 +493,10 @@ final class ColorFade { == Display.COLOR_MODE_DISPLAY_P3; SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer = mDisplayManagerInternal.systemScreenshot(mDisplayId); + if (screenshotBuffer == null) { + Slog.e(TAG, "Failed to take screenshot. Buffer is null"); + return false; + } s.attachAndQueueBufferWithColorSpace(screenshotBuffer.getHardwareBuffer(), screenshotBuffer.getColorSpace()); diff --git a/services/core/java/com/android/server/display/DisplayModeDirector.java b/services/core/java/com/android/server/display/DisplayModeDirector.java index 3c050804f01d..cc6687f8566d 100644 --- a/services/core/java/com/android/server/display/DisplayModeDirector.java +++ b/services/core/java/com/android/server/display/DisplayModeDirector.java @@ -869,10 +869,11 @@ public class DisplayModeDirector { } private void updateRefreshRateSettingLocked() { - float minRefreshRate = Settings.System.getFloat(mContext.getContentResolver(), - Settings.System.MIN_REFRESH_RATE, 0f); - float peakRefreshRate = Settings.System.getFloat(mContext.getContentResolver(), - Settings.System.PEAK_REFRESH_RATE, mDefaultPeakRefreshRate); + final ContentResolver cr = mContext.getContentResolver(); + float minRefreshRate = Settings.System.getFloatForUser(cr, + Settings.System.MIN_REFRESH_RATE, 0f, cr.getUserId()); + float peakRefreshRate = Settings.System.getFloatForUser(cr, + Settings.System.PEAK_REFRESH_RATE, mDefaultPeakRefreshRate, cr.getUserId()); updateRefreshRateSettingLocked(minRefreshRate, peakRefreshRate, mDefaultRefreshRate); } @@ -1301,8 +1302,9 @@ public class DisplayModeDirector { } // TODO: brightnessfloat: make it use float not int private void onBrightnessChangedLocked() { - int brightness = Settings.System.getInt(mContext.getContentResolver(), - Settings.System.SCREEN_BRIGHTNESS, -1); + final ContentResolver cr = mContext.getContentResolver(); + int brightness = Settings.System.getIntForUser(cr, + Settings.System.SCREEN_BRIGHTNESS, -1, cr.getUserId()); Vote vote = null; boolean insideZone = isInsideZone(brightness, mAmbientLux); diff --git a/services/core/java/com/android/server/location/util/SystemSettingsHelper.java b/services/core/java/com/android/server/location/util/SystemSettingsHelper.java index ff4ba914cb9c..39aeaba16579 100644 --- a/services/core/java/com/android/server/location/util/SystemSettingsHelper.java +++ b/services/core/java/com/android/server/location/util/SystemSettingsHelper.java @@ -29,6 +29,7 @@ import static com.android.server.location.LocationManagerService.D; import static com.android.server.location.LocationManagerService.TAG; import android.app.ActivityManager; +import android.content.ContentResolver; import android.content.Context; import android.database.ContentObserver; import android.net.Uri; @@ -330,11 +331,13 @@ public class SystemSettingsHelper extends SettingsHelper { @Override public float getCoarseLocationAccuracyM() { long identity = Binder.clearCallingIdentity(); + final ContentResolver cr = mContext.getContentResolver(); try { - return Settings.Secure.getFloat( - mContext.getContentResolver(), + return Settings.Secure.getFloatForUser( + cr, LOCATION_COARSE_ACCURACY_M, - DEFAULT_COARSE_LOCATION_ACCURACY_M); + DEFAULT_COARSE_LOCATION_ACCURACY_M, + cr.getUserId()); } finally { Binder.restoreCallingIdentity(identity); } diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java index 1e02f49c43e4..793cfcd77414 100644 --- a/services/core/java/com/android/server/media/MediaSessionRecord.java +++ b/services/core/java/com/android/server/media/MediaSessionRecord.java @@ -23,7 +23,6 @@ import android.content.Intent; import android.content.pm.ParceledListSlice; import android.media.AudioAttributes; import android.media.AudioManager; -import android.media.AudioManagerInternal; import android.media.AudioSystem; import android.media.MediaMetadata; import android.media.Rating; @@ -53,8 +52,6 @@ import android.os.SystemClock; import android.util.Log; import android.view.KeyEvent; -import com.android.server.LocalServices; - import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; @@ -144,7 +141,6 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR // Volume handling fields private AudioAttributes mAudioAttrs; private AudioManager mAudioManager; - private AudioManagerInternal mAudioManagerInternal; private int mVolumeType = PlaybackInfo.PLAYBACK_TYPE_LOCAL; private int mVolumeControlType = VolumeProvider.VOLUME_CONTROL_ABSOLUTE; private int mMaxVolume = 0; @@ -179,7 +175,6 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR mContext = mService.getContext(); mHandler = new MessageHandler(handlerLooper); mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE); - mAudioManagerInternal = LocalServices.getService(AudioManagerInternal.class); mAudioAttrs = DEFAULT_ATTRIBUTES; mPolicies = policies; @@ -328,8 +323,9 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR @Override public void run() { try { - mAudioManagerInternal.setStreamVolumeForUid(stream, volumeValue, flags, - opPackageName, uid, pid); + mAudioManager.setStreamVolumeForUid(stream, volumeValue, flags, + opPackageName, uid, pid, + mContext.getApplicationInfo().targetSdkVersion); } catch (IllegalArgumentException | SecurityException e) { Log.e(TAG, "Cannot set volume: stream=" + stream + ", value=" + volumeValue + ", flags=" + flags, e); @@ -518,16 +514,19 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR try { if (useSuggested) { if (AudioSystem.isStreamActive(stream, 0)) { - mAudioManagerInternal.adjustSuggestedStreamVolumeForUid(stream, - direction, flags, opPackageName, uid, pid); + mAudioManager.adjustSuggestedStreamVolumeForUid(stream, + direction, flags, opPackageName, uid, pid, + mContext.getApplicationInfo().targetSdkVersion); } else { - mAudioManagerInternal.adjustSuggestedStreamVolumeForUid( + mAudioManager.adjustSuggestedStreamVolumeForUid( AudioManager.USE_DEFAULT_STREAM_TYPE, direction, - flags | previousFlagPlaySound, opPackageName, uid, pid); + flags | previousFlagPlaySound, opPackageName, uid, pid, + mContext.getApplicationInfo().targetSdkVersion); } } else { - mAudioManagerInternal.adjustStreamVolumeForUid(stream, direction, flags, - opPackageName, uid, pid); + mAudioManager.adjustStreamVolumeForUid(stream, direction, flags, + opPackageName, uid, pid, + mContext.getApplicationInfo().targetSdkVersion); } } catch (IllegalArgumentException | SecurityException e) { Log.e(TAG, "Cannot adjust volume: direction=" + direction + ", stream=" diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java index 9521611c241d..d34502922b66 100644 --- a/services/core/java/com/android/server/media/MediaSessionService.java +++ b/services/core/java/com/android/server/media/MediaSessionService.java @@ -42,7 +42,6 @@ import android.content.pm.PackageManager; import android.content.pm.ParceledListSlice; import android.content.pm.UserInfo; import android.media.AudioManager; -import android.media.AudioManagerInternal; import android.media.AudioPlaybackConfiguration; import android.media.AudioSystem; import android.media.IRemoteVolumeController; @@ -85,7 +84,6 @@ import android.view.ViewConfiguration; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.DumpUtils; -import com.android.server.LocalServices; import com.android.server.SystemService; import com.android.server.SystemService.TargetUser; import com.android.server.Watchdog; @@ -136,7 +134,7 @@ public class MediaSessionService extends SystemService implements Monitor { new ArrayList<>(); private KeyguardManager mKeyguardManager; - private AudioManagerInternal mAudioManagerInternal; + private AudioManager mAudioManager; private ContentResolver mContentResolver; private boolean mHasFeatureLeanback; @@ -162,6 +160,7 @@ public class MediaSessionService extends SystemService implements Monitor { PowerManager pm = mContext.getSystemService(PowerManager.class); mMediaEventWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "handleMediaEvent"); mNotificationManager = mContext.getSystemService(NotificationManager.class); + mAudioManager = mContext.getSystemService(AudioManager.class); } @Override @@ -169,7 +168,6 @@ public class MediaSessionService extends SystemService implements Monitor { publishBinderService(Context.MEDIA_SESSION_SERVICE, mSessionManagerImpl); Watchdog.getInstance().addMonitor(this); mKeyguardManager = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE); - mAudioManagerInternal = LocalServices.getService(AudioManagerInternal.class); mAudioPlayerStateMonitor = AudioPlayerStateMonitor.getInstance(mContext); mAudioPlayerStateMonitor.registerListener( (config, isRemoved) -> { @@ -2057,8 +2055,9 @@ public class MediaSessionService extends SystemService implements Monitor { callingPid = pid; } try { - mAudioManagerInternal.adjustSuggestedStreamVolumeForUid(suggestedStream, - direction, flags, callingOpPackageName, callingUid, callingPid); + mAudioManager.adjustSuggestedStreamVolumeForUid(suggestedStream, + direction, flags, callingOpPackageName, callingUid, callingPid, + getContext().getApplicationInfo().targetSdkVersion); } catch (SecurityException | IllegalArgumentException e) { Log.e(TAG, "Cannot adjust volume: direction=" + direction + ", suggestedStream=" + suggestedStream + ", flags=" + flags diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 5bc6e237ef37..52e90218fd24 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -1684,8 +1684,10 @@ public class NotificationManagerService extends SystemService { final IntArray userIds = mUserProfiles.getCurrentProfileIds(); for (int i = 0; i < userIds.size(); i++) { - mArchive.updateHistoryEnabled(userIds.get(i), Settings.Secure.getInt(resolver, - Settings.Secure.NOTIFICATION_HISTORY_ENABLED, 0) == 1); + mArchive.updateHistoryEnabled(userIds.get(i), + Settings.Secure.getIntForUser(resolver, + Settings.Secure.NOTIFICATION_HISTORY_ENABLED, 0, + userIds.get(i)) == 1); } } if (uri == null || NOTIFICATION_SHOW_MEDIA_ON_QUICK_SETTINGS_URI.equals(uri)) { @@ -7148,9 +7150,10 @@ public class NotificationManagerService extends SystemService { } protected void playInCallNotification() { + final ContentResolver cr = getContext().getContentResolver(); if (mAudioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_NORMAL - && Settings.Secure.getInt(getContext().getContentResolver(), - Settings.Secure.IN_CALL_NOTIFICATION_ENABLED, 1) != 0) { + && Settings.Secure.getIntForUser(cr, + Settings.Secure.IN_CALL_NOTIFICATION_ENABLED, 1, cr.getUserId()) != 0) { new Thread() { @Override public void run() { @@ -8462,7 +8465,10 @@ public class NotificationManagerService extends SystemService { if (Notification.CATEGORY_CAR_EMERGENCY.equals(notification.category) || Notification.CATEGORY_CAR_WARNING.equals(notification.category) || Notification.CATEGORY_CAR_INFORMATION.equals(notification.category)) { - checkCallerIsSystem(); + getContext().enforceCallingPermission( + android.Manifest.permission.SEND_CATEGORY_CAR_NOTIFICATIONS, + String.format("Notification category %s restricted", + notification.category)); } } diff --git a/services/core/java/com/android/server/om/OverlayActorEnforcer.java b/services/core/java/com/android/server/om/OverlayActorEnforcer.java index 8c03c6ce3092..8121a43e9060 100644 --- a/services/core/java/com/android/server/om/OverlayActorEnforcer.java +++ b/services/core/java/com/android/server/om/OverlayActorEnforcer.java @@ -26,6 +26,7 @@ import android.os.Process; import android.text.TextUtils; import android.util.Pair; +import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ArrayUtils; import com.android.internal.util.CollectionUtils; @@ -66,7 +67,7 @@ public class OverlayActorEnforcer { String actorNamespace = actorUri.getAuthority(); Map<String, String> namespace = namedActors.get(actorNamespace); - if (namespace == null) { + if (ArrayUtils.isEmpty(namespace)) { return Pair.create(null, ActorState.MISSING_NAMESPACE); } @@ -102,21 +103,32 @@ public class OverlayActorEnforcer { * See {@link OverlayActorEnforcer} class comment for actor requirements. * @return true if the actor is allowed to act on the target overlayInfo */ - private ActorState isAllowedActor(String methodName, OverlayInfo overlayInfo, + @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) + public ActorState isAllowedActor(String methodName, OverlayInfo overlayInfo, int callingUid, int userId) { + // Checked first to avoid package not found errors, which are ignored for calls from shell switch (callingUid) { case Process.ROOT_UID: case Process.SYSTEM_UID: return ActorState.ALLOWED; } + final String targetPackageName = overlayInfo.targetPackageName; + final PackageInfo targetPkgInfo = mPackageManager.getPackageInfo(targetPackageName, userId); + if (targetPkgInfo == null) { + return ActorState.TARGET_NOT_FOUND; + } + + if ((targetPkgInfo.applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { + return ActorState.ALLOWED; + } + String[] callingPackageNames = mPackageManager.getPackagesForUid(callingUid); if (ArrayUtils.isEmpty(callingPackageNames)) { return ActorState.NO_PACKAGES_FOR_UID; } // A target is always an allowed actor for itself - String targetPackageName = overlayInfo.targetPackageName; if (ArrayUtils.contains(callingPackageNames, targetPackageName)) { return ActorState.ALLOWED; } @@ -149,7 +161,7 @@ public class OverlayActorEnforcer { targetOverlayable = mPackageManager.getOverlayableForTarget(targetPackageName, targetOverlayableName, userId); } catch (IOException e) { - return ActorState.UNABLE_TO_GET_TARGET; + return ActorState.UNABLE_TO_GET_TARGET_OVERLAYABLE; } if (targetOverlayable == null) { @@ -189,7 +201,7 @@ public class OverlayActorEnforcer { } // Currently only pre-installed apps can be actors - if (!appInfo.isSystemApp() && !appInfo.isUpdatedSystemApp()) { + if (!appInfo.isSystemApp()) { return ActorState.ACTOR_NOT_PREINSTALLED; } @@ -203,22 +215,25 @@ public class OverlayActorEnforcer { /** * For easier logging/debugging, a set of all possible failure/success states when running * enforcement. + * + * The ordering of this enum should be maintained in the order that cases are checked in code, + * as this ordering is used inside OverlayActorEnforcerTests. */ public enum ActorState { - ALLOWED, - INVALID_ACTOR, - MISSING_NAMESPACE, - MISSING_PACKAGE, - MISSING_APP_INFO, - ACTOR_NOT_PREINSTALLED, + TARGET_NOT_FOUND, NO_PACKAGES_FOR_UID, - MISSING_ACTOR_NAME, - ERROR_READING_OVERLAYABLE, MISSING_TARGET_OVERLAYABLE_NAME, + MISSING_LEGACY_PERMISSION, + ERROR_READING_OVERLAYABLE, + UNABLE_TO_GET_TARGET_OVERLAYABLE, MISSING_OVERLAYABLE, INVALID_OVERLAYABLE_ACTOR_NAME, NO_NAMED_ACTORS, - UNABLE_TO_GET_TARGET, - MISSING_LEGACY_PERMISSION + MISSING_NAMESPACE, + MISSING_ACTOR_NAME, + MISSING_APP_INFO, + ACTOR_NOT_PREINSTALLED, + INVALID_ACTOR, + ALLOWED } } diff --git a/services/core/java/com/android/server/pm/ApexManager.java b/services/core/java/com/android/server/pm/ApexManager.java index 07527c2a15d8..5b5ec4221093 100644 --- a/services/core/java/com/android/server/pm/ApexManager.java +++ b/services/core/java/com/android/server/pm/ApexManager.java @@ -778,7 +778,7 @@ public abstract class ApexManager { void registerApkInApex(AndroidPackage pkg) { synchronized (mLock) { for (ActiveApexInfo aai : mActiveApexInfosCache) { - if (pkg.getBaseCodePath().startsWith(aai.apexDirectory.getAbsolutePath())) { + if (pkg.getBaseApkPath().startsWith(aai.apexDirectory.getAbsolutePath())) { List<String> apks = mApksInApex.get(aai.apexModuleName); if (apks == null) { apks = Lists.newArrayList(); diff --git a/services/core/java/com/android/server/pm/ComponentResolver.java b/services/core/java/com/android/server/pm/ComponentResolver.java index d25ddad174f9..4be509b3f464 100644 --- a/services/core/java/com/android/server/pm/ComponentResolver.java +++ b/services/core/java/com/android/server/pm/ComponentResolver.java @@ -623,7 +623,6 @@ public class ComponentResolver { AndroidPackage pkg = sPackageManagerInternal.getPackage(p.getPackageName()); if (pkg != null) { - // TODO(b/135203078): Print AppInfo? pw.print(" applicationInfo="); pw.println(pkg.toAppInfoWithoutState()); } } diff --git a/services/core/java/com/android/server/pm/OtaDexoptService.java b/services/core/java/com/android/server/pm/OtaDexoptService.java index eddab76de5ee..7db2319b5164 100644 --- a/services/core/java/com/android/server/pm/OtaDexoptService.java +++ b/services/core/java/com/android/server/pm/OtaDexoptService.java @@ -384,17 +384,17 @@ public class OtaDexoptService extends IOtaDexopt.Stub { if (!PackageDexOptimizer.canOptimizePackage(pkg)) { continue; } - if (pkg.getCodePath() == null) { + if (pkg.getPath() == null) { Slog.w(TAG, "Package " + pkg + " can be optimized but has null codePath"); continue; } // If the path is in /system, /vendor, /product or /system_ext, ignore. It will // have been ota-dexopted into /data/ota and moved into the dalvik-cache already. - if (pkg.getCodePath().startsWith("/system") - || pkg.getCodePath().startsWith("/vendor") - || pkg.getCodePath().startsWith("/product") - || pkg.getCodePath().startsWith("/system_ext")) { + if (pkg.getPath().startsWith("/system") + || pkg.getPath().startsWith("/vendor") + || pkg.getPath().startsWith("/product") + || pkg.getPath().startsWith("/system_ext")) { continue; } @@ -408,7 +408,7 @@ public class OtaDexoptService extends IOtaDexopt.Stub { for (String dexCodeInstructionSet : dexCodeInstructionSets) { for (String path : paths) { String oatDir = PackageDexOptimizer.getOatDir( - new File(pkg.getCodePath())).getAbsolutePath(); + new File(pkg.getPath())).getAbsolutePath(); // TODO: Check first whether there is an artifact, to save the roundtrip time. diff --git a/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java b/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java index 8af7e1f4f6d1..da4ea16d0bfd 100644 --- a/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java +++ b/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java @@ -136,7 +136,7 @@ final class PackageAbiHelperImpl implements PackageAbiHelper { // Trying to derive the paths, thus need the raw ABI info from the parsed package, and the // current state in PackageSetting is irrelevant. return deriveNativeLibraryPaths(new Abis(pkg.getPrimaryCpuAbi(), pkg.getSecondaryCpuAbi()), - appLib32InstallDir, pkg.getCodePath(), pkg.getBaseCodePath(), pkg.isSystem(), + appLib32InstallDir, pkg.getPath(), pkg.getBaseApkPath(), pkg.isSystem(), isUpdatedSystemApp); } @@ -205,11 +205,11 @@ final class PackageAbiHelperImpl implements PackageAbiHelper { @Override public Abis getBundledAppAbis(AndroidPackage pkg) { - final String apkName = deriveCodePathName(pkg.getCodePath()); + final String apkName = deriveCodePathName(pkg.getPath()); // If "/system/lib64/apkname" exists, assume that is the per-package // native library directory to use; otherwise use "/system/lib/apkname". - final String apkRoot = calculateBundledApkRoot(pkg.getBaseCodePath()); + final String apkRoot = calculateBundledApkRoot(pkg.getBaseApkPath()); final Abis abis = getBundledAppAbi(pkg, apkRoot, apkName); return abis; } @@ -223,7 +223,7 @@ final class PackageAbiHelperImpl implements PackageAbiHelper { * @param apkName the name of the installed package. */ private Abis getBundledAppAbi(AndroidPackage pkg, String apkRoot, String apkName) { - final File codeFile = new File(pkg.getCodePath()); + final File codeFile = new File(pkg.getPath()); final boolean has64BitLibs; final boolean has32BitLibs; @@ -304,15 +304,15 @@ final class PackageAbiHelperImpl implements PackageAbiHelper { String pkgRawSecondaryCpuAbi = AndroidPackageUtils.getRawSecondaryCpuAbi(pkg); final NativeLibraryPaths initialLibraryPaths = deriveNativeLibraryPaths( new Abis(pkgRawPrimaryCpuAbi, pkgRawSecondaryCpuAbi), - PackageManagerService.sAppLib32InstallDir, pkg.getCodePath(), - pkg.getBaseCodePath(), pkg.isSystem(), + PackageManagerService.sAppLib32InstallDir, pkg.getPath(), + pkg.getBaseApkPath(), pkg.isSystem(), isUpdatedSystemApp); final boolean extractLibs = shouldExtractLibs(pkg, isUpdatedSystemApp); final String nativeLibraryRootStr = initialLibraryPaths.nativeLibraryRootDir; final boolean useIsaSpecificSubdirs = initialLibraryPaths.nativeLibraryRootRequiresIsa; - final boolean onIncremental = isIncrementalPath(pkg.getCodePath()); + final boolean onIncremental = isIncrementalPath(pkg.getPath()); String primaryCpuAbi = null; String secondaryCpuAbi = null; @@ -453,7 +453,7 @@ final class PackageAbiHelperImpl implements PackageAbiHelper { final Abis abis = new Abis(primaryCpuAbi, secondaryCpuAbi); return new Pair<>(abis, deriveNativeLibraryPaths(abis, PackageManagerService.sAppLib32InstallDir, - pkg.getCodePath(), pkg.getBaseCodePath(), pkg.isSystem(), + pkg.getPath(), pkg.getBaseApkPath(), pkg.isSystem(), isUpdatedSystemApp)); } diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java index 0d8ba3e54801..42e6d8f0bf83 100644 --- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java +++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java @@ -199,7 +199,7 @@ public class PackageDexOptimizer { throw new IllegalStateException("Inconsistent information " + "between PackageParser.Package and its ApplicationInfo. " + "pkg.getAllCodePaths=" + paths - + " pkg.getBaseCodePath=" + pkg.getBaseCodePath() + + " pkg.getBaseCodePath=" + pkg.getBaseApkPath() + " pkg.getSplitCodePaths=" + (splitCodePaths == null ? "null" : Arrays.toString(splitCodePaths))); } @@ -772,7 +772,7 @@ public class PackageDexOptimizer { if (!AndroidPackageUtils.canHaveOatDir(pkg, isUpdatedSystemApp)) { return null; } - File codePath = new File(pkg.getCodePath()); + File codePath = new File(pkg.getPath()); if (!codePath.isDirectory()) { return null; } diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index ca125320bbf2..17cd8f58c3a3 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -2083,7 +2083,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { if (ps == null) { return 0; } - final File apkDirOrPath = ps.getCodePath(); + final File apkDirOrPath = ps.getPath(); if (apkDirOrPath == null) { return 0; } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 9f78f0f08fd1..ed2c058b5c8a 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -2220,7 +2220,7 @@ public class PackageManagerService extends IPackageManager.Stub // Send installed broadcasts if the package is not a static shared lib. if (res.pkg.getStaticSharedLibName() == null) { mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash( - res.pkg.getBaseCodePath()); + res.pkg.getBaseApkPath()); // Send added for users that see the package for the first time // sendPackageAddedForNewUsers also deals with system apps @@ -3101,7 +3101,7 @@ public class PackageManagerService extends IPackageManager.Stub final int packageSettingCount = mSettings.mPackages.size(); for (int i = packageSettingCount - 1; i >= 0; i--) { PackageSetting ps = mSettings.mPackages.valueAt(i); - if (!isExternal(ps) && (ps.getCodePath() == null || !ps.getCodePath().exists()) + if (!isExternal(ps) && (ps.getPath() == null || !ps.getPath().exists()) && mSettings.getDisabledSystemPkgLPr(ps.name) != null) { mSettings.mPackages.removeAt(i); mSettings.enableSystemPackageLPw(ps.name); @@ -3266,11 +3266,11 @@ public class PackageManagerService extends IPackageManager.Stub logCriticalInfo(Log.WARN, "Expecting better updated system app for " + ps.name + "; removing system app. Last known" - + " codePath=" + ps.getCodePathString() + + " codePath=" + ps.getPathString() + ", versionCode=" + ps.versionCode + "; scanned versionCode=" + scannedPkg.getLongVersionCode()); removePackageLI(scannedPkg, true); - mExpectingBetter.put(ps.name, ps.getCodePath()); + mExpectingBetter.put(ps.name, ps.getPath()); } continue; @@ -3293,14 +3293,14 @@ public class PackageManagerService extends IPackageManager.Stub // code path, but, changes the package name. final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name); - if (disabledPs.getCodePath() == null || !disabledPs.getCodePath().exists() + if (disabledPs.getPath() == null || !disabledPs.getPath().exists() || disabledPs.pkg == null) { possiblyDeletedUpdatedSystemApps.add(ps.name); } else { // We're expecting that the system app should remain disabled, but add // it to expecting better to recover in case the data version cannot // be scanned. - mExpectingBetter.put(disabledPs.name, disabledPs.getCodePath()); + mExpectingBetter.put(disabledPs.name, disabledPs.getPath()); } } } @@ -3373,7 +3373,7 @@ public class PackageManagerService extends IPackageManager.Stub // special privileges removePackageLI(pkg, true); try { - final File codePath = new File(pkg.getCodePath()); + final File codePath = new File(pkg.getPath()); scanPackageTracedLI(codePath, 0, scanFlags, 0, null); } catch (PackageManagerException e) { Slog.e(TAG, "Failed to parse updated, ex-system package: " @@ -3854,7 +3854,7 @@ public class PackageManagerService extends IPackageManager.Stub // If we don't, installing the system package fails during scan enableSystemPackageLPw(stubPkg); } - installPackageFromSystemLIF(stubPkg.getCodePath(), + installPackageFromSystemLIF(stubPkg.getPath(), mUserManager.getUserIds() /*allUserHandles*/, null /*origUserHandles*/, true /*writeSettings*/); } catch (PackageManagerException pme) { @@ -3878,7 +3878,7 @@ public class PackageManagerService extends IPackageManager.Stub clearAppDataLIF(pkg, UserHandle.USER_ALL, FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); mDexManager.notifyPackageUpdated(pkg.getPackageName(), - pkg.getBaseCodePath(), pkg.getSplitCodePaths()); + pkg.getBaseApkPath(), pkg.getSplitCodePaths()); } return true; } @@ -3890,10 +3890,10 @@ public class PackageManagerService extends IPackageManager.Stub Slog.i(TAG, "Uncompressing system stub; pkg: " + stubPkg.getPackageName()); } // uncompress the binary to its eventual destination on /data - final File scanFile = decompressPackage(stubPkg.getPackageName(), stubPkg.getCodePath()); + final File scanFile = decompressPackage(stubPkg.getPackageName(), stubPkg.getPath()); if (scanFile == null) { throw new PackageManagerException( - "Unable to decompress stub at " + stubPkg.getCodePath()); + "Unable to decompress stub at " + stubPkg.getPath()); } synchronized (mLock) { mSettings.disableSystemPackageLPw(stubPkg.getPackageName(), true /*replaced*/); @@ -9261,11 +9261,11 @@ public class PackageManagerService extends IPackageManager.Stub // When upgrading from pre-N MR1, verify the package time stamp using the package // directory and not the APK file. final long lastModifiedTime = mIsPreNMR1Upgrade - ? new File(parsedPackage.getCodePath()).lastModified() + ? new File(parsedPackage.getPath()).lastModified() : getLastModifiedTime(parsedPackage); final VersionInfo settingsVersionForPackage = getSettingsVersionForPackage(parsedPackage); if (ps != null && !forceCollect - && ps.getCodePathString().equals(parsedPackage.getCodePath()) + && ps.getPathString().equals(parsedPackage.getPath()) && ps.timeStamp == lastModifiedTime && !isCompatSignatureUpdateNeeded(settingsVersionForPackage) && !isRecoverSignatureUpdateNeeded(settingsVersionForPackage)) { @@ -9283,8 +9283,8 @@ public class PackageManagerService extends IPackageManager.Stub Slog.w(TAG, "PackageSetting for " + ps.name + " is missing signatures. Collecting certs again to recover them."); } else { - Slog.i(TAG, parsedPackage.getCodePath() + " changed; collecting certs" + - (forceCollect ? " (forced)" : "")); + Slog.i(TAG, parsedPackage.getPath() + " changed; collecting certs" + + (forceCollect ? " (forced)" : "")); } try { @@ -9368,7 +9368,7 @@ public class PackageManagerService extends IPackageManager.Stub * Returns if forced apk verification can be skipped for the whole package, including splits. */ private boolean canSkipForcedPackageVerification(AndroidPackage pkg) { - if (!canSkipForcedApkVerification(pkg.getBaseCodePath())) { + if (!canSkipForcedApkVerification(pkg.getBaseApkPath())) { return false; } // TODO: Allow base and splits to be verified individually. @@ -9499,7 +9499,7 @@ public class PackageManagerService extends IPackageManager.Stub } final boolean newPkgChangedPaths = pkgAlreadyExists - && !pkgSetting.getCodePathString().equals(parsedPackage.getCodePath()); + && !pkgSetting.getPathString().equals(parsedPackage.getPath()); final boolean newPkgVersionGreater = pkgAlreadyExists && parsedPackage.getLongVersionCode() > pkgSetting.versionCode; final boolean isSystemPkgBetter = scanSystemPartition && isSystemPkgUpdated @@ -9518,11 +9518,11 @@ public class PackageManagerService extends IPackageManager.Stub "System package updated;" + " name: " + pkgSetting.name + "; " + pkgSetting.versionCode + " --> " + parsedPackage.getLongVersionCode() - + "; " + pkgSetting.getCodePathString() - + " --> " + parsedPackage.getCodePath()); + + "; " + pkgSetting.getPathString() + + " --> " + parsedPackage.getPath()); final InstallArgs args = createInstallArgsForExisting( - pkgSetting.getCodePathString(), getAppDexInstructionSets( + pkgSetting.getPathString(), getAppDexInstructionSets( pkgSetting.primaryCpuAbiString, pkgSetting.secondaryCpuAbiString)); args.cleanUpResourcesLI(); synchronized (mLock) { @@ -9535,7 +9535,7 @@ public class PackageManagerService extends IPackageManager.Stub // equal to the version on the /data partition. Throw an exception and use // the application already installed on the /data partition. throw new PackageManagerException(Log.WARN, "Package " + parsedPackage.getPackageName() - + " at " + parsedPackage.getCodePath() + " ignored: updated version " + + " at " + parsedPackage.getPath() + " ignored: updated version " + pkgSetting.versionCode + " better than this " + parsedPackage.getLongVersionCode()); } @@ -9597,10 +9597,10 @@ public class PackageManagerService extends IPackageManager.Stub + " name: " + pkgSetting.name + "; " + pkgSetting.versionCode + " --> " + parsedPackage.getLongVersionCode() - + "; " + pkgSetting.getCodePathString() + " --> " - + parsedPackage.getCodePath()); + + "; " + pkgSetting.getPathString() + " --> " + + parsedPackage.getPath()); InstallArgs args = createInstallArgsForExisting( - pkgSetting.getCodePathString(), getAppDexInstructionSets( + pkgSetting.getPathString(), getAppDexInstructionSets( pkgSetting.primaryCpuAbiString, pkgSetting.secondaryCpuAbiString)); synchronized (mInstallLock) { args.cleanUpResourcesLI(); @@ -9613,10 +9613,10 @@ public class PackageManagerService extends IPackageManager.Stub logCriticalInfo(Log.INFO, "System package disabled;" + " name: " + pkgSetting.name - + "; old: " + pkgSetting.getCodePathString() + " @ " + + "; old: " + pkgSetting.getPathString() + " @ " + pkgSetting.versionCode - + "; new: " + parsedPackage.getCodePath() + " @ " - + parsedPackage.getCodePath()); + + "; new: " + parsedPackage.getPath() + " @ " + + parsedPackage.getPath()); } } @@ -9797,7 +9797,7 @@ public class PackageManagerService extends IPackageManager.Stub * Return the prebuilt profile path given a package base code path. */ private static String getPrebuildProfilePath(AndroidPackage pkg) { - return pkg.getBaseCodePath() + ".prof"; + return pkg.getBaseApkPath() + ".prof"; } /** @@ -11450,7 +11450,7 @@ public class PackageManagerService extends IPackageManager.Stub if (changedAbiCodePath == null) { changedAbiCodePath = new ArrayList<>(); } - changedAbiCodePath.add(ps.getCodePathString()); + changedAbiCodePath.add(ps.getPathString()); } } } @@ -11545,7 +11545,7 @@ public class PackageManagerService extends IPackageManager.Stub } // Initialize package source and resource directories - final File destCodeFile = new File(parsedPackage.getCodePath()); + final File destCodeFile = new File(parsedPackage.getPath()); // We keep references to the derived CPU Abis from settings in oder to reuse // them in the case where we're not upgrading or booting for the first time. @@ -11883,9 +11883,9 @@ public class PackageManagerService extends IPackageManager.Stub private static void assertCodePolicy(AndroidPackage pkg) throws PackageManagerException { final boolean shouldHaveCode = pkg.isHasCode(); - if (shouldHaveCode && !apkHasCode(pkg.getBaseCodePath())) { + if (shouldHaveCode && !apkHasCode(pkg.getBaseApkPath())) { throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, - "Package " + pkg.getBaseCodePath() + " code is missing"); + "Package " + pkg.getBaseApkPath() + " code is missing"); } if (!ArrayUtils.isEmpty(pkg.getSplitCodePaths())) { @@ -11917,7 +11917,7 @@ public class PackageManagerService extends IPackageManager.Stub if (parsedPackage.isDirectBootAware()) { parsedPackage.setAllComponentsDirectBootAware(true); } - if (compressedFileExists(parsedPackage.getCodePath())) { + if (compressedFileExists(parsedPackage.getPath())) { parsedPackage.setStub(true); } } else { @@ -12008,7 +12008,7 @@ public class PackageManagerService extends IPackageManager.Stub assertCodePolicy(pkg); } - if (pkg.getCodePath() == null) { + if (pkg.getPath() == null) { // Bail out. The resource and code paths haven't been set. throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, "Code and resource paths haven't been set correctly"); @@ -12035,7 +12035,7 @@ public class PackageManagerService extends IPackageManager.Stub if (mAndroidApplication != null) { Slog.w(TAG, "*************************************************"); Slog.w(TAG, "Core android package being redefined. Skipping."); - Slog.w(TAG, " codePath=" + pkg.getCodePath()); + Slog.w(TAG, " codePath=" + pkg.getPath()); Slog.w(TAG, "*************************************************"); throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, "Core android package being redefined. Skipping."); @@ -12191,14 +12191,14 @@ public class PackageManagerService extends IPackageManager.Stub PackageSetting known = mSettings.getPackageLPr(pkg.getPackageName()); if (known != null) { if (DEBUG_PACKAGE_SCANNING) { - Log.d(TAG, "Examining " + pkg.getCodePath() - + " and requiring known path " + known.getCodePathString()); + Log.d(TAG, "Examining " + pkg.getPath() + + " and requiring known path " + known.getPathString()); } - if (!pkg.getCodePath().equals(known.getCodePathString())) { + if (!pkg.getPath().equals(known.getPathString())) { throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED, "Application package " + pkg.getPackageName() - + " found at " + pkg.getCodePath() - + " but expected at " + known.getCodePathString() + + " found at " + pkg.getPath() + + " but expected at " + known.getPathString() + "; ignoring."); } } else { @@ -14532,13 +14532,11 @@ public class PackageManagerService extends IPackageManager.Stub Log.v(TAG, "restoreAndPostInstall userId=" + userId + " package=" + res.pkg); } - // A restore should be performed at this point if (a) the install - // succeeded, (b) the operation is not an update, and (c) the new - // package has not opted out of backup participation. + // A restore should be requested at this point if (a) the install + // succeeded, (b) the operation is not an update. final boolean update = res.removedInfo != null && res.removedInfo.removedPackage != null; - boolean allowBackup = res.pkg != null && res.pkg.isAllowBackup(); - boolean doRestore = !update && allowBackup; + boolean doRestore = !update && res.pkg != null; // Set up the post-install work request bookkeeping. This will be used // and cleaned up by the post-install event handling regardless of whether @@ -15787,7 +15785,7 @@ public class PackageManagerService extends IPackageManager.Stub abstract boolean doRename(int status, ParsedPackage parsedPackage); abstract int doPostInstall(int status, int uid); - /** @see PackageSettingBase#getCodePath() */ + /** @see PackageSettingBase#getPath() */ abstract String getCodePath(); // Need installer lock especially for dex file removal. @@ -15968,7 +15966,7 @@ public class PackageManagerService extends IPackageManager.Stub return false; } parsedPackage.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile, - afterCodeFile, parsedPackage.getBaseCodePath())); + afterCodeFile, parsedPackage.getBaseApkPath())); parsedPackage.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile, parsedPackage.getSplitCodePaths())); @@ -16235,7 +16233,7 @@ public class PackageManagerService extends IPackageManager.Stub InstallSource installSource = installArgs.installSource; final String installerPackageName = installSource.installerPackageName; - if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + pkg.getCodePath()); + if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + pkg.getPath()); synchronized (mLock) { // NOTE: This changes slightly to include UPDATE_PERMISSIONS_ALL regardless of the size of pkg.permissions mPermissionManager.updatePermissions(pkgName, pkg); @@ -16874,7 +16872,7 @@ public class PackageManagerService extends IPackageManager.Stub // which means we are replacing another update that is already // installed. We need to make sure to delete the older one's .apk. res.removedInfo.args = createInstallArgsForExisting( - oldPackage.getCodePath(), + oldPackage.getPath(), getAppDexInstructionSets( AndroidPackageUtils.getPrimaryCpuAbi(oldPackage, deletedPkgSetting), @@ -16917,7 +16915,7 @@ public class PackageManagerService extends IPackageManager.Stub if (ps1.mOldCodePaths == null) { ps1.mOldCodePaths = new ArraySet<>(); } - Collections.addAll(ps1.mOldCodePaths, oldPackage.getBaseCodePath()); + Collections.addAll(ps1.mOldCodePaths, oldPackage.getBaseApkPath()); if (oldPackage.getSplitCodePaths() != null) { Collections.addAll(ps1.mOldCodePaths, oldPackage.getSplitCodePaths()); } @@ -17082,7 +17080,7 @@ public class PackageManagerService extends IPackageManager.Stub // For incremental installs, we bypass the verifier prior to install. Now // that we know the package is valid, send a notice to the verifier with // the root hash of the base.apk. - final String baseCodePath = request.installResult.pkg.getBaseCodePath(); + final String baseCodePath = request.installResult.pkg.getBaseApkPath(); final String[] splitCodePaths = request.installResult.pkg.getSplitCodePaths(); final Uri originUri = Uri.fromFile(args.origin.resolvedFile); final int verificationId = mPendingVerificationToken++; @@ -17127,9 +17125,9 @@ public class PackageManagerService extends IPackageManager.Stub final AndroidPackage pkg = reconciledPkg.pkgSetting.pkg; final String packageName = pkg.getPackageName(); final boolean onIncremental = mIncrementalManager != null - && isIncrementalPath(pkg.getCodePath()); + && isIncrementalPath(pkg.getPath()); if (onIncremental) { - IncrementalStorage storage = mIncrementalManager.openStorage(pkg.getCodePath()); + IncrementalStorage storage = mIncrementalManager.openStorage(pkg.getPath()); if (storage == null) { throw new IllegalArgumentException( "Install: null storage for incremental package " + packageName); @@ -17143,7 +17141,7 @@ public class PackageManagerService extends IPackageManager.Stub } if (reconciledPkg.prepareResult.replace) { mDexManager.notifyPackageUpdated(pkg.getPackageName(), - pkg.getBaseCodePath(), pkg.getSplitCodePaths()); + pkg.getBaseApkPath(), pkg.getSplitCodePaths()); } // Prepare the application profiles for the new code paths. @@ -17763,7 +17761,6 @@ public class PackageManagerService extends IPackageManager.Stub oldPackage = mPackages.get(pkgName11); existingPackage = oldPackage; if (DEBUG_INSTALL) { - // TODO(b/135203078): PackageImpl.toString() Slog.d(TAG, "replacePackageLI: new=" + parsedPackage + ", old=" + oldPackage); } @@ -17797,7 +17794,7 @@ public class PackageManagerService extends IPackageManager.Stub final byte[] digestBytes; try { final MessageDigest digest = MessageDigest.getInstance("SHA-512"); - updateDigest(digest, new File(parsedPackage.getBaseCodePath())); + updateDigest(digest, new File(parsedPackage.getBaseApkPath())); if (!ArrayUtils.isEmpty(parsedPackage.getSplitCodePaths())) { for (String path : parsedPackage.getSplitCodePaths()) { updateDigest(digest, new File(path)); @@ -17977,7 +17974,7 @@ public class PackageManagerService extends IPackageManager.Stub synchronized (mLock) { final PackageSetting ps = mSettings.mPackages.get(pkg.getPackageName()); if (ps != null && ps.isPrivileged()) { - fsverityCandidates.put(pkg.getBaseCodePath(), null); + fsverityCandidates.put(pkg.getBaseApkPath(), null); if (pkg.getSplitCodePaths() != null) { for (String splitPath : pkg.getSplitCodePaths()) { fsverityCandidates.put(splitPath, null); @@ -17988,11 +17985,11 @@ public class PackageManagerService extends IPackageManager.Stub } else { // NB: These files will become only accessible if the signing key is loaded in kernel's // .fs-verity keyring. - fsverityCandidates.put(pkg.getBaseCodePath(), - VerityUtils.getFsveritySignatureFilePath(pkg.getBaseCodePath())); + fsverityCandidates.put(pkg.getBaseApkPath(), + VerityUtils.getFsveritySignatureFilePath(pkg.getBaseApkPath())); final String dmPath = DexMetadataHelper.buildDexMetadataPathForApk( - pkg.getBaseCodePath()); + pkg.getBaseApkPath()); if (new File(dmPath).exists()) { fsverityCandidates.put(dmPath, VerityUtils.getFsveritySignatureFilePath(dmPath)); } @@ -19103,7 +19100,7 @@ public class PackageManagerService extends IPackageManager.Stub // Install the system package if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs); try { - installPackageFromSystemLIF(disabledPs.getCodePathString(), allUserHandles, + installPackageFromSystemLIF(disabledPs.getPathString(), allUserHandles, outInfo == null ? null : outInfo.origUsers, writeSettings); } catch (PackageManagerException e) { Slog.w(TAG, "Failed to restore system package:" + deletedPkg.getPackageName() + ": " @@ -19228,7 +19225,7 @@ public class PackageManagerService extends IPackageManager.Stub // Delete application code and resources only for parent packages if (deleteCodeAndResources && (outInfo != null)) { outInfo.args = createInstallArgsForExisting( - ps.getCodePathString(), getAppDexInstructionSets( + ps.getPathString(), getAppDexInstructionSets( ps.primaryCpuAbiString, ps.secondaryCpuAbiString)); if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args); } @@ -19770,7 +19767,7 @@ public class PackageManagerService extends IPackageManager.Stub final String[] packageNames = { packageName }; final long[] ceDataInodes = { ps.getCeDataInode(userId) }; - final String[] codePaths = { ps.getCodePathString() }; + final String[] codePaths = { ps.getPathString() }; try { mInstaller.getAppSize(ps.volumeUuid, packageNames, userId, 0, @@ -19867,7 +19864,7 @@ public class PackageManagerService extends IPackageManager.Stub final PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId); final ArrayList<PreferredActivity> existing = pir.findFilters(filter); if (removeExisting && existing != null) { - removeFiltersLocked(pir, filter, existing); + mSettings.removeFiltersLPw(pir, filter, existing); } pir.addFilter(new PreferredActivity(filter, match, set, activity, always)); scheduleWritePackageRestrictionsLocked(userId); @@ -19968,7 +19965,7 @@ public class PackageManagerService extends IPackageManager.Stub } } if (existing != null) { - removeFiltersLocked(pir, filter, existing); + mSettings.removeFiltersLPw(pir, filter, existing); } } } @@ -19976,22 +19973,6 @@ public class PackageManagerService extends IPackageManager.Stub "Replacing preferred", false); } - private void removeFiltersLocked(@NonNull PreferredIntentResolver pir, - @NonNull IntentFilter filter, @NonNull List<PreferredActivity> existing) { - if (DEBUG_PREFERRED) { - Slog.i(TAG, existing.size() + " preferred matches for:"); - filter.dump(new LogPrinter(Log.INFO, TAG), " "); - } - for (int i = existing.size() - 1; i >= 0; --i) { - final PreferredActivity pa = existing.get(i); - if (DEBUG_PREFERRED) { - Slog.i(TAG, "Removing preferred activity " + pa.mPref.mComponent + ":"); - pa.dump(new LogPrinter(Log.INFO, TAG), " "); - } - pir.removeFilter(pa); - } - } - @Override public void clearPackagePreferredActivities(String packageName) { final int callingUid = Binder.getCallingUid(); @@ -22713,11 +22694,11 @@ public class PackageManagerService extends IPackageManager.Stub synchronized (mInstallLock) { final AndroidPackage pkg; try { - pkg = scanPackageTracedLI(ps.getCodePath(), parseFlags, SCAN_INITIAL, 0, null); + pkg = scanPackageTracedLI(ps.getPath(), parseFlags, SCAN_INITIAL, 0, null); loaded.add(pkg); } catch (PackageManagerException e) { - Slog.w(TAG, "Failed to scan " + ps.getCodePath() + ": " + e.getMessage()); + Slog.w(TAG, "Failed to scan " + ps.getPath() + ": " + e.getMessage()); } if (!Build.FINGERPRINT.equals(ver.fingerprint)) { @@ -22804,7 +22785,7 @@ public class PackageManagerService extends IPackageManager.Stub false, null)) { unloaded.add(pkg); } else { - Slog.w(TAG, "Failed to unload " + ps.getCodePath()); + Slog.w(TAG, "Failed to unload " + ps.getPath()); } } @@ -22858,7 +22839,7 @@ public class PackageManagerService extends IPackageManager.Stub final int packageCount = mSettings.mPackages.size(); for (int i = 0; i < packageCount; i++) { final PackageSetting ps = mSettings.mPackages.valueAt(i); - codePaths.add(ps.getCodePath().getAbsolutePath()); + codePaths.add(ps.getPath().getAbsolutePath()); } return codePaths; } @@ -23434,7 +23415,7 @@ public class PackageManagerService extends IPackageManager.Stub currentVolumeUuid = ps.volumeUuid; - final File probe = new File(pkg.getCodePath()); + final File probe = new File(pkg.getPath()); final File probeOat = new File(probe, "oat"); if (!probe.isDirectory() || !probeOat.isDirectory()) { throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, @@ -23456,7 +23437,7 @@ public class PackageManagerService extends IPackageManager.Stub } isCurrentLocationExternal = pkg.isExternalStorage(); - codeFile = new File(pkg.getCodePath()); + codeFile = new File(pkg.getPath()); installSource = ps.installSource; packageAbiOverride = ps.cpuAbiOverrideString; appId = UserHandle.getAppId(pkg.getUid()); @@ -24887,7 +24868,7 @@ public class PackageManagerService extends IPackageManager.Stub mApexManager.getApksInApex(apexPackages.get(i).packageName); for (int j = 0, apksInApex = apkNames.size(); j < apksInApex; j++) { final AndroidPackage pkg = getPackage(apkNames.get(j)); - cacher.cleanCachedResult(new File(pkg.getCodePath())); + cacher.cleanCachedResult(new File(pkg.getPath())); } } } @@ -24963,7 +24944,7 @@ public class PackageManagerService extends IPackageManager.Stub Slog.e(TAG, "failed to find package " + packageName); return false; } - overlayPaths.add(pkg.getBaseCodePath()); + overlayPaths.add(pkg.getBaseApkPath()); } } @@ -25679,7 +25660,7 @@ public class PackageManagerService extends IPackageManager.Stub pkgSetting.getPkgState().isUpdatedSystemApp())) { return null; } - File codePath = new File(pkg.getCodePath()); + File codePath = new File(pkg.getPath()); if (codePath.isDirectory()) { return PackageDexOptimizer.getOatDir(codePath).getAbsolutePath(); } diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java index 5553cd0e2fb8..e5dad8570254 100644 --- a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java +++ b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java @@ -326,11 +326,11 @@ public class PackageManagerServiceUtils { } public static long getLastModifiedTime(AndroidPackage pkg) { - final File srcFile = new File(pkg.getCodePath()); + final File srcFile = new File(pkg.getPath()); if (!srcFile.isDirectory()) { return srcFile.lastModified(); } - final File baseFile = new File(pkg.getBaseCodePath()); + final File baseFile = new File(pkg.getBaseApkPath()); long maxModifiedTime = baseFile.lastModified(); if (pkg.getSplitCodePaths() != null) { for (int i = pkg.getSplitCodePaths().length - 1; i >=0; --i) { diff --git a/services/core/java/com/android/server/pm/PackageSetting.java b/services/core/java/com/android/server/pm/PackageSetting.java index a3a727367c56..4476e8ac8d90 100644 --- a/services/core/java/com/android/server/pm/PackageSetting.java +++ b/services/core/java/com/android/server/pm/PackageSetting.java @@ -44,8 +44,33 @@ import java.util.Set; public class PackageSetting extends PackageSettingBase { int appId; + /** + * This can be null whenever a physical APK on device is missing. This can be the result of + * removing an external storage device where the APK resides. + * + * This will result in the system reading the {@link PackageSetting} from disk, but without + * being able to parse the base APK's AndroidManifest.xml to read all of its metadata. The data + * that is written and read in {@link Settings} includes a minimal set of metadata needed to + * perform other checks in the system. + * + * This is important in order to enforce uniqueness within the system, as the package, even if + * on a removed storage device, is still considered installed. Another package of the same + * application ID or declaring the same permissions or similar cannot be installed. + * + * Re-attaching the storage device to make the APK available should allow the user to use the + * app once the device reboots or otherwise re-scans it. + * + * It is expected that all code that uses a {@link PackageSetting} understands this inner field + * may be null. Note that this relationship only works one way. It should not be possible to + * have an entry inside {@link PackageManagerService#mPackages} without a corresponding + * {@link PackageSetting} inside {@link Settings#mPackages}. + * + * @deprecated Use {@link #getPkg()}. The setter is favored to avoid unintended mutation. + */ @Nullable + @Deprecated public AndroidPackage pkg; + /** * WARNING. The object reference is important. We perform integer equality and NOT * object equality to check whether shared user settings are the same. @@ -104,6 +129,12 @@ public class PackageSetting extends PackageSettingBase { doCopy(orig); } + /** @see #pkg **/ + @Nullable + public AndroidPackage getPkg() { + return pkg; + } + public int getSharedUserId() { if (sharedUser != null) { return sharedUser.userId; @@ -200,7 +231,6 @@ public class PackageSetting extends PackageSettingBase { return installPermissionsFixed; } - // TODO(b/135203078): Remove these in favor of reading from the package directly public boolean isPrivileged() { return (pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0; } diff --git a/services/core/java/com/android/server/pm/PackageSettingBase.java b/services/core/java/com/android/server/pm/PackageSettingBase.java index 6010344b8c65..a7bbf8d66aac 100644 --- a/services/core/java/com/android/server/pm/PackageSettingBase.java +++ b/services/core/java/com/android/server/pm/PackageSettingBase.java @@ -40,6 +40,7 @@ import android.util.SparseArray; import android.util.proto.ProtoOutputStream; import com.android.internal.annotations.VisibleForTesting; +import com.android.server.pm.parsing.pkg.AndroidPackage; import java.io.File; import java.util.Arrays; @@ -59,13 +60,9 @@ public abstract class PackageSettingBase extends SettingBase { public final String name; final String realName; - /** - * Path where this package was found on disk. For monolithic packages - * this is path to single base APK file; for cluster packages this is - * path to the cluster directory. - */ - private File mCodePath; - private String mCodePathString; + /** @see AndroidPackage#getPath() */ + private File mPath; + private String mPathString; String[] usesStaticLibraries; long[] usesStaticLibrariesVersions; @@ -136,7 +133,7 @@ public abstract class PackageSettingBase extends SettingBase { boolean forceQueryableOverride; - PackageSettingBase(String name, String realName, @NonNull File codePath, + PackageSettingBase(String name, String realName, @NonNull File path, String legacyNativeLibraryPathString, String primaryCpuAbiString, String secondaryCpuAbiString, String cpuAbiOverrideString, long pVersionCode, int pkgFlags, int pkgPrivateFlags, @@ -146,7 +143,7 @@ public abstract class PackageSettingBase extends SettingBase { this.realName = realName; this.usesStaticLibraries = usesStaticLibraries; this.usesStaticLibrariesVersions = usesStaticLibrariesVersions; - setCodePath(codePath); + setPath(path); this.legacyNativeLibraryPathString = legacyNativeLibraryPathString; this.primaryCpuAbiString = primaryCpuAbiString; this.secondaryCpuAbiString = secondaryCpuAbiString; @@ -230,7 +227,7 @@ public abstract class PackageSettingBase extends SettingBase { } private void doCopy(PackageSettingBase orig) { - setCodePath(orig.getCodePath()); + setPath(orig.getPath()); cpuAbiOverrideString = orig.cpuAbiOverrideString; firstInstallTime = orig.firstInstallTime; installPermissionsFixed = orig.installPermissionsFixed; @@ -697,18 +694,23 @@ public abstract class PackageSettingBase extends SettingBase { return userState.harmfulAppWarning; } - PackageSettingBase setCodePath(@NonNull File codePath) { - this.mCodePath = codePath; - this.mCodePathString = codePath.toString(); + /** + * @see #mPath + */ + PackageSettingBase setPath(@NonNull File path) { + this.mPath = path; + this.mPathString = path.toString(); return this; } - File getCodePath() { - return mCodePath; + /** @see #mPath */ + File getPath() { + return mPath; } - String getCodePathString() { - return mCodePathString; + /** @see #mPath */ + String getPathString() { + return mPathString; } /** @@ -733,7 +735,7 @@ public abstract class PackageSettingBase extends SettingBase { protected PackageSettingBase updateFrom(PackageSettingBase other) { super.copyFrom(other); - setCodePath(other.getCodePath()); + setPath(other.getPath()); this.usesStaticLibraries = other.usesStaticLibraries; this.usesStaticLibrariesVersions = other.usesStaticLibrariesVersions; this.legacyNativeLibraryPathString = other.legacyNativeLibraryPathString; diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index 659e2a32e267..74bc49dd9108 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -102,7 +102,6 @@ import com.android.internal.util.XmlUtils; import com.android.permission.persistence.RuntimePermissionsPersistence; import com.android.permission.persistence.RuntimePermissionsState; import com.android.server.LocalServices; -import com.android.server.pm.Installer.Batch; import com.android.server.pm.Installer.InstallerException; import com.android.server.pm.parsing.PackageInfoUtils; import com.android.server.pm.parsing.pkg.AndroidPackage; @@ -307,8 +306,8 @@ public final class Settings { private final ArrayMap<String, KernelPackageState> mKernelMapping = new ArrayMap<>(); // List of replaced system applications - private final ArrayMap<String, PackageSetting> mDisabledSysPackages = - new ArrayMap<String, PackageSetting>(); + @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) + final ArrayMap<String, PackageSetting> mDisabledSysPackages = new ArrayMap<>(); /** List of packages that are blocked for uninstall for specific users */ private final SparseArray<ArraySet<String>> mBlockUninstallPackages = new SparseArray<>(); @@ -539,7 +538,7 @@ public final class Settings { return null; } p.getPkgState().setUpdatedSystemApp(false); - PackageSetting ret = addPackageLPw(name, p.realName, p.getCodePath(), + PackageSetting ret = addPackageLPw(name, p.realName, p.getPath(), p.legacyNativeLibraryPathString, p.primaryCpuAbiString, p.secondaryCpuAbiString, p.cpuAbiOverrideString, p.appId, p.versionCode, p.pkgFlags, p.pkgPrivateFlags, @@ -646,7 +645,7 @@ public final class Settings { if (PackageManagerService.DEBUG_UPGRADE) Log.v(PackageManagerService.TAG, "Package " + pkgName + " is adopting original package " + originalPkg.name); pkgSetting = new PackageSetting(originalPkg, pkgName /*realPkgName*/); - pkgSetting.setCodePath(codePath); + pkgSetting.setPath(codePath); pkgSetting.legacyNativeLibraryPathString = legacyNativeLibraryPath; pkgSetting.pkgFlags = pkgFlags; pkgSetting.pkgPrivateFlags = pkgPrivateFlags; @@ -771,12 +770,12 @@ public final class Settings { "Updating application package " + pkgName + " failed"); } - if (!pkgSetting.getCodePath().equals(codePath)) { + if (!pkgSetting.getPath().equals(codePath)) { final boolean isSystem = pkgSetting.isSystem(); Slog.i(PackageManagerService.TAG, "Update" + (isSystem ? " system" : "") + " package " + pkgName - + " code path from " + pkgSetting.getCodePathString() + + " code path from " + pkgSetting.getPathString() + " to " + codePath.toString() + "; Retain data and using new"); if (!isSystem) { @@ -798,7 +797,7 @@ public final class Settings { // internal to external storage or vice versa. pkgSetting.legacyNativeLibraryPathString = legacyNativeLibraryPath; } - pkgSetting.setCodePath(codePath); + pkgSetting.setPath(codePath); } // If what we are scanning is a system (and possibly privileged) package, // then make it so, regardless of whether it was previously installed only @@ -2175,32 +2174,24 @@ public final class Settings { void readUsesStaticLibLPw(XmlPullParser parser, PackageSetting outPs) throws IOException, XmlPullParserException { - int outerDepth = parser.getDepth(); - int type; - while ((type = parser.next()) != XmlPullParser.END_DOCUMENT - && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { - if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { - continue; - } - String libName = parser.getAttributeValue(null, ATTR_NAME); - String libVersionStr = parser.getAttributeValue(null, ATTR_VERSION); - - long libVersion = -1; - try { - libVersion = Long.parseLong(libVersionStr); - } catch (NumberFormatException e) { - // ignore - } + String libName = parser.getAttributeValue(null, ATTR_NAME); + String libVersionStr = parser.getAttributeValue(null, ATTR_VERSION); - if (libName != null && libVersion >= 0) { - outPs.usesStaticLibraries = ArrayUtils.appendElement(String.class, - outPs.usesStaticLibraries, libName); - outPs.usesStaticLibrariesVersions = ArrayUtils.appendLong( - outPs.usesStaticLibrariesVersions, libVersion); - } + long libVersion = -1; + try { + libVersion = Long.parseLong(libVersionStr); + } catch (NumberFormatException e) { + // ignore + } - XmlUtils.skipCurrentTag(parser); + if (libName != null && libVersion >= 0) { + outPs.usesStaticLibraries = ArrayUtils.appendElement(String.class, + outPs.usesStaticLibraries, libName); + outPs.usesStaticLibrariesVersions = ArrayUtils.appendLong( + outPs.usesStaticLibrariesVersions, libVersion); } + + XmlUtils.skipCurrentTag(parser); } void writeUsesStaticLibLPw(XmlSerializer serializer, String[] usesStaticLibraries, @@ -2711,7 +2702,7 @@ public final class Settings { if (pkg.realName != null) { serializer.attribute(null, "realName", pkg.realName); } - serializer.attribute(null, "codePath", pkg.getCodePathString()); + serializer.attribute(null, "codePath", pkg.getPathString()); serializer.attribute(null, "ft", Long.toHexString(pkg.timeStamp)); serializer.attribute(null, "it", Long.toHexString(pkg.firstInstallTime)); serializer.attribute(null, "ut", Long.toHexString(pkg.lastUpdateTime)); @@ -2753,7 +2744,7 @@ public final class Settings { if (pkg.realName != null) { serializer.attribute(null, "realName", pkg.realName); } - serializer.attribute(null, "codePath", pkg.getCodePathString()); + serializer.attribute(null, "codePath", pkg.getPathString()); if (pkg.legacyNativeLibraryPathString != null) { serializer.attribute(null, "nativeLibraryPath", pkg.legacyNativeLibraryPathString); @@ -3192,6 +3183,22 @@ public final class Settings { } } + void removeFiltersLPw(@NonNull PreferredIntentResolver pir, + @NonNull IntentFilter filter, @NonNull List<PreferredActivity> existing) { + if (PackageManagerService.DEBUG_PREFERRED) { + Slog.i(TAG, existing.size() + " preferred matches for:"); + filter.dump(new LogPrinter(Log.INFO, TAG), " "); + } + for (int i = existing.size() - 1; i >= 0; --i) { + final PreferredActivity pa = existing.get(i); + if (PackageManagerService.DEBUG_PREFERRED) { + Slog.i(TAG, "Removing preferred activity " + pa.mPref.mComponent + ":"); + pa.dump(new LogPrinter(Log.INFO, TAG), " "); + } + pir.removeFilter(pa); + } + } + private void applyDefaultPreferredActivityLPw( PackageManagerInternal pmInternal, IntentFilter tmpPa, ComponentName cn, int userId) { // The initial preferences only specify the target activity @@ -3395,8 +3402,13 @@ public final class Settings { Slog.w(TAG, "Malformed mimetype " + intent.getType() + " for " + cn); } } + final PreferredIntentResolver pir = editPreferredActivitiesLPw(userId); + final List<PreferredActivity> existing = pir.findFilters(filter); + if (existing != null) { + removeFiltersLPw(pir, filter, existing); + } PreferredActivity pa = new PreferredActivity(filter, systemMatch, set, cn, true); - editPreferredActivitiesLPw(userId).addFilter(pa); + pir.addFilter(pa); } else if (haveNonSys == null) { StringBuilder sb = new StringBuilder(); sb.append("No component "); @@ -3855,6 +3867,8 @@ public final class Settings { readDomainVerificationLPw(parser, packageSetting); } else if (tagName.equals(TAG_MIME_GROUP)) { packageSetting.mimeGroups = readMimeGroupLPw(parser, packageSetting.mimeGroups); + } else if (tagName.equals(TAG_USES_STATIC_LIB)) { + readUsesStaticLibLPw(parser, packageSetting); } else { PackageManagerService.reportSettingsProblem(Log.WARN, "Unknown element under <package>: " + parser.getName()); @@ -4541,9 +4555,9 @@ public final class Settings { pw.print(prefix); pw.print(" sharedUser="); pw.println(ps.sharedUser); } pw.print(prefix); pw.print(" pkg="); pw.println(pkg); - pw.print(prefix); pw.print(" codePath="); pw.println(ps.getCodePathString()); + pw.print(prefix); pw.print(" codePath="); pw.println(ps.getPathString()); if (permissionNames == null) { - pw.print(prefix); pw.print(" resourcePath="); pw.println(ps.getCodePathString()); + pw.print(prefix); pw.print(" resourcePath="); pw.println(ps.getPathString()); pw.print(prefix); pw.print(" legacyNativeLibraryDir="); pw.println(ps.legacyNativeLibraryPathString); pw.print(prefix); pw.print(" extractNativeLibs="); @@ -4561,10 +4575,10 @@ public final class Settings { pw.println(); if (pkg != null) { pw.print(prefix); pw.print(" versionName="); pw.println(pkg.getVersionName()); + pw.print(prefix); pw.print(" usesNonSdkApi="); pw.println(pkg.isUsesNonSdkApi()); pw.print(prefix); pw.print(" splits="); dumpSplitNames(pw, pkg); pw.println(); final int apkSigningVersion = pkg.getSigningDetails().signatureSchemeVersion; pw.print(prefix); pw.print(" apkSigningVersion="); pw.println(apkSigningVersion); - // TODO(b/135203078): Is there anything to print here with AppInfo removed? pw.print(prefix); pw.print(" applicationInfo="); pw.println(pkg.toAppInfoToString()); pw.print(prefix); pw.print(" flags="); @@ -5160,7 +5174,6 @@ public final class Settings { } void dumpComponents(PrintWriter pw, String prefix, PackageSetting ps) { - // TODO(b/135203078): ParsedComponent toString methods for dumping dumpComponents(pw, prefix, "activities:", ps.pkg.getActivities()); dumpComponents(pw, prefix, "services:", ps.pkg.getServices()); dumpComponents(pw, prefix, "receivers:", ps.pkg.getReceivers()); diff --git a/services/core/java/com/android/server/pm/dex/ArtManagerService.java b/services/core/java/com/android/server/pm/dex/ArtManagerService.java index 8000c639139f..587cb825fbb0 100644 --- a/services/core/java/com/android/server/pm/dex/ArtManagerService.java +++ b/services/core/java/com/android/server/pm/dex/ArtManagerService.java @@ -486,7 +486,7 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub { public boolean compileLayouts(AndroidPackage pkg) { try { final String packageName = pkg.getPackageName(); - final String apkPath = pkg.getBaseCodePath(); + final String apkPath = pkg.getBaseApkPath(); // TODO(b/143971007): Use a cross-user directory File dataDir = PackageInfoWithoutStateUtils.getDataDir(pkg, UserHandle.myUserId()); final String outDexFile = dataDir.getAbsolutePath() + "/code_cache/compiled_view.dex"; @@ -524,7 +524,7 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub { private ArrayMap<String, String> getPackageProfileNames(AndroidPackage pkg) { ArrayMap<String, String> result = new ArrayMap<>(); if (pkg.isHasCode()) { - result.put(pkg.getBaseCodePath(), ArtManager.getProfileName(null)); + result.put(pkg.getBaseApkPath(), ArtManager.getProfileName(null)); } String[] splitCodePaths = pkg.getSplitCodePaths(); diff --git a/services/core/java/com/android/server/pm/dex/DexoptUtils.java b/services/core/java/com/android/server/pm/dex/DexoptUtils.java index 6807388fa2b2..fa0183642f94 100644 --- a/services/core/java/com/android/server/pm/dex/DexoptUtils.java +++ b/services/core/java/com/android/server/pm/dex/DexoptUtils.java @@ -18,12 +18,12 @@ package com.android.server.pm.dex; import android.content.pm.ApplicationInfo; import android.content.pm.SharedLibraryInfo; -import com.android.server.pm.parsing.pkg.AndroidPackage; import android.util.Slog; import android.util.SparseArray; import com.android.internal.os.ClassLoaderFactory; import com.android.internal.util.ArrayUtils; +import com.android.server.pm.parsing.pkg.AndroidPackage; import java.io.File; import java.util.List; @@ -90,7 +90,7 @@ public final class DexoptUtils { // The splits have an implicit dependency on the base apk. // This means that we have to add the base apk file in addition to the shared libraries. - String baseApkName = new File(pkg.getBaseCodePath()).getName(); + String baseApkName = new File(pkg.getBaseApkPath()).getName(); String baseClassPath = baseApkName; // The result is stored in classLoaderContexts. @@ -401,7 +401,7 @@ public final class DexoptUtils { * Assumes that the application declares a non-null array of splits. */ private static String[] getSplitRelativeCodePaths(AndroidPackage pkg) { - String baseCodePath = new File(pkg.getBaseCodePath()).getParent(); + String baseCodePath = new File(pkg.getBaseApkPath()).getParent(); String[] splitCodePaths = pkg.getSplitCodePaths(); String[] splitRelativeCodePaths = new String[ArrayUtils.size(splitCodePaths)]; for (int i = 0; i < splitRelativeCodePaths.length; i++) { diff --git a/services/core/java/com/android/server/pm/dex/ViewCompiler.java b/services/core/java/com/android/server/pm/dex/ViewCompiler.java index 5506a523cd60..a5672664f6fd 100644 --- a/services/core/java/com/android/server/pm/dex/ViewCompiler.java +++ b/services/core/java/com/android/server/pm/dex/ViewCompiler.java @@ -40,7 +40,7 @@ public class ViewCompiler { public boolean compileLayouts(AndroidPackage pkg) { try { final String packageName = pkg.getPackageName(); - final String apkPath = pkg.getBaseCodePath(); + final String apkPath = pkg.getBaseApkPath(); // TODO(b/143971007): Use a cross-user directory File dataDir = PackageInfoWithoutStateUtils.getDataDir(pkg, UserHandle.myUserId()); final String outDexFile = dataDir.getAbsolutePath() + "/code_cache/compiled_view.dex"; diff --git a/services/core/java/com/android/server/pm/parsing/PackageCacher.java b/services/core/java/com/android/server/pm/parsing/PackageCacher.java index 99c6dd1f0312..74ec16140c94 100644 --- a/services/core/java/com/android/server/pm/parsing/PackageCacher.java +++ b/services/core/java/com/android/server/pm/parsing/PackageCacher.java @@ -79,7 +79,6 @@ public class PackageCacher { final PackageParserCacheHelper.ReadHelper helper = new PackageParserCacheHelper.ReadHelper(p); helper.startAndInstall(); - // TODO(b/135203078): Hide PackageImpl constructor? ParsedPackage pkg = new PackageImpl(p); p.recycle(); diff --git a/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java b/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java index 09b4f8967729..d695a01109ff 100644 --- a/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java +++ b/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java @@ -35,6 +35,7 @@ import android.content.pm.ProviderInfo; import android.content.pm.ServiceInfo; import android.content.pm.SharedLibraryInfo; import android.content.pm.parsing.PackageInfoWithoutStateUtils; +import android.content.pm.parsing.ParsingUtils; import android.content.pm.parsing.component.ComponentParseUtils; import android.content.pm.parsing.component.ParsedActivity; import android.content.pm.parsing.component.ParsedComponent; @@ -73,7 +74,7 @@ import java.util.Set; * @hide **/ public class PackageInfoUtils { - private static final String TAG = PackageParser2.TAG; + private static final String TAG = ParsingUtils.TAG; /** * @param pkgSetting See {@link PackageInfoUtils} for description of pkgSetting usage. @@ -207,7 +208,6 @@ public class PackageInfoUtils { public static ApplicationInfo generateApplicationInfo(AndroidPackage pkg, @PackageManager.ApplicationInfoFlags int flags, PackageUserState state, int userId, @Nullable PackageSetting pkgSetting) { - // TODO(b/135203078): Consider cases where we don't have a PkgSetting if (pkg == null) { return null; } @@ -354,7 +354,6 @@ public class PackageInfoUtils { return null; } - // TODO(b/135203078): Add setting related state info.primaryCpuAbi = AndroidPackageUtils.getPrimaryCpuAbi(pkg, pkgSetting); info.secondaryCpuAbi = AndroidPackageUtils.getSecondaryCpuAbi(pkg, pkgSetting); info.nativeLibraryDir = pkg.getNativeLibraryDir(); @@ -454,7 +453,6 @@ public class PackageInfoUtils { /** @see ApplicationInfo#flags */ public static int appInfoFlags(AndroidPackage pkg, @Nullable PackageSetting pkgSetting) { - // TODO(b/135203078): Add setting related state // @formatter:off int pkgWithoutStateFlags = PackageInfoWithoutStateUtils.appInfoFlags(pkg) | flag(pkg.isSystem(), ApplicationInfo.FLAG_SYSTEM) diff --git a/services/core/java/com/android/server/pm/parsing/PackageParser2.java b/services/core/java/com/android/server/pm/parsing/PackageParser2.java index 1145057452c2..851ddd1eae48 100644 --- a/services/core/java/com/android/server/pm/parsing/PackageParser2.java +++ b/services/core/java/com/android/server/pm/parsing/PackageParser2.java @@ -71,7 +71,7 @@ public class PackageParser2 implements AutoCloseable { return platformCompat.isChangeEnabled(changeId, appInfo); } catch (Exception e) { // This shouldn't happen, but assume enforcement if it does - Slog.wtf(ParsingUtils.TAG, "IPlatformCompat query failed", e); + Slog.wtf(TAG, "IPlatformCompat query failed", e); return true; } } @@ -87,7 +87,7 @@ public class PackageParser2 implements AutoCloseable { }); } - static final String TAG = "PackageParser2"; + private static final String TAG = ParsingUtils.TAG; private static final boolean LOG_PARSE_TIMINGS = Build.IS_DEBUGGABLE; private static final int LOG_PARSE_TIMINGS_THRESHOLD_MS = 100; diff --git a/services/core/java/com/android/server/pm/parsing/pkg/AndroidPackage.java b/services/core/java/com/android/server/pm/parsing/pkg/AndroidPackage.java index 39784cf32cea..a13680ad32af 100644 --- a/services/core/java/com/android/server/pm/parsing/pkg/AndroidPackage.java +++ b/services/core/java/com/android/server/pm/parsing/pkg/AndroidPackage.java @@ -23,7 +23,6 @@ import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageParser; import android.content.pm.PermissionGroupInfo; -import android.content.pm.SharedLibraryInfo; import android.content.pm.parsing.ParsingPackageRead; import android.content.pm.parsing.component.ParsedAttribution; import android.content.pm.parsing.component.ParsedIntentInfo; @@ -65,18 +64,16 @@ public interface AndroidPackage extends PkgAppInfo, PkgPackageInfo, ParsingPacka /** Path of base APK */ @NonNull - String getBaseCodePath(); + String getBaseApkPath(); /** Revision code of base APK */ int getBaseRevisionCode(); /** - * Path where this package was found on disk. For monolithic packages - * this is path to single base APK file; for cluster packages this is - * path to the cluster directory. + * The path to the folder containing the base APK and any installed splits. */ @NonNull - String getCodePath(); + String getPath(); /** * Permissions requested but not in the manifest. These may have been split or migrated from diff --git a/services/core/java/com/android/server/pm/parsing/pkg/AndroidPackageUtils.java b/services/core/java/com/android/server/pm/parsing/pkg/AndroidPackageUtils.java index a6f02e7842d3..0a56e1343418 100644 --- a/services/core/java/com/android/server/pm/parsing/pkg/AndroidPackageUtils.java +++ b/services/core/java/com/android/server/pm/parsing/pkg/AndroidPackageUtils.java @@ -58,7 +58,7 @@ public class AndroidPackageUtils { PackageImpl pkg = (PackageImpl) aPkg; ArrayList<String> paths = new ArrayList<>(); if (pkg.isHasCode()) { - paths.add(pkg.getBaseCodePath()); + paths.add(pkg.getBaseApkPath()); } String[] splitCodePaths = pkg.getSplitCodePaths(); if (!ArrayUtils.isEmpty(splitCodePaths)) { @@ -77,7 +77,7 @@ public class AndroidPackageUtils { public static List<String> getAllCodePaths(AndroidPackage aPkg) { PackageImpl pkg = (PackageImpl) aPkg; ArrayList<String> paths = new ArrayList<>(); - paths.add(pkg.getBaseCodePath()); + paths.add(pkg.getBaseApkPath()); String[] splitCodePaths = pkg.getSplitCodePaths(); if (!ArrayUtils.isEmpty(splitCodePaths)) { @@ -147,7 +147,7 @@ public class AndroidPackageUtils { if (pkg.isSystem() && !isUpdatedSystemApp) { return false; } - if (IncrementalManager.isIncrementalPath(pkg.getCodePath())) { + if (IncrementalManager.isIncrementalPath(pkg.getPath())) { return false; } return true; diff --git a/services/core/java/com/android/server/pm/parsing/pkg/PackageImpl.java b/services/core/java/com/android/server/pm/parsing/pkg/PackageImpl.java index 43365fa4b3e6..0e3e110bdc56 100644 --- a/services/core/java/com/android/server/pm/parsing/pkg/PackageImpl.java +++ b/services/core/java/com/android/server/pm/parsing/pkg/PackageImpl.java @@ -136,9 +136,9 @@ public final class PackageImpl extends ParsingPackageImpl implements ParsedPacka private int uid = -1; @VisibleForTesting - public PackageImpl(@NonNull String packageName, @NonNull String baseCodePath, - @NonNull String codePath, @Nullable TypedArray manifestArray, boolean isCoreApp) { - super(packageName, baseCodePath, codePath, manifestArray); + public PackageImpl(@NonNull String packageName, @NonNull String baseApkPath, + @NonNull String path, @Nullable TypedArray manifestArray, boolean isCoreApp) { + super(packageName, baseApkPath, path, manifestArray); this.manifestPackageName = this.packageName; this.coreApp = isCoreApp; } @@ -247,7 +247,7 @@ public final class PackageImpl extends ParsingPackageImpl implements ParsedPacka @Override public PackageImpl setCodePath(@NonNull String value) { - this.codePath = value; + this.mPath = value; return this; } @@ -322,7 +322,7 @@ public final class PackageImpl extends ParsingPackageImpl implements ParsedPacka @Override public PackageImpl setBaseCodePath(@NonNull String baseCodePath) { - this.baseCodePath = TextUtils.safeIntern(baseCodePath); + this.mBaseApkPath = TextUtils.safeIntern(baseCodePath); return this; } @@ -430,7 +430,7 @@ public final class PackageImpl extends ParsingPackageImpl implements ParsedPacka @Deprecated @Override public String toAppInfoToString() { - return "ApplicationInfo{" + return "PackageImpl{" + Integer.toHexString(System.identityHashCode(this)) + " " + getPackageName() + "}"; } diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java index ffdcc227b7f1..1cfc5b135cfa 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java @@ -3526,7 +3526,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { deniedPermissions == null || !deniedPermissions.contains(perm); if (permissionViolation) { Slog.w(TAG, "Privileged permission " + perm + " for package " - + pkg.getPackageName() + " (" + pkg.getCodePath() + + pkg.getPackageName() + " (" + pkg.getPath() + ") not in privapp-permissions whitelist"); if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) { @@ -3534,7 +3534,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { mPrivappPermissionsViolations = new ArraySet<>(); } mPrivappPermissionsViolations.add( - pkg.getPackageName() + " (" + pkg.getCodePath() + "): " + pkg.getPackageName() + " (" + pkg.getPath() + "): " + perm); } } else { diff --git a/services/core/java/com/android/server/slice/SliceManagerService.java b/services/core/java/com/android/server/slice/SliceManagerService.java index 5aedfc19028b..2a74b3d23829 100644 --- a/services/core/java/com/android/server/slice/SliceManagerService.java +++ b/services/core/java/com/android/server/slice/SliceManagerService.java @@ -28,6 +28,8 @@ import static android.os.Process.SYSTEM_UID; import android.Manifest.permission; import android.annotation.NonNull; import android.app.AppOpsManager; +import android.app.role.OnRoleHoldersChangedListener; +import android.app.role.RoleManager; import android.app.slice.ISliceManager; import android.app.slice.SliceSpec; import android.app.usage.UsageStatsManagerInternal; @@ -39,7 +41,9 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; +import android.content.pm.PackageManagerInternal; import android.content.pm.ProviderInfo; +import android.content.pm.ResolveInfo; import android.net.Uri; import android.os.Binder; import android.os.Handler; @@ -61,6 +65,7 @@ import com.android.internal.app.AssistUtils; import com.android.server.LocalServices; import com.android.server.ServiceThread; import com.android.server.SystemService; +import com.android.server.SystemService.TargetUser; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -72,7 +77,10 @@ import java.io.ByteArrayOutputStream; import java.io.FileDescriptor; import java.io.IOException; import java.util.ArrayList; +import java.util.List; import java.util.Objects; +import java.util.concurrent.Executor; +import java.util.function.Supplier; public class SliceManagerService extends ISliceManager.Stub { @@ -80,13 +88,16 @@ public class SliceManagerService extends ISliceManager.Stub { private final Object mLock = new Object(); private final Context mContext; + private final PackageManagerInternal mPackageManagerInternal; private final AppOpsManager mAppOps; private final AssistUtils mAssistUtils; @GuardedBy("mLock") private final ArrayMap<Uri, PinnedSliceState> mPinnedSlicesByUri = new ArrayMap<>(); @GuardedBy("mLock") - private final SparseArray<String> mLastAssistantPackage = new SparseArray<>(); + private final SparseArray<PackageMatchingCache> mAssistantLookup = new SparseArray<>(); + @GuardedBy("mLock") + private final SparseArray<PackageMatchingCache> mHomeLookup = new SparseArray<>(); private final Handler mHandler; private final SlicePermissionManager mPermissions; @@ -99,6 +110,8 @@ public class SliceManagerService extends ISliceManager.Stub { @VisibleForTesting SliceManagerService(Context context, Looper looper) { mContext = context; + mPackageManagerInternal = Objects.requireNonNull( + LocalServices.getService(PackageManagerInternal.class)); mAppOps = context.getSystemService(AppOpsManager.class); mAssistUtils = new AssistUtils(context); mHandler = new Handler(looper); @@ -111,6 +124,7 @@ public class SliceManagerService extends ISliceManager.Stub { filter.addAction(Intent.ACTION_PACKAGE_DATA_CLEARED); filter.addAction(Intent.ACTION_PACKAGE_REMOVED); filter.addDataScheme("package"); + mRoleObserver = new RoleObserver(); mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, mHandler); } @@ -160,7 +174,8 @@ public class SliceManagerService extends ISliceManager.Stub { mHandler.post(() -> { if (slicePkg != null && !Objects.equals(pkg, slicePkg)) { mAppUsageStats.reportEvent(slicePkg, user, - isAssistant(pkg, user) ? SLICE_PINNED_PRIV : SLICE_PINNED); + isAssistant(pkg, user) || isDefaultHomeApp(pkg, user) + ? SLICE_PINNED_PRIV : SLICE_PINNED); } }); } @@ -425,19 +440,38 @@ public class SliceManagerService extends ISliceManager.Stub { private boolean hasFullSliceAccess(String pkg, int userId) { long ident = Binder.clearCallingIdentity(); try { - return isAssistant(pkg, userId) || isGrantedFullAccess(pkg, userId); + boolean ret = isDefaultHomeApp(pkg, userId) || isAssistant(pkg, userId) + || isGrantedFullAccess(pkg, userId); + return ret; } finally { Binder.restoreCallingIdentity(ident); } } private boolean isAssistant(String pkg, int userId) { - if (pkg == null) return false; - if (!pkg.equals(mLastAssistantPackage.get(userId))) { - // Failed on cached value, try updating. - mLastAssistantPackage.put(userId, getAssistant(userId)); + return getAssistantMatcher(userId).matches(pkg); + } + + private boolean isDefaultHomeApp(String pkg, int userId) { + return getHomeMatcher(userId).matches(pkg); + } + + private PackageMatchingCache getAssistantMatcher(int userId) { + PackageMatchingCache matcher = mAssistantLookup.get(userId); + if (matcher == null) { + matcher = new PackageMatchingCache(() -> getAssistant(userId)); + mAssistantLookup.put(userId, matcher); } - return pkg.equals(mLastAssistantPackage.get(userId)); + return matcher; + } + + private PackageMatchingCache getHomeMatcher(int userId) { + PackageMatchingCache matcher = mHomeLookup.get(userId); + if (matcher == null) { + matcher = new PackageMatchingCache(() -> getDefaultHome(userId)); + mHomeLookup.put(userId, matcher); + } + return matcher; } private String getAssistant(int userId) { @@ -448,6 +482,111 @@ public class SliceManagerService extends ISliceManager.Stub { return cn.getPackageName(); } + /** + * A cached value of the default home app + */ + private String mCachedDefaultHome = null; + + // Based on getDefaultHome in ShortcutService. + // TODO: Unify if possible + @VisibleForTesting + protected String getDefaultHome(int userId) { + + // Set VERIFY to true to run the cache in "shadow" mode for cache + // testing. Do not commit set to true; + final boolean VERIFY = false; + + if (mCachedDefaultHome != null) { + if (!VERIFY) { + return mCachedDefaultHome; + } + } + + final long token = Binder.clearCallingIdentity(); + try { + final List<ResolveInfo> allHomeCandidates = new ArrayList<>(); + + // Default launcher from package manager. + final ComponentName defaultLauncher = mPackageManagerInternal + .getHomeActivitiesAsUser(allHomeCandidates, userId); + + ComponentName detected = defaultLauncher; + + // Cache the default launcher. It is not a problem if the + // launcher is null - eventually, the default launcher will be + // set to something non-null. + mCachedDefaultHome = ((detected != null) ? detected.getPackageName() : null); + + if (detected == null) { + // If we reach here, that means it's the first check since the user was created, + // and there's already multiple launchers and there's no default set. + // Find the system one with the highest priority. + // (We need to check the priority too because of FallbackHome in Settings.) + // If there's no system launcher yet, then no one can access slices, until + // the user explicitly sets one. + final int size = allHomeCandidates.size(); + + int lastPriority = Integer.MIN_VALUE; + for (int i = 0; i < size; i++) { + final ResolveInfo ri = allHomeCandidates.get(i); + if (!ri.activityInfo.applicationInfo.isSystemApp()) { + continue; + } + if (ri.priority < lastPriority) { + continue; + } + detected = ri.activityInfo.getComponentName(); + lastPriority = ri.priority; + } + } + final String ret = ((detected != null) ? detected.getPackageName() : null); + if (VERIFY) { + if (mCachedDefaultHome != null && !mCachedDefaultHome.equals(ret)) { + Slog.e(TAG, "getDefaultHome() cache failure, is " + + mCachedDefaultHome + " should be " + ret); + } + } + return ret; + } finally { + Binder.restoreCallingIdentity(token); + } + } + + public void invalidateCachedDefaultHome() { + mCachedDefaultHome = null; + } + + /** + * Listen for changes in the roles, and invalidate the cached default + * home as necessary. + */ + private RoleObserver mRoleObserver; + + class RoleObserver implements OnRoleHoldersChangedListener { + private RoleManager mRm; + private final Executor mExecutor; + + RoleObserver() { + mExecutor = mContext.getMainExecutor(); + register(); + } + + public void register() { + mRm = mContext.getSystemService(RoleManager.class); + if (mRm != null) { + mRm.addOnRoleHoldersChangedListenerAsUser(mExecutor, this, UserHandle.ALL); + invalidateCachedDefaultHome(); + } + } + + @Override + public void onRoleHoldersChanged(@NonNull String roleName, @NonNull UserHandle user) { + if (RoleManager.ROLE_HOME.equals(roleName)) { + invalidateCachedDefaultHome(); + } + } + } + private boolean isGrantedFullAccess(String pkg, int userId) { return mPermissions.hasFullAccess(pkg, userId); } @@ -496,6 +635,30 @@ public class SliceManagerService extends ISliceManager.Stub { return mPermissions.getAllPackagesGranted(pkg); } + /** + * Holder that caches a package that has access to a slice. + */ + static class PackageMatchingCache { + + private final Supplier<String> mPkgSource; + private String mCurrentPkg; + + public PackageMatchingCache(Supplier<String> pkgSource) { + mPkgSource = pkgSource; + } + + public boolean matches(String pkgCandidate) { + if (pkgCandidate == null) return false; + + if (Objects.equals(pkgCandidate, mCurrentPkg)) { + return true; + } + // Failed on cached value, try updating. + mCurrentPkg = mPkgSource.get(); + return Objects.equals(pkgCandidate, mCurrentPkg); + } + } + public static class Lifecycle extends SystemService { private SliceManagerService mService; diff --git a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java index f74cd611e9d0..0314cf8605bc 100644 --- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java +++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java @@ -3005,10 +3005,10 @@ public class StatsPullAtomService extends SystemService { Settings.Secure.FACE_UNLOCK_KEYGUARD_ENABLED, 1, userId); int unlockDismissesKeyguard = Settings.Secure.getIntForUser( mContext.getContentResolver(), - Settings.Secure.FACE_UNLOCK_DISMISSES_KEYGUARD, 0, userId); + Settings.Secure.FACE_UNLOCK_DISMISSES_KEYGUARD, 1, userId); int unlockAttentionRequired = Settings.Secure.getIntForUser( mContext.getContentResolver(), - Settings.Secure.FACE_UNLOCK_ATTENTION_REQUIRED, 1, userId); + Settings.Secure.FACE_UNLOCK_ATTENTION_REQUIRED, 0, userId); int unlockAppEnabled = Settings.Secure.getIntForUser( mContext.getContentResolver(), Settings.Secure.FACE_UNLOCK_APP_ENABLED, 1, userId); diff --git a/services/core/java/com/android/server/telecom/InternalServiceRepository.java b/services/core/java/com/android/server/telecom/InternalServiceRepository.java new file mode 100644 index 000000000000..76ea5c788bd7 --- /dev/null +++ b/services/core/java/com/android/server/telecom/InternalServiceRepository.java @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2020 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.server.telecom; + +import android.content.Context; +import android.os.Binder; +import android.os.Process; + +import com.android.internal.telecom.IDeviceIdleControllerAdapter; +import com.android.internal.telecom.IInternalServiceRetriever; +import com.android.server.DeviceIdleInternal; + +/** + * The Telecom APK can not access services stored in LocalService directly and since it is in the + * SYSTEM process, it also can not use the *Manager interfaces + * (see {@link Context#enforceCallingPermission(String, String)}). Instead, we must wrap these local + * services in binder interfaces to allow Telecom access. + */ +public class InternalServiceRepository extends IInternalServiceRetriever.Stub { + + private final IDeviceIdleControllerAdapter.Stub mDeviceIdleControllerAdapter = + new IDeviceIdleControllerAdapter.Stub() { + @Override + public void exemptAppTemporarilyForEvent(String packageName, long duration, int userHandle, + String reason) { + mDeviceIdleController.addPowerSaveTempWhitelistApp(Process.myUid(), packageName, + duration, userHandle, true /*sync*/, reason); + } + }; + + private final DeviceIdleInternal mDeviceIdleController; + + public InternalServiceRepository(DeviceIdleInternal deviceIdleController) { + mDeviceIdleController = deviceIdleController; + } + + @Override + public IDeviceIdleControllerAdapter getDeviceIdleController() { + ensureSystemProcess(); + return mDeviceIdleControllerAdapter; + } + + private void ensureSystemProcess() { + if (Binder.getCallingUid() != Process.SYSTEM_UID) { + // Correctness check - this should never happen. + throw new SecurityException("SYSTEM ONLY API."); + } + } +} diff --git a/services/core/java/com/android/server/telecom/OWNERS b/services/core/java/com/android/server/telecom/OWNERS new file mode 100644 index 000000000000..39be2c1aecc4 --- /dev/null +++ b/services/core/java/com/android/server/telecom/OWNERS @@ -0,0 +1,6 @@ +breadley@google.com +hallliu@google.com +tgunn@google.com +xiaotonj@google.com +shuoq@google.com +rgreenwalt@google.com diff --git a/services/core/java/com/android/server/telecom/TelecomLoaderService.java b/services/core/java/com/android/server/telecom/TelecomLoaderService.java index a853529f49e4..52ad893a9ace 100644 --- a/services/core/java/com/android/server/telecom/TelecomLoaderService.java +++ b/services/core/java/com/android/server/telecom/TelecomLoaderService.java @@ -35,7 +35,10 @@ import android.util.IntArray; import android.util.Slog; import com.android.internal.annotations.GuardedBy; +import com.android.internal.telecom.ITelecomLoader; +import com.android.internal.telecom.ITelecomService; import com.android.internal.telephony.SmsApplication; +import com.android.server.DeviceIdleInternal; import com.android.server.LocalServices; import com.android.server.SystemService; import com.android.server.pm.UserManagerService; @@ -53,16 +56,13 @@ public class TelecomLoaderService extends SystemService { @Override public void onServiceConnected(ComponentName name, IBinder service) { // Normally, we would listen for death here, but since telecom runs in the same process - // as this loader (process="system") thats redundant here. + // as this loader (process="system") that's redundant here. try { - service.linkToDeath(new IBinder.DeathRecipient() { - @Override - public void binderDied() { - connectToTelecom(); - } - }, 0); + ITelecomLoader telecomLoader = ITelecomLoader.Stub.asInterface(service); + ITelecomService telecomService = telecomLoader.createTelecomService(mServiceRepo); + SmsApplication.getDefaultMmsApplication(mContext, false); - ServiceManager.addService(Context.TELECOM_SERVICE, service); + ServiceManager.addService(Context.TELECOM_SERVICE, telecomService.asBinder()); synchronized (mLock) { final PermissionManagerServiceInternal permissionManager = @@ -114,6 +114,8 @@ public class TelecomLoaderService extends SystemService { @GuardedBy("mLock") private TelecomServiceConnection mServiceConnection; + private InternalServiceRepository mServiceRepo; + public TelecomLoaderService(Context context) { super(context); mContext = context; @@ -129,6 +131,8 @@ public class TelecomLoaderService extends SystemService { if (phase == PHASE_ACTIVITY_MANAGER_READY) { registerDefaultAppNotifier(); registerCarrierConfigChangedReceiver(); + // core services will have already been loaded. + setupServiceRepository(); connectToTelecom(); } } @@ -154,6 +158,11 @@ public class TelecomLoaderService extends SystemService { } } + private void setupServiceRepository() { + DeviceIdleInternal deviceIdleInternal = getLocalService(DeviceIdleInternal.class); + mServiceRepo = new InternalServiceRepository(deviceIdleInternal); + } + private void registerDefaultAppProviders() { final PermissionManagerServiceInternal permissionManager = diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 8410e175eadd..ad281247a719 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -6655,8 +6655,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A final Configuration resolvedConfig = getResolvedOverrideConfiguration(); final Rect resolvedBounds = resolvedConfig.windowConfiguration.getBounds(); final int requestedOrientation = getRequestedConfigurationOrientation(); - final boolean orientationRequested = requestedOrientation != ORIENTATION_UNDEFINED - && !mDisplayContent.ignoreRotationForApps(); + final boolean orientationRequested = requestedOrientation != ORIENTATION_UNDEFINED; final int orientation = orientationRequested ? requestedOrientation : newParentConfiguration.orientation; diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index 080a438df357..2657eb29b06c 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -137,6 +137,7 @@ import android.app.ActivityManager; import android.app.ActivityManagerInternal; import android.app.ActivityOptions; import android.app.ActivityTaskManager; +import android.app.ActivityTaskManager.RootTaskInfo; import android.app.ActivityThread; import android.app.AlertDialog; import android.app.AppGlobals; @@ -2158,14 +2159,14 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } @Override - public ActivityManager.StackInfo getFocusedStackInfo() throws RemoteException { - enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()"); + public RootTaskInfo getFocusedRootTaskInfo() throws RemoteException { + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getFocusedRootTaskInfo()"); long ident = Binder.clearCallingIdentity(); try { synchronized (mGlobalLock) { Task focusedStack = getTopDisplayFocusedStack(); if (focusedStack != null) { - return mRootWindowContainer.getStackInfo(focusedStack.mTaskId); + return mRootWindowContainer.getRootTaskInfo(focusedStack.mTaskId); } return null; } @@ -2893,14 +2894,13 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } } - // TODO(148895075): deprecate and replace with task equivalents @Override - public List<ActivityManager.StackInfo> getAllStackInfos() { - enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()"); + public List<RootTaskInfo> getAllRootTaskInfos() { + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllRootTaskInfos()"); long ident = Binder.clearCallingIdentity(); try { synchronized (mGlobalLock) { - return mRootWindowContainer.getAllStackInfos(INVALID_DISPLAY); + return mRootWindowContainer.getAllRootTaskInfos(INVALID_DISPLAY); } } finally { Binder.restoreCallingIdentity(ident); @@ -2908,26 +2908,26 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } @Override - public ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType) { - enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()"); + public RootTaskInfo getRootTaskInfo(int windowingMode, int activityType) { + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getRootTaskInfo()"); long ident = Binder.clearCallingIdentity(); try { synchronized (mGlobalLock) { - return mRootWindowContainer.getStackInfo(windowingMode, activityType); + return mRootWindowContainer.getRootTaskInfo(windowingMode, activityType); } } finally { Binder.restoreCallingIdentity(ident); } } - // TODO(148895075): deprecate and replace with task equivalents @Override - public List<ActivityManager.StackInfo> getAllStackInfosOnDisplay(int displayId) { - enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()"); + public List<RootTaskInfo> getAllRootTaskInfosOnDisplay(int displayId) { + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, + "getAllRootTaskInfosOnDisplay()"); long ident = Binder.clearCallingIdentity(); try { synchronized (mGlobalLock) { - return mRootWindowContainer.getAllStackInfos(displayId); + return mRootWindowContainer.getAllRootTaskInfos(displayId); } } finally { Binder.restoreCallingIdentity(ident); @@ -2935,13 +2935,13 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } @Override - public ActivityManager.StackInfo getStackInfoOnDisplay(int windowingMode, int activityType, + public RootTaskInfo getRootTaskInfoOnDisplay(int windowingMode, int activityType, int displayId) { - enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()"); + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getRootTaskInfoOnDisplay()"); long ident = Binder.clearCallingIdentity(); try { synchronized (mGlobalLock) { - return mRootWindowContainer.getStackInfo(windowingMode, activityType, displayId); + return mRootWindowContainer.getRootTaskInfo(windowingMode, activityType, displayId); } } finally { Binder.restoreCallingIdentity(ident); diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 9d5db1eba9e9..4db121b6ea33 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -28,7 +28,6 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; -import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_USER; import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; import static android.content.res.Configuration.ORIENTATION_PORTRAIT; import static android.content.res.Configuration.ORIENTATION_UNDEFINED; @@ -43,14 +42,14 @@ import static android.view.Display.INVALID_DISPLAY; import static android.view.Display.REMOVE_MODE_DESTROY_CONTENT; import static android.view.InsetsState.ITYPE_IME; import static android.view.InsetsState.ITYPE_LEFT_GESTURES; +import static android.view.InsetsState.ITYPE_NAVIGATION_BAR; import static android.view.InsetsState.ITYPE_RIGHT_GESTURES; import static android.view.Surface.ROTATION_0; import static android.view.Surface.ROTATION_180; import static android.view.Surface.ROTATION_270; import static android.view.Surface.ROTATION_90; import static android.view.View.GONE; -import static android.view.View.SYSTEM_UI_FLAG_HIDE_NAVIGATION; -import static android.view.View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY; +import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE; import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW; import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; @@ -368,13 +367,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp final float mCloseToSquareMaxAspectRatio; /** - * If this is true, we would not rotate the display for apps. The rotation would be either the - * sensor rotation or the user rotation, controlled by - * {@link WindowManagerPolicy.UserRotationMode}. - */ - private boolean mIgnoreRotationForApps; - - /** * Keep track of wallpaper visibility to notify changes. */ private boolean mLastWallpaperVisible = false; @@ -619,6 +611,12 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp */ private boolean mInEnsureActivitiesVisible = false; + /** + * Last window to be requested focus via {@code SurfaceControl.Transaction#setFocusedWindow} to + * prevent duplicate requests to input. + */ + WindowState mLastRequestedFocus = null; + private final Consumer<WindowState> mUpdateWindowsForAnimator = w -> { WindowStateAnimator winAnimator = w.mWinAnimator; final ActivityRecord activity = w.mActivityRecord; @@ -1752,26 +1750,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp mDisplayFrames.onDisplayInfoUpdated(mDisplayInfo, calculateDisplayCutoutForRotation(mDisplayInfo.rotation)); - - // Not much of use to rotate the display for apps since it's close to square. - mIgnoreRotationForApps = isNonDecorDisplayCloseToSquare(Surface.ROTATION_0, width, height); - } - - /** @return {@code true} if the orientation requested from application will be ignored. */ - boolean ignoreRotationForApps() { - return mIgnoreRotationForApps; - } - - private boolean isNonDecorDisplayCloseToSquare(int rotation, int width, int height) { - final DisplayCutout displayCutout = - calculateDisplayCutoutForRotation(rotation).getDisplayCutout(); - final int uiMode = mWmService.mPolicy.getUiMode(); - final int w = mDisplayPolicy.getNonDecorDisplayWidth( - width, height, rotation, uiMode, displayCutout); - final int h = mDisplayPolicy.getNonDecorDisplayHeight( - width, height, rotation, uiMode, displayCutout); - final float aspectRatio = Math.max(w, h) / (float) Math.min(w, h); - return aspectRatio <= mCloseToSquareMaxAspectRatio; } /** @@ -2337,10 +2315,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp int getOrientation() { mLastOrientationSource = null; - if (mIgnoreRotationForApps) { - return SCREEN_ORIENTATION_USER; - } - if (mWmService.mDisplayFrozen) { if (mWmService.mPolicy.isKeyguardLocked()) { // Use the last orientation the while the display is frozen with the keyguard @@ -4754,7 +4728,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp } // Apply restriction if necessary. - if (needsGestureExclusionRestrictions(w, mLastDispatchedSystemUiVisibility)) { + if (needsGestureExclusionRestrictions(w, false /* ignoreRequest */)) { // Processes the region along the left edge. remainingLeftRight[0] = addToGlobalAndConsumeLimit(local, outExclusion, leftEdge, @@ -4771,7 +4745,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp outExclusion.op(middle, Op.UNION); middle.recycle(); } else { - boolean loggable = needsGestureExclusionRestrictions(w, 0 /* lastSysUiVis */); + boolean loggable = needsGestureExclusionRestrictions(w, true /* ignoreRequest */); if (loggable) { addToGlobalAndConsumeLimit(local, outExclusion, leftEdge, Integer.MAX_VALUE, w, EXCLUSION_LEFT); @@ -4793,17 +4767,21 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp } /** - * @return Whether gesture exclusion area should be restricted from the window depending on the - * current SystemUI visibility flags. + * Returns whether gesture exclusion area should be restricted from the window depending on the + * window/activity types and the requested navigation bar visibility and the behavior. + * + * @param win The target window. + * @param ignoreRequest If this is {@code true}, only the window/activity types are considered. + * @return {@code true} if the gesture exclusion restrictions are needed. */ - private static boolean needsGestureExclusionRestrictions(WindowState win, int sysUiVisibility) { + private static boolean needsGestureExclusionRestrictions(WindowState win, + boolean ignoreRequest) { final int type = win.mAttrs.type; - final int stickyHideNavFlags = - SYSTEM_UI_FLAG_HIDE_NAVIGATION | SYSTEM_UI_FLAG_IMMERSIVE_STICKY; final boolean stickyHideNav = - (sysUiVisibility & stickyHideNavFlags) == stickyHideNavFlags; - return !stickyHideNav && type != TYPE_INPUT_METHOD && type != TYPE_NOTIFICATION_SHADE - && win.getActivityType() != ACTIVITY_TYPE_HOME; + !win.getRequestedInsetsState().getSourceOrDefaultVisibility(ITYPE_NAVIGATION_BAR) + && win.mAttrs.insetsFlags.behavior == BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE; + return (!stickyHideNav || ignoreRequest) && type != TYPE_INPUT_METHOD + && type != TYPE_NOTIFICATION_SHADE && win.getActivityType() != ACTIVITY_TYPE_HOME; } /** @@ -4819,7 +4797,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp && type != TYPE_APPLICATION_STARTING && type != TYPE_NAVIGATION_BAR && (attrs.flags & FLAG_NOT_TOUCHABLE) == 0 - && needsGestureExclusionRestrictions(win, 0 /* sysUiVisibility */) + && needsGestureExclusionRestrictions(win, true /* ignoreRequest */) && win.getDisplayContent().mDisplayPolicy.hasSideGestures(); } diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index 941db09f59bd..779f6b2d30cc 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -900,10 +900,6 @@ public class DisplayPolicy { (int) attrs.hideTimeoutMilliseconds, AccessibilityManager.FLAG_CONTENT_TEXT); attrs.windowAnimations = com.android.internal.R.style.Animation_Toast; - // Toast can show with below conditions when the screen is locked. - if (canToastShowWhenLocked(callingPid)) { - attrs.flags |= WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED; - } // Toasts can't be clickable attrs.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; break; @@ -934,16 +930,6 @@ public class DisplayPolicy { } /** - * @return {@code true} if the calling activity initiate toast and is visible with - * {@link WindowManager.LayoutParams#FLAG_SHOW_WHEN_LOCKED} flag. - */ - boolean canToastShowWhenLocked(int callingPid) { - return mDisplayContent.forAllWindows(w -> { - return callingPid == w.mSession.mPid && w.isVisible() && w.canShowWhenLocked(); - }, true /* traverseTopToBottom */); - } - - /** * Check if a window can be added to the system. * * Currently enforces that two window types are singletons per display: diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java index 4efd687b7bb4..c493b66b6204 100644 --- a/services/core/java/com/android/server/wm/InputMonitor.java +++ b/services/core/java/com/android/server/wm/InputMonitor.java @@ -275,7 +275,7 @@ final class InputMonitor { void populateInputWindowHandle(final InputWindowHandle inputWindowHandle, final WindowState child, int flags, final int type, final boolean isVisible, - final boolean hasFocus, final boolean hasWallpaper) { + final boolean focusable, final boolean hasWallpaper) { // Add a window to our list of input windows. inputWindowHandle.name = child.toString(); flags = child.getSurfaceTouchableRegion(inputWindowHandle, flags); @@ -283,7 +283,7 @@ final class InputMonitor { inputWindowHandle.layoutParamsType = type; inputWindowHandle.dispatchingTimeoutMillis = child.getInputDispatchingTimeoutMillis(); inputWindowHandle.visible = isVisible; - inputWindowHandle.focusable = hasFocus; + inputWindowHandle.focusable = focusable; inputWindowHandle.hasWallpaper = hasWallpaper; inputWindowHandle.paused = child.mActivityRecord != null ? child.mActivityRecord.paused : false; inputWindowHandle.ownerPid = child.mSession.mPid; @@ -472,8 +472,9 @@ final class InputMonitor { resetInputConsumers(mInputTransaction); - mDisplayContent.forAllWindows(this, - true /* traverseTopToBottom */); + mDisplayContent.forAllWindows(this, true /* traverseTopToBottom */); + + updateInputFocusRequest(); if (!mUpdateInputWindowsImmediately) { mDisplayContent.getPendingTransaction().merge(mInputTransaction); @@ -483,6 +484,29 @@ final class InputMonitor { Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); } + private void updateInputFocusRequest() { + if (mDisplayContent.mLastRequestedFocus == mDisplayContent.mCurrentFocus) { + return; + } + + final WindowState focus = mDisplayContent.mCurrentFocus; + if (focus == null || focus.mInputWindowHandle.token == null) { + mDisplayContent.mLastRequestedFocus = focus; + return; + } + + if (!focus.mWinAnimator.hasSurface()) { + ProtoLog.d(WM_DEBUG_FOCUS_LIGHT, + "Focus not requested for window=%s because it has no surface", + focus); + return; + } + + mInputTransaction.setFocusedWindow(focus.mInputWindowHandle.token, mDisplayId); + mDisplayContent.mLastRequestedFocus = focus; + ProtoLog.v(WM_DEBUG_FOCUS_LIGHT, "Focus requested for window=%s", focus); + } + @Override public void accept(WindowState w) { final InputChannel inputChannel = w.mInputChannel; @@ -510,11 +534,12 @@ final class InputMonitor { final int flags = w.mAttrs.flags; final int privateFlags = w.mAttrs.privateFlags; - final boolean hasFocus = w.isFocused(); + final boolean focusable = w.canReceiveKeys() + && (mService.mPerDisplayFocusEnabled || mDisplayContent.isOnTop()); if (mAddRecentsAnimationInputConsumerHandle && shouldApplyRecentsInputConsumer) { if (recentsAnimationController.updateInputConsumerForApp( - mRecentsAnimationInputConsumer.mWindowHandle, hasFocus)) { + mRecentsAnimationInputConsumer.mWindowHandle, focusable)) { mRecentsAnimationInputConsumer.show(mInputTransaction, w); mAddRecentsAnimationInputConsumerHandle = false; } @@ -559,7 +584,7 @@ final class InputMonitor { } populateInputWindowHandle( - inputWindowHandle, w, flags, type, isVisible, hasFocus, hasWallpaper); + inputWindowHandle, w, flags, type, isVisible, focusable, hasWallpaper); // register key interception info mService.mKeyInterceptionInfoForToken.put(inputWindowHandle.token, diff --git a/services/core/java/com/android/server/wm/InsetsStateController.java b/services/core/java/com/android/server/wm/InsetsStateController.java index ab1074ee2821..5520ad37e8ed 100644 --- a/services/core/java/com/android/server/wm/InsetsStateController.java +++ b/services/core/java/com/android/server/wm/InsetsStateController.java @@ -286,6 +286,7 @@ class InsetsStateController { } if (changed) { notifyInsetsChanged(); + mDisplayContent.updateSystemGestureExclusion(); mDisplayContent.getDisplayPolicy().updateSystemUiVisibilityLw(); } } diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java index 6882dc4ca151..b50cb4c34398 100644 --- a/services/core/java/com/android/server/wm/RecentsAnimationController.java +++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java @@ -814,14 +814,14 @@ public class RecentsAnimationController implements DeathRecipient { } boolean updateInputConsumerForApp(InputWindowHandle inputWindowHandle, - boolean hasFocus) { + boolean focusable) { // Update the input consumer touchable region to match the target app main window final WindowState targetAppMainWindow = mTargetActivityRecord != null ? mTargetActivityRecord.findMainWindow() : null; if (targetAppMainWindow != null) { targetAppMainWindow.getBounds(mTmpRect); - inputWindowHandle.focusable = hasFocus; + inputWindowHandle.focusable = focusable; inputWindowHandle.touchableRegion.set(mTmpRect); return true; } diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index fca89ac68c39..d149db6b676f 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -99,6 +99,7 @@ import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.ActivityManager; import android.app.ActivityOptions; +import android.app.ActivityTaskManager.RootTaskInfo; import android.app.AppGlobals; import android.app.WindowConfiguration; import android.content.ComponentName; @@ -2213,7 +2214,22 @@ class RootWindowContainer extends WindowContainer<DisplayContent> ensureActivitiesVisible(null, 0, false /* preserveWindows */); resumeFocusedStacksTopActivities(); - mService.getTaskChangeNotificationController().notifyActivityPinned(r); + notifyActivityPipModeChanged(r); + } + + /** + * Notifies when an activity enters or leaves PIP mode. + * @param r indicates the activity currently in PIP, can be null to indicate no activity is + * currently in PIP mode. + */ + void notifyActivityPipModeChanged(@Nullable ActivityRecord r) { + final boolean inPip = r != null; + if (inPip) { + mService.getTaskChangeNotificationController().notifyActivityPinned(r); + } else { + mService.getTaskChangeNotificationController().notifyActivityUnpinned(); + } + mWindowManager.mPolicy.setPipVisibilityLw(inPip); } void executeAppTransitionForAllDisplay() { @@ -2435,77 +2451,73 @@ class RootWindowContainer extends WindowContainer<DisplayContent> return display.getStack(windowingMode, activityType); } - private ActivityManager.StackInfo getStackInfo(Task stack) { - final TaskDisplayArea taskDisplayArea = stack.getDisplayArea(); - ActivityManager.StackInfo info = new ActivityManager.StackInfo(); - stack.getBounds(info.bounds); - info.displayId = taskDisplayArea != null ? taskDisplayArea.getDisplayId() : INVALID_DISPLAY; - info.stackId = stack.mTaskId; - info.stackToken = stack.mRemoteToken.toWindowContainerToken(); - info.userId = stack.mCurrentUser; - info.visible = stack.shouldBeVisible(null); - // A stack might be not attached to a display. - // TODO: Can be removed since no one is using it. - info.position = taskDisplayArea != null ? taskDisplayArea.getIndexOf(stack) : 0; - info.configuration.setTo(stack.getConfiguration()); - - final int numTasks = stack.getDescendantTaskCount(); - info.taskIds = new int[numTasks]; - info.taskNames = new String[numTasks]; - info.taskBounds = new Rect[numTasks]; - info.taskUserIds = new int[numTasks]; + private RootTaskInfo getRootTaskInfo(Task task) { + final TaskDisplayArea taskDisplayArea = task.getDisplayArea(); + RootTaskInfo info = new RootTaskInfo(); + task.fillTaskInfo(info); + + // A task might be not attached to a display. + info.position = taskDisplayArea != null ? taskDisplayArea.getIndexOf(task) : 0; + info.visible = task.shouldBeVisible(null); + task.getBounds(info.bounds); + + final int numTasks = task.getDescendantTaskCount(); + info.childTaskIds = new int[numTasks]; + info.childTaskNames = new String[numTasks]; + info.childTaskBounds = new Rect[numTasks]; + info.childTaskUserIds = new int[numTasks]; final int[] currentIndex = {0}; final PooledConsumer c = PooledLambda.obtainConsumer( - RootWindowContainer::processTaskForStackInfo, PooledLambda.__(Task.class), info, + RootWindowContainer::processTaskForTaskInfo, PooledLambda.__(Task.class), info, currentIndex); - stack.forAllLeafTasks(c, false /* traverseTopToBottom */); + task.forAllLeafTasks(c, false /* traverseTopToBottom */); c.recycle(); - final ActivityRecord top = stack.topRunningActivity(); + final ActivityRecord top = task.topRunningActivity(); info.topActivity = top != null ? top.intent.getComponent() : null; return info; } - private static void processTaskForStackInfo( - Task task, ActivityManager.StackInfo info, int[] currentIndex) { + private static void processTaskForTaskInfo( + Task task, RootTaskInfo info, int[] currentIndex) { int i = currentIndex[0]; - info.taskIds[i] = task.mTaskId; - info.taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString() + info.childTaskIds[i] = task.mTaskId; + info.childTaskNames[i] = task.origActivity != null ? task.origActivity.flattenToString() : task.realActivity != null ? task.realActivity.flattenToString() : task.getTopNonFinishingActivity() != null ? task.getTopNonFinishingActivity().packageName : "unknown"; - info.taskBounds[i] = task.mAtmService.getTaskBounds(task.mTaskId); - info.taskUserIds[i] = task.mUserId; + info.childTaskBounds[i] = task.mAtmService.getTaskBounds(task.mTaskId); + info.childTaskUserIds[i] = task.mUserId; currentIndex[0] = ++i; } - ActivityManager.StackInfo getStackInfo(int stackId) { - Task stack = getStack(stackId); - if (stack != null) { - return getStackInfo(stack); + RootTaskInfo getRootTaskInfo(int taskId) { + Task task = getStack(taskId); + if (task != null) { + return getRootTaskInfo(task); } return null; } - ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType) { + RootTaskInfo getRootTaskInfo(int windowingMode, int activityType) { final Task stack = getStack(windowingMode, activityType); - return (stack != null) ? getStackInfo(stack) : null; + return (stack != null) ? getRootTaskInfo(stack) : null; } - ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType, int displayId) { + RootTaskInfo getRootTaskInfo(int windowingMode, int activityType, int displayId) { final Task stack = getStack(windowingMode, activityType, displayId); - return (stack != null) ? getStackInfo(stack) : null; + return (stack != null) ? getRootTaskInfo(stack) : null; } - /** If displayId == INVALID_DISPLAY, this will get stack infos on all displays */ - ArrayList<ActivityManager.StackInfo> getAllStackInfos(int displayId) { - ArrayList<ActivityManager.StackInfo> list = new ArrayList<>(); + /** If displayId == INVALID_DISPLAY, this will get root task infos on all displays */ + ArrayList<RootTaskInfo> getAllRootTaskInfos(int displayId) { + ArrayList<RootTaskInfo> list = new ArrayList<>(); if (displayId == INVALID_DISPLAY) { forAllTaskDisplayAreas(taskDisplayArea -> { for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) { final Task stack = taskDisplayArea.getStackAt(sNdx); - list.add(getStackInfo(stack)); + list.add(getRootTaskInfo(stack)); } }); return list; @@ -2517,7 +2529,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> display.forAllTaskDisplayAreas(taskDisplayArea -> { for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) { final Task stack = taskDisplayArea.getStackAt(sNdx); - list.add(getStackInfo(stack)); + list.add(getRootTaskInfo(stack)); } }); return list; diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java index 3b32a9d76258..3d6d7b72671b 100644 --- a/services/core/java/com/android/server/wm/Session.java +++ b/services/core/java/com/android/server/wm/Session.java @@ -56,6 +56,7 @@ import android.view.InsetsState; import android.view.SurfaceControl; import android.view.SurfaceSession; import android.view.WindowManager; +import android.window.ClientWindowFrames; import com.android.internal.os.logging.MetricsLoggerWrapper; import com.android.internal.protolog.common.ProtoLog; @@ -201,9 +202,7 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { @Override public int relayout(IWindow window, int seq, WindowManager.LayoutParams attrs, int requestedWidth, int requestedHeight, int viewFlags, int flags, long frameNumber, - Rect outFrame, Rect outContentInsets, Rect outVisibleInsets, - Rect outStableInsets, Rect outBackdropFrame, - DisplayCutout.ParcelableWrapper cutout, MergedConfiguration mergedConfiguration, + ClientWindowFrames outFrames, MergedConfiguration mergedConfiguration, SurfaceControl outSurfaceControl, InsetsState outInsetsState, InsetsSourceControl[] outActiveControls, Point outSurfaceSize, SurfaceControl outBLASTSurfaceControl) { @@ -212,10 +211,8 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, mRelayoutTag); int res = mService.relayoutWindow(this, window, seq, attrs, requestedWidth, requestedHeight, viewFlags, flags, frameNumber, - outFrame, outContentInsets, outVisibleInsets, - outStableInsets, outBackdropFrame, cutout, - mergedConfiguration, outSurfaceControl, outInsetsState, outActiveControls, - outSurfaceSize, outBLASTSurfaceControl); + outFrames, mergedConfiguration, outSurfaceControl, outInsetsState, + outActiveControls, outSurfaceSize, outBLASTSurfaceControl); Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); if (false) Slog.d(TAG_WM, "<<<<<< EXITING relayout to " + Binder.getCallingPid()); @@ -240,11 +237,6 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { } @Override - public void getDisplayFrame(IWindow window, Rect outDisplayFrame) { - mService.getWindowDisplayFrame(this, window, outDisplayFrame); - } - - @Override public void finishDrawing(IWindow window, @Nullable SurfaceControl.Transaction postDrawTransaction) { if (DEBUG) Slog.v(TAG_WM, "IWindow finishDrawing called for " + window); diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index a541192885fe..c4ca4cd637e3 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -1433,7 +1433,7 @@ class Task extends WindowContainer<WindowContainer> { && (newParent == null || !newParent.inPinnedWindowingMode())) { // Notify if a task from the pinned stack is being removed // (or moved depending on the mode). - mAtmService.getTaskChangeNotificationController().notifyActivityUnpinned(); + mRootWindowContainer.notifyActivityPipModeChanged(null); } } @@ -4018,7 +4018,7 @@ class Task extends WindowContainer<WindowContainer> { */ void fillTaskInfo(TaskInfo info, boolean stripExtras) { getNumRunningActivities(mReuseActivitiesReport); - info.userId = mUserId; + info.userId = isLeafTask() ? mUserId : mCurrentUser; info.stackId = getRootTaskId(); info.taskId = mTaskId; info.displayId = getDisplayId(); @@ -5101,10 +5101,11 @@ class Task extends WindowContainer<WindowContainer> { : WINDOWING_MODE_FULLSCREEN; } if (currentMode == WINDOWING_MODE_PINNED) { - mAtmService.getTaskChangeNotificationController().notifyActivityUnpinned(); + mRootWindowContainer.notifyActivityPipModeChanged(null); } if (likelyResolvedMode == WINDOWING_MODE_PINNED && taskDisplayArea.getRootPinnedTask() != null) { + // Can only have 1 pip at a time, so replace an existing pip taskDisplayArea.getRootPinnedTask().dismissPip(); } diff --git a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java index e9ada6be7e7b..100f1bff12a7 100644 --- a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java +++ b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java @@ -67,7 +67,6 @@ import android.os.RemoteException; import android.os.SystemClock; import android.util.MergedConfiguration; import android.util.Slog; -import android.view.DisplayCutout; import android.view.IWindowSession; import android.view.InsetsSourceControl; import android.view.InsetsState; @@ -79,6 +78,7 @@ import android.view.ViewGroup.LayoutParams; import android.view.ViewRootImpl; import android.view.WindowManager; import android.view.WindowManagerGlobal; +import android.window.ClientWindowFrames; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; @@ -159,12 +159,8 @@ class TaskSnapshotSurface implements StartingSurface { final IWindowSession session = WindowManagerGlobal.getWindowSession(); window.setSession(session); final SurfaceControl surfaceControl = new SurfaceControl(); - final Rect tmpRect = new Rect(); - final DisplayCutout.ParcelableWrapper tmpCutout = new DisplayCutout.ParcelableWrapper(); - final Rect tmpFrame = new Rect(); + final ClientWindowFrames tmpFrames = new ClientWindowFrames(); final Rect taskBounds; - final Rect tmpContentInsets = new Rect(); - final Rect tmpStableInsets = new Rect(); final InsetsState mTmpInsetsState = new InsetsState(); final InsetsSourceControl[] mTempControls = new InsetsSourceControl[0]; final MergedConfiguration tmpMergedConfiguration = new MergedConfiguration(); @@ -254,8 +250,9 @@ class TaskSnapshotSurface implements StartingSurface { } try { final int res = session.addToDisplay(window, window.mSeq, layoutParams, - View.GONE, activity.getDisplayContent().getDisplayId(), tmpFrame, tmpRect, - tmpRect, tmpCutout, null, mTmpInsetsState, mTempControls); + View.GONE, activity.getDisplayContent().getDisplayId(), tmpFrames.frame, + tmpFrames.contentInsets, tmpFrames.stableInsets, tmpFrames.displayCutout, + null /* outInputChannel */, mTmpInsetsState, mTempControls); if (res < 0) { Slog.w(TAG, "Failed to add snapshot starting window res=" + res); return null; @@ -270,15 +267,14 @@ class TaskSnapshotSurface implements StartingSurface { window.setOuter(snapshotSurface); try { session.relayout(window, window.mSeq, layoutParams, -1, -1, View.VISIBLE, 0, -1, - tmpFrame, tmpContentInsets, tmpRect, tmpStableInsets, tmpRect, - tmpCutout, tmpMergedConfiguration, surfaceControl, mTmpInsetsState, + tmpFrames, tmpMergedConfiguration, surfaceControl, mTmpInsetsState, mTempControls, sTmpSurfaceSize, sTmpSurfaceControl); } catch (RemoteException e) { // Local call. } - final Rect systemBarInsets = getSystemBarInsets(tmpFrame, insetsState); - snapshotSurface.setFrames(tmpFrame, systemBarInsets); + final Rect systemBarInsets = getSystemBarInsets(tmpFrames.frame, insetsState); + snapshotSurface.setFrames(tmpFrames.frame, systemBarInsets); snapshotSurface.drawSnapshot(); return snapshotSurface; } @@ -528,11 +524,9 @@ class TaskSnapshotSurface implements StartingSurface { } @Override - public void resized(Rect frame, Rect contentInsets, Rect visibleInsets, - Rect stableInsets, boolean reportDraw, - MergedConfiguration mergedConfiguration, Rect backDropFrame, boolean forceLayout, - boolean alwaysConsumeSystemBars, int displayId, - DisplayCutout.ParcelableWrapper displayCutout) { + public void resized(ClientWindowFrames frames, boolean reportDraw, + MergedConfiguration mergedConfiguration, boolean forceLayout, + boolean alwaysConsumeSystemBars, int displayId) { if (mergedConfiguration != null && mOuter != null && mOuter.mOrientationOnCreation != mergedConfiguration.getMergedConfiguration().orientation) { diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 017747f03ca0..8eb6432e0d52 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -258,6 +258,7 @@ import android.view.WindowManager.RemoveContentMode; import android.view.WindowManager.TransitionType; import android.view.WindowManagerGlobal; import android.view.WindowManagerPolicyConstants.PointerEventListener; +import android.window.ClientWindowFrames; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; @@ -2065,21 +2066,6 @@ public class WindowManagerService extends IWindowManager.Stub } } - public void getWindowDisplayFrame(Session session, IWindow client, - Rect outDisplayFrame) { - synchronized (mGlobalLock) { - WindowState win = windowForClientLocked(session, client, false); - if (win == null) { - outDisplayFrame.setEmpty(); - return; - } - outDisplayFrame.set(win.getDisplayFrame()); - if (win.inSizeCompatMode()) { - outDisplayFrame.scale(win.mInvGlobalScale); - } - } - } - public void onRectangleOnScreenRequested(IBinder token, Rect rectangle) { synchronized (mGlobalLock) { if (mAccessibilityController != null) { @@ -2115,9 +2101,7 @@ public class WindowManagerService extends IWindowManager.Stub public int relayoutWindow(Session session, IWindow client, int seq, LayoutParams attrs, int requestedWidth, int requestedHeight, int viewVisibility, int flags, - long frameNumber, Rect outFrame, Rect outContentInsets, - Rect outVisibleInsets, Rect outStableInsets, Rect outBackdropFrame, - DisplayCutout.ParcelableWrapper outCutout, MergedConfiguration mergedConfiguration, + long frameNumber, ClientWindowFrames outFrames, MergedConfiguration mergedConfiguration, SurfaceControl outSurfaceControl, InsetsState outInsetsState, InsetsSourceControl[] outActiveControls, Point outSurfaceSize, SurfaceControl outBLASTSurfaceControl) { @@ -2386,10 +2370,6 @@ public class WindowManagerService extends IWindowManager.Stub if (win.mActivityRecord != null) { win.mActivityRecord.updateReportedVisibilityLocked(); } - if (winAnimator.mReportSurfaceResized) { - winAnimator.mReportSurfaceResized = false; - result |= WindowManagerGlobal.RELAYOUT_RES_SURFACE_RESIZED; - } if (displayPolicy.areSystemBarsForcedShownLw(win)) { result |= WindowManagerGlobal.RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS; } @@ -2419,18 +2399,14 @@ public class WindowManagerService extends IWindowManager.Stub // The last inset values represent the last client state win.updateLastInsetValues(); - win.getCompatFrame(outFrame); - win.getInsetsForRelayout(outContentInsets, outVisibleInsets, - outStableInsets); - outCutout.set(win.getWmDisplayCutout().getDisplayCutout()); - outBackdropFrame.set(win.getBackdropFrame(win.getFrame())); + win.fillClientWindowFrames(outFrames); outInsetsState.set(win.getInsetsState(), win.isClientLocal()); if (DEBUG) { Slog.v(TAG_WM, "Relayout given client " + client.asBinder() + ", requestedWidth=" + requestedWidth + ", requestedHeight=" + requestedHeight + ", viewVisibility=" + viewVisibility - + "\nRelayout returning frame=" + outFrame + + "\nRelayout returning frame=" + outFrames.frame + ", surface=" + outSurfaceControl); } @@ -2440,8 +2416,7 @@ public class WindowManagerService extends IWindowManager.Stub result |= mInTouchMode ? WindowManagerGlobal.RELAYOUT_RES_IN_TOUCH_MODE : 0; if (DEBUG_LAYOUT) { - Slog.v(TAG_WM, - "Relayout complete " + win + ": outFrame=" + outFrame.toShortString()); + Slog.v(TAG_WM, "Relayout complete " + win + ": outFrames=" + outFrames); } win.mInRelayout = false; @@ -5753,19 +5728,6 @@ public class WindowManagerService extends IWindowManager.Stub } @Override - public void setPipVisibility(boolean visible) { - if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR) - != PackageManager.PERMISSION_GRANTED) { - throw new SecurityException("Caller does not hold permission " - + android.Manifest.permission.STATUS_BAR); - } - - synchronized (mGlobalLock) { - mPolicy.setPipVisibilityLw(visible); - } - } - - @Override public void statusBarVisibilityChanged(int displayId, int visibility) { if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR) != PackageManager.PERMISSION_GRANTED) { diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 84a9c750d2d3..721f002a1b41 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -209,7 +209,6 @@ import android.util.Slog; import android.util.TimeUtils; import android.util.proto.ProtoOutputStream; import android.view.Display; -import android.view.DisplayCutout; import android.view.DisplayInfo; import android.view.Gravity; import android.view.IApplicationToken; @@ -233,6 +232,7 @@ import android.view.WindowManager; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.view.animation.Interpolator; +import android.window.ClientWindowFrames; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.policy.KeyInterceptionInfo; @@ -388,15 +388,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP private final Configuration mTempConfiguration = new Configuration(); /** - * The last content insets returned to the client in relayout. We use - * these in the bounds animation to ensure we only observe inset changes - * at the same time that a client resizes it's surface so that we may use - * the geometryAppliesWithResize synchronization mechanism to keep - * the contents in place. - */ - final Rect mLastRelayoutContentInsets = new Rect(); - - /** * Set to true if we are waiting for this window to receive its * given internal insets before laying out other windows based on it. */ @@ -437,6 +428,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP private final WindowFrames mWindowFrames = new WindowFrames(); + private final ClientWindowFrames mClientWindowFrames = new ClientWindowFrames(); + /** The frames used to compute a temporal layout appearance. */ private WindowFrames mSimulatedWindowFrames; @@ -1299,7 +1292,10 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP return mWindowFrames.mRelFrame; } - /** Retrieves the frame of the display that this window was last laid out in. */ + /** + * Gets the frame that excludes the area of side insets according to the layout parameter from + * {@link WindowManager.LayoutParams#setFitInsetsSides}. + */ Rect getDisplayFrame() { return mWindowFrames.mDisplayFrame; } @@ -3585,6 +3581,39 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP return wpc != null && wpc.registeredForDisplayConfigChanges(); } + void fillClientWindowFrames(ClientWindowFrames outFrames) { + outFrames.frame.set(mWindowFrames.mCompatFrame); + outFrames.displayFrame.set(mWindowFrames.mDisplayFrame); + if (mInvGlobalScale != 1.0f && inSizeCompatMode()) { + outFrames.displayFrame.scale(mInvGlobalScale); + } + + final Rect backdropFrame = outFrames.backdropFrame; + // When the task is docked, we send fullscreen sized backdropFrame as soon as resizing + // start even if we haven't received the relayout window, so that the client requests + // the relayout sooner. When dragging stops, backdropFrame needs to stay fullscreen + // until the window to small size, otherwise the multithread renderer will shift last + // one or more frame to wrong offset. So here we send fullscreen backdrop if either + // isDragResizing() or isDragResizeChanged() is true. + final boolean resizing = isDragResizing() || isDragResizeChanged(); + if (!resizing || getWindowConfiguration().useWindowFrameForBackdrop()) { + // Surface position is now inherited from parent, and BackdropFrameRenderer uses + // backdrop frame to position content. Thus we just keep the size of backdrop frame, + // and remove the offset to avoid double offset from display origin. + backdropFrame.set(outFrames.frame); + backdropFrame.offsetTo(0, 0); + } else { + final DisplayInfo displayInfo = getDisplayInfo(); + backdropFrame.set(0, 0, displayInfo.logicalWidth, displayInfo.logicalHeight); + } + outFrames.displayCutout.set(mWindowFrames.mDisplayCutout.getDisplayCutout()); + + // TODO(b/149813814): Remove legacy insets. + outFrames.contentInsets.set(mWindowFrames.mLastContentInsets); + outFrames.visibleInsets.set(mWindowFrames.mLastVisibleInsets); + outFrames.stableInsets.set(mWindowFrames.mLastStableInsets); + } + void reportResized() { // If the activity is scheduled to relaunch, skip sending the resized to ViewRootImpl now // since it will be destroyed anyway. This also prevents the client from receiving @@ -3616,23 +3645,18 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP mWinAnimator.mSurfaceResized = false; mWindowFrames.resetInsetsChanged(); - final Rect frame = mWindowFrames.mCompatFrame; - final Rect contentInsets = mWindowFrames.mLastContentInsets; - final Rect visibleInsets = mWindowFrames.mLastVisibleInsets; - final Rect stableInsets = mWindowFrames.mLastStableInsets; final MergedConfiguration mergedConfiguration = mLastReportedConfiguration; final boolean reportDraw = mWinAnimator.mDrawState == DRAW_PENDING || useBLASTSync() || !mRedrawForSyncReported; final boolean forceRelayout = reportOrientation || isDragResizeChanged() || !mRedrawForSyncReported; final int displayId = getDisplayId(); - final DisplayCutout displayCutout = getWmDisplayCutout().getDisplayCutout(); + fillClientWindowFrames(mClientWindowFrames); mRedrawForSyncReported = true; try { - mClient.resized(frame, contentInsets, visibleInsets, stableInsets, reportDraw, - mergedConfiguration, getBackdropFrame(frame), forceRelayout, + mClient.resized(mClientWindowFrames, reportDraw, mergedConfiguration, forceRelayout, getDisplayContent().getDisplayPolicy().areSystemBarsForcedShownLw(this), - displayId, new DisplayCutout.ParcelableWrapper(displayCutout)); + displayId); if (mWmService.mAccessibilityController != null) { mWmService.mAccessibilityController.onSomeWindowResizedOrMovedLocked(displayId); @@ -3738,27 +3762,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP return (mAttrs.insetsFlags.behavior & BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE) != 0; } - Rect getBackdropFrame(Rect frame) { - // When the task is docked, we send fullscreen sized backDropFrame as soon as resizing - // start even if we haven't received the relayout window, so that the client requests - // the relayout sooner. When dragging stops, backDropFrame needs to stay fullscreen - // until the window to small size, otherwise the multithread renderer will shift last - // one or more frame to wrong offset. So here we send fullscreen backdrop if either - // isDragResizing() or isDragResizeChanged() is true. - boolean resizing = isDragResizing() || isDragResizeChanged(); - if (getWindowConfiguration().useWindowFrameForBackdrop() || !resizing) { - // Surface position is now inherited from parent, and BackdropFrameRenderer uses - // backdrop frame to position content. Thus we just keep the size of backdrop frame, and - // remove the offset to avoid double offset from display origin. - mTmpRect.set(frame); - mTmpRect.offsetTo(0, 0); - return mTmpRect; - } - final DisplayInfo displayInfo = getDisplayInfo(); - mTmpRect.set(0, 0, displayInfo.logicalWidth, displayInfo.logicalHeight); - return mTmpRect; - } - private int getRootTaskId() { final Task stack = getRootTask(); if (stack == null) { @@ -5670,18 +5673,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } } - /** - * Copy the inset values over so they can be sent back to the client when a relayout occurs. - */ - void getInsetsForRelayout(Rect outContentInsets, Rect outVisibleInsets, - Rect outStableInsets) { - outContentInsets.set(mWindowFrames.mContentInsets); - outVisibleInsets.set(mWindowFrames.mVisibleInsets); - outStableInsets.set(mWindowFrames.mStableInsets); - - mLastRelayoutContentInsets.set(mWindowFrames.mContentInsets); - } - void getContentInsets(Rect outContentInsets) { outContentInsets.set(mWindowFrames.mContentInsets); } diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java index 1bd712c3638b..5e814005a5e2 100644 --- a/services/core/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java @@ -126,11 +126,7 @@ class WindowStateAnimator { * we must tell them application to resize (and thus redraw itself). */ boolean mSurfaceResized; - /** - * Whether we should inform the client on next relayoutWindow that - * the surface has been resized since last time. - */ - boolean mReportSurfaceResized; + WindowSurfaceController mSurfaceController; private WindowSurfaceController mPendingDestroySurface; @@ -872,7 +868,6 @@ class WindowStateAnimator { } if (mSurfaceResized) { - mReportSurfaceResized = true; mWin.getDisplayContent().pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER; } } diff --git a/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp b/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp index 7e9e11d209a6..95d4ba7c199a 100644 --- a/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp +++ b/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp @@ -29,6 +29,7 @@ #include <nativehelper/JNIHelp.h> #include <android_runtime/AndroidRuntime.h> +#include <binder/IPCThreadState.h> #include <jni.h> #include <processgroup/processgroup.h> @@ -90,11 +91,20 @@ static void com_android_server_am_CachedAppOptimizer_enableFreezerInternal( } } +static void com_android_server_am_CachedAppOptimizer_freezeBinder( + JNIEnv *env, jobject clazz, jint pid, jboolean freeze) { + + if (IPCThreadState::freeze(pid, freeze, 100 /* timeout [ms] */) != 0) { + jniThrowException(env, "java/lang/RuntimeException", "Unable to freeze/unfreeze binder"); + } +} + static const JNINativeMethod sMethods[] = { /* name, signature, funcPtr */ {"compactSystem", "()V", (void*)com_android_server_am_CachedAppOptimizer_compactSystem}, {"enableFreezerInternal", "(Z)V", (void*)com_android_server_am_CachedAppOptimizer_enableFreezerInternal}, + {"freezeBinder", "(IZ)V", (void*)com_android_server_am_CachedAppOptimizer_freezeBinder} }; int register_android_server_am_CachedAppOptimizer(JNIEnv* env) diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 80455833a3eb..b6f0f9ffe001 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -7132,9 +7132,22 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return (deviceOwner != null) ? deviceOwner.keepUninstalledPackages : null; } + /** + * Logs a warning when the device doesn't have {@code PackageManager.FEATURE_DEVICE_ADMIN}. + * + * @param message action that was not executed; should not end with a period because the missing + * feature will be appended to it. + */ + private void logMissingFeatureAction(String message) { + Slog.w(LOG_TAG, message + " because device does not have the " + + PackageManager.FEATURE_DEVICE_ADMIN + " feature."); + } + @Override public boolean setDeviceOwner(ComponentName admin, String ownerName, int userId) { if (!mHasFeature) { + logMissingFeatureAction("Cannot set " + ComponentName.flattenToShortString(admin) + + " as device owner for user " + userId); return false; } if (admin == null @@ -7456,6 +7469,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public boolean setProfileOwner(ComponentName who, String ownerName, int userHandle) { if (!mHasFeature) { + logMissingFeatureAction("Cannot set " + ComponentName.flattenToShortString(who) + + " as profile owner for user " + userHandle); return false; } if (who == null @@ -7676,6 +7691,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public void setUserProvisioningState(int newState, int userHandle) { if (!mHasFeature) { + logMissingFeatureAction("Cannot set provisioning state " + newState + " for user " + + userHandle); return; } @@ -7753,6 +7770,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public void setProfileEnabled(ComponentName who) { if (!mHasFeature) { + logMissingFeatureAction("Cannot enable profile for " + + ComponentName.flattenToShortString(who)); return; } Objects.requireNonNull(who, "ComponentName is null"); diff --git a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java index 12c69eaa0f8d..ddd1f7568224 100644 --- a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java +++ b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java @@ -16,6 +16,11 @@ package com.android.server.profcollect; +import android.app.job.JobInfo; +import android.app.job.JobParameters; +import android.app.job.JobScheduler; +import android.app.job.JobService; +import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.os.Handler; @@ -34,6 +39,7 @@ import com.android.server.wm.ActivityMetricsLaunchObserverRegistry; import com.android.server.wm.ActivityTaskManagerInternal; import java.util.concurrent.ThreadLocalRandom; +import java.util.concurrent.TimeUnit; /** * System-server-local proxy into the {@code IProfcollectd} native service. @@ -41,28 +47,43 @@ import java.util.concurrent.ThreadLocalRandom; public final class ProfcollectForwardingService extends SystemService { public static final String LOG_TAG = "ProfcollectForwardingService"; + private static final boolean DEBUG = Log.isLoggable(LOG_TAG, Log.DEBUG); + + private static final long BG_PROCESS_PERIOD = DEBUG + ? TimeUnit.MINUTES.toMillis(1) + : TimeUnit.DAYS.toMillis(1); + private IProfCollectd mIProfcollect; - private ProfcollectForwardingService mSelfService; + private static ProfcollectForwardingService sSelfService; private final Handler mHandler = new ProfcollectdHandler(IoThread.getHandler().getLooper()); public ProfcollectForwardingService(Context context) { super(context); - if (mSelfService != null) { + if (sSelfService != null) { throw new AssertionError("only one service instance allowed"); } - mSelfService = this; + sSelfService = this; } @Override public void onStart() { - Log.i(LOG_TAG, "Profcollect forwarding service start"); - connectNativeService(); - if (mIProfcollect == null) { - return; + if (DEBUG) { + Log.d(LOG_TAG, "Profcollect forwarding service start"); } - if (serviceHasSupportedTraceProvider()) { - registerObservers(); + connectNativeService(); + } + + @Override + public void onBootPhase(int phase) { + if (phase == PHASE_BOOT_COMPLETED) { + if (mIProfcollect == null) { + return; + } + if (serviceHasSupportedTraceProvider()) { + registerObservers(); + } + ProfcollectBGJobService.schedule(getContext()); } } @@ -130,6 +151,50 @@ public final class ProfcollectForwardingService extends SystemService { } } + /** + * Background trace process service. + */ + public static class ProfcollectBGJobService extends JobService { + // Unique ID in system service + private static final int JOB_IDLE_PROCESS = 260817; + private static final ComponentName JOB_SERVICE_NAME = new ComponentName( + "android", + ProfcollectBGJobService.class.getName()); + + /** + * Attach the service to the system job scheduler. + */ + public static void schedule(Context context) { + JobScheduler js = context.getSystemService(JobScheduler.class); + + js.schedule(new JobInfo.Builder(JOB_IDLE_PROCESS, JOB_SERVICE_NAME) + .setRequiresDeviceIdle(true) + .setRequiresCharging(true) + .setPeriodic(BG_PROCESS_PERIOD) + .build()); + } + + @Override + public boolean onStartJob(JobParameters params) { + if (DEBUG) { + Log.d(LOG_TAG, "Starting background process job"); + } + + try { + sSelfService.mIProfcollect.ProcessProfile(); + } catch (RemoteException e) { + Log.e(LOG_TAG, e.getMessage()); + } + return true; + } + + @Override + public boolean onStopJob(JobParameters params) { + // TODO: Handle this? + return false; + } + } + // Event observers private void registerObservers() { registerAppLaunchObserver(); @@ -155,7 +220,9 @@ public final class ProfcollectForwardingService extends SystemService { int randomNum = ThreadLocalRandom.current().nextInt(100); if (randomNum < traceFrequency) { try { - Log.i(LOG_TAG, "Tracing on app launch event: " + packageName); + if (DEBUG) { + Log.d(LOG_TAG, "Tracing on app launch event: " + packageName); + } mIProfcollect.TraceOnce("applaunch"); } catch (RemoteException e) { Log.e(LOG_TAG, e.getMessage()); diff --git a/services/tests/PackageManagerServiceTests/host/Android.bp b/services/tests/PackageManagerServiceTests/host/Android.bp index 4f636efc7c06..a941331fcec9 100644 --- a/services/tests/PackageManagerServiceTests/host/Android.bp +++ b/services/tests/PackageManagerServiceTests/host/Android.bp @@ -21,12 +21,15 @@ java_test_host { "truth-prebuilt", ], static_libs: [ + "cts-host-utils", "frameworks-base-hostutils", "PackageManagerServiceHostTestsIntentVerifyUtils", ], test_suites: ["general-tests"], java_resources: [ + ":PackageManagerTestAppDeclaresStaticLibrary", ":PackageManagerTestAppStub", + ":PackageManagerTestAppUsesStaticLibrary", ":PackageManagerTestAppVersion1", ":PackageManagerTestAppVersion2", ":PackageManagerTestAppVersion3", diff --git a/services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/HostUtils.kt b/services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/HostUtils.kt index 24c714c0d5f2..9399030e057c 100644 --- a/services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/HostUtils.kt +++ b/services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/HostUtils.kt @@ -18,6 +18,7 @@ package com.android.server.pm.test import com.android.internal.util.test.SystemPreparer import com.android.tradefed.device.ITestDevice +import com.google.common.truth.Truth import org.junit.rules.TemporaryFolder import java.io.File import java.io.FileOutputStream @@ -48,6 +49,44 @@ internal fun ITestDevice.installJavaResourceApk( internal fun ITestDevice.uninstallPackages(vararg pkgNames: String) = pkgNames.forEach { uninstallPackage(it) } +/** + * Retry [block] a total of [maxAttempts] times, waiting [millisBetweenAttempts] milliseconds + * between each iteration, until a non-null result is returned, providing that result back to the + * caller. + * + * If an [AssertionError] is thrown by the [block] and a non-null result is never returned, that + * error will be re-thrown. This allows the use of [Truth.assertThat] to indicate success while + * providing a meaningful error message in case of failure. + */ +internal fun <T> retryUntilNonNull( + maxAttempts: Int = 10, + millisBetweenAttempts: Long = 1000, + block: () -> T? +): T { + var attempt = 0 + var failure: AssertionError? = null + while (attempt++ < maxAttempts) { + val result = try { + block() + } catch (e: AssertionError) { + failure = e + null + } + + if (result != null) { + return result + } else { + Thread.sleep(millisBetweenAttempts) + } + } + + throw failure ?: AssertionError("Never succeeded") +} + +internal fun retryUntilSuccess(block: () -> Boolean) { + retryUntilNonNull { block().takeIf { it } } +} + internal object HostUtils { fun getDataDir(device: ITestDevice, pkgName: String) = @@ -78,6 +117,25 @@ internal object HostUtils { * dumpsys package and therefore device.getAppPackageInfo doesn't work immediately after reboot, * so the following methods parse the package dump directly to see if the path matches. */ + + /** + * Reads the pm dump for a package name starting from the Packages: metadata section until + * the following section. + */ + fun packageSection( + device: ITestDevice, + pkgName: String, + sectionName: String = "Packages" + ) = device.executeShellCommand("pm dump $pkgName") + .lineSequence() + .dropWhile { !it.startsWith(sectionName) } // Wait until the header + .drop(1) // Drop the header itself + .takeWhile { + // Until next top level header, a non-empty line that doesn't start with whitespace + it.isEmpty() || it.first().isWhitespace() + } + .map(String::trim) + fun getCodePaths(device: ITestDevice, pkgName: String) = device.executeShellCommand("pm dump $pkgName") .lineSequence() @@ -87,14 +145,7 @@ internal object HostUtils { .toList() private fun userIdLineSequence(device: ITestDevice, pkgName: String) = - device.executeShellCommand("pm dump $pkgName") - .lineSequence() - .dropWhile { !it.startsWith("Packages:") } - .takeWhile { - !it.startsWith("Hidden system packages:") && - !it.startsWith("Queries:") - } - .map(String::trim) + packageSection(device, pkgName) .filter { it.startsWith("User ") } fun getUserIdToPkgEnabledState(device: ITestDevice, pkgName: String) = diff --git a/services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/SdCardEjectionTests.kt b/services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/SdCardEjectionTests.kt new file mode 100644 index 000000000000..9f9e6a310d0b --- /dev/null +++ b/services/tests/PackageManagerServiceTests/host/src/com/android/server/pm/test/SdCardEjectionTests.kt @@ -0,0 +1,255 @@ +/* + * Copyright (C) 2020 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.server.pm.test + +import android.cts.host.utils.DeviceJUnit4ClassRunnerWithParameters +import android.cts.host.utils.DeviceJUnit4Parameterized +import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test +import com.google.common.truth.Truth.assertThat +import org.junit.After +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.rules.TemporaryFolder +import org.junit.runner.RunWith +import org.junit.runners.Parameterized +import java.io.File +import java.util.regex.Pattern + +/** + * Verifies PackageManagerService behavior when an app is moved to an adoptable storage device. + * + * Also has the effect of verifying system behavior when the PackageSetting for a package has no + * corresponding AndroidPackage which can be parsed from the APK on disk. This is done by removing + * the storage device and causing a reboot, at which point PMS will read PackageSettings from disk + * and fail to find the package path. + */ +@RunWith(DeviceJUnit4Parameterized::class) +@Parameterized.UseParametersRunnerFactory( + DeviceJUnit4ClassRunnerWithParameters.RunnerFactory::class) +class SdCardEjectionTests : BaseHostJUnit4Test() { + + companion object { + private const val VERSION_DECLARES = "PackageManagerTestAppDeclaresStaticLibrary.apk" + private const val VERSION_DECLARES_PKG_NAME = + "com.android.server.pm.test.test_app_declares_static_library" + private const val VERSION_USES = "PackageManagerTestAppUsesStaticLibrary.apk" + private const val VERSION_USES_PKG_NAME = + "com.android.server.pm.test.test_app_uses_static_library" + + // TODO(chiuwinson): Use the HostUtils constants when merged + private const val TEST_PKG_NAME = "com.android.server.pm.test.test_app" + private const val VERSION_ONE = "PackageManagerTestAppVersion1.apk" + + @Parameterized.Parameters(name = "reboot={0}") + @JvmStatic + fun parameters() = arrayOf(false, true) + + data class Volume( + val diskId: String, + val fsUuid: String + ) + } + + @Rule + @JvmField + val tempFolder = TemporaryFolder() + + @Parameterized.Parameter(0) + @JvmField + var reboot: Boolean = false + + @Before + @After + fun removePackagesAndDeleteVirtualDisk() { + device.uninstallPackages(VERSION_ONE, VERSION_USES_PKG_NAME, VERSION_DECLARES_PKG_NAME) + removeVirtualDisk() + device.reboot() + } + + @Test + fun launchActivity() { + val hostApkFile = HostUtils.copyResourceToHostFile(VERSION_ONE, tempFolder.newFile()) + assertThat(device.installPackage(hostApkFile, true)).isNull() + + val errorRegex = Pattern.compile("error", Pattern.CASE_INSENSITIVE) + fun assertStartResponse(launched: Boolean) { + val response = device.executeShellCommand("am start -n $TEST_PKG_NAME/.TestActivity") + if (launched) { + assertThat(response).doesNotContainMatch(errorRegex) + } else { + assertThat(response).containsMatch(errorRegex) + } + } + + assertStartResponse(launched = true) + + val volume = initializeVirtualDisk() + + movePackage(TEST_PKG_NAME, volume) + assertStartResponse(launched = true) + + unmount(volume, TEST_PKG_NAME) + assertStartResponse(launched = false) + + remount(volume, hostApkFile, TEST_PKG_NAME) + assertStartResponse(launched = true) + } + + @Test + fun uninstallStaticLibraryInUse() { + assertThat(device.installJavaResourceApk(tempFolder, VERSION_DECLARES)).isNull() + + val usesApkFile = HostUtils.copyResourceToHostFile(VERSION_USES, tempFolder.newFile()) + assertThat(device.installPackage(usesApkFile, true)).isNull() + + fun assertUninstallFails() = assertThat(device.uninstallPackage(VERSION_DECLARES_PKG_NAME)) + .isEqualTo("DELETE_FAILED_USED_SHARED_LIBRARY") + + assertUninstallFails() + + val volume = initializeVirtualDisk() + + movePackage(VERSION_USES_PKG_NAME, volume) + assertUninstallFails() + + unmount(volume, VERSION_USES_PKG_NAME) + assertUninstallFails() + + remount(volume, usesApkFile, VERSION_USES_PKG_NAME) + assertUninstallFails() + + // Check that install in the correct order (uses first) passes + assertThat(device.uninstallPackage(VERSION_USES_PKG_NAME)).isNull() + assertThat(device.uninstallPackage(VERSION_DECLARES_PKG_NAME)).isNull() + } + + private fun initializeVirtualDisk(): Volume { + // Rather than making any assumption about what disks/volumes exist on the device, + // save the existing disks/volumes to compare and see when a new one pops up, assuming + // it was created as the result of the calls in this test. + val existingDisks = device.executeShellCommand("sm list-disks adoptable").lines() + val existingVolumes = device.executeShellCommand("sm list-volumes private").lines() + device.executeShellCommand("sm set-virtual-disk true") + + val diskId = retryUntilNonNull { + device.executeShellCommand("sm list-disks adoptable") + .lines() + .filterNot(existingDisks::contains) + .filterNot(String::isEmpty) + .firstOrNull() + } + + device.executeShellCommand("sm partition $diskId private") + + return retrieveNewVolume(existingVolumes) + } + + private fun retrieveNewVolume(existingVolumes: List<String>): Volume { + val newVolume = retryUntilNonNull { + device.executeShellCommand("sm list-volumes private") + .lines() + .toMutableList() + .apply { removeAll(existingVolumes) } + .firstOrNull() + ?.takeIf { it.isNotEmpty() } + } + + val sections = newVolume.split(" ") + return Volume(diskId = sections.first(), fsUuid = sections.last()).also { + assertThat(it.diskId).isNotEmpty() + assertThat(it.fsUuid).isNotEmpty() + } + } + + private fun removeVirtualDisk() { + device.executeShellCommand("sm set-virtual-disk false") + retryUntilSuccess { + !device.executeShellCommand("sm list-volumes").contains("ejecting") + } + } + + private fun movePackage(pkgName: String, volume: Volume) { + // TODO(b/167241596): oat dir must exist for a move install + val codePath = HostUtils.getCodePaths(device, pkgName).first() + device.executeShellCommand("mkdir $codePath/oat") + assertThat(device.executeShellCommand( + "pm move-package $pkgName ${volume.fsUuid}").trim()) + .isEqualTo("Success") + } + + private fun unmount(volume: Volume, pkgName: String) { + assertThat(device.executeShellCommand("sm unmount ${volume.diskId}")).isEmpty() + if (reboot) { + // The system automatically mounts the virtual disk on startup, which would mean the + // app files are available to the system. To prevent this, disable the disk entirely. + // TODO: There must be a better way to prevent it from auto-mounting. + removeVirtualDisk() + device.reboot() + } else { + // Because PackageManager unmount scan is asynchronous, need to retry until the package + // has been unloaded. This only has to be done in the non-reboot case. Reboot will + // clear the data structure by its nature. + retryUntilSuccess { + // The compiler section will print the state of the physical APK + HostUtils.packageSection(device, pkgName, sectionName = "Compiler stats") + .any { it.contains("Unable to find package: $pkgName") } + } + } + } + + private fun remount(volume: Volume, hostApkFile: File, pkgName: String) { + if (reboot) { + // Because the disk was destroyed when unmounting, it now has to be rebuilt manually. + // This enables a new virtual disk, unmounts it, mutates its UUID to match the previous + // partition's, remounts it, and pushes the base.apk back onto the device. This + // simulates the same disk being re-inserted. This is very hacky. + val newVolume = initializeVirtualDisk() + val mountPoint = device.executeShellCommand("mount") + .lineSequence() + .first { it.contains(newVolume.fsUuid) } + .takeWhile { !it.isWhitespace() } + + device.executeShellCommand("sm unmount ${newVolume.diskId}") + + // Save without renamed UUID to compare and see when the renamed pops up + val existingVolumes = device.executeShellCommand("sm list-volumes private").lines() + + device.executeShellCommand("make_f2fs -U ${volume.fsUuid} $mountPoint") + device.executeShellCommand("sm mount ${newVolume.diskId}") + + val reparsedVolume = retrieveNewVolume(existingVolumes) + assertThat(reparsedVolume.fsUuid).isEqualTo(volume.fsUuid) + + val codePath = HostUtils.getCodePaths(device, pkgName).first() + device.pushFile(hostApkFile, "$codePath/base.apk") + + // Unmount so following remount will re-kick package scan + device.executeShellCommand("sm unmount ${newVolume.diskId}") + } + + device.executeShellCommand("sm mount ${volume.diskId}") + + // Because PackageManager remount scan is asynchronous, need to retry until the package + // has been loaded and added to the internal structures. Otherwise resolution will fail. + retryUntilSuccess { + // The compiler section will print the state of the physical APK + HostUtils.packageSection(device, pkgName, sectionName = "Compiler stats") + .none { it.contains("Unable to find package: $pkgName") } + } + } +} diff --git a/services/tests/PackageManagerServiceTests/host/test-apps/Android.bp b/services/tests/PackageManagerServiceTests/host/test-apps/Generic/Android.bp index 4a3076e4736a..4a3076e4736a 100644 --- a/services/tests/PackageManagerServiceTests/host/test-apps/Android.bp +++ b/services/tests/PackageManagerServiceTests/host/test-apps/Generic/Android.bp diff --git a/services/tests/PackageManagerServiceTests/host/test-apps/AndroidManifestOriginalOverride.xml b/services/tests/PackageManagerServiceTests/host/test-apps/Generic/AndroidManifestOriginalOverride.xml index cba580e44065..cba580e44065 100644 --- a/services/tests/PackageManagerServiceTests/host/test-apps/AndroidManifestOriginalOverride.xml +++ b/services/tests/PackageManagerServiceTests/host/test-apps/Generic/AndroidManifestOriginalOverride.xml diff --git a/services/tests/PackageManagerServiceTests/host/test-apps/AndroidManifestVersion1.xml b/services/tests/PackageManagerServiceTests/host/test-apps/Generic/AndroidManifestVersion1.xml index efc7372a177c..05b6248e761e 100644 --- a/services/tests/PackageManagerServiceTests/host/test-apps/AndroidManifestVersion1.xml +++ b/services/tests/PackageManagerServiceTests/host/test-apps/Generic/AndroidManifestVersion1.xml @@ -25,4 +25,9 @@ android:protectionLevel="normal" /> + <application> + <activity android:name="com.android.server.pm.test.test_app.TestActivity" + android:label="PackageManagerTestApp" /> + </application> + </manifest> diff --git a/services/tests/PackageManagerServiceTests/host/test-apps/AndroidManifestVersion2.xml b/services/tests/PackageManagerServiceTests/host/test-apps/Generic/AndroidManifestVersion2.xml index 620054c5dd57..d6eb3e02f7f0 100644 --- a/services/tests/PackageManagerServiceTests/host/test-apps/AndroidManifestVersion2.xml +++ b/services/tests/PackageManagerServiceTests/host/test-apps/Generic/AndroidManifestVersion2.xml @@ -25,4 +25,6 @@ android:protectionLevel="normal" /> + <application/> + </manifest> diff --git a/services/tests/PackageManagerServiceTests/host/test-apps/AndroidManifestVersion3.xml b/services/tests/PackageManagerServiceTests/host/test-apps/Generic/AndroidManifestVersion3.xml index 1997771783dd..90317cb6cec9 100644 --- a/services/tests/PackageManagerServiceTests/host/test-apps/AndroidManifestVersion3.xml +++ b/services/tests/PackageManagerServiceTests/host/test-apps/Generic/AndroidManifestVersion3.xml @@ -25,4 +25,6 @@ android:protectionLevel="normal" /> + <application/> + </manifest> diff --git a/services/tests/PackageManagerServiceTests/host/test-apps/AndroidManifestVersion4.xml b/services/tests/PackageManagerServiceTests/host/test-apps/Generic/AndroidManifestVersion4.xml index d6ade0304189..795c3c105951 100644 --- a/services/tests/PackageManagerServiceTests/host/test-apps/AndroidManifestVersion4.xml +++ b/services/tests/PackageManagerServiceTests/host/test-apps/Generic/AndroidManifestVersion4.xml @@ -25,4 +25,6 @@ android:protectionLevel="normal" /> + <application/> + </manifest> diff --git a/services/tests/PackageManagerServiceTests/host/test-apps/Generic/src/com/android/server/pm/test/test_app/TestActivity.kt b/services/tests/PackageManagerServiceTests/host/test-apps/Generic/src/com/android/server/pm/test/test_app/TestActivity.kt new file mode 100644 index 000000000000..0c9b8d481fa5 --- /dev/null +++ b/services/tests/PackageManagerServiceTests/host/test-apps/Generic/src/com/android/server/pm/test/test_app/TestActivity.kt @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2020 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.server.pm.test.test_app + +import android.app.Activity + +class TestActivity : Activity() diff --git a/services/tests/PackageManagerServiceTests/host/test-apps/UsesStaticLibrary/Android.bp b/services/tests/PackageManagerServiceTests/host/test-apps/UsesStaticLibrary/Android.bp new file mode 100644 index 000000000000..58f17f253a24 --- /dev/null +++ b/services/tests/PackageManagerServiceTests/host/test-apps/UsesStaticLibrary/Android.bp @@ -0,0 +1,24 @@ +// Copyright (C) 2020 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. + +android_test_helper_app { + name: "PackageManagerTestAppDeclaresStaticLibrary", + manifest: "AndroidManifestDeclaresStaticLibrary.xml", + certificate: ":FrameworksCoreTests_keyset_A_cert", +} + +android_test_helper_app { + name: "PackageManagerTestAppUsesStaticLibrary", + manifest: "AndroidManifestUsesStaticLibrary.xml", +} diff --git a/services/tests/PackageManagerServiceTests/host/test-apps/UsesStaticLibrary/AndroidManifestDeclaresStaticLibrary.xml b/services/tests/PackageManagerServiceTests/host/test-apps/UsesStaticLibrary/AndroidManifestDeclaresStaticLibrary.xml new file mode 100644 index 000000000000..8a6c01ab2ba0 --- /dev/null +++ b/services/tests/PackageManagerServiceTests/host/test-apps/UsesStaticLibrary/AndroidManifestDeclaresStaticLibrary.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?><!-- + ~ Copyright (C) 2020 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. + --> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.server.pm.test.test_app_declares_static_library"> + + <application> + <static-library android:name="com.android.server.pm.test.static_library" + android:version="1" /> + </application> + +</manifest> diff --git a/services/tests/PackageManagerServiceTests/host/test-apps/UsesStaticLibrary/AndroidManifestUsesStaticLibrary.xml b/services/tests/PackageManagerServiceTests/host/test-apps/UsesStaticLibrary/AndroidManifestUsesStaticLibrary.xml new file mode 100644 index 000000000000..82d9ac46d7d7 --- /dev/null +++ b/services/tests/PackageManagerServiceTests/host/test-apps/UsesStaticLibrary/AndroidManifestUsesStaticLibrary.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="utf-8"?><!-- + ~ Copyright (C) 2020 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. + --> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.server.pm.test.test_app_uses_static_library"> + + <application> + <activity android:name="com.android.server.pm.test.static_library.TestActivity" + android:label="TestActivity" + android:exported="true"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + + <uses-static-library android:name="com.android.server.pm.test.static_library" + android:certDigest="1F:BE:5F:FB:B0:AD:DC:0C:CD:BF:22:B9:8A:2F:5A:58:A5:C8:29:80:E1:30:2F:65:0E:6B:CA:ED:03:82:BF:CF" + android:version="1" /> + </application> + +</manifest> diff --git a/services/tests/PackageManagerServiceTests/host/test-apps/UsesStaticLibrary/src/com/android/server/pm/test/static_library/TestActivity.kt b/services/tests/PackageManagerServiceTests/host/test-apps/UsesStaticLibrary/src/com/android/server/pm/test/static_library/TestActivity.kt new file mode 100644 index 000000000000..fa85258cd95b --- /dev/null +++ b/services/tests/PackageManagerServiceTests/host/test-apps/UsesStaticLibrary/src/com/android/server/pm/test/static_library/TestActivity.kt @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2020 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.server.pm.test.static_library + +import android.app.Activity +import android.graphics.Color +import android.os.Bundle +import android.view.ViewGroup +import android.widget.FrameLayout + +class TestActivity : Activity() { + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(FrameLayout(this).apply { + setBackgroundColor(Color.BLUE) + }, ViewGroup.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT + )) + } +} diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationControllerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationControllerTest.java index 57bfbf33d680..6acd9b6b3803 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationControllerTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationControllerTest.java @@ -44,6 +44,7 @@ import android.graphics.Rect; import android.graphics.Region; import android.os.Looper; import android.view.MagnificationSpec; +import android.view.accessibility.MagnificationAnimationCallback; import androidx.test.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; @@ -99,12 +100,12 @@ public class FullScreenMagnificationControllerTest { ValueAnimator.AnimatorListener mStateListener; FullScreenMagnificationController mFullScreenMagnificationController; - Runnable mEndCallback; + MagnificationAnimationCallback mAnimationCallback; @Before public void setUp() { Looper looper = InstrumentationRegistry.getContext().getMainLooper(); - mEndCallback = Mockito.mock(Runnable.class); + mAnimationCallback = Mockito.mock(MagnificationAnimationCallback.class); // Pretending ID of the Thread associated with looper as main thread ID in controller when(mMockContext.getMainLooper()).thenReturn(looper); when(mMockControllerCtx.getContext()).thenReturn(mMockContext); @@ -323,7 +324,6 @@ public class FullScreenMagnificationControllerTest { for (int i = 0; i < DISPLAY_COUNT; i++) { setScaleAndCenter_animated_stateChangesAndAnimationHappens(i); resetMockWindowManager(); - Mockito.reset(mEndCallback); } } @@ -336,7 +336,7 @@ public class FullScreenMagnificationControllerTest { MagnificationSpec endSpec = getMagnificationSpec(scale, offsets); assertTrue(mFullScreenMagnificationController.setScaleAndCenter(displayId, scale, - newCenter.x, newCenter.y, mEndCallback, SERVICE_ID_1)); + newCenter.x, newCenter.y, mAnimationCallback, SERVICE_ID_1)); mMessageCapturingHandler.sendAllMessages(); assertEquals(newCenter.x, mFullScreenMagnificationController.getCenterX(displayId), 0.5); @@ -365,18 +365,17 @@ public class FullScreenMagnificationControllerTest { mTargetAnimationListener.onAnimationUpdate(mMockValueAnimator); mStateListener.onAnimationEnd(mMockValueAnimator); verify(mMockWindowManager).setMagnificationSpec(eq(displayId), argThat(closeTo(endSpec))); - verify(mEndCallback).run(); + verify(mAnimationCallback).onResult(true); } @Test public void testSetScaleAndCenterWithAnimation_sameSpec_noAnimationButInvokeEndCallback() { for (int i = 0; i < DISPLAY_COUNT; i++) { - setScaleAndCenter_sameSpec_noAnimationButInvokeEndCallback(i); - Mockito.reset(mEndCallback); + setScaleAndCenter_sameSpec_noAnimationButInvokeCallbacks(i); } } - private void setScaleAndCenter_sameSpec_noAnimationButInvokeEndCallback(int displayId) { + private void setScaleAndCenter_sameSpec_noAnimationButInvokeCallbacks(int displayId) { register(displayId); final PointF center = INITIAL_BOUNDS_LOWER_RIGHT_2X_CENTER; final float targetScale = 2.0f; @@ -385,11 +384,11 @@ public class FullScreenMagnificationControllerTest { mMessageCapturingHandler.sendAllMessages(); assertFalse(mFullScreenMagnificationController.setScaleAndCenter(displayId, - targetScale, center.x, center.y, mEndCallback, SERVICE_ID_1)); + targetScale, center.x, center.y, mAnimationCallback, SERVICE_ID_1)); mMessageCapturingHandler.sendAllMessages(); verify(mMockValueAnimator, never()).start(); - verify(mEndCallback).run(); + verify(mAnimationCallback).onResult(true); } @Test @@ -673,38 +672,38 @@ public class FullScreenMagnificationControllerTest { public void testReset_notMagnifying_noStateChangeButInvokeCallback() { for (int i = 0; i < DISPLAY_COUNT; i++) { reset_notMagnifying_noStateChangeButInvokeCallback(i); - Mockito.reset(mEndCallback); } } private void reset_notMagnifying_noStateChangeButInvokeCallback(int displayId) { register(displayId); - assertFalse(mFullScreenMagnificationController.reset(displayId, mEndCallback)); + assertFalse(mFullScreenMagnificationController.reset(displayId, mAnimationCallback)); mMessageCapturingHandler.sendAllMessages(); verify(mMockAms, never()).notifyMagnificationChanged(eq(displayId), any(Region.class), anyFloat(), anyFloat(), anyFloat()); - verify(mEndCallback).run(); + verify(mAnimationCallback).onResult(true); } @Test - public void testReset_Magnifying_resetsMagnificationAndInvokeLastEndCallback() { + public void testReset_Magnifying_resetsMagnificationAndInvokeCallbacks() { for (int i = 0; i < DISPLAY_COUNT; i++) { - reset_Magnifying_resetsMagnificationAndInvokeLastEndCallback(i); + reset_Magnifying_resetsMagnificationAndInvokeCallbacks(i); } } - private void reset_Magnifying_resetsMagnificationAndInvokeLastEndCallback(int displayId) { + private void reset_Magnifying_resetsMagnificationAndInvokeCallbacks(int displayId) { register(displayId); float scale = 2.5f; PointF firstCenter = INITIAL_BOUNDS_LOWER_RIGHT_2X_CENTER; assertTrue(mFullScreenMagnificationController.setScaleAndCenter(displayId, - scale, firstCenter.x, firstCenter.y, mEndCallback, SERVICE_ID_1)); + scale, firstCenter.x, firstCenter.y, mAnimationCallback, SERVICE_ID_1)); mMessageCapturingHandler.sendAllMessages(); Mockito.reset(mMockValueAnimator); // Stubs the logic after the animation is started. doAnswer(invocation -> { + mStateListener.onAnimationCancel(mMockValueAnimator); mStateListener.onAnimationEnd(mMockValueAnimator); return null; }).when(mMockValueAnimator).cancel(); @@ -713,13 +712,14 @@ public class FullScreenMagnificationControllerTest { float fraction = 0.33f; when(mMockValueAnimator.getAnimatedFraction()).thenReturn(fraction); mTargetAnimationListener.onAnimationUpdate(mMockValueAnimator); - Runnable lastEndCallback = Mockito.mock(Runnable.class); + MagnificationAnimationCallback lastAnimationCallback = Mockito.mock( + MagnificationAnimationCallback.class); - assertTrue(mFullScreenMagnificationController.reset(displayId, lastEndCallback)); + assertTrue(mFullScreenMagnificationController.reset(displayId, lastAnimationCallback)); mMessageCapturingHandler.sendAllMessages(); // Verify expected actions. - verify(mEndCallback, never()).run(); + verify(mAnimationCallback).onResult(false); verify(mMockValueAnimator).start(); verify(mMockValueAnimator).cancel(); @@ -729,7 +729,7 @@ public class FullScreenMagnificationControllerTest { mStateListener.onAnimationEnd(mMockValueAnimator); assertFalse(mFullScreenMagnificationController.isMagnifying(DISPLAY_0)); - verify(lastEndCallback).run(); + verify(lastAnimationCallback).onResult(true); } @Test @@ -1142,6 +1142,7 @@ public class FullScreenMagnificationControllerTest { verify(mMockValueAnimator).addListener(animatorListenerArgumentCaptor.capture()); mStateListener = animatorListenerArgumentCaptor.getValue(); Mockito.reset(mMockValueAnimator); // Ignore other initialization + Mockito.reset(mAnimationCallback); } private void zoomIn2xToMiddle(int displayId) { diff --git a/services/tests/servicestests/src/com/android/server/audio/NoOpAudioSystemAdapter.java b/services/tests/servicestests/src/com/android/server/audio/NoOpAudioSystemAdapter.java index 609af8d5bf4d..8d706cb960e9 100644 --- a/services/tests/servicestests/src/com/android/server/audio/NoOpAudioSystemAdapter.java +++ b/services/tests/servicestests/src/com/android/server/audio/NoOpAudioSystemAdapter.java @@ -79,6 +79,23 @@ public class NoOpAudioSystemAdapter extends AudioSystemAdapter { } @Override + public int setDevicesRoleForCapturePreset(int capturePreset, int role, + @NonNull List<AudioDeviceAttributes> devices) { + return AudioSystem.AUDIO_STATUS_OK; + } + + @Override + public int removeDevicesRoleForCapturePreset( + int capturePreset, int role, @NonNull List<AudioDeviceAttributes> devicesToRemove) { + return AudioSystem.AUDIO_STATUS_OK; + } + + @Override + public int clearDevicesRoleForCapturePreset(int capturePreset, int role) { + return AudioSystem.AUDIO_STATUS_OK; + } + + @Override public int setParameters(String keyValuePairs) { return AudioSystem.AUDIO_STATUS_OK; } diff --git a/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java b/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java index 1d04c8397ffa..e02a46af3849 100644 --- a/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java +++ b/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java @@ -24,7 +24,7 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import android.app.ActivityManager; +import android.app.ActivityTaskManager.RootTaskInfo; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.ContentResolver; @@ -984,8 +984,8 @@ public class BrightnessTrackerTest { } @Override - public ActivityManager.StackInfo getFocusedStack() throws RemoteException { - ActivityManager.StackInfo focusedStack = new ActivityManager.StackInfo(); + public RootTaskInfo getFocusedStack() throws RemoteException { + RootTaskInfo focusedStack = new RootTaskInfo(); focusedStack.userId = 0; focusedStack.topActivity = new ComponentName("a.package", "a.class"); return focusedStack; diff --git a/services/tests/servicestests/src/com/android/server/om/OverlayActorEnforcerTests.kt b/services/tests/servicestests/src/com/android/server/om/OverlayActorEnforcerTests.kt index 08392737350a..154d42ce3f8d 100644 --- a/services/tests/servicestests/src/com/android/server/om/OverlayActorEnforcerTests.kt +++ b/services/tests/servicestests/src/com/android/server/om/OverlayActorEnforcerTests.kt @@ -21,172 +21,387 @@ import android.content.om.OverlayableInfo import android.content.pm.ApplicationInfo import android.content.pm.PackageInfo import android.os.Process -import org.junit.Rule +import com.android.server.om.OverlayActorEnforcer.ActorState +import com.android.server.testutils.mockThrowOnUnmocked +import com.android.server.testutils.whenever +import com.google.common.truth.Truth.assertThat +import org.junit.BeforeClass import org.junit.Test -import org.junit.rules.ExpectedException -import java.lang.UnsupportedOperationException +import org.junit.runner.RunWith +import org.junit.runners.Parameterized +import org.mockito.Mockito.spy +import java.io.IOException +@RunWith(Parameterized::class) class OverlayActorEnforcerTests { + companion object { - private const val NAMESPACE = "testnamespace" - private const val ACTOR_NAME = "testactor" - private const val ACTOR_PKG_NAME = "com.test.actor.one" + private const val TARGET_PKG = "com.test.target" + private const val OVERLAY_PKG = "com.test.overlay" + + private const val VALID_NAMESPACE = "testNamespaceValid" + private const val INVALID_NAMESPACE = "testNamespaceInvalid" + private const val VALID_ACTOR_NAME = "testActorOne" + private const val INVALID_ACTOR_NAME = "testActorTwo" + private const val VALID_ACTOR_PKG = "com.test.actor.valid" + private const val INVALID_ACTOR_PKG = "com.test.actor.invalid" private const val OVERLAYABLE_NAME = "TestOverlayable" - private const val UID = 3536 + private const val NULL_UID = 3536 + private const val EMPTY_UID = NULL_UID + 1 + private const val INVALID_ACTOR_UID = NULL_UID + 2 + private const val VALID_ACTOR_UID = NULL_UID + 3 + private const val TARGET_UID = NULL_UID + 4 private const val USER_ID = 55 - } - @get:Rule - val expectedException = ExpectedException.none()!! + @JvmStatic + @Parameterized.Parameters(name = "{0}") + fun parameters() = CASES.mapIndexed { caseIndex, testCase -> + fun param(pair: Pair<String, TestState.() -> Unit>, type: Params.Type): Params { + val expectedState = testCase.state.takeUnless { type == Params.Type.ALLOWED } + ?: ActorState.ALLOWED + val (caseName, case) = pair + val testName = makeTestName(testCase, caseName, type) + return Params(caseIndex, expectedState, testName, type, case) + } - @Test - fun isRoot() { - verify(callingUid = Process.ROOT_UID) - } + testCase.failures.map { param(it, Params.Type.FAILURE) } + + testCase.allowed.map { param(it, Params.Type.ALLOWED) } + }.flatten() - @Test(expected = SecurityException::class) - fun isShell() { - verify(callingUid = Process.SHELL_UID) - } + @BeforeClass + @JvmStatic + fun checkAllCasesHandled() { + // Assert that all states have been tested at least once. + assertThat(CASES.map { it.state }.distinct()).containsAllIn(ActorState.values()) + } - @Test - fun isSystem() { - verify(callingUid = Process.SYSTEM_UID) - } + @BeforeClass + @JvmStatic + fun checkAllCasesUniquelyNamed() { + val duplicateCaseNames = CASES.mapIndexed { caseIndex, testCase -> + testCase.failures.map { + makeTestName(testCase, it.first, Params.Type.FAILURE) + } + testCase.allowed.map { + makeTestName(testCase, it.first, Params.Type.ALLOWED) + } + } + .flatten() + .groupingBy { it } + .eachCount() + .filterValues { it > 1 } + .keys - @Test(expected = SecurityException::class) - fun noOverlayable_noTarget() { - verify(targetOverlayableName = null) - } + assertThat(duplicateCaseNames).isEmpty() + } - @Test - fun noOverlayable_noTarget_withPermission() { - verify(targetOverlayableName = null, hasPermission = true) - } + /* + The pattern in this block is a result of the incredible number of branches in + enforcement logic. It serves to verify failures with the assumption that all errors + are checked in order. The idea is to emulate the if-else branches from code, but using + actual test data instead of if statements. - @Test(expected = SecurityException::class) - fun noOverlayable_withTarget() { - verify(targetOverlayableName = OVERLAYABLE_NAME) - } + Each state is verified by providing a failure or exclusive set of failures which cause + a failure state to be returned. Each state also provides a success case which will + "skip" the state. This allows subsequent failure cases to cascade from the first case + by calling all the skip branches for preceding states and then choosing only 1 of + the failures to test. - @Test(expected = SecurityException::class) - fun withOverlayable_noTarget() { - verify( - targetOverlayableName = null, - overlayableInfo = OverlayableInfo(OVERLAYABLE_NAME, null) - ) - } + Given the failure states A, B, and C: testA calls A.failure + assert, testB calls + A.skip + B.failure + assert, testC calls A.skip + B.skip + C.failure + assert, etc. - @Test(expected = SecurityException::class) - fun withOverlayable_noActor() { - verify( - overlayableInfo = OverlayableInfo(OVERLAYABLE_NAME, null) - ) - } + Calling `allowed` is a special case for when there is a combination of parameters that + skips the remaining checks and immediately allows the actor through. For these cases, + the first failure branch will be run, assert that it's not allowed, and the + allowed branch will run, asserting that it now results in ALLOWED, skipping all + remaining functions. - @Test - fun withOverlayable_noActor_withPermission() { - verify( - hasPermission = true, - overlayableInfo = OverlayableInfo(OVERLAYABLE_NAME, null) - ) - } + This is an ordered list of TestCase objects, with the possibility to repeat failure + states if any can occur multiple times in the logic tree. - @Test(expected = SecurityException::class) - fun withOverlayable_withActor_notActor() { - verify( - isActor = false, - overlayableInfo = OverlayableInfo(OVERLAYABLE_NAME, - "overlay://$NAMESPACE/$ACTOR_NAME") + Each failure must be handled at least once. + */ + private val CASES = listOf( + ActorState.TARGET_NOT_FOUND withCases { + failure("nullPkgInfo") { targetPkgInfo = null } + allowed("debuggable") { + targetPkgInfo = pkgInfo(TARGET_PKG).apply { + applicationInfo.flags = ApplicationInfo.FLAG_DEBUGGABLE + } + } + skip { targetPkgInfo = pkgInfo(TARGET_PKG) } + }, + ActorState.NO_PACKAGES_FOR_UID withCases { + failure("empty") { callingUid = EMPTY_UID } + failure("null") { callingUid = NULL_UID } + failure("shell") { callingUid = Process.SHELL_UID } + allowed("targetUid") { callingUid = TARGET_UID } + allowed("rootUid") { callingUid = Process.ROOT_UID } + allowed("systemUid") { callingUid = Process.SYSTEM_UID } + skip { callingUid = INVALID_ACTOR_UID } + }, + ActorState.MISSING_TARGET_OVERLAYABLE_NAME withCases { + failure("nullTargetOverlayableName") { + overlayInfoParams.targetOverlayableName = null + targetOverlayableInfo = OverlayableInfo(OVERLAYABLE_NAME, + "overlay://$VALID_NAMESPACE/$VALID_ACTOR_NAME") + } + skip { overlayInfoParams.targetOverlayableName = OVERLAYABLE_NAME } + }, + ActorState.MISSING_LEGACY_PERMISSION withCases { + failure("noPermission") { + overlayInfoParams.targetOverlayableName = null + targetOverlayableInfo = null + hasPermission = false + } + allowed("hasPermission") { hasPermission = true } + skip { overlayInfoParams.targetOverlayableName = OVERLAYABLE_NAME } + }, + ActorState.ERROR_READING_OVERLAYABLE withCases { + failure("doesTargetDefineOverlayableIOException") { + overlayInfoParams.targetOverlayableName = null + whenever(doesTargetDefineOverlayable(TARGET_PKG, USER_ID)) + .thenThrow(IOException::class.java) + } + skip { overlayInfoParams.targetOverlayableName = OVERLAYABLE_NAME } + }, + ActorState.UNABLE_TO_GET_TARGET_OVERLAYABLE withCases { + failure("getOverlayableForTargetIOException") { + whenever(getOverlayableForTarget(TARGET_PKG, OVERLAYABLE_NAME, + USER_ID)).thenThrow(IOException::class.java) + } + }, + ActorState.MISSING_OVERLAYABLE withCases { + failure("nullTargetOverlayableInfo") { targetOverlayableInfo = null } + skip { + targetOverlayableInfo = OverlayableInfo(OVERLAYABLE_NAME, + "overlay://$VALID_NAMESPACE/$VALID_ACTOR_NAME") + } + }, + ActorState.MISSING_LEGACY_PERMISSION withCases { + failure("noPermissionNullActor") { + targetOverlayableInfo = OverlayableInfo(OVERLAYABLE_NAME, null) + hasPermission = false + } + failure("noPermissionEmptyActor") { + targetOverlayableInfo = OverlayableInfo(OVERLAYABLE_NAME, "") + hasPermission = false + } + allowed("hasPermissionNullActor") { + hasPermission = true + } + skip { + targetOverlayableInfo = OverlayableInfo(OVERLAYABLE_NAME, + "overlay://$VALID_NAMESPACE/$VALID_ACTOR_NAME") + } + }, + ActorState.INVALID_OVERLAYABLE_ACTOR_NAME withCases { + fun TestState.mockActor(actorUri: String) { + targetOverlayableInfo = OverlayableInfo(OVERLAYABLE_NAME, actorUri) + } + failure("wrongScheme") { + mockActor("notoverlay://$VALID_NAMESPACE/$VALID_ACTOR_NAME") + } + failure("extraPath") { + mockActor("overlay://$VALID_NAMESPACE/$VALID_ACTOR_NAME/extraPath") + } + failure("missingPath") { mockActor("overlay://$VALID_NAMESPACE") } + failure("missingAuthority") { mockActor("overlay://") } + skip { mockActor("overlay://$VALID_NAMESPACE/$VALID_ACTOR_NAME") } + }, + ActorState.NO_NAMED_ACTORS withCases { + failure("empty") { namedActorsMap = emptyMap() } + skip { + namedActorsMap = mapOf(INVALID_NAMESPACE to + mapOf(INVALID_ACTOR_NAME to VALID_ACTOR_PKG)) + } + }, + ActorState.MISSING_NAMESPACE withCases { + failure("invalidNamespace") { + namedActorsMap = mapOf(INVALID_NAMESPACE to + mapOf(INVALID_ACTOR_NAME to VALID_ACTOR_PKG)) + } + skip { + namedActorsMap = mapOf(VALID_NAMESPACE to + mapOf(INVALID_ACTOR_NAME to VALID_ACTOR_PKG)) + } + }, + ActorState.MISSING_ACTOR_NAME withCases { + failure("invalidActorName") { + namedActorsMap = mapOf(VALID_NAMESPACE to + mapOf(INVALID_ACTOR_NAME to VALID_ACTOR_PKG)) + } + skip { + namedActorsMap = mapOf(VALID_NAMESPACE to + mapOf(VALID_ACTOR_NAME to VALID_ACTOR_PKG)) + } + }, + ActorState.MISSING_APP_INFO withCases { + failure("nullActorPkgInfo") { actorPkgInfo = null } + failure("nullActorAppInfo") { + actorPkgInfo = PackageInfo().apply { applicationInfo = null } + } + skip { actorPkgInfo = pkgInfo(VALID_ACTOR_PKG) } + }, + ActorState.ACTOR_NOT_PREINSTALLED withCases { + failure("notSystem") { + actorPkgInfo = pkgInfo(VALID_ACTOR_PKG).apply { + applicationInfo.flags = 0 + } + } + skip { + actorPkgInfo = pkgInfo(VALID_ACTOR_PKG).apply { + applicationInfo.flags = ApplicationInfo.FLAG_SYSTEM + } + } + }, + ActorState.INVALID_ACTOR withCases { + failure("invalidUid") { callingUid = INVALID_ACTOR_UID } + skip { callingUid = VALID_ACTOR_UID } + }, + ActorState.ALLOWED withCases { + // No point making an exception for this case in all of the test code, so + // just pretend this is a failure that results in a success result code. + failure("allowed") { /* Do nothing */ } + } ) - } - @Test(expected = SecurityException::class) - fun withOverlayable_withActor_isActor_notPreInstalled() { - verify( - isActor = true, - isPreInstalled = false, - overlayableInfo = OverlayableInfo(OVERLAYABLE_NAME, - "overlay://$NAMESPACE/$ACTOR_NAME") - ) + data class OverlayInfoParams( + var targetPackageName: String = TARGET_PKG, + var targetOverlayableName: String? = null + ) { + fun toOverlayInfo() = OverlayInfo( + OVERLAY_PKG, + targetPackageName, + targetOverlayableName, + null, + "/path", + OverlayInfo.STATE_UNKNOWN, 0, + 0, false) + } + + private infix fun ActorState.withCases(block: TestCase.() -> Unit) = + TestCase(this).apply(block) + + private fun pkgInfo(pkgName: String): PackageInfo = mockThrowOnUnmocked { + this.packageName = pkgName + this.applicationInfo = ApplicationInfo().apply { + this.packageName = pkgName + } + } + + private fun makeTestName(testCase: TestCase, caseName: String, type: Params.Type): String { + val resultSuffix = if (type == Params.Type.ALLOWED) "allowed" else "failed" + return "${testCase.state}_${resultSuffix}_$caseName" + } } + @Parameterized.Parameter(0) + lateinit var params: Params + @Test - fun withOverlayable_withActor_isActor_isPreInstalled() { - verify( - isActor = true, - isPreInstalled = true, - overlayableInfo = OverlayableInfo(OVERLAYABLE_NAME, - "overlay://$NAMESPACE/$ACTOR_NAME") - ) - } + fun verify() { + // Apply all the skip states before the failure to be verified + val testState = CASES.take(params.index) + .fold(TestState.create()) { testState, case -> + testState.apply(case.skip) + } - @Test(expected = SecurityException::class) - fun withOverlayable_invalidActor() { - verify( - isActor = true, - isPreInstalled = true, - overlayableInfo = OverlayableInfo(OVERLAYABLE_NAME, "notValidActor") - ) + // If testing an allowed branch, first apply a failure to ensure it fails + if (params.type == Params.Type.ALLOWED) { + CASES[params.index].failures.firstOrNull()?.second?.run(testState::apply) + assertThat(testState.toResult()).isNotEqualTo(ActorState.ALLOWED) + } + + // Apply the test case in the params to the collected state + testState.apply(params.function) + + // Assert the result matches the expected state + assertThat(testState.toResult()).isEqualTo(params.expectedState) } - private fun verify( - isActor: Boolean = false, - isPreInstalled: Boolean = false, - hasPermission: Boolean = false, - overlayableInfo: OverlayableInfo? = null, - callingUid: Int = UID, - targetOverlayableName: String? = OVERLAYABLE_NAME + private fun TestState.toResult() = OverlayActorEnforcer(this) + .isAllowedActor("test", overlayInfoParams.toOverlayInfo(), callingUid, USER_ID) + + data class Params( + var index: Int, + var expectedState: ActorState, + val testName: String, + val type: Type, + val function: TestState.() -> Unit ) { - val callback = MockCallback( - isActor = isActor, - isPreInstalled = isPreInstalled, - hasPermission = hasPermission, - overlayableInfo = overlayableInfo - ) + override fun toString() = testName - val overlayInfo = overlayInfo(targetOverlayableName) - OverlayActorEnforcer(callback) - .enforceActor(overlayInfo, "test", callingUid, USER_ID) + enum class Type { + FAILURE, + ALLOWED + } } - private fun overlayInfo(targetOverlayableName: String?) = OverlayInfo("com.test.overlay", - "com.test.target", targetOverlayableName, null, "/path", OverlayInfo.STATE_UNKNOWN, 0, - 0, false) + data class TestCase( + val state: ActorState, + val failures: MutableList<Pair<String, TestState.() -> Unit>> = mutableListOf(), + var allowed: MutableList<Pair<String, TestState.() -> Unit>> = mutableListOf(), + var skip: (TestState.() -> Unit) = {} + ) { + fun failure(caseName: String, block: TestState.() -> Unit) { + failures.add(caseName to block) + } - private class MockCallback( - private val isActor: Boolean = false, - private val isPreInstalled: Boolean = false, - private val hasPermission: Boolean = false, - private val overlayableInfo: OverlayableInfo? = null, - private vararg val packageNames: String = arrayOf("com.test.actor.one") + fun allowed(caseName: String, block: TestState.() -> Unit) { + allowed.add(caseName to block) + } + + fun skip(block: TestState.() -> Unit) { + this.skip = block + } + } + + open class TestState private constructor( + var callingUid: Int = NULL_UID, + val overlayInfoParams: OverlayInfoParams = OverlayInfoParams(), + var namedActorsMap: Map<String, Map<String, String>> = emptyMap(), + var hasPermission: Boolean = false, + var targetOverlayableInfo: OverlayableInfo? = null, + var targetPkgInfo: PackageInfo? = null, + var actorPkgInfo: PackageInfo? = null, + vararg val packageNames: String = arrayOf("com.test.actor.one") ) : PackageManagerHelper { - override fun getNamedActors() = if (isActor) { - mapOf(NAMESPACE to mapOf(ACTOR_NAME to ACTOR_PKG_NAME)) - } else { - emptyMap() + companion object { + // Enforce that new instances are spied + fun create() = spy(TestState())!! } + override fun getNamedActors() = namedActorsMap + + @Throws(IOException::class) override fun getOverlayableForTarget( packageName: String, targetOverlayableName: String, userId: Int - ) = overlayableInfo + ) = targetOverlayableInfo?.takeIf { + // Protect against this method being called with the wrong package name + targetPkgInfo == null || targetPkgInfo?.packageName == packageName + } override fun getPackagesForUid(uid: Int) = when (uid) { - UID -> packageNames + EMPTY_UID -> emptyArray() + INVALID_ACTOR_UID -> arrayOf(INVALID_ACTOR_PKG) + VALID_ACTOR_UID -> arrayOf(VALID_ACTOR_PKG) + TARGET_UID -> arrayOf(TARGET_PKG) + NULL_UID -> null else -> null } - override fun getPackageInfo(packageName: String, userId: Int) = PackageInfo().apply { - applicationInfo = ApplicationInfo().apply { - flags = if (isPreInstalled) ApplicationInfo.FLAG_SYSTEM else 0 - } - } + override fun getPackageInfo(packageName: String, userId: Int) = + listOfNotNull(targetPkgInfo, actorPkgInfo).find { it.packageName == packageName } + @Throws(IOException::class) // Mockito requires this checked exception to be declared override fun doesTargetDefineOverlayable(targetPackageName: String?, userId: Int): Boolean { - return overlayableInfo != null + return targetOverlayableInfo?.takeIf { + // Protect against this method being called with the wrong package name + targetPkgInfo == null || targetPkgInfo?.packageName == targetPackageName + } != null } override fun enforcePermission(permission: String?, message: String?) { diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java index 0bf06bb4dda7..dac05424e01f 100644 --- a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java +++ b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java @@ -45,6 +45,7 @@ import android.content.pm.SuspendDialogInfo; import android.content.pm.UserInfo; import android.os.BaseBundle; import android.os.PersistableBundle; +import android.os.Process; import android.os.UserHandle; import android.os.UserManagerInternal; import android.util.ArrayMap; @@ -59,8 +60,12 @@ import androidx.test.runner.AndroidJUnit4; import com.android.permission.persistence.RuntimePermissionsPersistence; import com.android.server.LocalServices; +import com.android.server.pm.parsing.pkg.PackageImpl; +import com.android.server.pm.parsing.pkg.ParsedPackage; import com.android.server.pm.permission.PermissionSettings; +import com.google.common.truth.Truth; + import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -380,6 +385,74 @@ public class PackageManagerSettingsTests { } @Test + public void testWriteReadUsesStaticLibraries() { + final Context context = InstrumentationRegistry.getTargetContext(); + final Object lock = new Object(); + final Settings settingsUnderTest = new Settings(context.getFilesDir(), mPermissionSettings, + mRuntimePermissionsPersistence, lock); + final PackageSetting ps1 = createPackageSetting(PACKAGE_NAME_1); + ps1.appId = Process.FIRST_APPLICATION_UID; + ps1.pkg = ((ParsedPackage) PackageImpl.forTesting(PACKAGE_NAME_1).hideAsParsed()) + .setUid(ps1.appId) + .setSystem(true) + .hideAsFinal(); + final PackageSetting ps2 = createPackageSetting(PACKAGE_NAME_2); + ps2.appId = Process.FIRST_APPLICATION_UID + 1; + ps2.pkg = ((ParsedPackage) PackageImpl.forTesting(PACKAGE_NAME_2).hideAsParsed()) + .setUid(ps2.appId) + .hideAsFinal(); + + ps1.usesStaticLibraries = new String[] { "com.example.shared.one" }; + ps1.usesStaticLibrariesVersions = new long[] { 12 }; + ps1.setFlags(ps1.pkgFlags | ApplicationInfo.FLAG_SYSTEM); + settingsUnderTest.mPackages.put(PACKAGE_NAME_1, ps1); + assertThat(settingsUnderTest.disableSystemPackageLPw(PACKAGE_NAME_1, false), is(true)); + + ps2.usesStaticLibraries = new String[] { "com.example.shared.two" }; + ps2.usesStaticLibrariesVersions = new long[] { 34 }; + settingsUnderTest.mPackages.put(PACKAGE_NAME_2, ps2); + + settingsUnderTest.writeLPr(); + + settingsUnderTest.mPackages.clear(); + settingsUnderTest.mDisabledSysPackages.clear(); + + assertThat(settingsUnderTest.readLPw(createFakeUsers()), is(true)); + + PackageSetting readPs1 = settingsUnderTest.getPackageLPr(PACKAGE_NAME_1); + PackageSetting readPs2 = settingsUnderTest.getPackageLPr(PACKAGE_NAME_2); + + Truth.assertThat(readPs1).isNotNull(); + Truth.assertThat(readPs1.usesStaticLibraries).isNotNull(); + Truth.assertThat(readPs1.usesStaticLibrariesVersions).isNotNull(); + Truth.assertThat(readPs2).isNotNull(); + Truth.assertThat(readPs2.usesStaticLibraries).isNotNull(); + Truth.assertThat(readPs2.usesStaticLibrariesVersions).isNotNull(); + + List<Long> ps1VersionsAsList = new ArrayList<>(); + for (long version : ps1.usesStaticLibrariesVersions) { + ps1VersionsAsList.add(version); + } + + List<Long> ps2VersionsAsList = new ArrayList<>(); + for (long version : ps2.usesStaticLibrariesVersions) { + ps2VersionsAsList.add(version); + } + + Truth.assertThat(readPs1.usesStaticLibraries).asList() + .containsExactlyElementsIn(ps1.usesStaticLibraries).inOrder(); + + Truth.assertThat(readPs1.usesStaticLibrariesVersions).asList() + .containsExactlyElementsIn(ps1VersionsAsList).inOrder(); + + Truth.assertThat(readPs2.usesStaticLibraries).asList() + .containsExactlyElementsIn(ps2.usesStaticLibraries).inOrder(); + + Truth.assertThat(readPs2.usesStaticLibrariesVersions).asList() + .containsExactlyElementsIn(ps2VersionsAsList).inOrder(); + } + + @Test public void testPackageRestrictionsDistractionFlagsDefault() { final PackageSetting defaultSetting = createPackageSetting(PACKAGE_NAME_1); assertThat(defaultSetting.getDistractionFlags(0), is(PackageManager.RESTRICTION_NONE)); @@ -617,7 +690,7 @@ public class PackageManagerSettingsTests { null /*usesStaticLibraries*/, null /*usesStaticLibrariesVersions*/, null /*mimeGroups*/); - assertThat(testPkgSetting01.getCodePath(), is(UPDATED_CODE_PATH)); + assertThat(testPkgSetting01.getPath(), is(UPDATED_CODE_PATH)); assertThat(testPkgSetting01.name, is(PACKAGE_NAME)); assertThat(testPkgSetting01.pkgFlags, is(ApplicationInfo.FLAG_SYSTEM)); assertThat(testPkgSetting01.pkgPrivateFlags, is(ApplicationInfo.PRIVATE_FLAG_PRIVILEGED)); @@ -656,7 +729,7 @@ public class PackageManagerSettingsTests { null /*usesStaticLibrariesVersions*/, null /*mimeGroups*/); assertThat(testPkgSetting01.appId, is(0)); - assertThat(testPkgSetting01.getCodePath(), is(INITIAL_CODE_PATH)); + assertThat(testPkgSetting01.getPath(), is(INITIAL_CODE_PATH)); assertThat(testPkgSetting01.name, is(PACKAGE_NAME)); assertThat(testPkgSetting01.pkgFlags, is(0)); assertThat(testPkgSetting01.pkgPrivateFlags, is(0)); @@ -700,7 +773,7 @@ public class PackageManagerSettingsTests { null /*usesStaticLibrariesVersions*/, null /*mimeGroups*/); assertThat(testPkgSetting01.appId, is(10064)); - assertThat(testPkgSetting01.getCodePath(), is(INITIAL_CODE_PATH)); + assertThat(testPkgSetting01.getPath(), is(INITIAL_CODE_PATH)); assertThat(testPkgSetting01.name, is(PACKAGE_NAME)); assertThat(testPkgSetting01.pkgFlags, is(0)); assertThat(testPkgSetting01.pkgPrivateFlags, is(0)); @@ -741,7 +814,7 @@ public class PackageManagerSettingsTests { null /*usesStaticLibrariesVersions*/, null /*mimeGroups*/); assertThat(testPkgSetting01.appId, is(10064)); - assertThat(testPkgSetting01.getCodePath(), is(UPDATED_CODE_PATH)); + assertThat(testPkgSetting01.getPath(), is(UPDATED_CODE_PATH)); assertThat(testPkgSetting01.name, is(PACKAGE_NAME)); assertThat(testPkgSetting01.pkgFlags, is(0)); assertThat(testPkgSetting01.pkgPrivateFlags, is(0)); @@ -792,10 +865,10 @@ public class PackageManagerSettingsTests { private void verifySettingCopy(PackageSetting origPkgSetting, PackageSetting testPkgSetting) { assertThat(origPkgSetting, is(not(testPkgSetting))); assertThat(origPkgSetting.appId, is(testPkgSetting.appId)); - assertSame(origPkgSetting.getCodePath(), testPkgSetting.getCodePath()); - assertThat(origPkgSetting.getCodePath(), is(testPkgSetting.getCodePath())); - assertSame(origPkgSetting.getCodePathString(), testPkgSetting.getCodePathString()); - assertThat(origPkgSetting.getCodePathString(), is(testPkgSetting.getCodePathString())); + assertSame(origPkgSetting.getPath(), testPkgSetting.getPath()); + assertThat(origPkgSetting.getPath(), is(testPkgSetting.getPath())); + assertSame(origPkgSetting.getPathString(), testPkgSetting.getPathString()); + assertThat(origPkgSetting.getPathString(), is(testPkgSetting.getPathString())); assertSame(origPkgSetting.cpuAbiOverrideString, testPkgSetting.cpuAbiOverrideString); assertThat(origPkgSetting.cpuAbiOverrideString, is(testPkgSetting.cpuAbiOverrideString)); assertThat(origPkgSetting.firstInstallTime, is(testPkgSetting.firstInstallTime)); diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java index 2651cfa5449b..1d384e961dc3 100644 --- a/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java @@ -312,7 +312,7 @@ public class PackageParserTest { private static PackageSetting mockPkgSetting(AndroidPackage pkg) { return new PackageSetting(pkg.getPackageName(), pkg.getRealPackage(), - new File(pkg.getCodePath()), null, pkg.getPrimaryCpuAbi(), pkg.getSecondaryCpuAbi(), + new File(pkg.getPath()), null, pkg.getPrimaryCpuAbi(), pkg.getSecondaryCpuAbi(), null, pkg.getVersionCode(), PackageInfoUtils.appInfoFlags(pkg, null), PackageInfoUtils.appInfoPrivateFlags(pkg, null), @@ -335,8 +335,8 @@ public class PackageParserTest { assertEquals(a.getPackageName(), b.getPackageName()); assertArrayEquals(a.getSplitNames(), b.getSplitNames()); assertEquals(a.getVolumeUuid(), b.getVolumeUuid()); - assertEquals(a.getCodePath(), b.getCodePath()); - assertEquals(a.getBaseCodePath(), b.getBaseCodePath()); + assertEquals(a.getPath(), b.getPath()); + assertEquals(a.getBaseApkPath(), b.getBaseApkPath()); assertArrayEquals(a.getSplitCodePaths(), b.getSplitCodePaths()); assertArrayEquals(a.getSplitRevisionCodes(), b.getSplitRevisionCodes()); assertArrayEquals(a.getSplitFlags(), b.getSplitFlags()); diff --git a/services/tests/servicestests/src/com/android/server/pm/ScanTests.java b/services/tests/servicestests/src/com/android/server/pm/ScanTests.java index 56dddb0a8112..4d8cc4647271 100644 --- a/services/tests/servicestests/src/com/android/server/pm/ScanTests.java +++ b/services/tests/servicestests/src/com/android/server/pm/ScanTests.java @@ -533,7 +533,7 @@ public class ScanTests { arrayContaining("some.static.library", "some.other.static.library")); assertThat(pkgSetting.usesStaticLibrariesVersions, is(new long[]{234L, 456L})); assertThat(pkgSetting.pkg, is(scanResult.request.parsedPackage)); - assertThat(pkgSetting.getCodePath(), is(new File(createCodePath(packageName)))); + assertThat(pkgSetting.getPath(), is(new File(createCodePath(packageName)))); assertThat(pkgSetting.versionCode, is(PackageInfo.composeLongVersionCode(1, 2345))); } diff --git a/services/tests/servicestests/src/com/android/server/pm/dex/DexMetadataHelperTest.java b/services/tests/servicestests/src/com/android/server/pm/dex/DexMetadataHelperTest.java index caa8ae5e0e39..3ce7a7d73d4a 100644 --- a/services/tests/servicestests/src/com/android/server/pm/dex/DexMetadataHelperTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/dex/DexMetadataHelperTest.java @@ -29,12 +29,10 @@ import android.content.pm.PackageParser.PackageLite; import android.content.pm.PackageParser.PackageParserException; import android.content.pm.dex.DexMetadataHelper; import android.content.pm.parsing.ApkLiteParseUtils; -import android.content.pm.parsing.result.ParseInput; import android.content.pm.parsing.result.ParseResult; import android.content.pm.parsing.result.ParseTypeImpl; import android.os.FileUtils; -import androidx.annotation.NonNull; import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; @@ -106,9 +104,9 @@ public class DexMetadataHelperTest { Map<String, String> packageDexMetadata = AndroidPackageUtils.getPackageDexMetadata(pkg); assertEquals(1, packageDexMetadata.size()); - String baseDexMetadata = packageDexMetadata.get(pkg.getBaseCodePath()); + String baseDexMetadata = packageDexMetadata.get(pkg.getBaseApkPath()); assertNotNull(baseDexMetadata); - assertTrue(isDexMetadataForApk(baseDexMetadata, pkg.getBaseCodePath())); + assertTrue(isDexMetadataForApk(baseDexMetadata, pkg.getBaseApkPath())); } @Test @@ -122,9 +120,9 @@ public class DexMetadataHelperTest { Map<String, String> packageDexMetadata = AndroidPackageUtils.getPackageDexMetadata(pkg); assertEquals(2, packageDexMetadata.size()); - String baseDexMetadata = packageDexMetadata.get(pkg.getBaseCodePath()); + String baseDexMetadata = packageDexMetadata.get(pkg.getBaseApkPath()); assertNotNull(baseDexMetadata); - assertTrue(isDexMetadataForApk(baseDexMetadata, pkg.getBaseCodePath())); + assertTrue(isDexMetadataForApk(baseDexMetadata, pkg.getBaseApkPath())); String splitDexMetadata = packageDexMetadata.get(pkg.getSplitCodePaths()[0]); assertNotNull(splitDexMetadata); diff --git a/services/tests/servicestests/utils-mockito/com/android/server/testutils/MockitoUtils.kt b/services/tests/servicestests/utils-mockito/com/android/server/testutils/MockitoUtils.kt index 056fa886f640..59cbd1ce1d7b 100644 --- a/services/tests/servicestests/utils-mockito/com/android/server/testutils/MockitoUtils.kt +++ b/services/tests/servicestests/utils-mockito/com/android/server/testutils/MockitoUtils.kt @@ -22,8 +22,6 @@ import org.mockito.invocation.InvocationOnMock import org.mockito.stubbing.Answer import org.mockito.stubbing.Stubber -// TODO(chiuwinson): Move this entire file to a shared utility module -// TODO(b/135203078): De-dupe utils added for overlays vs package refactor object MockitoUtils { val ANSWER_THROWS = Answer<Any?> { when (val name = it.method.name) { @@ -64,7 +62,7 @@ fun <Type : Any?> whenever(mock: Type, block: InvocationOnMock.() -> Any?) = fun whenever(mock: Unit) = Mockito.`when`(mock).thenAnswer { } -inline fun <reified T> spyThrowOnUnmocked(value: T?, block: T.() -> Unit): T { +inline fun <reified T> spyThrowOnUnmocked(value: T?, block: T.() -> Unit = {}): T { val swappingAnswer = object : Answer<Any?> { var delegate: Answer<*> = Answers.RETURNS_DEFAULTS @@ -81,4 +79,5 @@ inline fun <reified T> spyThrowOnUnmocked(value: T?, block: T.() -> Unit): T { } } -inline fun <reified T> mockThrowOnUnmocked(block: T.() -> Unit) = spyThrowOnUnmocked<T>(null, block) +inline fun <reified T> mockThrowOnUnmocked(block: T.() -> Unit = {}) = + spyThrowOnUnmocked<T>(null, block) diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java index 86447192a441..9e7226e7cacf 100755 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -1086,12 +1086,18 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } /** - * Confirm the system user on automotive devices can use car categories + * Confirm an application with the SEND_CATEGORY_CAR_NOTIFICATIONS permission on automotive + * devices can use car categories. */ @Test - public void testEnqueuedRestrictedNotifications_asSystem() throws Exception { + public void testEnqueuedRestrictedNotifications_hasPermission() throws Exception { when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, 0)) .thenReturn(true); + // SEND_CATEGORY_CAR_NOTIFICATIONS is a system-level permission that this test cannot + // obtain. Mocking out enforce permission call to ensure notifications can be created when + // permitted. + doNothing().when(mContext).enforceCallingPermission( + eq("android.permission.SEND_CATEGORY_CAR_NOTIFICATIONS"), anyString()); List<String> categories = Arrays.asList(Notification.CATEGORY_CAR_EMERGENCY, Notification.CATEGORY_CAR_WARNING, Notification.CATEGORY_CAR_INFORMATION); @@ -1114,7 +1120,6 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { */ @Test public void testEnqueuedRestrictedNotifications_notAutomotive() throws Exception { - mService.isSystemUid = false; when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, 0)) .thenReturn(false); List<String> categories = Arrays.asList(Notification.CATEGORY_CAR_EMERGENCY, @@ -1134,12 +1139,11 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } /** - * Confirm if a non-system user tries to use the car categories on a automotive device that - * they will get a security exception + * Confirm if an application tries to use the car categories on a automotive device without the + * SEND_CATEGORY_CAR_NOTIFICATIONS permission that a security exception will be thrown. */ @Test - public void testEnqueuedRestrictedNotifications_badUser() throws Exception { - mService.isSystemUid = false; + public void testEnqueuedRestrictedNotifications_noPermission() throws Exception { when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, 0)) .thenReturn(true); List<String> categories = Arrays.asList(Notification.CATEGORY_CAR_EMERGENCY, diff --git a/services/tests/uiservicestests/src/com/android/server/slice/PackageMatchingCacheTest.java b/services/tests/uiservicestests/src/com/android/server/slice/PackageMatchingCacheTest.java new file mode 100644 index 000000000000..f6c854e23494 --- /dev/null +++ b/services/tests/uiservicestests/src/com/android/server/slice/PackageMatchingCacheTest.java @@ -0,0 +1,76 @@ +/* + * 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.server.slice; + +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.testing.AndroidTestingRunner; +import android.testing.TestableLooper.RunWithLooper; + +import androidx.test.filters.SmallTest; + +import com.android.server.UiServiceTestCase; +import com.android.server.slice.SliceManagerService.PackageMatchingCache; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.function.Supplier; + +@SmallTest +@RunWith(AndroidTestingRunner.class) +@RunWithLooper +public class PackageMatchingCacheTest extends UiServiceTestCase { + + private final Supplier<String> supplier = mock(Supplier.class); + private final PackageMatchingCache cache = new PackageMatchingCache(supplier); + + @Test + public void testNulls() { + // Doesn't get for a null input + cache.matches(null); + verify(supplier, never()).get(); + + // Gets once valid input in sent. + cache.matches(""); + verify(supplier).get(); + } + + @Test + public void testCaching() { + when(supplier.get()).thenReturn("ret.pkg"); + + assertTrue(cache.matches("ret.pkg")); + assertTrue(cache.matches("ret.pkg")); + assertTrue(cache.matches("ret.pkg")); + + verify(supplier, times(1)).get(); + } + + @Test + public void testGetOnFailure() { + when(supplier.get()).thenReturn("ret.pkg"); + assertTrue(cache.matches("ret.pkg")); + + when(supplier.get()).thenReturn("other.pkg"); + assertTrue(cache.matches("other.pkg")); + verify(supplier, times(2)).get(); + } +} diff --git a/services/tests/uiservicestests/src/com/android/server/slice/SliceManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/slice/SliceManagerServiceTest.java index cf1c36c0d243..a4436951f48b 100644 --- a/services/tests/uiservicestests/src/com/android/server/slice/SliceManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/slice/SliceManagerServiceTest.java @@ -90,6 +90,8 @@ public class SliceManagerServiceTest extends UiServiceTestCase { @Test public void testAddPinCreatesPinned() throws RemoteException { + doReturn("pkg").when(mService).getDefaultHome(anyInt()); + mService.pinSlice("pkg", TEST_URI, EMPTY_SPECS, mToken); mService.pinSlice("pkg", TEST_URI, EMPTY_SPECS, mToken); verify(mService, times(1)).createPinnedSlice(eq(maybeAddUserId(TEST_URI, 0)), anyString()); @@ -97,6 +99,8 @@ public class SliceManagerServiceTest extends UiServiceTestCase { @Test public void testRemovePinDestroysPinned() throws RemoteException { + doReturn("pkg").when(mService).getDefaultHome(anyInt()); + mService.pinSlice("pkg", TEST_URI, EMPTY_SPECS, mToken); when(mCreatedSliceState.unpin(eq("pkg"), eq(mToken))).thenReturn(false); diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java index 32896791d915..89a34cfc77f3 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java @@ -24,7 +24,6 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; -import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_USER; import static android.os.Build.VERSION_CODES.P; import static android.os.Build.VERSION_CODES.Q; import static android.view.Display.DEFAULT_DISPLAY; @@ -762,13 +761,14 @@ public class DisplayContentTests extends WindowTestsBase { window.mAttrs.screenOrientation, dc.getOrientation()); // ---------------------------- - // Test close-to-square display + // Test close-to-square display - should be handled in the same way // ---------------------------- dc.mBaseDisplayHeight = dc.mBaseDisplayWidth; dc.configureDisplayPolicy(); - assertEquals("Screen orientation must be SCREEN_ORIENTATION_USER.", - SCREEN_ORIENTATION_USER, dc.getOrientation()); + assertEquals( + "Screen orientation must be defined by the window even on close-to-square display.", + window.mAttrs.screenOrientation, dc.getOrientation()); } @Test diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java index b50530ed3059..b77d21c0f711 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java @@ -27,11 +27,9 @@ import static android.view.WindowInsetsController.BEHAVIOR_SHOW_BARS_BY_TOUCH; import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; import static android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND; import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS; -import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR; import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; -import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION; @@ -39,7 +37,6 @@ import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR; -import static android.view.WindowManager.LayoutParams.TYPE_TOAST; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.server.policy.WindowManagerPolicy.NAV_BAR_BOTTOM; @@ -47,7 +44,6 @@ import static com.android.server.policy.WindowManagerPolicy.NAV_BAR_RIGHT; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; @@ -235,18 +231,6 @@ public class DisplayPolicyTests extends WindowTestsBase { assertEquals(mAppWindow, policy.getTopFullscreenOpaqueWindow()); } - @Test - public void testShouldShowToastWhenScreenLocked() { - final DisplayPolicy policy = mDisplayContent.getDisplayPolicy(); - final WindowState activity = createApplicationWindow(); - final WindowState toast = createToastWindow(); - - policy.adjustWindowParamsLw(toast, toast.mAttrs, 0 /* callingPid */, 0 /* callingUid */); - - assertTrue(policy.canToastShowWhenLocked(0 /* callingUid */)); - assertNotEquals(0, toast.getAttrs().flags & FLAG_SHOW_WHEN_LOCKED); - } - @Test(expected = RuntimeException.class) public void testMainAppWindowDisallowFitSystemWindowTypes() { final DisplayPolicy policy = mDisplayContent.getDisplayPolicy(); @@ -257,16 +241,6 @@ public class DisplayPolicyTests extends WindowTestsBase { 0 /* callingUid */); } - private WindowState createToastWindow() { - final WindowState win = createWindow(null, TYPE_TOAST, "Toast"); - final WindowManager.LayoutParams attrs = win.mAttrs; - attrs.width = WRAP_CONTENT; - attrs.height = WRAP_CONTENT; - attrs.flags = FLAG_KEEP_SCREEN_ON | FLAG_NOT_FOCUSABLE | FLAG_NOT_TOUCHABLE; - attrs.format = PixelFormat.TRANSLUCENT; - return win; - } - private WindowState createApplicationWindow() { final WindowState win = createWindow(null, TYPE_APPLICATION, "Application"); final WindowManager.LayoutParams attrs = win.mAttrs; diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java index 5231fd7ba956..58d994c6cae3 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java @@ -1172,12 +1172,12 @@ public class RecentTasksTest extends WindowTestsBase { () -> mAtm.setTaskWindowingModeSplitScreenPrimary(0, true)); assertSecurityException(expectCallable, () -> mAtm.moveTopActivityToPinnedStack(INVALID_STACK_ID, new Rect())); - assertSecurityException(expectCallable, () -> mAtm.getAllStackInfos()); + assertSecurityException(expectCallable, () -> mAtm.getAllRootTaskInfos()); assertSecurityException(expectCallable, - () -> mAtm.getStackInfo(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_UNDEFINED)); + () -> mAtm.getRootTaskInfo(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_UNDEFINED)); assertSecurityException(expectCallable, () -> { try { - mAtm.getFocusedStackInfo(); + mAtm.getFocusedRootTaskInfo(); } catch (RemoteException e) { // Ignore } diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java index 29081d389225..edcf0d4f5501 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java @@ -138,8 +138,6 @@ public class SizeCompatTests extends WindowTestsBase { public void testFixedAspectRatioBoundsWithDecorInSquareDisplay() { final int notchHeight = 100; setUpApp(new TestDisplayContent.Builder(mAtm, 600, 800).setNotch(notchHeight).build()); - // Rotation is ignored so because the display size is close to square (700/600<1.333). - assertTrue(mActivity.mDisplayContent.ignoreRotationForApps()); final Rect displayBounds = mActivity.mDisplayContent.getWindowConfiguration().getBounds(); final float aspectRatio = 1.2f; @@ -163,23 +161,14 @@ public class SizeCompatTests extends WindowTestsBase { mActivity.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE); assertFitted(); - // After the orientation of activity is changed, even display is not rotated, the aspect - // ratio should be the same (bounds=[0, 0 - 600, 600], appBounds=[0, 100 - 600, 600]). + // After the orientation of activity is changed, the display is rotated, the aspect + // ratio should be the same (bounds=[100, 0 - 800, 583], appBounds=[100, 0 - 800, 583]). assertEquals(appBounds.width(), appBounds.height() * aspectRatio, 0.5f /* delta */); - // The notch is still on top. - assertEquals(mActivity.getBounds().height(), appBounds.height() + notchHeight); + // The notch is no longer on top. + assertEquals(appBounds, mActivity.getBounds()); mActivity.setRequestedOrientation(SCREEN_ORIENTATION_PORTRAIT); assertFitted(); - - // Close-to-square display can rotate without being restricted by the requested orientation. - // The notch becomes on the left side. The activity is horizontal centered in 100 ~ 800. - // So the bounds and appBounds will be [200, 0 - 700, 600] (500x600) that is still fitted. - // Left = 100 + (800 - 100 - 500) / 2 = 200. - rotateDisplay(mActivity.mDisplayContent, ROTATION_90); - assertFitted(); - assertEquals(appBounds.left, - notchHeight + (displayBounds.width() - notchHeight - appBounds.width()) / 2); } @Test diff --git a/services/tests/wmtests/src/com/android/server/wm/TestIWindow.java b/services/tests/wmtests/src/com/android/server/wm/TestIWindow.java index e39b4bcd2eb0..d37f3f402c30 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TestIWindow.java +++ b/services/tests/wmtests/src/com/android/server/wm/TestIWindow.java @@ -17,17 +17,16 @@ package com.android.server.wm; import android.graphics.Point; -import android.graphics.Rect; import android.os.Bundle; import android.os.ParcelFileDescriptor; import android.os.RemoteException; import android.util.MergedConfiguration; -import android.view.DisplayCutout; import android.view.DragEvent; import android.view.IScrollCaptureController; import android.view.IWindow; import android.view.InsetsSourceControl; import android.view.InsetsState; +import android.window.ClientWindowFrames; import com.android.internal.os.IResultReceiver; @@ -38,10 +37,9 @@ public class TestIWindow extends IWindow.Stub { } @Override - public void resized(Rect frame, Rect contentInsets, Rect visibleInsets, - Rect stableInsets, boolean reportDraw, MergedConfiguration mergedConfig, - Rect backDropFrame, boolean forceLayout, boolean alwaysConsumeSystemBars, int displayId, - DisplayCutout.ParcelableWrapper displayCutout) throws RemoteException { + public void resized(ClientWindowFrames frames, boolean reportDraw, + MergedConfiguration mergedConfig, boolean forceLayout, boolean alwaysConsumeSystemBars, + int displayId) throws RemoteException { } @Override diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java index 38909f6a28d4..5d8a2a11dce8 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java @@ -52,7 +52,7 @@ import static org.mockito.ArgumentMatchers.anyInt; import android.app.ActivityManager; import android.app.ActivityManager.RunningTaskInfo; -import android.app.ActivityManager.StackInfo; +import android.app.ActivityTaskManager.RootTaskInfo; import android.app.PictureInPictureParams; import android.content.pm.ActivityInfo; import android.content.res.Configuration; @@ -301,9 +301,9 @@ public class WindowOrganizerTests extends WindowTestsBase { removeGlobalMinSizeRestriction(); final Task stack = new TaskBuilder(mSupervisor) .setWindowingMode(WINDOWING_MODE_FREEFORM).build(); - StackInfo info = - mWm.mAtmService.getStackInfo(WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD); - assertEquals(stack.mRemoteToken.toWindowContainerToken(), info.stackToken); + RootTaskInfo info = + mWm.mAtmService.getRootTaskInfo(WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD); + assertEquals(stack.mRemoteToken.toWindowContainerToken(), info.token); testTransaction(stack); } diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java index 3106ca26c8a1..c18043fcc4b9 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java @@ -581,12 +581,10 @@ public class WindowStateTests extends WindowTestsBase { mWm.mResizingWindows.remove(win); spyOn(win.mClient); try { - doThrow(new RemoteException("test")).when(win.mClient).resized(any() /* frame */, - any() /* contentInsets */, any() /* visibleInsets */, any() /* stableInsets */, + doThrow(new RemoteException("test")).when(win.mClient).resized(any() /* frames */, anyBoolean() /* reportDraw */, any() /* mergedConfig */, - any() /* backDropFrame */, anyBoolean() /* forceLayout */, - anyBoolean() /* alwaysConsumeSystemBars */, anyInt() /* displayId */, - any() /* displayCutout */); + anyBoolean() /* forceLayout */, anyBoolean() /* alwaysConsumeSystemBars */, + anyInt() /* displayId */); } catch (RemoteException ignored) { } win.reportResized(); diff --git a/telecomm/OWNERS b/telecomm/OWNERS index 673a0a9b558e..9969ee965fbd 100644 --- a/telecomm/OWNERS +++ b/telecomm/OWNERS @@ -1,7 +1,8 @@ set noparent -tgunn@google.com breadley@google.com hallliu@google.com +tgunn@google.com +xiaotonj@google.com +shuoq@google.com rgreenwalt@google.com -paulye@google.com diff --git a/telecomm/java/android/telecom/Logging/SessionManager.java b/telecomm/java/android/telecom/Logging/SessionManager.java index 67e5eabf54eb..9d17219c1ae4 100644 --- a/telecomm/java/android/telecom/Logging/SessionManager.java +++ b/telecomm/java/android/telecom/Logging/SessionManager.java @@ -17,6 +17,7 @@ package android.telecom.Logging; import android.annotation.Nullable; +import android.content.ContentResolver; import android.content.Context; import android.os.Handler; import android.os.Looper; @@ -453,7 +454,9 @@ public class SessionManager { * perform a sweep to check and make sure that the session is still not incomplete (stale). */ private long getCleanupTimeout(Context context) { - return Settings.Secure.getLong(context.getContentResolver(), TIMEOUTS_PREFIX + - "stale_session_cleanup_timeout_millis", DEFAULT_SESSION_TIMEOUT_MS); + final ContentResolver cr = context.getContentResolver(); + return Settings.Secure.getLongForUser(cr, TIMEOUTS_PREFIX + + "stale_session_cleanup_timeout_millis", DEFAULT_SESSION_TIMEOUT_MS, + cr.getUserId()); } } diff --git a/telecomm/java/com/android/internal/telecom/IDeviceIdleControllerAdapter.aidl b/telecomm/java/com/android/internal/telecom/IDeviceIdleControllerAdapter.aidl new file mode 100644 index 000000000000..50bbf4c41284 --- /dev/null +++ b/telecomm/java/com/android/internal/telecom/IDeviceIdleControllerAdapter.aidl @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2020 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.telecom; + +/* + * Adapter interface for using DeviceIdleController, since the PowerWhitelistManager is not + * directly accessible in the SYSTEM process. + */ +interface IDeviceIdleControllerAdapter { + void exemptAppTemporarilyForEvent(String packageName, long duration, int userHandle, + String reason); +}
\ No newline at end of file diff --git a/telecomm/java/com/android/internal/telecom/IInternalServiceRetriever.aidl b/telecomm/java/com/android/internal/telecom/IInternalServiceRetriever.aidl new file mode 100644 index 000000000000..b56010696361 --- /dev/null +++ b/telecomm/java/com/android/internal/telecom/IInternalServiceRetriever.aidl @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2020 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.telecom; + +import com.android.internal.telecom.IDeviceIdleControllerAdapter; + +/* + * Interface used to retrieve services that are only accessible via LocalService in the SYSTEM + * process. + */ +interface IInternalServiceRetriever { + IDeviceIdleControllerAdapter getDeviceIdleController(); +} diff --git a/telecomm/java/com/android/internal/telecom/ITelecomLoader.aidl b/telecomm/java/com/android/internal/telecom/ITelecomLoader.aidl new file mode 100644 index 000000000000..eda0f5b24958 --- /dev/null +++ b/telecomm/java/com/android/internal/telecom/ITelecomLoader.aidl @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2020 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.telecom; + +import com.android.internal.telecom.ITelecomService; +import com.android.internal.telecom.IInternalServiceRetriever; + +/* + * Internal interface for getting an instance of the ITelecomService for external publication. + * Allows the TelecomLoaderService to pass additional dependencies required for creation. + */ +interface ITelecomLoader { + ITelecomService createTelecomService(IInternalServiceRetriever retriever); +} diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt index c1a3ed695096..69b11872e123 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt @@ -109,7 +109,7 @@ fun LayersAssertion.navBarLayerRotatesAndScales( } if (startingPos == endingPos) { - all("navBarLayerRotatesAndScales", enabled, bugId) { + all("navBarLayerRotatesAndScales", enabled = false, bugId = 167747321) { this.hasVisibleRegion(FlickerTestBase.NAVIGATION_BAR_WINDOW_TITLE, startingPos) } } diff --git a/tools/validatekeymaps/Main.cpp b/tools/validatekeymaps/Main.cpp index 0aca13e95a52..7c150f9c8db9 100644 --- a/tools/validatekeymaps/Main.cpp +++ b/tools/validatekeymaps/Main.cpp @@ -16,8 +16,8 @@ #include <input/KeyCharacterMap.h> #include <input/KeyLayoutMap.h> +#include <input/PropertyMap.h> #include <input/VirtualKeyMap.h> -#include <utils/PropertyMap.h> #include <stdarg.h> #include <stdio.h> diff --git a/wifi/Android.bp b/wifi/Android.bp index 941ff61b3ba5..3040041038cb 100644 --- a/wifi/Android.bp +++ b/wifi/Android.bp @@ -129,12 +129,8 @@ java_sdk_library { }, hostdex: true, // for hiddenapi check - // Allow access to the stubs from anywhere. - visibility: ["//visibility:public"], - // Restrict access to implementation library. impl_library_visibility: [ - "//visibility:override", // Ignore the visibility property. "//frameworks/opt/net/wifi/service:__subpackages__", ] + test_access_hidden_api_whitelist, diff --git a/wifi/api/current.txt b/wifi/api/current.txt index ae9b5ab07851..3f5c673eeb81 100644 --- a/wifi/api/current.txt +++ b/wifi/api/current.txt @@ -144,6 +144,7 @@ package android.net.wifi { @Deprecated public static class WifiConfiguration.GroupCipher { field @Deprecated public static final int CCMP = 3; // 0x3 + field @Deprecated public static final int GCMP_128 = 7; // 0x7 field @Deprecated public static final int GCMP_256 = 5; // 0x5 field @Deprecated public static final int SMS4 = 6; // 0x6 field @Deprecated public static final int TKIP = 2; // 0x2 @@ -173,6 +174,7 @@ package android.net.wifi { @Deprecated public static class WifiConfiguration.PairwiseCipher { field @Deprecated public static final int CCMP = 2; // 0x2 + field @Deprecated public static final int GCMP_128 = 5; // 0x5 field @Deprecated public static final int GCMP_256 = 3; // 0x3 field @Deprecated public static final int NONE = 0; // 0x0 field @Deprecated public static final int SMS4 = 4; // 0x4 @@ -655,6 +657,7 @@ package android.net.wifi.aware { method public void attach(@NonNull android.net.wifi.aware.AttachCallback, @NonNull android.net.wifi.aware.IdentityChangedListener, @Nullable android.os.Handler); method public android.net.wifi.aware.Characteristics getCharacteristics(); method public boolean isAvailable(); + method public boolean isDeviceAttached(); field public static final String ACTION_WIFI_AWARE_STATE_CHANGED = "android.net.wifi.aware.action.WIFI_AWARE_STATE_CHANGED"; field public static final int WIFI_AWARE_DATA_PATH_ROLE_INITIATOR = 0; // 0x0 field public static final int WIFI_AWARE_DATA_PATH_ROLE_RESPONDER = 1; // 0x1 diff --git a/wifi/api/system-current.txt b/wifi/api/system-current.txt index eff64a31367a..c3e573c311c2 100644 --- a/wifi/api/system-current.txt +++ b/wifi/api/system-current.txt @@ -449,6 +449,7 @@ package android.net.wifi { method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public android.net.wifi.WifiConfiguration getWifiApConfiguration(); method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public int getWifiApState(); method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD}) public java.util.List<android.net.wifi.WifiConfiguration> getWifiConfigForMatchedNetworkSuggestionsSharedWithUser(@NonNull java.util.List<android.net.wifi.ScanResult>); + method public boolean is60GHzBandSupported(); method public boolean isApMacRandomizationSupported(); method public boolean isConnectedMacRandomizationSupported(); method @Deprecated public boolean isDeviceToDeviceRttSupported(); @@ -651,6 +652,7 @@ package android.net.wifi { field public static final int WIFI_BAND_5_GHZ = 2; // 0x2 field public static final int WIFI_BAND_5_GHZ_DFS_ONLY = 4; // 0x4 field public static final int WIFI_BAND_5_GHZ_WITH_DFS = 6; // 0x6 + field public static final int WIFI_BAND_60_GHZ = 16; // 0x10 field public static final int WIFI_BAND_6_GHZ = 8; // 0x8 field public static final int WIFI_BAND_BOTH = 3; // 0x3 field public static final int WIFI_BAND_BOTH_WITH_DFS = 7; // 0x7 diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index e4937892e2f7..b3ed8ac09034 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -118,6 +118,8 @@ interface IWifiManager boolean is6GHzBandSupported(); + boolean is60GHzBandSupported(); + boolean isWifiStandardSupported(int standard); DhcpInfo getDhcpInfo(); diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java index 9302f78b7fca..54ec1e1c7c0b 100644 --- a/wifi/java/android/net/wifi/ScanResult.java +++ b/wifi/java/android/net/wifi/ScanResult.java @@ -595,6 +595,27 @@ public final class ScanResult implements Parcelable { public static final int BAND_6_GHZ_END_FREQ_MHZ = 7105; /** + * 60 GHz band first channel number + * @hide + */ + public static final int BAND_60_GHZ_FIRST_CH_NUM = 1; + /** + * 60 GHz band last channel number + * @hide + */ + public static final int BAND_60_GHZ_LAST_CH_NUM = 6; + /** + * 60 GHz band frequency of first channel in MHz + * @hide + */ + public static final int BAND_60_GHZ_START_FREQ_MHZ = 58320; + /** + * 60 GHz band frequency of last channel in MHz + * @hide + */ + public static final int BAND_60_GHZ_END_FREQ_MHZ = 70200; + + /** * Utility function to check if a frequency within 2.4 GHz band * @param freqMhz frequency in MHz * @return true if within 2.4GHz, false otherwise @@ -628,6 +649,17 @@ public final class ScanResult implements Parcelable { } /** + * Utility function to check if a frequency within 60 GHz band + * @param freqMhz + * @return true if within 60GHz, false otherwise + * + * @hide + */ + public static boolean is60GHz(int freqMhz) { + return freqMhz >= BAND_60_GHZ_START_FREQ_MHZ && freqMhz <= BAND_60_GHZ_END_FREQ_MHZ; + } + + /** * Utility function to convert channel number/band to frequency in MHz * @param channel number to convert * @param band of channel to convert @@ -707,6 +739,13 @@ public final class ScanResult implements Parcelable { } /** + * @hide + */ + public boolean is60GHz() { + return ScanResult.is60GHz(frequency); + } + + /** * @hide * anqp lines from supplicant BSS response */ diff --git a/wifi/java/android/net/wifi/SoftApCapability.java b/wifi/java/android/net/wifi/SoftApCapability.java index 99c4eac7977b..cf54f26fc5e4 100644 --- a/wifi/java/android/net/wifi/SoftApCapability.java +++ b/wifi/java/android/net/wifi/SoftApCapability.java @@ -21,7 +21,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.net.wifi.SoftApConfiguration.BandType; -import android.os.Build; +import android.net.wifi.util.SdkLevelUtil; import android.os.Parcel; import android.os.Parcelable; @@ -176,7 +176,7 @@ public final class SoftApCapability implements Parcelable { */ @NonNull public int[] getSupportedChannelList(@BandType int band) { - if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.R) { + if (!SdkLevelUtil.isAtLeastS()) { throw new UnsupportedOperationException(); } switch (band) { diff --git a/wifi/java/android/net/wifi/SoftApConfiguration.java b/wifi/java/android/net/wifi/SoftApConfiguration.java index 393fe8d3ab9a..bc837b3c344d 100644 --- a/wifi/java/android/net/wifi/SoftApConfiguration.java +++ b/wifi/java/android/net/wifi/SoftApConfiguration.java @@ -22,7 +22,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.net.MacAddress; -import android.os.Build; +import android.net.wifi.util.SdkLevelUtil; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; @@ -551,7 +551,7 @@ public final class SoftApConfiguration implements Parcelable { @SystemApi @MacRandomizationSetting public int getMacRandomizationSetting() { - if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.R) { + if (!SdkLevelUtil.isAtLeastS()) { throw new UnsupportedOperationException(); } return mMacRandomizationSetting; @@ -1046,7 +1046,7 @@ public final class SoftApConfiguration implements Parcelable { @NonNull public Builder setMacRandomizationSetting( @MacRandomizationSetting int macRandomizationSetting) { - if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.R) { + if (!SdkLevelUtil.isAtLeastS()) { throw new UnsupportedOperationException(); } mMacRandomizationSetting = macRandomizationSetting; diff --git a/wifi/java/android/net/wifi/SoftApInfo.java b/wifi/java/android/net/wifi/SoftApInfo.java index 4791275cdce5..40981f7b0fb1 100644 --- a/wifi/java/android/net/wifi/SoftApInfo.java +++ b/wifi/java/android/net/wifi/SoftApInfo.java @@ -20,7 +20,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.net.MacAddress; -import android.os.Build; +import android.net.wifi.util.SdkLevelUtil; import android.os.Parcel; import android.os.Parcelable; @@ -138,7 +138,7 @@ public final class SoftApInfo implements Parcelable { */ @Nullable public MacAddress getBssid() { - if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.R) { + if (!SdkLevelUtil.isAtLeastS()) { throw new UnsupportedOperationException(); } return mBssid; diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index 79f61bb791f6..02b7a42d3878 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -301,9 +301,16 @@ public class WifiConfiguration implements Parcelable { */ public static final int SMS4 = 4; + /** + * AES in Galois/Counter Mode with a 128-bit integrity key + */ + public static final int GCMP_128 = 5; + + public static final String varName = "pairwise"; - public static final String[] strings = { "NONE", "TKIP", "CCMP", "GCMP_256", "SMS4" }; + public static final String[] strings = { "NONE", "TKIP", "CCMP", "GCMP_256", "SMS4", + "GCMP_128" }; } /** @@ -345,13 +352,17 @@ public class WifiConfiguration implements Parcelable { * SMS4 cipher for WAPI */ public static final int SMS4 = 6; + /** + * AES in Galois/Counter Mode with a 128-bit integrity key + */ + public static final int GCMP_128 = 7; public static final String varName = "group"; public static final String[] strings = { /* deprecated */ "WEP40", /* deprecated */ "WEP104", "TKIP", "CCMP", "GTK_NOT_USED", "GCMP_256", - "SMS4" }; + "SMS4", "GCMP_128" }; } /** @@ -498,8 +509,10 @@ public class WifiConfiguration implements Parcelable { allowedProtocols.set(WifiConfiguration.Protocol.RSN); allowedKeyManagement.set(WifiConfiguration.KeyMgmt.SAE); allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP); + allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.GCMP_128); allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.GCMP_256); allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP); + allowedGroupCiphers.set(WifiConfiguration.GroupCipher.GCMP_128); allowedGroupCiphers.set(WifiConfiguration.GroupCipher.GCMP_256); requirePmf = true; break; @@ -508,7 +521,9 @@ public class WifiConfiguration implements Parcelable { allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP); allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X); allowedKeyManagement.set(WifiConfiguration.KeyMgmt.SUITE_B_192); + allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.GCMP_128); allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.GCMP_256); + allowedGroupCiphers.set(WifiConfiguration.GroupCipher.GCMP_128); allowedGroupCiphers.set(WifiConfiguration.GroupCipher.GCMP_256); allowedGroupManagementCiphers.set(WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256); // Note: allowedSuiteBCiphers bitset will be set by the service once the @@ -519,8 +534,10 @@ public class WifiConfiguration implements Parcelable { allowedProtocols.set(WifiConfiguration.Protocol.RSN); allowedKeyManagement.set(WifiConfiguration.KeyMgmt.OWE); allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP); + allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.GCMP_128); allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.GCMP_256); allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP); + allowedGroupCiphers.set(WifiConfiguration.GroupCipher.GCMP_128); allowedGroupCiphers.set(WifiConfiguration.GroupCipher.GCMP_256); requirePmf = true; break; @@ -596,6 +613,12 @@ public class WifiConfiguration implements Parcelable { public static final int AP_BAND_5GHZ = 1; /** + * 60GHz band + * @hide + */ + public static final int AP_BAND_60GHZ = 2; + + /** * Device is allowed to choose the optimal band (2Ghz or 5Ghz) based on device capability, * operating country code and current radio conditions. * @hide diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index b28b902910bf..c76f4a63a777 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -2407,6 +2407,8 @@ public class WifiManager { public static final long WIFI_FEATURE_OCE = 0x1000000000L; // OCE Support /** @hide */ public static final long WIFI_FEATURE_WAPI = 0x2000000000L; // WAPI + /** @hide */ + public static final long WIFI_FEATURE_INFRA_60G = 0x4000000000L; // 60 GHz Band Support /** @hide */ public static final long WIFI_FEATURE_FILS_SHA256 = 0x4000000000L; // FILS-SHA256 @@ -2569,6 +2571,21 @@ public class WifiManager { } /** + * Check if the chipset supports the 60GHz frequency band. + * + * @return {@code true} if supported, {@code false} otherwise. + * @hide + */ + @SystemApi + public boolean is60GHzBandSupported() { + try { + return mService.is60GHzBandSupported(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** * Check if the chipset supports 6GHz band. * @return {@code true} if supported, {@code false} otherwise. */ diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java index 94771ac4ad78..a68d7e260b6a 100644 --- a/wifi/java/android/net/wifi/WifiScanner.java +++ b/wifi/java/android/net/wifi/WifiScanner.java @@ -68,7 +68,9 @@ public class WifiScanner { /** @hide */ public static final int WIFI_BAND_INDEX_6_GHZ = 3; /** @hide */ - public static final int WIFI_BAND_COUNT = 4; + public static final int WIFI_BAND_INDEX_60_GHZ = 4; + /** @hide */ + public static final int WIFI_BAND_COUNT = 5; /** @hide */ @Retention(RetentionPolicy.SOURCE) @@ -76,7 +78,8 @@ public class WifiScanner { WIFI_BAND_INDEX_24_GHZ, WIFI_BAND_INDEX_5_GHZ, WIFI_BAND_INDEX_5_GHZ_DFS_ONLY, - WIFI_BAND_INDEX_6_GHZ}) + WIFI_BAND_INDEX_6_GHZ, + WIFI_BAND_INDEX_60_GHZ}) public @interface WifiBandIndex {} /** no band specified; use channel list instead */ @@ -89,6 +92,8 @@ public class WifiScanner { public static final int WIFI_BAND_5_GHZ_DFS_ONLY = 1 << WIFI_BAND_INDEX_5_GHZ_DFS_ONLY; /** 6 GHz band */ public static final int WIFI_BAND_6_GHZ = 1 << WIFI_BAND_INDEX_6_GHZ; + /** 60 GHz band */ + public static final int WIFI_BAND_60_GHZ = 1 << WIFI_BAND_INDEX_60_GHZ; /** * Combination of bands @@ -113,6 +118,12 @@ public class WifiScanner { /** 2.4 GHz band and 5 GHz band; with DFS channels and 6 GHz */ public static final int WIFI_BAND_24_5_WITH_DFS_6_GHZ = WIFI_BAND_BOTH_WITH_DFS | WIFI_BAND_6_GHZ; + /** @hide */ + public static final int WIFI_BAND_24_5_6_60_GHZ = + WIFI_BAND_24_5_6_GHZ | WIFI_BAND_60_GHZ; + /** @hide */ + public static final int WIFI_BAND_24_5_WITH_DFS_6_60_GHZ = + WIFI_BAND_24_5_6_60_GHZ | WIFI_BAND_5_GHZ_DFS_ONLY; /** @hide */ @Retention(RetentionPolicy.SOURCE) @@ -127,7 +138,10 @@ public class WifiScanner { WIFI_BAND_BOTH_WITH_DFS, WIFI_BAND_6_GHZ, WIFI_BAND_24_5_6_GHZ, - WIFI_BAND_24_5_WITH_DFS_6_GHZ}) + WIFI_BAND_24_5_WITH_DFS_6_GHZ, + WIFI_BAND_60_GHZ, + WIFI_BAND_24_5_6_60_GHZ, + WIFI_BAND_24_5_WITH_DFS_6_60_GHZ}) public @interface WifiBand {} /** @@ -179,7 +193,10 @@ public class WifiScanner { * @hide */ public static boolean isFullBandScan(@WifiBand int bandScanned, boolean excludeDfs) { - return (bandScanned | WIFI_BAND_6_GHZ | (excludeDfs ? WIFI_BAND_5_GHZ_DFS_ONLY : 0)) + // 5GHz DFS channel is part of 5GHz, mark 5GHz scanned as well. + if ((bandScanned & WIFI_BAND_5_GHZ_DFS_ONLY) != 0) bandScanned |= WIFI_BAND_5_GHZ; + return (bandScanned | WIFI_BAND_6_GHZ | WIFI_BAND_60_GHZ + | (excludeDfs ? WIFI_BAND_5_GHZ_DFS_ONLY : 0)) == WIFI_BAND_ALL; } @@ -571,6 +588,19 @@ public class WifiScanner { } } + /** {@hide} */ + public void addResults(@NonNull ScanData s) { + mBandScanned |= s.mBandScanned; + mFlags |= s.mFlags; + addResults(s.getResults()); + } + + /** {@hide} */ + public boolean isFullBandScanResults() { + return (mBandScanned & WifiScanner.WIFI_BAND_24_GHZ) != 0 + && (mBandScanned & WifiScanner.WIFI_BAND_5_GHZ) != 0; + } + /** Implement the Parcelable interface {@hide} */ public int describeContents() { return 0; diff --git a/wifi/java/android/net/wifi/aware/IWifiAwareManager.aidl b/wifi/java/android/net/wifi/aware/IWifiAwareManager.aidl index 88f95ad4d495..f5b1edce1d69 100644 --- a/wifi/java/android/net/wifi/aware/IWifiAwareManager.aidl +++ b/wifi/java/android/net/wifi/aware/IWifiAwareManager.aidl @@ -36,6 +36,7 @@ interface IWifiAwareManager // Aware API boolean isUsageEnabled(); Characteristics getCharacteristics(); + boolean isDeviceAttached(); // client API void connect(in IBinder binder, in String callingPackage, in String callingFeatureId, diff --git a/wifi/java/android/net/wifi/aware/WifiAwareManager.java b/wifi/java/android/net/wifi/aware/WifiAwareManager.java index 6352a2f4305c..d6e46fd52caf 100644 --- a/wifi/java/android/net/wifi/aware/WifiAwareManager.java +++ b/wifi/java/android/net/wifi/aware/WifiAwareManager.java @@ -179,6 +179,22 @@ public class WifiAwareManager { } /** + * Return the current status of the Aware service: whether ot not the device is already attached + * to an Aware cluster. To attach to an Aware cluster, please use + * {@link #attach(AttachCallback, Handler)} or + * {@link #attach(AttachCallback, IdentityChangedListener, Handler)}. + * @return A boolean indicating whether the device is attached to a cluster at this time (true) + * or not (false). + */ + public boolean isDeviceAttached() { + try { + return mService.isDeviceAttached(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** * Returns the characteristics of the Wi-Fi Aware interface: a set of parameters which specify * limitations on configurations, e.g. the maximum service name length. * diff --git a/wifi/java/android/net/wifi/nl80211/NativeScanResult.java b/wifi/java/android/net/wifi/nl80211/NativeScanResult.java index a8e999973fe8..35cf45fe36ed 100644 --- a/wifi/java/android/net/wifi/nl80211/NativeScanResult.java +++ b/wifi/java/android/net/wifi/nl80211/NativeScanResult.java @@ -225,6 +225,15 @@ public final class NativeScanResult implements Parcelable { * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): Immediate Block Ack. */ public static final int BSS_CAPABILITY_IMMEDIATE_BLOCK_ACK = 0x1 << 15; + /** + * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): DMG ESS. + * In DMG bits 0 and 1 are parsed together, where ESS=0x3 and IBSS=0x1 + */ + public static final int BSS_CAPABILITY_DMG_ESS = 0x3; + /** + * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): DMG IBSS. + */ + public static final int BSS_CAPABILITY_DMG_IBSS = 0x1; /** * Returns the capabilities of the AP repseresented by this scan result as advertised in the diff --git a/wifi/java/android/net/wifi/nl80211/WifiNl80211Manager.java b/wifi/java/android/net/wifi/nl80211/WifiNl80211Manager.java index 4116234c4c8d..3175e456693d 100644 --- a/wifi/java/android/net/wifi/nl80211/WifiNl80211Manager.java +++ b/wifi/java/android/net/wifi/nl80211/WifiNl80211Manager.java @@ -223,7 +223,11 @@ public class WifiNl80211Manager { /** * Callbacks for SoftAp interface registered using * {@link #registerApCallback(String, Executor, SoftApCallback)}. + * + * @deprecated The usage is replaced by vendor HAL + * {@code android.hardware.wifi.hostapd.V1_3.IHostapdCallback}. */ + @Deprecated public interface SoftApCallback { /** * Invoked when there is a fatal failure and the SoftAp is shutdown. @@ -1121,7 +1125,11 @@ public class WifiNl80211Manager { * @param callback Callback for AP events. * @return true on success, false on failure (e.g. when called on an interface which has not * been set up). + * + * @deprecated The usage is replaced by vendor HAL + * {@code android.hardware.wifi.hostapd.V1_3.IHostapdCallback}. */ + @Deprecated public boolean registerApCallback(@NonNull String ifaceName, @NonNull @CallbackExecutor Executor executor, @NonNull SoftApCallback callback) { diff --git a/wifi/java/android/net/wifi/util/SdkLevelUtil.java b/wifi/java/android/net/wifi/util/SdkLevelUtil.java index f29b0a6f3611..042634c7125c 100644 --- a/wifi/java/android/net/wifi/util/SdkLevelUtil.java +++ b/wifi/java/android/net/wifi/util/SdkLevelUtil.java @@ -30,8 +30,13 @@ public class SdkLevelUtil { /** This class is instantiable to allow easy mocking. */ public SdkLevelUtil() { } + /** See {@link #isAtLeastS()}. This version is non-static to allow easy mocking. */ + public boolean isAtLeastSMockable() { + return isAtLeastS(); + } + /** Returns true if the Android platform SDK is at least "S", false otherwise. */ - public boolean isAtLeastS() { + public static boolean isAtLeastS() { // TODO(b/167575586): after S SDK finalization, this method should just be // `return Build.VERSION.SDK_INT >= Build.VERSION_CODES.S;` diff --git a/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java b/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java index 3e5ee14be898..5fe0cb42073d 100644 --- a/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java +++ b/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java @@ -146,6 +146,15 @@ public class WifiAwareManagerTest { verify(mockAwareService).getCharacteristics(); } + /** + * Validate pass-through of isDeviceAttached() API. + */ + @Test + public void testIsAttached() throws Exception { + mDut.isDeviceAttached(); + verify(mockAwareService).isDeviceAttached(); + } + /* * WifiAwareEventCallbackProxy Tests */ |