summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.txt14
-rw-r--r--api/system-current.txt14
-rw-r--r--api/test-current.txt14
-rw-r--r--cmds/pm/src/com/android/commands/pm/Pm.java4
-rw-r--r--core/java/android/animation/AnimationHandler.java3
-rw-r--r--core/java/android/animation/ValueAnimator.java2
-rw-r--r--core/java/android/app/Activity.java1
-rw-r--r--core/java/android/app/ActivityManager.java12
-rw-r--r--core/java/android/app/ActivityOptions.java28
-rw-r--r--core/java/android/app/ApplicationPackageManager.java4
-rw-r--r--core/java/android/app/Notification.java16
-rw-r--r--core/java/android/app/TimePickerDialog.java5
-rw-r--r--core/java/android/app/job/JobInfo.java45
-rw-r--r--core/java/android/app/job/JobServiceEngine.java3
-rw-r--r--core/java/android/app/usage/IStorageStatsManager.aidl1
-rw-r--r--core/java/android/app/usage/StorageStatsManager.java18
-rw-r--r--core/java/android/content/pm/IPackageManager.aidl4
-rw-r--r--core/java/android/nfc/IAppCallback.aidl4
-rw-r--r--core/java/android/os/BatteryStats.java138
-rw-r--r--core/java/android/os/storage/StorageManager.java11
-rw-r--r--core/java/android/provider/ContactsContract.java19
-rwxr-xr-xcore/java/android/provider/Settings.java42
-rw-r--r--core/java/android/util/proto/ProtoOutputStream.java6
-rw-r--r--core/java/android/view/AppTransitionAnimationSpec.java15
-rw-r--r--core/java/android/view/IPinnedStackController.aidl8
-rw-r--r--core/java/android/view/IWindowManager.aidl5
-rw-r--r--core/java/android/view/SurfaceView.java58
-rw-r--r--core/java/android/view/ViewRootImpl.java22
-rw-r--r--core/java/android/view/WindowManagerInternal.java3
-rw-r--r--core/java/android/view/autofill/AutofillManager.java36
-rw-r--r--core/java/android/view/autofill/AutofillPopupWindow.java6
-rw-r--r--core/java/com/android/internal/app/IBatteryStats.aidl2
-rw-r--r--core/java/com/android/internal/os/BatteryStatsImpl.java1069
-rw-r--r--core/java/com/android/internal/util/DumpUtils.java2
-rw-r--r--core/jni/AndroidRuntime.cpp4
-rw-r--r--core/jni/android_hardware_Radio.cpp4
-rw-r--r--core/proto/android/providers/settings.proto6
-rw-r--r--core/res/res/values-ar/strings.xml2
-rw-r--r--core/res/res/values-bs/strings.xml12
-rw-r--r--core/res/res/values-ca/strings.xml2
-rw-r--r--core/res/res/values-ko/strings.xml4
-rw-r--r--core/res/res/values-ru/strings.xml2
-rw-r--r--core/res/res/values-th/strings.xml24
-rw-r--r--core/res/res/values/themes_device_defaults.xml8
-rw-r--r--core/tests/coretests/src/android/content/pm/AppCacheTest.java4
-rw-r--r--core/tests/coretests/src/android/provider/SettingsBackupTest.java6
-rw-r--r--core/tests/coretests/src/com/android/internal/app/procstats/SparseMappingTableTest.java4
-rw-r--r--core/tests/coretests/src/com/android/internal/os/BatteryStatsBackgroundStatsTest.java39
-rw-r--r--core/tests/coretests/src/com/android/internal/os/BatteryStatsCounterTest.java148
-rw-r--r--core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java16
-rw-r--r--core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java7
-rw-r--r--graphics/java/android/graphics/Paint.java9
-rw-r--r--graphics/java/android/graphics/Typeface.java6
-rw-r--r--libs/hwui/pipeline/skia/RenderNodeDrawable.cpp13
-rw-r--r--libs/hwui/renderthread/CanvasContext.cpp11
-rw-r--r--media/java/android/media/MediaCodec.java4
-rw-r--r--media/java/android/media/MediaSync.java2
-rw-r--r--packages/CaptivePortalLogin/res/layout/activity_captive_portal_login.xml42
-rw-r--r--packages/CaptivePortalLogin/res/values/styles.xml5
-rw-r--r--packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java58
-rw-r--r--packages/SettingsLib/res/layout/usage_view.xml7
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/applications/StorageStatsSource.java5
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/graph/BottomLabelLayout.java97
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/graph/BottomLabelLayoutTest.java70
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java16
-rw-r--r--packages/Shell/src/com/android/shell/BugreportProgressService.java9
-rw-r--r--packages/SystemUI/AndroidManifest.xml2
-rw-r--r--packages/SystemUI/res/drawable/ic_qs_signal_1x.xml27
-rw-r--r--packages/SystemUI/res/drawable/ic_qs_signal_3g.xml27
-rw-r--r--packages/SystemUI/res/drawable/ic_qs_signal_4g.xml27
-rw-r--r--packages/SystemUI/res/drawable/ic_qs_signal_4g_plus.xml30
-rw-r--r--packages/SystemUI/res/drawable/ic_qs_signal_disabled.xml28
-rw-r--r--packages/SystemUI/res/drawable/ic_qs_signal_e.xml27
-rw-r--r--packages/SystemUI/res/drawable/ic_qs_signal_g.xml26
-rw-r--r--packages/SystemUI/res/drawable/ic_qs_signal_h.xml27
-rw-r--r--packages/SystemUI/res/drawable/ic_qs_signal_lte.xml30
-rw-r--r--packages/SystemUI/res/drawable/ic_qs_signal_lte_plus.xml33
-rw-r--r--packages/SystemUI/res/layout/qs_footer.xml1
-rw-r--r--packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml9
-rw-r--r--packages/SystemUI/res/values-af/strings.xml2
-rw-r--r--packages/SystemUI/res/values-am/strings.xml2
-rw-r--r--packages/SystemUI/res/values-ar/strings.xml2
-rw-r--r--packages/SystemUI/res/values-az/strings.xml2
-rw-r--r--packages/SystemUI/res/values-b+sr+Latn/strings.xml2
-rw-r--r--packages/SystemUI/res/values-be/strings.xml2
-rw-r--r--packages/SystemUI/res/values-bg/strings.xml2
-rw-r--r--packages/SystemUI/res/values-bn/strings.xml2
-rw-r--r--packages/SystemUI/res/values-bs/strings.xml2
-rw-r--r--packages/SystemUI/res/values-ca/strings.xml2
-rw-r--r--packages/SystemUI/res/values-cs/strings.xml2
-rw-r--r--packages/SystemUI/res/values-da/strings.xml2
-rw-r--r--packages/SystemUI/res/values-de/strings.xml2
-rw-r--r--packages/SystemUI/res/values-el/strings.xml2
-rw-r--r--packages/SystemUI/res/values-en-rAU/strings.xml2
-rw-r--r--packages/SystemUI/res/values-en-rGB/strings.xml2
-rw-r--r--packages/SystemUI/res/values-en-rIN/strings.xml2
-rw-r--r--packages/SystemUI/res/values-es-rUS/strings.xml2
-rw-r--r--packages/SystemUI/res/values-es/strings.xml2
-rw-r--r--packages/SystemUI/res/values-et/strings.xml2
-rw-r--r--packages/SystemUI/res/values-eu/strings.xml2
-rw-r--r--packages/SystemUI/res/values-fa/strings.xml2
-rw-r--r--packages/SystemUI/res/values-fi/strings.xml2
-rw-r--r--packages/SystemUI/res/values-fr-rCA/strings.xml2
-rw-r--r--packages/SystemUI/res/values-fr/strings.xml2
-rw-r--r--packages/SystemUI/res/values-gl/strings.xml2
-rw-r--r--packages/SystemUI/res/values-gu/strings.xml2
-rw-r--r--packages/SystemUI/res/values-hi/strings.xml2
-rw-r--r--packages/SystemUI/res/values-hr/strings.xml2
-rw-r--r--packages/SystemUI/res/values-hu/strings.xml2
-rw-r--r--packages/SystemUI/res/values-hy/strings.xml2
-rw-r--r--packages/SystemUI/res/values-hy/strings_tv.xml2
-rw-r--r--packages/SystemUI/res/values-in/strings.xml2
-rw-r--r--packages/SystemUI/res/values-is/strings.xml2
-rw-r--r--packages/SystemUI/res/values-it/strings.xml2
-rw-r--r--packages/SystemUI/res/values-iw/strings.xml4
-rw-r--r--packages/SystemUI/res/values-ja/strings.xml2
-rw-r--r--packages/SystemUI/res/values-ka/strings.xml2
-rw-r--r--packages/SystemUI/res/values-kk/strings.xml2
-rw-r--r--packages/SystemUI/res/values-km/strings.xml2
-rw-r--r--packages/SystemUI/res/values-kn/strings.xml2
-rw-r--r--packages/SystemUI/res/values-ko/strings.xml2
-rw-r--r--packages/SystemUI/res/values-ky/strings.xml2
-rw-r--r--packages/SystemUI/res/values-lo/strings.xml2
-rw-r--r--packages/SystemUI/res/values-lt/strings.xml2
-rw-r--r--packages/SystemUI/res/values-lv/strings.xml2
-rw-r--r--packages/SystemUI/res/values-mk/strings.xml2
-rw-r--r--packages/SystemUI/res/values-ml/strings.xml2
-rw-r--r--packages/SystemUI/res/values-mn/strings.xml2
-rw-r--r--packages/SystemUI/res/values-mr/strings.xml2
-rw-r--r--packages/SystemUI/res/values-ms/strings.xml2
-rw-r--r--packages/SystemUI/res/values-my/strings.xml2
-rw-r--r--packages/SystemUI/res/values-nb/strings.xml2
-rw-r--r--packages/SystemUI/res/values-ne/strings.xml2
-rw-r--r--packages/SystemUI/res/values-nl/strings.xml2
-rw-r--r--packages/SystemUI/res/values-pa/strings.xml2
-rw-r--r--packages/SystemUI/res/values-pl/strings.xml2
-rw-r--r--packages/SystemUI/res/values-pt-rBR/strings.xml2
-rw-r--r--packages/SystemUI/res/values-pt-rPT/strings.xml26
-rw-r--r--packages/SystemUI/res/values-pt/strings.xml2
-rw-r--r--packages/SystemUI/res/values-ro/strings.xml2
-rw-r--r--packages/SystemUI/res/values-ru/strings.xml2
-rw-r--r--packages/SystemUI/res/values-si/strings.xml2
-rw-r--r--packages/SystemUI/res/values-sk/strings.xml2
-rw-r--r--packages/SystemUI/res/values-sl/strings.xml2
-rw-r--r--packages/SystemUI/res/values-sq/strings.xml2
-rw-r--r--packages/SystemUI/res/values-sr/strings.xml2
-rw-r--r--packages/SystemUI/res/values-sv/strings.xml2
-rw-r--r--packages/SystemUI/res/values-sw/strings.xml2
-rw-r--r--packages/SystemUI/res/values-ta/strings.xml2
-rw-r--r--packages/SystemUI/res/values-te/strings.xml2
-rw-r--r--packages/SystemUI/res/values-th/strings.xml14
-rw-r--r--packages/SystemUI/res/values-tl/strings.xml2
-rw-r--r--packages/SystemUI/res/values-tr/strings.xml2
-rw-r--r--packages/SystemUI/res/values-uk/strings.xml2
-rw-r--r--packages/SystemUI/res/values-ur/strings.xml2
-rw-r--r--packages/SystemUI/res/values-uz/strings.xml4
-rw-r--r--packages/SystemUI/res/values-vi/strings.xml2
-rw-r--r--packages/SystemUI/res/values-zh-rCN/strings.xml2
-rw-r--r--packages/SystemUI/res/values-zh-rHK/strings.xml2
-rw-r--r--packages/SystemUI/res/values-zh-rTW/strings.xml6
-rw-r--r--packages/SystemUI/res/values-zu/strings.xml2
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSFooter.java20
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSFragment.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java37
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java58
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/views/TaskViewAccessibilityDelegate.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java24
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java38
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java32
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java33
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/Utils.java31
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java15
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java85
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java22
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ZenModeControllerImplTest.java56
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationChildrenContainerTest.java8
-rw-r--r--services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java10
-rw-r--r--services/autofill/java/com/android/server/autofill/Session.java55
-rw-r--r--services/autofill/java/com/android/server/autofill/ViewState.java9
-rw-r--r--services/autofill/java/com/android/server/autofill/ui/FillUi.java3
-rw-r--r--services/core/java/com/android/server/EventLogTags.logtags10
-rw-r--r--services/core/java/com/android/server/StorageManagerService.java35
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java12
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerShellCommand.java4
-rw-r--r--services/core/java/com/android/server/am/ActivityRecord.java13
-rw-r--r--services/core/java/com/android/server/am/ActivityStack.java2
-rw-r--r--services/core/java/com/android/server/am/ActivityStackSupervisor.java4
-rw-r--r--services/core/java/com/android/server/am/ActivityStarter.java8
-rw-r--r--services/core/java/com/android/server/am/BatteryStatsService.java113
-rw-r--r--services/core/java/com/android/server/am/KeyguardController.java9
-rw-r--r--services/core/java/com/android/server/am/PinnedActivityStack.java4
-rw-r--r--services/core/java/com/android/server/am/ProcessStatsService.java3
-rw-r--r--services/core/java/com/android/server/am/ProviderMap.java62
-rw-r--r--services/core/java/com/android/server/am/TaskRecord.java8
-rw-r--r--services/core/java/com/android/server/notification/ManagedServices.java4
-rw-r--r--services/core/java/com/android/server/notification/NotificationManagerService.java10
-rw-r--r--services/core/java/com/android/server/pm/Installer.java5
-rw-r--r--services/core/java/com/android/server/pm/InstantAppRegistry.java221
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java138
-rw-r--r--services/core/java/com/android/server/policy/PhoneWindowManager.java18
-rw-r--r--services/core/java/com/android/server/policy/WindowOrientationListener.java58
-rw-r--r--services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java2
-rw-r--r--services/core/java/com/android/server/power/PowerManagerService.java5
-rw-r--r--services/core/java/com/android/server/storage/DeviceStorageMonitorService.java753
-rw-r--r--services/core/java/com/android/server/vr/VrManagerService.java3
-rw-r--r--services/core/java/com/android/server/wm/AppTransition.java21
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java7
-rw-r--r--services/core/java/com/android/server/wm/PinnedStackController.java40
-rw-r--r--services/core/java/com/android/server/wm/PinnedStackWindowController.java41
-rw-r--r--services/core/java/com/android/server/wm/RootWindowContainer.java10
-rw-r--r--services/core/java/com/android/server/wm/TaskSnapshotController.java20
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerDebugConfig.java2
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java37
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java30
-rw-r--r--services/core/java/com/android/server/wm/WindowStateAnimator.java1
-rw-r--r--services/core/java/com/android/server/wm/WindowSurfacePlacer.java15
-rw-r--r--services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java3
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java18
-rw-r--r--services/usage/java/com/android/server/usage/StorageStatsService.java43
-rw-r--r--telephony/java/android/telephony/PhoneNumberUtils.java5
-rw-r--r--tools/aapt2/Android.bp2
-rw-r--r--tools/aapt2/Format.proto1
-rw-r--r--tools/aapt2/ResourceParser.cpp10
-rw-r--r--tools/aapt2/ResourceParser_test.cpp4
-rw-r--r--tools/aapt2/ResourceTable.cpp16
-rw-r--r--tools/aapt2/ResourceTable.h7
-rw-r--r--tools/aapt2/ResourceUtils.cpp16
-rw-r--r--tools/aapt2/ResourceUtils.h3
-rw-r--r--tools/aapt2/ResourceValues.cpp183
-rw-r--r--tools/aapt2/ResourceValues.h32
-rw-r--r--tools/aapt2/ResourceValues_test.cpp32
-rw-r--r--tools/aapt2/cmd/Link.cpp3
-rw-r--r--tools/aapt2/link/TableMerger.cpp95
-rw-r--r--tools/aapt2/link/TableMerger_test.cpp103
-rw-r--r--tools/aapt2/proto/TableProtoDeserializer.cpp27
-rw-r--r--tools/aapt2/proto/TableProtoSerializer.cpp13
-rw-r--r--tools/aapt2/proto/TableProtoSerializer_test.cpp21
-rw-r--r--tools/aapt2/readme.md1
-rw-r--r--tools/aapt2/test/Builders.h6
-rw-r--r--tools/aapt2/test/Common.h63
-rw-r--r--tools/aapt2/test/Test.h1
-rw-r--r--tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java5
-rw-r--r--wifi/java/android/net/wifi/WifiManager.java70
-rw-r--r--wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java20
-rw-r--r--wifi/java/android/net/wifi/hotspot2/pps/Credential.java164
-rw-r--r--wifi/java/android/net/wifi/hotspot2/pps/HomeSp.java32
-rw-r--r--wifi/tests/src/android/net/wifi/WifiManagerTest.java9
263 files changed, 3832 insertions, 2323 deletions
diff --git a/api/current.txt b/api/current.txt
index 6023aabc1ca3..ac97b543fbdb 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -26513,7 +26513,6 @@ package android.net.wifi {
method public boolean isTdlsSupported();
method public boolean isWifiEnabled();
method public deprecated boolean pingSupplicant();
- method public void queryPasspointIcon(long, java.lang.String);
method public boolean reassociate();
method public boolean reconnect();
method public boolean removeNetwork(int);
@@ -26526,29 +26525,17 @@ package android.net.wifi {
method public boolean startScan();
method public void startWps(android.net.wifi.WpsInfo, android.net.wifi.WifiManager.WpsCallback);
method public int updateNetwork(android.net.wifi.WifiConfiguration);
- field public static final java.lang.String ACTION_PASSPOINT_DEAUTH_IMMINENT = "android.net.wifi.action.PASSPOINT_DEAUTH_IMMINENT";
- field public static final java.lang.String ACTION_PASSPOINT_ICON = "android.net.wifi.action.PASSPOINT_ICON";
- field public static final java.lang.String ACTION_PASSPOINT_OSU_PROVIDERS_LIST = "android.net.wifi.action.PASSPOINT_OSU_PROVIDERS_LIST";
- field public static final java.lang.String ACTION_PASSPOINT_SUBSCRIPTION_REMEDIATION = "android.net.wifi.action.PASSPOINT_SUBSCRIPTION_REMEDIATION";
field public static final java.lang.String ACTION_PICK_WIFI_NETWORK = "android.net.wifi.PICK_WIFI_NETWORK";
field public static final java.lang.String ACTION_REQUEST_SCAN_ALWAYS_AVAILABLE = "android.net.wifi.action.REQUEST_SCAN_ALWAYS_AVAILABLE";
field public static final int ERROR_AUTHENTICATING = 1; // 0x1
- field public static final java.lang.String EXTRA_ANQP_ELEMENT_DATA = "android.net.wifi.extra.ANQP_ELEMENT_DATA";
field public static final java.lang.String EXTRA_BSSID = "bssid";
- field public static final java.lang.String EXTRA_BSSID_LONG = "android.net.wifi.extra.BSSID_LONG";
- field public static final java.lang.String EXTRA_DELAY = "android.net.wifi.extra.DELAY";
- field public static final java.lang.String EXTRA_ESS = "android.net.wifi.extra.ESS";
- field public static final java.lang.String EXTRA_FILENAME = "android.net.wifi.extra.FILENAME";
- field public static final java.lang.String EXTRA_ICON = "android.net.wifi.extra.ICON";
field public static final java.lang.String EXTRA_NETWORK_INFO = "networkInfo";
field public static final java.lang.String EXTRA_NEW_RSSI = "newRssi";
field public static final java.lang.String EXTRA_NEW_STATE = "newState";
field public static final java.lang.String EXTRA_PREVIOUS_WIFI_STATE = "previous_wifi_state";
field public static final java.lang.String EXTRA_RESULTS_UPDATED = "resultsUpdated";
- field public static final java.lang.String EXTRA_SUBSCRIPTION_REMEDIATION_METHOD = "android.net.wifi.extra.SUBSCRIPTION_REMEDIATION_METHOD";
field public static final java.lang.String EXTRA_SUPPLICANT_CONNECTED = "connected";
field public static final java.lang.String EXTRA_SUPPLICANT_ERROR = "supplicantError";
- field public static final java.lang.String EXTRA_URL = "android.net.wifi.extra.URL";
field public static final java.lang.String EXTRA_WIFI_INFO = "wifiInfo";
field public static final java.lang.String EXTRA_WIFI_STATE = "wifi_state";
field public static final java.lang.String NETWORK_IDS_CHANGED_ACTION = "android.net.wifi.NETWORK_IDS_CHANGED";
@@ -33907,7 +33894,6 @@ package android.provider {
field public static final java.lang.String EXTRA_RECIPIENT_CONTACT_CHAT_ID = "android.provider.extra.RECIPIENT_CONTACT_CHAT_ID";
field public static final java.lang.String EXTRA_RECIPIENT_CONTACT_NAME = "android.provider.extra.RECIPIENT_CONTACT_NAME";
field public static final java.lang.String EXTRA_RECIPIENT_CONTACT_URI = "android.provider.extra.RECIPIENT_CONTACT_URI";
- field public static final java.lang.String EXTRA_SENDER_ACCOUNT_HASH = "android.provider.extra.SENDER_ACCOUNT_HASH";
field public static final java.lang.String INVITE_CONTACT = "com.android.contacts.action.INVITE_CONTACT";
field public static final java.lang.String METADATA_ACCOUNT_TYPE = "android.provider.account_type";
field public static final java.lang.String METADATA_MIMETYPE = "android.provider.mimetype";
diff --git a/api/system-current.txt b/api/system-current.txt
index 67b6e821a589..a2c2771b4844 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -29038,7 +29038,6 @@ package android.net.wifi {
method public boolean isWifiEnabled();
method public boolean isWifiScannerSupported();
method public deprecated boolean pingSupplicant();
- method public void queryPasspointIcon(long, java.lang.String);
method public boolean reassociate();
method public boolean reconnect();
method public boolean removeNetwork(int);
@@ -29055,10 +29054,6 @@ package android.net.wifi {
method public boolean startScan(android.os.WorkSource);
method public void startWps(android.net.wifi.WpsInfo, android.net.wifi.WifiManager.WpsCallback);
method public int updateNetwork(android.net.wifi.WifiConfiguration);
- field public static final java.lang.String ACTION_PASSPOINT_DEAUTH_IMMINENT = "android.net.wifi.action.PASSPOINT_DEAUTH_IMMINENT";
- field public static final java.lang.String ACTION_PASSPOINT_ICON = "android.net.wifi.action.PASSPOINT_ICON";
- field public static final java.lang.String ACTION_PASSPOINT_OSU_PROVIDERS_LIST = "android.net.wifi.action.PASSPOINT_OSU_PROVIDERS_LIST";
- field public static final java.lang.String ACTION_PASSPOINT_SUBSCRIPTION_REMEDIATION = "android.net.wifi.action.PASSPOINT_SUBSCRIPTION_REMEDIATION";
field public static final java.lang.String ACTION_PICK_WIFI_NETWORK = "android.net.wifi.PICK_WIFI_NETWORK";
field public static final java.lang.String ACTION_REQUEST_SCAN_ALWAYS_AVAILABLE = "android.net.wifi.action.REQUEST_SCAN_ALWAYS_AVAILABLE";
field public static final int CHANGE_REASON_ADDED = 0; // 0x0
@@ -29066,14 +29061,8 @@ package android.net.wifi {
field public static final int CHANGE_REASON_REMOVED = 1; // 0x1
field public static final java.lang.String CONFIGURED_NETWORKS_CHANGED_ACTION = "android.net.wifi.CONFIGURED_NETWORKS_CHANGE";
field public static final int ERROR_AUTHENTICATING = 1; // 0x1
- field public static final java.lang.String EXTRA_ANQP_ELEMENT_DATA = "android.net.wifi.extra.ANQP_ELEMENT_DATA";
field public static final java.lang.String EXTRA_BSSID = "bssid";
- field public static final java.lang.String EXTRA_BSSID_LONG = "android.net.wifi.extra.BSSID_LONG";
field public static final java.lang.String EXTRA_CHANGE_REASON = "changeReason";
- field public static final java.lang.String EXTRA_DELAY = "android.net.wifi.extra.DELAY";
- field public static final java.lang.String EXTRA_ESS = "android.net.wifi.extra.ESS";
- field public static final java.lang.String EXTRA_FILENAME = "android.net.wifi.extra.FILENAME";
- field public static final java.lang.String EXTRA_ICON = "android.net.wifi.extra.ICON";
field public static final java.lang.String EXTRA_MULTIPLE_NETWORKS_CHANGED = "multipleChanges";
field public static final java.lang.String EXTRA_NETWORK_INFO = "networkInfo";
field public static final java.lang.String EXTRA_NEW_RSSI = "newRssi";
@@ -29081,10 +29070,8 @@ package android.net.wifi {
field public static final java.lang.String EXTRA_PREVIOUS_WIFI_AP_STATE = "previous_wifi_state";
field public static final java.lang.String EXTRA_PREVIOUS_WIFI_STATE = "previous_wifi_state";
field public static final java.lang.String EXTRA_RESULTS_UPDATED = "resultsUpdated";
- field public static final java.lang.String EXTRA_SUBSCRIPTION_REMEDIATION_METHOD = "android.net.wifi.extra.SUBSCRIPTION_REMEDIATION_METHOD";
field public static final java.lang.String EXTRA_SUPPLICANT_CONNECTED = "connected";
field public static final java.lang.String EXTRA_SUPPLICANT_ERROR = "supplicantError";
- field public static final java.lang.String EXTRA_URL = "android.net.wifi.extra.URL";
field public static final java.lang.String EXTRA_WIFI_AP_STATE = "wifi_state";
field public static final java.lang.String EXTRA_WIFI_CONFIGURATION = "wifiConfiguration";
field public static final java.lang.String EXTRA_WIFI_CREDENTIAL_EVENT_TYPE = "et";
@@ -36821,7 +36808,6 @@ package android.provider {
field public static final java.lang.String EXTRA_RECIPIENT_CONTACT_CHAT_ID = "android.provider.extra.RECIPIENT_CONTACT_CHAT_ID";
field public static final java.lang.String EXTRA_RECIPIENT_CONTACT_NAME = "android.provider.extra.RECIPIENT_CONTACT_NAME";
field public static final java.lang.String EXTRA_RECIPIENT_CONTACT_URI = "android.provider.extra.RECIPIENT_CONTACT_URI";
- field public static final java.lang.String EXTRA_SENDER_ACCOUNT_HASH = "android.provider.extra.SENDER_ACCOUNT_HASH";
field public static final java.lang.String INVITE_CONTACT = "com.android.contacts.action.INVITE_CONTACT";
field public static final java.lang.String METADATA_ACCOUNT_TYPE = "android.provider.account_type";
field public static final java.lang.String METADATA_MIMETYPE = "android.provider.mimetype";
diff --git a/api/test-current.txt b/api/test-current.txt
index cf119d112010..1cad48ead7de 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -26622,7 +26622,6 @@ package android.net.wifi {
method public boolean isTdlsSupported();
method public boolean isWifiEnabled();
method public deprecated boolean pingSupplicant();
- method public void queryPasspointIcon(long, java.lang.String);
method public boolean reassociate();
method public boolean reconnect();
method public boolean removeNetwork(int);
@@ -26635,29 +26634,17 @@ package android.net.wifi {
method public boolean startScan();
method public void startWps(android.net.wifi.WpsInfo, android.net.wifi.WifiManager.WpsCallback);
method public int updateNetwork(android.net.wifi.WifiConfiguration);
- field public static final java.lang.String ACTION_PASSPOINT_DEAUTH_IMMINENT = "android.net.wifi.action.PASSPOINT_DEAUTH_IMMINENT";
- field public static final java.lang.String ACTION_PASSPOINT_ICON = "android.net.wifi.action.PASSPOINT_ICON";
- field public static final java.lang.String ACTION_PASSPOINT_OSU_PROVIDERS_LIST = "android.net.wifi.action.PASSPOINT_OSU_PROVIDERS_LIST";
- field public static final java.lang.String ACTION_PASSPOINT_SUBSCRIPTION_REMEDIATION = "android.net.wifi.action.PASSPOINT_SUBSCRIPTION_REMEDIATION";
field public static final java.lang.String ACTION_PICK_WIFI_NETWORK = "android.net.wifi.PICK_WIFI_NETWORK";
field public static final java.lang.String ACTION_REQUEST_SCAN_ALWAYS_AVAILABLE = "android.net.wifi.action.REQUEST_SCAN_ALWAYS_AVAILABLE";
field public static final int ERROR_AUTHENTICATING = 1; // 0x1
- field public static final java.lang.String EXTRA_ANQP_ELEMENT_DATA = "android.net.wifi.extra.ANQP_ELEMENT_DATA";
field public static final java.lang.String EXTRA_BSSID = "bssid";
- field public static final java.lang.String EXTRA_BSSID_LONG = "android.net.wifi.extra.BSSID_LONG";
- field public static final java.lang.String EXTRA_DELAY = "android.net.wifi.extra.DELAY";
- field public static final java.lang.String EXTRA_ESS = "android.net.wifi.extra.ESS";
- field public static final java.lang.String EXTRA_FILENAME = "android.net.wifi.extra.FILENAME";
- field public static final java.lang.String EXTRA_ICON = "android.net.wifi.extra.ICON";
field public static final java.lang.String EXTRA_NETWORK_INFO = "networkInfo";
field public static final java.lang.String EXTRA_NEW_RSSI = "newRssi";
field public static final java.lang.String EXTRA_NEW_STATE = "newState";
field public static final java.lang.String EXTRA_PREVIOUS_WIFI_STATE = "previous_wifi_state";
field public static final java.lang.String EXTRA_RESULTS_UPDATED = "resultsUpdated";
- field public static final java.lang.String EXTRA_SUBSCRIPTION_REMEDIATION_METHOD = "android.net.wifi.extra.SUBSCRIPTION_REMEDIATION_METHOD";
field public static final java.lang.String EXTRA_SUPPLICANT_CONNECTED = "connected";
field public static final java.lang.String EXTRA_SUPPLICANT_ERROR = "supplicantError";
- field public static final java.lang.String EXTRA_URL = "android.net.wifi.extra.URL";
field public static final java.lang.String EXTRA_WIFI_INFO = "wifiInfo";
field public static final java.lang.String EXTRA_WIFI_STATE = "wifi_state";
field public static final java.lang.String NETWORK_IDS_CHANGED_ACTION = "android.net.wifi.NETWORK_IDS_CHANGED";
@@ -34044,7 +34031,6 @@ package android.provider {
field public static final java.lang.String EXTRA_RECIPIENT_CONTACT_CHAT_ID = "android.provider.extra.RECIPIENT_CONTACT_CHAT_ID";
field public static final java.lang.String EXTRA_RECIPIENT_CONTACT_NAME = "android.provider.extra.RECIPIENT_CONTACT_NAME";
field public static final java.lang.String EXTRA_RECIPIENT_CONTACT_URI = "android.provider.extra.RECIPIENT_CONTACT_URI";
- field public static final java.lang.String EXTRA_SENDER_ACCOUNT_HASH = "android.provider.extra.SENDER_ACCOUNT_HASH";
field public static final java.lang.String INVITE_CONTACT = "com.android.contacts.action.INVITE_CONTACT";
field public static final java.lang.String METADATA_ACCOUNT_TYPE = "android.provider.account_type";
field public static final java.lang.String METADATA_MIMETYPE = "android.provider.mimetype";
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index b60aed68ba1c..d71573f7ca50 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -63,6 +63,7 @@ import android.os.ShellCallback;
import android.os.SystemClock;
import android.os.UserHandle;
import android.os.UserManager;
+import android.os.storage.StorageManager;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.util.Log;
@@ -1471,7 +1472,8 @@ public final class Pm {
}
ClearDataObserver obs = new ClearDataObserver();
try {
- mPm.freeStorageAndNotify(volumeUuid, sizeVal, obs);
+ mPm.freeStorageAndNotify(volumeUuid, sizeVal,
+ StorageManager.FLAG_ALLOCATE_DEFY_RESERVED, obs);
synchronized (obs) {
while (!obs.finished) {
try {
diff --git a/core/java/android/animation/AnimationHandler.java b/core/java/android/animation/AnimationHandler.java
index e2e5a8f66288..260323fe2d10 100644
--- a/core/java/android/animation/AnimationHandler.java
+++ b/core/java/android/animation/AnimationHandler.java
@@ -136,7 +136,8 @@ public class AnimationHandler {
private void doAnimationFrame(long frameTime) {
long currentTime = SystemClock.uptimeMillis();
- for (int i = 0; i < mAnimationCallbacks.size(); i++) {
+ final int size = mAnimationCallbacks.size();
+ for (int i = 0; i < size; i++) {
final AnimationFrameCallback callback = mAnimationCallbacks.get(i);
if (callback == null) {
continue;
diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java
index 4e31e44d6e75..e686a89accef 100644
--- a/core/java/android/animation/ValueAnimator.java
+++ b/core/java/android/animation/ValueAnimator.java
@@ -1397,7 +1397,7 @@ public class ValueAnimator extends Animator implements AnimationHandler.Animatio
if (mStartTime < 0) {
// First frame. If there is start delay, start delay count down will happen *after* this
// frame.
- mStartTime = mReversing ? frameTime : frameTime + mStartDelay;
+ mStartTime = mReversing ? frameTime : frameTime + (long) (mStartDelay * sDurationScale);
}
// Handle pause/resume
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index b439c1dc02c4..b360c82374d0 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -6142,6 +6142,7 @@ public class Activity extends ContextThemeWrapper
*
* @param action the action to run on the UI thread
*/
+ @Override
public final void runOnUiThread(Runnable action) {
if (Thread.currentThread() != mUiThread) {
mHandler.post(action);
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 09252175a1db..7e230a3d9ea4 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -1139,8 +1139,12 @@ public class ActivityManager {
* E.g. freeform, split-screen, picture-in-picture.
* @hide
*/
- static public boolean supportsMultiWindow() {
- return !isLowRamDeviceStatic()
+ static public boolean supportsMultiWindow(Context context) {
+ // On watches, multi-window is used to present essential system UI, and thus it must be
+ // supported regardless of device memory characteristics.
+ boolean isWatch = context.getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_WATCH);
+ return (!isLowRamDeviceStatic() || isWatch)
&& Resources.getSystem().getBoolean(
com.android.internal.R.bool.config_supportsMultiWindow);
}
@@ -1149,8 +1153,8 @@ public class ActivityManager {
* Returns true if the system supports split screen multi-window.
* @hide
*/
- static public boolean supportsSplitScreenMultiWindow() {
- return supportsMultiWindow()
+ static public boolean supportsSplitScreenMultiWindow(Context context) {
+ return supportsMultiWindow(context)
&& Resources.getSystem().getBoolean(
com.android.internal.R.bool.config_supportsSplitScreenMultiWindow);
}
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index 53608fbdd4bb..c4d51168d20c 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -25,6 +25,8 @@ import android.annotation.TestApi;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
+import android.graphics.Bitmap.Config;
+import android.graphics.GraphicBuffer;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.Handler;
@@ -826,7 +828,11 @@ public class ActivityOptions {
case ANIM_THUMBNAIL_SCALE_DOWN:
case ANIM_THUMBNAIL_ASPECT_SCALE_UP:
case ANIM_THUMBNAIL_ASPECT_SCALE_DOWN:
- mThumbnail = (Bitmap) opts.getParcelable(KEY_ANIM_THUMBNAIL);
+ // Unpackage the GraphicBuffer from the parceled thumbnail
+ final GraphicBuffer buffer = opts.getParcelable(KEY_ANIM_THUMBNAIL);
+ if (buffer != null) {
+ mThumbnail = Bitmap.createHardwareBitmap(buffer);
+ }
mStartX = opts.getInt(KEY_ANIM_START_X, 0);
mStartY = opts.getInt(KEY_ANIM_START_Y, 0);
mWidth = opts.getInt(KEY_ANIM_WIDTH, 0);
@@ -919,9 +925,14 @@ public class ActivityOptions {
return mCustomInPlaceResId;
}
- /** @hide */
- public Bitmap getThumbnail() {
- return mThumbnail;
+ /**
+ * The thumbnail is copied into a hardware bitmap when it is bundled and sent to the system, so
+ * it should always be backed by a GraphicBuffer on the other end.
+ *
+ * @hide
+ */
+ public GraphicBuffer getThumbnail() {
+ return mThumbnail.createGraphicBufferHandle();
}
/** @hide */
@@ -1230,7 +1241,14 @@ public class ActivityOptions {
case ANIM_THUMBNAIL_SCALE_DOWN:
case ANIM_THUMBNAIL_ASPECT_SCALE_UP:
case ANIM_THUMBNAIL_ASPECT_SCALE_DOWN:
- b.putParcelable(KEY_ANIM_THUMBNAIL, mThumbnail);
+ // Once we parcel the thumbnail for transfering over to the system, create a copy of
+ // the bitmap to a hardware bitmap and pass through the GraphicBuffer
+ if (mThumbnail == null) {
+ b.putParcelable(KEY_ANIM_THUMBNAIL, null);
+ } else {
+ final Bitmap hwBitmap = mThumbnail.copy(Config.HARDWARE, true /* immutable */);
+ b.putParcelable(KEY_ANIM_THUMBNAIL, hwBitmap.createGraphicBufferHandle());
+ }
b.putInt(KEY_ANIM_START_X, mStartX);
b.putInt(KEY_ANIM_START_Y, mStartY);
b.putInt(KEY_ANIM_WIDTH, mWidth);
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 525b15113855..e5c420876c8a 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -2108,7 +2108,7 @@ public class ApplicationPackageManager extends PackageManager {
public void freeStorageAndNotify(String volumeUuid, long idealStorageSize,
IPackageDataObserver observer) {
try {
- mPM.freeStorageAndNotify(volumeUuid, idealStorageSize, observer);
+ mPM.freeStorageAndNotify(volumeUuid, idealStorageSize, 0, observer);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -2117,7 +2117,7 @@ public class ApplicationPackageManager extends PackageManager {
@Override
public void freeStorage(String volumeUuid, long freeStorageSize, IntentSender pi) {
try {
- mPM.freeStorage(volumeUuid, freeStorageSize, pi);
+ mPM.freeStorage(volumeUuid, freeStorageSize, 0, pi);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 3ed174b2d46f..31f52dbea548 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -1168,7 +1168,7 @@ public class Notification implements Parcelable
*/
public static final int GROUP_ALERT_CHILDREN = 2;
- private int mGroupAlertBehavior = GROUP_ALERT_ALL;
+ private int mGroupAlertBehavior = GROUP_ALERT_CHILDREN;
/**
* If this notification is being shown as a badge, always show as a number.
@@ -2640,6 +2640,20 @@ public class Notification implements Parcelable
}
/**
+ * @hide
+ */
+ public boolean suppressAlertingDueToGrouping() {
+ if (isGroupSummary()
+ && getGroupAlertBehavior() == Notification.GROUP_ALERT_CHILDREN) {
+ return true;
+ } else if (isGroupChild()
+ && getGroupAlertBehavior() == Notification.GROUP_ALERT_SUMMARY) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
* Builder class for {@link Notification} objects.
*
* Provides a convenient way to set the various fields of a {@link Notification} and generate
diff --git a/core/java/android/app/TimePickerDialog.java b/core/java/android/app/TimePickerDialog.java
index 8a4f8a626c71..0f006b6618b3 100644
--- a/core/java/android/app/TimePickerDialog.java
+++ b/core/java/android/app/TimePickerDialog.java
@@ -151,10 +151,7 @@ public class TimePickerDialog extends AlertDialog implements OnClickListener,
@Override
public void onClick(View view) {
if (mTimePicker.validateInput()) {
- if (mTimeSetListener != null) {
- mTimeSetListener.onTimeSet(mTimePicker, mTimePicker.getCurrentHour(),
- mTimePicker.getCurrentMinute());
- }
+ TimePickerDialog.this.onClick(TimePickerDialog.this, BUTTON_POSITIVE);
dismiss();
}
}
diff --git a/core/java/android/app/job/JobInfo.java b/core/java/android/app/job/JobInfo.java
index 3cb59f27bfaf..87e516cabba5 100644
--- a/core/java/android/app/job/JobInfo.java
+++ b/core/java/android/app/job/JobInfo.java
@@ -35,6 +35,7 @@ import android.util.Log;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Objects;
/**
@@ -501,7 +502,7 @@ public class JobInfo implements Parcelable {
if (constraintFlags != j.constraintFlags) {
return false;
}
- if (!Objects.deepEquals(triggerContentUris, j.triggerContentUris)) {
+ if (!Arrays.equals(triggerContentUris, j.triggerContentUris)) {
return false;
}
if (triggerContentUpdateDelay != j.triggerContentUpdateDelay) {
@@ -556,37 +557,37 @@ public class JobInfo implements Parcelable {
public int hashCode() {
int hashCode = jobId;
if (extras != null) {
- hashCode = 31*hashCode + extras.hashCode();
+ hashCode = 31 * hashCode + extras.hashCode();
}
if (transientExtras != null) {
- hashCode = 31*hashCode + transientExtras.hashCode();
+ hashCode = 31 * hashCode + transientExtras.hashCode();
}
if (clipData != null) {
- hashCode = 31*hashCode + clipData.hashCode();
+ hashCode = 31 * hashCode + clipData.hashCode();
}
hashCode = 31*hashCode + clipGrantFlags;
if (service != null) {
- hashCode = 31*hashCode + service.hashCode();
+ hashCode = 31 * hashCode + service.hashCode();
}
- hashCode = 31*hashCode + constraintFlags;
+ hashCode = 31 * hashCode + constraintFlags;
if (triggerContentUris != null) {
- hashCode = 31*hashCode + triggerContentUris.hashCode();
+ hashCode = 31 * hashCode + Arrays.hashCode(triggerContentUris);
}
- hashCode = 31*hashCode + Long.hashCode(triggerContentUpdateDelay);
- hashCode = 31*hashCode + Long.hashCode(triggerContentMaxDelay);
- hashCode = 31*hashCode + Boolean.hashCode(hasEarlyConstraint);
- hashCode = 31*hashCode + Boolean.hashCode(hasLateConstraint);
- hashCode = 31*hashCode + networkType;
- hashCode = 31*hashCode + Long.hashCode(minLatencyMillis);
- hashCode = 31*hashCode + Long.hashCode(maxExecutionDelayMillis);
- hashCode = 31*hashCode + Boolean.hashCode(isPeriodic);
- hashCode = 31*hashCode + Boolean.hashCode(isPersisted);
- hashCode = 31*hashCode + Long.hashCode(intervalMillis);
- hashCode = 31*hashCode + Long.hashCode(flexMillis);
- hashCode = 31*hashCode + Long.hashCode(initialBackoffMillis);
- hashCode = 31*hashCode + backoffPolicy;
- hashCode = 31*hashCode + priority;
- hashCode = 31*hashCode + flags;
+ hashCode = 31 * hashCode + Long.hashCode(triggerContentUpdateDelay);
+ hashCode = 31 * hashCode + Long.hashCode(triggerContentMaxDelay);
+ hashCode = 31 * hashCode + Boolean.hashCode(hasEarlyConstraint);
+ hashCode = 31 * hashCode + Boolean.hashCode(hasLateConstraint);
+ hashCode = 31 * hashCode + networkType;
+ hashCode = 31 * hashCode + Long.hashCode(minLatencyMillis);
+ hashCode = 31 * hashCode + Long.hashCode(maxExecutionDelayMillis);
+ hashCode = 31 * hashCode + Boolean.hashCode(isPeriodic);
+ hashCode = 31 * hashCode + Boolean.hashCode(isPersisted);
+ hashCode = 31 * hashCode + Long.hashCode(intervalMillis);
+ hashCode = 31 * hashCode + Long.hashCode(flexMillis);
+ hashCode = 31 * hashCode + Long.hashCode(initialBackoffMillis);
+ hashCode = 31 * hashCode + backoffPolicy;
+ hashCode = 31 * hashCode + priority;
+ hashCode = 31 * hashCode + flags;
return hashCode;
}
diff --git a/core/java/android/app/job/JobServiceEngine.java b/core/java/android/app/job/JobServiceEngine.java
index b0ec6502c4b1..ab94da843635 100644
--- a/core/java/android/app/job/JobServiceEngine.java
+++ b/core/java/android/app/job/JobServiceEngine.java
@@ -210,6 +210,9 @@ public abstract class JobServiceEngine {
* information.
*/
public void jobFinished(JobParameters params, boolean needsReschedule) {
+ if (params == null) {
+ throw new NullPointerException("params");
+ }
Message m = Message.obtain(mHandler, MSG_JOB_FINISHED, params);
m.arg2 = needsReschedule ? 1 : 0;
m.sendToTarget();
diff --git a/core/java/android/app/usage/IStorageStatsManager.aidl b/core/java/android/app/usage/IStorageStatsManager.aidl
index 5d1550f1a557..15e5ea5f44ff 100644
--- a/core/java/android/app/usage/IStorageStatsManager.aidl
+++ b/core/java/android/app/usage/IStorageStatsManager.aidl
@@ -24,6 +24,7 @@ interface IStorageStatsManager {
boolean isQuotaSupported(String volumeUuid, String callingPackage);
long getTotalBytes(String volumeUuid, String callingPackage);
long getFreeBytes(String volumeUuid, String callingPackage);
+ long getCacheBytes(String volumeUuid, String callingPackage);
long getCacheQuotaBytes(String volumeUuid, int uid, String callingPackage);
StorageStats queryStatsForPackage(String volumeUuid, String packageName, int userId, String callingPackage);
StorageStats queryStatsForUid(String volumeUuid, int uid, String callingPackage);
diff --git a/core/java/android/app/usage/StorageStatsManager.java b/core/java/android/app/usage/StorageStatsManager.java
index d9d958c0653c..0b2b1900c4e0 100644
--- a/core/java/android/app/usage/StorageStatsManager.java
+++ b/core/java/android/app/usage/StorageStatsManager.java
@@ -142,6 +142,24 @@ public class StorageStatsManager {
return getFreeBytes(convert(uuid));
}
+ /** {@hide} */
+ public @BytesLong long getCacheBytes(@NonNull UUID storageUuid) throws IOException {
+ try {
+ return mService.getCacheBytes(convert(storageUuid), mContext.getOpPackageName());
+ } catch (ParcelableException e) {
+ e.maybeRethrow(IOException.class);
+ throw new RuntimeException(e);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /** {@hide} */
+ @Deprecated
+ public long getCacheBytes(String uuid) throws IOException {
+ return getCacheBytes(convert(uuid));
+ }
+
/**
* Return storage statistics for a specific package on the requested storage
* volume.
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 7aaf453e404d..2ebfa8fb3ac2 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -360,7 +360,7 @@ interface IPackageManager {
* the operation is completed
*/
void freeStorageAndNotify(in String volumeUuid, in long freeStorageSize,
- IPackageDataObserver observer);
+ int storageFlags, IPackageDataObserver observer);
/**
* Free storage by deleting LRU sorted list of cache files across
@@ -384,7 +384,7 @@ interface IPackageManager {
* to indicate that no call back is desired.
*/
void freeStorage(in String volumeUuid, in long freeStorageSize,
- in IntentSender pi);
+ int storageFlags, in IntentSender pi);
/**
* Delete all the cache files in an applications cache directory
diff --git a/core/java/android/nfc/IAppCallback.aidl b/core/java/android/nfc/IAppCallback.aidl
index c027d54647bd..133146de2aa1 100644
--- a/core/java/android/nfc/IAppCallback.aidl
+++ b/core/java/android/nfc/IAppCallback.aidl
@@ -25,6 +25,6 @@ import android.nfc.Tag;
interface IAppCallback
{
BeamShareData createBeamShareData(byte peerLlcpVersion);
- void onNdefPushComplete(byte peerLlcpVersion);
- void onTagDiscovered(in Tag tag);
+ oneway void onNdefPushComplete(byte peerLlcpVersion);
+ oneway void onTagDiscovered(in Tag tag);
}
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 499d6bbdf535..ecc4dec47af7 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -162,6 +162,11 @@ public abstract class BatteryStats implements Parcelable {
public static final int AGGREGATED_WAKE_TYPE_PARTIAL = 20;
/**
+ * A constant indicating a bluetooth scan timer for unoptimized scans.
+ */
+ public static final int BLUETOOTH_UNOPTIMIZED_SCAN_ON = 21;
+
+ /**
* Include all of the data in the stats, including previously saved data.
*/
public static final int STATS_SINCE_CHARGED = 0;
@@ -191,8 +196,12 @@ public abstract class BatteryStats implements Parcelable {
* New in version 21:
* - Actual (not just apportioned) Wakelock time is also recorded.
* - Aggregated partial wakelock time (per uid, instead of per wakelock) is recorded.
+ * - BLE scan result count
+ * - CPU frequency time per uid
+ * New in version 22:
+ * - BLE scan result background count, BLE unoptimized scan time
*/
- static final String CHECKIN_VERSION = "21";
+ static final String CHECKIN_VERSION = "22";
/**
* Old version, we hit 9 and ran out of room, need to remove.
@@ -217,9 +226,10 @@ public abstract class BatteryStats implements Parcelable {
private static final String STATE_TIME_DATA = "st";
// wl line is:
// BATTERY_STATS_CHECKIN_VERSION, uid, which, "wl", name,
- // full totalTime, 'f', count, current duration, max duration, total duration,
- // partial totalTime, 'p', count, current duration, max duration, total duration,
- // window totalTime, 'w', count, current duration, max duration, total duration
+ // full totalTime, 'f', count, current duration, max duration, total duration,
+ // partial totalTime, 'p', count, current duration, max duration, total duration,
+ // bg partial totalTime, 'bp', count, current duration, max duration, total duration,
+ // window totalTime, 'w', count, current duration, max duration, total duration
// [Currently, full and window wakelocks have durations current = max = total = -1]
private static final String WAKELOCK_DATA = "wl";
// awl line is:
@@ -565,7 +575,10 @@ public abstract class BatteryStats implements Parcelable {
public abstract Timer getForegroundActivityTimer();
public abstract Timer getBluetoothScanTimer();
public abstract Timer getBluetoothScanBackgroundTimer();
+ public abstract Timer getBluetoothUnoptimizedScanTimer();
+ public abstract Timer getBluetoothUnoptimizedScanBackgroundTimer();
public abstract Counter getBluetoothScanResultCounter();
+ public abstract Counter getBluetoothScanResultBgCounter();
public abstract long[] getCpuFreqTimes(int which);
public abstract long[] getScreenOffCpuFreqTimes(int which);
@@ -3429,10 +3442,29 @@ public abstract class BatteryStats implements Parcelable {
final long actualTime = bleTimer.getTotalDurationMsLocked(rawRealtimeMs);
final long actualTimeBg = bleTimerBg != null ?
bleTimerBg.getTotalDurationMsLocked(rawRealtimeMs) : 0;
+ // Result counters
final int resultCount = u.getBluetoothScanResultCounter() != null ?
u.getBluetoothScanResultCounter().getCountLocked(which) : 0;
+ final int resultCountBg = u.getBluetoothScanResultBgCounter() != null ?
+ u.getBluetoothScanResultBgCounter().getCountLocked(which) : 0;
+ // Unoptimized scan timer. Unpooled and since reset (regardless of 'which').
+ final Timer unoptimizedScanTimer = u.getBluetoothUnoptimizedScanTimer();
+ final long unoptimizedScanTotalTime = unoptimizedScanTimer != null ?
+ unoptimizedScanTimer.getTotalDurationMsLocked(rawRealtimeMs) : 0;
+ final long unoptimizedScanMaxTime = unoptimizedScanTimer != null ?
+ unoptimizedScanTimer.getMaxDurationMsLocked(rawRealtimeMs) : 0;
+ // Unoptimized bg scan timer. Unpooled and since reset (regardless of 'which').
+ final Timer unoptimizedScanTimerBg =
+ u.getBluetoothUnoptimizedScanBackgroundTimer();
+ final long unoptimizedScanTotalTimeBg = unoptimizedScanTimerBg != null ?
+ unoptimizedScanTimerBg.getTotalDurationMsLocked(rawRealtimeMs) : 0;
+ final long unoptimizedScanMaxTimeBg = unoptimizedScanTimerBg != null ?
+ unoptimizedScanTimerBg.getMaxDurationMsLocked(rawRealtimeMs) : 0;
+
dumpLine(pw, uid, category, BLUETOOTH_MISC_DATA, totalTime, count,
- countBg, actualTime, actualTimeBg, resultCount);
+ countBg, actualTime, actualTimeBg, resultCount, resultCountBg,
+ unoptimizedScanTotalTime, unoptimizedScanTotalTimeBg,
+ unoptimizedScanMaxTime, unoptimizedScanMaxTimeBg);
}
}
@@ -3469,8 +3501,11 @@ public abstract class BatteryStats implements Parcelable {
sb.setLength(0);
linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_FULL),
rawRealtime, "f", which, linePrefix);
- linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL),
+ final Timer pTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
+ linePrefix = printWakeLockCheckin(sb, pTimer,
rawRealtime, "p", which, linePrefix);
+ linePrefix = printWakeLockCheckin(sb, pTimer != null ? pTimer.getSubTimer() : null,
+ rawRealtime, "bp", which, linePrefix);
linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_WINDOW),
rawRealtime, "w", which, linePrefix);
@@ -4625,34 +4660,94 @@ public abstract class BatteryStats implements Parcelable {
final long actualTimeMs = bleTimer.getTotalDurationMsLocked(rawRealtimeMs);
final long actualTimeMsBg = bleTimerBg != null ?
bleTimerBg.getTotalDurationMsLocked(rawRealtimeMs) : 0;
+ // Result counters
final int resultCount = u.getBluetoothScanResultCounter() != null ?
u.getBluetoothScanResultCounter().getCountLocked(which) : 0;
+ final int resultCountBg = u.getBluetoothScanResultBgCounter() != null ?
+ u.getBluetoothScanResultBgCounter().getCountLocked(which) : 0;
+ // Unoptimized scan timer. Unpooled and since reset (regardless of 'which').
+ final Timer unoptimizedScanTimer = u.getBluetoothUnoptimizedScanTimer();
+ final long unoptimizedScanTotalTime = unoptimizedScanTimer != null ?
+ unoptimizedScanTimer.getTotalDurationMsLocked(rawRealtimeMs) : 0;
+ final long unoptimizedScanMaxTime = unoptimizedScanTimer != null ?
+ unoptimizedScanTimer.getMaxDurationMsLocked(rawRealtimeMs) : 0;
+ // Unoptimized bg scan timer. Unpooled and since reset (regardless of 'which').
+ final Timer unoptimizedScanTimerBg =
+ u.getBluetoothUnoptimizedScanBackgroundTimer();
+ final long unoptimizedScanTotalTimeBg = unoptimizedScanTimerBg != null ?
+ unoptimizedScanTimerBg.getTotalDurationMsLocked(rawRealtimeMs) : 0;
+ final long unoptimizedScanMaxTimeBg = unoptimizedScanTimerBg != null ?
+ unoptimizedScanTimerBg.getMaxDurationMsLocked(rawRealtimeMs) : 0;
sb.setLength(0);
- sb.append(prefix);
- sb.append(" ");
- sb.append("Bluetooth Scan");
- sb.append(": ");
if (actualTimeMs != totalTimeMs) {
+ sb.append(prefix);
+ sb.append(" Bluetooth Scan (total blamed realtime): ");
formatTimeMs(sb, totalTimeMs);
- sb.append("blamed realtime, ");
+ sb.append(" (");
+ sb.append(count);
+ sb.append(" times)");
+ if (bleTimer.isRunningLocked()) {
+ sb.append(" (currently running)");
+ }
+ sb.append("\n");
}
- formatTimeMs(sb, actualTimeMs); // since reset, regardless of 'which'
- sb.append("realtime (");
+
+ sb.append(prefix);
+ sb.append(" Bluetooth Scan (total actual realtime): ");
+ formatTimeMs(sb, actualTimeMs); // since reset, ignores 'which'
+ sb.append(" (");
sb.append(count);
sb.append(" times)");
if (bleTimer.isRunningLocked()) {
- sb.append(" (running)");
+ sb.append(" (currently running)");
}
- if (actualTimeMsBg != 0 || countBg > 0) {
- sb.append(", ");
- formatTimeMs(sb, actualTimeMsBg); // since reset, regardless of 'which'
- sb.append("background (");
+ sb.append("\n");
+ if (actualTimeMsBg > 0 || countBg > 0) {
+ sb.append(prefix);
+ sb.append(" Bluetooth Scan (background realtime): ");
+ formatTimeMs(sb, actualTimeMsBg); // since reset, ignores 'which'
+ sb.append(" (");
sb.append(countBg);
sb.append(" times)");
+ if (bleTimerBg != null && bleTimerBg.isRunningLocked()) {
+ sb.append(" (currently running in background)");
+ }
+ sb.append("\n");
}
- sb.append("; Results count ");
+
+ sb.append(prefix);
+ sb.append(" Bluetooth Scan Results: ");
sb.append(resultCount);
+ sb.append(" (");
+ sb.append(resultCountBg);
+ sb.append(" in background)");
+
+ if (unoptimizedScanTotalTime > 0 || unoptimizedScanTotalTimeBg > 0) {
+ sb.append("\n");
+ sb.append(prefix);
+ sb.append(" Unoptimized Bluetooth Scan (realtime): ");
+ formatTimeMs(sb, unoptimizedScanTotalTime); // since reset, ignores 'which'
+ sb.append(" (max ");
+ formatTimeMs(sb, unoptimizedScanMaxTime); // since reset, ignores 'which'
+ sb.append(")");
+ if (unoptimizedScanTimer != null
+ && unoptimizedScanTimer.isRunningLocked()) {
+ sb.append(" (currently running unoptimized)");
+ }
+ if (unoptimizedScanTimerBg != null && unoptimizedScanTotalTimeBg > 0) {
+ sb.append("\n");
+ sb.append(prefix);
+ sb.append(" Unoptimized Bluetooth Scan (background realtime): ");
+ formatTimeMs(sb, unoptimizedScanTotalTimeBg); // since reset
+ sb.append(" (max ");
+ formatTimeMs(sb, unoptimizedScanMaxTimeBg); // since reset
+ sb.append(")");
+ if (unoptimizedScanTimerBg.isRunningLocked()) {
+ sb.append(" (currently running unoptimized in background)");
+ }
+ }
+ }
pw.println(sb.toString());
uidActivity = true;
}
@@ -4696,8 +4791,11 @@ public abstract class BatteryStats implements Parcelable {
sb.append(wakelocks.keyAt(iw));
linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_FULL), rawRealtime,
"full", which, linePrefix);
- linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), rawRealtime,
+ final Timer pTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
+ linePrefix = printWakeLock(sb, pTimer, rawRealtime,
"partial", which, linePrefix);
+ linePrefix = printWakeLock(sb, pTimer != null ? pTimer.getSubTimer() : null,
+ rawRealtime, "background partial", which, linePrefix);
linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), rawRealtime,
"window", which, linePrefix);
linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_DRAW), rawRealtime,
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index f361c549f016..d81ee4ef9843 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -1642,11 +1642,20 @@ public class StorageManager {
*/
@RequiresPermission(android.Manifest.permission.ALLOCATE_AGGRESSIVE)
@SystemApi
- public static final int FLAG_ALLOCATE_AGGRESSIVE = 1;
+ public static final int FLAG_ALLOCATE_AGGRESSIVE = 1 << 0;
+
+ /**
+ * Flag indicating that a disk space allocation request should defy any
+ * reserved disk space.
+ *
+ * @hide
+ */
+ public static final int FLAG_ALLOCATE_DEFY_RESERVED = 1 << 1;
/** @hide */
@IntDef(flag = true, value = {
FLAG_ALLOCATE_AGGRESSIVE,
+ FLAG_ALLOCATE_DEFY_RESERVED,
})
@Retention(RetentionPolicy.SOURCE)
public @interface AllocateFlags {}
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index 5408e1319e36..70ef0355af8c 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -8915,15 +8915,11 @@ public final class ContactsContract {
* ambiguous then the activity should prompt the user for the recipient to send the message
* to.
* <p>
- * Voice Assistant may provide additional information to messaging app about which account
- * to use for sending a message by populating {@link #EXTRA_SENDER_ACCOUNT_HASH}.
- * <p>
* Output: nothing
*
* @see #EXTRA_RECIPIENT_CONTACT_URI
* @see #EXTRA_RECIPIENT_CONTACT_CHAT_ID
* @see #EXTRA_RECIPIENT_CONTACT_NAME
- * @see #EXTRA_SENDER_ACCOUNT_HASH
* @see #METADATA_ACCOUNT_TYPE
* @see #METADATA_MIMETYPE
*/
@@ -8982,21 +8978,6 @@ public final class ContactsContract {
"android.provider.extra.RECIPIENT_CONTACT_NAME";
/**
- * This optional extra specifies the hash of the account that should be used by messaging
- * app for sending voice message with {@link #ACTION_VOICE_SEND_MESSAGE_TO_CONTACTS}. The
- * value of this extra is a {@code String} and should be the value of {@link
- * android.accounts.Account#hashCode()} for some account returned by {@link
- * android.accounts.AccountManager#getAccounts()}.
- * <p>
- * If the extra is not specified, the app can decide which account to use.
- * <p>
- * If the account specified in the extra cannot be used for any reason (account missing, not
- * usable by the app, etc), the message should not be sent.
- */
- public static final String EXTRA_SENDER_ACCOUNT_HASH =
- "android.provider.extra.SENDER_ACCOUNT_HASH";
-
- /**
* A string associated with an {@link #ACTION_VOICE_SEND_MESSAGE_TO_CONTACTS} activity
* describing {@link RawContacts#ACCOUNT_TYPE} for the corresponding Contacts Provider
* implementation.
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 3cd54b8af39e..6a17ed1500bd 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -9817,13 +9817,49 @@ public final class Settings {
public static final String ENABLE_EPHEMERAL_FEATURE = "enable_ephemeral_feature";
/**
- * The duration for caching uninstalled instant apps.
+ * The min period for caching installed instant apps in milliseconds.
* <p>
* Type: long
* @hide
*/
- public static final String UNINSTALLED_INSTANT_APP_CACHE_DURATION_MILLIS =
- "uninstalled_instant_app_cache_duration_millis";
+ public static final String INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD =
+ "installed_instant_app_min_cache_period";
+
+ /**
+ * The max period for caching installed instant apps in milliseconds.
+ * <p>
+ * Type: long
+ * @hide
+ */
+ public static final String INSTALLED_INSTANT_APP_MAX_CACHE_PERIOD =
+ "installed_instant_app_max_cache_period";
+
+ /**
+ * The min period for caching uninstalled instant apps in milliseconds.
+ * <p>
+ * Type: long
+ * @hide
+ */
+ public static final String UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD =
+ "uninstalled_instant_app_min_cache_period";
+
+ /**
+ * The max period for caching uninstalled instant apps in milliseconds.
+ * <p>
+ * Type: long
+ * @hide
+ */
+ public static final String UNINSTALLED_INSTANT_APP_MAX_CACHE_PERIOD =
+ "uninstalled_instant_app_max_cache_period";
+
+ /**
+ * The min period for caching unused static shared libs in milliseconds.
+ * <p>
+ * Type: long
+ * @hide
+ */
+ public static final String UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD =
+ "unused_static_shared_lib_min_cache_period";
/**
* Allows switching users when system user is locked.
diff --git a/core/java/android/util/proto/ProtoOutputStream.java b/core/java/android/util/proto/ProtoOutputStream.java
index adf49387a05d..480abc1482a3 100644
--- a/core/java/android/util/proto/ProtoOutputStream.java
+++ b/core/java/android/util/proto/ProtoOutputStream.java
@@ -1593,7 +1593,7 @@ public final class ProtoOutputStream {
assertNotCompacted();
final int id = checkFieldId(fieldId, FIELD_COUNT_REPEATED | FIELD_TYPE_FIXED64);
- writeRepeatedFixed64(id, val);
+ writeRepeatedFixed64Impl(id, val);
}
private void writeRepeatedFixed64Impl(int id, long val) {
@@ -1720,7 +1720,7 @@ public final class ProtoOutputStream {
assertNotCompacted();
final int id = checkFieldId(fieldId, FIELD_COUNT_REPEATED | FIELD_TYPE_SFIXED64);
- writeRepeatedSFixed64(id, val);
+ writeRepeatedSFixed64Impl(id, val);
}
private void writeRepeatedSFixed64Impl(int id, long val) {
@@ -1785,7 +1785,7 @@ public final class ProtoOutputStream {
assertNotCompacted();
final int id = checkFieldId(fieldId, FIELD_COUNT_REPEATED | FIELD_TYPE_BOOL);
- writeRepeatedBool(id, val);
+ writeRepeatedBoolImpl(id, val);
}
private void writeRepeatedBoolImpl(int id, boolean val) {
diff --git a/core/java/android/view/AppTransitionAnimationSpec.java b/core/java/android/view/AppTransitionAnimationSpec.java
index c6e1989e8b55..86a5fb761355 100644
--- a/core/java/android/view/AppTransitionAnimationSpec.java
+++ b/core/java/android/view/AppTransitionAnimationSpec.java
@@ -1,6 +1,6 @@
package android.view;
-import android.graphics.Bitmap;
+import android.graphics.GraphicBuffer;
import android.graphics.Rect;
import android.os.Parcel;
import android.os.Parcelable;
@@ -15,19 +15,19 @@ import android.os.Parcelable;
*/
public class AppTransitionAnimationSpec implements Parcelable {
public final int taskId;
- public final Bitmap bitmap;
+ public final GraphicBuffer buffer;
public final Rect rect;
- public AppTransitionAnimationSpec(int taskId, Bitmap bitmap, Rect rect) {
+ public AppTransitionAnimationSpec(int taskId, GraphicBuffer buffer, Rect rect) {
this.taskId = taskId;
- this.bitmap = bitmap;
this.rect = rect;
+ this.buffer = buffer;
}
public AppTransitionAnimationSpec(Parcel in) {
taskId = in.readInt();
- bitmap = in.readParcelable(null);
rect = in.readParcelable(null);
+ buffer = in.readParcelable(null);
}
@Override
@@ -38,9 +38,8 @@ public class AppTransitionAnimationSpec implements Parcelable {
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(taskId);
- dest.writeParcelable(bitmap, 0 /* flags */);
dest.writeParcelable(rect, 0 /* flags */);
-
+ dest.writeParcelable(buffer, 0);
}
public static final Parcelable.Creator<AppTransitionAnimationSpec> CREATOR
@@ -56,6 +55,6 @@ public class AppTransitionAnimationSpec implements Parcelable {
@Override
public String toString() {
- return "{taskId: " + taskId + ", bitmap: " + bitmap + ", rect: " + rect + "}";
+ return "{taskId: " + taskId + ", buffer: " + buffer + ", rect: " + rect + "}";
}
}
diff --git a/core/java/android/view/IPinnedStackController.aidl b/core/java/android/view/IPinnedStackController.aidl
index dbeb747adfba..d2dcb568ef6c 100644
--- a/core/java/android/view/IPinnedStackController.aidl
+++ b/core/java/android/view/IPinnedStackController.aidl
@@ -30,6 +30,14 @@ interface IPinnedStackController {
oneway void setIsMinimized(boolean isMinimized);
/**
+ * Notifies the controller of the current min edge size, this is needed to allow the system to
+ * properly calculate the aspect ratio of the expanded PIP. The given {@param minEdgeSize} is
+ * always bounded to be larger than the default minEdgeSize, so the caller can call this method
+ * with 0 to reset to the default size.
+ */
+ oneway void setMinEdgeSize(int minEdgeSize);
+
+ /**
* @return what WM considers to be the current device rotation.
*/
int getDisplayRotation();
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index a2ff4f787b61..58a6a5e78803 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -26,6 +26,7 @@ import com.android.internal.policy.IShortcutService;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
import android.graphics.Bitmap;
+import android.graphics.GraphicBuffer;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Bundle;
@@ -96,9 +97,9 @@ interface IWindowManager
int startHeight);
void overridePendingAppTransitionClipReveal(int startX, int startY,
int startWidth, int startHeight);
- void overridePendingAppTransitionThumb(in Bitmap srcThumb, int startX, int startY,
+ void overridePendingAppTransitionThumb(in GraphicBuffer srcThumb, int startX, int startY,
IRemoteCallback startedCallback, boolean scaleUp);
- void overridePendingAppTransitionAspectScaledThumb(in Bitmap srcThumb, int startX,
+ void overridePendingAppTransitionAspectScaledThumb(in GraphicBuffer srcThumb, int startX,
int startY, int targetWidth, int targetHeight, IRemoteCallback startedCallback,
boolean scaleUp);
/**
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 2c9b2e4388f8..b57ac66e10cc 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -31,7 +31,7 @@ import android.graphics.Rect;
import android.graphics.Region;
import android.os.Build;
import android.os.Handler;
-import android.os.Message;
+import android.os.Looper;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.util.Log;
@@ -120,34 +120,11 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb
final Rect mTmpRect = new Rect();
final Configuration mConfiguration = new Configuration();
- static final int KEEP_SCREEN_ON_MSG = 1;
- static final int DRAW_FINISHED_MSG = 2;
-
int mSubLayer = APPLICATION_MEDIA_SUBLAYER;
boolean mIsCreating = false;
private volatile boolean mRtHandlingPositionUpdates = false;
- final Handler mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case KEEP_SCREEN_ON_MSG: {
- setKeepScreenOn(msg.arg1 != 0);
- } break;
- case DRAW_FINISHED_MSG: {
- mDrawFinished = true;
- if (mAttachedToWindow) {
- mParent.requestTransparentRegion(SurfaceView.this);
-
- notifyDrawFinished();
- invalidate();
- }
- } break;
- }
- }
- };
-
private final ViewTreeObserver.OnScrollChangedListener mScrollChangedListener
= new ViewTreeObserver.OnScrollChangedListener() {
@Override
@@ -287,6 +264,22 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb
updateSurface();
}
+ private void performDrawFinished() {
+ if (mPendingReportDraws > 0) {
+ mDrawFinished = true;
+ if (mAttachedToWindow) {
+ mParent.requestTransparentRegion(SurfaceView.this);
+
+ notifyDrawFinished();
+ invalidate();
+ }
+ } else {
+ Log.e(TAG, System.identityHashCode(this) + "finished drawing"
+ + " but no pending report draw (extra call"
+ + " to draw completion runnable?)");
+ }
+ }
+
void notifyDrawFinished() {
ViewRootImpl viewRoot = getViewRootImpl();
if (viewRoot != null) {
@@ -751,7 +744,9 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb
mDeferredDestroySurfaceControl = null;
}
- mHandler.sendEmptyMessage(DRAW_FINISHED_MSG);
+ runOnUiThread(() -> {
+ performDrawFinished();
+ });
}
private void setParentSpaceRectangle(Rect position, long frameNumber) {
@@ -880,6 +875,15 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb
+ "type=" + type, new Throwable());
}
+ private void runOnUiThread(Runnable runnable) {
+ Handler handler = getHandler();
+ if (handler != null && handler.getLooper() != Looper.myLooper()) {
+ handler.post(runnable);
+ } else {
+ runnable.run();
+ }
+ }
+
/**
* Check to see if the surface has fixed size dimensions or if the surface's
* dimensions are dimensions are dependent on its current layout.
@@ -960,9 +964,7 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb
@Override
public void setKeepScreenOn(boolean screenOn) {
- Message msg = mHandler.obtainMessage(KEEP_SCREEN_ON_MSG);
- msg.arg1 = screenOn ? 1 : 0;
- mHandler.sendMessage(msg);
+ runOnUiThread(() -> SurfaceView.this.setKeepScreenOn(screenOn));
}
/**
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 28ded55c54fa..a720aae0d1be 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -2330,7 +2330,7 @@ public final class ViewRootImpl implements ViewParent,
// Remember if we must report the next draw.
if ((relayoutResult & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0) {
- mReportNextDraw = true;
+ reportNextDraw();
}
boolean cancelDraw = mAttachInfo.mTreeObserver.dispatchOnPreDraw() || !isViewVisible;
@@ -2731,11 +2731,8 @@ public final class ViewRootImpl implements ViewParent,
/**
* A count of the number of calls to pendingDrawFinished we
* require to notify the WM drawing is complete.
- *
- * This starts at 1, for the ViewRootImpl surface itself.
- * Subsurfaces may debt the value with drawPending.
*/
- int mDrawsNeededToReport = 1;
+ int mDrawsNeededToReport = 0;
/**
* Delay notifying WM of draw finished until
@@ -2761,7 +2758,7 @@ public final class ViewRootImpl implements ViewParent,
private void reportDrawFinished() {
try {
- mDrawsNeededToReport = 1;
+ mDrawsNeededToReport = 0;
mWindowSession.finishDrawing(mWindow);
} catch (RemoteException e) {
// Have fun!
@@ -3772,13 +3769,12 @@ public final class ViewRootImpl implements ViewParent,
args.recycle();
if (msg.what == MSG_RESIZED_REPORT) {
- mReportNextDraw = true;
+ reportNextDraw();
}
if (mView != null && framesChanged) {
forceLayout(mView);
}
-
requestLayout();
}
break;
@@ -7343,6 +7339,14 @@ public final class ViewRootImpl implements ViewParent,
return false;
}
+
+ private void reportNextDraw() {
+ if (mReportNextDraw == false) {
+ drawPending();
+ }
+ mReportNextDraw = true;
+ }
+
/**
* Force the window to report its next draw.
* <p>
@@ -7352,7 +7356,7 @@ public final class ViewRootImpl implements ViewParent,
* @hide
*/
public void setReportNextDraw() {
- mReportNextDraw = true;
+ reportNextDraw();
invalidate();
}
diff --git a/core/java/android/view/WindowManagerInternal.java b/core/java/android/view/WindowManagerInternal.java
index bf0e10f993ad..55aed529037d 100644
--- a/core/java/android/view/WindowManagerInternal.java
+++ b/core/java/android/view/WindowManagerInternal.java
@@ -225,6 +225,9 @@ public abstract class WindowManagerInternal {
*/
public abstract boolean isKeyguardLocked();
+ /** @return {@code true} if the keyguard is going away. */
+ public abstract boolean isKeyguardGoingAway();
+
/**
* Gets the frame of a window given its token.
*
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index a2aff931ccff..02ecc501ea39 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -258,6 +258,11 @@ public final class AutofillManager {
* @return The view, or {@code null} if not found
*/
@Nullable View findViewByAccessibilityIdTraversal(int viewId);
+
+ /**
+ * Runs the specified action on the UI thread.
+ */
+ void runOnUiThread(Runnable action);
}
/**
@@ -1233,6 +1238,15 @@ public final class AutofillManager {
return mService != null;
}
+ private void post(Runnable runnable) {
+ final AutofillClient client = getClientLocked();
+ if (client == null) {
+ if (sVerbose) Log.v(TAG, "ignoring post() because client is null");
+ return;
+ }
+ client.runOnUiThread(runnable);
+ }
+
/**
* View tracking information. Once all tracked views become invisible the session is finished.
*/
@@ -1516,8 +1530,7 @@ public final class AutofillManager {
public void setState(boolean enabled, boolean resetSession, boolean resetClient) {
final AutofillManager afm = mAfm.get();
if (afm != null) {
- afm.mContext.getMainThreadHandler().post(
- () -> afm.setState(enabled, resetSession, resetClient));
+ afm.post(() -> afm.setState(enabled, resetSession, resetClient));
}
}
@@ -1525,8 +1538,7 @@ public final class AutofillManager {
public void autofill(int sessionId, List<AutofillId> ids, List<AutofillValue> values) {
final AutofillManager afm = mAfm.get();
if (afm != null) {
- afm.mContext.getMainThreadHandler().post(
- () -> afm.autofill(sessionId, ids, values));
+ afm.post(() -> afm.autofill(sessionId, ids, values));
}
}
@@ -1535,8 +1547,7 @@ public final class AutofillManager {
Intent fillInIntent) {
final AutofillManager afm = mAfm.get();
if (afm != null) {
- afm.mContext.getMainThreadHandler().post(
- () -> afm.authenticate(sessionId, authenticationId, intent, fillInIntent));
+ afm.post(() -> afm.authenticate(sessionId, authenticationId, intent, fillInIntent));
}
}
@@ -1545,9 +1556,8 @@ public final class AutofillManager {
Rect anchorBounds, IAutofillWindowPresenter presenter) {
final AutofillManager afm = mAfm.get();
if (afm != null) {
- afm.mContext.getMainThreadHandler().post(
- () -> afm.requestShowFillUi(sessionId, id, width, height, anchorBounds,
- presenter));
+ afm.post(() -> afm.requestShowFillUi(sessionId, id, width, height, anchorBounds,
+ presenter));
}
}
@@ -1555,7 +1565,7 @@ public final class AutofillManager {
public void requestHideFillUi(int sessionId, AutofillId id) {
final AutofillManager afm = mAfm.get();
if (afm != null) {
- afm.mContext.getMainThreadHandler().post(() -> afm.requestHideFillUi(id));
+ afm.post(() -> afm.requestHideFillUi(id));
}
}
@@ -1563,7 +1573,7 @@ public final class AutofillManager {
public void notifyNoFillUi(int sessionId, AutofillId id) {
final AutofillManager afm = mAfm.get();
if (afm != null) {
- afm.mContext.getMainThreadHandler().post(() -> afm.notifyNoFillUi(sessionId, id));
+ afm.post(() -> afm.notifyNoFillUi(sessionId, id));
}
}
@@ -1571,7 +1581,7 @@ public final class AutofillManager {
public void startIntentSender(IntentSender intentSender) {
final AutofillManager afm = mAfm.get();
if (afm != null) {
- afm.mContext.getMainThreadHandler().post(() -> {
+ afm.post(() -> {
try {
afm.mContext.startIntentSender(intentSender, null, 0, 0, 0);
} catch (IntentSender.SendIntentException e) {
@@ -1586,7 +1596,7 @@ public final class AutofillManager {
boolean saveOnAllViewsInvisible, AutofillId[] fillableIds) {
final AutofillManager afm = mAfm.get();
if (afm != null) {
- afm.mContext.getMainThreadHandler().post(() ->
+ afm.post(() ->
afm.setTrackedViews(sessionId, ids, saveOnAllViewsInvisible, fillableIds)
);
}
diff --git a/core/java/android/view/autofill/AutofillPopupWindow.java b/core/java/android/view/autofill/AutofillPopupWindow.java
index cd16a245c9b4..5f476380b1c3 100644
--- a/core/java/android/view/autofill/AutofillPopupWindow.java
+++ b/core/java/android/view/autofill/AutofillPopupWindow.java
@@ -16,6 +16,8 @@
package android.view.autofill;
+import static android.view.autofill.Helper.sVerbose;
+
import android.annotation.NonNull;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
@@ -186,6 +188,10 @@ public class AutofillPopupWindow extends PopupWindow {
@Override
public void showAsDropDown(View anchor, int xoff, int yoff, int gravity) {
+ if (sVerbose) {
+ Log.v(TAG, "showAsDropDown(): anchor=" + anchor + ", xoff=" + xoff + ", yoff=" + yoff
+ + ", isShowing(): " + isShowing());
+ }
if (isShowing()) {
return;
}
diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl
index 78566dfc458e..04f7c76c8e74 100644
--- a/core/java/com/android/internal/app/IBatteryStats.aidl
+++ b/core/java/com/android/internal/app/IBatteryStats.aidl
@@ -129,7 +129,7 @@ interface IBatteryStats {
long getAwakeTimeBattery();
long getAwakeTimePlugged();
- void noteBleScanStarted(in WorkSource ws);
+ void noteBleScanStarted(in WorkSource ws, boolean isUnoptimized);
void noteBleScanStopped(in WorkSource ws);
void noteResetBleScan();
void noteBleScanResults(in WorkSource ws, int numNewResults);
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 31064ac73dff..1b0d3323b3d0 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -56,6 +56,7 @@ import android.util.LogWriter;
import android.util.LongSparseArray;
import android.util.LongSparseLongArray;
import android.util.MutableInt;
+import android.util.Pools;
import android.util.PrintWriterPrinter;
import android.util.Printer;
import android.util.Slog;
@@ -66,6 +67,7 @@ import android.util.TimeUtils;
import android.util.Xml;
import android.view.Display;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.net.NetworkStatsFactory;
import com.android.internal.util.ArrayUtils;
@@ -116,7 +118,7 @@ public class BatteryStatsImpl extends BatteryStats {
private static final int MAGIC = 0xBA757475; // 'BATSTATS'
// Current on-disk Parcel version
- private static final int VERSION = 158 + (USE_OLD_HISTORY ? 1000 : 0);
+ private static final int VERSION = 159 + (USE_OLD_HISTORY ? 1000 : 0);
// Maximum number of items we will record in the history.
private static final int MAX_HISTORY_ITEMS = 2000;
@@ -173,7 +175,6 @@ public class BatteryStatsImpl extends BatteryStats {
private final PlatformIdleStateCallback mPlatformIdleStateCallback;
-
final class MyHandler extends Handler {
public MyHandler(Looper looper) {
super(looper, null, true);
@@ -228,11 +229,11 @@ public class BatteryStatsImpl extends BatteryStats {
}
public interface ExternalStatsSync {
- public static final int UPDATE_CPU = 0x01;
- public static final int UPDATE_WIFI = 0x02;
- public static final int UPDATE_RADIO = 0x04;
- public static final int UPDATE_BT = 0x08;
- public static final int UPDATE_ALL = UPDATE_CPU | UPDATE_WIFI | UPDATE_RADIO | UPDATE_BT;
+ int UPDATE_CPU = 0x01;
+ int UPDATE_WIFI = 0x02;
+ int UPDATE_RADIO = 0x04;
+ int UPDATE_BT = 0x08;
+ int UPDATE_ALL = UPDATE_CPU | UPDATE_WIFI | UPDATE_RADIO | UPDATE_BT;
void scheduleSync(String reason, int flags);
void scheduleCpuSyncDueToRemovedUid(int uid);
@@ -572,8 +573,6 @@ public class BatteryStatsImpl extends BatteryStats {
private int mMinLearnedBatteryCapacity = -1;
private int mMaxLearnedBatteryCapacity = -1;
- private final NetworkStats.Entry mTmpNetworkStatsEntry = new NetworkStats.Entry();
-
private long[] mCpuFreqs;
private PowerProfile mPowerProfile;
@@ -637,19 +636,9 @@ public class BatteryStatsImpl extends BatteryStats {
private void init(Clocks clocks) {
mClocks = clocks;
- mMobileNetworkStats = new NetworkStats[] {
- new NetworkStats(mClocks.elapsedRealtime(), 50),
- new NetworkStats(mClocks.elapsedRealtime(), 50),
- new NetworkStats(mClocks.elapsedRealtime(), 50)
- };
- mWifiNetworkStats = new NetworkStats[] {
- new NetworkStats(mClocks.elapsedRealtime(), 50),
- new NetworkStats(mClocks.elapsedRealtime(), 50),
- new NetworkStats(mClocks.elapsedRealtime(), 50)
- };
}
- public static interface TimeBaseObs {
+ public interface TimeBaseObs {
void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime);
void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime);
}
@@ -862,21 +851,19 @@ public class BatteryStatsImpl extends BatteryStats {
final AtomicInteger mCount = new AtomicInteger();
final TimeBase mTimeBase;
int mLoadedCount;
- int mLastCount;
int mUnpluggedCount;
int mPluggedCount;
- Counter(TimeBase timeBase, Parcel in) {
+ public Counter(TimeBase timeBase, Parcel in) {
mTimeBase = timeBase;
mPluggedCount = in.readInt();
mCount.set(mPluggedCount);
mLoadedCount = in.readInt();
- mLastCount = 0;
mUnpluggedCount = in.readInt();
timeBase.add(this);
}
- Counter(TimeBase timeBase) {
+ public Counter(TimeBase timeBase) {
mTimeBase = timeBase;
timeBase.add(this);
}
@@ -887,11 +874,12 @@ public class BatteryStatsImpl extends BatteryStats {
out.writeInt(mUnpluggedCount);
}
+ @Override
public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
mUnpluggedCount = mPluggedCount;
- mCount.set(mPluggedCount);
}
+ @Override
public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
mPluggedCount = mCount.get();
}
@@ -926,17 +914,22 @@ public class BatteryStatsImpl extends BatteryStats {
public void logState(Printer pw, String prefix) {
pw.println(prefix + "mCount=" + mCount.get()
- + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
+ + " mLoadedCount=" + mLoadedCount
+ " mUnpluggedCount=" + mUnpluggedCount
+ " mPluggedCount=" + mPluggedCount);
}
- void stepAtomic() {
- mCount.incrementAndGet();
+ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+ public void stepAtomic() {
+ if (mTimeBase.isRunning()) {
+ mCount.incrementAndGet();
+ }
}
void addAtomic(int delta) {
- mCount.addAndGet(delta);
+ if (mTimeBase.isRunning()) {
+ mCount.addAndGet(delta);
+ }
}
/**
@@ -944,7 +937,7 @@ public class BatteryStatsImpl extends BatteryStats {
*/
void reset(boolean detachIfReset) {
mCount.set(0);
- mLoadedCount = mLastCount = mPluggedCount = mUnpluggedCount = 0;
+ mLoadedCount = mPluggedCount = mUnpluggedCount = 0;
if (detachIfReset) {
detach();
}
@@ -954,15 +947,16 @@ public class BatteryStatsImpl extends BatteryStats {
mTimeBase.remove(this);
}
- void writeSummaryFromParcelLocked(Parcel out) {
+ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+ public void writeSummaryFromParcelLocked(Parcel out) {
int count = mCount.get();
out.writeInt(count);
}
- void readSummaryFromParcelLocked(Parcel in) {
+ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+ public void readSummaryFromParcelLocked(Parcel in) {
mLoadedCount = in.readInt();
mCount.set(mLoadedCount);
- mLastCount = 0;
mUnpluggedCount = mPluggedCount = mLoadedCount;
}
}
@@ -998,7 +992,6 @@ public class BatteryStatsImpl extends BatteryStats {
@Override
public void onTimeStarted(long elapsedRealTime, long baseUptime, long baseRealtime) {
mUnpluggedCounts = copyArray(mPluggedCounts, mUnpluggedCounts);
- mCounts = copyArray(mPluggedCounts, mCounts);
}
@Override
@@ -1029,11 +1022,13 @@ public class BatteryStatsImpl extends BatteryStats {
if (counts == null) {
return;
}
- if (mCounts == null) {
- mCounts = new long[counts.length];
- }
- for (int i = 0; i < counts.length; ++i) {
- mCounts[i] += counts[i];
+ if (mTimeBase.isRunning()) {
+ if (mCounts == null) {
+ mCounts = new long[counts.length];
+ }
+ for (int i = 0; i < counts.length; ++i) {
+ mCounts[i] += counts[i];
+ }
}
}
@@ -1104,13 +1099,13 @@ public class BatteryStatsImpl extends BatteryStats {
}
}
- private void fillArray(long[] a, long val) {
+ private static void fillArray(long[] a, long val) {
if (a != null) {
Arrays.fill(a, val);
}
}
- private void subtract(@NonNull long[] val, long[] toSubtract) {
+ private static void subtract(@NonNull long[] val, long[] toSubtract) {
if (toSubtract == null) {
return;
}
@@ -1119,7 +1114,7 @@ public class BatteryStatsImpl extends BatteryStats {
}
}
- private long[] copyArray(long[] src, long[] dest) {
+ private static long[] copyArray(long[] src, long[] dest) {
if (src == null) {
return null;
} else {
@@ -1162,7 +1157,6 @@ public class BatteryStatsImpl extends BatteryStats {
@Override
public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
mUnpluggedCount = mPluggedCount;
- mCount = mPluggedCount;
}
@Override
@@ -1189,7 +1183,9 @@ public class BatteryStatsImpl extends BatteryStats {
}
void addCountLocked(long count) {
- mCount += count;
+ if (mTimeBase.isRunning()) {
+ mCount += count;
+ }
}
/**
@@ -4193,7 +4189,10 @@ public class BatteryStatsImpl extends BatteryStats {
getUidStatsLocked(uid).noteMobileRadioApWakeupLocked();
}
- public void noteMobileRadioPowerState(int powerState, long timestampNs, int uid) {
+ /**
+ * 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();
if (mMobileRadioPowerState != powerState) {
@@ -4230,13 +4229,15 @@ public class BatteryStatsImpl extends BatteryStats {
mMobileRadioActivePerAppTimer.startRunningLocked(elapsedRealtime);
} else {
mMobileRadioActiveTimer.stopRunningLocked(realElapsedRealtimeMs);
- updateMobileRadioStateLocked(realElapsedRealtimeMs, null);
mMobileRadioActivePerAppTimer.stopRunningLocked(realElapsedRealtimeMs);
+ // Tell the caller to collect radio network/power stats.
+ return true;
}
}
+ return false;
}
- public void notePowerSaveMode(boolean enabled) {
+ public void notePowerSaveModeLocked(boolean enabled) {
if (mPowerSaveModeEnabled != enabled) {
int stepState = enabled ? STEP_LEVEL_MODE_POWER_SAVE : 0;
mModStepMode |= (mCurStepMode&STEP_LEVEL_MODE_POWER_SAVE) ^ stepState;
@@ -4821,7 +4822,7 @@ public class BatteryStatsImpl extends BatteryStats {
}
}
- private void noteBluetoothScanStartedLocked(int uid) {
+ private void noteBluetoothScanStartedLocked(int uid, boolean isUnoptimized) {
uid = mapUid(uid);
final long elapsedRealtime = mClocks.elapsedRealtime();
final long uptime = mClocks.uptimeMillis();
@@ -4833,13 +4834,13 @@ public class BatteryStatsImpl extends BatteryStats {
mBluetoothScanTimer.startRunningLocked(elapsedRealtime);
}
mBluetoothScanNesting++;
- getUidStatsLocked(uid).noteBluetoothScanStartedLocked(elapsedRealtime);
+ getUidStatsLocked(uid).noteBluetoothScanStartedLocked(elapsedRealtime, isUnoptimized);
}
- public void noteBluetoothScanStartedFromSourceLocked(WorkSource ws) {
+ public void noteBluetoothScanStartedFromSourceLocked(WorkSource ws, boolean isUnoptimized) {
final int N = ws.size();
for (int i = 0; i < N; i++) {
- noteBluetoothScanStartedLocked(ws.get(i));
+ noteBluetoothScanStartedLocked(ws.get(i), isUnoptimized);
}
}
@@ -5236,28 +5237,26 @@ public class BatteryStatsImpl extends BatteryStats {
public void noteNetworkInterfaceTypeLocked(String iface, int networkType) {
if (TextUtils.isEmpty(iface)) return;
- if (ConnectivityManager.isNetworkTypeMobile(networkType)) {
- mMobileIfaces = includeInStringArray(mMobileIfaces, iface);
- if (DEBUG) Slog.d(TAG, "Note mobile iface " + iface + ": " + mMobileIfaces);
- } else {
- mMobileIfaces = excludeFromStringArray(mMobileIfaces, iface);
- if (DEBUG) Slog.d(TAG, "Note non-mobile iface " + iface + ": " + mMobileIfaces);
- }
- if (ConnectivityManager.isNetworkTypeWifi(networkType)) {
- mWifiIfaces = includeInStringArray(mWifiIfaces, iface);
- if (DEBUG) Slog.d(TAG, "Note wifi iface " + iface + ": " + mWifiIfaces);
- } else {
- mWifiIfaces = excludeFromStringArray(mWifiIfaces, iface);
- if (DEBUG) Slog.d(TAG, "Note non-wifi iface " + iface + ": " + mWifiIfaces);
+
+ synchronized (mModemNetworkLock) {
+ if (ConnectivityManager.isNetworkTypeMobile(networkType)) {
+ mModemIfaces = includeInStringArray(mModemIfaces, iface);
+ if (DEBUG) Slog.d(TAG, "Note mobile iface " + iface + ": " + mModemIfaces);
+ } else {
+ mModemIfaces = excludeFromStringArray(mModemIfaces, iface);
+ if (DEBUG) Slog.d(TAG, "Note non-mobile iface " + iface + ": " + mModemIfaces);
+ }
}
- }
- public void noteNetworkStatsEnabledLocked() {
- // 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.
- updateMobileRadioStateLocked(mClocks.elapsedRealtime(), null);
- updateWifiStateLocked(null);
+ synchronized (mWifiNetworkLock) {
+ if (ConnectivityManager.isNetworkTypeWifi(networkType)) {
+ mWifiIfaces = includeInStringArray(mWifiIfaces, iface);
+ if (DEBUG) Slog.d(TAG, "Note wifi iface " + iface + ": " + mWifiIfaces);
+ } else {
+ mWifiIfaces = excludeFromStringArray(mWifiIfaces, iface);
+ if (DEBUG) Slog.d(TAG, "Note non-wifi iface " + iface + ": " + mWifiIfaces);
+ }
+ }
}
@Override public long getScreenOnTime(long elapsedRealtimeUs, int which) {
@@ -5611,7 +5610,9 @@ public class BatteryStatsImpl extends BatteryStats {
/** Total time spent by the uid holding any partial wakelocks. */
DualTimer mAggregatedPartialWakelockTimer;
DualTimer mBluetoothScanTimer;
+ DualTimer mBluetoothUnoptimizedScanTimer;
Counter mBluetoothScanResultCounter;
+ Counter mBluetoothScanResultBgCounter;
int mProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT;
StopwatchTimer[] mProcessStateTimer;
@@ -6096,20 +6097,41 @@ public class BatteryStatsImpl extends BatteryStats {
return mBluetoothScanTimer;
}
- public void noteBluetoothScanStartedLocked(long elapsedRealtimeMs) {
+ public DualTimer createBluetoothUnoptimizedScanTimerLocked() {
+ if (mBluetoothUnoptimizedScanTimer == null) {
+ mBluetoothUnoptimizedScanTimer = new DualTimer(mBsi.mClocks, Uid.this,
+ BLUETOOTH_UNOPTIMIZED_SCAN_ON, null,
+ mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase);
+ }
+ return mBluetoothUnoptimizedScanTimer;
+ }
+
+ public void noteBluetoothScanStartedLocked(long elapsedRealtimeMs, boolean isUnoptimized) {
createBluetoothScanTimerLocked().startRunningLocked(elapsedRealtimeMs);
+ if (isUnoptimized) {
+ createBluetoothUnoptimizedScanTimerLocked().startRunningLocked(elapsedRealtimeMs);
+ }
}
public void noteBluetoothScanStoppedLocked(long elapsedRealtimeMs) {
if (mBluetoothScanTimer != null) {
mBluetoothScanTimer.stopRunningLocked(elapsedRealtimeMs);
}
+ // In the ble code, a scan cannot change types and nested starts are not possible.
+ // So if an unoptimizedScan is running, it is now being stopped.
+ if (mBluetoothUnoptimizedScanTimer != null
+ && mBluetoothUnoptimizedScanTimer.isRunningLocked()) {
+ mBluetoothUnoptimizedScanTimer.stopRunningLocked(elapsedRealtimeMs);
+ }
}
public void noteResetBluetoothScanLocked(long elapsedRealtimeMs) {
if (mBluetoothScanTimer != null) {
mBluetoothScanTimer.stopAllRunningLocked(elapsedRealtimeMs);
}
+ if (mBluetoothUnoptimizedScanTimer != null) {
+ mBluetoothUnoptimizedScanTimer.stopAllRunningLocked(elapsedRealtimeMs);
+ }
}
public Counter createBluetoothScanResultCounterLocked() {
@@ -6119,8 +6141,17 @@ public class BatteryStatsImpl extends BatteryStats {
return mBluetoothScanResultCounter;
}
+ public Counter createBluetoothScanResultBgCounterLocked() {
+ if (mBluetoothScanResultBgCounter == null) {
+ mBluetoothScanResultBgCounter = new Counter(mOnBatteryBackgroundTimeBase);
+ }
+ return mBluetoothScanResultBgCounter;
+ }
+
public void noteBluetoothScanResultsLocked(int numNewResults) {
createBluetoothScanResultCounterLocked().addAtomic(numNewResults);
+ // Uses background timebase, so the count will only be incremented if uid in background.
+ createBluetoothScanResultBgCounterLocked().addAtomic(numNewResults);
}
@Override
@@ -6277,10 +6308,28 @@ public class BatteryStatsImpl extends BatteryStats {
}
@Override
+ public Timer getBluetoothUnoptimizedScanTimer() {
+ return mBluetoothUnoptimizedScanTimer;
+ }
+
+ @Override
+ public Timer getBluetoothUnoptimizedScanBackgroundTimer() {
+ if (mBluetoothUnoptimizedScanTimer == null) {
+ return null;
+ }
+ return mBluetoothUnoptimizedScanTimer.getSubTimer();
+ }
+
+ @Override
public Counter getBluetoothScanResultCounter() {
return mBluetoothScanResultCounter;
}
+ @Override
+ public Counter getBluetoothScanResultBgCounter() {
+ return mBluetoothScanResultBgCounter;
+ }
+
void makeProcessState(int i, Parcel in) {
if (i < 0 || i >= NUM_PROCESS_STATE) return;
@@ -6531,9 +6580,13 @@ public class BatteryStatsImpl extends BatteryStats {
active |= !resetTimerIfNotNull(mForegroundActivityTimer, false);
active |= !resetTimerIfNotNull(mAggregatedPartialWakelockTimer, false);
active |= !resetTimerIfNotNull(mBluetoothScanTimer, false);
+ active |= !resetTimerIfNotNull(mBluetoothUnoptimizedScanTimer, false);
if (mBluetoothScanResultCounter != null) {
mBluetoothScanResultCounter.reset(false);
}
+ if (mBluetoothScanResultBgCounter != null) {
+ mBluetoothScanResultBgCounter.reset(false);
+ }
if (mProcessStateTimer != null) {
for (int i = 0; i < NUM_PROCESS_STATE; i++) {
@@ -6731,10 +6784,18 @@ public class BatteryStatsImpl extends BatteryStats {
mBluetoothScanTimer.detach();
mBluetoothScanTimer = null;
}
+ if (mBluetoothUnoptimizedScanTimer != null) {
+ mBluetoothUnoptimizedScanTimer.detach();
+ mBluetoothUnoptimizedScanTimer = null;
+ }
if (mBluetoothScanResultCounter != null) {
mBluetoothScanResultCounter.detach();
mBluetoothScanResultCounter = null;
}
+ if (mBluetoothScanResultBgCounter != null) {
+ mBluetoothScanResultBgCounter.detach();
+ mBluetoothScanResultBgCounter = null;
+ }
if (mUserActivityCounters != null) {
for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
mUserActivityCounters[i].detach();
@@ -6919,12 +6980,24 @@ public class BatteryStatsImpl extends BatteryStats {
} else {
out.writeInt(0);
}
+ if (mBluetoothUnoptimizedScanTimer != null) {
+ out.writeInt(1);
+ mBluetoothUnoptimizedScanTimer.writeToParcel(out, elapsedRealtimeUs);
+ } else {
+ out.writeInt(0);
+ }
if (mBluetoothScanResultCounter != null) {
out.writeInt(1);
mBluetoothScanResultCounter.writeToParcel(out);
} else {
out.writeInt(0);
}
+ if (mBluetoothScanResultBgCounter != null) {
+ out.writeInt(1);
+ mBluetoothScanResultBgCounter.writeToParcel(out);
+ } else {
+ out.writeInt(0);
+ }
for (int i = 0; i < NUM_PROCESS_STATE; i++) {
if (mProcessStateTimer[i] != null) {
out.writeInt(1);
@@ -7033,7 +7106,8 @@ public class BatteryStatsImpl extends BatteryStats {
for (int j = 0; j < numWakelocks; j++) {
String wakelockName = in.readString();
Uid.Wakelock wakelock = new Wakelock(mBsi, this);
- wakelock.readFromParcelLocked(timeBase, screenOffTimeBase, in);
+ wakelock.readFromParcelLocked(
+ timeBase, screenOffTimeBase, mOnBatteryScreenOffBackgroundTimeBase, in);
mWakelockStats.add(wakelockName, wakelock);
}
@@ -7168,10 +7242,22 @@ public class BatteryStatsImpl extends BatteryStats {
mBluetoothScanTimer = null;
}
if (in.readInt() != 0) {
+ mBluetoothUnoptimizedScanTimer = new DualTimer(mBsi.mClocks, Uid.this,
+ BLUETOOTH_UNOPTIMIZED_SCAN_ON, null,
+ mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, in);
+ } else {
+ mBluetoothUnoptimizedScanTimer = null;
+ }
+ if (in.readInt() != 0) {
mBluetoothScanResultCounter = new Counter(mBsi.mOnBatteryTimeBase, in);
} else {
mBluetoothScanResultCounter = null;
}
+ if (in.readInt() != 0) {
+ mBluetoothScanResultBgCounter = new Counter(mOnBatteryBackgroundTimeBase, in);
+ } else {
+ mBluetoothScanResultBgCounter = null;
+ }
mProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT;
for (int i = 0; i < NUM_PROCESS_STATE; i++) {
if (in.readInt() != 0) {
@@ -7298,8 +7384,9 @@ public class BatteryStatsImpl extends BatteryStats {
/**
* How long (in ms) this uid has been keeping the device partially awake.
+ * Tracks both the total time and the time while the app was in the background.
*/
- DurationTimer mTimerPartial;
+ DualTimer mTimerPartial;
/**
* How long (in ms) this uid has been keeping the device fully awake.
@@ -7344,13 +7431,13 @@ public class BatteryStatsImpl extends BatteryStats {
* @param in the Parcel to be read from.
* return a new Timer, or null.
*/
- private DurationTimer readDurationTimerFromParcel(int type,
- ArrayList<StopwatchTimer> pool, TimeBase timeBase, Parcel in) {
+ private DualTimer readDualTimerFromParcel(int type, ArrayList<StopwatchTimer> pool,
+ TimeBase timeBase, TimeBase bgTimeBase, Parcel in) {
if (in.readInt() == 0) {
return null;
}
- return new DurationTimer(mBsi.mClocks, mUid, type, pool, timeBase, in);
+ return new DualTimer(mBsi.mClocks, mUid, type, pool, timeBase, bgTimeBase, in);
}
boolean reset() {
@@ -7388,9 +7475,10 @@ public class BatteryStatsImpl extends BatteryStats {
return !wlactive;
}
- void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, Parcel in) {
- mTimerPartial = readDurationTimerFromParcel(WAKE_TYPE_PARTIAL,
- mBsi.mPartialTimers, screenOffTimeBase, in);
+ void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase,
+ TimeBase screenOffBgTimeBase, Parcel in) {
+ mTimerPartial = readDualTimerFromParcel(WAKE_TYPE_PARTIAL,
+ mBsi.mPartialTimers, screenOffTimeBase, screenOffBgTimeBase, in);
mTimerFull = readStopwatchTimerFromParcel(WAKE_TYPE_FULL,
mBsi.mFullTimers, timeBase, in);
mTimerWindow = readStopwatchTimerFromParcel(WAKE_TYPE_WINDOW,
@@ -7416,49 +7504,6 @@ public class BatteryStatsImpl extends BatteryStats {
default: throw new IllegalArgumentException("type = " + type);
}
}
-
- public StopwatchTimer getStopwatchTimer(int type) {
- switch (type) {
- case WAKE_TYPE_PARTIAL: {
- DurationTimer t = mTimerPartial;
- if (t == null) {
- t = new DurationTimer(mBsi.mClocks, mUid, WAKE_TYPE_PARTIAL,
- mBsi.mPartialTimers, mBsi.mOnBatteryScreenOffTimeBase);
- mTimerPartial = t;
- }
- return t;
- }
- case WAKE_TYPE_FULL: {
- StopwatchTimer t = mTimerFull;
- if (t == null) {
- t = new StopwatchTimer(mBsi.mClocks, mUid, WAKE_TYPE_FULL,
- mBsi.mFullTimers, mBsi.mOnBatteryTimeBase);
- mTimerFull = t;
- }
- return t;
- }
- case WAKE_TYPE_WINDOW: {
- StopwatchTimer t = mTimerWindow;
- if (t == null) {
- t = new StopwatchTimer(mBsi.mClocks, mUid, WAKE_TYPE_WINDOW,
- mBsi.mWindowTimers, mBsi.mOnBatteryTimeBase);
- mTimerWindow = t;
- }
- return t;
- }
- case WAKE_TYPE_DRAW: {
- StopwatchTimer t = mTimerDraw;
- if (t == null) {
- t = new StopwatchTimer(mBsi.mClocks, mUid, WAKE_TYPE_DRAW,
- mBsi.mDrawTimers, mBsi.mOnBatteryTimeBase);
- mTimerDraw = t;
- }
- return t;
- }
- default:
- throw new IllegalArgumentException("type=" + type);
- }
- }
}
public static class Sensor extends BatteryStats.Uid.Sensor {
@@ -8351,16 +8396,16 @@ public class BatteryStatsImpl extends BatteryStats {
Wakelock wl = new Wakelock(mBsi, this);
mWakelockStats.add(wlName, wl);
if (in.readInt() != 0) {
- wl.getStopwatchTimer(WAKE_TYPE_FULL).readSummaryFromParcelLocked(in);
+ getWakelockTimerLocked(wl, WAKE_TYPE_FULL).readSummaryFromParcelLocked(in);
}
if (in.readInt() != 0) {
- wl.getStopwatchTimer(WAKE_TYPE_PARTIAL).readSummaryFromParcelLocked(in);
+ getWakelockTimerLocked(wl, WAKE_TYPE_PARTIAL).readSummaryFromParcelLocked(in);
}
if (in.readInt() != 0) {
- wl.getStopwatchTimer(WAKE_TYPE_WINDOW).readSummaryFromParcelLocked(in);
+ getWakelockTimerLocked(wl, WAKE_TYPE_WINDOW).readSummaryFromParcelLocked(in);
}
if (in.readInt() != 0) {
- wl.getStopwatchTimer(WAKE_TYPE_DRAW).readSummaryFromParcelLocked(in);
+ getWakelockTimerLocked(wl, WAKE_TYPE_DRAW).readSummaryFromParcelLocked(in);
}
}
@@ -8416,10 +8461,57 @@ public class BatteryStatsImpl extends BatteryStats {
}
}
+ public StopwatchTimer getWakelockTimerLocked(Wakelock wl, int type) {
+ if (wl == null) {
+ return null;
+ }
+ switch (type) {
+ case WAKE_TYPE_PARTIAL: {
+ DualTimer t = wl.mTimerPartial;
+ if (t == null) {
+ t = new DualTimer(mBsi.mClocks, this, WAKE_TYPE_PARTIAL,
+ mBsi.mPartialTimers, mBsi.mOnBatteryScreenOffTimeBase,
+ mOnBatteryScreenOffBackgroundTimeBase);
+ wl.mTimerPartial = t;
+ }
+ return t;
+ }
+ case WAKE_TYPE_FULL: {
+ StopwatchTimer t = wl.mTimerFull;
+ if (t == null) {
+ t = new StopwatchTimer(mBsi.mClocks, this, WAKE_TYPE_FULL,
+ mBsi.mFullTimers, mBsi.mOnBatteryTimeBase);
+ wl.mTimerFull = t;
+ }
+ return t;
+ }
+ case WAKE_TYPE_WINDOW: {
+ StopwatchTimer t = wl.mTimerWindow;
+ if (t == null) {
+ t = new StopwatchTimer(mBsi.mClocks, this, WAKE_TYPE_WINDOW,
+ mBsi.mWindowTimers, mBsi.mOnBatteryTimeBase);
+ wl.mTimerWindow = t;
+ }
+ return t;
+ }
+ case WAKE_TYPE_DRAW: {
+ StopwatchTimer t = wl.mTimerDraw;
+ if (t == null) {
+ t = new StopwatchTimer(mBsi.mClocks, this, WAKE_TYPE_DRAW,
+ mBsi.mDrawTimers, mBsi.mOnBatteryTimeBase);
+ wl.mTimerDraw = t;
+ }
+ return t;
+ }
+ default:
+ throw new IllegalArgumentException("type=" + type);
+ }
+ }
+
public void noteStartWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) {
Wakelock wl = mWakelockStats.startObject(name);
if (wl != null) {
- wl.getStopwatchTimer(type).startRunningLocked(elapsedRealtimeMs);
+ getWakelockTimerLocked(wl, type).startRunningLocked(elapsedRealtimeMs);
}
if (type == WAKE_TYPE_PARTIAL) {
createAggregatedPartialWakelockTimerLocked().startRunningLocked(elapsedRealtimeMs);
@@ -8435,7 +8527,7 @@ public class BatteryStatsImpl extends BatteryStats {
public void noteStopWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) {
Wakelock wl = mWakelockStats.stopObject(name);
if (wl != null) {
- wl.getStopwatchTimer(type).stopRunningLocked(elapsedRealtimeMs);
+ getWakelockTimerLocked(wl, type).stopRunningLocked(elapsedRealtimeMs);
}
if (type == WAKE_TYPE_PARTIAL) {
if (mAggregatedPartialWakelockTimer != null) {
@@ -8613,27 +8705,25 @@ public class BatteryStatsImpl extends BatteryStats {
mPlatformIdleStateCallback = null;
}
- public void setPowerProfile(PowerProfile profile) {
- synchronized (this) {
- mPowerProfile = profile;
+ public void setPowerProfileLocked(PowerProfile profile) {
+ mPowerProfile = profile;
- // We need to initialize the KernelCpuSpeedReaders to read from
- // the first cpu of each core. Once we have the PowerProfile, we have access to this
- // information.
- final int numClusters = mPowerProfile.getNumCpuClusters();
- mKernelCpuSpeedReaders = new KernelCpuSpeedReader[numClusters];
- int firstCpuOfCluster = 0;
- for (int i = 0; i < numClusters; i++) {
- final int numSpeedSteps = mPowerProfile.getNumSpeedStepsInCpuCluster(i);
- mKernelCpuSpeedReaders[i] = new KernelCpuSpeedReader(firstCpuOfCluster,
- numSpeedSteps);
- firstCpuOfCluster += mPowerProfile.getNumCoresInCpuCluster(i);
- }
+ // We need to initialize the KernelCpuSpeedReaders to read from
+ // the first cpu of each core. Once we have the PowerProfile, we have access to this
+ // information.
+ final int numClusters = mPowerProfile.getNumCpuClusters();
+ mKernelCpuSpeedReaders = new KernelCpuSpeedReader[numClusters];
+ int firstCpuOfCluster = 0;
+ for (int i = 0; i < numClusters; i++) {
+ final int numSpeedSteps = mPowerProfile.getNumSpeedStepsInCpuCluster(i);
+ mKernelCpuSpeedReaders[i] = new KernelCpuSpeedReader(firstCpuOfCluster,
+ numSpeedSteps);
+ firstCpuOfCluster += mPowerProfile.getNumCoresInCpuCluster(i);
+ }
- if (mEstimatedBatteryCapacity == -1) {
- // Initialize the estimated battery capacity to a known preset one.
- mEstimatedBatteryCapacity = (int) mPowerProfile.getBatteryCapacity();
- }
+ if (mEstimatedBatteryCapacity == -1) {
+ // Initialize the estimated battery capacity to a known preset one.
+ mEstimatedBatteryCapacity = (int) mPowerProfile.getBatteryCapacity();
}
}
@@ -8641,7 +8731,7 @@ public class BatteryStatsImpl extends BatteryStats {
mCallback = cb;
}
- public void setRadioScanningTimeout(long timeout) {
+ public void setRadioScanningTimeoutLocked(long timeout) {
if (mPhoneSignalScanningTimer != null) {
mPhoneSignalScanningTimer.setTimeout(timeout);
}
@@ -9333,277 +9423,293 @@ public class BatteryStatsImpl extends BatteryStats {
}
}
- private String[] mMobileIfaces = EmptyArray.STRING;
+ private final NetworkStatsFactory mNetworkStatsFactory = new NetworkStatsFactory();
+ private final Pools.Pool<NetworkStats> mNetworkStatsPool = new Pools.SynchronizedPool<>(6);
+
+ private final Object mWifiNetworkLock = new Object();
+
+ @GuardedBy("mWifiNetworkLock")
private String[] mWifiIfaces = EmptyArray.STRING;
- private final NetworkStatsFactory mNetworkStatsFactory = new NetworkStatsFactory();
+ @GuardedBy("mWifiNetworkLock")
+ private NetworkStats mLastWifiNetworkStats = new NetworkStats(0, -1);
- private static final int NETWORK_STATS_LAST = 0;
- private static final int NETWORK_STATS_NEXT = 1;
- private static final int NETWORK_STATS_DELTA = 2;
+ private final Object mModemNetworkLock = new Object();
- private NetworkStats[] mMobileNetworkStats;
- private NetworkStats[] mWifiNetworkStats;
+ @GuardedBy("mModemNetworkLock")
+ private String[] mModemIfaces = EmptyArray.STRING;
- /**
- * Retrieves the delta of network stats for the given network ifaces. Uses networkStatsBuffer
- * as a buffer of NetworkStats objects to cycle through when computing deltas.
- */
- private NetworkStats getNetworkStatsDeltaLocked(String[] ifaces,
- NetworkStats[] networkStatsBuffer)
- throws IOException {
- if (!SystemProperties.getBoolean(NetworkManagementSocketTagger.PROP_QTAGUID_ENABLED,
- false)) {
- return null;
- }
+ @GuardedBy("mModemNetworkLock")
+ private NetworkStats mLastModemNetworkStats = new NetworkStats(0, -1);
- final NetworkStats stats = mNetworkStatsFactory.readNetworkStatsDetail(NetworkStats.UID_ALL,
- ifaces, NetworkStats.TAG_NONE, networkStatsBuffer[NETWORK_STATS_NEXT]);
- networkStatsBuffer[NETWORK_STATS_DELTA] = NetworkStats.subtract(stats,
- networkStatsBuffer[NETWORK_STATS_LAST], null, null,
- networkStatsBuffer[NETWORK_STATS_DELTA]);
- networkStatsBuffer[NETWORK_STATS_NEXT] = networkStatsBuffer[NETWORK_STATS_LAST];
- networkStatsBuffer[NETWORK_STATS_LAST] = stats;
- return networkStatsBuffer[NETWORK_STATS_DELTA];
+ private NetworkStats readNetworkStatsLocked(String[] ifaces) {
+ try {
+ if (!ArrayUtils.isEmpty(ifaces)) {
+ return mNetworkStatsFactory.readNetworkStatsDetail(NetworkStats.UID_ALL, ifaces,
+ NetworkStats.TAG_NONE, mNetworkStatsPool.acquire());
+ }
+ } catch (IOException e) {
+ Slog.e(TAG, "failed to read network stats for ifaces: " + Arrays.toString(ifaces));
+ }
+ return null;
}
/**
* Distribute WiFi energy info and network traffic to apps.
* @param info The energy information from the WiFi controller.
*/
- public void updateWifiStateLocked(@Nullable final WifiActivityEnergyInfo info) {
+ public void updateWifiState(@Nullable final WifiActivityEnergyInfo info) {
if (DEBUG_ENERGY) {
- Slog.d(TAG, "Updating wifi stats");
+ Slog.d(TAG, "Updating wifi stats: " + Arrays.toString(mWifiIfaces));
}
- final long elapsedRealtimeMs = mClocks.elapsedRealtime();
+ // Grab a separate lock to acquire the network stats, which may do I/O.
NetworkStats delta = null;
- try {
- if (!ArrayUtils.isEmpty(mWifiIfaces)) {
- delta = getNetworkStatsDeltaLocked(mWifiIfaces, mWifiNetworkStats);
+ synchronized (mWifiNetworkLock) {
+ final NetworkStats latestStats = readNetworkStatsLocked(mWifiIfaces);
+ if (latestStats != null) {
+ delta = NetworkStats.subtract(latestStats, mLastWifiNetworkStats, null, null,
+ mNetworkStatsPool.acquire());
+ mNetworkStatsPool.release(mLastWifiNetworkStats);
+ mLastWifiNetworkStats = latestStats;
}
- } catch (IOException e) {
- Slog.wtf(TAG, "Failed to get wifi network stats", e);
- return;
- }
-
- if (!mOnBatteryInternal) {
- return;
}
- SparseLongArray rxPackets = new SparseLongArray();
- SparseLongArray txPackets = new SparseLongArray();
- long totalTxPackets = 0;
- long totalRxPackets = 0;
- if (delta != null) {
- final int size = delta.size();
- for (int i = 0; i < size; i++) {
- final NetworkStats.Entry entry = delta.getValues(i, mTmpNetworkStatsEntry);
-
- if (DEBUG_ENERGY) {
- Slog.d(TAG, "Wifi uid " + entry.uid + ": delta rx=" + entry.rxBytes
- + " tx=" + entry.txBytes + " rxPackets=" + entry.rxPackets
- + " txPackets=" + entry.txPackets);
+ synchronized (this) {
+ if (!mOnBatteryInternal) {
+ if (delta != null) {
+ mNetworkStatsPool.release(delta);
}
+ return;
+ }
- if (entry.rxBytes == 0 && entry.txBytes == 0) {
- // Skip the lookup below since there is no work to do.
- continue;
- }
+ final long elapsedRealtimeMs = mClocks.elapsedRealtime();
+ SparseLongArray rxPackets = new SparseLongArray();
+ SparseLongArray txPackets = new SparseLongArray();
+ long totalTxPackets = 0;
+ long totalRxPackets = 0;
+ if (delta != null) {
+ NetworkStats.Entry entry = new NetworkStats.Entry();
+ final int size = delta.size();
+ for (int i = 0; i < size; i++) {
+ entry = delta.getValues(i, entry);
- final Uid u = getUidStatsLocked(mapUid(entry.uid));
- if (entry.rxBytes != 0) {
- u.noteNetworkActivityLocked(NETWORK_WIFI_RX_DATA, entry.rxBytes,
- entry.rxPackets);
- if (entry.set == NetworkStats.SET_DEFAULT) { // Background transfers
- u.noteNetworkActivityLocked(NETWORK_WIFI_BG_RX_DATA, entry.rxBytes,
- entry.rxPackets);
+ if (DEBUG_ENERGY) {
+ Slog.d(TAG, "Wifi uid " + entry.uid + ": delta rx=" + entry.rxBytes
+ + " tx=" + entry.txBytes + " rxPackets=" + entry.rxPackets
+ + " txPackets=" + entry.txPackets);
}
- mNetworkByteActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked(
- entry.rxBytes);
- mNetworkPacketActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked(
- entry.rxPackets);
-
- rxPackets.put(u.getUid(), entry.rxPackets);
- // Sum the total number of packets so that the Rx Power can
- // be evenly distributed amongst the apps.
- totalRxPackets += entry.rxPackets;
- }
-
- if (entry.txBytes != 0) {
- u.noteNetworkActivityLocked(NETWORK_WIFI_TX_DATA, entry.txBytes,
- entry.txPackets);
- if (entry.set == NetworkStats.SET_DEFAULT) { // Background transfers
- u.noteNetworkActivityLocked(NETWORK_WIFI_BG_TX_DATA, entry.txBytes,
- entry.txPackets);
+ if (entry.rxBytes == 0 && entry.txBytes == 0) {
+ // Skip the lookup below since there is no work to do.
+ continue;
}
- mNetworkByteActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked(
- entry.txBytes);
- mNetworkPacketActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked(
- entry.txPackets);
- txPackets.put(u.getUid(), entry.txPackets);
+ final Uid u = getUidStatsLocked(mapUid(entry.uid));
+ if (entry.rxBytes != 0) {
+ u.noteNetworkActivityLocked(NETWORK_WIFI_RX_DATA, entry.rxBytes,
+ entry.rxPackets);
+ if (entry.set == NetworkStats.SET_DEFAULT) { // Background transfers
+ u.noteNetworkActivityLocked(NETWORK_WIFI_BG_RX_DATA, entry.rxBytes,
+ entry.rxPackets);
+ }
+ mNetworkByteActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked(
+ entry.rxBytes);
+ mNetworkPacketActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked(
+ entry.rxPackets);
- // Sum the total number of packets so that the Tx Power can
- // be evenly distributed amongst the apps.
- totalTxPackets += entry.txPackets;
- }
- }
- }
+ rxPackets.put(u.getUid(), entry.rxPackets);
- if (info != null) {
- mHasWifiReporting = true;
+ // Sum the total number of packets so that the Rx Power can
+ // be evenly distributed amongst the apps.
+ totalRxPackets += entry.rxPackets;
+ }
- // Measured in mAms
- final long txTimeMs = info.getControllerTxTimeMillis();
- final long rxTimeMs = info.getControllerRxTimeMillis();
- final long idleTimeMs = info.getControllerIdleTimeMillis();
- final long totalTimeMs = txTimeMs + rxTimeMs + idleTimeMs;
+ if (entry.txBytes != 0) {
+ u.noteNetworkActivityLocked(NETWORK_WIFI_TX_DATA, entry.txBytes,
+ entry.txPackets);
+ if (entry.set == NetworkStats.SET_DEFAULT) { // Background transfers
+ u.noteNetworkActivityLocked(NETWORK_WIFI_BG_TX_DATA, entry.txBytes,
+ entry.txPackets);
+ }
+ mNetworkByteActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked(
+ entry.txBytes);
+ mNetworkPacketActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked(
+ entry.txPackets);
- long leftOverRxTimeMs = rxTimeMs;
- long leftOverTxTimeMs = txTimeMs;
+ txPackets.put(u.getUid(), entry.txPackets);
- if (DEBUG_ENERGY) {
- Slog.d(TAG, "------ BEGIN WiFi power blaming ------");
- Slog.d(TAG, " Tx Time: " + txTimeMs + " ms");
- Slog.d(TAG, " Rx Time: " + rxTimeMs + " ms");
- Slog.d(TAG, " Idle Time: " + idleTimeMs + " ms");
- Slog.d(TAG, " Total Time: " + totalTimeMs + " ms");
+ // Sum the total number of packets so that the Tx Power can
+ // be evenly distributed amongst the apps.
+ totalTxPackets += entry.txPackets;
+ }
+ }
+ mNetworkStatsPool.release(delta);
+ delta = null;
}
- long totalWifiLockTimeMs = 0;
- long totalScanTimeMs = 0;
-
- // On the first pass, collect some totals so that we can normalize power
- // calculations if we need to.
- final int uidStatsSize = mUidStats.size();
- for (int i = 0; i < uidStatsSize; i++) {
- final Uid uid = mUidStats.valueAt(i);
+ if (info != null) {
+ mHasWifiReporting = true;
- // Sum the total scan power for all apps.
- totalScanTimeMs += uid.mWifiScanTimer.getTimeSinceMarkLocked(
- elapsedRealtimeMs * 1000) / 1000;
+ // Measured in mAms
+ final long txTimeMs = info.getControllerTxTimeMillis();
+ final long rxTimeMs = info.getControllerRxTimeMillis();
+ final long idleTimeMs = info.getControllerIdleTimeMillis();
+ final long totalTimeMs = txTimeMs + rxTimeMs + idleTimeMs;
- // Sum the total time holding wifi lock for all apps.
- totalWifiLockTimeMs += uid.mFullWifiLockTimer.getTimeSinceMarkLocked(
- elapsedRealtimeMs * 1000) / 1000;
- }
-
- if (DEBUG_ENERGY && totalScanTimeMs > rxTimeMs) {
- Slog.d(TAG, " !Estimated scan time > Actual rx time (" + totalScanTimeMs + " ms > "
- + rxTimeMs + " ms). Normalizing scan time.");
- }
- if (DEBUG_ENERGY && totalScanTimeMs > txTimeMs) {
- Slog.d(TAG, " !Estimated scan time > Actual tx time (" + totalScanTimeMs + " ms > "
- + txTimeMs + " ms). Normalizing scan time.");
- }
+ long leftOverRxTimeMs = rxTimeMs;
+ long leftOverTxTimeMs = txTimeMs;
- // Actually assign and distribute power usage to apps.
- for (int i = 0; i < uidStatsSize; i++) {
- final Uid uid = mUidStats.valueAt(i);
-
- long scanTimeSinceMarkMs = uid.mWifiScanTimer.getTimeSinceMarkLocked(
- elapsedRealtimeMs * 1000) / 1000;
- if (scanTimeSinceMarkMs > 0) {
- // Set the new mark so that next time we get new data since this point.
- uid.mWifiScanTimer.setMark(elapsedRealtimeMs);
+ if (DEBUG_ENERGY) {
+ Slog.d(TAG, "------ BEGIN WiFi power blaming ------");
+ Slog.d(TAG, " Tx Time: " + txTimeMs + " ms");
+ Slog.d(TAG, " Rx Time: " + rxTimeMs + " ms");
+ Slog.d(TAG, " Idle Time: " + idleTimeMs + " ms");
+ Slog.d(TAG, " Total Time: " + totalTimeMs + " ms");
+ }
+
+ long totalWifiLockTimeMs = 0;
+ long totalScanTimeMs = 0;
+
+ // On the first pass, collect some totals so that we can normalize power
+ // calculations if we need to.
+ final int uidStatsSize = mUidStats.size();
+ for (int i = 0; i < uidStatsSize; i++) {
+ final Uid uid = mUidStats.valueAt(i);
+
+ // Sum the total scan power for all apps.
+ totalScanTimeMs += uid.mWifiScanTimer.getTimeSinceMarkLocked(
+ elapsedRealtimeMs * 1000) / 1000;
+
+ // Sum the total time holding wifi lock for all apps.
+ totalWifiLockTimeMs += uid.mFullWifiLockTimer.getTimeSinceMarkLocked(
+ elapsedRealtimeMs * 1000) / 1000;
+ }
+
+ if (DEBUG_ENERGY && totalScanTimeMs > rxTimeMs) {
+ Slog.d(TAG,
+ " !Estimated scan time > Actual rx time (" + totalScanTimeMs + " ms > "
+ + rxTimeMs + " ms). Normalizing scan time.");
+ }
+ if (DEBUG_ENERGY && totalScanTimeMs > txTimeMs) {
+ Slog.d(TAG,
+ " !Estimated scan time > Actual tx time (" + totalScanTimeMs + " ms > "
+ + txTimeMs + " ms). Normalizing scan time.");
+ }
+
+ // Actually assign and distribute power usage to apps.
+ for (int i = 0; i < uidStatsSize; i++) {
+ final Uid uid = mUidStats.valueAt(i);
+
+ long scanTimeSinceMarkMs = uid.mWifiScanTimer.getTimeSinceMarkLocked(
+ elapsedRealtimeMs * 1000) / 1000;
+ if (scanTimeSinceMarkMs > 0) {
+ // Set the new mark so that next time we get new data since this point.
+ uid.mWifiScanTimer.setMark(elapsedRealtimeMs);
+
+ long scanRxTimeSinceMarkMs = scanTimeSinceMarkMs;
+ long scanTxTimeSinceMarkMs = scanTimeSinceMarkMs;
+
+ // Our total scan time is more than the reported Tx/Rx time.
+ // This is possible because the cost of a scan is approximate.
+ // Let's normalize the result so that we evenly blame each app
+ // scanning.
+ //
+ // This means that we may have apps that transmitted/received packets not be
+ // blamed for this, but this is fine as scans are relatively more expensive.
+ if (totalScanTimeMs > rxTimeMs) {
+ scanRxTimeSinceMarkMs = (rxTimeMs * scanRxTimeSinceMarkMs) /
+ totalScanTimeMs;
+ }
+ if (totalScanTimeMs > txTimeMs) {
+ scanTxTimeSinceMarkMs = (txTimeMs * scanTxTimeSinceMarkMs) /
+ totalScanTimeMs;
+ }
- long scanRxTimeSinceMarkMs = scanTimeSinceMarkMs;
- long scanTxTimeSinceMarkMs = scanTimeSinceMarkMs;
+ if (DEBUG_ENERGY) {
+ Slog.d(TAG, " ScanTime for UID " + uid.getUid() + ": Rx:"
+ + scanRxTimeSinceMarkMs + " ms Tx:"
+ + scanTxTimeSinceMarkMs + " ms)");
+ }
- // Our total scan time is more than the reported Tx/Rx time.
- // This is possible because the cost of a scan is approximate.
- // Let's normalize the result so that we evenly blame each app
- // scanning.
- //
- // This means that we may have apps that transmitted/received packets not be
- // blamed for this, but this is fine as scans are relatively more expensive.
- if (totalScanTimeMs > rxTimeMs) {
- scanRxTimeSinceMarkMs = (rxTimeMs * scanRxTimeSinceMarkMs) /
- totalScanTimeMs;
- }
- if (totalScanTimeMs > txTimeMs) {
- scanTxTimeSinceMarkMs = (txTimeMs * scanTxTimeSinceMarkMs) /
- totalScanTimeMs;
+ ControllerActivityCounterImpl activityCounter =
+ uid.getOrCreateWifiControllerActivityLocked();
+ activityCounter.getRxTimeCounter().addCountLocked(scanRxTimeSinceMarkMs);
+ activityCounter.getTxTimeCounters()[0].addCountLocked(
+ scanTxTimeSinceMarkMs);
+ leftOverRxTimeMs -= scanRxTimeSinceMarkMs;
+ leftOverTxTimeMs -= scanTxTimeSinceMarkMs;
}
- if (DEBUG_ENERGY) {
- Slog.d(TAG, " ScanTime for UID " + uid.getUid() + ": Rx:"
- + scanRxTimeSinceMarkMs + " ms Tx:"
- + scanTxTimeSinceMarkMs + " ms)");
+ // Distribute evenly the power consumed while Idle to each app holding a WiFi
+ // lock.
+ final long wifiLockTimeSinceMarkMs =
+ uid.mFullWifiLockTimer.getTimeSinceMarkLocked(
+ elapsedRealtimeMs * 1000) / 1000;
+ if (wifiLockTimeSinceMarkMs > 0) {
+ // Set the new mark so that next time we get new data since this point.
+ uid.mFullWifiLockTimer.setMark(elapsedRealtimeMs);
+
+ final long myIdleTimeMs = (wifiLockTimeSinceMarkMs * idleTimeMs)
+ / totalWifiLockTimeMs;
+ if (DEBUG_ENERGY) {
+ Slog.d(TAG, " IdleTime for UID " + uid.getUid() + ": "
+ + myIdleTimeMs + " ms");
+ }
+ uid.getOrCreateWifiControllerActivityLocked().getIdleTimeCounter()
+ .addCountLocked(myIdleTimeMs);
}
-
- ControllerActivityCounterImpl activityCounter =
- uid.getOrCreateWifiControllerActivityLocked();
- activityCounter.getRxTimeCounter().addCountLocked(scanRxTimeSinceMarkMs);
- activityCounter.getTxTimeCounters()[0].addCountLocked(scanTxTimeSinceMarkMs);
- leftOverRxTimeMs -= scanRxTimeSinceMarkMs;
- leftOverTxTimeMs -= scanTxTimeSinceMarkMs;
}
- // Distribute evenly the power consumed while Idle to each app holding a WiFi
- // lock.
- final long wifiLockTimeSinceMarkMs = uid.mFullWifiLockTimer.getTimeSinceMarkLocked(
- elapsedRealtimeMs * 1000) / 1000;
- if (wifiLockTimeSinceMarkMs > 0) {
- // Set the new mark so that next time we get new data since this point.
- uid.mFullWifiLockTimer.setMark(elapsedRealtimeMs);
+ if (DEBUG_ENERGY) {
+ Slog.d(TAG, " New RxPower: " + leftOverRxTimeMs + " ms");
+ Slog.d(TAG, " New TxPower: " + leftOverTxTimeMs + " ms");
+ }
- final long myIdleTimeMs = (wifiLockTimeSinceMarkMs * idleTimeMs)
- / totalWifiLockTimeMs;
+ // 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 long myTxTimeMs = (txPackets.valueAt(i) * leftOverTxTimeMs)
+ / totalTxPackets;
if (DEBUG_ENERGY) {
- Slog.d(TAG, " IdleTime for UID " + uid.getUid() + ": "
- + myIdleTimeMs + " ms");
+ Slog.d(TAG, " TxTime for UID " + uid.getUid() + ": " + myTxTimeMs + " ms");
}
- uid.getOrCreateWifiControllerActivityLocked().getIdleTimeCounter()
- .addCountLocked(myIdleTimeMs);
+ uid.getOrCreateWifiControllerActivityLocked().getTxTimeCounters()[0]
+ .addCountLocked(myTxTimeMs);
}
- }
-
- if (DEBUG_ENERGY) {
- Slog.d(TAG, " New RxPower: " + leftOverRxTimeMs + " ms");
- Slog.d(TAG, " New TxPower: " + leftOverTxTimeMs + " ms");
- }
- // 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 long myTxTimeMs = (txPackets.valueAt(i) * leftOverTxTimeMs) / totalTxPackets;
- if (DEBUG_ENERGY) {
- Slog.d(TAG, " TxTime for UID " + uid.getUid() + ": " + myTxTimeMs + " ms");
+ // 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 long myRxTimeMs = (rxPackets.valueAt(i) * leftOverRxTimeMs)
+ / totalRxPackets;
+ if (DEBUG_ENERGY) {
+ Slog.d(TAG, " RxTime for UID " + uid.getUid() + ": " + myRxTimeMs + " ms");
+ }
+ uid.getOrCreateWifiControllerActivityLocked().getRxTimeCounter()
+ .addCountLocked(myRxTimeMs);
}
- uid.getOrCreateWifiControllerActivityLocked().getTxTimeCounters()[0]
- .addCountLocked(myTxTimeMs);
- }
- // 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 long myRxTimeMs = (rxPackets.valueAt(i) * leftOverRxTimeMs) / totalRxPackets;
- if (DEBUG_ENERGY) {
- Slog.d(TAG, " RxTime for UID " + uid.getUid() + ": " + myRxTimeMs + " ms");
- }
- uid.getOrCreateWifiControllerActivityLocked().getRxTimeCounter()
- .addCountLocked(myRxTimeMs);
- }
+ // Any left over power use will be picked up by the WiFi category in BatteryStatsHelper.
- // Any left over power use will be picked up by the WiFi category in BatteryStatsHelper.
- // Update WiFi controller stats.
- mWifiActivity.getRxTimeCounter().addCountLocked(info.getControllerRxTimeMillis());
- mWifiActivity.getTxTimeCounters()[0].addCountLocked(info.getControllerTxTimeMillis());
- mWifiActivity.getIdleTimeCounter().addCountLocked(info.getControllerIdleTimeMillis());
+ // Update WiFi controller stats.
+ mWifiActivity.getRxTimeCounter().addCountLocked(info.getControllerRxTimeMillis());
+ mWifiActivity.getTxTimeCounters()[0].addCountLocked(
+ info.getControllerTxTimeMillis());
+ mWifiActivity.getIdleTimeCounter().addCountLocked(
+ info.getControllerIdleTimeMillis());
- // POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V.
- final double opVolt = mPowerProfile.getAveragePower(
- PowerProfile.POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE) / 1000.0;
- if (opVolt != 0) {
- // We store the power drain as mAms.
- mWifiActivity.getPowerCounter().addCountLocked(
- (long)(info.getControllerEnergyUsed() / opVolt));
+ // POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V.
+ final double opVolt = mPowerProfile.getAveragePower(
+ PowerProfile.POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE) / 1000.0;
+ if (opVolt != 0) {
+ // We store the power drain as mAms.
+ mWifiActivity.getPowerCounter().addCountLocked(
+ (long) (info.getControllerEnergyUsed() / opVolt));
+ }
}
}
}
@@ -9611,133 +9717,148 @@ public class BatteryStatsImpl extends BatteryStats {
/**
* Distribute Cell radio energy info and network traffic to apps.
*/
- public void updateMobileRadioStateLocked(final long elapsedRealtimeMs,
- final ModemActivityInfo activityInfo) {
+ public void updateMobileRadioState(@Nullable final ModemActivityInfo activityInfo) {
if (DEBUG_ENERGY) {
Slog.d(TAG, "Updating mobile radio stats with " + activityInfo);
}
+ // Grab a separate lock to acquire the network stats, which may do I/O.
NetworkStats delta = null;
- try {
- if (!ArrayUtils.isEmpty(mMobileIfaces)) {
- delta = getNetworkStatsDeltaLocked(mMobileIfaces, mMobileNetworkStats);
+ synchronized (mModemNetworkLock) {
+ final NetworkStats latestStats = readNetworkStatsLocked(mModemIfaces);
+ if (latestStats != null) {
+ delta = NetworkStats.subtract(latestStats, mLastModemNetworkStats, null, null,
+ mNetworkStatsPool.acquire());
+ mNetworkStatsPool.release(mLastModemNetworkStats);
+ mLastModemNetworkStats = latestStats;
}
- } catch (IOException e) {
- Slog.wtf(TAG, "Failed to get mobile network stats", e);
- return;
- }
-
- if (!mOnBatteryInternal) {
- return;
}
- long radioTime = mMobileRadioActivePerAppTimer.getTimeSinceMarkLocked(
- elapsedRealtimeMs * 1000);
- mMobileRadioActivePerAppTimer.setMark(elapsedRealtimeMs);
-
- long totalRxPackets = 0;
- long totalTxPackets = 0;
- if (delta != null) {
- final int size = delta.size();
- for (int i = 0; i < size; i++) {
- final NetworkStats.Entry entry = delta.getValues(i, mTmpNetworkStatsEntry);
- if (entry.rxPackets == 0 && entry.txPackets == 0) {
- continue;
- }
-
- if (DEBUG_ENERGY) {
- Slog.d(TAG, "Mobile uid " + entry.uid + ": delta rx=" + entry.rxBytes
- + " tx=" + entry.txBytes + " rxPackets=" + entry.rxPackets
- + " txPackets=" + entry.txPackets);
- }
-
- totalRxPackets += entry.rxPackets;
- totalTxPackets += entry.txPackets;
-
- final Uid u = getUidStatsLocked(mapUid(entry.uid));
- u.noteNetworkActivityLocked(NETWORK_MOBILE_RX_DATA, entry.rxBytes, entry.rxPackets);
- u.noteNetworkActivityLocked(NETWORK_MOBILE_TX_DATA, entry.txBytes, entry.txPackets);
- if (entry.set == NetworkStats.SET_DEFAULT) { // Background transfers
- u.noteNetworkActivityLocked(NETWORK_MOBILE_BG_RX_DATA,
- entry.rxBytes, entry.rxPackets);
- u.noteNetworkActivityLocked(NETWORK_MOBILE_BG_TX_DATA,
- entry.txBytes, entry.txPackets);
+ synchronized (this) {
+ if (!mOnBatteryInternal) {
+ if (delta != null) {
+ mNetworkStatsPool.release(delta);
}
-
- mNetworkByteActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked(
- entry.rxBytes);
- mNetworkByteActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked(
- entry.txBytes);
- mNetworkPacketActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked(
- entry.rxPackets);
- mNetworkPacketActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked(
- entry.txPackets);
+ return;
}
- // Now distribute proportional blame to the apps that did networking.
- long totalPackets = totalRxPackets + totalTxPackets;
- if (totalPackets > 0) {
+ final long elapsedRealtimeMs = SystemClock.elapsedRealtime();
+ long radioTime = mMobileRadioActivePerAppTimer.getTimeSinceMarkLocked(
+ elapsedRealtimeMs * 1000);
+ mMobileRadioActivePerAppTimer.setMark(elapsedRealtimeMs);
+
+ long totalRxPackets = 0;
+ long totalTxPackets = 0;
+ if (delta != null) {
+ NetworkStats.Entry entry = new NetworkStats.Entry();
+ final int size = delta.size();
for (int i = 0; i < size; i++) {
- final NetworkStats.Entry entry = delta.getValues(i, mTmpNetworkStatsEntry);
+ entry = delta.getValues(i, entry);
if (entry.rxPackets == 0 && entry.txPackets == 0) {
continue;
}
- final Uid u = getUidStatsLocked(mapUid(entry.uid));
+ if (DEBUG_ENERGY) {
+ Slog.d(TAG, "Mobile uid " + entry.uid + ": delta rx=" + entry.rxBytes
+ + " tx=" + entry.txBytes + " rxPackets=" + entry.rxPackets
+ + " txPackets=" + entry.txPackets);
+ }
- // 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);
+ totalRxPackets += entry.rxPackets;
+ totalTxPackets += entry.txPackets;
+
+ final Uid u = getUidStatsLocked(mapUid(entry.uid));
+ u.noteNetworkActivityLocked(NETWORK_MOBILE_RX_DATA, entry.rxBytes,
+ entry.rxPackets);
+ u.noteNetworkActivityLocked(NETWORK_MOBILE_TX_DATA, entry.txBytes,
+ entry.txPackets);
+ if (entry.set == NetworkStats.SET_DEFAULT) { // Background transfers
+ u.noteNetworkActivityLocked(NETWORK_MOBILE_BG_RX_DATA,
+ entry.rxBytes, entry.rxPackets);
+ u.noteNetworkActivityLocked(NETWORK_MOBILE_BG_TX_DATA,
+ entry.txBytes, entry.txPackets);
+ }
- // Remove this app from the totals, so that we don't lose any time
- // due to rounding.
- radioTime -= appRadioTime;
- totalPackets -= appPackets;
+ mNetworkByteActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked(
+ entry.rxBytes);
+ mNetworkByteActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked(
+ entry.txBytes);
+ mNetworkPacketActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked(
+ entry.rxPackets);
+ mNetworkPacketActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked(
+ entry.txPackets);
+ }
- if (activityInfo != null) {
- ControllerActivityCounterImpl activityCounter =
- u.getOrCreateModemControllerActivityLocked();
- if (totalRxPackets > 0 && entry.rxPackets > 0) {
- final long rxMs = (entry.rxPackets * activityInfo.getRxTimeMillis())
- / totalRxPackets;
- activityCounter.getRxTimeCounter().addCountLocked(rxMs);
+ // Now distribute proportional blame to the apps that did networking.
+ long totalPackets = totalRxPackets + totalTxPackets;
+ if (totalPackets > 0) {
+ for (int i = 0; i < size; i++) {
+ entry = delta.getValues(i, entry);
+ if (entry.rxPackets == 0 && entry.txPackets == 0) {
+ continue;
}
- if (totalTxPackets > 0 && entry.txPackets > 0) {
- for (int lvl = 0; lvl < ModemActivityInfo.TX_POWER_LEVELS; lvl++) {
- long txMs = entry.txPackets * activityInfo.getTxTimeMillis()[lvl];
- txMs /= totalTxPackets;
- activityCounter.getTxTimeCounters()[lvl].addCountLocked(txMs);
+ final Uid u = getUidStatsLocked(mapUid(entry.uid));
+
+ // 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);
+
+ // Remove this app from the totals, so that we don't lose any time
+ // due to rounding.
+ radioTime -= appRadioTime;
+ totalPackets -= appPackets;
+
+ if (activityInfo != null) {
+ ControllerActivityCounterImpl activityCounter =
+ u.getOrCreateModemControllerActivityLocked();
+ if (totalRxPackets > 0 && entry.rxPackets > 0) {
+ final long rxMs = (entry.rxPackets * activityInfo.getRxTimeMillis())
+ / totalRxPackets;
+ activityCounter.getRxTimeCounter().addCountLocked(rxMs);
+ }
+
+ if (totalTxPackets > 0 && entry.txPackets > 0) {
+ for (int lvl = 0; lvl < ModemActivityInfo.TX_POWER_LEVELS; lvl++) {
+ long txMs =
+ entry.txPackets * activityInfo.getTxTimeMillis()[lvl];
+ txMs /= totalTxPackets;
+ activityCounter.getTxTimeCounters()[lvl].addCountLocked(txMs);
+ }
}
}
}
}
- }
- if (radioTime > 0) {
- // Whoops, there is some radio time we can't blame on an app!
- mMobileRadioActiveUnknownTime.addCountLocked(radioTime);
- mMobileRadioActiveUnknownCount.addCountLocked(1);
- }
- }
+ if (radioTime > 0) {
+ // Whoops, there is some radio time we can't blame on an app!
+ mMobileRadioActiveUnknownTime.addCountLocked(radioTime);
+ mMobileRadioActiveUnknownCount.addCountLocked(1);
+ }
- if (activityInfo != null) {
- mHasModemReporting = true;
- mModemActivity.getIdleTimeCounter().addCountLocked(activityInfo.getIdleTimeMillis());
- mModemActivity.getRxTimeCounter().addCountLocked(activityInfo.getRxTimeMillis());
- for (int lvl = 0; lvl < ModemActivityInfo.TX_POWER_LEVELS; lvl++) {
- mModemActivity.getTxTimeCounters()[lvl]
- .addCountLocked(activityInfo.getTxTimeMillis()[lvl]);
+ mNetworkStatsPool.release(delta);
+ delta = null;
}
- // POWER_MODEM_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V.
- final double opVolt = mPowerProfile.getAveragePower(
- PowerProfile.POWER_MODEM_CONTROLLER_OPERATING_VOLTAGE) / 1000.0;
- if (opVolt != 0) {
- // We store the power drain as mAms.
- mModemActivity.getPowerCounter().addCountLocked(
- (long) (activityInfo.getEnergyUsed() / opVolt));
+ if (activityInfo != null) {
+ mHasModemReporting = true;
+ mModemActivity.getIdleTimeCounter().addCountLocked(
+ activityInfo.getIdleTimeMillis());
+ mModemActivity.getRxTimeCounter().addCountLocked(activityInfo.getRxTimeMillis());
+ for (int lvl = 0; lvl < ModemActivityInfo.TX_POWER_LEVELS; lvl++) {
+ mModemActivity.getTxTimeCounters()[lvl]
+ .addCountLocked(activityInfo.getTxTimeMillis()[lvl]);
+ }
+
+ // POWER_MODEM_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V.
+ final double opVolt = mPowerProfile.getAveragePower(
+ PowerProfile.POWER_MODEM_CONTROLLER_OPERATING_VOLTAGE) / 1000.0;
+ if (opVolt != 0) {
+ // We store the power drain as mAms.
+ mModemActivity.getPowerCounter().addCountLocked(
+ (long) (activityInfo.getEnergyUsed() / opVolt));
+ }
}
}
}
@@ -11380,8 +11501,14 @@ public class BatteryStatsImpl extends BatteryStats {
u.createBluetoothScanTimerLocked().readSummaryFromParcelLocked(in);
}
if (in.readInt() != 0) {
+ u.createBluetoothUnoptimizedScanTimerLocked().readSummaryFromParcelLocked(in);
+ }
+ if (in.readInt() != 0) {
u.createBluetoothScanResultCounterLocked().readSummaryFromParcelLocked(in);
}
+ if (in.readInt() != 0) {
+ u.createBluetoothScanResultBgCounterLocked().readSummaryFromParcelLocked(in);
+ }
u.mProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT;
for (int i = 0; i < Uid.NUM_PROCESS_STATE; i++) {
if (in.readInt() != 0) {
@@ -11789,12 +11916,24 @@ public class BatteryStatsImpl extends BatteryStats {
} else {
out.writeInt(0);
}
+ if (u.mBluetoothUnoptimizedScanTimer != null) {
+ out.writeInt(1);
+ u.mBluetoothUnoptimizedScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
+ } else {
+ out.writeInt(0);
+ }
if (u.mBluetoothScanResultCounter != null) {
out.writeInt(1);
u.mBluetoothScanResultCounter.writeSummaryFromParcelLocked(out);
} else {
out.writeInt(0);
}
+ if (u.mBluetoothScanResultBgCounter != null) {
+ out.writeInt(1);
+ u.mBluetoothScanResultBgCounter.writeSummaryFromParcelLocked(out);
+ } else {
+ out.writeInt(0);
+ }
for (int i = 0; i < Uid.NUM_PROCESS_STATE; i++) {
if (u.mProcessStateTimer[i] != null) {
out.writeInt(1);
diff --git a/core/java/com/android/internal/util/DumpUtils.java b/core/java/com/android/internal/util/DumpUtils.java
index ce89501c970a..66b777e8e8e6 100644
--- a/core/java/com/android/internal/util/DumpUtils.java
+++ b/core/java/com/android/internal/util/DumpUtils.java
@@ -31,7 +31,7 @@ import java.io.StringWriter;
*/
public final class DumpUtils {
private static final String TAG = "DumpUtils";
- private static final boolean DEBUG = true;
+ private static final boolean DEBUG = false;
private DumpUtils() {
}
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 369bb7f7b157..785fd2c4dd4f 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -16,7 +16,7 @@
#define ATRACE_TAG ATRACE_TAG_DALVIK
#define LOG_TAG "AndroidRuntime"
-//#define LOG_NDEBUG 0
+#define LOG_NDEBUG 1
#include <android_runtime/AndroidRuntime.h>
#include <binder/IBinder.h>
@@ -661,7 +661,7 @@ int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote)
checkJni = true;
}
}
- ALOGD("CheckJNI is %s\n", checkJni ? "ON" : "OFF");
+ ALOGV("CheckJNI is %s\n", checkJni ? "ON" : "OFF");
if (checkJni) {
/* extended JNI checking */
addOption("-Xcheck:jni");
diff --git a/core/jni/android_hardware_Radio.cpp b/core/jni/android_hardware_Radio.cpp
index b6b1ac75f0e9..18cf8caa9672 100644
--- a/core/jni/android_hardware_Radio.cpp
+++ b/core/jni/android_hardware_Radio.cpp
@@ -15,7 +15,7 @@
** limitations under the License.
*/
-//#define LOG_NDEBUG 0
+#define LOG_NDEBUG 1
#define LOG_TAG "Radio-JNI"
#include <utils/Log.h>
@@ -955,7 +955,7 @@ int register_android_hardware_Radio(JNIEnv *env)
int ret = RegisterMethodsOrDie(env, kRadioModuleClassPathName, gModuleMethods, NELEM(gModuleMethods));
- ALOGI("%s DONE", __FUNCTION__);
+ ALOGV("%s DONE", __FUNCTION__);
return ret;
}
diff --git a/core/proto/android/providers/settings.proto b/core/proto/android/providers/settings.proto
index 8b73daf47f0f..e212c432558c 100644
--- a/core/proto/android/providers/settings.proto
+++ b/core/proto/android/providers/settings.proto
@@ -310,7 +310,7 @@ message GlobalSettingsProto {
SettingProto lte_service_forced = 265;
SettingProto ephemeral_cookie_max_size_bytes = 266;
SettingProto enable_ephemeral_feature = 267;
- SettingProto uninstalled_ephemeral_app_cache_duration_millis = 268;
+ SettingProto installed_instant_app_min_cache_period = 268;
SettingProto allow_user_switching_when_system_user_locked = 269;
SettingProto boot_count = 270;
SettingProto safe_boot_disallowed = 271;
@@ -331,6 +331,10 @@ message GlobalSettingsProto {
SettingProto network_recommendations_package = 286;
SettingProto bluetooth_a2dp_supports_optional_codecs_prefix = 287;
SettingProto bluetooth_a2dp_optional_codecs_enabled_prefix = 288;
+ SettingProto installed_instant_app_max_cache_period = 289;
+ SettingProto uninstalled_instant_app_min_cache_period = 290;
+ SettingProto uninstalled_instant_app_max_cache_period = 291;
+ SettingProto unused_static_shared_lib_min_cache_period = 292;
}
message SecureSettingsProto {
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 3c42334be445..7e5a0816cba8 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -703,7 +703,7 @@
<string name="relationTypeFriend" msgid="7313106762483391262">"صديق"</string>
<string name="relationTypeManager" msgid="6365677861610137895">"مدير"</string>
<string name="relationTypeMother" msgid="4578571352962758304">"أم"</string>
- <string name="relationTypeParent" msgid="4755635567562925226">"الأبوان"</string>
+ <string name="relationTypeParent" msgid="4755635567562925226">"الوالدان"</string>
<string name="relationTypePartner" msgid="7266490285120262781">"شريك"</string>
<string name="relationTypeReferredBy" msgid="101573059844135524">"جهة الإحالة"</string>
<string name="relationTypeRelative" msgid="1799819930085610271">"قريب"</string>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 649cadd400d4..06e60202d231 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -28,15 +28,15 @@
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> dana"</string>
- <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> dan <xliff:g id="HOURS">%2$d</xliff:g> sati"</string>
- <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> dan <xliff:g id="HOURS">%2$d</xliff:g> sat"</string>
+ <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> d i <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
+ <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> d i <xliff:g id="HOURS">%2$d</xliff:g> h"</string>
<string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> sati"</string>
- <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> sat <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
- <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> sat <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
+ <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> h i <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
+ <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> h i <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
<string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
<string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
- <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> sek"</string>
- <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> sek"</string>
+ <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> min i <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
+ <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min i <xliff:g id="SECONDS">%2$d</xliff:g> s"</string>
<string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> sek"</string>
<string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> sek"</string>
<string name="untitled" msgid="4638956954852782576">"&lt;Bez naslova&gt;"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index c644866b7e7a..c5774cf3e1a7 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -1116,7 +1116,7 @@
<string name="wifi_no_internet" msgid="8451173622563841546">"La Wi-Fi no té accés a Internet"</string>
<string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Toca per veure les opcions"</string>
<string name="network_switch_metered" msgid="4671730921726992671">"Actualment en ús: <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string>
- <string name="network_switch_metered_detail" msgid="5325661434777870353">"El dispositiu utilitza <xliff:g id="NEW_NETWORK">%1$s</xliff:g> en cas que <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> no tingui accés a Internet. És possible que s\'apliquin càrrecs."</string>
+ <string name="network_switch_metered_detail" msgid="5325661434777870353">"El dispositiu utilitza <xliff:g id="NEW_NETWORK">%1$s</xliff:g> en cas que <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> no tingui accés a Internet. És possible que s\'hi apliquin càrrecs."</string>
<string name="network_switch_metered_toast" msgid="5779283181685974304">"Abans es feia servir la xarxa <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g>; ara s\'utilitza <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
<string-array name="network_switch_type_name">
<item msgid="3979506840912951943">"dades mòbils"</item>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index e7f9a7f2cdf4..d2f8ecf1778c 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -291,7 +291,7 @@
<string name="permgroupdesc_camera" msgid="3250611594678347720">"사진 및 동영상 촬영"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"전화"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"전화 걸기 및 관리"</string>
- <string name="permgrouplab_sensors" msgid="416037179223226722">"신체 센서"</string>
+ <string name="permgrouplab_sensors" msgid="416037179223226722">"인체 감지 센서"</string>
<string name="permgroupdesc_sensors" msgid="7147968539346634043">"생체 신호에 관한 센서 데이터에 액세스"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"창 콘텐츠 가져오기"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"상호작용 중인 창의 콘텐츠를 검사합니다."</string>
@@ -381,7 +381,7 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"앱에서 수신 및 발신 통화 데이터를 포함하여 태블릿의 통화 기록을 수정할 수 있도록 허용합니다. 이 경우 악성 앱이 통화 기록을 지우거나 수정할 수 있습니다."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"앱에서 수신 및 발신 통화 데이터를 포함하여 TV의 통화 기록을 수정할 수 있도록 허용합니다. 이 경우 악성 앱이 통화 기록을 삭제하거나 수정할 수도 있습니다."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"앱에서 수신 및 발신 통화 데이터를 포함하여 휴대전화의 통화 기록을 수정할 수 있도록 허용합니다. 이 경우 악성 앱이 통화 기록을 지우거나 수정할 수 있습니다."</string>
- <string name="permlab_bodySensors" msgid="4683341291818520277">"신체 센서(예: 심박수 모니터)에 액세스"</string>
+ <string name="permlab_bodySensors" msgid="4683341291818520277">"인체 감지 센서(예: 심박수 모니터)에 액세스"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"앱이 심박수와 같은 신체 상태를 확인하는 센서의 데이터에 접근하도록 허용합니다."</string>
<string name="permlab_readCalendar" msgid="6716116972752441641">"캘린더 일정 및 세부정보 읽기"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="4993979255403945892">"이 앱은 태블릿에 저장된 모든 캘린더 일정을 읽고 캘린더 데이터를 공유하거나 저장할 수 있습니다."</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 69fe42f642e7..0d5f04ac3b70 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -213,7 +213,7 @@
<string name="reboot_to_update_prepare" msgid="6305853831955310890">"Подготовка обновлений…"</string>
<string name="reboot_to_update_package" msgid="3871302324500927291">"Обработка обновлений…"</string>
<string name="reboot_to_update_reboot" msgid="6428441000951565185">"Перезагрузка…"</string>
- <string name="reboot_to_reset_title" msgid="4142355915340627490">"Сбросить все данные"</string>
+ <string name="reboot_to_reset_title" msgid="4142355915340627490">"Сброс к заводским настройкам"</string>
<string name="reboot_to_reset_message" msgid="2432077491101416345">"Перезагрузка…"</string>
<string name="shutdown_progress" msgid="2281079257329981203">"Выключение..."</string>
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Планшетный ПК будет отключен."</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 51d932d16560..eb9994aed9de 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -152,8 +152,8 @@
<string name="cfTemplateForwardedTime" msgid="9206251736527085256">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> หลังผ่านไป <xliff:g id="TIME_DELAY">{2}</xliff:g> วินาที"</string>
<string name="cfTemplateRegistered" msgid="5073237827620166285">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ไม่ได้โอนสาย"</string>
<string name="cfTemplateRegisteredTime" msgid="6781621964320635172">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ไม่ได้โอนสาย"</string>
- <string name="fcComplete" msgid="3118848230966886575">"รหัสคุณลักษณะเสร็จสมบูรณ์"</string>
- <string name="fcError" msgid="3327560126588500777">"พบปัญหาในการเชื่อมต่อหรือรหัสคุณลักษณะไม่ถูกต้อง"</string>
+ <string name="fcComplete" msgid="3118848230966886575">"รหัสฟีเจอร์เสร็จสมบูรณ์"</string>
+ <string name="fcError" msgid="3327560126588500777">"พบปัญหาในการเชื่อมต่อหรือรหัสฟีเจอร์ไม่ถูกต้อง"</string>
<string name="httpErrorOk" msgid="1191919378083472204">"ตกลง"</string>
<string name="httpError" msgid="7956392511146698522">"เกิดข้อผิดพลาดของเครือข่าย"</string>
<string name="httpErrorLookup" msgid="4711687456111963163">"ไม่พบ URL"</string>
@@ -414,7 +414,7 @@
<string name="permlab_accessImsCallService" msgid="3574943847181793918">"เข้าถึงบริการโทร IMS"</string>
<string name="permdesc_accessImsCallService" msgid="8992884015198298775">"อนุญาตให้แอปใช้บริการ IMS เพื่อโทรออกโดยคุณไม่ต้องดำเนินการใดๆ เลย"</string>
<string name="permlab_readPhoneState" msgid="9178228524507610486">"อ่านสถานะและข้อมูลระบุตัวตนของโทรศัพท์"</string>
- <string name="permdesc_readPhoneState" msgid="1639212771826125528">"อนุญาตให้แอปพลิเคชันเข้าถึงคุณลักษณะโทรศัพท์ของอุปกรณ์ การอนุญาตนี้ทำให้แอปพลิเคชันสามารถตรวจสอบหมายเลขโทรศัพท์และรหัสอุปกรณ์ ตรวจสอบว่ามีการโทรที่ทำงานอยู่หรือไม่ และตรวจสอบหมายเลขระยะไกลที่เชื่อมต่อด้วยการโทร"</string>
+ <string name="permdesc_readPhoneState" msgid="1639212771826125528">"อนุญาตให้แอปพลิเคชันเข้าถึงฟีเจอร์โทรศัพท์ของอุปกรณ์ การอนุญาตนี้ทำให้แอปพลิเคชันสามารถตรวจสอบหมายเลขโทรศัพท์และรหัสอุปกรณ์ ตรวจสอบว่ามีการโทรที่ทำงานอยู่หรือไม่ และตรวจสอบหมายเลขระยะไกลที่เชื่อมต่อด้วยการโทร"</string>
<string name="permlab_manageOwnCalls" msgid="1503034913274622244">"กำหนดเส้นทางการโทรผ่านระบบ"</string>
<string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"อนุญาตให้แอปกำหนดเส้นทางการโทรของแอปผ่านระบบเพื่อปรับปรุงประสบการณ์ในการโทร"</string>
<string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"อ่านหมายเลขโทรศัพท์"</string>
@@ -586,8 +586,8 @@
<string name="policydesc_encryptedStorage" msgid="2637732115325316992">"ข้อมูลของแอปพลิเคชันที่จัดเก็บต้องมีการเข้ารหัส"</string>
<string name="policylab_disableCamera" msgid="6395301023152297826">"ปิดใช้งานกล้องถ่ายรูป"</string>
<string name="policydesc_disableCamera" msgid="2306349042834754597">"ป้องกันการใช้กล้องถ่ายรูปของอุปกรณ์ทั้งหมด"</string>
- <string name="policylab_disableKeyguardFeatures" msgid="8552277871075367771">"ปิดคุณลักษณะล็อกหน้าจอบางอย่าง"</string>
- <string name="policydesc_disableKeyguardFeatures" msgid="2044755691354158439">"ป้องกันการใช้คุณลักษณะบางอย่างของการล็อกหน้าจอ"</string>
+ <string name="policylab_disableKeyguardFeatures" msgid="8552277871075367771">"ปิดฟีเจอร์ล็อกหน้าจอบางอย่าง"</string>
+ <string name="policydesc_disableKeyguardFeatures" msgid="2044755691354158439">"ป้องกันการใช้ฟีเจอร์บางอย่างของการล็อกหน้าจอ"</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"บ้าน"</item>
<item msgid="869923650527136615">"มือถือ"</item>
@@ -722,7 +722,7 @@
<string name="lockscreen_pattern_correct" msgid="9039008650362261237">"ถูกต้อง!"</string>
<string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"ลองอีกครั้ง"</string>
<string name="lockscreen_password_wrong" msgid="5737815393253165301">"ลองอีกครั้ง"</string>
- <string name="lockscreen_storage_locked" msgid="9167551160010625200">"ปลดล็อกคุณลักษณะและข้อมูลทั้งหมด"</string>
+ <string name="lockscreen_storage_locked" msgid="9167551160010625200">"ปลดล็อกฟีเจอร์และข้อมูลทั้งหมด"</string>
<string name="faceunlock_multiple_failures" msgid="754137583022792429">"มีความพยายามที่จะใช้ Face Unlock เกินขีดจำกัด"</string>
<string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"ไม่มีซิมการ์ด"</string>
<string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"ไม่มีซิมการ์ดในแท็บเล็ต"</string>
@@ -842,7 +842,7 @@
<string name="permdesc_writeHistoryBookmarks" product="tv" msgid="7007393823197766548">"อนุญาตให้แอปแก้ไขประวัติของเบราว์เซอร์หรือบุ๊กมาร์กที่เก็บไว้ในทีวี ซึ่งอาจอนุญาตให้แอปลบหรือแก้ไขข้อมูลเบราว์เซอร์ หมายเหตุ: สิทธิ์นี้ไม่สามารถใช้ได้กับเบราว์เซอร์ของบุคคลที่สามหรือแอปพลิเคชันอื่นที่สามารถท่องเว็บได้"</string>
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"อนุญาตให้แอปพลิเคชันเปลี่ยนแปลงประวัติหรือบุ๊กมาร์กของเบราว์เซอร์ที่จัดเก็บไว้ในโทรศัพท์ ซึ่งทำให้แอปพลิเคชันสามารถลบหรือเปลี่ยนข้อมูลเบราว์เซอร์ได้ หมายเหตุ: การอนุญาตนี้อาจไม่สามารถใช้งานได้กับเบราว์เซอร์ของบุคคลที่สามหรือแอปพลิเคชันอื่นๆ ที่มีความสามารถในการเรียกดูบนเว็บ"</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"ตั้งปลุก"</string>
- <string name="permdesc_setAlarm" msgid="316392039157473848">"อนุญาตให้แอปพลิเคชันตั้งเวลาปลุกในแอปพลิเคชันนาฬิกาปลุกที่ติดตั้ง แอปพลิเคชันนาฬิกาปลุกบางรายการอาจไม่ใช้คุณลักษณะนี้"</string>
+ <string name="permdesc_setAlarm" msgid="316392039157473848">"อนุญาตให้แอปพลิเคชันตั้งเวลาปลุกในแอปพลิเคชันนาฬิกาปลุกที่ติดตั้ง แอปพลิเคชันนาฬิกาปลุกบางรายการอาจไม่ใช้ฟีเจอร์นี้"</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"เพิ่มข้อวามเสียง"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"อนุญาตให้แอปพลิเคชันเพิ่มข้อความลงในกล่องข้อความเสียงของคุณ"</string>
<string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"แก้ไขการอนุญาตเกี่ยวกับการระบุตำแหน่งทางภูมิศาสตร์ของเบราว์เซอร์"</string>
@@ -1206,7 +1206,7 @@
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรลวศษสหฬอฮ"</string>
<string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> แสดงทับแอปอื่นๆ"</string>
<string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> กำลังแสดงทับแอปอื่นๆ"</string>
- <string name="alert_windows_notification_message" msgid="8917232109522912560">"หากคุณไม่ต้องการให้ <xliff:g id="NAME">%s</xliff:g> ใช้คุณลักษณะนี้ ให้แตะเพื่อเปิดการตั้งค่าแล้วปิดคุณลักษณะ"</string>
+ <string name="alert_windows_notification_message" msgid="8917232109522912560">"หากคุณไม่ต้องการให้ <xliff:g id="NAME">%s</xliff:g> ใช้ฟีเจอร์นี้ ให้แตะเพื่อเปิดการตั้งค่าแล้วปิดฟีเจอร์"</string>
<string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"ปิด"</string>
<string name="ext_media_checking_notification_title" msgid="5734005953288045806">"กำลังเตรียม <xliff:g id="NAME">%s</xliff:g>"</string>
<string name="ext_media_checking_notification_message" msgid="4747432538578886744">"กำลังตรวจหาข้อผิดพลาด"</string>
@@ -1480,13 +1480,13 @@
<string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"ลบ"</string>
<string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"นี่เป็นการเพิ่มระดับเสียงเกินระดับที่แนะนำ\n\nการฟังเสียงดังเป็นเวลานานอาจทำให้การได้ยินของคุณบกพร่องได้"</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="8404780875025725199">"ใช้ทางลัดการเข้าถึงพิเศษไหม"</string>
- <string name="accessibility_shortcut_toogle_warning" msgid="7256507885737444807">"เมื่อทางลัดเปิดอยู่ การกดปุ่มปรับระดับเสียงทั้ง 2 ปุ่มเป็นเวลา 3 วินาทีจะเริ่มคุณลักษณะการเข้าถึงพิเศษ\n\n คุณลักษณะการเข้าถึงพิเศษปัจจุบัน:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n คุณสามารถเปลี่ยนคุณลักษณะในการตั้งค่า &gt; การเข้าถึงพิเศษ"</string>
+ <string name="accessibility_shortcut_toogle_warning" msgid="7256507885737444807">"เมื่อทางลัดเปิดอยู่ การกดปุ่มปรับระดับเสียงทั้ง 2 ปุ่มเป็นเวลา 3 วินาทีจะเริ่มฟีเจอร์การเข้าถึงพิเศษ\n\n ฟีเจอร์การเข้าถึงพิเศษปัจจุบัน:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n คุณสามารถเปลี่ยนฟีเจอร์ในการตั้งค่า &gt; การเข้าถึงพิเศษ"</string>
<string name="disable_accessibility_shortcut" msgid="627625354248453445">"ปิดทางลัด"</string>
<string name="leave_accessibility_shortcut_on" msgid="7653111894438512680">"ใช้ทางลัด"</string>
<string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"ทางลัดการเข้าถึงเปิด <xliff:g id="SERVICE_NAME">%1$s</xliff:g> แล้ว"</string>
<string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"ทางลัดการเข้าถึงปิด <xliff:g id="SERVICE_NAME">%1$s</xliff:g> แล้ว"</string>
- <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"เลือกคุณลักษณะที่จะใช้เมื่อคุณแตะปุ่ม \"การเข้าถึงพิเศษ\":"</string>
- <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"หากต้องการเปลี่ยนคุณลักษณะ ให้แตะปุ่ม \"การเข้าถึงพิเศษ\" ค้างไว้"</string>
+ <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"เลือกฟีเจอร์ที่จะใช้เมื่อคุณแตะปุ่ม \"การเข้าถึงพิเศษ\":"</string>
+ <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"หากต้องการเปลี่ยนฟีเจอร์ ให้แตะปุ่ม \"การเข้าถึงพิเศษ\" ค้างไว้"</string>
<string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"การขยาย"</string>
<string name="user_switched" msgid="3768006783166984410">"ผู้ใช้ปัจจุบัน <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="user_switching_message" msgid="2871009331809089783">"กำลังเปลี่ยนเป็น <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1708,7 +1708,7 @@
<string name="region_picker_section_all" msgid="8966316787153001779">"ภูมิภาคทั้งหมด"</string>
<string name="locale_search_menu" msgid="2560710726687249178">"ค้นหา"</string>
<string name="work_mode_off_title" msgid="2615362773958585967">"เปิดโหมดงานไหม"</string>
- <string name="work_mode_off_message" msgid="2961559609199223594">"การดำเนินการนี้จะเปิดโปรไฟล์งานของคุณ รวมถึงแอป การซิงค์ในพื้นหลัง และคุณลักษณะที่เกี่ยวข้อง"</string>
+ <string name="work_mode_off_message" msgid="2961559609199223594">"การดำเนินการนี้จะเปิดโปรไฟล์งานของคุณ รวมถึงแอป การซิงค์ในพื้นหลัง และฟีเจอร์ที่เกี่ยวข้อง"</string>
<string name="work_mode_turn_on" msgid="2062544985670564875">"เปิด"</string>
<string name="new_sms_notification_title" msgid="8442817549127555977">"คุณมีข้อความใหม่"</string>
<string name="new_sms_notification_content" msgid="7002938807812083463">"เปิดแอป SMS เพื่อดู"</string>
diff --git a/core/res/res/values/themes_device_defaults.xml b/core/res/res/values/themes_device_defaults.xml
index 75179463f0c4..8755e37f105f 100644
--- a/core/res/res/values/themes_device_defaults.xml
+++ b/core/res/res/values/themes_device_defaults.xml
@@ -758,6 +758,14 @@ easier.
<item name="colorControlNormal">?attr/textColorPrimary</item>
</style>
+ <style name="Theme.DeviceDefault.QuickSettings.Dialog" parent="Theme.DeviceDefault.Light.Dialog">
+ <!-- Color palette -->
+ <item name="colorPrimary">@color/primary_device_default_settings_light</item>
+ <item name="colorPrimaryDark">@color/primary_dark_device_default_settings_light</item>
+ <item name="colorSecondary">@color/secondary_device_default_settings_light</item>
+ <item name="colorAccent">@color/accent_device_default_light</item>
+ </style>
+
<!-- Variant of {@link #Theme_DeviceDefault_Settings_Dark} with no action bar -->
<style name="Theme.DeviceDefault.Settings.Dark.NoActionBar" parent="Theme.Material.NoActionBar">
<!-- Color palette -->
diff --git a/core/tests/coretests/src/android/content/pm/AppCacheTest.java b/core/tests/coretests/src/android/content/pm/AppCacheTest.java
index 15dbddff54df..59aa50ae1445 100644
--- a/core/tests/coretests/src/android/content/pm/AppCacheTest.java
+++ b/core/tests/coretests/src/android/content/pm/AppCacheTest.java
@@ -492,7 +492,7 @@ public class AppCacheTest extends AndroidTestCase {
PackageDataObserver observer = new PackageDataObserver();
//wait on observer
synchronized(observer) {
- getPm().freeStorageAndNotify(null, idealStorageSize, observer);
+ getPm().freeStorageAndNotify(null, idealStorageSize, 0, observer);
long waitTime = 0;
while(!observer.isDone() || (waitTime > MAX_WAIT_TIME)) {
observer.wait(WAIT_TIME_INCR);
@@ -517,7 +517,7 @@ public class AppCacheTest extends AndroidTestCase {
try {
// Spin lock waiting for call back
synchronized(r) {
- getPm().freeStorage(null, idealStorageSize, pi.getIntentSender());
+ getPm().freeStorage(null, idealStorageSize, 0, pi.getIntentSender());
long waitTime = 0;
while(!r.isDone() && (waitTime < MAX_WAIT_TIME)) {
r.wait(WAIT_TIME_INCR);
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index 54d5285e3224..d875ed4e5ec5 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -334,7 +334,11 @@ public class SettingsBackupTest {
Settings.Global.TRUSTED_SOUND,
Settings.Global.TZINFO_UPDATE_CONTENT_URL,
Settings.Global.TZINFO_UPDATE_METADATA_URL,
- Settings.Global.UNINSTALLED_INSTANT_APP_CACHE_DURATION_MILLIS,
+ Settings.Global.INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
+ Settings.Global.INSTALLED_INSTANT_APP_MAX_CACHE_PERIOD,
+ Settings.Global.UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
+ Settings.Global.UNINSTALLED_INSTANT_APP_MAX_CACHE_PERIOD,
+ Settings.Global.UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD,
Settings.Global.UNLOCK_SOUND,
Settings.Global.USE_GOOGLE_MAIL,
Settings.Global.VT_IMS_ENABLED,
diff --git a/core/tests/coretests/src/com/android/internal/app/procstats/SparseMappingTableTest.java b/core/tests/coretests/src/com/android/internal/app/procstats/SparseMappingTableTest.java
index fd57baa217b0..115af5e0ea5d 100644
--- a/core/tests/coretests/src/com/android/internal/app/procstats/SparseMappingTableTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/procstats/SparseMappingTableTest.java
@@ -180,7 +180,9 @@ public class SparseMappingTableTest extends TestCase {
try {
table.getValue(key);
- throw new Exception("Exception not thrown after mismatched reset calls.");
+ // Turn off this assertion because the check in SparseMappingTable.assertConsistency
+ // is also turned off.
+ //throw new Exception("Exception not thrown after mismatched reset calls.");
} catch (RuntimeException ex) {
// Good
}
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsBackgroundStatsTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsBackgroundStatsTest.java
index 9aabdbb2c8f0..c539f789ff60 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsBackgroundStatsTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsBackgroundStatsTest.java
@@ -205,9 +205,9 @@ public class BatteryStatsBackgroundStatsTest extends TestCase {
// App in foreground
bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND);
- // Start timer
+ // Start timer (optimized)
curr = 1000 * (clocks.realtime = clocks.uptime = 202);
- bi.noteBluetoothScanStartedFromSourceLocked(ws);
+ bi.noteBluetoothScanStartedFromSourceLocked(ws, false);
// Move to background
curr = 1000 * (clocks.realtime = clocks.uptime = 254);
@@ -221,21 +221,44 @@ public class BatteryStatsBackgroundStatsTest extends TestCase {
curr = 1000 * (clocks.realtime = clocks.uptime = 409);
bi.noteBluetoothScanStoppedFromSourceLocked(ws);
+ // Start timer (unoptimized)
+ curr = 1000 * (clocks.realtime = clocks.uptime = 1000);
+ bi.noteBluetoothScanStartedFromSourceLocked(ws, true);
+
+ // On battery
+ curr = 1000 * (clocks.realtime = clocks.uptime = 2001);
+ bi.updateTimeBasesLocked(true, false, curr, curr); // on battery
+
+ // Move to foreground
+ curr = 1000 * (clocks.realtime = clocks.uptime = 3004);
+ bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP);
+
+ // Stop timer
+ curr = 1000 * (clocks.realtime = clocks.uptime = 4008);
+ bi.noteBluetoothScanStoppedFromSourceLocked(ws);
+
// Test
- curr = 1000 * (clocks.realtime = clocks.uptime = 657);
+ curr = 1000 * (clocks.realtime = clocks.uptime = 5000);
BatteryStats.Timer timer = bi.getUidStats().get(UID).getBluetoothScanTimer();
BatteryStats.Timer bgTimer = bi.getUidStats().get(UID).getBluetoothScanBackgroundTimer();
+ BatteryStats.Timer badTimer = bi.getUidStats().get(UID).getBluetoothUnoptimizedScanTimer();
+ BatteryStats.Timer badBgTimer = bi.getUidStats().get(UID)
+ .getBluetoothUnoptimizedScanBackgroundTimer();
long time = timer.getTotalTimeLocked(curr, STATS_SINCE_CHARGED);
int count = timer.getCountLocked(STATS_SINCE_CHARGED);
int bgCount = bgTimer.getCountLocked(STATS_SINCE_CHARGED);
long actualTime = timer.getTotalDurationMsLocked(clocks.realtime) * 1000;
long bgTime = bgTimer.getTotalDurationMsLocked(clocks.realtime) * 1000;
- assertEquals((305 - 202) * 1000, time);
- assertEquals(1, count);
- assertEquals(0, bgCount);
- assertEquals((305 - 202) * 1000, actualTime);
- assertEquals((305 - 254) * 1000, bgTime);
+ long badTime = badTimer.getTotalDurationMsLocked(clocks.realtime) * 1000;
+ long badBgTime = badBgTimer.getTotalDurationMsLocked(clocks.realtime) * 1000;
+ assertEquals((305 - 202 + 4008 - 2001) * 1000, time);
+ assertEquals(1, count); // second scan starts off-battery
+ assertEquals(0, bgCount); // first scan starts in fg, second starts off-battery
+ assertEquals((305 - 202 + 4008 - 2001) * 1000, actualTime);
+ assertEquals((305 - 254 + 3004 - 2001) * 1000, bgTime);
+ assertEquals((4008 - 2001) * 1000, badTime);
+ assertEquals((3004 - 2001) * 1000, badBgTime);
}
@SmallTest
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsCounterTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsCounterTest.java
new file mode 100644
index 000000000000..08f8dd146516
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsCounterTest.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2017 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 android.os.BatteryStats;
+import android.os.Parcel;
+import android.support.test.filters.SmallTest;
+
+import junit.framework.TestCase;
+
+/**
+ * Test BatteryStatsImpl.Counter.
+ */
+public class BatteryStatsCounterTest extends TestCase {
+
+ @SmallTest
+ public void testCounter() throws Exception {
+ final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms
+ final BatteryStatsImpl.TimeBase timeBase = new BatteryStatsImpl.TimeBase();
+ timeBase.init(clocks.uptimeMillis(), clocks.elapsedRealtime());
+
+ final BatteryStatsImpl.Counter counter = new BatteryStatsImpl.Counter(timeBase);
+
+ // timeBase off (i.e. plugged in)
+ timeBase.setRunning(false, 1, 1);
+ counter.stepAtomic();
+ counter.stepAtomic();
+ counter.stepAtomic();
+ counter.stepAtomic();
+ counter.stepAtomic();
+ assertEquals(0, counter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
+ assertEquals(0, counter.getCountLocked(BatteryStats.STATS_CURRENT));
+ assertEquals(0, counter.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED));
+
+ // timeBase on (i.e. unplugged)
+ timeBase.setRunning(true, 2, 2);
+ counter.stepAtomic();
+ counter.stepAtomic();
+ counter.stepAtomic();
+ counter.stepAtomic();
+ assertEquals(4, counter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
+ assertEquals(4, counter.getCountLocked(BatteryStats.STATS_CURRENT));
+ assertEquals(4, counter.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED));
+
+ // timeBase off (i.e. plugged in)
+ timeBase.setRunning(false, 3, 3);
+ counter.stepAtomic();
+ counter.stepAtomic();
+ counter.stepAtomic();
+ assertEquals(4, counter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
+ assertEquals(4, counter.getCountLocked(BatteryStats.STATS_CURRENT));
+ assertEquals(4, counter.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED));
+
+ // timeBase on (i.e. unplugged)
+ timeBase.setRunning(true, 4, 4);
+ counter.stepAtomic();
+ counter.stepAtomic();
+ assertEquals(6, counter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
+ assertEquals(6, counter.getCountLocked(BatteryStats.STATS_CURRENT));
+ assertEquals(2, counter.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED));
+ }
+
+
+ @SmallTest
+ public void testParceling() throws Exception {
+ final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms
+ final BatteryStatsImpl.TimeBase timeBase = new BatteryStatsImpl.TimeBase();
+ timeBase.init(clocks.uptimeMillis(), clocks.elapsedRealtime());
+
+ final BatteryStatsImpl.Counter origCounter = new BatteryStatsImpl.Counter(timeBase);
+
+ // timeBase on (i.e. unplugged)
+ timeBase.setRunning(true, 1, 1);
+ origCounter.stepAtomic(); origCounter.stepAtomic(); origCounter.stepAtomic(); // three times
+ assertEquals(3, origCounter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
+ assertEquals(3, origCounter.getCountLocked(BatteryStats.STATS_CURRENT));
+ assertEquals(3, origCounter.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED));
+
+ // Test summary parcelling (from origCounter)
+ final Parcel summaryParcel = Parcel.obtain();
+ origCounter.writeSummaryFromParcelLocked(summaryParcel);
+ summaryParcel.setDataPosition(0);
+ final BatteryStatsImpl.Counter summaryCounter = new BatteryStatsImpl.Counter(timeBase);
+ summaryCounter.stepAtomic(); // occurs before reading the summary, so must not count later
+ summaryCounter.readSummaryFromParcelLocked(summaryParcel);
+
+ // timeBase still on (i.e. unplugged)
+ summaryCounter.stepAtomic(); // once
+ assertEquals(4, summaryCounter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
+ assertEquals(1, summaryCounter.getCountLocked(BatteryStats.STATS_CURRENT));
+ assertEquals(1, summaryCounter.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED));
+
+ // timeBase off (i.e. plugged in)
+ timeBase.setRunning(false, 3, 3);
+ summaryCounter.stepAtomic(); summaryCounter.stepAtomic(); // twice
+ assertEquals(4, summaryCounter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
+ assertEquals(1, summaryCounter.getCountLocked(BatteryStats.STATS_CURRENT));
+ assertEquals(1, summaryCounter.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED));
+
+ // timeBase on (i.e. unplugged)
+ timeBase.setRunning(true, 4, 4);
+ summaryCounter.stepAtomic(); summaryCounter.stepAtomic(); // twice
+ assertEquals(6, summaryCounter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
+ assertEquals(3, summaryCounter.getCountLocked(BatteryStats.STATS_CURRENT));
+ assertEquals(2, summaryCounter.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED));
+
+
+ // Test full parcelling (from summaryCounter)
+ final Parcel fullParcel = Parcel.obtain();
+ summaryCounter.writeToParcel(fullParcel);
+ fullParcel.setDataPosition(0);
+ final BatteryStatsImpl.Counter fullParcelCounter
+ = new BatteryStatsImpl.Counter(timeBase, fullParcel);
+
+ // timeBase still on (i.e. unplugged)
+ fullParcelCounter.stepAtomic(); // once
+ assertEquals(7, fullParcelCounter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
+ assertEquals(4, fullParcelCounter.getCountLocked(BatteryStats.STATS_CURRENT));
+ assertEquals(3, fullParcelCounter.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED));
+
+ // timeBase off (i.e. plugged in)
+ timeBase.setRunning(false, 5, 5);
+ fullParcelCounter.stepAtomic(); fullParcelCounter.stepAtomic(); // twice
+ assertEquals(7, fullParcelCounter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
+ assertEquals(4, fullParcelCounter.getCountLocked(BatteryStats.STATS_CURRENT));
+ assertEquals(3, fullParcelCounter.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED));
+
+ // timeBase on (i.e. unplugged)
+ timeBase.setRunning(true, 6, 6);
+ fullParcelCounter.stepAtomic(); fullParcelCounter.stepAtomic(); // twice
+ assertEquals(9, fullParcelCounter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
+ assertEquals(6, fullParcelCounter.getCountLocked(BatteryStats.STATS_CURRENT));
+ assertEquals(2, fullParcelCounter.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED));
+ }
+}
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java
index 06ca18d072e7..4e8ab316e1c9 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java
@@ -37,12 +37,28 @@ public class BatteryStatsNoteTest extends TestCase{
public void testNoteBluetoothScanResultLocked() throws Exception {
MockBatteryStatsImpl bi = new MockBatteryStatsImpl(new MockClocks());
bi.updateTimeBasesLocked(true, true, 0, 0);
+ bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP);
bi.noteBluetoothScanResultsFromSourceLocked(WS, 1);
bi.noteBluetoothScanResultsFromSourceLocked(WS, 100);
assertEquals(101,
bi.getUidStats().get(UID).getBluetoothScanResultCounter()
.getCountLocked(STATS_SINCE_CHARGED));
+ // TODO: remove next line when Counter misreporting values when plugged-in bug is fixed.
+ bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND);
+ BatteryStats.Counter bgCntr = bi.getUidStats().get(UID).getBluetoothScanResultBgCounter();
+ if (bgCntr != null) {
+ assertEquals(0, bgCntr.getCountLocked(STATS_SINCE_CHARGED));
+ }
+
+ bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND);
+ bi.noteBluetoothScanResultsFromSourceLocked(WS, 17);
+ assertEquals(101 + 17,
+ bi.getUidStats().get(UID).getBluetoothScanResultCounter()
+ .getCountLocked(STATS_SINCE_CHARGED));
+ assertEquals(17,
+ bi.getUidStats().get(UID).getBluetoothScanResultBgCounter()
+ .getCountLocked(STATS_SINCE_CHARGED));
}
/** Test BatteryStatsImpl.Uid.noteStartWakeLocked. */
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java
index 3a16fcff38a2..1412d3e7df59 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java
@@ -5,17 +5,18 @@ import org.junit.runners.Suite;
@RunWith(Suite.class)
@Suite.SuiteClasses({
+ BatteryStatsBackgroundStatsTest.class,
+ BatteryStatsCounterTest.class,
BatteryStatsDualTimerTest.class,
BatteryStatsDurationTimerTest.class,
+ BatteryStatsNoteTest.class,
BatteryStatsSamplingTimerTest.class,
+ BatteryStatsSensorTest.class,
BatteryStatsServTest.class,
BatteryStatsStopwatchTimerTest.class,
BatteryStatsTimeBaseTest.class,
BatteryStatsTimerTest.class,
BatteryStatsUidTest.class,
- BatteryStatsSensorTest.class,
- BatteryStatsBackgroundStatsTest.class,
- BatteryStatsNoteTest.class,
})
public class BatteryStatsTests {
}
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index e62df8ff4742..e3b47405e0d4 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -529,6 +529,7 @@ public class Paint {
setTextLocales(LocaleList.getAdjustedDefault());
setElegantTextHeight(false);
mFontFeatureSettings = null;
+ mFontVariationSettings = null;
}
/**
@@ -565,6 +566,7 @@ public class Paint {
mBidiFlags = paint.mBidiFlags;
mLocales = paint.mLocales;
mFontFeatureSettings = paint.mFontFeatureSettings;
+ mFontVariationSettings = paint.mFontVariationSettings;
}
/** @hide */
@@ -1594,10 +1596,13 @@ public class Paint {
return true;
}
+ // The null typeface is valid and it is equivalent to Typeface.DEFAULT.
+ // To call isSupportedAxes method, use Typeface.DEFAULT instance.
+ Typeface targetTypeface = mTypeface == null ? Typeface.DEFAULT : mTypeface;
FontVariationAxis[] axes = FontVariationAxis.fromFontVariationSettings(settings);
final ArrayList<FontVariationAxis> filteredAxes = new ArrayList<FontVariationAxis>();
for (final FontVariationAxis axis : axes) {
- if (mTypeface.isSupportedAxes(axis.getOpenTypeTagValue())) {
+ if (targetTypeface.isSupportedAxes(axis.getOpenTypeTagValue())) {
filteredAxes.add(axis);
}
}
@@ -1605,7 +1610,7 @@ public class Paint {
return false;
}
mFontVariationSettings = settings;
- setTypeface(Typeface.createFromTypefaceWithVariation(mTypeface, filteredAxes));
+ setTypeface(Typeface.createFromTypefaceWithVariation(targetTypeface, filteredAxes));
return true;
}
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index 5a56f5335373..c4b56c333c64 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -725,8 +725,8 @@ public class Typeface {
}
/** @hide */
- public static Typeface createFromTypefaceWithVariation(Typeface family,
- List<FontVariationAxis> axes) {
+ public static Typeface createFromTypefaceWithVariation(@Nullable Typeface family,
+ @NonNull List<FontVariationAxis> axes) {
final long ni = family == null ? 0 : family.native_instance;
return new Typeface(nativeCreateFromTypefaceWithVariation(ni, axes));
}
@@ -1056,7 +1056,7 @@ public class Typeface {
}
}
}
- return Arrays.binarySearch(mSupportedAxes, axis) > 0;
+ return Arrays.binarySearch(mSupportedAxes, axis) >= 0;
}
private static native long nativeCreateFromTypeface(long native_instance, int style);
diff --git a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
index 39f11b8e6bfe..4ee47afe87fd 100644
--- a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
+++ b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
@@ -61,8 +61,17 @@ void RenderNodeDrawable::drawBackwardsProjectedNodes(SkCanvas* canvas, const Ski
static void clipOutline(const Outline& outline, SkCanvas* canvas, const SkRect* pendingClip) {
Rect possibleRect;
float radius;
- LOG_ALWAYS_FATAL_IF(!outline.getAsRoundRect(&possibleRect, &radius),
- "clipping outlines should be at most roundedRects");
+
+ /* To match the existing HWUI behavior we only supports rectangles or
+ * rounded rectangles; passing in a more complicated outline fails silently.
+ */
+ if (!outline.getAsRoundRect(&possibleRect, &radius)) {
+ if (pendingClip) {
+ canvas->clipRect(*pendingClip);
+ }
+ return;
+ }
+
SkRect rect = possibleRect.toSkRect();
if (radius != 0.0f) {
if (pendingClip && !pendingClip->contains(rect)) {
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 02a9ffa3039c..cbc5163244c1 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -436,8 +436,15 @@ void CanvasContext::draw() {
swap.vsyncTime = mRenderThread.timeLord().latestVsync();
if (mNativeSurface.get()) {
int durationUs;
- mNativeSurface->query(NATIVE_WINDOW_LAST_DEQUEUE_DURATION, &durationUs);
- swap.dequeueDuration = us2ns(durationUs);
+ nsecs_t dequeueStart = mNativeSurface->getLastDequeueStartTime();
+ if (dequeueStart < mCurrentFrameInfo->get(FrameInfoIndex::Vsync)) {
+ // Ignoring dequeue duration as it happened prior to vsync
+ // and thus is not part of the frame.
+ swap.dequeueDuration = 0;
+ } else {
+ mNativeSurface->query(NATIVE_WINDOW_LAST_DEQUEUE_DURATION, &durationUs);
+ swap.dequeueDuration = us2ns(durationUs);
+ }
mNativeSurface->query(NATIVE_WINDOW_LAST_QUEUE_DURATION, &durationUs);
swap.queueDuration = us2ns(durationUs);
} else {
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index 6cab56c1d466..2de69e7bc1de 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -75,12 +75,12 @@ import java.util.Map;
<h4>Compressed Buffers</h4>
<p>
Input buffers (for decoders) and output buffers (for encoders) contain compressed data according
- to the {@linkplain MediaFormat#KEY_MIME format's type}. For video types this is a single
+ to the {@linkplain MediaFormat#KEY_MIME format's type}. For video types this is normally a single
compressed video frame. For audio data this is normally a single access unit (an encoded audio
segment typically containing a few milliseconds of audio as dictated by the format type), but
this requirement is slightly relaxed in that a buffer may contain multiple encoded access units
of audio. In either case, buffers do not start or end on arbitrary byte boundaries, but rather on
- frame/access unit boundaries.
+ frame/access unit boundaries unless they are flagged with {@link #BUFFER_FLAG_PARTIAL_FRAME}.
<h4>Raw Audio Buffers</h4>
<p>
diff --git a/media/java/android/media/MediaSync.java b/media/java/android/media/MediaSync.java
index 5522d362bc09..799f4bf4f866 100644
--- a/media/java/android/media/MediaSync.java
+++ b/media/java/android/media/MediaSync.java
@@ -35,7 +35,7 @@ import java.util.LinkedList;
import java.util.List;
/**
- * MediaSync class can be used to synchronously playback audio and video streams.
+ * MediaSync class can be used to synchronously play audio and video streams.
* It can be used to play audio-only or video-only stream, too.
*
* <p>MediaSync is generally used like this:
diff --git a/packages/CaptivePortalLogin/res/layout/activity_captive_portal_login.xml b/packages/CaptivePortalLogin/res/layout/activity_captive_portal_login.xml
index 2f0a411448a5..232459338f48 100644
--- a/packages/CaptivePortalLogin/res/layout/activity_captive_portal_login.xml
+++ b/packages/CaptivePortalLogin/res/layout/activity_captive_portal_login.xml
@@ -4,31 +4,35 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.android.captiveportallogin.CaptivePortalLoginActivity"
- tools:ignore="MergeRootFrame">
+ tools:ignore="MergeRootFrame" >
+
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
- <TextView
- android:id="@+id/url_bar"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:textSize="20sp"
- android:singleLine="true" />
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="4dp" >
- <ProgressBar
- android:id="@+id/progress_bar"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- style="?android:attr/progressBarStyleHorizontal" />
+ <!-- Eliminates ProgressBar padding by boxing it into a 4dp high container -->
+ <ProgressBar
+ android:id="@+id/progress_bar"
+ style="@android:style/Widget.Material.Light.ProgressBar.Horizontal"
+ android:indeterminate="false"
+ android:max="100"
+ android:progress="0"
+ android:layout_gravity="center"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+ </FrameLayout>
- <WebView
- android:id="@+id/webview"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_alignParentBottom="false"
- android:layout_alignParentRight="false" />
+ <WebView
+ android:id="@+id/webview"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_alignParentBottom="false"
+ android:layout_alignParentRight="false" />
-</LinearLayout>
+ </LinearLayout>
</FrameLayout>
diff --git a/packages/CaptivePortalLogin/res/values/styles.xml b/packages/CaptivePortalLogin/res/values/styles.xml
index 4a99638aec95..f6c233954b52 100644
--- a/packages/CaptivePortalLogin/res/values/styles.xml
+++ b/packages/CaptivePortalLogin/res/values/styles.xml
@@ -4,7 +4,7 @@
Base application theme, dependent on API level. This theme is replaced
by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
-->
- <style name="AppBaseTheme" parent="@android:style/Theme.Material.Settings">
+ <style name="AppBaseTheme" parent="@android:style/Theme.DeviceDefault.Settings">
<!--
Theme customizations available in newer API levels can go in
res/values-vXX/styles.xml, while customizations related to
@@ -15,8 +15,5 @@
<!-- Application theme. -->
<style name="AppTheme" parent="AppBaseTheme">
<!-- All customizations that are NOT specific to a particular API-level can go here. -->
- <!-- Setting's theme's accent color makes ProgressBar useless, reset back. -->
- <item name="android:colorAccent">@*android:color/material_deep_teal_500</item>
</style>
-
</resources>
diff --git a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
index c9fba95bc828..401a7bca525c 100644
--- a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
+++ b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
@@ -37,6 +37,7 @@ import android.util.Log;
import android.util.TypedValue;
import android.view.Menu;
import android.view.MenuItem;
+import android.view.View;
import android.webkit.SslErrorHandler;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
@@ -97,8 +98,6 @@ public class CaptivePortalLoginActivity extends Activity {
// setContentView initializes the WebView logic which in turn reads the system properties.
setContentView(R.layout.activity_captive_portal_login);
- getActionBar().setDisplayShowHomeEnabled(false);
-
// Exit app if Network disappears.
final NetworkCapabilities networkCapabilities = mCm.getNetworkCapabilities(mNetwork);
if (networkCapabilities == null) {
@@ -117,9 +116,14 @@ public class CaptivePortalLoginActivity extends Activity {
}
mCm.registerNetworkCallback(builder.build(), mNetworkCallback);
- final WebView myWebView = findViewById(R.id.webview);
- myWebView.clearCache(true);
- WebSettings webSettings = myWebView.getSettings();
+ getActionBar().setDisplayShowHomeEnabled(false);
+ getActionBar().setElevation(0); // remove shadow
+ getActionBar().setTitle(getHeaderTitle());
+ getActionBar().setSubtitle("");
+
+ final WebView webview = getWebview();
+ webview.clearCache(true);
+ WebSettings webSettings = webview.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE);
webSettings.setUseWideViewPort(true);
@@ -128,11 +132,11 @@ public class CaptivePortalLoginActivity extends Activity {
webSettings.setBuiltInZoomControls(true);
webSettings.setDisplayZoomControls(false);
mWebViewClient = new MyWebViewClient();
- myWebView.setWebViewClient(mWebViewClient);
- myWebView.setWebChromeClient(new MyWebChromeClient());
+ webview.setWebViewClient(mWebViewClient);
+ webview.setWebChromeClient(new MyWebChromeClient());
// Start initial page load so WebView finishes loading proxy settings.
// Actual load of mUrl is initiated by MyWebViewClient.
- myWebView.loadData("", "text/html", null);
+ webview.loadData("", "text/html", null);
}
// Find WebView's proxy BroadcastReceiver and prompt it to read proxy system properties.
@@ -251,10 +255,14 @@ public class CaptivePortalLoginActivity extends Activity {
if (url == null) {
url = mCm.getCaptivePortalServerUrl();
}
+ return makeURL(url);
+ }
+
+ private static URL makeURL(String url) {
try {
return new URL(url);
} catch (MalformedURLException e) {
- Log.e(TAG, "Invalid captive portal URL " + url);
+ Log.e(TAG, "Invalid URL " + url);
}
return null;
}
@@ -331,15 +339,16 @@ public class CaptivePortalLoginActivity extends Activity {
// For internally generated pages, leave URL bar listing prior URL as this is the URL
// the page refers to.
if (!url.startsWith(INTERNAL_ASSETS)) {
- final TextView myUrlBar = findViewById(R.id.url_bar);
- myUrlBar.setText(url);
+ getActionBar().setSubtitle(getHeaderSubtitle(url));
}
+ getProgressBar().setVisibility(View.VISIBLE);
testForCaptivePortal();
}
@Override
public void onPageFinished(WebView view, String url) {
mPagesLoaded++;
+ getProgressBar().setVisibility(View.INVISIBLE);
if (mPagesLoaded == 1) {
// Now that WebView has loaded at least one page we know it has read in the proxy
// settings. Now prompt the WebView read the Network-specific proxy settings.
@@ -412,8 +421,31 @@ public class CaptivePortalLoginActivity extends Activity {
private class MyWebChromeClient extends WebChromeClient {
@Override
public void onProgressChanged(WebView view, int newProgress) {
- final ProgressBar myProgressBar = findViewById(R.id.progress_bar);
- myProgressBar.setProgress(newProgress);
+ getProgressBar().setProgress(newProgress);
+ }
+ }
+
+ private ProgressBar getProgressBar() {
+ return findViewById(R.id.progress_bar);
+ }
+
+ private WebView getWebview() {
+ return findViewById(R.id.webview);
+ }
+
+ private String getHeaderTitle() {
+ return getString(R.string.action_bar_label);
+ }
+
+ private String getHeaderSubtitle(String urlString) {
+ URL url = makeURL(urlString);
+ if (url == null) {
+ return urlString;
+ }
+ final String https = "https";
+ if (https.equals(url.getProtocol())) {
+ return https + "://" + url.getHost();
}
+ return url.getHost();
}
}
diff --git a/packages/SettingsLib/res/layout/usage_view.xml b/packages/SettingsLib/res/layout/usage_view.xml
index 151d1ee3b899..da66814f49cb 100644
--- a/packages/SettingsLib/res/layout/usage_view.xml
+++ b/packages/SettingsLib/res/layout/usage_view.xml
@@ -76,7 +76,7 @@
android:id="@+id/bottom_label_space"
android:layout_width="@dimen/usage_graph_labels_width"
android:layout_height="wrap_content"/>
- <LinearLayout
+ <com.android.settingslib.graph.BottomLabelLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
@@ -86,13 +86,14 @@
layout="@layout/usage_side_label" />
<Space
- android:layout_width="0dp"
+ android:id="@+id/spacer"
+ android:layout_width="40dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<include android:id="@+id/label_end"
layout="@layout/usage_side_label" />
- </LinearLayout>
+ </com.android.settingslib.graph.BottomLabelLayout>
</LinearLayout>
</LinearLayout>
diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/StorageStatsSource.java b/packages/SettingsLib/src/com/android/settingslib/applications/StorageStatsSource.java
index 34fdc9ddd99d..a8f6f025b6d5 100644
--- a/packages/SettingsLib/src/com/android/settingslib/applications/StorageStatsSource.java
+++ b/packages/SettingsLib/src/com/android/settingslib/applications/StorageStatsSource.java
@@ -63,15 +63,17 @@ public class StorageStatsSource {
public long audioBytes;
public long videoBytes;
public long imageBytes;
+ public long appBytes;
/** Convenience method for testing. */
@VisibleForTesting
public ExternalStorageStats(
- long totalBytes, long audioBytes, long videoBytes, long imageBytes) {
+ long totalBytes, long audioBytes, long videoBytes, long imageBytes, long appBytes) {
this.totalBytes = totalBytes;
this.audioBytes = audioBytes;
this.videoBytes = videoBytes;
this.imageBytes = imageBytes;
+ this.appBytes = appBytes;
}
/**
@@ -84,6 +86,7 @@ public class StorageStatsSource {
audioBytes = stats.getAudioBytes();
videoBytes = stats.getVideoBytes();
imageBytes = stats.getImageBytes();
+ appBytes = stats.getAppBytes();
}
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/graph/BottomLabelLayout.java b/packages/SettingsLib/src/com/android/settingslib/graph/BottomLabelLayout.java
new file mode 100644
index 000000000000..8161dd4bb934
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/graph/BottomLabelLayout.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2017 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.settingslib.graph;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.support.annotation.VisibleForTesting;
+import android.util.AttributeSet;
+import android.view.Gravity;
+import android.view.View;
+import android.widget.LinearLayout;
+
+import com.android.settingslib.R;
+
+/**
+ * An extension of LinearLayout that automatically switches to vertical
+ * orientation when it can't fit its child views horizontally.
+ *
+ * Main logic in this class comes from {@link android.support.v7.widget.ButtonBarLayout}.
+ * Compared with {@link android.support.v7.widget.ButtonBarLayout}, this layout won't reverse
+ * children's order and won't update the minimum height
+ */
+public class BottomLabelLayout extends LinearLayout {
+ private static final String TAG = "BottomLabelLayout";
+
+ public BottomLabelLayout(Context context,
+ @Nullable AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
+ final boolean isStacked = isStacked();
+ boolean needsRemeasure = false;
+
+ // If we're not stacked, make sure the measure spec is AT_MOST rather
+ // than EXACTLY. This ensures that we'll still get TOO_SMALL so that we
+ // know to stack the buttons.
+ final int initialWidthMeasureSpec;
+ if (!isStacked && MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY) {
+ initialWidthMeasureSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.AT_MOST);
+
+ // We'll need to remeasure again to fill excess space.
+ needsRemeasure = true;
+ } else {
+ initialWidthMeasureSpec = widthMeasureSpec;
+ }
+
+ super.onMeasure(initialWidthMeasureSpec, heightMeasureSpec);
+ if (!isStacked) {
+ final int measuredWidth = getMeasuredWidthAndState();
+ final int measuredWidthState = measuredWidth & View.MEASURED_STATE_MASK;
+
+ if (measuredWidthState == View.MEASURED_STATE_TOO_SMALL) {
+ setStacked(true);
+ // Measure again in the new orientation.
+ needsRemeasure = true;
+ }
+ }
+
+ if (needsRemeasure) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ }
+
+ }
+
+ @VisibleForTesting
+ void setStacked(boolean stacked) {
+ setOrientation(stacked ? LinearLayout.VERTICAL : LinearLayout.HORIZONTAL);
+ setGravity(stacked ? Gravity.START : Gravity.BOTTOM);
+
+ final View spacer = findViewById(R.id.spacer);
+ if (spacer != null) {
+ spacer.setVisibility(stacked ? View.GONE : View.VISIBLE);
+ }
+ }
+
+ private boolean isStacked() {
+ return getOrientation() == LinearLayout.VERTICAL;
+ }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/graph/BottomLabelLayoutTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/graph/BottomLabelLayoutTest.java
new file mode 100644
index 000000000000..ec217230af95
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/graph/BottomLabelLayoutTest.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2017 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.settingslib.graph;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.view.View;
+import android.widget.LinearLayout;
+import android.widget.Space;
+
+import com.android.settingslib.R;
+import com.android.settingslib.TestConfig;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+@RunWith(RobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class BottomLabelLayoutTest {
+ private BottomLabelLayout mBottomLabelLayout;
+ private Context mContext;
+ private Space mSpace;
+
+ @Before
+ public void setUp() {
+ mContext = RuntimeEnvironment.application;
+ mBottomLabelLayout = new BottomLabelLayout(mContext, null);
+ mBottomLabelLayout.setOrientation(LinearLayout.HORIZONTAL);
+
+ mSpace = new Space(mContext);
+ mSpace.setId(R.id.spacer);
+ mBottomLabelLayout.addView(mSpace);
+ }
+
+ @Test
+ public void testSetStacked_stackedTrue_layoutVertical() {
+ mBottomLabelLayout.setStacked(true);
+
+ assertThat(mBottomLabelLayout.getOrientation()).isEqualTo(LinearLayout.VERTICAL);
+ assertThat(mSpace.getVisibility()).isEqualTo(View.GONE);
+ }
+
+ @Test
+ public void testSetStacked_stackedFalse_layoutHorizontal() {
+ mBottomLabelLayout.setStacked(false);
+
+ assertThat(mBottomLabelLayout.getOrientation()).isEqualTo(LinearLayout.HORIZONTAL);
+ assertThat(mSpace.getVisibility()).isEqualTo(View.VISIBLE);
+ }
+}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index 930935914967..b328933cd1c5 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -888,8 +888,20 @@ class SettingsProtoDumpUtil {
Settings.Global.ENABLE_EPHEMERAL_FEATURE,
GlobalSettingsProto.ENABLE_EPHEMERAL_FEATURE);
dumpSetting(s, p,
- Settings.Global.UNINSTALLED_INSTANT_APP_CACHE_DURATION_MILLIS,
- GlobalSettingsProto.UNINSTALLED_EPHEMERAL_APP_CACHE_DURATION_MILLIS);
+ Settings.Global.UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
+ GlobalSettingsProto.UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD);
+ dumpSetting(s, p,
+ Settings.Global.UNINSTALLED_INSTANT_APP_MAX_CACHE_PERIOD,
+ GlobalSettingsProto.UNINSTALLED_INSTANT_APP_MAX_CACHE_PERIOD);
+ dumpSetting(s, p,
+ Settings.Global.INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
+ GlobalSettingsProto.INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD);
+ dumpSetting(s, p,
+ Settings.Global.INSTALLED_INSTANT_APP_MAX_CACHE_PERIOD,
+ GlobalSettingsProto.INSTALLED_INSTANT_APP_MAX_CACHE_PERIOD);
+ dumpSetting(s, p,
+ Settings.Global.UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD,
+ GlobalSettingsProto.UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD);
dumpSetting(s, p,
Settings.Global.ALLOW_USER_SWITCHING_WHEN_SYSTEM_USER_LOCKED,
GlobalSettingsProto.ALLOW_USER_SWITCHING_WHEN_SYSTEM_USER_LOCKED);
diff --git a/packages/Shell/src/com/android/shell/BugreportProgressService.java b/packages/Shell/src/com/android/shell/BugreportProgressService.java
index 1ddbcad8e844..348b02aeda4a 100644
--- a/packages/Shell/src/com/android/shell/BugreportProgressService.java
+++ b/packages/Shell/src/com/android/shell/BugreportProgressService.java
@@ -966,17 +966,24 @@ public class BugreportProgressService extends Service {
}
final Intent notifIntent;
+ boolean useChooser = true;
// Send through warning dialog by default
if (getWarningState(mContext, STATE_UNKNOWN) != STATE_HIDE) {
notifIntent = buildWarningIntent(mContext, sendIntent);
+ // No need to show a chooser in this case.
+ useChooser = false;
} else {
notifIntent = sendIntent;
}
notifIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// Send the share intent...
- sendShareIntent(mContext, notifIntent);
+ if (useChooser) {
+ sendShareIntent(mContext, notifIntent);
+ } else {
+ mContext.startActivity(notifIntent);
+ }
// ... and stop watching this process.
stopProgress(id);
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 79b02a5286e0..c4e134b92ec7 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -531,7 +531,7 @@
<activity
android:name=".settings.BrightnessDialog"
android:label="@string/quick_settings_brightness_dialog_title"
- android:theme="@android:style/Theme.DeviceDefault.Light.Dialog"
+ android:theme="@*android:style/Theme.DeviceDefault.QuickSettings.Dialog"
android:finishOnCloseSystemDialogs="true"
android:launchMode="singleInstance"
android:excludeFromRecents="true"
diff --git a/packages/SystemUI/res/drawable/ic_qs_signal_1x.xml b/packages/SystemUI/res/drawable/ic_qs_signal_1x.xml
deleted file mode 100644
index 195849a932be..000000000000
--- a/packages/SystemUI/res/drawable/ic_qs_signal_1x.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<!--
-Copyright (C) 2014 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:width="32.0dp"
- android:height="32dp"
- android:viewportWidth="12.0"
- android:viewportHeight="12.0">
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M3.500000,11.000000L1.800000,11.000000L1.800000,4.400000L0.200000,5.100000L0.200000,3.700000l3.100000,-1.300000l0.200000,0.000000L3.500000,11.000000z"/>
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M8.600000,5.500000l1.200000,-3.000000l1.900000,0.000000L9.700000,6.700000l2.200000,4.300000L9.900000,11.000000L8.700000,7.900000L7.400000,11.000000L5.500000,11.000000l2.100000,-4.300000L5.600000,2.500000l1.900000,0.000000L8.600000,5.500000z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_signal_3g.xml b/packages/SystemUI/res/drawable/ic_qs_signal_3g.xml
deleted file mode 100644
index 68c43074d33f..000000000000
--- a/packages/SystemUI/res/drawable/ic_qs_signal_3g.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<!--
-Copyright (C) 2014 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:width="32dp"
- android:height="32dp"
- android:viewportWidth="13.0"
- android:viewportHeight="13.0">
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M2.000000,6.000000l0.800000,0.000000c0.300000,0.000000 0.500000,-0.100000 0.700000,-0.300000s0.200000,-0.500000 0.200000,-0.900000c0.000000,-0.300000 -0.100000,-0.600000 -0.200000,-0.800000S3.200000,3.700000 2.900000,3.700000C2.700000,3.700000 2.500000,3.800000 2.300000,4.000000S2.100000,4.400000 2.100000,4.700000L0.500000,4.700000C0.500000,4.000000 0.700000,3.400000 1.100000,3.000000s1.000000,-0.600000 1.700000,-0.600000c0.800000,0.000000 1.400000,0.200000 1.900000,0.600000s0.700000,1.000000 0.700000,1.800000c0.000000,0.400000 -0.100000,0.700000 -0.300000,1.100000S4.600000,6.500000 4.300000,6.600000C4.700000,6.800000 5.000000,7.100000 5.200000,7.400000s0.300000,0.700000 0.300000,1.200000c0.000000,0.800000 -0.200000,1.400000 -0.700000,1.800000s-1.100000,0.700000 -1.900000,0.700000c-0.700000,0.000000 -1.300000,-0.200000 -1.800000,-0.600000s-0.700000,-1.000000 -0.700000,-1.800000L2.000000,8.700000C2.000000,9.000000 2.100000,9.300000 2.300000,9.500000s0.400000,0.300000 0.600000,0.300000c0.300000,0.000000 0.500000,-0.100000 0.700000,-0.300000S3.900000,9.000000 3.900000,8.600000c0.000000,-0.500000 -0.100000,-0.800000 -0.300000,-1.000000S3.200000,7.300000 2.800000,7.300000L2.000000,7.300000L2.000000,6.000000z"/>
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M12.500000,9.900000c-0.200000,0.400000 -0.600000,0.700000 -1.000000,0.900000s-1.000000,0.400000 -1.800000,0.400000c-0.900000,0.000000 -1.700000,-0.300000 -2.200000,-0.800000S6.700000,9.000000 6.700000,7.900000L6.700000,5.600000c0.000000,-1.100000 0.300000,-1.900000 0.800000,-2.400000s1.200000,-0.800000 2.100000,-0.800000c1.000000,0.000000 1.700000,0.200000 2.100000,0.700000s0.700000,1.200000 0.700000,2.100000l-1.600000,0.000000c0.000000,-0.500000 -0.100000,-0.900000 -0.200000,-1.100000s-0.500000,-0.300000 -0.900000,-0.300000c-0.400000,0.000000 -0.700000,0.200000 -0.900000,0.500000S8.400000,5.000000 8.400000,5.600000l0.000000,2.300000c0.000000,0.700000 0.100000,1.100000 0.300000,1.400000s0.600000,0.500000 1.000000,0.500000c0.300000,0.000000 0.600000,0.000000 0.700000,-0.100000s0.300000,-0.200000 0.400000,-0.300000L10.799999,7.800000L9.600000,7.800000L9.600000,6.600000l2.900000,0.000000L12.500000,9.900000z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_signal_4g.xml b/packages/SystemUI/res/drawable/ic_qs_signal_4g.xml
deleted file mode 100644
index 61ecc9c02a45..000000000000
--- a/packages/SystemUI/res/drawable/ic_qs_signal_4g.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<!--
-Copyright (C) 2014 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:width="32.0dp"
- android:height="32dp"
- android:viewportWidth="12.0"
- android:viewportHeight="12.0">
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M4.600000,7.800000l0.700000,0.000000l0.000000,1.300000L4.600000,9.100000L4.600000,11.000000L3.000000,11.000000L3.000000,9.200000L0.100000,9.200000L0.000000,8.100000L3.000000,2.500000l1.700000,0.000000L4.700000,7.800000zM1.600000,7.800000L3.000000,7.800000l0.000000,-3.000000L2.900000,5.000000L1.600000,7.800000z"/>
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M11.900000,9.900000c-0.200000,0.400000 -0.600000,0.700000 -1.000000,0.900000s-1.000000,0.400000 -1.800000,0.400000c-0.900000,0.000000 -1.700000,-0.300000 -2.200000,-0.800000S6.100000,9.000000 6.100000,7.900000L6.100000,5.600000c0.000000,-1.100000 0.300000,-1.900000 0.800000,-2.400000S8.100000,2.400000 9.000000,2.400000c1.000000,0.000000 1.700000,0.200000 2.100000,0.700000s0.700000,1.200000 0.700000,2.100000l-1.600000,0.000000c0.000000,-0.500000 -0.100000,-0.900000 -0.200000,-1.100000S9.500000,3.700000 9.000000,3.700000c-0.400000,0.000000 -0.700000,0.200000 -0.900000,0.500000S7.700000,5.000000 7.700000,5.600000l0.000000,2.300000c0.000000,0.700000 0.100000,1.100000 0.300000,1.400000s0.600000,0.500000 1.000000,0.500000c0.300000,0.000000 0.600000,0.000000 0.700000,-0.100000s0.300000,-0.200000 0.400000,-0.300000L10.099999,7.800000L9.000000,7.800000L9.000000,6.600000l2.900000,0.000000L11.900000,9.900000z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_signal_4g_plus.xml b/packages/SystemUI/res/drawable/ic_qs_signal_4g_plus.xml
deleted file mode 100644
index 782fbe4853d3..000000000000
--- a/packages/SystemUI/res/drawable/ic_qs_signal_4g_plus.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<!--
- Copyright (C) 2016 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:width="32.0dp"
- android:height="32.0dp"
- android:viewportWidth="19.0"
- android:viewportHeight="19.0">
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M4.6,7.8l0.7,0.0l0.0,1.3L4.6,9.1L4.6,11.0L3.0,11.0L3.0,9.2L0.1,9.2L0.0,8.2l3.0,-5.7l1.7,0.0L4.6,7.8L4.6,7.8zM1.7,7.8L3.0,7.8l0.0,-3.0L2.9,5.0L1.7,7.8z"/>
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M11.9,9.9c-0.2,0.4 -0.6,0.7 -1.0,0.9s-1.0,0.4 -1.8,0.4c-0.9,0.0 -1.7,-0.3 -2.2,-0.8S6.1,9.0 6.1,7.9L6.1,5.6c0.0,-1.1 0.3,-1.9 0.8,-2.4S8.2,2.4 9.0,2.4c1.0,0.0 1.7,0.2 2.1,0.7s0.7,1.2 0.7,2.1l-1.6,0.0c0.0,-0.5 -0.1,-0.9 -0.2,-1.1S9.5,3.7 9.0,3.7c-0.4,0.0 -0.7,0.2 -0.9,0.5S7.8,5.0 7.8,5.6l0.0,2.3c0.0,0.7 0.1,1.1 0.3,1.4c0.2,0.3 0.6,0.5 1.0,0.5c0.3,0.0 0.6,0.0 0.7,-0.1s0.3,-0.2 0.4,-0.3L10.2,7.8L9.0,7.8L9.0,6.6l2.9,0.0L11.9,9.9z"/>
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M17.7,4.4l-1.900001,0.0 0.0,-1.9 -1.2,0.0 0.0,1.9 -1.900001,0.0 0.0,1.2 1.900001,0.0 0.0,1.9 1.2,0.0 0.0,-1.9 1.900001,0.0z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_signal_disabled.xml b/packages/SystemUI/res/drawable/ic_qs_signal_disabled.xml
deleted file mode 100644
index dd5843d1183a..000000000000
--- a/packages/SystemUI/res/drawable/ic_qs_signal_disabled.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
-Copyright (C) 2014 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:autoMirrored="true"
- android:width="32dp"
- android:height="32dp"
- android:viewportWidth="24.0"
- android:viewportHeight="24.0">
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M21.799999,22.299999l-1.199999,-1.299999 0.000000,0.000000 -9.600000,-10.000000 0.000000,0.000000 -6.400000,-6.700000 -1.300000,1.300000 6.400000,6.700000 -8.700000,8.700000 16.900000,0.000000 2.600000,2.700001z"/>
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M21.000000,1.000000l-8.600000,8.600000 8.600000,9.100000z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_signal_e.xml b/packages/SystemUI/res/drawable/ic_qs_signal_e.xml
deleted file mode 100644
index 42321263f397..000000000000
--- a/packages/SystemUI/res/drawable/ic_qs_signal_e.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<!--
-Copyright (C) 2014 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:width="32dp"
- android:height="32dp"
- android:viewportWidth="13.0"
- android:viewportHeight="13.0">
- <group
- android:translateX="3.5" >
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M4.400000,7.300000L1.700000,7.300000l0.000000,2.400000l3.300000,0.000000L5.000000,11.000000L0.000000,11.000000L0.000000,2.500000l4.900000,0.000000l0.000000,1.300000L1.700000,3.800000l0.000000,2.100000l2.800000,0.000000L4.500000,7.300000z"/>
- </group>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_signal_g.xml b/packages/SystemUI/res/drawable/ic_qs_signal_g.xml
deleted file mode 100644
index 0c512d74ce31..000000000000
--- a/packages/SystemUI/res/drawable/ic_qs_signal_g.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<!--
-Copyright (C) 2014 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:width="32dp"
- android:height="32dp"
- android:viewportWidth="13.0"
- android:viewportHeight="13.0">
- <group android:translateX="3.5" >
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M6.500000,9.900000c-0.200000,0.400000 -0.600000,0.700000 -1.000000,0.900000s-1.000000,0.400000 -1.800000,0.400000c-0.900000,0.000000 -1.700000,-0.300000 -2.200000,-0.800000S0.700000,9.000000 0.700000,7.900000L0.700000,5.600000c0.000000,-1.100000 0.300000,-1.900000 0.800000,-2.400000s1.200000,-0.800000 2.100000,-0.800000c1.000000,0.000000 1.700000,0.200000 2.100000,0.700000s0.700000,1.200000 0.700000,2.100000L4.700000,5.200000c0.000000,-0.500000 -0.100000,-0.900000 -0.200000,-1.100000S4.000000,3.700000 3.600000,3.700000c-0.400000,0.000000 -0.700000,0.200000 -0.900000,0.500000S2.300000,5.000000 2.300000,5.600000l0.000000,2.300000c0.000000,0.700000 0.100000,1.100000 0.300000,1.400000s0.600000,0.500000 1.000000,0.500000c0.300000,0.000000 0.600000,0.000000 0.700000,-0.100000s0.300000,-0.200000 0.400000,-0.300000L4.700000,7.800000L3.500000,7.800000L3.500000,6.600000l2.900000,0.000000L6.400000,9.900000z"/>
- </group>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_signal_h.xml b/packages/SystemUI/res/drawable/ic_qs_signal_h.xml
deleted file mode 100644
index b9572b26501b..000000000000
--- a/packages/SystemUI/res/drawable/ic_qs_signal_h.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<!--
-Copyright (C) 2014 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:width="32dp"
- android:height="32dp"
- android:viewportWidth="13.0"
- android:viewportHeight="13.0">
- <group
- android:translateX="3.5" >
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M6.000000,11.000000L4.400000,11.000000L4.400000,7.500000L1.700000,7.500000L1.700000,11.000000L0.000000,11.000000L0.000000,2.500000l1.700000,0.000000l0.000000,3.700000l2.700000,0.000000L4.400000,2.500000L6.000000,2.500000L6.000000,11.000000z"/>
- </group>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_signal_lte.xml b/packages/SystemUI/res/drawable/ic_qs_signal_lte.xml
deleted file mode 100644
index a381d03e272a..000000000000
--- a/packages/SystemUI/res/drawable/ic_qs_signal_lte.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<!--
-Copyright (C) 2014 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:width="32dp"
- android:height="32dp"
- android:viewportWidth="13.0"
- android:viewportHeight="13.0">
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M2.000000,9.700000l2.000000,0.000000L4.000000,11.000000L0.300000,11.000000L0.300000,2.500000L2.000000,2.500000L2.000000,9.700000z"/>
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M8.300000,3.800000L7.000000,3.800000L7.000000,11.000000L5.300000,11.000000L5.300000,3.800000L4.000000,3.800000L4.000000,2.500000l4.300000,0.000000L8.300000,3.800000z"/>
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M12.400000,7.300000l-1.700000,0.000000l0.000000,2.400000l2.100000,0.000000L12.799999,11.000000L9.000000,11.000000L9.000000,2.500000l3.700000,0.000000l0.000000,1.300000l-2.100000,0.000000l0.000000,2.100000l1.700000,0.000000L12.300000,7.300000z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_signal_lte_plus.xml b/packages/SystemUI/res/drawable/ic_qs_signal_lte_plus.xml
deleted file mode 100644
index 3bed28a33609..000000000000
--- a/packages/SystemUI/res/drawable/ic_qs_signal_lte_plus.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<!--
- Copyright (C) 2016 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:width="32.0dp"
- android:height="32.0dp"
- android:viewportWidth="24.0"
- android:viewportHeight="24.0">
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M2.0,9.7l2.0,0.0L4.0,11.0L0.4,11.0L0.4,2.5L2.0,2.5L2.0,9.7z"/>
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M8.3,3.8L7.0,3.8L7.0,11.0L5.4,11.0L5.4,3.8L4.0,3.8L4.0,2.5l4.3,0.0L8.3,3.8z"/>
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M12.4,7.3l-1.7,0.0l0.0,2.4l2.1,0.0L12.799999,11.0L9.0,11.0L9.0,2.5l3.7,0.0l0.0,1.3l-2.1,0.0l0.0,2.1l1.7,0.0L12.4,7.3L12.4,7.3z"/>
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M18.4,4.4l-1.9,0.0 0.0,-1.9 -1.2,0.0 0.0,1.9 -1.900001,0.0 0.0,1.2 1.900001,0.0 0.0,1.9 1.2,0.0 0.0,-1.9 1.9,0.0z"/>
-</vector>
diff --git a/packages/SystemUI/res/layout/qs_footer.xml b/packages/SystemUI/res/layout/qs_footer.xml
index 577be2fd684b..871d1f361dd0 100644
--- a/packages/SystemUI/res/layout/qs_footer.xml
+++ b/packages/SystemUI/res/layout/qs_footer.xml
@@ -27,6 +27,7 @@
android:clipChildren="false"
android:clipToPadding="false"
android:paddingTop="0dp"
+ android:background="#00000000"
android:gravity="center_vertical"
android:orientation="horizontal">
diff --git a/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml b/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
index 005e9552a554..66c5dd5b5275 100644
--- a/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
+++ b/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
@@ -29,7 +29,6 @@
android:clickable="false"
android:clipChildren="false"
android:clipToPadding="false"
- android:paddingBottom="48dp"
android:paddingTop="0dp"
android:paddingEnd="0dp"
android:paddingStart="0dp">
@@ -83,10 +82,9 @@
<com.android.systemui.qs.QuickQSPanel
android:id="@+id/quick_qs_panel"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
+ android:layout_height="48dp"
android:layout_alignParentEnd="true"
- android:layout_marginTop="36dp"
- android:layout_marginBottom="8dp"
+ android:layout_marginTop="31dp"
android:layout_alignParentTop="true"
android:accessibilityTraversalAfter="@+id/date_time_group"
android:accessibilityTraversalBefore="@id/expand_indicator"
@@ -95,8 +93,7 @@
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:focusable="true"
- android:importantForAccessibility="yes"
- android:paddingTop="0dp"/>
+ android:importantForAccessibility="yes" />
<com.android.systemui.statusbar.AlphaOptimizedImageView
android:id="@+id/qs_detail_header_progress"
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 36ceff57544f..3fce776e2e11 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -573,6 +573,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 minute"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 minute"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 uur"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"ONTDOEN"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"Sluimer vir <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"Batterygebruik"</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index f9edd7c7b54f..a217d3cd8ee9 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -573,6 +573,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 ደቂቃዎች"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 ደቂቃዎች"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 ሰዓት"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"ቀልብስ"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"ለ<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> አሸልቧል"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"የባትሪ አጠቃቀም"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 4ab49a026a91..1c1fbbce444c 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -589,6 +589,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"١٥ دقيقة"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"٣۰ دقيقة"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"ساعة واحدة"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"تراجع"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"تم تأجيل الإشعار لمدة <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"استخدام البطارية"</string>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index aca6a3b31e07..24b71e7d5515 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -573,6 +573,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 dəqiqə"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 dəqiqə"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 saat"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"GERİ QAYTARIN"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> üçün təxirə salınıb"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"Batareya istifadəsi"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 29a5e194c472..f4607300ce5d 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -577,6 +577,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 minuta"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 minuta"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 sat"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"OPOZOVI"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"Odloženo je za <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"Potrošnja baterije"</string>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 15f1d86db22a..dfad96ca84e1 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -583,6 +583,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 хвілін"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 хвілін"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 гадзіна"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"АДРАБІЦЬ"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"Адкладзена на <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"Выкарыстанне зараду"</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index b77cc9e5b3ea..be327135046e 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -573,6 +573,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 минути"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 минути"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 час"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"ОТМЯНА"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"Отложено за <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"Ползв. на батерията"</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index b9fa325880d7..822652ba8ad1 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -573,6 +573,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"১৫ মিনিট"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"৩০ মিনিট"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"১ ঘণ্টা"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"পূর্বাবস্থায় ফিরুন"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> পরে আবার মনে করানো হবে"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"ব্যাটারির ব্যবহার"</string>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 11450ae820cc..e4e02d7410d9 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -579,6 +579,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 minuta"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 minuta"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 sat"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"OPOZOVI"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"Odgođeno za <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"Potrošnja baterije"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 16f2a32185f5..c9254ef85cf3 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -573,6 +573,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 minuts"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 minuts"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 hora"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"DESFÉS"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"S\'ha posposat <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"Ús de la bateria"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index f4a45c2f2645..2ad9dbaa28b3 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -583,6 +583,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 minut"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 minut"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 hodina"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"VRÁTIT ZPĚT"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"Odloženo o <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"Využití baterie"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 55b39d56dfe4..e2852dd4bada 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -573,6 +573,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutter"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 minutter"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 time"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"FORTRYD"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"Udsat i <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"Batteriforbrug"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index bc7f1d5ffb60..b0b4323593ab 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -575,6 +575,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 Minuten"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 Minuten"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 Stunde"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"RÜCKGÄNGIG"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"Erinnerung in <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"Akkunutzung"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index bbefef459a7d..5d8703492bb2 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -573,6 +573,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 λεπτά"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 λεπτά"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 ώρα"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"ΑΝΑΙΡΕΣΗ"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"Σε αφύπνιση για <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"Χρήση της μπαταρίας"</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 2561d29ecb76..05c413091c1f 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -573,6 +573,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutes"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 minutes"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 hour"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"UNDO"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"Snoozed for <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"Battery usage"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 2561d29ecb76..05c413091c1f 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -573,6 +573,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutes"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 minutes"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 hour"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"UNDO"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"Snoozed for <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"Battery usage"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 2561d29ecb76..05c413091c1f 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -573,6 +573,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutes"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 minutes"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 hour"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"UNDO"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"Snoozed for <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"Battery usage"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 64a4bfebed4f..07b564d9e8ee 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -575,6 +575,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutos"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 minutos"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 hora"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"DESHACER"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"Posponer <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"Uso de la batería"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 8d9f8a58f853..3bf6a8cc003a 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -575,6 +575,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutos"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 minutos"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 hora"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"DESHACER"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"Volverá a mostrarse en <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"Uso de la batería"</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index 604d266623aa..26b460319789 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -575,6 +575,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutit"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 minutit"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"Üks tund"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"VÕTA TAGASI"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"Edasi lükatud <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"Akukasutus"</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 2c83e5b8ff62..86fd3b24efa5 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -575,6 +575,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutu"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 minutu"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 ordu"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"DESEGIN"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g>z atzeratu da"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"Bateriaren erabilera"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 1f49e9894262..5570f9edf7de 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -573,6 +573,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"۱۵ دقیقه"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"۳۰ دقیقه"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"۱ ساعت"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"واگرد"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> به تعویق افتاد"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"مصرف باتری"</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index f5b0b6b96f8e..c60c4c45aa55 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -573,6 +573,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 minuuttia"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 minuuttia"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 tunti"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"KUMOA"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"Torkku: <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"Akun käyttö"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index e615ff427574..10b0cba8a0a5 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -575,6 +575,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutes"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 minutes"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 heure"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"ANNULER"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"Reporté pour <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"Utilisation de la pile"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 811b16ce37bf..862d13fb748b 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -575,6 +575,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutes"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 minutes"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 heure"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"ANNULER"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"Répétée après <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"Utilisation batterie"</string>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 7481d1aea66d..0cb91b454b21 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -575,6 +575,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutos"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 minutos"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 hora"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"DESFACER"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"Adiouse <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"Uso de batería"</string>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index ca7a779e7f1c..7f718d98b1f6 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -573,6 +573,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 મિનિટ"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 મિનિટ"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 કલાક"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"પૂર્વવત્ કરો"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> માટે સ્નૂઝ કરો"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"બૅટરી વપરાશ"</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 92bc82e033d0..613d8d302eb7 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -573,6 +573,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 मिनट"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 मिनट"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 घंटा"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"पहले जैसा करें"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> के लिए याद दिलाया गया"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"बैटरी उपयोग"</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 2065b8c42101..e716f5dfa98d 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -577,6 +577,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 minuta"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 minuta"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 sat"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"PONIŠTI"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"Odgođeno <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"Potrošnja baterije"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index d1e85d91710c..fe1b12b19b54 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -573,6 +573,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 perc"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 perc"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 óra"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"VISSZAVONÁS"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"Elhalasztva: <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"Akkumulátorhasználat"</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 1189b0535af6..bdceafe86670 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -573,6 +573,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 րոպե"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 րոպե"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 ժամ"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"ՀԵՏԱՐԿԵԼ"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"Հետաձգվել է <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>ով"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"Մարտկոցի օգտագործում"</string>
diff --git a/packages/SystemUI/res/values-hy/strings_tv.xml b/packages/SystemUI/res/values-hy/strings_tv.xml
index ac7711b39ecc..0493584e39a7 100644
--- a/packages/SystemUI/res/values-hy/strings_tv.xml
+++ b/packages/SystemUI/res/values-hy/strings_tv.xml
@@ -19,7 +19,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="notification_channel_tv_pip" msgid="134047986446577723">"Նկարը նկարի մեջ"</string>
+ <string name="notification_channel_tv_pip" msgid="134047986446577723">"Նկար նկարի մեջ"</string>
<string name="pip_notification_unknown_title" msgid="6289156118095849438">"(Առանց վերնագրի ծրագիր)"</string>
<string name="pip_close" msgid="3480680679023423574">"Փակել PIP-ն"</string>
<string name="pip_fullscreen" msgid="8604643018538487816">"Լիէկրան"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 25a2a14b0afa..2853d9d291dd 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -573,6 +573,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 menit"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 menit"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 jam"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"URUNG"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"Ditunda selama <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"Pemakaian baterai"</string>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index d2b97872344f..f56720ae1d35 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -573,6 +573,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 mínútur"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 mínútur"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 klukkustund"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"AFTURKALLA"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"Þaggað í <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"Rafhlöðunotkun"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 01b2464ed938..cfe5deb3e6e5 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -575,6 +575,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 minuti"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 minuti"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 ora"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"ANNULLA"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"Posticipato di <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"Utilizzo batteria"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index b7e950819f02..4b1236e5758b 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -581,6 +581,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 דקות"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 דקות"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"שעה אחת"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"ביטול"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"נדחה לטיפול בעוד <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"שימוש בסוללה"</string>
@@ -638,7 +640,7 @@
<string name="headset" msgid="4534219457597457353">"אוזניות"</string>
<string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"אוזניות מחוברות"</string>
<string name="accessibility_status_bar_headset" msgid="8666419213072449202">"אוזניות מחוברות"</string>
- <string name="data_saver" msgid="5037565123367048522">"‏חוסך הנתונים&lt;br&gt;(Data Saver)"</string>
+ <string name="data_saver" msgid="5037565123367048522">"‏חוסך הנתונים (Data Saver)"</string>
<string name="accessibility_data_saver_on" msgid="8454111686783887148">"‏חוסך הנתונים (Data Saver) פועל"</string>
<string name="accessibility_data_saver_off" msgid="8841582529453005337">"‏חוסך הנתונים (Data Saver) כבוי"</string>
<string name="switch_bar_on" msgid="1142437840752794229">"פועל"</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 15fccc618d4e..4c7c85e43570 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -575,6 +575,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15分"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30分"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1時間"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"元に戻す"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"スヌーズ: <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"電池の使用状況"</string>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index 17320ef7eaf0..d8cbc199ad5b 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -573,6 +573,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 წუთი"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 წუთი"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 საათი"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"მოქმედების გაუქმება"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"ჩაჩუმებული იქნება <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"ბატარეის მოხმარება"</string>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 724af886ebce..f71601eb9b21 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -573,6 +573,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 минут"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 минут"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 сағат"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"КЕРІ ҚАЙТАРУ"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> кідіртілді"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"Батареяны пайдалану"</string>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 229e345f82ed..9aed68928016 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -573,6 +573,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 នាទី"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 នាទី"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 ម៉ោង"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"មិន​ធ្វើវិញ"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"បាន​ផ្អាក​រយៈពេល <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"ការប្រើប្រាស់ថ្ម"</string>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index 9c87cf7fd0bd..cd85f749d288 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -573,6 +573,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 ನಿಮಿಷಗಳು"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 ನಿಮಿಷಗಳು"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 ಗಂಟೆ"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"ರದ್ದುಮಾಡಿ"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> ಗೆ ಸ್ನೂಜ್ ಮಾಡಲಾಗಿದೆ"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"ಬ್ಯಾಟರಿ ಬಳಕೆ"</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 273b39051fcb..a237ba9926b7 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -575,6 +575,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15분"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30분"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1시간"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"실행취소"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> 동안 일시 중지됨"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"배터리 사용량"</string>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index 209d38d80263..1127c24c0b10 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -573,6 +573,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 мүнөт"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 мүнөт"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 саат"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"КАЙТАРУУ"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> тындырылды"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"Батарея колдонулушу"</string>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 536958370d53..42baec6d95ca 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -573,6 +573,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 ນາທີ"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 ນາທີ"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 ຊົ່ວໂມງ"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"ຍົກເລີກ"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"ເລື່ອນໄປ <xliff:g id="TIME_AMOUNT">%1$s</xliff:g> ນາທີແລ້ວ"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"ການໃຊ້ແບັດເຕີຣີ"</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index cc123cf179d9..ce403ef8c6cb 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -581,6 +581,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 min."</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 min."</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 val."</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"ANULIUOTI"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"Nustatyta snausti <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"Akum. energ. vartoj."</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 9bd3c65bf260..28758ca7609b 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -577,6 +577,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 minūtes"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 minūtes"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 stunda"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"ATSAUKT"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"Atlikts: <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"Akumulatora lietojums"</string>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 519cfac30323..3355090c121f 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -573,6 +573,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 минути"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 минути"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 час"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"ВРАТИ"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"Одложено за <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"Користење батерија"</string>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index a7aa20a401e0..a41e305eea55 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -573,6 +573,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 മിനിറ്റ്"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 മിനിറ്റ്"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"ഒരു മണിക്കൂർ"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"പഴയപടിയാക്കുക"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> സമയത്തേക്ക് സ്‌നൂസ് ‌ചെയ്‌തു"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"ബാറ്ററി ഉപയോഗം"</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 7144c2849406..3a33cd6cb01f 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -573,6 +573,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 минут"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 минут"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 цаг"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"БУЦААХ"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g>-д түр хойшлуулсан"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"Тэжээл ашиглалт"</string>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index f7360c9d6944..ad107d8390f2 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -573,6 +573,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 मिनिटे"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 मिनिटे"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 तास"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"पूर्ववत करा"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> साठी स्नूझ करा"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"बॅटरी वापर"</string>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index a05dd2b4984c..898cdfc849f2 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -573,6 +573,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 minit"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 minit"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 jam"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"BUAT ASAL"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"Ditunda selama <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"Penggunaan bateri"</string>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 797aa977c8d5..346bbe245e32 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -573,6 +573,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"၁၅ မိနစ်"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"၃၀ မိနစ်"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"၁ နာရီ"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"တစ်ဆင့် နောက်ပြန်ပြန်ပါ"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> ဆိုင်းငံ့ရန်"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"ဘက်ထရီ အသုံးပြုမှု"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index f59367fcedaa..a13c09745958 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -573,6 +573,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutter"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 minutter"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 time"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"ANGRE"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"Slumrer i <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"Batteribruk"</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index fb49b17bee2a..c8cd38384b7b 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -573,6 +573,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"१५ मिनेट"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"३० मिनेट"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"१ घन्टा"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"अनडू गर्नुहोस्"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> का लागि स्नुज गरियो"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"ब्याट्री उपयोग"</string>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index b708e6631789..78077e973050 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -573,6 +573,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 minuten"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 minuten"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 uur"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"ONGEDAAN MAKEN"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"Snoozefunctie <xliff:g id="TIME_AMOUNT">%1$s</xliff:g> actief"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"Accugebruik"</string>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 1039e3407678..07a0e8222e07 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -573,6 +573,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 ਮਿੰਟ"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 ਮਿੰਟ"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 ਘੰਟਾ"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"ਅਣਕੀਤਾ ਕਰੋ"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> ਲਈ ਸਨੂਜ਼ ਕੀਤਾ ਗਿਆ"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"ਬੈਟਰੀ ਵਰਤੋਂ"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 91a7c09c5752..03b5ed9e9acd 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -581,6 +581,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 min"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 min"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 godz."</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"COFNIJ"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"Odłożono na <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"Wykorzystanie baterii"</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index ab705e7f58fb..8ef330b7a447 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -575,6 +575,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutos"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 minutos"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"Uma hora"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"DESFAZER"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"Adiada para <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"Uso da bateria"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 74089b2982cf..49f14804ea58 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -444,29 +444,29 @@
<string name="monitoring_description_managed_profile_ca_certificate" msgid="4683248196789897964">"A sua entidade instalou uma autoridade de certificação no seu perfil de trabalho. O tráfego da sua rede segura pode ser monitorizado ou alterado."</string>
<string name="monitoring_description_ca_certificate" msgid="7886985418413598352">"Está instalada uma autoridade de certificação neste dispositivo. O tráfego da sua rede segura pode ser monitorizado ou alterado."</string>
<string name="monitoring_description_management_network_logging" msgid="7184005419733060736">"O administrador ativou os registos de rede, que monitorizam o tráfego no seu dispositivo."</string>
- <string name="monitoring_description_named_vpn" msgid="7403457334088909254">"Está ligado à rede <xliff:g id="VPN_APP">%1$s</xliff:g>, que pode monitorizar a sua atividade de rede, incluindo emails, aplicações e Websites."</string>
- <string name="monitoring_description_two_named_vpns" msgid="4198511413729213802">"Está ligado às redes <xliff:g id="VPN_APP_0">%1$s</xliff:g> e <xliff:g id="VPN_APP_1">%2$s</xliff:g>, que podem monitorizar a sua atividade de rede, incluindo emails, aplicações e Websites."</string>
- <string name="monitoring_description_managed_profile_named_vpn" msgid="1427905889862420559">"O seu perfil de trabalho está ligado à rede <xliff:g id="VPN_APP">%1$s</xliff:g>, que pode monitorizar a sua atividade de rede, incluindo emails, aplicações e Websites."</string>
- <string name="monitoring_description_personal_profile_named_vpn" msgid="3133980926929069283">"O seu perfil pessoal está ligado à rede <xliff:g id="VPN_APP">%1$s</xliff:g>, que pode monitorizar a sua atividade de rede, incluindo emails, aplicações e Websites."</string>
+ <string name="monitoring_description_named_vpn" msgid="7403457334088909254">"Está ligado à rede <xliff:g id="VPN_APP">%1$s</xliff:g>, que pode monitorizar a sua atividade de rede, incluindo emails, aplicações e Sites."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="4198511413729213802">"Está ligado às redes <xliff:g id="VPN_APP_0">%1$s</xliff:g> e <xliff:g id="VPN_APP_1">%2$s</xliff:g>, que podem monitorizar a sua atividade de rede, incluindo emails, aplicações e Sites."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="1427905889862420559">"O seu perfil de trabalho está ligado à rede <xliff:g id="VPN_APP">%1$s</xliff:g>, que pode monitorizar a sua atividade de rede, incluindo emails, aplicações e Sites."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="3133980926929069283">"O seu perfil pessoal está ligado à rede <xliff:g id="VPN_APP">%1$s</xliff:g>, que pode monitorizar a sua atividade de rede, incluindo emails, aplicações e Sites."</string>
<string name="monitoring_description_do_header_generic" msgid="96588491028288691">"O seu dispositivo é gerido pelo <xliff:g id="DEVICE_OWNER_APP">%1$s</xliff:g>."</string>
<string name="monitoring_description_do_header_with_name" msgid="5511133708978206460">"A <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> utiliza o <xliff:g id="DEVICE_OWNER_APP">%2$s</xliff:g> para gerir o seu dispositivo."</string>
<string name="monitoring_description_do_body" msgid="3639594537660975895">"O administ. pode monitorizar e gerir definições, acesso empresarial, aplic. e dados associados ao dispositivo, bem como inf. de localiz. do disp."</string>
<string name="monitoring_description_do_learn_more_separator" msgid="3785251953067436862">" "</string>
<string name="monitoring_description_do_learn_more" msgid="1849514470437907421">"Saiba mais"</string>
- <string name="monitoring_description_do_body_vpn" msgid="8255218762488901796">"Está ligado à rede <xliff:g id="VPN_APP">%1$s</xliff:g>, que pode monitorizar a sua atividade de rede, incluindo emails, aplicações e Websites."</string>
+ <string name="monitoring_description_do_body_vpn" msgid="8255218762488901796">"Está ligado à rede <xliff:g id="VPN_APP">%1$s</xliff:g>, que pode monitorizar a sua atividade de rede, incluindo emails, aplicações e Sites."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="1933186756733474388">" "</string>
<string name="monitoring_description_vpn_settings" msgid="8869300202410505143">"Abrir as definições de VPN"</string>
<string name="monitoring_description_ca_cert_settings_separator" msgid="4987350385906393626">" "</string>
<string name="monitoring_description_ca_cert_settings" msgid="5489969458872997092">"Abrir credenciais fidedignas"</string>
<string name="monitoring_description_network_logging" msgid="7223505523384076027">"O seu administrador ativou os registos de rede, que monitorizam o tráfego no seu dispositivo.\n\nPara obter mais informações, contacte o administrador."</string>
- <string name="monitoring_description_vpn" msgid="4445150119515393526">"Concedeu autorização a uma aplicação para configurar uma ligação VPN.\n\nEsta aplicação pode monitorizar a atividade do dispositivo e da rede, incluindo emails, aplicações e Websites."</string>
- <string name="monitoring_description_vpn_profile_owned" msgid="2958019119161161530">"O seu perfil de trabalho é gerido por <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nO seu administrador tem a capacidade de monitorizar a sua atividade da rede, incluindo emails, aplicações e Websites.\n\nPara obter mais informações, contacte o administrador.\n\nAlém disso, está ligado a uma VPN, que pode monitorizar a sua atividade da rede."</string>
+ <string name="monitoring_description_vpn" msgid="4445150119515393526">"Concedeu autorização a uma aplicação para configurar uma ligação VPN.\n\nEsta aplicação pode monitorizar a atividade do dispositivo e da rede, incluindo emails, aplicações e Sites."</string>
+ <string name="monitoring_description_vpn_profile_owned" msgid="2958019119161161530">"O seu perfil de trabalho é gerido por <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nO seu administrador tem a capacidade de monitorizar a sua atividade da rede, incluindo emails, aplicações e Sites.\n\nPara obter mais informações, contacte o administrador.\n\nAlém disso, está ligado a uma VPN, que pode monitorizar a sua atividade da rede."</string>
<string name="legacy_vpn_name" msgid="6604123105765737830">"VPN"</string>
- <string name="monitoring_description_app" msgid="1828472472674709532">"Está associado à aplicação <xliff:g id="APPLICATION">%1$s</xliff:g>, que pode monitorizar a sua atividade de rede, incluindo emails, aplicações e Websites."</string>
- <string name="monitoring_description_app_personal" msgid="484599052118316268">"Está ligado a <xliff:g id="APPLICATION">%1$s</xliff:g>, que pode monitorizar a atividade da rede pessoal, incluindo emails, aplicações e Websites."</string>
- <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Está ligado ao <xliff:g id="APPLICATION">%1$s</xliff:g>, que pode monitorizar a atividade da rede pessoal, incluindo emails, aplicações e Websites."</string>
- <string name="monitoring_description_app_work" msgid="4612997849787922906">"O seu perfil de trabalho é gerido pela <xliff:g id="ORGANIZATION">%1$s</xliff:g>. O perfil está associado à aplicação <xliff:g id="APPLICATION">%2$s</xliff:g>, que pode monitorizar a atividade da rede de trabalho, incluindo emails, aplicações e Websites.\n\nContacte o administrador para obter mais informações."</string>
- <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"O seu perfil de trabalho é gerido pela <xliff:g id="ORGANIZATION">%1$s</xliff:g>. O perfil está associado à aplicação <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, que pode monitorizar a atividade da rede de trabalho, incluindo emails, aplicações e Websites.\n\nTambém está associado à aplicação <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, que pode monitorizar a atividade da rede pessoal."</string>
+ <string name="monitoring_description_app" msgid="1828472472674709532">"Está associado à aplicação <xliff:g id="APPLICATION">%1$s</xliff:g>, que pode monitorizar a sua atividade de rede, incluindo emails, aplicações e Sites."</string>
+ <string name="monitoring_description_app_personal" msgid="484599052118316268">"Está ligado a <xliff:g id="APPLICATION">%1$s</xliff:g>, que pode monitorizar a atividade da rede pessoal, incluindo emails, aplicações e Sites."</string>
+ <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Está ligado ao <xliff:g id="APPLICATION">%1$s</xliff:g>, que pode monitorizar a atividade da rede pessoal, incluindo emails, aplicações e Sites."</string>
+ <string name="monitoring_description_app_work" msgid="4612997849787922906">"O seu perfil de trabalho é gerido pela <xliff:g id="ORGANIZATION">%1$s</xliff:g>. O perfil está associado à aplicação <xliff:g id="APPLICATION">%2$s</xliff:g>, que pode monitorizar a atividade da rede de trabalho, incluindo emails, aplicações e Sites.\n\nContacte o administrador para obter mais informações."</string>
+ <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"O seu perfil de trabalho é gerido pela <xliff:g id="ORGANIZATION">%1$s</xliff:g>. O perfil está associado à aplicação <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, que pode monitorizar a atividade da rede de trabalho, incluindo emails, aplicações e Sites.\n\nTambém está associado à aplicação <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, que pode monitorizar a atividade da rede pessoal."</string>
<string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"O dispositivo permanecerá bloqueado até ser desbloqueado manualmente"</string>
<string name="hidden_notifications_title" msgid="7139628534207443290">"Receber notificações mais rapidamente"</string>
<string name="hidden_notifications_text" msgid="2326409389088668981">"Ver antes de desbloquear"</string>
@@ -573,6 +573,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutos"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 minutos"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 hora"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"ANULAR"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"Suspensa por <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"Utiliz. da bateria"</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index ab705e7f58fb..8ef330b7a447 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -575,6 +575,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 minutos"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 minutos"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"Uma hora"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"DESFAZER"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"Adiada para <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"Uso da bateria"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index cadce25ee1ec..29bc5bf22584 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -579,6 +579,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 minute"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 de minute"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 oră"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"ANULAȚI"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"Amânată <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"Utilizarea bateriei"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 34939b58fec4..e593f89d6961 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -583,6 +583,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 минут"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 минут"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 час"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"ОТМЕНИТЬ"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"Отложено на <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"Уровень заряда"</string>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index 7065c83b8aa2..991be52d2a14 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -573,6 +573,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"මිනිත්තු 15"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"මිනිත්තු 30"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"පැය 1"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"අස් කරන්න"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g>ක් මදක් නතර කරන ලදී"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"බැටරි භාවිතය"</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 6e4c33bb3b1e..33793ce7795f 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -583,6 +583,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 minút"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 minút"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 hod."</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"SPÄŤ"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"Stlmené na <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"Využitie batérie"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index b0e770fbdd6c..9e03e425dcd4 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -583,6 +583,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 minut"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 minut"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 ura"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"RAZVELJAVI"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"Preloženo za <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"Poraba akumulatorja"</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index a68ec872ebb7..cbdb5b21ddbe 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -573,6 +573,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 minuta"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 minuta"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 orë"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"ZHBËJ"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"U shty për <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"Përdorimi i baterisë"</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index f4b488422d66..5c4790762b00 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -577,6 +577,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 минута"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 минута"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 сат"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"ОПОЗОВИ"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"Одложено је за <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"Потрошња батерије"</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 685c0a445a83..967e3a5a4aa0 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -573,6 +573,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 minuter"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 minuter"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 timme"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"ÅNGRA"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"Snoozad i <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"Batteriförbrukning"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 9a52d9b1e39e..82220748a875 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -573,6 +573,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"Dakika 15"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"Dakika 30"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"Saa 1"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"TENDUA"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"Imeahirishwa kwa <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"Matumizi ya betri"</string>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index 1c4b7de301f2..eb672e18e30e 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -573,6 +573,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 நிமிடங்கள்"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 நிமிடங்கள்"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 மணிநேரம்"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"செயல்தவிர்"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"உறக்கநிலையில் வைத்திருந்த நேரம்: <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"பேட்டரி உபயோகம்"</string>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 2bdabd2bcc83..b5470e75101f 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -573,6 +573,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 నిమిషాలు"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 నిమిషాలు"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 గంట"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"చర్య రద్దు చేయి"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> వరకు తాత్కాలికంగా ఆపివేయబడింది"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"బ్యాటరీ వినియోగం"</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 8077d1432642..f47cfa9b6b7f 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -64,7 +64,7 @@
<string name="usb_debugging_message" msgid="2220143855912376496">"ลายนิ้วมือหลัก RSA ของคอมพิวเตอร์คือ:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
<string name="usb_debugging_always" msgid="303335496705863070">"อนุญาตจากคอมพิวเตอร์เครื่องนี้เสมอ"</string>
<string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"ไม่อนุญาตให้แก้ไขข้อบกพร่องผ่าน USB"</string>
- <string name="usb_debugging_secondary_user_message" msgid="8572228137833020196">"ผู้ใช้ที่ลงชื่อเข้าใช้อุปกรณ์นี้อยู่ในขณะนี้ไม่สามารถเปิดการแก้ปัญหาผ่าน USB ได้ หากต้องการใช้คุณลักษณะนี้ โปรดเปลี่ยนไปเป็นผู้ใช้ที่เป็นผู้ดูแลระบบ"</string>
+ <string name="usb_debugging_secondary_user_message" msgid="8572228137833020196">"ผู้ใช้ที่ลงชื่อเข้าใช้อุปกรณ์นี้อยู่ในขณะนี้ไม่สามารถเปิดการแก้ปัญหาผ่าน USB ได้ หากต้องการใช้ฟีเจอร์นี้ โปรดเปลี่ยนไปเป็นผู้ใช้ที่เป็นผู้ดูแลระบบ"</string>
<string name="compat_mode_on" msgid="6623839244840638213">"ขยายจนเต็มหน้าจอ"</string>
<string name="compat_mode_off" msgid="4434467572461327898">"ยืดจนเต็มหน้าจอ"</string>
<string name="screenshot_saving_ticker" msgid="7403652894056693515">"กำลังบันทึกภาพหน้าจอ..."</string>
@@ -524,12 +524,12 @@
<string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"ฮอตสปอต"</string>
<string name="accessibility_managed_profile" msgid="6613641363112584120">"โปรไฟล์งาน"</string>
<string name="tuner_warning_title" msgid="7094689930793031682">"เพลิดเพลินกับบางส่วนแต่ไม่ใช่ทั้งหมด"</string>
- <string name="tuner_warning" msgid="8730648121973575701">"ตัวรับสัญญาณ UI ระบบช่วยให้คุณมีวิธีพิเศษในการปรับแต่งและกำหนดค่าส่วนติดต่อผู้ใช้ Android คุณลักษณะรุ่นทดลองเหล่านี้อาจมีการเปลี่ยนแปลง ขัดข้อง หรือหายไปในเวอร์ชันอนาคต โปรดดำเนินการด้วยความระมัดระวัง"</string>
- <string name="tuner_persistent_warning" msgid="8597333795565621795">"คุณลักษณะรุ่นทดลองเหล่านี้อาจมีการเปลี่ยนแปลง ขัดข้อง หรือหายไปในเวอร์ชันอนาคต โปรดดำเนินการด้วยความระมัดระวัง"</string>
+ <string name="tuner_warning" msgid="8730648121973575701">"ตัวรับสัญญาณ UI ระบบช่วยให้คุณมีวิธีพิเศษในการปรับแต่งและกำหนดค่าส่วนติดต่อผู้ใช้ Android ฟีเจอร์รุ่นทดลองเหล่านี้อาจมีการเปลี่ยนแปลง ขัดข้อง หรือหายไปในเวอร์ชันอนาคต โปรดดำเนินการด้วยความระมัดระวัง"</string>
+ <string name="tuner_persistent_warning" msgid="8597333795565621795">"ฟีเจอร์รุ่นทดลองเหล่านี้อาจมีการเปลี่ยนแปลง ขัดข้อง หรือหายไปในเวอร์ชันอนาคต โปรดดำเนินการด้วยความระมัดระวัง"</string>
<string name="got_it" msgid="2239653834387972602">"รับทราบ"</string>
<string name="tuner_toast" msgid="603429811084428439">"ยินดีด้วย! เพิ่มตัวรับสัญญาณ UI ระบบไปยังการตั้งค่าแล้ว"</string>
<string name="remove_from_settings" msgid="8389591916603406378">"นำออกจากการตั้งค่า"</string>
- <string name="remove_from_settings_prompt" msgid="6069085993355887748">"นำตัวรับสัญญาณ UI ระบบออกจากการตั้งค่าและหยุดใช้คุณลักษณะทั้งหมดของตัวรับสัญญาณใช่ไหม"</string>
+ <string name="remove_from_settings_prompt" msgid="6069085993355887748">"นำตัวรับสัญญาณ UI ระบบออกจากการตั้งค่าและหยุดใช้ฟีเจอร์ทั้งหมดของตัวรับสัญญาณใช่ไหม"</string>
<string name="activity_not_found" msgid="348423244327799974">"ยังไม่ได้ติดตั้งแอปพลิเคชันบนอุปกรณ์ของคุณ"</string>
<string name="clock_seconds" msgid="7689554147579179507">"แสดงวินาทีของนาฬิกา"</string>
<string name="clock_seconds_desc" msgid="6282693067130470675">"แสดงวินาทีของนาฬิกาในแถบสถานะ อาจส่งผลต่ออายุแบตเตอรี"</string>
@@ -573,6 +573,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 นาที"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 นาที"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 ชั่วโมง"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"เลิกทำ"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"ปิดเสียงเตือนชั่วคราวไว้เป็นเวลา <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"การใช้งานแบตเตอรี่"</string>
@@ -719,7 +721,7 @@
<string name="pip_phone_dismiss_hint" msgid="6351678169095923899">"ลากลงเพื่อปิด"</string>
<string name="pip_menu_title" msgid="3328510504196964712">"เมนูการแสดงผลหลายแหล่งพร้อมกัน"</string>
<string name="pip_notification_title" msgid="3204024940158161322">"<xliff:g id="NAME">%s</xliff:g> ใช้การแสดงผลหลายแหล่งพร้อมกัน"</string>
- <string name="pip_notification_message" msgid="4171698133469539591">"หากคุณไม่ต้องการให้ <xliff:g id="NAME">%s</xliff:g> ใช้คุณลักษณะนี้ ให้แตะเพื่อเปิดการตั้งค่าแล้วปิดคุณลักษณะ"</string>
+ <string name="pip_notification_message" msgid="4171698133469539591">"หากคุณไม่ต้องการให้ <xliff:g id="NAME">%s</xliff:g> ใช้ฟีเจอร์นี้ ให้แตะเพื่อเปิดการตั้งค่าแล้วปิดฟีเจอร์"</string>
<string name="pip_play" msgid="1417176722760265888">"เล่น"</string>
<string name="pip_pause" msgid="8881063404466476571">"หยุดชั่วคราว"</string>
<string name="pip_skip_to_next" msgid="1948440006726306284">"ข้ามไปรายการถัดไป"</string>
@@ -728,7 +730,7 @@
<string name="thermal_shutdown_message" msgid="9006456746902370523">"ขณะนี้โทรศัพท์ทำงานเป็นปกติ"</string>
<string name="thermal_shutdown_dialog_message" msgid="566347880005304139">"โทรศัพท์ร้อนเกินไปจึงปิดเครื่องเพื่อให้เย็นลง ขณะนี้โทรศัพท์ทำงานเป็นปกติ\n\nโทรศัพท์อาจร้อนเกินไปหากคุณ\n • ใช้แอปที่ใช้ทรัพยากรมาก (เช่น เกม วิดีโอ หรือแอปการนำทาง)\n • ดาวน์โหลดหรืออัปโหลดไฟล์ขนาดใหญ่\n • ใช้โทรศัพท์ในอุณหภูมิที่สูง"</string>
<string name="high_temp_title" msgid="4589508026407318374">"โทรศัพท์เริ่มเครื่องร้อน"</string>
- <string name="high_temp_notif_message" msgid="5642466103153429279">"คุณลักษณะบางอย่างจะใช้งานได้จำกัดขณะโทรศัพท์ลดอุณหภูมิลง"</string>
+ <string name="high_temp_notif_message" msgid="5642466103153429279">"ฟีเจอร์บางอย่างจะใช้งานได้จำกัดขณะโทรศัพท์ลดอุณหภูมิลง"</string>
<string name="high_temp_dialog_message" msgid="6840700639374113553">"โทรศัพท์จะพยายามลดอุณหภูมิลงโดยอัตโนมัติ คุณยังสามารถใช้โทรศัพท์ได้ แต่โทรศัพท์อาจทำงานช้าลง\n\nโทรศัพท์จะทำงานตามปกติเมื่อเย็นลงแล้ว"</string>
<string name="lockscreen_shortcut_left" msgid="2182769107618938629">"ทางลัดทางซ้าย"</string>
<string name="lockscreen_shortcut_right" msgid="3328683699505226536">"ทางลัดทางขวา"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 194b16186de6..3304ab71c7ac 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -573,6 +573,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 minuto"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 minuto"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 oras"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"I-UNDO"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"Na-snooze ng <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"Paggamit ng baterya"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 7f1d8ff71d68..944316cc7d77 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -573,6 +573,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 dakika"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 dakika"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 saat"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"GERİ AL"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> süreyle ertelendi"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"Pil kullanımı"</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 1006eae3a18d..5636a8725fc6 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -583,6 +583,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 хвилин"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 хвилин"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 годину"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"ВІДМІНИТИ"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"Відкладено на <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"Використання заряду"</string>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 9f284942c011..7a5f1c7fba7b 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -573,6 +573,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 منٹ"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 منٹ"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 گھنٹہ"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"کالعدم کریں"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> کیلئے اسنوز کیا گیا"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"بیٹری کا استعمال"</string>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 02f7c43b4045..262225c10761 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -201,7 +201,7 @@
<string name="accessibility_quick_settings_airplane_changed_off" msgid="66846307818850664">"Parvoz rejimi o‘chirildi."</string>
<string name="accessibility_quick_settings_airplane_changed_on" msgid="8983005603505087728">"Parvoz rejimi yoqildi."</string>
<string name="accessibility_quick_settings_dnd_priority_on" msgid="1448402297221249355">"“Bezovta qilinmasin” funksiyasi yoqilgan, faqat muhim bildirishnomalar ko‘rsatiladi."</string>
- <string name="accessibility_quick_settings_dnd_none_on" msgid="6882582132662613537">"Bezovta qilinmasin, tinchlik saqlansin"</string>
+ <string name="accessibility_quick_settings_dnd_none_on" msgid="6882582132662613537">"Bezovta qilinmasin, jimjitlik."</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="9152834845587554157">"Bezovta qilinmasin, faqat signallar"</string>
<string name="accessibility_quick_settings_dnd" msgid="6607873236717185815">"Bezovta qilinmasin."</string>
<string name="accessibility_quick_settings_dnd_off" msgid="2371832603753738581">"“Bezovta qilinmasin” funksiyasi o‘chirilgan."</string>
@@ -575,6 +575,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 daqiqa"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 daqiqa"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 soat"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"BEKOR QILISH"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"<xliff:g id="TIME_AMOUNT">%1$s</xliff:g> muddatga kechiktirildi"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"Batareya sarfi"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 167d0a1eeed0..1d125f6d9336 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -575,6 +575,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 phút"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 phút"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 giờ"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"HOÀN TÁC"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"Báo lại sau <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"Mức sử dụng pin"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index cf9b7d2b421c..600e17d4d029 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -573,6 +573,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 分钟"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 分钟"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 小时"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"撤消"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"已延后 <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"电池使用情况"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index d123c930c2ca..109c33e93572 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -575,6 +575,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 分鐘"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 分鐘"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 小時"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"復原"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"已延後 <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"電池用量"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index af7ed48ca93f..353d98590243 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -268,7 +268,7 @@
<string name="ethernet_label" msgid="7967563676324087464">"乙太網路"</string>
<string name="quick_settings_dnd_label" msgid="8735855737575028208">"零打擾"</string>
<string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"僅限優先通知"</string>
- <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"僅允許鬧鐘"</string>
+ <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"僅限鬧鐘"</string>
<string name="quick_settings_dnd_none_label" msgid="5025477807123029478">"完全靜音"</string>
<string name="quick_settings_bluetooth_label" msgid="6304190285170721401">"藍牙"</string>
<string name="quick_settings_bluetooth_multiple_devices_label" msgid="3912245565613684735">"藍牙 (<xliff:g id="NUMBER">%d</xliff:g> 個裝置)"</string>
@@ -369,7 +369,7 @@
<string name="interruption_level_none_with_warning" msgid="5114872171614161084">"完全靜音。這也會關閉螢幕閱讀器的音訊。"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"完全靜音"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"僅限優先通知"</string>
- <string name="interruption_level_alarms" msgid="5226306993448328896">"僅允許鬧鐘"</string>
+ <string name="interruption_level_alarms" msgid="5226306993448328896">"僅限鬧鐘"</string>
<string name="interruption_level_none_twoline" msgid="3957581548190765889">"完全\n靜音"</string>
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"僅允許\n優先通知"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"僅允許\n鬧鐘"</string>
@@ -573,6 +573,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 分鐘"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 分鐘"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 小時"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"復原"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"已延後 <xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"電池用量"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index c1765c692520..d81c32084b8e 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -573,6 +573,8 @@
<string name="snooze_option_15_min" msgid="1068727451405610715">"15 amaminithi"</string>
<string name="snooze_option_30_min" msgid="867081342535195788">"30 amaminithi"</string>
<string name="snooze_option_1_hour" msgid="1098086401880077154">"1 ihora"</string>
+ <!-- no translation found for snooze_option_2_hour (8332218255658969475) -->
+ <skip />
<string name="snooze_undo" msgid="6074877317002985129">"HLEHLISA"</string>
<string name="snoozed_for_time" msgid="2390718332980204462">"Kusnuzwe u-<xliff:g id="TIME_AMOUNT">%1$s</xliff:g>"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"Ukusetshenziswa kwebhethri"</string>
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
index f0ff22dc45c7..db1e8a9c112e 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
@@ -147,8 +147,10 @@ public class KeyguardStatusView extends GridLayout {
mClockView.setLayoutParams(layoutParams);
mDateView.setTextSize(TypedValue.COMPLEX_UNIT_PX,
getResources().getDimensionPixelSize(R.dimen.widget_label_font_size));
- mOwnerInfo.setTextSize(TypedValue.COMPLEX_UNIT_PX,
- getResources().getDimensionPixelSize(R.dimen.widget_label_font_size));
+ if (mOwnerInfo != null) {
+ mOwnerInfo.setTextSize(TypedValue.COMPLEX_UNIT_PX,
+ getResources().getDimensionPixelSize(R.dimen.widget_label_font_size));
+ }
}
public void refreshTime() {
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 c35fdd5c5781..854696ee313d 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
@@ -716,9 +716,15 @@ public class PipTouchHandler {
* Updates the current movement bounds based on whether the menu is currently visible.
*/
private void updateMovementBounds(int menuState) {
- mMovementBounds = menuState == MENU_STATE_FULL
+ boolean isMenuExpanded = menuState == MENU_STATE_FULL;
+ mMovementBounds = isMenuExpanded
? mExpandedMovementBounds
: mNormalMovementBounds;
+ try {
+ mPinnedStackController.setMinEdgeSize(isMenuExpanded ? mExpandedShortestEdgeSize : 0);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Could not set minimized state", e);
+ }
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
index 149b5ccd7b1a..0d74b7a85ad1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
@@ -58,6 +58,16 @@ public class QSContainerImpl extends FrameLayout {
mBackground = findViewById(R.id.qs_background);
mGutterHeight = getContext().getResources().getDimensionPixelSize(R.dimen.qs_gutter_height);
mFullElevation = mQSPanel.getElevation();
+
+ setClickable(true);
+ setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO);
+ }
+
+ @Override
+ public boolean performClick() {
+ // Want to receive clicks so missing QQS tiles doesn't cause collapse, but
+ // don't want to do anything with them.
+ return true;
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
index 87b042d61147..682c56c0ef24 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
@@ -101,6 +101,8 @@ public class QSFooter extends FrameLayout implements
private boolean mShowEditIcon;
private TouchAnimator mAnimator;
private View mDateTimeGroup;
+ private boolean mKeyguardShowing;
+ private TouchAnimator mAlarmAnimator;
public QSFooter(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -163,13 +165,14 @@ public class QSFooter extends FrameLayout implements
int remaining = (width - numTiles * size) / (numTiles - 1);
int defSpace = mContext.getResources().getDimensionPixelOffset(R.dimen.default_gear_space);
- final Builder builder = new Builder()
+ mAnimator = new Builder()
.addFloat(mSettingsContainer, "translationX", -(remaining - defSpace), 0)
.addFloat(mSettingsButton, "rotation", -120, 0)
- .addFloat(mAlarmStatus, "alpha", 0, 1);
+ .build();
if (mAlarmShowing) {
- builder.addFloat(mDate, "alpha", 1, 0)
+ mAlarmAnimator = new Builder().addFloat(mDate, "alpha", 1, 0)
.addFloat(mDateTimeGroup, "translationX", 0, -mDate.getWidth())
+ .addFloat(mAlarmStatus, "alpha", 0, 1)
.setListener(new ListenerAdapter() {
@Override
public void onAnimationAtStart() {
@@ -180,13 +183,13 @@ public class QSFooter extends FrameLayout implements
public void onAnimationStarted() {
mAlarmStatus.setVisibility(View.VISIBLE);
}
- });
+ }).build();
} else {
+ mAlarmAnimator = null;
mAlarmStatus.setVisibility(View.GONE);
mDate.setAlpha(1);
mDateTimeGroup.setTranslationX(0);
}
- mAnimator = builder.build();
setExpansion(mExpansionAmount);
}
@@ -248,6 +251,11 @@ public class QSFooter extends FrameLayout implements
return animatorBuilder.build();
}
+ public void setKeyguardShowing(boolean keyguardShowing) {
+ mKeyguardShowing = keyguardShowing;
+ setExpansion(mExpansionAmount);
+ }
+
public void setExpanded(boolean expanded) {
if (mExpanded == expanded) return;
mExpanded = expanded;
@@ -275,6 +283,8 @@ public class QSFooter extends FrameLayout implements
public void setExpansion(float headerExpansionFraction) {
mExpansionAmount = headerExpansionFraction;
if (mAnimator != null) mAnimator.setPosition(headerExpansionFraction);
+ if (mAlarmAnimator != null) mAlarmAnimator.setPosition(
+ mKeyguardShowing ? 0 : headerExpansionFraction);
if (mSettingsAlpha != null) {
mSettingsAlpha.setPosition(headerExpansionFraction);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
index 61fd6244b700..c9c3a7f9e147 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
@@ -222,6 +222,7 @@ public class QSFragment extends Fragment implements QS {
mQSAnimator.setOnKeyguard(keyguardShowing);
}
+ mFooter.setKeyguardShowing(keyguardShowing);
updateQsState();
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
index 8539cb9d5473..00b883a541db 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
@@ -60,6 +60,12 @@ public class QuickQSPanel extends QSPanel {
mTileLayout = new HeaderTileLayout(context);
mTileLayout.setListening(mListening);
addView((View) mTileLayout, 0 /* Between brightness and footer */);
+ super.setPadding(0, 0, 0, 0);
+ }
+
+ @Override
+ public void setPadding(int left, int top, int right, int bottom) {
+ // Always have no padding.
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
index e457d7247434..abafd64e3707 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
@@ -23,13 +23,11 @@ import android.support.annotation.VisibleForTesting;
import android.util.AttributeSet;
import android.view.View;
import android.widget.RelativeLayout;
-import android.widget.TextClock;
import com.android.settingslib.Utils;
import com.android.systemui.BatteryMeterView;
import com.android.systemui.Dependency;
import com.android.systemui.R;
-import com.android.systemui.R.id;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.qs.QSDetail.Callback;
import com.android.systemui.statusbar.SignalClusterView;
@@ -79,7 +77,7 @@ public class QuickStatusBarHeader extends RelativeLayout {
battery.setForceShowPercent(true);
// Don't show the Wi-Fi indicator here, because it is shown just below in the tile.
SignalClusterView signalCluster = findViewById(R.id.signal_cluster);
- signalCluster.setForceBlockWifi();
+ signalCluster.setQsSignalCluster();
mActivityStarter = Dependency.get(ActivityStarter.class);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
index 1afce64539d2..76f6e7d7d243 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
@@ -353,13 +353,20 @@ public class WifiTile extends QSTileImpl<SignalState> {
private void updateItems() {
if (mItems == null) return;
- if (mSignalCallback.mInfo.enabled) {
- mItems.setEmptyState(R.drawable.ic_qs_wifi_detail_empty,
- R.string.quick_settings_wifi_detail_empty_text);
- } else {
+
+ // Wi-Fi is off
+ if (!mSignalCallback.mInfo.enabled) {
mItems.setEmptyState(R.drawable.ic_qs_wifi_detail_empty,
R.string.wifi_is_off);
+ mItems.setItems(null);
+ return;
}
+
+ // No available access points
+ mItems.setEmptyState(R.drawable.ic_qs_wifi_detail_empty,
+ R.string.quick_settings_wifi_detail_empty_text);
+
+ // Build the list
Item[] items = null;
if (mAccessPoints != null) {
items = new Item[mAccessPoints.length];
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
index e2e9b1b7d76f..611169f575c1 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
@@ -30,6 +30,7 @@ import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
+import android.graphics.GraphicBuffer;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
@@ -239,8 +240,6 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
}
});
- protected Bitmap mThumbTransitionBitmapCache;
-
public RecentsImpl(Context context) {
mContext = context;
mHandler = new Handler();
@@ -775,14 +774,6 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
}
mHeaderBar.layout(0, 0, taskViewWidth, mTaskBarHeight);
}
-
- // Update the transition bitmap to match the new header bar height
- if (mThumbTransitionBitmapCache == null ||
- (mThumbTransitionBitmapCache.getWidth() != taskViewWidth) ||
- (mThumbTransitionBitmapCache.getHeight() != mTaskBarHeight)) {
- mThumbTransitionBitmapCache = Bitmap.createBitmap(taskViewWidth,
- mTaskBarHeight, Bitmap.Config.ARGB_8888);
- }
}
}
@@ -864,8 +855,7 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
mTmpTransform = stackLayout.getStackTransformScreenCoordinates(task,
stackScroller.getStackScroll(), mTmpTransform, null,
windowOverrideRect);
- Bitmap thumbnail = drawThumbnailTransitionBitmap(task, mTmpTransform,
- mThumbTransitionBitmapCache);
+ GraphicBuffer thumbnail = drawThumbnailTransitionBitmap(task, mTmpTransform);
Rect toTaskRect = new Rect();
mTmpTransform.rect.round(toTaskRect);
specs.add(new AppTransitionAnimationSpec(task.key.id, thumbnail, toTaskRect));
@@ -887,8 +877,8 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
() -> {
Rect rect = new Rect();
toTaskRect.round(rect);
- Bitmap thumbnail = drawThumbnailTransitionBitmap(toTask, toTransform,
- mThumbTransitionBitmapCache);
+ GraphicBuffer thumbnail = drawThumbnailTransitionBitmap(toTask,
+ toTransform);
return Lists.newArrayList(new AppTransitionAnimationSpec(
toTask.key.id, thumbnail, rect));
});
@@ -924,19 +914,19 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
/**
* Draws the header of a task used for the window animation into a bitmap.
*/
- private Bitmap drawThumbnailTransitionBitmap(Task toTask, TaskViewTransform toTransform,
- Bitmap thumbnail) {
+ private GraphicBuffer drawThumbnailTransitionBitmap(Task toTask,
+ TaskViewTransform toTransform) {
SystemServicesProxy ssp = Recents.getSystemServices();
if (toTransform != null && toTask.key != null) {
synchronized (mHeaderBarLock) {
boolean disabledInSafeMode = !toTask.isSystemApp && ssp.isInSafeMode();
- mHeaderBar.onTaskViewSizeChanged((int) toTransform.rect.width(),
- (int) toTransform.rect.height());
+ int width = (int) toTransform.rect.width();
+ int height = (int) toTransform.rect.height();
+ mHeaderBar.onTaskViewSizeChanged(width, height);
if (RecentsDebugFlags.Static.EnableTransitionThumbnailDebugMode) {
- thumbnail.eraseColor(0xFFff0000);
+ return RecentsTransitionHelper.drawViewIntoGraphicBuffer(width, mTaskBarHeight,
+ null, 1f, 0xFFff0000);
} else {
- thumbnail.eraseColor(0);
- Canvas c = new Canvas(thumbnail);
// Workaround for b/27815919, reset the callback so that we do not trigger an
// invalidate on the header bar as a result of updating the icon
Drawable icon = mHeaderBar.getIconView().getDrawable();
@@ -947,11 +937,10 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
disabledInSafeMode);
mHeaderBar.onTaskDataLoaded();
mHeaderBar.setDimAlpha(toTransform.dimAlpha);
- mHeaderBar.draw(c);
- c.setBitmap(null);
+ return RecentsTransitionHelper.drawViewIntoGraphicBuffer(width, mTaskBarHeight,
+ mHeaderBar, 1f, 0);
}
}
- return thumbnail.createAshmemBitmap();
}
return null;
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
index d7d264e3aa07..21dfe8caf964 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
@@ -30,6 +30,7 @@ import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
+import android.graphics.GraphicBuffer;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.Handler;
@@ -37,7 +38,11 @@ import android.os.IRemoteCallback;
import android.os.RemoteException;
import android.util.Log;
import android.view.AppTransitionAnimationSpec;
+import android.view.DisplayListCanvas;
import android.view.IAppTransitionAnimationSpecsFuture;
+import android.view.RenderNode;
+import android.view.ThreadedRenderer;
+import android.view.View;
import com.android.internal.annotations.GuardedBy;
import com.android.systemui.recents.Recents;
@@ -264,8 +269,8 @@ public class RecentsTransitionHelper {
Rect bounds) {
mTmpTransform.fillIn(taskView);
Task task = taskView.getTask();
- Bitmap thumbnail = RecentsTransitionHelper.composeTaskBitmap(taskView, mTmpTransform);
- return Collections.singletonList(new AppTransitionAnimationSpec(task.key.id, thumbnail,
+ GraphicBuffer buffer = RecentsTransitionHelper.composeTaskBitmap(taskView, mTmpTransform);
+ return Collections.singletonList(new AppTransitionAnimationSpec(task.key.id, buffer,
bounds));
}
@@ -346,7 +351,7 @@ public class RecentsTransitionHelper {
return new AppTransitionAnimationSpec(task.key.id, null, taskRect);
}
- public static Bitmap composeTaskBitmap(TaskView taskView, TaskViewTransform transform) {
+ public static GraphicBuffer composeTaskBitmap(TaskView taskView, TaskViewTransform transform) {
float scale = transform.scale;
int fromWidth = (int) (transform.rect.width() * scale);
int fromHeight = (int) (transform.rect.height() * scale);
@@ -354,26 +359,17 @@ public class RecentsTransitionHelper {
Log.e(TAG, "Could not compose thumbnail for task: " + taskView.getTask() +
" at transform: " + transform);
- Bitmap b = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
- b.eraseColor(Color.TRANSPARENT);
- return b;
+ return drawViewIntoGraphicBuffer(1, 1, null, 1f, 0x00ffffff);
} else {
- Bitmap b = Bitmap.createBitmap(fromWidth, fromHeight,
- Bitmap.Config.ARGB_8888);
-
if (RecentsDebugFlags.Static.EnableTransitionThumbnailDebugMode) {
- b.eraseColor(0xFFff0000);
+ return drawViewIntoGraphicBuffer(fromWidth, fromHeight, null, 1f, 0xFFff0000);
} else {
- Canvas c = new Canvas(b);
- c.scale(scale, scale);
- taskView.draw(c);
- c.setBitmap(null);
+ return drawViewIntoGraphicBuffer(fromWidth, fromHeight, taskView, scale, 0);
}
- return b.createAshmemBitmap();
}
}
- private static Bitmap composeHeaderBitmap(TaskView taskView,
+ private static GraphicBuffer composeHeaderBitmap(TaskView taskView,
TaskViewTransform transform) {
float scale = transform.scale;
int headerWidth = (int) (transform.rect.width());
@@ -382,16 +378,30 @@ public class RecentsTransitionHelper {
return null;
}
- Bitmap b = Bitmap.createBitmap(headerWidth, headerHeight, Bitmap.Config.ARGB_8888);
if (RecentsDebugFlags.Static.EnableTransitionThumbnailDebugMode) {
- b.eraseColor(0xFFff0000);
+ return drawViewIntoGraphicBuffer(headerWidth, headerHeight, null, 1f, 0xFFff0000);
} else {
- Canvas c = new Canvas(b);
- c.scale(scale, scale);
- taskView.mHeaderView.draw(c);
- c.setBitmap(null);
+ return drawViewIntoGraphicBuffer(headerWidth, headerHeight, taskView.mHeaderView,
+ scale, 0);
+ }
+ }
+
+ public static GraphicBuffer drawViewIntoGraphicBuffer(int bufferWidth, int bufferHeight,
+ View view, float scale, int eraseColor) {
+ RenderNode node = RenderNode.create("RecentsTransition", null);
+ node.setLeftTopRightBottom(0, 0, bufferWidth, bufferHeight);
+ node.setClipToBounds(false);
+ DisplayListCanvas c = node.start(bufferWidth, bufferHeight);
+ c.scale(scale, scale);
+ if (eraseColor != 0) {
+ c.drawColor(eraseColor);
+ }
+ if (view != null) {
+ view.draw(c);
}
- return b.createAshmemBitmap();
+ node.end(c);
+ return ThreadedRenderer.createHardwareBitmap(node, bufferWidth, bufferHeight)
+ .createGraphicBufferHandle();
}
/**
@@ -399,7 +409,7 @@ public class RecentsTransitionHelper {
*/
private static AppTransitionAnimationSpec composeAnimationSpec(TaskStackView stackView,
TaskView taskView, TaskViewTransform transform, boolean addHeaderBitmap) {
- Bitmap b = null;
+ GraphicBuffer b = null;
if (addHeaderBitmap) {
b = composeHeaderBitmap(taskView, transform);
if (b == null) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java
index 2180ec824fb6..46619c214f12 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java
@@ -138,7 +138,7 @@ public class RecentsViewTouchHandler {
}
mVisibleDockStates.clear();
- if (ActivityManager.supportsMultiWindow() && !ssp.hasDockedTask()
+ if (ActivityManager.supportsMultiWindow(mRv.getContext()) && !ssp.hasDockedTask()
&& mDividerSnapAlgorithm.isSplitScreenFeasible()) {
Recents.logDockAttempt(mRv.getContext(), event.task.getTopComponent(),
event.task.resizeMode);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewAccessibilityDelegate.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewAccessibilityDelegate.java
index 2c3e78f8cb84..0c6b6b842655 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewAccessibilityDelegate.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewAccessibilityDelegate.java
@@ -59,7 +59,7 @@ public class TaskViewAccessibilityDelegate extends View.AccessibilityDelegate {
@Override
public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfo(host, info);
- if (ActivityManager.supportsSplitScreenMultiWindow()
+ if (ActivityManager.supportsSplitScreenMultiWindow(mTaskView.getContext())
&& !Recents.getSystemServices().hasDockedTask()) {
TaskStack.DockState[] dockStates = Recents.getConfiguration()
.getDockStatesForCurrentOrientation();
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
index d01bba86636f..9e2ec571faa8 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
@@ -832,7 +832,10 @@ public class DividerView extends FrameLayout implements OnTouchListener,
.setDuration(animDuration)
.start();
mAdjustedForIme = adjustedForIme;
- if (mHomeStackResizable && adjustedForIme) {
+
+ // Only get new position if home stack is resizable, ime is open and not minimized
+ // (including the animation)
+ if (mHomeStackResizable && adjustedForIme && !mIsInMinimizeInteraction) {
mDividerPositionBeforeMinimized = getCurrentPosition();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
index 28a858c066ce..ab41485793a1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
@@ -121,6 +121,7 @@ public class SignalClusterView extends LinearLayout implements NetworkController
private boolean mBlockEthernet;
private boolean mActivityEnabled;
private boolean mForceBlockWifi;
+ private boolean mQsSignal;
public SignalClusterView(Context context) {
this(context, null);
@@ -152,9 +153,10 @@ public class SignalClusterView extends LinearLayout implements NetworkController
updateActivityEnabled();
}
- public void setForceBlockWifi() {
+ public void setQsSignalCluster() {
mForceBlockWifi = true;
mBlockWifi = true;
+ mQsSignal = true;
if (isAttachedToWindow()) {
// Re-register to get new callbacks.
mNetworkController.removeCallback(this);
@@ -292,26 +294,30 @@ public class SignalClusterView extends LinearLayout implements NetworkController
mWifiStrengthId = statusIcon.icon;
mWifiBadgeId = statusIcon.iconOverlay;
mWifiDescription = statusIcon.contentDescription;
- mWifiIn = activityIn && mActivityEnabled;
- mWifiOut = activityOut && mActivityEnabled;
+ mWifiIn = activityIn && mActivityEnabled && mWifiVisible;
+ mWifiOut = activityOut && mActivityEnabled && mWifiVisible;
apply();
}
@Override
- public void setMobileDataIndicators(IconState statusIcon, IconState qsIcon, int statusType,
+ public void setMobileDataIndicators(IconState icon, IconState qsIcon, int type,
int qsType, boolean activityIn, boolean activityOut, String typeContentDescription,
String description, boolean isWide, int subId, boolean roaming) {
PhoneState state = getState(subId);
if (state == null) {
return;
}
- state.mMobileVisible = statusIcon.visible && !mBlockMobile;
- state.mMobileStrengthId = statusIcon.icon;
- state.mMobileTypeId = statusType;
- state.mMobileDescription = statusIcon.contentDescription;
+ if (mQsSignal) {
+ icon = qsIcon;
+ type = qsType;
+ }
+ state.mMobileVisible = icon.visible && !mBlockMobile;
+ state.mMobileStrengthId = icon.icon;
+ state.mMobileTypeId = type;
+ state.mMobileDescription = icon.contentDescription;
state.mMobileTypeDescription = typeContentDescription;
- state.mIsMobileTypeIconWide = statusType != 0 && isWide;
+ state.mIsMobileTypeIconWide = type != 0 && isWide;
state.mRoaming = roaming;
state.mActivityIn = activityIn && mActivityEnabled;
state.mActivityOut = activityOut && mActivityEnabled;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index c7fbbf956c68..85475b60902f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -179,6 +179,10 @@ public class StatusBarIconView extends AnimatedImageView {
mIconScale = (float)imageBounds / (float)outerBounds;
}
+ public float getIconScaleFullyDark() {
+ return (float) mStatusBarIconDrawingSizeDark / mStatusBarIconDrawingSize;
+ }
+
public float getIconScale() {
return mIconScale;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
index 4bfc16b7b4d6..d047fa929da2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
@@ -545,7 +545,7 @@ public class NavigationBarFragment extends Fragment implements Callbacks {
}
private boolean onLongPressRecents() {
- if (mRecents == null || !ActivityManager.supportsMultiWindow()
+ if (mRecents == null || !ActivityManager.supportsMultiWindow(getContext())
|| !mDivider.getView().getSnapAlgorithm().isSplitScreenFeasible()) {
return false;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
index 9000eb4655d1..f94bb0cdd4f7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
@@ -267,6 +267,9 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
boolean forceOverflow = mSpeedBumpIndex != -1 && i >= mSpeedBumpIndex
&& iconState.iconAppearAmount > 0.0f || i >= maxVisibleIcons;
boolean noOverflowAfter = i == childCount - 1;
+ float drawingScale = mDark && view instanceof StatusBarIconView
+ ? ((StatusBarIconView) view).getIconScaleFullyDark()
+ : 1f;
if (mOpenedAmount != 0.0f) {
noOverflowAfter = noOverflowAfter && !hasAmbient && !forceOverflow;
}
@@ -303,7 +306,7 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
visualOverflowStart += mVisualOverflowAdaption * (1f - mOpenedAmount);
}
}
- translationX += iconState.iconAppearAmount * view.getWidth();
+ translationX += iconState.iconAppearAmount * view.getWidth() * drawingScale;
}
if (firstOverflowIndex != -1) {
int numDots = 1;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 51fb204f13a0..24c19282a4f6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -759,6 +759,7 @@ public class StatusBar extends SystemUI implements DemoMode,
mBatteryController = Dependency.get(BatteryController.class);
mAssistManager = Dependency.get(AssistManager.class);
mDeviceProvisionedController = Dependency.get(DeviceProvisionedController.class);
+ mSystemServicesProxy = SystemServicesProxy.getInstance(mContext);
mWindowManager = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
mDisplay = mWindowManager.getDefaultDisplay();
@@ -1825,23 +1826,20 @@ public class StatusBar extends SystemUI implements DemoMode,
// temporarily become children if they were isolated before.
continue;
}
- int vis = ent.notification.getNotification().visibility;
int userId = ent.notification.getUserId();
// Display public version of the notification if we need to redact.
- boolean deviceSensitive = (isLockscreenPublicMode(mCurrentUserId)
- && !userAllowsPrivateNotificationsInPublic(mCurrentUserId));
- boolean userSensitive = deviceSensitive || (isLockscreenPublicMode(userId)
- && !userAllowsPrivateNotificationsInPublic(userId));
- boolean sensitiveNote = vis == Notification.VISIBILITY_PRIVATE;
- boolean sensitivePackage = packageHasVisibilityOverride(ent.notification.getKey());
- boolean sensitive = (sensitiveNote && userSensitive) || sensitivePackage;
- boolean showingPublic = sensitive && isLockscreenPublicMode(userId);
- if (showingPublic) {
+ boolean devicePublic = isLockscreenPublicMode(mCurrentUserId);
+ boolean userPublic = devicePublic || isLockscreenPublicMode(userId);
+ boolean needsRedaction = needsRedaction(ent);
+ boolean sensitive = userPublic && needsRedaction;
+ boolean deviceSensitive = devicePublic
+ && !userAllowsPrivateNotificationsInPublic(mCurrentUserId);
+ if (sensitive) {
updatePublicContentView(ent, ent.notification);
}
ent.row.setSensitive(sensitive, deviceSensitive);
- ent.row.setNeedsRedaction(needsRedaction(ent));
+ ent.row.setNeedsRedaction(needsRedaction);
if (mGroupManager.isChildInGroupWithSummary(ent.row.getStatusBarNotification())) {
ExpandableNotificationRow summary = mGroupManager.getGroupSummary(
ent.row.getStatusBarNotification());
@@ -4320,7 +4318,12 @@ public class StatusBar extends SystemUI implements DemoMode,
final int userId = mCurrentProfiles.valueAt(i).id;
boolean isProfilePublic = devicePublic;
if (!devicePublic && userId != mCurrentUserId) {
- if (mStatusBarKeyguardViewManager.isSecure(userId)) {
+ // We can't rely on KeyguardManager#isDeviceLocked() for unified profile challenge
+ // due to a race condition where this code could be called before
+ // TrustManagerService updates its internal records, resulting in an incorrect
+ // state being cached in mLockscreenPublicMode. (b/35951989)
+ if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)
+ && mStatusBarKeyguardViewManager.isSecure(userId)) {
isProfilePublic = mKeyguardManager.isDeviceLocked(userId);
}
}
@@ -5192,6 +5195,7 @@ public class StatusBar extends SystemUI implements DemoMode,
protected KeyguardManager mKeyguardManager;
private LockPatternUtils mLockPatternUtils;
private DeviceProvisionedController mDeviceProvisionedController;
+ protected SystemServicesProxy mSystemServicesProxy;
// UI-specific methods
@@ -6816,6 +6820,7 @@ public class StatusBar extends SystemUI implements DemoMode,
protected boolean shouldPeek(Entry entry, StatusBarNotification sbn) {
if (!mUseHeadsUp || isDeviceInVrMode()) {
+ if (DEBUG) Log.d(TAG, "No peeking: no huns or vr mode");
return false;
}
@@ -6824,8 +6829,7 @@ public class StatusBar extends SystemUI implements DemoMode,
return false;
}
- boolean inUse = mPowerManager.isScreenOn()
- && !SystemServicesProxy.getInstance(mContext).isDreaming();
+ boolean inUse = mPowerManager.isScreenOn() && !mSystemServicesProxy.isDreaming();
if (!inUse && !isDozing()) {
if (DEBUG) {
@@ -6868,6 +6872,12 @@ public class StatusBar extends SystemUI implements DemoMode,
}
}
+ // Don't peek notifications that are suppressed due to group alert behavior
+ if (sbn.isGroup() && sbn.getNotification().suppressAlertingDueToGrouping()) {
+ if (DEBUG) Log.d(TAG, "No peeking: suppressed due to group alert behavior");
+ return false;
+ }
+
return true;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
index 67b5596e34c9..03a50a209de1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
@@ -253,11 +253,6 @@ public class MobileSignalController extends SignalController<
}
@Override
- public int getQsCurrentIconId() {
- return getCurrentIconId();
- }
-
- @Override
public void notifyListeners(SignalCallback callback) {
MobileIconGroup icons = getIcons();
@@ -276,9 +271,9 @@ public class MobileSignalController extends SignalController<
String description = null;
// Only send data sim callbacks to QS.
if (mCurrentState.dataSim) {
- qsTypeIcon = showDataIcon ? icons.mQsDataType : 0;
+ qsTypeIcon = showDataIcon ? icons.mDataType : 0;
qsIcon = new IconState(mCurrentState.enabled
- && !mCurrentState.isEmergency, getQsCurrentIconId(), contentDescription);
+ && !mCurrentState.isEmergency, getCurrentIconId(), contentDescription);
description = mCurrentState.isEmergency ? null : mCurrentState.networkName;
}
boolean activityIn = mCurrentState.dataConnected
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java
index aaa0568a72cd..d91ae39bc920 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java
@@ -22,16 +22,6 @@ import com.android.systemui.statusbar.policy.MobileSignalController.MobileIconGr
class TelephonyIcons {
//***** Data connection icons
- static final int QS_DATA_G = R.drawable.ic_qs_signal_g;
- static final int QS_DATA_3G = R.drawable.ic_qs_signal_3g;
- static final int QS_DATA_E = R.drawable.ic_qs_signal_e;
- static final int QS_DATA_H = R.drawable.ic_qs_signal_h;
- static final int QS_DATA_1X = R.drawable.ic_qs_signal_1x;
- static final int QS_DATA_4G = R.drawable.ic_qs_signal_4g;
- static final int QS_DATA_4G_PLUS = R.drawable.ic_qs_signal_4g_plus;
- static final int QS_DATA_LTE = R.drawable.ic_qs_signal_lte;
- static final int QS_DATA_LTE_PLUS = R.drawable.ic_qs_signal_lte_plus;
-
static final int FLIGHT_MODE_ICON = R.drawable.stat_sys_airplane_mode;
static final int ICON_LTE = R.drawable.stat_sys_data_fully_connected_lte;
@@ -46,8 +36,6 @@ class TelephonyIcons {
static final int ICON_DATA_DISABLED = R.drawable.stat_sys_data_disabled;
- static final int QS_ICON_DATA_DISABLED = R.drawable.ic_qs_data_disabled;
-
static final MobileIconGroup CARRIER_NETWORK_CHANGE = new MobileIconGroup(
"CARRIER_NETWORK_CHANGE",
null,
@@ -75,7 +63,7 @@ class TelephonyIcons {
R.string.accessibility_data_connection_3g,
TelephonyIcons.ICON_3G,
true,
- TelephonyIcons.QS_DATA_3G
+ TelephonyIcons.ICON_3G
);
static final MobileIconGroup WFC = new MobileIconGroup(
@@ -114,7 +102,7 @@ class TelephonyIcons {
R.string.accessibility_data_connection_edge,
TelephonyIcons.ICON_E,
false,
- TelephonyIcons.QS_DATA_E
+ TelephonyIcons.ICON_E
);
static final MobileIconGroup ONE_X = new MobileIconGroup(
@@ -129,7 +117,7 @@ class TelephonyIcons {
R.string.accessibility_data_connection_cdma,
TelephonyIcons.ICON_1X,
true,
- TelephonyIcons.QS_DATA_1X
+ TelephonyIcons.ICON_1X
);
static final MobileIconGroup G = new MobileIconGroup(
@@ -144,7 +132,7 @@ class TelephonyIcons {
R.string.accessibility_data_connection_gprs,
TelephonyIcons.ICON_G,
false,
- TelephonyIcons.QS_DATA_G
+ TelephonyIcons.ICON_G
);
static final MobileIconGroup H = new MobileIconGroup(
@@ -159,7 +147,7 @@ class TelephonyIcons {
R.string.accessibility_data_connection_3_5g,
TelephonyIcons.ICON_H,
false,
- TelephonyIcons.QS_DATA_H
+ TelephonyIcons.ICON_H
);
static final MobileIconGroup FOUR_G = new MobileIconGroup(
@@ -174,7 +162,7 @@ class TelephonyIcons {
R.string.accessibility_data_connection_4g,
TelephonyIcons.ICON_4G,
true,
- TelephonyIcons.QS_DATA_4G
+ TelephonyIcons.ICON_4G
);
static final MobileIconGroup FOUR_G_PLUS = new MobileIconGroup(
@@ -189,7 +177,7 @@ class TelephonyIcons {
R.string.accessibility_data_connection_4g_plus,
TelephonyIcons.ICON_4G_PLUS,
true,
- TelephonyIcons.QS_DATA_4G_PLUS
+ TelephonyIcons.ICON_4G_PLUS
);
static final MobileIconGroup LTE = new MobileIconGroup(
@@ -204,7 +192,7 @@ class TelephonyIcons {
R.string.accessibility_data_connection_lte,
TelephonyIcons.ICON_LTE,
true,
- TelephonyIcons.QS_DATA_LTE
+ TelephonyIcons.ICON_LTE
);
static final MobileIconGroup LTE_PLUS = new MobileIconGroup(
@@ -219,7 +207,7 @@ class TelephonyIcons {
R.string.accessibility_data_connection_lte_plus,
TelephonyIcons.ICON_LTE_PLUS,
true,
- TelephonyIcons.QS_DATA_LTE_PLUS
+ TelephonyIcons.ICON_LTE_PLUS
);
static final MobileIconGroup DATA_DISABLED = new MobileIconGroup(
@@ -234,7 +222,7 @@ class TelephonyIcons {
R.string.accessibility_cell_data_off,
TelephonyIcons.ICON_DATA_DISABLED,
false,
- TelephonyIcons.QS_ICON_DATA_DISABLED
+ TelephonyIcons.ICON_DATA_DISABLED
);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java
index e80d3b3a6409..0fd244527540 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java
@@ -36,11 +36,13 @@ import android.service.notification.Condition;
import android.service.notification.IConditionListener;
import android.service.notification.ZenModeConfig;
import android.service.notification.ZenModeConfig.ZenRule;
+import android.support.annotation.VisibleForTesting;
import android.util.Log;
import android.util.Slog;
import com.android.systemui.qs.GlobalSetting;
import com.android.systemui.settings.CurrentUserTracker;
+import com.android.systemui.util.Utils;
import java.util.ArrayList;
import java.util.LinkedHashMap;
@@ -169,45 +171,32 @@ public class ZenModeControllerImpl extends CurrentUserTracker implements ZenMode
}
private void fireNextAlarmChanged() {
- for (Callback cb : mCallbacks) {
- cb.onNextAlarmChanged();
- }
+ Utils.safeForeach(mCallbacks, c -> c.onNextAlarmChanged());
}
private void fireEffectsSuppressorChanged() {
- for (Callback cb : mCallbacks) {
- cb.onEffectsSupressorChanged();
- }
+ Utils.safeForeach(mCallbacks, c -> c.onEffectsSupressorChanged());
}
private void fireZenChanged(int zen) {
- for (Callback cb : mCallbacks) {
- cb.onZenChanged(zen);
- }
+ Utils.safeForeach(mCallbacks, c -> c.onZenChanged(zen));
}
private void fireZenAvailableChanged(boolean available) {
- for (Callback cb : mCallbacks) {
- cb.onZenAvailableChanged(available);
- }
+ Utils.safeForeach(mCallbacks, c -> c.onZenAvailableChanged(available));
}
private void fireConditionsChanged(Condition[] conditions) {
- for (Callback cb : mCallbacks) {
- cb.onConditionsChanged(conditions);
- }
+ Utils.safeForeach(mCallbacks, c -> c.onConditionsChanged(conditions));
}
private void fireManualRuleChanged(ZenRule rule) {
- for (Callback cb : mCallbacks) {
- cb.onManualRuleChanged(rule);
- }
+ Utils.safeForeach(mCallbacks, c -> c.onManualRuleChanged(rule));
}
- private void fireConfigChanged(ZenModeConfig config) {
- for (Callback cb : mCallbacks) {
- cb.onConfigChanged(config);
- }
+ @VisibleForTesting
+ protected void fireConfigChanged(ZenModeConfig config) {
+ Utils.safeForeach(mCallbacks, c -> c.onConfigChanged(config));
}
private void updateConditions(Condition[] conditions) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
index 0dbd1d6cc74a..ff06b5b33a05 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
@@ -300,7 +300,7 @@ public class NotificationChildrenContainer extends ViewGroup {
mNotificationHeaderWrapper.notifyContentUpdated(mContainingNotification);
recreateLowPriorityHeader(builder);
recreateAmbientHeader(builder);
- resetHeaderVisibilityIfNeeded(mNotificationHeader, calculateDesiredHeader());
+ updateHeaderVisibility(false /* animate */);
updateChildrenHeaderAppearance();
}
@@ -833,6 +833,11 @@ public class NotificationChildrenContainer extends ViewGroup {
return mNotificationHeaderLowPriority;
}
+ @VisibleForTesting
+ public ViewGroup getCurrentHeaderView() {
+ return mCurrentHeader;
+ }
+
public void notifyShowAmbientChanged() {
updateHeaderVisibility(false);
}
@@ -869,7 +874,12 @@ public class NotificationChildrenContainer extends ViewGroup {
desiredHeader.setVisibility(VISIBLE);
}
if (currentHeader != null) {
- getWrapperForView(currentHeader).setVisible(false);
+ // Wrapper can be null if we were a low priority notification
+ // and just destroyed it by calling setIsLowPriority(false)
+ NotificationViewWrapper wrapper = getWrapperForView(currentHeader);
+ if (wrapper != null) {
+ wrapper.setVisible(false);
+ }
currentHeader.setVisibility(INVISIBLE);
}
}
@@ -878,7 +888,7 @@ public class NotificationChildrenContainer extends ViewGroup {
resetHeaderVisibilityIfNeeded(mNotificationHeaderAmbient, desiredHeader);
resetHeaderVisibilityIfNeeded(mNotificationHeaderLowPriority, desiredHeader);
- mCurrentHeader = currentHeader;
+ mCurrentHeader = desiredHeader;
}
private void resetHeaderVisibilityIfNeeded(View header, View desiredHeader) {
diff --git a/packages/SystemUI/src/com/android/systemui/util/Utils.java b/packages/SystemUI/src/com/android/systemui/util/Utils.java
new file mode 100644
index 000000000000..f4aebae7bdaf
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/Utils.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2017 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.util;
+
+import java.util.List;
+import java.util.function.Consumer;
+
+public class Utils {
+
+ /**
+ * Allows lambda iteration over a list. It is done in reverse order so it is safe
+ * to add or remove items during the iteration.
+ */
+ public static <T> void safeForeach(List<T> list, Consumer<T> c) {
+ for (int i = list.size() - 1; i >= 0; i--) {
+ c.accept(list.get(i));
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
index 51fcdbb92c81..ecdea4f442b2 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
@@ -57,7 +57,6 @@ import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.Prefs;
import com.android.systemui.R;
-import com.android.systemui.R.string;
import com.android.systemui.statusbar.policy.ZenModeController;
import java.io.FileDescriptor;
@@ -294,11 +293,6 @@ public class ZenModePanel extends FrameLayout {
private void onAttach() {
setExpanded(true);
mAttached = true;
- for (int i = 0; i < mZenRadioGroupContent.getChildCount(); i++) {
- ConditionTag tag = getConditionTagAt(i);
- if (tag != null) tag.rb.setChecked(false);
- mZenRadioGroupContent.getChildAt(i).setTag(null);
- }
mAttachedZen = mController.getZen();
ZenRule manualRule = mController.getManualRule();
mExitCondition = manualRule != null ? manualRule.condition : null;
@@ -311,6 +305,7 @@ public class ZenModePanel extends FrameLayout {
setSessionExitCondition(copy(mExitCondition));
updateWidgets();
setRequestingConditions(!mHidden);
+ ensureSelection();
}
private void onDetach() {
@@ -366,9 +361,6 @@ public class ZenModePanel extends FrameLayout {
if (expanded == mExpanded) return;
if (DEBUG) Log.d(mTag, "setExpanded " + expanded);
mExpanded = expanded;
- if (mExpanded) {
- ensureSelection();
- }
updateWidgets();
fireExpanded();
}
@@ -464,7 +456,8 @@ public class ZenModePanel extends FrameLayout {
ActivityManager.getCurrentUser(), false);
return c;
}
- return null;
+ // If there is a manual rule, but it has no condition listed then it is forever.
+ return forever();
}
private void handleUpdateZen(int zen) {
@@ -491,6 +484,7 @@ public class ZenModePanel extends FrameLayout {
final ConditionTag tag = getConditionTagAt(i);
if (tag != null && sameConditionId(tag.condition, mExitCondition)) {
bind(exitCondition, mZenRadioGroupContent.getChildAt(i), i);
+ tag.rb.setChecked(true);
return;
}
}
@@ -498,6 +492,7 @@ public class ZenModePanel extends FrameLayout {
exitCondition.id)) {
bind(exitCondition, mZenRadioGroupContent.getChildAt(COUNTDOWN_CONDITION_INDEX),
COUNTDOWN_CONDITION_INDEX);
+ getConditionTagAt(COUNTDOWN_CONDITION_INDEX).rb.setChecked(true);
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
index bf6b3946d101..55ec3079bdbb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
@@ -16,13 +16,27 @@
package com.android.systemui.statusbar.phone;
+import static android.app.NotificationManager.IMPORTANCE_HIGH;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyBoolean;
+import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
+import android.app.Notification;
import android.metrics.LogMaker;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.IPowerManager;
+import android.os.Looper;
+import android.os.PowerManager;
+import android.os.UserHandle;
+import android.service.notification.StatusBarNotification;
import android.support.test.filters.SmallTest;
import android.support.test.metricshelper.MetricsAsserts;
import android.support.test.runner.AndroidJUnit4;
@@ -33,9 +47,11 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.logging.testing.FakeMetricsLogger;
import com.android.keyguard.KeyguardHostView.OnDismissAction;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.recents.misc.SystemServicesProxy;
import com.android.systemui.statusbar.ActivatableNotificationView;
import com.android.systemui.statusbar.KeyguardIndicationController;
import com.android.systemui.statusbar.NotificationData;
+import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
import org.junit.Before;
@@ -52,19 +68,34 @@ public class StatusBarTest extends SysuiTestCase {
NotificationStackScrollLayout mStackScroller;
StatusBar mStatusBar;
FakeMetricsLogger mMetricsLogger;
+ HeadsUpManager mHeadsUpManager;
+ NotificationData mNotificationData;
+ PowerManager mPowerManager;
+ SystemServicesProxy mSystemServicesProxy;
private DisplayMetrics mDisplayMetrics = new DisplayMetrics();
@Before
- public void setup() {
+ public void setup() throws Exception {
mStatusBarKeyguardViewManager = mock(StatusBarKeyguardViewManager.class);
mUnlockMethodCache = mock(UnlockMethodCache.class);
mKeyguardIndicationController = mock(KeyguardIndicationController.class);
mStackScroller = mock(NotificationStackScrollLayout.class);
mMetricsLogger = new FakeMetricsLogger();
+ mHeadsUpManager = mock(HeadsUpManager.class);
+ mNotificationData = mock(NotificationData.class);
+ mSystemServicesProxy = mock(SystemServicesProxy.class);
+ IPowerManager powerManagerService = mock(IPowerManager.class);
+ HandlerThread handlerThread = new HandlerThread("TestThread");
+ handlerThread.start();
+ mPowerManager = new PowerManager(mContext, powerManagerService,
+ new Handler(handlerThread.getLooper()));
+ when(powerManagerService.isInteractive()).thenReturn(true);
+
mDependency.injectTestDependency(MetricsLogger.class, mMetricsLogger);
mStatusBar = new TestableStatusBar(mStatusBarKeyguardViewManager, mUnlockMethodCache,
- mKeyguardIndicationController, mStackScroller);
+ mKeyguardIndicationController, mStackScroller, mHeadsUpManager,
+ mNotificationData, mPowerManager, mSystemServicesProxy);
doAnswer(invocation -> {
OnDismissAction onDismissAction = (OnDismissAction) invocation.getArguments()[0];
@@ -210,14 +241,62 @@ public class StatusBarTest extends SysuiTestCase {
.setType(MetricsEvent.TYPE_ACTION));
}
+ @Test
+ public void testShouldPeek_nonSuppressedGroupSummary() {
+ when(mPowerManager.isScreenOn()).thenReturn(true);
+ when(mHeadsUpManager.isSnoozed(anyString())).thenReturn(false);
+ when(mNotificationData.shouldSuppressScreenOn(any())).thenReturn(false);
+ when(mNotificationData.shouldFilterOut(any())).thenReturn(false);
+ when(mSystemServicesProxy.isDreaming()).thenReturn(false);
+ when(mNotificationData.getImportance(any())).thenReturn(IMPORTANCE_HIGH);
+
+ Notification n = new Notification.Builder(getContext(), "a")
+ .setGroup("a")
+ .setGroupSummary(true)
+ .setGroupAlertBehavior(Notification.GROUP_ALERT_SUMMARY)
+ .build();
+ StatusBarNotification sbn = new StatusBarNotification("a", "a", 0, "a", 0, 0, n,
+ UserHandle.of(0), null, 0);
+ NotificationData.Entry entry = new NotificationData.Entry(sbn);
+
+ assertTrue(mStatusBar.shouldPeek(entry, sbn));
+ }
+
+ @Test
+ public void testShouldPeek_suppressedGroupSummary() {
+ when(mPowerManager.isScreenOn()).thenReturn(true);
+ when(mHeadsUpManager.isSnoozed(anyString())).thenReturn(false);
+ when(mNotificationData.shouldSuppressScreenOn(any())).thenReturn(false);
+ when(mNotificationData.shouldFilterOut(any())).thenReturn(false);
+ when(mSystemServicesProxy.isDreaming()).thenReturn(false);
+ when(mNotificationData.getImportance(any())).thenReturn(IMPORTANCE_HIGH);
+
+ Notification n = new Notification.Builder(getContext(), "a")
+ .setGroup("a")
+ .setGroupSummary(true)
+ .setGroupAlertBehavior(Notification.GROUP_ALERT_CHILDREN)
+ .build();
+ StatusBarNotification sbn = new StatusBarNotification("a", "a", 0, "a", 0, 0, n,
+ UserHandle.of(0), null, 0);
+ NotificationData.Entry entry = new NotificationData.Entry(sbn);
+
+ assertFalse(mStatusBar.shouldPeek(entry, sbn));
+ }
+
static class TestableStatusBar extends StatusBar {
public TestableStatusBar(StatusBarKeyguardViewManager man,
UnlockMethodCache unlock, KeyguardIndicationController key,
- NotificationStackScrollLayout stack) {
+ NotificationStackScrollLayout stack, HeadsUpManager hum, NotificationData nd,
+ PowerManager pm, SystemServicesProxy ssp) {
mStatusBarKeyguardViewManager = man;
mUnlockMethodCache = unlock;
mKeyguardIndicationController = key;
mStackScroller = stack;
+ mHeadsUpManager = hum;
+ mNotificationData = nd;
+ mUseHeadsUp = true;
+ mPowerManager = pm;
+ mSystemServicesProxy = ssp;
}
@Override
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java
index cb2063967639..6157d44d1319 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java
@@ -111,7 +111,7 @@ public class CallbackHandlerTest extends SysuiTestCase {
String typeDescription = "Test 1";
String description = "Test 2";
int type = R.drawable.stat_sys_data_fully_connected_1x;
- int qsType = R.drawable.ic_qs_signal_1x;
+ int qsType = type;
boolean wide = true;
int subId = 5;
boolean roaming = true;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
index 505e1d8346fd..c233fea3c495 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
@@ -70,7 +70,7 @@ public class NetworkControllerBaseTest extends SysuiTestCase {
protected static final int DEFAULT_SIGNAL_STRENGTH = DEFAULT_LEVEL;
protected static final int DEFAULT_QS_SIGNAL_STRENGTH = DEFAULT_LEVEL;
protected static final int DEFAULT_ICON = TelephonyIcons.ICON_3G;
- protected static final int DEFAULT_QS_ICON = TelephonyIcons.QS_DATA_3G;
+ protected static final int DEFAULT_QS_ICON = DEFAULT_ICON;
protected NetworkControllerImpl mNetworkController;
protected MobileSignalController mMobileSignalController;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
index dfe00f95fe4d..ac64263c3eb9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
@@ -25,7 +25,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest {
setupDefaultSignal();
verifyDataIndicators(TelephonyIcons.ICON_3G,
- TelephonyIcons.QS_DATA_3G);
+ TelephonyIcons.ICON_3G);
}
@Test
@@ -35,7 +35,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest {
TelephonyManager.NETWORK_TYPE_GSM);
verifyDataIndicators(TelephonyIcons.ICON_G,
- TelephonyIcons.QS_DATA_G);
+ TelephonyIcons.ICON_G);
}
@Test
@@ -45,7 +45,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest {
TelephonyManager.NETWORK_TYPE_CDMA);
verifyDataIndicators(TelephonyIcons.ICON_1X,
- TelephonyIcons.QS_DATA_1X);
+ TelephonyIcons.ICON_1X);
}
@Test
@@ -55,7 +55,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest {
TelephonyManager.NETWORK_TYPE_EDGE);
verifyDataIndicators(TelephonyIcons.ICON_E,
- TelephonyIcons.QS_DATA_E);
+ TelephonyIcons.ICON_E);
}
@Test
@@ -65,7 +65,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest {
TelephonyManager.NETWORK_TYPE_LTE);
verifyDataIndicators(TelephonyIcons.ICON_LTE,
- TelephonyIcons.QS_DATA_LTE);
+ TelephonyIcons.ICON_LTE);
}
@Test
@@ -75,7 +75,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest {
TelephonyManager.NETWORK_TYPE_HSPA);
verifyDataIndicators(TelephonyIcons.ICON_H,
- TelephonyIcons.QS_DATA_H);
+ TelephonyIcons.ICON_H);
}
@Test
@@ -104,7 +104,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest {
TelephonyManager.NETWORK_TYPE_LTE);
verifyDataIndicators(TelephonyIcons.ICON_4G,
- TelephonyIcons.QS_DATA_4G);
+ TelephonyIcons.ICON_4G);
}
@Ignore("Flaky")
@@ -117,7 +117,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest {
setConnectivity(NetworkCapabilities.TRANSPORT_CELLULAR, false, false);
verifyDataIndicators(TelephonyIcons.ICON_DATA_DISABLED,
- TelephonyIcons.QS_ICON_DATA_DISABLED);
+ TelephonyIcons.ICON_DATA_DISABLED);
}
@Test
@@ -148,7 +148,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest {
mNetworkController.handleConfigurationChanged();
verifyDataIndicators(TelephonyIcons.ICON_4G,
- TelephonyIcons.QS_DATA_4G);
+ TelephonyIcons.ICON_4G);
}
@Test
@@ -158,13 +158,13 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest {
TelephonyManager.NETWORK_TYPE_LTE);
verifyDataIndicators(TelephonyIcons.ICON_LTE,
- TelephonyIcons.QS_DATA_LTE);
+ TelephonyIcons.ICON_LTE);
when(mServiceState.getDataNetworkType())
.thenReturn(TelephonyManager.NETWORK_TYPE_HSPA);
updateServiceState();
verifyDataIndicators(TelephonyIcons.ICON_H,
- TelephonyIcons.QS_DATA_H);
+ TelephonyIcons.ICON_H);
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
index 1627925ae1bc..aa62075530eb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
@@ -214,7 +214,7 @@ public class NetworkControllerSignalTest extends NetworkControllerBaseTest {
verifyLastQsMobileDataIndicators(true,
testStrength,
- TelephonyIcons.QS_DATA_1X, false, false);
+ TelephonyIcons.ICON_1X, false, false);
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ZenModeControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ZenModeControllerImplTest.java
new file mode 100644
index 000000000000..8124bf39328b
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ZenModeControllerImplTest.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2017 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.policy;
+
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import android.os.Handler;
+import android.service.notification.ZenModeConfig;
+import android.support.test.filters.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper.RunWithLooper;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.statusbar.policy.ZenModeController.Callback;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper
+public class ZenModeControllerImplTest extends SysuiTestCase {
+
+ private Callback mCallback;
+
+ @Test
+ public void testRemoveDuringCallback() {
+ ZenModeControllerImpl controller = new ZenModeControllerImpl(mContext, new Handler());
+ mCallback = new Callback() {
+ @Override
+ public void onConfigChanged(ZenModeConfig config) {
+ controller.removeCallback(mCallback);
+ }
+ };
+ controller.addCallback(mCallback);
+ Callback mockCallback = mock(Callback.class);
+ controller.addCallback(mockCallback);
+ controller.fireConfigChanged(null);
+ verify(mockCallback).onConfigChanged(eq(null));
+ }
+
+} \ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationChildrenContainerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationChildrenContainerTest.java
index e6c8815b9e21..2dd96b686996 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationChildrenContainerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationChildrenContainerTest.java
@@ -60,4 +60,12 @@ public class NotificationChildrenContainerTest extends SysuiTestCase {
Assert.assertTrue(lowPriorityHeaderView.getParent() == null);
Assert.assertTrue(childrenContainer.getLowPriorityHeaderView() == null);
}
+
+ @Test
+ public void testRecreateNotificationHeader_hasHeader() {
+ NotificationChildrenContainer childrenContainer = mGroup.getChildrenContainer();
+ childrenContainer.recreateNotificationHeader(null);
+ Assert.assertNotNull("Children container must have a header after recreation",
+ childrenContainer.getCurrentHeaderView());
+ }
}
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index 7abaf7ff9922..38b796b316de 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -51,6 +51,7 @@ import android.service.autofill.FillEventHistory.Event;
import android.service.autofill.FillResponse;
import android.service.autofill.IAutoFillService;
import android.text.TextUtils;
+import android.util.ArraySet;
import android.util.LocalLog;
import android.util.Slog;
import android.util.SparseArray;
@@ -465,10 +466,17 @@ final class AutofillManagerServiceImpl {
if (sVerbose) Slog.v(TAG, "destroyLocked()");
final int numSessions = mSessions.size();
+ final ArraySet<RemoteFillService> remoteFillServices = new ArraySet<>(numSessions);
for (int i = 0; i < numSessions; i++) {
- mSessions.valueAt(i).destroyLocked();
+ final RemoteFillService remoteFillService = mSessions.valueAt(i).destroyLocked();
+ if (remoteFillService != null) {
+ remoteFillServices.add(remoteFillService);
+ }
}
mSessions.clear();
+ for (int i = 0; i < remoteFillServices.size(); i++) {
+ remoteFillServices.valueAt(i).destroy();
+ }
sendStateToClients(true);
}
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index bad8dcf42aae..980a7d41200f 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -419,7 +419,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
notifyUnavailableToClient();
}
synchronized (mLock) {
- processResponseLocked(response);
+ processResponseLocked(response, requestFlags);
}
final LogMaker log = (new LogMaker(MetricsEvent.AUTOFILL_REQUEST))
@@ -1026,7 +1026,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
case ACTION_START_SESSION:
// View is triggering autofill.
mCurrentViewId = viewState.id;
- viewState.update(value, virtualBounds);
+ viewState.update(value, virtualBounds, flags);
viewState.setState(ViewState.STATE_STARTED_SESSION);
requestNewFillResponseLocked(flags);
break;
@@ -1065,7 +1065,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
}
// If the ViewState is ready to be displayed, onReady() will be called.
- viewState.update(value, virtualBounds);
+ viewState.update(value, virtualBounds, flags);
break;
case ACTION_VIEW_EXITED:
if (mCurrentViewId == viewState.id) {
@@ -1204,10 +1204,10 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
// Replace the old response
mResponses.put(newResponse.getRequestId(), newResponse);
// Now process the new response
- processResponseLocked(newResponse);
+ processResponseLocked(newResponse, 0);
}
- private void processResponseLocked(@NonNull FillResponse newResponse) {
+ private void processResponseLocked(@NonNull FillResponse newResponse, int flags) {
// Make sure we are hiding the UI which will be shown
// only if handling the current response requires it.
hideAllUiIfOwnedByMe();
@@ -1215,7 +1215,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
final int requestId = newResponse.getRequestId();
if (sVerbose) {
Slog.v(TAG, "processResponseLocked(): mCurrentViewId=" + mCurrentViewId
- + ", reqId=" + requestId + ", resp=" + newResponse);
+ + ",flags=" + flags + ", reqId=" + requestId + ", resp=" + newResponse);
}
if (mResponses == null) {
@@ -1231,21 +1231,9 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
return;
}
- final ArrayList<Dataset> datasets = newResponse.getDatasets();
-
- if (datasets != null && datasets.size() == 1) {
- // Check if it its a single response for a manual request, in which case it should
- // be automatically filled
- final FillContext context = getFillContextByRequestIdLocked(requestId);
- if (context != null && (context.getStructure().getFlags() & FLAG_MANUAL_REQUEST) != 0) {
- Slog.d(TAG, "autofilling manual request directly");
- autoFill(requestId, 0, datasets.get(0));
- return;
- }
- }
// Updates the UI, if necessary.
final ViewState currentView = mViewStates.get(mCurrentViewId);
- currentView.maybeCallOnFillReady();
+ currentView.maybeCallOnFillReady(flags);
}
/**
@@ -1331,20 +1319,6 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
return viewState;
}
- /**
- * Resets the given state from all existing views in the given dataset.
- */
- private void resetViewStatesLocked(@NonNull Dataset dataset, int state) {
- final ArrayList<AutofillId> ids = dataset.getFieldIds();
- for (int j = 0; j < ids.size(); j++) {
- final AutofillId id = ids.get(j);
- final ViewState viewState = mViewStates.get(id);
- if (viewState != null) {
- viewState.resetState(state);
- }
- }
- }
-
void autoFill(int requestId, int datasetIndex, Dataset dataset) {
synchronized (mLock) {
if (mDestroyed) {
@@ -1452,8 +1426,6 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
return;
}
try {
- if (sDebug) Slog.d(TAG, "autoFillApp(): the buck is on the app: " + dataset);
-
// Skip null values as a null values means no change
final int entryCount = dataset.getFieldIds().size();
final List<AutofillId> ids = new ArrayList<>(entryCount);
@@ -1480,6 +1452,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
if (waitingDatasetAuth) {
hideFillUiIfOwnedByMe();
}
+ if (sDebug) Slog.d(TAG, "autoFillApp(): the buck is on the app: " + dataset);
+
mClient.autofill(id, ids, values);
setViewStatesLocked(null, dataset, ViewState.STATE_AUTOFILLED, false);
}
@@ -1496,15 +1470,15 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
}
}
- void destroyLocked() {
+ RemoteFillService destroyLocked() {
if (mDestroyed) {
- return;
+ return null;
}
- mRemoteFillService.destroy();
hideAllUiIfOwnedByMe();
mUi.clearCallback(this);
mDestroyed = true;
mMetricsLogger.action(MetricsEvent.AUTOFILL_SESSION_FINISHED, mPackageName);
+ return mRemoteFillService;
}
private void hideAllUiIfOwnedByMe() {
@@ -1528,8 +1502,11 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
+ id + " destroyed");
return;
}
- destroyLocked();
+ final RemoteFillService remoteFillService = destroyLocked();
mService.removeSessionLocked(id);
+ if (remoteFillService != null) {
+ remoteFillService.destroy();
+ }
}
private int getLastResponseIndex() {
diff --git a/services/autofill/java/com/android/server/autofill/ViewState.java b/services/autofill/java/com/android/server/autofill/ViewState.java
index 8a52c965345c..cd8f4a59526f 100644
--- a/services/autofill/java/com/android/server/autofill/ViewState.java
+++ b/services/autofill/java/com/android/server/autofill/ViewState.java
@@ -16,6 +16,7 @@
package com.android.server.autofill;
+import static android.service.autofill.FillRequest.FLAG_MANUAL_REQUEST;
import static com.android.server.autofill.Helper.sDebug;
import static com.android.server.autofill.Helper.sVerbose;
@@ -157,7 +158,7 @@ final class ViewState {
// TODO: refactor / rename / document this method (and maybeCallOnFillReady) to make it clear
// that it can change the value and update the UI; similarly, should replace code that
// directly sets mAutofillValue to use encapsulation.
- void update(@Nullable AutofillValue autofillValue, @Nullable Rect virtualBounds) {
+ void update(@Nullable AutofillValue autofillValue, @Nullable Rect virtualBounds, int flags) {
if (autofillValue != null) {
mCurrentValue = autofillValue;
}
@@ -165,7 +166,7 @@ final class ViewState {
mVirtualBounds = virtualBounds;
}
- maybeCallOnFillReady();
+ maybeCallOnFillReady(flags);
}
/**
@@ -173,8 +174,8 @@ final class ViewState {
* Listener#onFillReady(FillResponse, AutofillId, AutofillValue)} if the
* fill UI is ready to be displayed (i.e. when response and bounds are set).
*/
- void maybeCallOnFillReady() {
- if ((mState & STATE_AUTOFILLED) != 0) {
+ void maybeCallOnFillReady(int flags) {
+ if ((mState & STATE_AUTOFILLED) != 0 && (flags & FLAG_MANUAL_REQUEST) == 0) {
if (sDebug) Slog.d(TAG, "Ignoring UI for " + id + " on " + getStateAsString());
return;
}
diff --git a/services/autofill/java/com/android/server/autofill/ui/FillUi.java b/services/autofill/java/com/android/server/autofill/ui/FillUi.java
index d315b3d7b70f..d566d3d608b4 100644
--- a/services/autofill/java/com/android/server/autofill/ui/FillUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/FillUi.java
@@ -158,6 +158,7 @@ final class FillUi {
final RemoteViews presentation = dataset.getFieldPresentation(index);
final View view;
try {
+ if (sVerbose) Slog.v(TAG, "setting remote view for " + focusedViewId);
view = presentation.apply(context, null, interceptionHandler);
} catch (RuntimeException e) {
Slog.e(TAG, "Error inflating remote views", e);
@@ -203,6 +204,7 @@ final class FillUi {
return;
}
if (count <= 0) {
+ if (sDebug) Slog.d(TAG, "No dataset matches filter: " + mFilterText);
mCallback.requestHideFillUi();
} else {
if (updateContentSize()) {
@@ -382,6 +384,7 @@ final class FillUi {
* Shows the window.
*/
public void show(WindowManager.LayoutParams params) {
+ if (sVerbose) Slog.v(TAG, "show(): showing=" + mShowing + ", params="+ params);
try {
if (!mShowing) {
params.accessibilityTitle = mContentView.getContext()
diff --git a/services/core/java/com/android/server/EventLogTags.logtags b/services/core/java/com/android/server/EventLogTags.logtags
index 6502c012ef5b..68f8c1bb182f 100644
--- a/services/core/java/com/android/server/EventLogTags.logtags
+++ b/services/core/java/com/android/server/EventLogTags.logtags
@@ -41,14 +41,10 @@ option java_package com.android.server
# ---------------------------
# DeviceStorageMonitorService.java
# ---------------------------
-# The disk space free on the /data partition, in bytes
-2744 free_storage_changed (data|2|2)
-# Device low memory notification and disk space free on the /data partition, in bytes at that time
-2745 low_storage (data|2|2)
-# disk space free on the /data, /system, and /cache partitions in bytes
-2746 free_storage_left (data|2|2),(system|2|2),(cache|2|2)
-# file on cache partition was deleted
+# File on cache partition was deleted
2748 cache_file_deleted (path|3)
+# Storage volume state and usable space in bytes
+2749 storage_state (uuid|3),(old_state|1),(new_state|1),(usable|2),(total|2)
# ---------------------------
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index cffb158a3f21..35b452a12e64 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -3296,6 +3296,9 @@ class StorageManagerService extends IStorageManager.Stub
final StorageManager storage = mContext.getSystemService(StorageManager.class);
final StorageStatsManager stats = mContext.getSystemService(StorageStatsManager.class);
+ // Apps can't defy reserved space
+ flags &= ~StorageManager.FLAG_ALLOCATE_DEFY_RESERVED;
+
final boolean aggressive = (flags & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0;
if (aggressive) {
mContext.enforceCallingOrSelfPermission(
@@ -3306,24 +3309,31 @@ class StorageManagerService extends IStorageManager.Stub
try {
// In general, apps can allocate as much space as they want, except
// we never let them eat into either the minimum cache space or into
- // the low disk warning space.
+ // the low disk warning space. To avoid user confusion, this logic
+ // should be kept in sync with getFreeBytes().
final File path = storage.findPathForUuid(volumeUuid);
+
+ final long usable = path.getUsableSpace();
+ final long lowReserved = storage.getStorageLowBytes(path);
+ final long fullReserved = storage.getStorageFullBytes(path);
+
if (stats.isQuotaSupported(volumeUuid)) {
+ final long cacheTotal = stats.getCacheBytes(volumeUuid);
+ final long cacheReserved = storage.getStorageCacheBytes(path);
+ final long cacheClearable = Math.max(0, cacheTotal - cacheReserved);
+
if (aggressive) {
- return Math.max(0,
- stats.getFreeBytes(volumeUuid) - storage.getStorageFullBytes(path));
+ return Math.max(0, (usable + cacheTotal) - fullReserved);
} else {
- return Math.max(0,
- stats.getFreeBytes(volumeUuid) - storage.getStorageLowBytes(path)
- - storage.getStorageCacheBytes(path));
+ return Math.max(0, (usable + cacheClearable) - lowReserved);
}
} else {
// When we don't have fast quota information, we ignore cached
// data and only consider unused bytes.
if (aggressive) {
- return Math.max(0, path.getUsableSpace() - storage.getStorageFullBytes(path));
+ return Math.max(0, usable - fullReserved);
} else {
- return Math.max(0, path.getUsableSpace() - storage.getStorageLowBytes(path));
+ return Math.max(0, usable - lowReserved);
}
}
} catch (IOException e) {
@@ -3337,6 +3347,9 @@ class StorageManagerService extends IStorageManager.Stub
public void allocateBytes(String volumeUuid, long bytes, int flags) {
final StorageManager storage = mContext.getSystemService(StorageManager.class);
+ // Apps can't defy reserved space
+ flags &= ~StorageManager.FLAG_ALLOCATE_DEFY_RESERVED;
+
// This method call will enforce FLAG_ALLOCATE_AGGRESSIVE permissions so
// we don't have to enforce them locally
final long allocatableBytes = getAllocatableBytes(volumeUuid, flags);
@@ -3350,7 +3363,11 @@ class StorageManagerService extends IStorageManager.Stub
// Free up enough disk space to satisfy both the requested allocation
// and our low disk warning space.
final File path = storage.findPathForUuid(volumeUuid);
- bytes += storage.getStorageLowBytes(path);
+ if ((flags & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0) {
+ bytes += storage.getStorageFullBytes(path);
+ } else {
+ bytes += storage.getStorageLowBytes(path);
+ }
mPms.freeStorage(volumeUuid, bytes, flags);
} catch (IOException e) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index fbab26aa0339..c92c36052e72 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -8447,8 +8447,8 @@ public class ActivityManagerService extends IActivityManager.Stub
synchronized (mPidsSelfLocked) {
proc = mPidsSelfLocked.get(callingPid);
}
- if (proc != null && proc.curProcState
- < ActivityManager.PROCESS_STATE_RECEIVER) {
+ if (proc != null &&
+ !ActivityManager.isProcStateBackground(proc.curProcState)) {
// Whoever is instigating this is in the foreground, so we will allow it
// to go through.
return ActivityManager.APP_START_MODE_NORMAL;
@@ -13545,7 +13545,9 @@ public class ActivityManagerService extends IActivityManager.Stub
return;
}
if (pr.hasTopUi != hasTopUi) {
- Slog.i(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
+ if (DEBUG_OOM_ADJ) {
+ Slog.d(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
+ }
pr.hasTopUi = hasTopUi;
changed = true;
}
@@ -13922,9 +13924,9 @@ public class ActivityManagerService extends IActivityManager.Stub
final boolean supportsPictureInPicture =
mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
- final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
+ final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow(mContext);
final boolean supportsSplitScreenMultiWindow =
- ActivityManager.supportsSplitScreenMultiWindow();
+ ActivityManager.supportsSplitScreenMultiWindow(mContext);
final boolean supportsMultiDisplay = mContext.getPackageManager()
.hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index 6eae9e6f9b05..d7683047143a 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -2382,7 +2382,7 @@ final class ActivityManagerShellCommand extends ShellCommand {
if (res == null) {
return -1;
}
- pw.println(ActivityManager.supportsMultiWindow());
+ pw.println(ActivityManager.supportsMultiWindow(mInternal.mContext));
return 0;
}
@@ -2391,7 +2391,7 @@ final class ActivityManagerShellCommand extends ShellCommand {
if (res == null) {
return -1;
}
- pw.println(ActivityManager.supportsSplitScreenMultiWindow());
+ pw.println(ActivityManager.supportsSplitScreenMultiWindow(mInternal.mContext));
return 0;
}
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 5636e197aaee..9698a8fa91fd 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -130,6 +130,7 @@ import android.content.pm.ApplicationInfo;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
import android.graphics.Bitmap;
+import android.graphics.GraphicBuffer;
import android.graphics.Rect;
import android.os.Build;
import android.os.Bundle;
@@ -1419,19 +1420,17 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
break;
case ANIM_THUMBNAIL_SCALE_UP:
case ANIM_THUMBNAIL_SCALE_DOWN:
- boolean scaleUp = (animationType == ANIM_THUMBNAIL_SCALE_UP);
- service.mWindowManager.overridePendingAppTransitionThumb(
- pendingOptions.getThumbnail(),
+ final boolean scaleUp = (animationType == ANIM_THUMBNAIL_SCALE_UP);
+ final GraphicBuffer buffer = pendingOptions.getThumbnail();
+ service.mWindowManager.overridePendingAppTransitionThumb(buffer,
pendingOptions.getStartX(), pendingOptions.getStartY(),
pendingOptions.getOnAnimationStartListener(),
scaleUp);
if (intent.getSourceBounds() == null) {
intent.setSourceBounds(new Rect(pendingOptions.getStartX(),
pendingOptions.getStartY(),
- pendingOptions.getStartX()
- + pendingOptions.getThumbnail().getWidth(),
- pendingOptions.getStartY()
- + pendingOptions.getThumbnail().getHeight()));
+ pendingOptions.getStartX() + buffer.getWidth(),
+ pendingOptions.getStartY() + buffer.getHeight()));
}
break;
case ANIM_THUMBNAIL_ASPECT_SCALE_UP:
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 93e1ab462945..9db957c427f0 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -244,7 +244,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
static final int REMOVE_TASK_MODE_MOVING = 1;
// Similar to {@link #REMOVE_TASK_MODE_MOVING} and the task will be added to the top of its new
// stack and the new stack will be on top of all stacks.
- private static final int REMOVE_TASK_MODE_MOVING_TO_TOP = 2;
+ static final int REMOVE_TASK_MODE_MOVING_TO_TOP = 2;
// The height/width divide used when fitting a task within a bounds with method
// {@link #fitWithinBounds}.
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index e180aefcd11a..e828d38ef249 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -2989,8 +2989,8 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
// Calculate the default bounds (don't use existing stack bounds as we may have just created
// the stack, and schedule the start of the animation into PiP (the bounds animator that
// is triggered by this is posted on another thread)
- final Rect destBounds = stack.getPictureInPictureBounds(aspectRatio,
- false /* useExistingStackBounds */);
+ final Rect destBounds = stack.getDefaultPictureInPictureBounds(aspectRatio);
+
stack.animateResizePinnedStack(sourceHintBounds, destBounds, -1 /* animationDuration */,
true /* fromFullscreen */);
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index 7ed07e0e931a..07caf9e5611a 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -1432,7 +1432,13 @@ class ActivityStarter {
+ "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + mIntent);
mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
mNewTaskInfo = mSourceRecord.info;
- mNewTaskIntent = mSourceRecord.getTask().intent;
+
+ // It is not guaranteed that the source record will have a task associated with it. For,
+ // example, if this method is being called for processing a pending activity launch, it
+ // is possible that the activity has been removed from the task after the launch was
+ // enqueued.
+ final TaskRecord sourceTask = mSourceRecord.getTask();
+ mNewTaskIntent = sourceTask != null ? sourceTask.intent : null;
}
mSourceRecord = null;
mSourceStack = null;
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 243906260593..c20221bfe4aa 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -17,6 +17,8 @@
package com.android.server.am;
import static com.android.internal.os.BatteryStatsImpl.ExternalStatsSync.UPDATE_CPU;
+import static com.android.internal.os.BatteryStatsImpl.ExternalStatsSync.UPDATE_RADIO;
+import static com.android.internal.os.BatteryStatsImpl.ExternalStatsSync.UPDATE_WIFI;
import android.annotation.Nullable;
import android.bluetooth.BluetoothActivityEnergyInfo;
@@ -87,6 +89,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub
implements PowerManagerInternal.LowPowerModeListener,
BatteryStatsImpl.PlatformIdleStateCallback {
static final String TAG = "BatteryStatsService";
+ static final boolean DBG = false;
/**
* How long to wait on an individual subsystem to return its stats.
@@ -152,11 +155,11 @@ public final class BatteryStatsService extends IBatteryStats.Stub
case MSG_WRITE_TO_DISK:
updateExternalStatsSync("write", UPDATE_ALL);
- Slog.d(TAG, "begin writeAsyncLocked");
+ if (DBG) Slog.d(TAG, "begin writeAsyncLocked");
synchronized (mStats) {
mStats.writeAsyncLocked();
}
- Slog.d(TAG, "end writeAsyncLocked");
+ if (DBG) Slog.d(TAG, "end writeAsyncLocked");
break;
}
}
@@ -196,7 +199,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub
@Override
public String getPlatformLowPowerStats() {
- Slog.d(TAG, "begin getPlatformLowPowerStats");
+ if (DBG) Slog.d(TAG, "begin getPlatformLowPowerStats");
try {
mUtf8BufferStat.clear();
mUtf16BufferStat.clear();
@@ -212,7 +215,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub
mUtf16BufferStat.flip();
return mUtf16BufferStat.toString();
} finally {
- Slog.d(TAG, "end getPlatformLowPowerStats");
+ if (DBG) Slog.d(TAG, "end getPlatformLowPowerStats");
}
}
@@ -230,10 +233,12 @@ public final class BatteryStatsService extends IBatteryStats.Stub
public void publish(Context context) {
mContext = context;
- mStats.setRadioScanningTimeout(mContext.getResources().getInteger(
- com.android.internal.R.integer.config_radioScanningTimeout)
- * 1000L);
- mStats.setPowerProfile(new PowerProfile(context));
+ synchronized (mStats) {
+ mStats.setRadioScanningTimeoutLocked(mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_radioScanningTimeout)
+ * 1000L);
+ mStats.setPowerProfileLocked(new PowerProfile(context));
+ }
ServiceManager.addService(BatteryStats.SERVICE_NAME, asBinder());
}
@@ -244,9 +249,11 @@ public final class BatteryStatsService extends IBatteryStats.Stub
public void initPowerManagement() {
final PowerManagerInternal powerMgr = LocalServices.getService(PowerManagerInternal.class);
powerMgr.registerLowPowerModeObserver(this);
- mStats.notePowerSaveMode(
- powerMgr.getLowPowerState(ServiceType.BATTERY_STATS)
- .batterySaverEnabled);
+ synchronized (mStats) {
+ mStats.notePowerSaveModeLocked(
+ powerMgr.getLowPowerState(ServiceType.BATTERY_STATS)
+ .batterySaverEnabled);
+ }
(new WakeupReasonThread()).start();
}
@@ -279,7 +286,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub
@Override
public void onLowPowerModeChanged(PowerSaveState result) {
synchronized (mStats) {
- mStats.notePowerSaveMode(result.batterySaverEnabled);
+ mStats.notePowerSaveModeLocked(result.batterySaverEnabled);
}
}
@@ -561,11 +568,11 @@ public final class BatteryStatsService extends IBatteryStats.Stub
public void noteScreenState(int state) {
enforceCallingPermission();
- Slog.d(TAG, "begin noteScreenState");
+ if (DBG) Slog.d(TAG, "begin noteScreenState");
synchronized (mStats) {
mStats.noteScreenStateLocked(state);
}
- Slog.d(TAG, "end noteScreenState");
+ if (DBG) Slog.d(TAG, "end noteScreenState");
}
public void noteScreenBrightness(int brightness) {
@@ -605,8 +612,13 @@ public final class BatteryStatsService extends IBatteryStats.Stub
public void noteMobileRadioPowerState(int powerState, long timestampNs, int uid) {
enforceCallingPermission();
+ boolean update;
synchronized (mStats) {
- mStats.noteMobileRadioPowerState(powerState, timestampNs, uid);
+ update = mStats.noteMobileRadioPowerStateLocked(powerState, timestampNs, uid);
+ }
+
+ if (update) {
+ mHandler.scheduleSync("modem-data", UPDATE_RADIO);
}
}
@@ -718,11 +730,11 @@ public final class BatteryStatsService extends IBatteryStats.Stub
public void noteStartCamera(int uid) {
enforceCallingPermission();
- Slog.d(TAG, "begin noteStartCamera");
+ if (DBG) Slog.d(TAG, "begin noteStartCamera");
synchronized (mStats) {
mStats.noteCameraOnLocked(uid);
}
- Slog.d(TAG, "end noteStartCamera");
+ if (DBG) Slog.d(TAG, "end noteStartCamera");
}
public void noteStopCamera(int uid) {
@@ -758,7 +770,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub
powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM) ? "active"
: "inactive";
mHandler.scheduleSync("wifi-data: " + type,
- BatteryStatsImpl.ExternalStatsSync.UPDATE_WIFI);
+ UPDATE_WIFI);
}
mStats.noteWifiRadioPowerState(powerState, tsNanos, uid);
}
@@ -916,9 +928,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub
@Override
public void noteNetworkStatsEnabled() {
enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteNetworkStatsEnabledLocked();
- }
+ mHandler.scheduleSync("network-stats-enabled", UPDATE_RADIO | UPDATE_WIFI);
}
@Override
@@ -944,10 +954,10 @@ public final class BatteryStatsService extends IBatteryStats.Stub
}
@Override
- public void noteBleScanStarted(WorkSource ws) {
+ public void noteBleScanStarted(WorkSource ws, boolean isUnoptimized) {
enforceCallingPermission();
synchronized (mStats) {
- mStats.noteBluetoothScanStartedFromSourceLocked(ws);
+ mStats.noteBluetoothScanStartedFromSourceLocked(ws, isUnoptimized);
}
}
@@ -984,9 +994,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub
return;
}
- synchronized (mStats) {
- mStats.updateWifiStateLocked(info);
- }
+ mStats.updateWifiState(info);
}
@Override
@@ -1011,9 +1019,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub
return;
}
- synchronized (mStats) {
- mStats.updateMobileRadioStateLocked(SystemClock.elapsedRealtime(), info);
- }
+ mStats.updateMobileRadioState(info);
}
public boolean isOnBattery() {
@@ -1342,23 +1348,23 @@ public final class BatteryStatsService extends IBatteryStats.Stub
}
}
}
- Slog.d(TAG, "begin dumpCheckinLocked from UID " + Binder.getCallingUid());
+ if (DBG) Slog.d(TAG, "begin dumpCheckinLocked from UID " + Binder.getCallingUid());
synchronized (mStats) {
mStats.dumpCheckinLocked(mContext, pw, apps, flags, historyStart);
if (writeData) {
mStats.writeAsyncLocked();
}
}
- Slog.d(TAG, "end dumpCheckinLocked");
+ if (DBG) Slog.d(TAG, "end dumpCheckinLocked");
} else {
- Slog.d(TAG, "begin dumpLocked from UID " + Binder.getCallingUid());
+ if (DBG) Slog.d(TAG, "begin dumpLocked from UID " + Binder.getCallingUid());
synchronized (mStats) {
mStats.dumpLocked(mContext, pw, flags, reqUid, historyStart);
if (writeData) {
mStats.writeAsyncLocked();
}
}
- Slog.d(TAG, "end dumpLocked");
+ if (DBG) Slog.d(TAG, "end dumpLocked");
}
}
@@ -1480,15 +1486,15 @@ public final class BatteryStatsService extends IBatteryStats.Stub
SynchronousResultReceiver bluetoothReceiver = null;
SynchronousResultReceiver modemReceiver = null;
- Slog.d(TAG, "begin updateExternalStatsSync reason=" + reason);
+ if (DBG) Slog.d(TAG, "begin updateExternalStatsSync reason=" + reason);
synchronized (mExternalStatsLock) {
if (mContext == null) {
// Don't do any work yet.
- Slog.d(TAG, "end updateExternalStatsSync");
+ if (DBG) Slog.d(TAG, "end updateExternalStatsSync");
return;
}
- if ((updateFlags & BatteryStatsImpl.ExternalStatsSync.UPDATE_WIFI) != 0) {
+ if ((updateFlags & UPDATE_WIFI) != 0) {
if (mWifiManager == null) {
mWifiManager = IWifiManager.Stub.asInterface(
ServiceManager.getService(Context.WIFI_SERVICE));
@@ -1557,14 +1563,6 @@ public final class BatteryStatsService extends IBatteryStats.Stub
mStats.updateKernelWakelocksLocked();
mStats.updateKernelMemoryBandwidthLocked();
- if (wifiInfo != null) {
- if (wifiInfo.isValid()) {
- mStats.updateWifiStateLocked(extractDelta(wifiInfo));
- } else {
- Slog.e(TAG, "wifi info is invalid: " + wifiInfo);
- }
- }
-
if (bluetoothInfo != null) {
if (bluetoothInfo.isValid()) {
mStats.updateBluetoothStateLocked(bluetoothInfo);
@@ -1572,18 +1570,25 @@ public final class BatteryStatsService extends IBatteryStats.Stub
Slog.e(TAG, "bluetooth info is invalid: " + bluetoothInfo);
}
}
+ }
- if (modemInfo != null) {
- if (modemInfo.isValid()) {
- mStats.updateMobileRadioStateLocked(SystemClock.elapsedRealtime(),
- modemInfo);
- } else {
- Slog.e(TAG, "modem info is invalid: " + modemInfo);
- }
+ if (wifiInfo != null) {
+ if (wifiInfo.isValid()) {
+ mStats.updateWifiState(extractDelta(wifiInfo));
+ } else {
+ Slog.e(TAG, "wifi info is invalid: " + wifiInfo);
+ }
+ }
+
+ if (modemInfo != null) {
+ if (modemInfo.isValid()) {
+ mStats.updateMobileRadioState(modemInfo);
+ } else {
+ Slog.e(TAG, "modem info is invalid: " + modemInfo);
}
}
}
- Slog.d(TAG, "end updateExternalStatsSync");
+ if (DBG) Slog.d(TAG, "end updateExternalStatsSync");
}
/**
@@ -1603,7 +1608,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub
return getHealthStatsForUidLocked(requestUid);
}
} catch (Exception ex) {
- Slog.d(TAG, "Crashed while writing for takeUidSnapshot(" + requestUid + ")", ex);
+ Slog.w(TAG, "Crashed while writing for takeUidSnapshot(" + requestUid + ")", ex);
throw ex;
} finally {
Binder.restoreCallingIdentity(ident);
@@ -1633,7 +1638,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub
return results;
}
} catch (Exception ex) {
- Slog.d(TAG, "Crashed while writing for takeUidSnapshots("
+ if (DBG) Slog.d(TAG, "Crashed while writing for takeUidSnapshots("
+ Arrays.toString(requestUids) + ") i=" + i, ex);
throw ex;
} finally {
diff --git a/services/core/java/com/android/server/am/KeyguardController.java b/services/core/java/com/android/server/am/KeyguardController.java
index 144eb11cbf85..2e0ec0b361e2 100644
--- a/services/core/java/com/android/server/am/KeyguardController.java
+++ b/services/core/java/com/android/server/am/KeyguardController.java
@@ -97,7 +97,7 @@ class KeyguardController {
mKeyguardShowing = showing;
dismissDockedStackIfNeeded();
if (showing) {
- mKeyguardGoingAway = false;
+ setKeyguardGoingAway(false);
mDismissalRequested = false;
}
mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
@@ -114,7 +114,7 @@ class KeyguardController {
if (mKeyguardShowing) {
mWindowManager.deferSurfaceLayout();
try {
- mKeyguardGoingAway = true;
+ setKeyguardGoingAway(true);
mWindowManager.prepareAppTransition(TRANSIT_KEYGUARD_GOING_AWAY,
false /* alwaysKeepCurrent */, convertTransitFlags(flags),
false /* forceOverride */);
@@ -139,6 +139,11 @@ class KeyguardController {
mWindowManager.dismissKeyguard(callback);
}
+ private void setKeyguardGoingAway(boolean keyguardGoingAway) {
+ mKeyguardGoingAway = keyguardGoingAway;
+ mWindowManager.setKeyguardGoingAway(keyguardGoingAway);
+ }
+
private void failCallback(IKeyguardDismissCallback callback) {
try {
callback.onDismissError();
diff --git a/services/core/java/com/android/server/am/PinnedActivityStack.java b/services/core/java/com/android/server/am/PinnedActivityStack.java
index 702bf92c65f8..2010c24000e8 100644
--- a/services/core/java/com/android/server/am/PinnedActivityStack.java
+++ b/services/core/java/com/android/server/am/PinnedActivityStack.java
@@ -44,9 +44,9 @@ class PinnedActivityStack extends ActivityStack<PinnedStackWindowController>
return new PinnedStackWindowController(mStackId, this, displayId, onTop, outBounds);
}
- Rect getPictureInPictureBounds(float aspectRatio, boolean useExistingStackBounds) {
+ Rect getDefaultPictureInPictureBounds(float aspectRatio) {
return getWindowContainerController().getPictureInPictureBounds(aspectRatio,
- useExistingStackBounds);
+ null /* currentStackBounds */);
}
void animateResizePinnedStack(Rect sourceHintBounds, Rect toBounds, int animationDuration,
diff --git a/services/core/java/com/android/server/am/ProcessStatsService.java b/services/core/java/com/android/server/am/ProcessStatsService.java
index deb3b287d7aa..39aed7cf3d67 100644
--- a/services/core/java/com/android/server/am/ProcessStatsService.java
+++ b/services/core/java/com/android/server/am/ProcessStatsService.java
@@ -233,7 +233,8 @@ public final class ProcessStatsService extends IProcessStats.Stub {
updateFile();
}
mLastWriteTime = SystemClock.uptimeMillis();
- Slog.i(TAG, "Prepared write state in " + (SystemClock.uptimeMillis()-now) + "ms");
+ if (DEBUG) Slog.d(TAG, "Prepared write state in "
+ + (SystemClock.uptimeMillis()-now) + "ms");
if (!sync) {
BackgroundThread.getHandler().post(new Runnable() {
@Override public void run() {
diff --git a/services/core/java/com/android/server/am/ProviderMap.java b/services/core/java/com/android/server/am/ProviderMap.java
index a6997f944a4c..32d03daedef3 100644
--- a/services/core/java/com/android/server/am/ProviderMap.java
+++ b/services/core/java/com/android/server/am/ProviderMap.java
@@ -382,18 +382,29 @@ public final class ProviderMap {
}
/**
- * Invokes IApplicationThread.dumpProvider() on the thread of the specified provider if
- * there is a thread associated with the provider.
+ * Before invoking IApplicationThread.dumpProvider(), print meta information to the print
+ * writer and handle passed flags.
*/
private void dumpProvider(String prefix, FileDescriptor fd, PrintWriter pw,
final ContentProviderRecord r, String[] args, boolean dumpAll) {
+ for (String s: args) {
+ if (!dumpAll && s.contains("--proto")) {
+ if (r.proc != null && r.proc.thread != null) {
+ dumpToTransferPipe(null , fd, pw, r, args);
+ }
+ return;
+ }
+ }
String innerPrefix = prefix + " ";
synchronized (mAm) {
pw.print(prefix); pw.print("PROVIDER ");
- pw.print(r);
- pw.print(" pid=");
- if (r.proc != null) pw.println(r.proc.pid);
- else pw.println("(not running)");
+ pw.print(r);
+ pw.print(" pid=");
+ if (r.proc != null) {
+ pw.println(r.proc.pid);
+ } else {
+ pw.println("(not running)");
+ }
if (dumpAll) {
r.dump(pw, innerPrefix, true);
}
@@ -401,23 +412,32 @@ public final class ProviderMap {
if (r.proc != null && r.proc.thread != null) {
pw.println(" Client:");
pw.flush();
+ dumpToTransferPipe(" ", fd, pw, r, args);
+ }
+ }
+
+ /**
+ * Invokes IApplicationThread.dumpProvider() on the thread of the specified provider without
+ * any meta string (e.g., provider info, indentation) written to the file descriptor.
+ */
+ private void dumpToTransferPipe(String prefix, FileDescriptor fd, PrintWriter pw,
+ final ContentProviderRecord r, String[] args) {
+ try {
+ TransferPipe tp = new TransferPipe();
try {
- TransferPipe tp = new TransferPipe();
- try {
- r.proc.thread.dumpProvider(
- tp.getWriteFd(), r.provider.asBinder(), args);
- tp.setBufferPrefix(" ");
- // Short timeout, since blocking here can
- // deadlock with the application.
- tp.go(fd, 2000);
- } finally {
- tp.kill();
- }
- } catch (IOException ex) {
- pw.println(" Failure while dumping the provider: " + ex);
- } catch (RemoteException ex) {
- pw.println(" Got a RemoteException while dumping the service");
+ r.proc.thread.dumpProvider(
+ tp.getWriteFd(), r.provider.asBinder(), args);
+ tp.setBufferPrefix(prefix);
+ // Short timeout, since blocking here can
+ // deadlock with the application.
+ tp.go(fd, 2000);
+ } finally {
+ tp.kill();
}
+ } catch (IOException ex) {
+ pw.println(" Failure while dumping the provider: " + ex);
+ } catch (RemoteException ex) {
+ pw.println(" Got a RemoteException while dumping the service");
}
}
}
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index 7eec945a6cbb..e81e6d7334b3 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -115,6 +115,7 @@ import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
import static com.android.server.am.ActivityRecord.STARTING_WINDOW_SHOWN;
import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_MOVING;
+import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_MOVING_TO_TOP;
import static com.android.server.am.ActivityStackSupervisor.PAUSE_IMMEDIATELY;
import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
@@ -673,8 +674,11 @@ final class TaskRecord extends ConfigurationContainer implements TaskWindowConta
mWindowContainerController.reparent(toStack.getWindowContainerController(), position,
moveStackMode == REPARENT_MOVE_STACK_TO_FRONT);
+ final boolean moveStackToFront = moveStackMode == REPARENT_MOVE_STACK_TO_FRONT
+ || (moveStackMode == REPARENT_KEEP_STACK_AT_FRONT && (wasFocused || wasFront));
// Move the task
- sourceStack.removeTask(this, reason, REMOVE_TASK_MODE_MOVING);
+ sourceStack.removeTask(this, reason, moveStackToFront
+ ? REMOVE_TASK_MODE_MOVING_TO_TOP : REMOVE_TASK_MODE_MOVING);
toStack.addTask(this, position, false /* schedulePictureInPictureModeChange */, reason);
if (schedulePictureInPictureModeChange) {
@@ -693,8 +697,6 @@ final class TaskRecord extends ConfigurationContainer implements TaskWindowConta
// If the task had focus before (or we're requested to move focus), move focus to the
// new stack by moving the stack to the front.
- final boolean moveStackToFront = moveStackMode == REPARENT_MOVE_STACK_TO_FRONT
- || (moveStackMode == REPARENT_KEEP_STACK_AT_FRONT && (wasFocused || wasFront));
if (r != null) {
toStack.moveToFrontAndResumeStateIfNeeded(r, moveStackToFront, wasResumed,
wasPaused, reason);
diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java
index b8d633fc666f..73a365b0da72 100644
--- a/services/core/java/com/android/server/notification/ManagedServices.java
+++ b/services/core/java/com/android/server/notification/ManagedServices.java
@@ -221,7 +221,9 @@ abstract public class ManagedServices {
restoredSettingName(element),
newValue,
userid);
- updateSettingsAccordingToInstalledServices(element, userid);
+ if (mConfig.secureSettingName.equals(element)) {
+ updateSettingsAccordingToInstalledServices(element, userid);
+ }
rebuildRestoredPackages();
}
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index e377d57a0ead..3667e161b7af 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -3225,7 +3225,7 @@ public class NotificationManagerService extends SystemService {
Settings.Global.SHOW_NOTIFICATION_CHANNEL_WARNINGS, defaultWarningEnabled) != 0;
if (warningEnabled) {
Toast toast = Toast.makeText(getContext(), mHandler.getLooper(), toastText,
- Toast.LENGTH_LONG);
+ Toast.LENGTH_SHORT);
toast.show();
}
}
@@ -3759,13 +3759,7 @@ public class NotificationManagerService extends SystemService {
return true;
}
if (record.sbn.isGroup()) {
- if (notification.isGroupSummary()
- && notification.getGroupAlertBehavior() == Notification.GROUP_ALERT_CHILDREN) {
- return true;
- } else if (notification.isGroupChild()
- && notification.getGroupAlertBehavior() == Notification.GROUP_ALERT_SUMMARY) {
- return true;
- }
+ return notification.suppressAlertingDueToGrouping();
}
return false;
}
diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java
index e6e461744094..c95b5c557b32 100644
--- a/services/core/java/com/android/server/pm/Installer.java
+++ b/services/core/java/com/android/server/pm/Installer.java
@@ -395,10 +395,11 @@ public class Installer extends SystemService {
}
}
- public void freeCache(String uuid, long freeStorageSize, int flags) throws InstallerException {
+ public void freeCache(String uuid, long targetFreeBytes, long cacheReservedBytes, int flags)
+ throws InstallerException {
if (!checkBeforeRemote()) return;
try {
- mInstalld.freeCache(uuid, freeStorageSize, flags);
+ mInstalld.freeCache(uuid, targetFreeBytes, cacheReservedBytes, flags);
} catch (Exception e) {
throw InstallerException.from(e);
}
diff --git a/services/core/java/com/android/server/pm/InstantAppRegistry.java b/services/core/java/com/android/server/pm/InstantAppRegistry.java
index b1659841d5ac..211a1c9f3edf 100644
--- a/services/core/java/com/android/server/pm/InstantAppRegistry.java
+++ b/services/core/java/com/android/server/pm/InstantAppRegistry.java
@@ -21,6 +21,7 @@ import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.content.Intent;
import android.content.pm.InstantAppInfo;
+import android.content.pm.PackageManager;
import android.content.pm.PackageParser;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
@@ -32,6 +33,8 @@ import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
+import android.os.UserHandle;
+import android.os.storage.StorageManager;
import android.provider.Settings;
import android.util.ArrayMap;
import android.util.AtomicFile;
@@ -76,7 +79,16 @@ class InstantAppRegistry {
private static final String LOG_TAG = "InstantAppRegistry";
- private static final long DEFAULT_UNINSTALLED_INSTANT_APP_CACHE_DURATION_MILLIS =
+ static final long DEFAULT_INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD =
+ DEBUG ? 30 * 1000L /* thirty seconds */ : 7 * 24 * 60 * 60 * 1000L; /* one week */
+
+ private static final long DEFAULT_INSTALLED_INSTANT_APP_MAX_CACHE_PERIOD =
+ DEBUG ? 60 * 1000L /* one min */ : 6 * 30 * 24 * 60 * 60 * 1000L; /* six months */
+
+ static final long DEFAULT_UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD =
+ DEBUG ? 30 * 1000L /* thirty seconds */ : 7 * 24 * 60 * 60 * 1000L; /* one week */
+
+ private static final long DEFAULT_UNINSTALLED_INSTANT_APP_MAX_CACHE_PERIOD =
DEBUG ? 60 * 1000L /* one min */ : 6 * 30 * 24 * 60 * 60 * 1000L; /* six months */
private static final String INSTANT_APPS_FOLDER = "instant";
@@ -535,46 +547,195 @@ class InstantAppRegistry {
}
}
- public void pruneInstantAppsLPw() {
- // For now we prune only state for uninstalled instant apps
- final long maxCacheDurationMillis = Settings.Global.getLong(
+ void pruneInstantApps() {
+ final long maxInstalledCacheDuration = Settings.Global.getLong(
mService.mContext.getContentResolver(),
- Settings.Global.UNINSTALLED_INSTANT_APP_CACHE_DURATION_MILLIS,
- DEFAULT_UNINSTALLED_INSTANT_APP_CACHE_DURATION_MILLIS);
-
- for (int userId : UserManagerService.getInstance().getUserIds()) {
- // Prune in-memory state
- removeUninstalledInstantAppStateLPw((UninstalledInstantAppState state) -> {
- final long elapsedCachingMillis = System.currentTimeMillis() - state.mTimestamp;
- return (elapsedCachingMillis > maxCacheDurationMillis);
- }, userId);
-
- // Prune on-disk state
- File instantAppsDir = getInstantApplicationsDir(userId);
- if (!instantAppsDir.exists()) {
- continue;
+ Settings.Global.INSTALLED_INSTANT_APP_MAX_CACHE_PERIOD,
+ DEFAULT_INSTALLED_INSTANT_APP_MAX_CACHE_PERIOD);
+
+ final long maxUninstalledCacheDuration = Settings.Global.getLong(
+ mService.mContext.getContentResolver(),
+ Settings.Global.UNINSTALLED_INSTANT_APP_MAX_CACHE_PERIOD,
+ DEFAULT_UNINSTALLED_INSTANT_APP_MAX_CACHE_PERIOD);
+
+ try {
+ pruneInstantApps(Long.MAX_VALUE,
+ maxInstalledCacheDuration, maxUninstalledCacheDuration);
+ } catch (IOException e) {
+ Slog.e(LOG_TAG, "Error pruning installed and uninstalled instant apps", e);
+ }
+ }
+
+ boolean pruneInstalledInstantApps(long neededSpace, long maxInstalledCacheDuration) {
+ try {
+ return pruneInstantApps(neededSpace, maxInstalledCacheDuration, Long.MAX_VALUE);
+ } catch (IOException e) {
+ Slog.e(LOG_TAG, "Error pruning installed instant apps", e);
+ return false;
+ }
+ }
+
+ boolean pruneUninstalledInstantApps(long neededSpace, long maxUninstalledCacheDuration) {
+ try {
+ return pruneInstantApps(neededSpace, Long.MAX_VALUE, maxUninstalledCacheDuration);
+ } catch (IOException e) {
+ Slog.e(LOG_TAG, "Error pruning uninstalled instant apps", e);
+ return false;
+ }
+ }
+
+ /**
+ * Prunes instant apps until there is enough <code>neededSpace</code>. Both
+ * installed and uninstalled instant apps are pruned that are older than
+ * <code>maxInstalledCacheDuration</code> and <code>maxUninstalledCacheDuration</code>
+ * respectively. All times are in milliseconds.
+ *
+ * @param neededSpace The space to ensure is free.
+ * @param maxInstalledCacheDuration The max duration for caching installed apps in millis.
+ * @param maxUninstalledCacheDuration The max duration for caching uninstalled apps in millis.
+ * @return Whether enough space was freed.
+ *
+ * @throws IOException
+ */
+ private boolean pruneInstantApps(long neededSpace, long maxInstalledCacheDuration,
+ long maxUninstalledCacheDuration) throws IOException {
+ final StorageManager storage = mService.mContext.getSystemService(StorageManager.class);
+ final File file = storage.findPathForUuid(StorageManager.UUID_PRIVATE_INTERNAL);
+
+ if (file.getUsableSpace() >= neededSpace) {
+ return true;
+ }
+
+ List<String> packagesToDelete = null;
+
+ final int[] allUsers;
+ final long now = System.currentTimeMillis();
+
+ // Prune first installed instant apps
+ synchronized (mService.mPackages) {
+ allUsers = PackageManagerService.sUserManager.getUserIds();
+
+ final int packageCount = mService.mPackages.size();
+ for (int i = 0; i < packageCount; i++) {
+ final PackageParser.Package pkg = mService.mPackages.valueAt(i);
+ if (now - pkg.getLatestPackageUseTimeInMills() < maxInstalledCacheDuration) {
+ continue;
+ }
+ if (!(pkg.mExtras instanceof PackageSetting)) {
+ continue;
+ }
+ final PackageSetting ps = (PackageSetting) pkg.mExtras;
+ boolean installedOnlyAsInstantApp = false;
+ for (int userId : allUsers) {
+ if (ps.getInstalled(userId)) {
+ if (ps.getInstantApp(userId)) {
+ installedOnlyAsInstantApp = true;
+ } else {
+ installedOnlyAsInstantApp = false;
+ break;
+ }
+ }
+ }
+ if (installedOnlyAsInstantApp) {
+ if (packagesToDelete == null) {
+ packagesToDelete = new ArrayList<>();
+ }
+ packagesToDelete.add(pkg.packageName);
+ }
}
- File[] files = instantAppsDir.listFiles();
- if (files == null) {
- continue;
+
+ if (packagesToDelete != null) {
+ packagesToDelete.sort((String lhs, String rhs) -> {
+ final PackageParser.Package lhsPkg = mService.mPackages.get(lhs);
+ final PackageParser.Package rhsPkg = mService.mPackages.get(rhs);
+ if (lhsPkg == null && rhsPkg == null) {
+ return 0;
+ } else if (lhsPkg == null) {
+ return -1;
+ } else if (rhsPkg == null) {
+ return 1;
+ } else {
+ if (lhsPkg.getLatestPackageUseTimeInMills() >
+ rhsPkg.getLatestPackageUseTimeInMills()) {
+ return 1;
+ } else if (lhsPkg.getLatestPackageUseTimeInMills() <
+ rhsPkg.getLatestPackageUseTimeInMills()) {
+ return -1;
+ } else {
+ if (lhsPkg.mExtras instanceof PackageSetting
+ && rhsPkg.mExtras instanceof PackageSetting) {
+ final PackageSetting lhsPs = (PackageSetting) lhsPkg.mExtras;
+ final PackageSetting rhsPs = (PackageSetting) rhsPkg.mExtras;
+ if (lhsPs.firstInstallTime > rhsPs.firstInstallTime) {
+ return 1;
+ } else {
+ return -1;
+ }
+ } else {
+ return 0;
+ }
+ }
+ }
+ });
}
- for (File instantDir : files) {
- if (!instantDir.isDirectory()) {
- continue;
+ }
+
+ if (packagesToDelete != null) {
+ final int packageCount = packagesToDelete.size();
+ for (int i = 0; i < packageCount; i++) {
+ final String packageToDelete = packagesToDelete.get(i);
+ if (mService.deletePackageX(packageToDelete, PackageManager.VERSION_CODE_HIGHEST,
+ UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS)
+ == PackageManager.DELETE_SUCCEEDED) {
+ if (file.getUsableSpace() >= neededSpace) {
+ return true;
+ }
}
+ }
+ }
- File metadataFile = new File(instantDir, INSTANT_APP_METADATA_FILE);
- if (!metadataFile.exists()) {
+ // Prune uninstalled instant apps
+ synchronized (mService.mPackages) {
+ // TODO: Track last used time for uninstalled instant apps for better pruning
+ for (int userId : UserManagerService.getInstance().getUserIds()) {
+ // Prune in-memory state
+ removeUninstalledInstantAppStateLPw((UninstalledInstantAppState state) -> {
+ final long elapsedCachingMillis = System.currentTimeMillis() - state.mTimestamp;
+ return (elapsedCachingMillis > maxUninstalledCacheDuration);
+ }, userId);
+
+ // Prune on-disk state
+ File instantAppsDir = getInstantApplicationsDir(userId);
+ if (!instantAppsDir.exists()) {
+ continue;
+ }
+ File[] files = instantAppsDir.listFiles();
+ if (files == null) {
continue;
}
+ for (File instantDir : files) {
+ if (!instantDir.isDirectory()) {
+ continue;
+ }
+
+ File metadataFile = new File(instantDir, INSTANT_APP_METADATA_FILE);
+ if (!metadataFile.exists()) {
+ continue;
+ }
- final long elapsedCachingMillis = System.currentTimeMillis()
- - metadataFile.lastModified();
- if (elapsedCachingMillis > maxCacheDurationMillis) {
- deleteDir(instantDir);
+ final long elapsedCachingMillis = System.currentTimeMillis()
+ - metadataFile.lastModified();
+ if (elapsedCachingMillis > maxUninstalledCacheDuration) {
+ deleteDir(instantDir);
+ if (file.getUsableSpace() >= neededSpace) {
+ return true;
+ }
+ }
}
}
}
+
+ return false;
}
private @Nullable List<InstantAppInfo> getInstalledInstantApplicationsLPr(
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 782325a941b9..99eda862473b 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -875,9 +875,9 @@ public class PackageManagerService extends IPackageManager.Stub
new ParallelPackageParserCallback();
public static final class SharedLibraryEntry {
- public final String path;
- public final String apk;
- public final SharedLibraryInfo info;
+ public final @Nullable String path;
+ public final @Nullable String apk;
+ public final @NonNull SharedLibraryInfo info;
SharedLibraryEntry(String _path, String _apk, String name, int version, int type,
String declaringPackageName, int declaringPackageVersionCode) {
@@ -1312,6 +1312,9 @@ public class PackageManagerService extends IPackageManager.Stub
// Delay time in millisecs
static final int BROADCAST_DELAY = 10 * 1000;
+ private static final long DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD =
+ 2 * 60 * 60 * 1000L; /* two hours */
+
static UserManagerService sUserManager;
// Stores a list of users whose package restrictions file needs to be updated
@@ -4155,13 +4158,13 @@ public class PackageManagerService extends IPackageManager.Stub
@Override
public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize,
- final IPackageDataObserver observer) {
+ final int storageFlags, final IPackageDataObserver observer) {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.CLEAR_APP_CACHE, null);
mHandler.post(() -> {
boolean success = false;
try {
- freeStorage(volumeUuid, freeStorageSize, 0);
+ freeStorage(volumeUuid, freeStorageSize, storageFlags);
success = true;
} catch (IOException e) {
Slog.w(TAG, e);
@@ -4178,13 +4181,13 @@ public class PackageManagerService extends IPackageManager.Stub
@Override
public void freeStorage(final String volumeUuid, final long freeStorageSize,
- final IntentSender pi) {
+ final int storageFlags, final IntentSender pi) {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.CLEAR_APP_CACHE, TAG);
mHandler.post(() -> {
boolean success = false;
try {
- freeStorage(volumeUuid, freeStorageSize, 0);
+ freeStorage(volumeUuid, freeStorageSize, storageFlags);
success = true;
} catch (IOException e) {
Slog.w(TAG, e);
@@ -4209,10 +4212,14 @@ public class PackageManagerService extends IPackageManager.Stub
if (file.getUsableSpace() >= bytes) return;
if (ENABLE_FREE_CACHE_V2) {
- final boolean aggressive = (storageFlags
- & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0;
final boolean internalVolume = Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL,
volumeUuid);
+ final boolean aggressive = (storageFlags
+ & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0;
+ final boolean defyReserved = (storageFlags
+ & StorageManager.FLAG_ALLOCATE_DEFY_RESERVED) != 0;
+ final long reservedBytes = (aggressive || defyReserved) ? 0
+ : storage.getStorageCacheBytes(file);
// 1. Pre-flight to determine if we have any chance to succeed
// 2. Consider preloaded data (after 1w honeymoon, unless aggressive)
@@ -4230,29 +4237,52 @@ public class PackageManagerService extends IPackageManager.Stub
// 4. Consider cached app data (above quotas)
try {
- mInstaller.freeCache(volumeUuid, bytes, Installer.FLAG_FREE_CACHE_V2);
+ mInstaller.freeCache(volumeUuid, bytes, reservedBytes,
+ Installer.FLAG_FREE_CACHE_V2);
} catch (InstallerException ignored) {
}
if (file.getUsableSpace() >= bytes) return;
- // 5. Consider shared libraries with refcount=0 and age>2h
+ // 5. Consider shared libraries with refcount=0 and age>min cache period
+ if (internalVolume && pruneUnusedStaticSharedLibraries(bytes,
+ android.provider.Settings.Global.getLong(mContext.getContentResolver(),
+ Global.UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD,
+ DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD))) {
+ return;
+ }
+
// 6. Consider dexopt output (aggressive only)
- // 7. Consider ephemeral apps not used in last week
+ // TODO: Implement
+
+ // 7. Consider installed instant apps unused longer than min cache period
+ if (internalVolume && mInstantAppRegistry.pruneInstalledInstantApps(bytes,
+ android.provider.Settings.Global.getLong(mContext.getContentResolver(),
+ Global.INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
+ InstantAppRegistry.DEFAULT_INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) {
+ return;
+ }
// 8. Consider cached app data (below quotas)
try {
- mInstaller.freeCache(volumeUuid, bytes, Installer.FLAG_FREE_CACHE_V2
- | Installer.FLAG_FREE_CACHE_V2_DEFY_QUOTA);
+ mInstaller.freeCache(volumeUuid, bytes, reservedBytes,
+ Installer.FLAG_FREE_CACHE_V2 | Installer.FLAG_FREE_CACHE_V2_DEFY_QUOTA);
} catch (InstallerException ignored) {
}
if (file.getUsableSpace() >= bytes) return;
// 9. Consider DropBox entries
- // 10. Consider ephemeral cookies
+ // TODO: Implement
+ // 10. Consider instant meta-data (uninstalled apps) older that min cache period
+ if (internalVolume && mInstantAppRegistry.pruneUninstalledInstantApps(bytes,
+ android.provider.Settings.Global.getLong(mContext.getContentResolver(),
+ Global.UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
+ InstantAppRegistry.DEFAULT_UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) {
+ return;
+ }
} else {
try {
- mInstaller.freeCache(volumeUuid, bytes, 0);
+ mInstaller.freeCache(volumeUuid, bytes, 0, 0);
} catch (InstallerException ignored) {
}
if (file.getUsableSpace() >= bytes) return;
@@ -4261,6 +4291,69 @@ public class PackageManagerService extends IPackageManager.Stub
throw new IOException("Failed to free " + bytes + " on storage device at " + file);
}
+ private boolean pruneUnusedStaticSharedLibraries(long neededSpace, long maxCachePeriod)
+ throws IOException {
+ final StorageManager storage = mContext.getSystemService(StorageManager.class);
+ final File volume = storage.findPathForUuid(StorageManager.UUID_PRIVATE_INTERNAL);
+
+ List<VersionedPackage> packagesToDelete = null;
+ final long now = System.currentTimeMillis();
+
+ synchronized (mPackages) {
+ final int[] allUsers = sUserManager.getUserIds();
+ final int libCount = mSharedLibraries.size();
+ for (int i = 0; i < libCount; i++) {
+ final SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
+ if (versionedLib == null) {
+ continue;
+ }
+ final int versionCount = versionedLib.size();
+ for (int j = 0; j < versionCount; j++) {
+ SharedLibraryInfo libInfo = versionedLib.valueAt(j).info;
+ // Skip packages that are not static shared libs.
+ if (!libInfo.isStatic()) {
+ break;
+ }
+ // Important: We skip static shared libs used for some user since
+ // in such a case we need to keep the APK on the device. The check for
+ // a lib being used for any user is performed by the uninstall call.
+ final VersionedPackage declaringPackage = libInfo.getDeclaringPackage();
+ // Resolve the package name - we use synthetic package names internally
+ final String internalPackageName = resolveInternalPackageNameLPr(
+ declaringPackage.getPackageName(), declaringPackage.getVersionCode());
+ final PackageSetting ps = mSettings.getPackageLPr(internalPackageName);
+ // Skip unused static shared libs cached less than the min period
+ // to prevent pruning a lib needed by a subsequently installed package.
+ if (ps == null || now - ps.lastUpdateTime < maxCachePeriod) {
+ continue;
+ }
+ if (packagesToDelete == null) {
+ packagesToDelete = new ArrayList<>();
+ }
+ packagesToDelete.add(new VersionedPackage(internalPackageName,
+ declaringPackage.getVersionCode()));
+ }
+ }
+ }
+
+ if (packagesToDelete != null) {
+ final int packageCount = packagesToDelete.size();
+ for (int i = 0; i < packageCount; i++) {
+ final VersionedPackage pkgToDelete = packagesToDelete.get(i);
+ // Delete the package synchronously (will fail of the lib used for any user).
+ if (deletePackageX(pkgToDelete.getPackageName(), pkgToDelete.getVersionCode(),
+ UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS)
+ == PackageManager.DELETE_SUCCEEDED) {
+ if (volume.getUsableSpace() >= neededSpace) {
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+ }
+
/**
* Update given flags based on encryption status of current user.
*/
@@ -10650,8 +10743,7 @@ public class PackageManagerService extends IPackageManager.Stub
final int versionCount = versionedLib.size();
for (int i = 0; i < versionCount; i++) {
SharedLibraryInfo libInfo = versionedLib.valueAt(i).info;
- // TODO: We will change version code to long, so in the new API it is long
- final int libVersionCode = (int) libInfo.getDeclaringPackage()
+ final int libVersionCode = libInfo.getDeclaringPackage()
.getVersionCode();
if (libInfo.getVersion() < pkg.staticSharedLibVersion) {
minVersionCode = Math.max(minVersionCode, libVersionCode + 1);
@@ -15494,7 +15586,7 @@ public class PackageManagerService extends IPackageManager.Stub
origin.resolvedPath, isForwardLocked(), packageAbiOverride);
try {
- mInstaller.freeCache(null, sizeBytes + lowThreshold, 0);
+ mInstaller.freeCache(null, sizeBytes + lowThreshold, 0, 0);
pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath,
installFlags, packageAbiOverride);
} catch (InstallerException e) {
@@ -18488,7 +18580,7 @@ public class PackageManagerService extends IPackageManager.Stub
* persisting settings for later use
* sending a broadcast if necessary
*/
- private int deletePackageX(String packageName, int versionCode, int userId, int deleteFlags) {
+ int deletePackageX(String packageName, int versionCode, int userId, int deleteFlags) {
final PackageRemovedInfo info = new PackageRemovedInfo(this);
final boolean res;
@@ -18531,7 +18623,7 @@ public class PackageManagerService extends IPackageManager.Stub
pkg.staticSharedLibVersion);
if (libEntry != null) {
for (int currUserId : allUsers) {
- if (userId != UserHandle.USER_ALL && userId != currUserId) {
+ if (removeUser != UserHandle.USER_ALL && removeUser != currUserId) {
continue;
}
List<VersionedPackage> libClientPackages = getPackagesUsingSharedLibraryLPr(
@@ -24273,9 +24365,7 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
@Override
public void pruneInstantApps() {
- synchronized (mPackages) {
- mInstantAppRegistry.pruneInstantAppsLPw();
- }
+ mInstantAppRegistry.pruneInstantApps();
}
@Override
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 908e51711b11..e3bc91971b06 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -60,7 +60,6 @@ import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_ST
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_STATUS_BAR_VISIBLE_TRANSPARENT;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TASK_SNAPSHOT;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SYSTEM_ERROR;
import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_CROSSFADE;
import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_JUMPCUT;
@@ -1128,16 +1127,25 @@ public class PhoneWindowManager implements WindowManagerPolicy {
+ ", mOrientationSensorEnabled=" + mOrientationSensorEnabled
+ ", mKeyguardDrawComplete=" + mKeyguardDrawComplete
+ ", mWindowManagerDrawComplete=" + mWindowManagerDrawComplete);
+ final boolean keyguardGoingAway = mWindowManagerInternal.isKeyguardGoingAway();
+
boolean disable = true;
// Note: We postpone the rotating of the screen until the keyguard as well as the
- // window manager have reported a draw complete.
- if (mScreenOnEarly && mAwake &&
- mKeyguardDrawComplete && mWindowManagerDrawComplete) {
+ // window manager have reported a draw complete or the keyguard is going away in dismiss
+ // mode.
+ if (mScreenOnEarly && mAwake && ((mKeyguardDrawComplete && mWindowManagerDrawComplete)
+ || keyguardGoingAway)) {
if (needSensorRunningLp()) {
disable = false;
//enable listener if not already enabled
if (!mOrientationSensorEnabled) {
- mOrientationListener.enable();
+ // Don't clear the current sensor orientation if the keyguard is going away in
+ // dismiss mode. This allows window manager to use the last sensor reading to
+ // determine the orientation vs. falling back to the last known orientation if
+ // the sensor reading was cleared which can cause it to relaunch the app that
+ // will show in the wrong orientation first before correcting leading to app
+ // launch delays.
+ mOrientationListener.enable(!keyguardGoingAway /* clearCurrentRotation */);
if(localLOGV) Slog.v(TAG, "Enabling listeners");
mOrientationSensorEnabled = true;
}
diff --git a/services/core/java/com/android/server/policy/WindowOrientationListener.java b/services/core/java/com/android/server/policy/WindowOrientationListener.java
index 8ef0acbd3808..64f64c0d45d6 100644
--- a/services/core/java/com/android/server/policy/WindowOrientationListener.java
+++ b/services/core/java/com/android/server/policy/WindowOrientationListener.java
@@ -109,24 +109,37 @@ public abstract class WindowOrientationListener {
* {@link #onProposedRotationChanged(int)} when the device orientation changes.
*/
public void enable() {
+ enable(true /* clearCurrentRotation */);
+ }
+
+ /**
+ * Enables the WindowOrientationListener so it will monitor the sensor and call
+ * {@link #onProposedRotationChanged(int)} when the device orientation changes.
+ *
+ * @param clearCurrentRotation True if the current proposed sensor rotation should be cleared as
+ * part of the reset.
+ */
+ public void enable(boolean clearCurrentRotation) {
synchronized (mLock) {
if (mSensor == null) {
Slog.w(TAG, "Cannot detect sensors. Not enabled");
return;
}
- if (mEnabled == false) {
- if (LOG) {
- Slog.d(TAG, "WindowOrientationListener enabled");
- }
- mOrientationJudge.resetLocked();
- if (mSensor.getType() == Sensor.TYPE_ACCELEROMETER) {
- mSensorManager.registerListener(
- mOrientationJudge, mSensor, mRate, DEFAULT_BATCH_LATENCY, mHandler);
- } else {
- mSensorManager.registerListener(mOrientationJudge, mSensor, mRate, mHandler);
- }
- mEnabled = true;
+ if (mEnabled) {
+ return;
}
+ if (LOG) {
+ Slog.d(TAG, "WindowOrientationListener enabled clearCurrentRotation="
+ + clearCurrentRotation);
+ }
+ mOrientationJudge.resetLocked(clearCurrentRotation);
+ if (mSensor.getType() == Sensor.TYPE_ACCELEROMETER) {
+ mSensorManager.registerListener(
+ mOrientationJudge, mSensor, mRate, DEFAULT_BATCH_LATENCY, mHandler);
+ } else {
+ mSensorManager.registerListener(mOrientationJudge, mSensor, mRate, mHandler);
+ }
+ mEnabled = true;
}
}
@@ -278,8 +291,11 @@ public abstract class WindowOrientationListener {
* Resets the state of the judge.
*
* Should only be called when holding WindowOrientationListener lock.
+ *
+ * @param clearCurrentRotation True if the current proposed sensor rotation should be
+ * cleared as part of the reset.
*/
- public abstract void resetLocked();
+ public abstract void resetLocked(boolean clearCurrentRotation);
/**
* Dumps internal state of the orientation judge.
@@ -602,7 +618,7 @@ public abstract class WindowOrientationListener {
if (LOG) {
Slog.v(TAG, "Resetting orientation listener.");
}
- resetLocked();
+ resetLocked(true /* clearCurrentRotation */);
skipSample = true;
} else {
final float alpha = timeDeltaMS / (FILTER_TIME_CONSTANT_MS + timeDeltaMS);
@@ -778,9 +794,11 @@ public abstract class WindowOrientationListener {
}
@Override
- public void resetLocked() {
+ public void resetLocked(boolean clearCurrentRotation) {
mLastFilteredTimestampNanos = Long.MIN_VALUE;
- mProposedRotation = -1;
+ if (clearCurrentRotation) {
+ mProposedRotation = -1;
+ }
mFlatTimestampNanos = Long.MIN_VALUE;
mFlat = false;
mSwingTimestampNanos = Long.MIN_VALUE;
@@ -1015,9 +1033,11 @@ public abstract class WindowOrientationListener {
}
@Override
- public void resetLocked() {
- mProposedRotation = -1;
- mDesiredRotation = -1;
+ public void resetLocked(boolean clearCurrentRotation) {
+ if (clearCurrentRotation) {
+ mProposedRotation = -1;
+ mDesiredRotation = -1;
+ }
mTouching = false;
mTouchEndedTimestampNanos = Long.MIN_VALUE;
unscheduleRotationEvaluationLocked();
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
index 1b4eaf548809..da90e5adf4c4 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
@@ -30,7 +30,7 @@ import java.io.PrintWriter;
*/
public class KeyguardServiceDelegate {
private static final String TAG = "KeyguardServiceDelegate";
- private static final boolean DEBUG = true;
+ private static final boolean DEBUG = false;
private static final int SCREEN_STATE_OFF = 0;
private static final int SCREEN_STATE_TURNING_ON = 1;
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index ed98d1cbc5b2..3b5db29de9e0 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -87,6 +87,7 @@ import com.android.server.LockGuard;
import com.android.server.RescueParty;
import com.android.server.ServiceThread;
import com.android.server.SystemService;
+import com.android.server.UiThread;
import com.android.server.Watchdog;
import com.android.server.am.BatteryStatsService;
import com.android.server.lights.Light;
@@ -2729,9 +2730,9 @@ public final class PowerManagerService extends SystemService
};
// ShutdownThread must run on a looper capable of displaying the UI.
- Message msg = Message.obtain(mHandler, runnable);
+ Message msg = Message.obtain(UiThread.getHandler(), runnable);
msg.setAsynchronous(true);
- mHandler.sendMessage(msg);
+ UiThread.getHandler().sendMessage(msg);
// PowerManager.reboot() is documented not to return so just wait for the inevitable.
if (wait) {
diff --git a/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java b/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java
index fbc9e56fabf5..88b6d870afd7 100644
--- a/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java
+++ b/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java
@@ -16,71 +16,60 @@
package com.android.server.storage;
-import android.app.NotificationChannel;
-
-import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
-import com.android.internal.notification.SystemNotificationChannels;
-import com.android.internal.util.DumpUtils;
-import com.android.server.EventLogTags;
-import com.android.server.SystemService;
-import com.android.server.pm.InstructionSets;
+import android.annotation.WorkerThread;
import android.app.Notification;
+import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
-import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
-import android.content.pm.IPackageDataObserver;
-import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
+import android.net.TrafficStats;
import android.os.Binder;
import android.os.Environment;
import android.os.FileObserver;
import android.os.Handler;
import android.os.Message;
-import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.ServiceManager;
import android.os.ShellCallback;
import android.os.ShellCommand;
-import android.os.StatFs;
-import android.os.SystemClock;
-import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.storage.StorageManager;
-import android.provider.Settings;
-import android.text.format.Formatter;
-import android.util.EventLog;
+import android.os.storage.VolumeInfo;
+import android.text.format.DateUtils;
+import android.util.ArrayMap;
import android.util.Slog;
-import android.util.TimeUtils;
+
+import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
+import com.android.internal.notification.SystemNotificationChannels;
+import com.android.internal.util.DumpUtils;
+import com.android.internal.util.IndentingPrintWriter;
+import com.android.server.EventLogTags;
+import com.android.server.IoThread;
+import com.android.server.SystemService;
+import com.android.server.pm.InstructionSets;
+import com.android.server.pm.PackageManagerService;
+
+import dalvik.system.VMRuntime;
import java.io.File;
import java.io.FileDescriptor;
+import java.io.IOException;
import java.io.PrintWriter;
+import java.util.Objects;
+import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;
-import dalvik.system.VMRuntime;
-
/**
- * This class implements a service to monitor the amount of disk
- * storage space on the device. If the free storage on device is less
- * than a tunable threshold value (a secure settings parameter;
- * default 10%) a low memory notification is displayed to alert the
- * user. If the user clicks on the low memory notification the
- * Application Manager application gets launched to let the user free
- * storage space.
- *
- * Event log events: A low memory event with the free storage on
- * device in bytes is logged to the event log when the device goes low
- * on storage space. The amount of free storage on the device is
- * periodically logged to the event log. The log interval is a secure
- * settings parameter with a default value of 12 hours. When the free
- * storage differential goes below a threshold (again a secure
- * settings parameter with a default value of 2MB), the free memory is
- * logged to the event log.
+ * Service that monitors and maintains free space on storage volumes.
+ * <p>
+ * As the free space on a volume nears the threshold defined by
+ * {@link StorageManager#getStorageLowBytes(File)}, this service will clear out
+ * cached data to keep the disk from entering this low state.
*/
public class DeviceStorageMonitorService extends SystemService {
- static final String TAG = "DeviceStorageMonitorService";
+ private static final String TAG = "DeviceStorageMonitorService";
/**
* Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
@@ -88,68 +77,75 @@ public class DeviceStorageMonitorService extends SystemService {
*/
public static final String EXTRA_SEQUENCE = "seq";
- // TODO: extend to watch and manage caches on all private volumes
+ private static final int MSG_CHECK = 1;
- static final boolean DEBUG = false;
- static final boolean localLOGV = false;
-
- static final int DEVICE_MEMORY_WHAT = 1;
- static final int FORCE_MEMORY_WHAT = 2;
- private static final int MONITOR_INTERVAL = 1; //in minutes
-
- private static final int DEFAULT_FREE_STORAGE_LOG_INTERVAL_IN_MINUTES = 12*60; //in minutes
- private static final long DEFAULT_DISK_FREE_CHANGE_REPORTING_THRESHOLD = 2 * 1024 * 1024; // 2MB
- private static final long DEFAULT_CHECK_INTERVAL = MONITOR_INTERVAL*60*1000;
+ private static final long DEFAULT_LOG_DELTA_BYTES = 64 * TrafficStats.MB_IN_BYTES;
+ private static final long DEFAULT_CHECK_INTERVAL = DateUtils.MINUTE_IN_MILLIS;
// com.android.internal.R.string.low_internal_storage_view_text_no_boot
// hard codes 250MB in the message as the storage space required for the
// boot image.
- private static final long BOOT_IMAGE_STORAGE_REQUIREMENT = 250 * 1024 * 1024;
-
- private long mFreeMem; // on /data
- private long mFreeMemAfterLastCacheClear; // on /data
- private long mLastReportedFreeMem;
- private long mLastReportedFreeMemTime;
- boolean mLowMemFlag=false;
- private boolean mMemFullFlag=false;
- private final boolean mIsBootImageOnDisk;
- private final ContentResolver mResolver;
- private final long mTotalMemory; // on /data
- private final StatFs mDataFileStats;
- private final StatFs mSystemFileStats;
- private final StatFs mCacheFileStats;
-
- private static final File DATA_PATH = Environment.getDataDirectory();
- private static final File SYSTEM_PATH = Environment.getRootDirectory();
- private static final File CACHE_PATH = Environment.getDownloadCacheDirectory();
-
- private long mThreadStartTime = -1;
- boolean mUpdatesStopped;
- AtomicInteger mSeq = new AtomicInteger(1);
- boolean mClearSucceeded = false;
- boolean mClearingCache;
- private final Intent mStorageLowIntent;
- private final Intent mStorageOkIntent;
- private final Intent mStorageFullIntent;
- private final Intent mStorageNotFullIntent;
- private CachePackageDataObserver mClearCacheObserver;
+ private static final long BOOT_IMAGE_STORAGE_REQUIREMENT = 250 * TrafficStats.MB_IN_BYTES;
+
+ private NotificationManager mNotifManager;
+
+ /** Sequence number used for testing */
+ private final AtomicInteger mSeq = new AtomicInteger(1);
+ /** Forced level used for testing */
+ private volatile int mForceLevel = State.LEVEL_UNKNOWN;
+
+ /** Map from storage volume UUID to internal state */
+ private final ArrayMap<UUID, State> mStates = new ArrayMap<>();
+
+ /**
+ * State for a specific storage volume, including the current "level" that
+ * we've alerted the user and apps about.
+ */
+ private static class State {
+ private static final int LEVEL_UNKNOWN = -1;
+ private static final int LEVEL_NORMAL = 0;
+ private static final int LEVEL_LOW = 1;
+ private static final int LEVEL_FULL = 2;
+
+ /** Last "level" that we alerted about */
+ public int level = LEVEL_NORMAL;
+ /** Last {@link File#getUsableSpace()} that we logged about */
+ public long lastUsableBytes = Long.MAX_VALUE;
+
+ /**
+ * Test if the given level transition is "entering" a specific level.
+ * <p>
+ * As an example, a transition from {@link #LEVEL_NORMAL} to
+ * {@link #LEVEL_FULL} is considered to "enter" both {@link #LEVEL_LOW}
+ * and {@link #LEVEL_FULL}.
+ */
+ private static boolean isEntering(int level, int oldLevel, int newLevel) {
+ return newLevel >= level && (oldLevel < level || oldLevel == LEVEL_UNKNOWN);
+ }
+
+ /**
+ * Test if the given level transition is "leaving" a specific level.
+ * <p>
+ * As an example, a transition from {@link #LEVEL_FULL} to
+ * {@link #LEVEL_NORMAL} is considered to "leave" both
+ * {@link #LEVEL_FULL} and {@link #LEVEL_LOW}.
+ */
+ private static boolean isLeaving(int level, int oldLevel, int newLevel) {
+ return newLevel < level && (oldLevel >= level || oldLevel == LEVEL_UNKNOWN);
+ }
+
+ private static String levelToString(int level) {
+ switch (level) {
+ case State.LEVEL_UNKNOWN: return "UNKNOWN";
+ case State.LEVEL_NORMAL: return "NORMAL";
+ case State.LEVEL_LOW: return "LOW";
+ case State.LEVEL_FULL: return "FULL";
+ default: return Integer.toString(level);
+ }
+ }
+ }
+
private CacheFileDeletedObserver mCacheFileDeletedObserver;
- private static final int _TRUE = 1;
- private static final int _FALSE = 0;
- // This is the raw threshold that has been set at which we consider
- // storage to be low.
- long mMemLowThreshold;
- // This is the threshold at which we start trying to flush caches
- // to get below the low threshold limit. It is less than the low
- // threshold; we will allow storage to get a bit beyond the limit
- // before flushing and checking if we are actually low.
- private long mMemCacheStartTrimThreshold;
- // This is the threshold that we try to get to when deleting cache
- // files. This is greater than the low threshold so that we will flush
- // more files than absolutely needed, to reduce the frequency that
- // flushing takes place.
- private long mMemCacheTrimToThreshold;
- private long mMemFullThreshold;
/**
* This string is used for ServiceManager access to this class.
@@ -159,244 +155,107 @@ public class DeviceStorageMonitorService extends SystemService {
private static final String TV_NOTIFICATION_CHANNEL_ID = "devicestoragemonitor.tv";
/**
- * Handler that checks the amount of disk space on the device and sends a
- * notification if the device runs low on disk space
- */
- private final Handler mHandler = new Handler() {
+ * Handler that checks the amount of disk space on the device and sends a
+ * notification if the device runs low on disk space
+ */
+ private final Handler mHandler = new Handler(IoThread.get().getLooper()) {
@Override
public void handleMessage(Message msg) {
- //don't handle an invalid message
switch (msg.what) {
- case DEVICE_MEMORY_WHAT:
- checkMemory(msg.arg1 == _TRUE);
- return;
- case FORCE_MEMORY_WHAT:
- forceMemory(msg.arg1, msg.arg2);
- return;
- default:
- Slog.w(TAG, "Will not process invalid message");
+ case MSG_CHECK:
+ check();
return;
}
}
};
- private class CachePackageDataObserver extends IPackageDataObserver.Stub {
- public void onRemoveCompleted(String packageName, boolean succeeded) {
- mClearSucceeded = succeeded;
- mClearingCache = false;
- if(localLOGV) Slog.i(TAG, " Clear succeeded:"+mClearSucceeded
- +", mClearingCache:"+mClearingCache+" Forcing memory check");
- postCheckMemoryMsg(false, 0);
- }
- }
-
- private void restatDataDir() {
- try {
- mDataFileStats.restat(DATA_PATH.getAbsolutePath());
- mFreeMem = (long) mDataFileStats.getAvailableBlocks() *
- mDataFileStats.getBlockSize();
- } catch (IllegalArgumentException e) {
- // use the old value of mFreeMem
- }
- // Allow freemem to be overridden by debug.freemem for testing
- String debugFreeMem = SystemProperties.get("debug.freemem");
- if (!"".equals(debugFreeMem)) {
- mFreeMem = Long.parseLong(debugFreeMem);
- }
- // Read the log interval from secure settings
- long freeMemLogInterval = Settings.Global.getLong(mResolver,
- Settings.Global.SYS_FREE_STORAGE_LOG_INTERVAL,
- DEFAULT_FREE_STORAGE_LOG_INTERVAL_IN_MINUTES)*60*1000;
- //log the amount of free memory in event log
- long currTime = SystemClock.elapsedRealtime();
- if((mLastReportedFreeMemTime == 0) ||
- (currTime-mLastReportedFreeMemTime) >= freeMemLogInterval) {
- mLastReportedFreeMemTime = currTime;
- long mFreeSystem = -1, mFreeCache = -1;
- try {
- mSystemFileStats.restat(SYSTEM_PATH.getAbsolutePath());
- mFreeSystem = (long) mSystemFileStats.getAvailableBlocks() *
- mSystemFileStats.getBlockSize();
- } catch (IllegalArgumentException e) {
- // ignore; report -1
- }
- try {
- mCacheFileStats.restat(CACHE_PATH.getAbsolutePath());
- mFreeCache = (long) mCacheFileStats.getAvailableBlocks() *
- mCacheFileStats.getBlockSize();
- } catch (IllegalArgumentException e) {
- // ignore; report -1
- }
- EventLog.writeEvent(EventLogTags.FREE_STORAGE_LEFT,
- mFreeMem, mFreeSystem, mFreeCache);
- }
- // Read the reporting threshold from secure settings
- long threshold = Settings.Global.getLong(mResolver,
- Settings.Global.DISK_FREE_CHANGE_REPORTING_THRESHOLD,
- DEFAULT_DISK_FREE_CHANGE_REPORTING_THRESHOLD);
- // If mFree changed significantly log the new value
- long delta = mFreeMem - mLastReportedFreeMem;
- if (delta > threshold || delta < -threshold) {
- mLastReportedFreeMem = mFreeMem;
- EventLog.writeEvent(EventLogTags.FREE_STORAGE_CHANGED, mFreeMem);
- }
- }
-
- private void clearCache() {
- if (mClearCacheObserver == null) {
- // Lazy instantiation
- mClearCacheObserver = new CachePackageDataObserver();
- }
- mClearingCache = true;
- try {
- if (localLOGV) Slog.i(TAG, "Clearing cache");
- IPackageManager.Stub.asInterface(ServiceManager.getService("package")).
- freeStorageAndNotify(null, mMemCacheTrimToThreshold, mClearCacheObserver);
- } catch (RemoteException e) {
- Slog.w(TAG, "Failed to get handle for PackageManger Exception: "+e);
- mClearingCache = false;
- mClearSucceeded = false;
+ private State findOrCreateState(UUID uuid) {
+ State state = mStates.get(uuid);
+ if (state == null) {
+ state = new State();
+ mStates.put(uuid, state);
}
+ return state;
}
- void forceMemory(int opts, int seq) {
- if ((opts&OPTION_UPDATES_STOPPED) == 0) {
- if (mUpdatesStopped) {
- mUpdatesStopped = false;
- checkMemory(true);
- }
- } else {
- mUpdatesStopped = true;
- final boolean forceLow = (opts&OPTION_STORAGE_LOW) != 0;
- if (mLowMemFlag != forceLow || (opts&OPTION_FORCE_UPDATE) != 0) {
- mLowMemFlag = forceLow;
- if (forceLow) {
- sendNotification(seq);
- } else {
- cancelNotification(seq);
+ /**
+ * Core logic that checks the storage state of every mounted private volume.
+ * Since this can do heavy I/O, callers should invoke indirectly using
+ * {@link #MSG_CHECK}.
+ */
+ @WorkerThread
+ private void check() {
+ final StorageManager storage = getContext().getSystemService(StorageManager.class);
+ final int seq = mSeq.get();
+
+ // Check every mounted private volume to see if they're low on space
+ for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
+ final File file = vol.getPath();
+ final long fullBytes = storage.getStorageFullBytes(file);
+ final long lowBytes = storage.getStorageLowBytes(file);
+
+ // Automatically trim cached data when nearing the low threshold;
+ // when it's within 150% of the threshold, we try trimming usage
+ // back to 200% of the threshold.
+ if (file.getUsableSpace() < (lowBytes * 3) / 2) {
+ final PackageManagerService pms = (PackageManagerService) ServiceManager
+ .getService("package");
+ try {
+ pms.freeStorage(vol.getFsUuid(), lowBytes * 2, 0);
+ } catch (IOException e) {
+ Slog.w(TAG, e);
}
}
- }
- }
- void checkMemory(boolean checkCache) {
- if (mUpdatesStopped) {
- return;
- }
-
- //if the thread that was started to clear cache is still running do nothing till its
- //finished clearing cache. Ideally this flag could be modified by clearCache
- // and should be accessed via a lock but even if it does this test will fail now and
- //hopefully the next time this flag will be set to the correct value.
- if (mClearingCache) {
- if(localLOGV) Slog.i(TAG, "Thread already running just skip");
- //make sure the thread is not hung for too long
- long diffTime = System.currentTimeMillis() - mThreadStartTime;
- if(diffTime > (10*60*1000)) {
- Slog.w(TAG, "Thread that clears cache file seems to run for ever");
- }
- } else {
- restatDataDir();
- if (localLOGV) Slog.v(TAG, "freeMemory="+mFreeMem);
-
- //post intent to NotificationManager to display icon if necessary
- if (mFreeMem < mMemLowThreshold) {
- if (checkCache) {
- // We are allowed to clear cache files at this point to
- // try to get down below the limit, because this is not
- // the initial call after a cache clear has been attempted.
- // In this case we will try a cache clear if our free
- // space has gone below the cache clear limit.
- if (mFreeMem < mMemCacheStartTrimThreshold) {
- // We only clear the cache if the free storage has changed
- // a significant amount since the last time.
- if ((mFreeMemAfterLastCacheClear-mFreeMem)
- >= ((mMemLowThreshold-mMemCacheStartTrimThreshold)/4)) {
- // See if clearing cache helps
- // Note that clearing cache is asynchronous and so we do a
- // memory check again once the cache has been cleared.
- mThreadStartTime = System.currentTimeMillis();
- mClearSucceeded = false;
- clearCache();
- }
- }
- } else {
- // This is a call from after clearing the cache. Note
- // the amount of free storage at this point.
- mFreeMemAfterLastCacheClear = mFreeMem;
- if (!mLowMemFlag) {
- // We tried to clear the cache, but that didn't get us
- // below the low storage limit. Tell the user.
- Slog.i(TAG, "Running low on memory. Sending notification");
- sendNotification(0);
- mLowMemFlag = true;
- } else {
- if (localLOGV) Slog.v(TAG, "Running low on memory " +
- "notification already sent. do nothing");
- }
- }
+ // Send relevant broadcasts and show notifications based on any
+ // recently noticed state transitions.
+ final UUID uuid = StorageManager.convert(vol.getFsUuid());
+ final State state = findOrCreateState(uuid);
+ final long totalBytes = file.getTotalSpace();
+ final long usableBytes = file.getUsableSpace();
+
+ int oldLevel = state.level;
+ int newLevel;
+ if (mForceLevel != State.LEVEL_UNKNOWN) {
+ // When in testing mode, use unknown old level to force sending
+ // of any relevant broadcasts.
+ oldLevel = State.LEVEL_UNKNOWN;
+ newLevel = mForceLevel;
+ } else if (usableBytes <= fullBytes) {
+ newLevel = State.LEVEL_FULL;
+ } else if (usableBytes <= lowBytes) {
+ newLevel = State.LEVEL_LOW;
+ } else if (StorageManager.UUID_DEFAULT.equals(uuid) && !isBootImageOnDisk()
+ && usableBytes < BOOT_IMAGE_STORAGE_REQUIREMENT) {
+ newLevel = State.LEVEL_LOW;
} else {
- mFreeMemAfterLastCacheClear = mFreeMem;
- if (mLowMemFlag) {
- Slog.i(TAG, "Memory available. Cancelling notification");
- cancelNotification(0);
- mLowMemFlag = false;
- }
+ newLevel = State.LEVEL_NORMAL;
}
- if (!mLowMemFlag && !mIsBootImageOnDisk && mFreeMem < BOOT_IMAGE_STORAGE_REQUIREMENT) {
- Slog.i(TAG, "No boot image on disk due to lack of space. Sending notification");
- sendNotification(0);
- mLowMemFlag = true;
- }
- if (mFreeMem < mMemFullThreshold) {
- if (!mMemFullFlag) {
- sendFullNotification();
- mMemFullFlag = true;
- }
- } else {
- if (mMemFullFlag) {
- cancelFullNotification();
- mMemFullFlag = false;
- }
+
+ // Log whenever we notice drastic storage changes
+ if ((Math.abs(state.lastUsableBytes - usableBytes) > DEFAULT_LOG_DELTA_BYTES)
+ || oldLevel != newLevel) {
+ EventLogTags.writeStorageState(uuid.toString(), oldLevel, newLevel,
+ usableBytes, totalBytes);
+ state.lastUsableBytes = usableBytes;
}
+
+ updateNotifications(vol, oldLevel, newLevel);
+ updateBroadcasts(vol, oldLevel, newLevel, seq);
+
+ state.level = newLevel;
}
- if(localLOGV) Slog.i(TAG, "Posting Message again");
- //keep posting messages to itself periodically
- postCheckMemoryMsg(true, DEFAULT_CHECK_INTERVAL);
- }
- void postCheckMemoryMsg(boolean clearCache, long delay) {
- // Remove queued messages
- mHandler.removeMessages(DEVICE_MEMORY_WHAT);
- mHandler.sendMessageDelayed(mHandler.obtainMessage(DEVICE_MEMORY_WHAT,
- clearCache ?_TRUE : _FALSE, 0),
- delay);
+ // Loop around to check again in future; we don't remove messages since
+ // there might be an immediate request pending.
+ if (!mHandler.hasMessages(MSG_CHECK)) {
+ mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_CHECK),
+ DEFAULT_CHECK_INTERVAL);
+ }
}
public DeviceStorageMonitorService(Context context) {
super(context);
- mLastReportedFreeMemTime = 0;
- mResolver = context.getContentResolver();
- mIsBootImageOnDisk = isBootImageOnDisk();
- //create StatFs object
- mDataFileStats = new StatFs(DATA_PATH.getAbsolutePath());
- mSystemFileStats = new StatFs(SYSTEM_PATH.getAbsolutePath());
- mCacheFileStats = new StatFs(CACHE_PATH.getAbsolutePath());
- //initialize total storage on device
- mTotalMemory = (long)mDataFileStats.getBlockCount() *
- mDataFileStats.getBlockSize();
- mStorageLowIntent = new Intent(Intent.ACTION_DEVICE_STORAGE_LOW);
- mStorageLowIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
- | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
- | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
- mStorageOkIntent = new Intent(Intent.ACTION_DEVICE_STORAGE_OK);
- mStorageOkIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
- | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
- | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
- mStorageFullIntent = new Intent(Intent.ACTION_DEVICE_STORAGE_FULL);
- mStorageFullIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
- mStorageNotFullIntent = new Intent(Intent.ACTION_DEVICE_STORAGE_NOT_FULL);
- mStorageNotFullIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
}
private static boolean isBootImageOnDisk() {
@@ -408,35 +267,20 @@ public class DeviceStorageMonitorService extends SystemService {
return true;
}
- /**
- * Initializes the disk space threshold value and posts an empty message to
- * kickstart the process.
- */
@Override
public void onStart() {
- // cache storage thresholds
- Context context = getContext();
- final StorageManager sm = StorageManager.from(context);
- mMemLowThreshold = sm.getStorageLowBytes(DATA_PATH);
- mMemFullThreshold = sm.getStorageFullBytes(DATA_PATH);
-
- mMemCacheStartTrimThreshold = ((mMemLowThreshold*3)+mMemFullThreshold)/4;
- mMemCacheTrimToThreshold = mMemLowThreshold
- + ((mMemLowThreshold-mMemCacheStartTrimThreshold)*2);
- mFreeMemAfterLastCacheClear = mTotalMemory;
- checkMemory(true);
+ final Context context = getContext();
+ mNotifManager = context.getSystemService(NotificationManager.class);
mCacheFileDeletedObserver = new CacheFileDeletedObserver();
mCacheFileDeletedObserver.startWatching();
// Ensure that the notification channel is set up
- NotificationManager notificationMgr =
- (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
PackageManager packageManager = context.getPackageManager();
boolean isTv = packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK);
if (isTv) {
- notificationMgr.createNotificationChannel(new NotificationChannel(
+ mNotifManager.createNotificationChannel(new NotificationChannel(
TV_NOTIFICATION_CHANNEL_ID,
context.getString(
com.android.internal.R.string.device_storage_monitor_notification_channel),
@@ -445,23 +289,29 @@ public class DeviceStorageMonitorService extends SystemService {
publishBinderService(SERVICE, mRemoteService);
publishLocalService(DeviceStorageMonitorInternal.class, mLocalService);
+
+ // Kick off pass to examine storage state
+ mHandler.removeMessages(MSG_CHECK);
+ mHandler.obtainMessage(MSG_CHECK).sendToTarget();
}
private final DeviceStorageMonitorInternal mLocalService = new DeviceStorageMonitorInternal() {
@Override
public void checkMemory() {
- // force an early check
- postCheckMemoryMsg(true, 0);
+ // Kick off pass to examine storage state
+ mHandler.removeMessages(MSG_CHECK);
+ mHandler.obtainMessage(MSG_CHECK).sendToTarget();
}
@Override
public boolean isMemoryLow() {
- return mLowMemFlag;
+ return Environment.getDataDirectory().getUsableSpace() < getMemoryLowThreshold();
}
@Override
public long getMemoryLowThreshold() {
- return mMemLowThreshold;
+ return getContext().getSystemService(StorageManager.class)
+ .getStorageLowBytes(Environment.getDataDirectory());
}
};
@@ -494,8 +344,6 @@ public class DeviceStorageMonitorService extends SystemService {
}
static final int OPTION_FORCE_UPDATE = 1<<0;
- static final int OPTION_UPDATES_STOPPED = 1<<1;
- static final int OPTION_STORAGE_LOW = 1<<2;
int parseOptions(Shell shell) {
String opt;
@@ -518,10 +366,11 @@ public class DeviceStorageMonitorService extends SystemService {
int opts = parseOptions(shell);
getContext().enforceCallingOrSelfPermission(
android.Manifest.permission.DEVICE_POWER, null);
+ mForceLevel = State.LEVEL_LOW;
int seq = mSeq.incrementAndGet();
- mHandler.sendMessage(mHandler.obtainMessage(FORCE_MEMORY_WHAT,
- opts | OPTION_UPDATES_STOPPED | OPTION_STORAGE_LOW, seq));
if ((opts & OPTION_FORCE_UPDATE) != 0) {
+ mHandler.removeMessages(MSG_CHECK);
+ mHandler.obtainMessage(MSG_CHECK).sendToTarget();
pw.println(seq);
}
} break;
@@ -529,10 +378,11 @@ public class DeviceStorageMonitorService extends SystemService {
int opts = parseOptions(shell);
getContext().enforceCallingOrSelfPermission(
android.Manifest.permission.DEVICE_POWER, null);
+ mForceLevel = State.LEVEL_NORMAL;
int seq = mSeq.incrementAndGet();
- mHandler.sendMessage(mHandler.obtainMessage(FORCE_MEMORY_WHAT,
- opts | OPTION_UPDATES_STOPPED, seq));
if ((opts & OPTION_FORCE_UPDATE) != 0) {
+ mHandler.removeMessages(MSG_CHECK);
+ mHandler.obtainMessage(MSG_CHECK).sendToTarget();
pw.println(seq);
}
} break;
@@ -540,10 +390,11 @@ public class DeviceStorageMonitorService extends SystemService {
int opts = parseOptions(shell);
getContext().enforceCallingOrSelfPermission(
android.Manifest.permission.DEVICE_POWER, null);
+ mForceLevel = State.LEVEL_UNKNOWN;
int seq = mSeq.incrementAndGet();
- mHandler.sendMessage(mHandler.obtainMessage(FORCE_MEMORY_WHAT,
- opts, seq));
if ((opts & OPTION_FORCE_UPDATE) != 0) {
+ mHandler.removeMessages(MSG_CHECK);
+ mHandler.obtainMessage(MSG_CHECK).sendToTarget();
pw.println(seq);
}
} break;
@@ -568,145 +419,125 @@ public class DeviceStorageMonitorService extends SystemService {
pw.println(" -f: force a storage change broadcast be sent, prints new sequence.");
}
- void dumpImpl(FileDescriptor fd, PrintWriter pw, String[] args) {
+ void dumpImpl(FileDescriptor fd, PrintWriter _pw, String[] args) {
+ final IndentingPrintWriter pw = new IndentingPrintWriter(_pw, " ");
if (args == null || args.length == 0 || "-a".equals(args[0])) {
- final Context context = getContext();
-
- pw.println("Current DeviceStorageMonitor state:");
-
- pw.print(" mFreeMem=");
- pw.print(Formatter.formatFileSize(context, mFreeMem));
- pw.print(" mTotalMemory=");
- pw.println(Formatter.formatFileSize(context, mTotalMemory));
-
- pw.print(" mFreeMemAfterLastCacheClear=");
- pw.println(Formatter.formatFileSize(context, mFreeMemAfterLastCacheClear));
-
- pw.print(" mLastReportedFreeMem=");
- pw.print(Formatter.formatFileSize(context, mLastReportedFreeMem));
- pw.print(" mLastReportedFreeMemTime=");
- TimeUtils.formatDuration(mLastReportedFreeMemTime, SystemClock.elapsedRealtime(), pw);
- pw.println();
-
- if (mUpdatesStopped) {
- pw.print(" mUpdatesStopped=");
- pw.print(mUpdatesStopped);
- pw.print(" mSeq=");
- pw.println(mSeq.get());
- } else {
- pw.print(" mClearSucceeded=");
- pw.print(mClearSucceeded);
- pw.print(" mClearingCache=");
- pw.println(mClearingCache);
+ pw.println("Known volumes:");
+ pw.increaseIndent();
+ for (int i = 0; i < mStates.size(); i++) {
+ final UUID uuid = mStates.keyAt(i);
+ final State state = mStates.valueAt(i);
+ if (StorageManager.UUID_DEFAULT.equals(uuid)) {
+ pw.println("Default:");
+ } else {
+ pw.println(uuid + ":");
+ }
+ pw.increaseIndent();
+ pw.printPair("level", State.levelToString(state.level));
+ pw.printPair("lastUsableBytes", state.lastUsableBytes);
+ pw.println();
+ pw.decreaseIndent();
}
+ pw.decreaseIndent();
+ pw.println();
- pw.print(" mLowMemFlag=");
- pw.print(mLowMemFlag);
- pw.print(" mMemFullFlag=");
- pw.println(mMemFullFlag);
-
- pw.print(" mMemLowThreshold=");
- pw.print(Formatter.formatFileSize(context, mMemLowThreshold));
- pw.print(" mMemFullThreshold=");
- pw.println(Formatter.formatFileSize(context, mMemFullThreshold));
-
- pw.print(" mMemCacheStartTrimThreshold=");
- pw.print(Formatter.formatFileSize(context, mMemCacheStartTrimThreshold));
- pw.print(" mMemCacheTrimToThreshold=");
- pw.println(Formatter.formatFileSize(context, mMemCacheTrimToThreshold));
+ pw.printPair("mSeq", mSeq.get());
+ pw.printPair("mForceState", State.levelToString(mForceLevel));
+ pw.println();
+ pw.println();
- pw.print(" mIsBootImageOnDisk="); pw.println(mIsBootImageOnDisk);
} else {
Shell shell = new Shell();
shell.exec(mRemoteService, null, fd, null, args, null, new ResultReceiver(null));
}
}
- /**
- * This method sends a notification to NotificationManager to display
- * an error dialog indicating low disk space and launch the Installer
- * application
- */
- private void sendNotification(int seq) {
+ private void updateNotifications(VolumeInfo vol, int oldLevel, int newLevel) {
final Context context = getContext();
- if(localLOGV) Slog.i(TAG, "Sending low memory notification");
- //log the event to event log with the amount of free storage(in bytes) left on the device
- EventLog.writeEvent(EventLogTags.LOW_STORAGE, mFreeMem);
- // Pack up the values and broadcast them to everyone
- Intent lowMemIntent = new Intent(StorageManager.ACTION_MANAGE_STORAGE);
- lowMemIntent.putExtra("memory", mFreeMem);
- lowMemIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- NotificationManager notificationMgr =
- (NotificationManager)context.getSystemService(
- Context.NOTIFICATION_SERVICE);
- CharSequence title = context.getText(
- com.android.internal.R.string.low_internal_storage_view_title);
- CharSequence details = context.getText(mIsBootImageOnDisk
- ? com.android.internal.R.string.low_internal_storage_view_text
- : com.android.internal.R.string.low_internal_storage_view_text_no_boot);
- PendingIntent intent = PendingIntent.getActivityAsUser(context, 0, lowMemIntent, 0,
- null, UserHandle.CURRENT);
- Notification notification =
- new Notification.Builder(context, SystemNotificationChannels.ALERTS)
- .setSmallIcon(com.android.internal.R.drawable.stat_notify_disk_full)
- .setTicker(title)
- .setColor(context.getColor(
- com.android.internal.R.color.system_notification_accent_color))
- .setContentTitle(title)
- .setContentText(details)
- .setContentIntent(intent)
- .setStyle(new Notification.BigTextStyle()
- .bigText(details))
- .setVisibility(Notification.VISIBILITY_PUBLIC)
- .setCategory(Notification.CATEGORY_SYSTEM)
- .extend(new Notification.TvExtender()
- .setChannelId(TV_NOTIFICATION_CHANNEL_ID))
- .build();
- notification.flags |= Notification.FLAG_NO_CLEAR;
- notificationMgr.notifyAsUser(null, SystemMessage.NOTE_LOW_STORAGE, notification,
- UserHandle.ALL);
- Intent broadcast = new Intent(mStorageLowIntent);
- if (seq != 0) {
- broadcast.putExtra(EXTRA_SEQUENCE, seq);
+ final UUID uuid = StorageManager.convert(vol.getFsUuid());
+
+ if (State.isEntering(State.LEVEL_LOW, oldLevel, newLevel)) {
+ Intent lowMemIntent = new Intent(StorageManager.ACTION_MANAGE_STORAGE);
+ lowMemIntent.putExtra(StorageManager.EXTRA_UUID, uuid);
+ lowMemIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+ final CharSequence title = context.getText(
+ com.android.internal.R.string.low_internal_storage_view_title);
+
+ final CharSequence details;
+ if (StorageManager.UUID_DEFAULT.equals(uuid)) {
+ details = context.getText(isBootImageOnDisk()
+ ? com.android.internal.R.string.low_internal_storage_view_text
+ : com.android.internal.R.string.low_internal_storage_view_text_no_boot);
+ } else {
+ details = context.getText(
+ com.android.internal.R.string.low_internal_storage_view_text);
+ }
+
+ PendingIntent intent = PendingIntent.getActivityAsUser(context, 0, lowMemIntent, 0,
+ null, UserHandle.CURRENT);
+ Notification notification =
+ new Notification.Builder(context, SystemNotificationChannels.ALERTS)
+ .setSmallIcon(com.android.internal.R.drawable.stat_notify_disk_full)
+ .setTicker(title)
+ .setColor(context.getColor(
+ com.android.internal.R.color.system_notification_accent_color))
+ .setContentTitle(title)
+ .setContentText(details)
+ .setContentIntent(intent)
+ .setStyle(new Notification.BigTextStyle()
+ .bigText(details))
+ .setVisibility(Notification.VISIBILITY_PUBLIC)
+ .setCategory(Notification.CATEGORY_SYSTEM)
+ .extend(new Notification.TvExtender()
+ .setChannelId(TV_NOTIFICATION_CHANNEL_ID))
+ .build();
+ notification.flags |= Notification.FLAG_NO_CLEAR;
+ mNotifManager.notifyAsUser(uuid.toString(), SystemMessage.NOTE_LOW_STORAGE,
+ notification, UserHandle.ALL);
+ } else if (State.isLeaving(State.LEVEL_LOW, oldLevel, newLevel)) {
+ mNotifManager.cancelAsUser(uuid.toString(), SystemMessage.NOTE_LOW_STORAGE,
+ UserHandle.ALL);
}
- context.sendStickyBroadcastAsUser(broadcast, UserHandle.ALL);
}
- /**
- * Cancels low storage notification and sends OK intent.
- */
- private void cancelNotification(int seq) {
- final Context context = getContext();
- if(localLOGV) Slog.i(TAG, "Canceling low memory notification");
- NotificationManager mNotificationMgr =
- (NotificationManager)context.getSystemService(
- Context.NOTIFICATION_SERVICE);
- //cancel notification since memory has been freed
- mNotificationMgr.cancelAsUser(null, SystemMessage.NOTE_LOW_STORAGE, UserHandle.ALL);
-
- context.removeStickyBroadcastAsUser(mStorageLowIntent, UserHandle.ALL);
- Intent broadcast = new Intent(mStorageOkIntent);
- if (seq != 0) {
- broadcast.putExtra(EXTRA_SEQUENCE, seq);
+ private void updateBroadcasts(VolumeInfo vol, int oldLevel, int newLevel, int seq) {
+ if (!Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, vol.getFsUuid())) {
+ // We don't currently send broadcasts for secondary volumes
+ return;
}
- context.sendBroadcastAsUser(broadcast, UserHandle.ALL);
- }
- /**
- * Send a notification when storage is full.
- */
- private void sendFullNotification() {
- if(localLOGV) Slog.i(TAG, "Sending memory full notification");
- getContext().sendStickyBroadcastAsUser(mStorageFullIntent, UserHandle.ALL);
- }
+ final Intent lowIntent = new Intent(Intent.ACTION_DEVICE_STORAGE_LOW)
+ .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
+ | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
+ | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS)
+ .putExtra(EXTRA_SEQUENCE, seq);
+ final Intent notLowIntent = new Intent(Intent.ACTION_DEVICE_STORAGE_OK)
+ .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
+ | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
+ | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS)
+ .putExtra(EXTRA_SEQUENCE, seq);
+
+ if (State.isEntering(State.LEVEL_LOW, oldLevel, newLevel)) {
+ getContext().sendStickyBroadcastAsUser(lowIntent, UserHandle.ALL);
+ } else if (State.isLeaving(State.LEVEL_LOW, oldLevel, newLevel)) {
+ getContext().removeStickyBroadcastAsUser(lowIntent, UserHandle.ALL);
+ getContext().sendBroadcastAsUser(notLowIntent, UserHandle.ALL);
+ }
- /**
- * Cancels memory full notification and sends "not full" intent.
- */
- private void cancelFullNotification() {
- if(localLOGV) Slog.i(TAG, "Canceling memory full notification");
- getContext().removeStickyBroadcastAsUser(mStorageFullIntent, UserHandle.ALL);
- getContext().sendBroadcastAsUser(mStorageNotFullIntent, UserHandle.ALL);
+ final Intent fullIntent = new Intent(Intent.ACTION_DEVICE_STORAGE_FULL)
+ .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT)
+ .putExtra(EXTRA_SEQUENCE, seq);
+ final Intent notFullIntent = new Intent(Intent.ACTION_DEVICE_STORAGE_NOT_FULL)
+ .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT)
+ .putExtra(EXTRA_SEQUENCE, seq);
+
+ if (State.isEntering(State.LEVEL_FULL, oldLevel, newLevel)) {
+ getContext().sendStickyBroadcastAsUser(fullIntent, UserHandle.ALL);
+ } else if (State.isLeaving(State.LEVEL_FULL, oldLevel, newLevel)) {
+ getContext().removeStickyBroadcastAsUser(fullIntent, UserHandle.ALL);
+ getContext().sendBroadcastAsUser(notFullIntent, UserHandle.ALL);
+ }
}
private static class CacheFileDeletedObserver extends FileObserver {
diff --git a/services/core/java/com/android/server/vr/VrManagerService.java b/services/core/java/com/android/server/vr/VrManagerService.java
index 4044fdb07b0d..b937f9d4c6d8 100644
--- a/services/core/java/com/android/server/vr/VrManagerService.java
+++ b/services/core/java/com/android/server/vr/VrManagerService.java
@@ -96,6 +96,7 @@ import java.util.Objects;
public class VrManagerService extends SystemService implements EnabledComponentChangeListener{
public static final String TAG = "VrManagerService";
+ static final boolean DBG = false;
private static final int PENDING_STATE_DELAY_MS = 300;
private static final int EVENT_LOG_SIZE = 32;
@@ -157,7 +158,7 @@ public class VrManagerService extends SystemService implements EnabledComponentC
private void setVrModeAllowedLocked(boolean allowed) {
if (mVrModeAllowed != allowed) {
mVrModeAllowed = allowed;
- Slog.i(TAG, "VR mode is " + ((allowed) ? "allowed" : "disallowed"));
+ if (DBG) Slog.d(TAG, "VR mode is " + ((allowed) ? "allowed" : "disallowed"));
if (mVrModeAllowed) {
consumeAndApplyPendingStateLocked();
} else {
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index a38addb1dad0..9d8f1241a7ae 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -52,6 +52,7 @@ import android.annotation.Nullable;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Bitmap;
+import android.graphics.GraphicBuffer;
import android.graphics.Path;
import android.graphics.Rect;
import android.os.Binder;
@@ -346,12 +347,12 @@ public class AppTransition implements Dump {
mAppTransitionState = APP_STATE_TIMEOUT;
}
- Bitmap getAppTransitionThumbnailHeader(int taskId) {
+ GraphicBuffer getAppTransitionThumbnailHeader(int taskId) {
AppTransitionAnimationSpec spec = mNextAppTransitionAnimationsSpecs.get(taskId);
if (spec == null) {
spec = mDefaultNextAppTransitionAnimationSpec;
}
- return spec != null ? spec.bitmap : null;
+ return spec != null ? spec.buffer : null;
}
/** Returns whether the next thumbnail transition is aspect scaled up. */
@@ -716,9 +717,9 @@ public class AppTransition implements Dump {
}
private void putDefaultNextAppTransitionCoordinates(int left, int top, int width, int height,
- Bitmap bitmap) {
+ GraphicBuffer buffer) {
mDefaultNextAppTransitionAnimationSpec = new AppTransitionAnimationSpec(-1 /* taskId */,
- bitmap, new Rect(left, top, left + width, top + height));
+ buffer, new Rect(left, top, left + width, top + height));
}
/**
@@ -943,7 +944,7 @@ public class AppTransition implements Dump {
* when a thumbnail is specified with the pending animation override.
*/
Animation createThumbnailAspectScaleAnimationLocked(Rect appRect, @Nullable Rect contentInsets,
- Bitmap thumbnailHeader, final int taskId, int uiMode, int orientation) {
+ GraphicBuffer thumbnailHeader, final int taskId, int uiMode, int orientation) {
Animation a;
final int thumbWidthI = thumbnailHeader.getWidth();
final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
@@ -1296,7 +1297,7 @@ public class AppTransition implements Dump {
* when a thumbnail is specified with the pending animation override.
*/
Animation createThumbnailScaleAnimationLocked(int appWidth, int appHeight, int transit,
- Bitmap thumbnailHeader) {
+ GraphicBuffer thumbnailHeader) {
Animation a;
getDefaultNextAppTransitionStartRect(mTmpRect);
final int thumbWidthI = thumbnailHeader.getWidth();
@@ -1341,7 +1342,7 @@ public class AppTransition implements Dump {
int transit, int taskId) {
final int appWidth = containingFrame.width();
final int appHeight = containingFrame.height();
- Bitmap thumbnailHeader = getAppTransitionThumbnailHeader(taskId);
+ final GraphicBuffer thumbnailHeader = getAppTransitionThumbnailHeader(taskId);
Animation a;
getDefaultNextAppTransitionStartRect(mTmpRect);
final int thumbWidthI = thumbnailHeader != null ? thumbnailHeader.getWidth() : appWidth;
@@ -1714,7 +1715,7 @@ public class AppTransition implements Dump {
}
}
- void overridePendingAppTransitionThumb(Bitmap srcThumb, int startX, int startY,
+ void overridePendingAppTransitionThumb(GraphicBuffer srcThumb, int startX, int startY,
IRemoteCallback startedCallback, boolean scaleUp) {
if (isTransitionSet()) {
clear();
@@ -1729,7 +1730,7 @@ public class AppTransition implements Dump {
}
}
- void overridePendingAppTransitionAspectScaledThumb(Bitmap srcThumb, int startX, int startY,
+ void overridePendingAppTransitionAspectScaledThumb(GraphicBuffer srcThumb, int startX, int startY,
int targetWidth, int targetHeight, IRemoteCallback startedCallback, boolean scaleUp) {
if (isTransitionSet()) {
clear();
@@ -1763,7 +1764,7 @@ public class AppTransition implements Dump {
// to be set.
Rect rect = spec.rect;
putDefaultNextAppTransitionCoordinates(rect.left, rect.top,
- rect.width(), rect.height(), spec.bitmap);
+ rect.width(), rect.height(), spec.buffer);
}
}
}
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 221e7957ef35..b5476d7e056b 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -3492,10 +3492,15 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
if (win != null) {
final int req = win.mAttrs.screenOrientation;
- if (DEBUG_ORIENTATION) Slog.v(TAG_WM, win + " forcing orientation to " + req);
if (policy.isKeyguardHostWindow(win.mAttrs)) {
mLastKeyguardForcedOrientation = req;
+ if (mService.mKeyguardGoingAway) {
+ // Keyguard can't affect the orientation if it is going away...
+ mLastWindowForcedOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
+ return SCREEN_ORIENTATION_UNSET;
+ }
}
+ if (DEBUG_ORIENTATION) Slog.v(TAG_WM, win + " forcing orientation to " + req);
return (mLastWindowForcedOrientation = req);
}
diff --git a/services/core/java/com/android/server/wm/PinnedStackController.java b/services/core/java/com/android/server/wm/PinnedStackController.java
index fc4ec2889523..9a9e29a7eb88 100644
--- a/services/core/java/com/android/server/wm/PinnedStackController.java
+++ b/services/core/java/com/android/server/wm/PinnedStackController.java
@@ -92,17 +92,16 @@ class PinnedStackController {
private final Rect mStableInsets = new Rect();
// The size and position information that describes where the pinned stack will go by default.
+ private int mDefaultMinSize;
private int mDefaultStackGravity;
private float mDefaultAspectRatio;
private Point mScreenEdgeInsets;
+ private int mCurrentMinSize;
// The aspect ratio bounds of the PIP.
private float mMinAspectRatio;
private float mMaxAspectRatio;
- // The minimum edge size of the normal PiP bounds.
- private int mMinSize;
-
// Temp vars for calculation
private final DisplayMetrics mTmpMetrics = new DisplayMetrics();
private final Rect mTmpInsets = new Rect();
@@ -124,6 +123,13 @@ class PinnedStackController {
}
@Override
+ public void setMinEdgeSize(int minEdgeSize) {
+ mHandler.post(() -> {
+ mCurrentMinSize = Math.max(mDefaultMinSize, minEdgeSize);
+ });
+ }
+
+ @Override
public int getDisplayRotation() {
synchronized (mService.mWindowMap) {
return mDisplayInfo.rotation;
@@ -160,10 +166,12 @@ class PinnedStackController {
*/
private void reloadResources() {
final Resources res = mService.mContext.getResources();
- mMinSize = res.getDimensionPixelSize(
+ mDefaultMinSize = res.getDimensionPixelSize(
com.android.internal.R.dimen.default_minimal_size_pip_resizable_task);
+ mCurrentMinSize = mDefaultMinSize;
mDefaultAspectRatio = res.getFloat(
com.android.internal.R.dimen.config_pictureInPictureDefaultAspectRatio);
+ mAspectRatio = mDefaultAspectRatio;
final String screenEdgeInsetsDpString = res.getString(
com.android.internal.R.string.config_defaultPictureInPictureScreenEdgeInsets);
final Size screenEdgeInsetsDp = !screenEdgeInsetsDpString.isEmpty()
@@ -212,11 +220,15 @@ class PinnedStackController {
* Returns the current bounds (or the default bounds if there are no current bounds) with the
* specified aspect ratio.
*/
- Rect transformBoundsToAspectRatio(Rect stackBounds, float aspectRatio) {
+ Rect transformBoundsToAspectRatio(Rect stackBounds, float aspectRatio,
+ boolean useCurrentMinEdgeSize) {
// Save the snap fraction, calculate the aspect ratio based on screen size
final float snapFraction = mSnapAlgorithm.getSnapFraction(stackBounds,
getMovementBounds(stackBounds));
- final Size size = getSize(aspectRatio);
+
+ final int minEdgeSize = useCurrentMinEdgeSize ? mCurrentMinSize : mDefaultMinSize;
+ final Size size = mSnapAlgorithm.getSizeForAspectRatio(aspectRatio, minEdgeSize,
+ mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight);
final int left = (int) (stackBounds.centerX() - size.getWidth() / 2f);
final int top = (int) (stackBounds.centerY() - size.getHeight() / 2f);
stackBounds.set(left, top, left + size.getWidth(), top + size.getHeight());
@@ -228,16 +240,6 @@ class PinnedStackController {
}
/**
- * @return the size of the PIP based on the given {@param aspectRatio}.
- */
- Size getSize(float aspectRatio) {
- synchronized (mService.mWindowMap) {
- return mSnapAlgorithm.getSizeForAspectRatio(aspectRatio, mMinSize,
- mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight);
- }
- }
-
- /**
* @return the default bounds to show the PIP when there is no active PIP.
*/
Rect getDefaultBounds() {
@@ -246,7 +248,8 @@ class PinnedStackController {
getInsetBounds(insetBounds);
final Rect defaultBounds = new Rect();
- final Size size = getSize(mDefaultAspectRatio);
+ final Size size = mSnapAlgorithm.getSizeForAspectRatio(mDefaultAspectRatio,
+ mDefaultMinSize, mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight);
Gravity.apply(mDefaultStackGravity, size.getWidth(), size.getHeight(), insetBounds,
0, mIsImeShowing ? mImeHeight : 0, defaultBounds);
return defaultBounds;
@@ -401,7 +404,8 @@ class PinnedStackController {
getInsetBounds(insetBounds);
final Rect normalBounds = getDefaultBounds();
if (isValidPictureInPictureAspectRatio(mAspectRatio)) {
- transformBoundsToAspectRatio(normalBounds, mAspectRatio);
+ transformBoundsToAspectRatio(normalBounds, mAspectRatio,
+ false /* useCurrentMinEdgeSize */);
}
final Rect animatingBounds = mTmpAnimatingBoundsRect;
final TaskStack pinnedStack = mDisplayContent.getStackById(PINNED_STACK_ID);
diff --git a/services/core/java/com/android/server/wm/PinnedStackWindowController.java b/services/core/java/com/android/server/wm/PinnedStackWindowController.java
index 0c628acba92c..989e8f23693a 100644
--- a/services/core/java/com/android/server/wm/PinnedStackWindowController.java
+++ b/services/core/java/com/android/server/wm/PinnedStackWindowController.java
@@ -17,7 +17,6 @@
package com.android.server.wm;
import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
-import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
import static com.android.server.wm.BoundsAnimationController.NO_PIP_MODE_CHANGED_CALLBACKS;
import static com.android.server.wm.BoundsAnimationController.SCHEDULE_PIP_MODE_CHANGED_ON_END;
@@ -36,7 +35,8 @@ import java.util.List;
*/
public class PinnedStackWindowController extends StackWindowController {
- private Rect mTmpBoundsRect = new Rect();
+ private Rect mTmpFromBounds = new Rect();
+ private Rect mTmpToBounds = new Rect();
public PinnedStackWindowController(int stackId, PinnedStackWindowListener listener,
int displayId, boolean onTop, Rect outBounds) {
@@ -44,16 +44,16 @@ public class PinnedStackWindowController extends StackWindowController {
}
/**
- * @param useExistingStackBounds Apply {@param aspectRatio} to the existing target stack bounds
- * if possible
+ * @return the {@param currentStackBounds} transformed to the give {@param aspectRatio}. If
+ * {@param currentStackBounds} is null, then the {@param aspectRatio} is applied to the
+ * default bounds.
*/
- public Rect getPictureInPictureBounds(float aspectRatio, boolean useExistingStackBounds) {
+ public Rect getPictureInPictureBounds(float aspectRatio, Rect stackBounds) {
synchronized (mWindowMap) {
if (!mService.mSupportsPictureInPicture || mContainer == null) {
return null;
}
- final Rect stackBounds;
final DisplayContent displayContent = mContainer.getDisplayContent();
if (displayContent == null) {
return null;
@@ -61,18 +61,14 @@ public class PinnedStackWindowController extends StackWindowController {
final PinnedStackController pinnedStackController =
displayContent.getPinnedStackController();
- if (useExistingStackBounds) {
- // If the stack exists, then use its final bounds to calculate the new aspect ratio
- // bounds
- stackBounds = new Rect();
- mContainer.getAnimationOrCurrentBounds(stackBounds);
- } else {
- // Otherwise, just calculate the aspect ratio bounds from the default bounds
+ if (stackBounds == null) {
+ // Calculate the aspect ratio bounds from the default bounds
stackBounds = pinnedStackController.getDefaultBounds();
}
if (pinnedStackController.isValidPictureInPictureAspectRatio(aspectRatio)) {
- return pinnedStackController.transformBoundsToAspectRatio(stackBounds, aspectRatio);
+ return pinnedStackController.transformBoundsToAspectRatio(stackBounds, aspectRatio,
+ true /* useCurrentMinEdgeSize */);
} else {
return stackBounds;
}
@@ -104,10 +100,10 @@ public class PinnedStackWindowController extends StackWindowController {
}
schedulePipModeChangedState = SCHEDULE_PIP_MODE_CHANGED_ON_START;
- mService.getStackBounds(FULLSCREEN_WORKSPACE_STACK_ID, mTmpBoundsRect);
- if (!mTmpBoundsRect.isEmpty()) {
+ mService.getStackBounds(FULLSCREEN_WORKSPACE_STACK_ID, mTmpToBounds);
+ if (!mTmpToBounds.isEmpty()) {
// If there is a fullscreen bounds, use that
- toBounds = new Rect(mTmpBoundsRect);
+ toBounds = new Rect(mTmpToBounds);
} else {
// Otherwise, use the display bounds
toBounds = new Rect();
@@ -142,16 +138,15 @@ public class PinnedStackWindowController extends StackWindowController {
return;
}
- final Rect toBounds = getPictureInPictureBounds(aspectRatio,
- true /* useExistingStackBounds */);
- final Rect targetBounds = new Rect();
- mContainer.getAnimationOrCurrentBounds(targetBounds);
final PinnedStackController pinnedStackController =
mContainer.getDisplayContent().getPinnedStackController();
if (Float.compare(aspectRatio, pinnedStackController.getAspectRatio()) != 0) {
- if (!toBounds.equals(targetBounds)) {
- animateResizePinnedStack(toBounds, null /* sourceHintBounds */,
+ mContainer.getAnimationOrCurrentBounds(mTmpFromBounds);
+ mTmpToBounds.set(mTmpFromBounds);
+ getPictureInPictureBounds(aspectRatio, mTmpToBounds);
+ if (!mTmpToBounds.equals(mTmpFromBounds)) {
+ animateResizePinnedStack(mTmpToBounds, null /* sourceHintBounds */,
-1 /* duration */, false /* fromFullscreen */);
}
pinnedStackController.setAspectRatio(
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 233e75bbfec7..fb500bc256fd 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -858,14 +858,20 @@ class RootWindowContainer extends WindowContainer<DisplayContent> {
final int privateflags = attrs.privateFlags;
boolean displayHasContent = false;
+ if (DEBUG_KEEP_SCREEN_ON && (attrFlags & FLAG_KEEP_SCREEN_ON) != 0
+ && w != mService.mLastWakeLockHoldingWindow) {
+ Slog.d(TAG_KEEP_SCREEN_ON, "handleNotObscuredLocked: " + w
+ + " has FLAG_KEEP_SCREEN_ON set, hasSurface=" + w.mHasSurface
+ + ", canBeSeen=" + canBeSeen);
+ }
+
if (w.mHasSurface && canBeSeen) {
if ((attrFlags & FLAG_KEEP_SCREEN_ON) != 0) {
mHoldScreen = w.mSession;
mHoldScreenWindow = w;
} else if (DEBUG_KEEP_SCREEN_ON && w == mService.mLastWakeLockHoldingWindow) {
Slog.d(TAG_KEEP_SCREEN_ON, "handleNotObscuredLocked: " + w + " was holding "
- + "screen wakelock but no longer has FLAG_KEEP_SCREEN_ON!!! called by"
- + Debug.getCallers(10));
+ + "screen wakelock but no longer has FLAG_KEEP_SCREEN_ON!!!");
}
if (!syswin && w.mAttrs.screenBrightness >= 0 && mScreenBrightness < 0) {
mScreenBrightness = w.mAttrs.screenBrightness;
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java
index b2667781b955..1f7ef5014d36 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotController.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java
@@ -31,6 +31,9 @@ import android.graphics.Rect;
import android.os.Environment;
import android.os.Handler;
import android.util.ArraySet;
+import android.view.DisplayListCanvas;
+import android.view.RenderNode;
+import android.view.ThreadedRenderer;
import android.view.WindowManager.LayoutParams;
import android.view.WindowManagerPolicy.ScreenOffListener;
import android.view.WindowManagerPolicy.StartingSurface;
@@ -238,19 +241,22 @@ class TaskSnapshotController {
final int color = task.getTaskDescription().getBackgroundColor();
final int statusBarColor = task.getTaskDescription().getStatusBarColor();
final int navigationBarColor = task.getTaskDescription().getNavigationBarColor();
- final Bitmap b = Bitmap.createBitmap(mainWindow.getFrameLw().width(),
- mainWindow.getFrameLw().height(), ARGB_8888);
- final Canvas c = new Canvas(b);
- c.drawColor(color);
final LayoutParams attrs = mainWindow.getAttrs();
final SystemBarBackgroundPainter decorPainter = new SystemBarBackgroundPainter(attrs.flags,
attrs.privateFlags, attrs.systemUiVisibility, statusBarColor, navigationBarColor);
+ final int width = mainWindow.getFrameLw().width();
+ final int height = mainWindow.getFrameLw().height();
+
+ final RenderNode node = RenderNode.create("TaskSnapshotController", null);
+ node.setLeftTopRightBottom(0, 0, width, height);
+ node.setClipToBounds(false);
+ final DisplayListCanvas c = node.start(width, height);
+ c.drawColor(color);
decorPainter.setInsets(mainWindow.mContentInsets, mainWindow.mStableInsets);
decorPainter.drawDecors(c, null /* statusBarExcludeFrame */);
+ node.end(c);
+ final Bitmap hwBitmap = ThreadedRenderer.createHardwareBitmap(node, width, height);
- // Flush writer.
- c.setBitmap(null);
- final Bitmap hwBitmap = b.copy(HARDWARE, false /* isMutable */);
return new TaskSnapshot(hwBitmap.createGraphicBufferHandle(),
topChild.getConfiguration().orientation, mainWindow.mStableInsets,
false /* reduced */, 1.0f /* scale */);
diff --git a/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java b/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java
index 8279b5167766..c080f344c186 100644
--- a/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java
+++ b/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java
@@ -77,5 +77,5 @@ public class WindowManagerDebugConfig {
static final boolean DEBUG_UNKNOWN_APP_VISIBILITY = false;
static final String TAG_KEEP_SCREEN_ON = "DebugKeepScreenOn";
- static final boolean DEBUG_KEEP_SCREEN_ON = false;
+ static final boolean DEBUG_KEEP_SCREEN_ON = true;
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index a15891bc6414..02fdfeeb365d 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -123,6 +123,7 @@ import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.database.ContentObserver;
import android.graphics.Bitmap;
+import android.graphics.GraphicBuffer;
import android.graphics.Matrix;
import android.graphics.PixelFormat;
import android.graphics.Point;
@@ -349,6 +350,7 @@ public class WindowManagerService extends IWindowManager.Stub
private static final int ANIMATION_DURATION_SCALE = 2;
final private KeyguardDisableHandler mKeyguardDisableHandler;
+ boolean mKeyguardGoingAway;
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
@@ -2629,7 +2631,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
@Override
- public void overridePendingAppTransitionThumb(Bitmap srcThumb, int startX,
+ public void overridePendingAppTransitionThumb(GraphicBuffer srcThumb, int startX,
int startY, IRemoteCallback startedCallback, boolean scaleUp) {
synchronized(mWindowMap) {
mAppTransition.overridePendingAppTransitionThumb(srcThumb, startX, startY,
@@ -2638,7 +2640,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
@Override
- public void overridePendingAppTransitionAspectScaledThumb(Bitmap srcThumb, int startX,
+ public void overridePendingAppTransitionAspectScaledThumb(GraphicBuffer srcThumb, int startX,
int startY, int targetWidth, int targetHeight, IRemoteCallback startedCallback,
boolean scaleUp) {
synchronized(mWindowMap) {
@@ -2876,6 +2878,12 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
+ public void setKeyguardGoingAway(boolean keyguardGoingAway) {
+ synchronized (mWindowMap) {
+ mKeyguardGoingAway = keyguardGoingAway;
+ }
+ }
+
// -------------------------------------------------------------
// Misc IWindowSession methods
// -------------------------------------------------------------
@@ -3816,20 +3824,22 @@ public class WindowManagerService extends IWindowManager.Stub
long origId = Binder.clearCallingIdentity();
try {
- final boolean rotationChanged;
// TODO(multi-display): Update rotation for different displays separately.
- final DisplayContent displayContent = getDefaultDisplayContentLocked();
+ final boolean rotationChanged;
+ final int displayId;
synchronized (mWindowMap) {
+ final DisplayContent displayContent = getDefaultDisplayContentLocked();
rotationChanged = displayContent.updateRotationUnchecked(
false /* inTransaction */);
if (!rotationChanged || forceRelayout) {
- getDefaultDisplayContentLocked().setLayoutNeeded();
+ displayContent.setLayoutNeeded();
mWindowPlacerLocked.performSurfacePlacement();
}
+ displayId = displayContent.getDisplayId();
}
if (rotationChanged || alwaysSendConfiguration) {
- sendNewConfiguration(displayContent.getDisplayId());
+ sendNewConfiguration(displayId);
}
} finally {
Binder.restoreCallingIdentity(origId);
@@ -6457,7 +6467,7 @@ public class WindowManagerService extends IWindowManager.Stub
pw.print(" window="); pw.print(mWindowAnimationScaleSetting);
pw.print(" transition="); pw.print(mTransitionAnimationScaleSetting);
pw.print(" animator="); pw.println(mAnimatorDurationScaleSetting);
- pw.print(" mSkipAppTransitionAnimation=");pw.println(mSkipAppTransitionAnimation);
+ pw.print(" mSkipAppTransitionAnimation=");pw.println(mSkipAppTransitionAnimation);
pw.println(" mLayoutToAnim:");
mAppTransition.dump(pw, " ");
}
@@ -6890,9 +6900,11 @@ public class WindowManagerService extends IWindowManager.Stub
"registerDockedStackListener()")) {
return;
}
- // TODO(multi-display): The listener is registered on the default display only.
- getDefaultDisplayContentLocked().mDividerControllerLocked.registerDockedStackListener(
- listener);
+ synchronized (mWindowMap) {
+ // TODO(multi-display): The listener is registered on the default display only.
+ getDefaultDisplayContentLocked().mDividerControllerLocked.registerDockedStackListener(
+ listener);
+ }
}
@Override
@@ -7173,6 +7185,11 @@ public class WindowManagerService extends IWindowManager.Stub
}
@Override
+ public boolean isKeyguardGoingAway() {
+ return WindowManagerService.this.mKeyguardGoingAway;
+ }
+
+ @Override
public void showGlobalActions() {
WindowManagerService.this.showGlobalActions();
}
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index acd7703836d1..44a867c9b65f 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -2202,18 +2202,30 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
}
}
- void prepareWindowToDisplayDuringRelayout(MergedConfiguration mergedConfiguration) {
+ void prepareWindowToDisplayDuringRelayout(MergedConfiguration mergedConfiguration,
+ boolean wasVisible) {
+ // We need to turn on screen regardless of visibility.
+ if ((mAttrs.flags & FLAG_TURN_SCREEN_ON) != 0) {
+ if (DEBUG_VISIBILITY) Slog.v(TAG, "Relayout window turning screen on: " + this);
+ mTurnOnScreen = true;
+ }
+
+ // If we were already visible, skip rest of preparation.
+ if (wasVisible) {
+ if (DEBUG_VISIBILITY) Slog.v(TAG,
+ "Already visible and does not turn on screen, skip preparing: " + this);
+ return;
+ }
+
if ((mAttrs.softInputMode & SOFT_INPUT_MASK_ADJUST)
== SOFT_INPUT_ADJUST_RESIZE) {
mLayoutNeeded = true;
}
+
if (isDrawnLw() && mService.okToDisplay()) {
mWinAnimator.applyEnterAnimationLocked();
}
- if ((mAttrs.flags & FLAG_TURN_SCREEN_ON) != 0) {
- if (DEBUG_VISIBILITY) Slog.v(TAG, "Relayout window turning screen on: " + this);
- mTurnOnScreen = true;
- }
+
if (isConfigChanged()) {
final Configuration globalConfig = mService.mRoot.getConfiguration();
final Configuration overrideConfig = getMergedOverrideConfiguration();
@@ -3407,7 +3419,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
pw.print(prefix); pw.print("mOrientationChanging=");
pw.print(mOrientationChanging);
pw.print(" mAppFreezing="); pw.print(mAppFreezing);
- pw.print(" mTurnOnScreen="); pw.println(mTurnOnScreen);
+ pw.print(" mTurnOnScreen="); pw.print(mTurnOnScreen);
pw.print(" mReportOrientationChanged="); pw.println(mReportOrientationChanged);
}
if (mLastFreezeDuration != 0) {
@@ -4348,9 +4360,9 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
mLastVisibleLayoutRotation = getDisplayContent().getRotation();
mWinAnimator.mEnteringAnimation = true;
- if (!wasVisible) {
- prepareWindowToDisplayDuringRelayout(mergedConfiguration);
- }
+
+ prepareWindowToDisplayDuringRelayout(mergedConfiguration, wasVisible);
+
if ((attrChanges & FORMAT_CHANGED) != 0) {
// If the format can't be changed in place, preserve the old surface until the app draws
// on the new one. This prevents blinking when we change elevation of freeform and
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index d75afcf357a8..73f8d27bc7a6 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -687,6 +687,7 @@ class WindowStateAnimator {
mSurfaceController = new WindowSurfaceController(mSession.mSurfaceSession,
attrs.getTitle().toString(),
width, height, format, flags, this, windowType, ownerUid);
+ mSurfaceFormat = format;
w.setHasSurface(true);
diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
index 4a1a7052a8b0..cb1b2e6abc58 100644
--- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
+++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
@@ -38,11 +38,9 @@ import static com.android.server.wm.WindowManagerService.MAX_ANIMATION_DURATION;
import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_PLACING_SURFACES;
import android.content.res.Configuration;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
+import android.graphics.GraphicBuffer;
import android.graphics.PixelFormat;
import android.graphics.Rect;
-import android.os.Binder;
import android.os.Debug;
import android.os.Trace;
import android.util.ArraySet;
@@ -675,8 +673,9 @@ class WindowSurfacePlacer {
return;
}
final int taskId = appToken.getTask().mTaskId;
- Bitmap thumbnailHeader = mService.mAppTransition.getAppTransitionThumbnailHeader(taskId);
- if (thumbnailHeader == null || thumbnailHeader.getConfig() == Bitmap.Config.ALPHA_8) {
+ final GraphicBuffer thumbnailHeader =
+ mService.mAppTransition.getAppTransitionThumbnailHeader(taskId);
+ if (thumbnailHeader == null) {
if (DEBUG_APP_TRANSITIONS) Slog.d(TAG, "No thumbnail header bitmap for: " + taskId);
return;
}
@@ -700,12 +699,10 @@ class WindowSurfacePlacer {
Slog.i(TAG, " THUMBNAIL " + surfaceControl + ": CREATE");
}
- // Draw the thumbnail onto the surface
+ // Transfer the thumbnail to the surface
Surface drawSurface = new Surface();
drawSurface.copyFrom(surfaceControl);
- Canvas c = drawSurface.lockCanvas(dirty);
- c.drawBitmap(thumbnailHeader, 0, 0, null);
- drawSurface.unlockCanvasAndPost(c);
+ drawSurface.attachAndQueueBuffer(thumbnailHeader);
drawSurface.release();
// Get the thumbnail animation
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
index 9cfa542da9d1..bac121695ed9 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
@@ -235,8 +235,7 @@ public class ActivityTestsBase {
if (mStackId == ActivityManager.StackId.PINNED_STACK_ID) {
mStack = new PinnedActivityStack(this, recents, mOnTop) {
@Override
- Rect getPictureInPictureBounds(float aspectRatio,
- boolean useExistingStackBounds) {
+ Rect getDefaultPictureInPictureBounds(float aspectRatio) {
return new Rect(50, 50, 100, 100);
}
};
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java
index 5f5189825deb..c809c325726f 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java
@@ -16,6 +16,8 @@
package com.android.server.wm;
+import android.util.MergedConfiguration;
+import android.view.WindowManager;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -204,4 +206,20 @@ public class WindowStateTests extends WindowTestsBase {
assertEquals(mediaChild, windows.pollFirst());
assertTrue(windows.isEmpty());
}
+
+ @Test
+ public void testPrepareWindowToDisplayDuringRelayout() throws Exception {
+ testPrepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
+ testPrepareWindowToDisplayDuringRelayout(true /*wasVisible*/);
+ }
+
+ private void testPrepareWindowToDisplayDuringRelayout(boolean wasVisible) {
+ final WindowState root = createWindow(null, TYPE_APPLICATION, "root");
+ root.mAttrs.flags |= WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
+ root.mTurnOnScreen = false;
+
+ root.prepareWindowToDisplayDuringRelayout(new MergedConfiguration(),
+ wasVisible /*wasVisible*/);
+ assertTrue(root.mTurnOnScreen);
+ }
}
diff --git a/services/usage/java/com/android/server/usage/StorageStatsService.java b/services/usage/java/com/android/server/usage/StorageStatsService.java
index 16b73d5515e5..562443f53546 100644
--- a/services/usage/java/com/android/server/usage/StorageStatsService.java
+++ b/services/usage/java/com/android/server/usage/StorageStatsService.java
@@ -62,6 +62,8 @@ import com.android.server.pm.Installer;
import com.android.server.pm.Installer.InstallerException;
import com.android.server.storage.CacheQuotaStrategy;
+import java.io.File;
+import java.io.FileNotFoundException;
import java.io.IOException;
public class StorageStatsService extends IStorageStatsManager.Stub {
@@ -181,29 +183,42 @@ public class StorageStatsService extends IStorageStatsManager.Stub {
public long getFreeBytes(String volumeUuid, String callingPackage) {
// NOTE: No permissions required
- long cacheBytes = 0;
final long token = Binder.clearCallingIdentity();
try {
+ final File path;
+ try {
+ path = mStorage.findPathForUuid(volumeUuid);
+ } catch (FileNotFoundException e) {
+ throw new ParcelableException(e);
+ }
+
+ // Free space is usable bytes plus any cached data that we're
+ // willing to automatically clear. To avoid user confusion, this
+ // logic should be kept in sync with getAllocatableBytes().
if (isQuotaSupported(volumeUuid, callingPackage)) {
- for (UserInfo user : mUser.getUsers()) {
- final StorageStats stats = queryStatsForUser(volumeUuid, user.id, null);
- cacheBytes += stats.cacheBytes;
- }
+ final long cacheTotal = getCacheBytes(volumeUuid, callingPackage);
+ final long cacheReserved = mStorage.getStorageCacheBytes(path);
+ final long cacheClearable = Math.max(0, cacheTotal - cacheReserved);
+
+ return path.getUsableSpace() + cacheClearable;
+ } else {
+ return path.getUsableSpace();
}
} finally {
Binder.restoreCallingIdentity(token);
}
+ }
- if (volumeUuid == StorageManager.UUID_PRIVATE_INTERNAL) {
- return Environment.getDataDirectory().getFreeSpace() + cacheBytes;
- } else {
- final VolumeInfo vol = mStorage.findVolumeByUuid(volumeUuid);
- if (vol == null) {
- throw new ParcelableException(
- new IOException("Failed to find storage device for UUID " + volumeUuid));
- }
- return vol.getPath().getFreeSpace() + cacheBytes;
+ @Override
+ public long getCacheBytes(String volumeUuid, String callingPackage) {
+ enforcePermission(Binder.getCallingUid(), callingPackage);
+
+ long cacheBytes = 0;
+ for (UserInfo user : mUser.getUsers()) {
+ final StorageStats stats = queryStatsForUser(volumeUuid, user.id, null);
+ cacheBytes += stats.cacheBytes;
}
+ return cacheBytes;
}
@Override
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index bc5e4d51e0f8..fa7b9b0b96f0 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -1449,6 +1449,11 @@ public class PhoneNumberUtils
* @hide
*/
public static boolean isInternationalNumber(String phoneNumber, String defaultCountryIso) {
+ // If no phone number is provided, it can't be international.
+ if (TextUtils.isEmpty(phoneNumber)) {
+ return false;
+ }
+
// If it starts with # or * its not international.
if (phoneNumber.startsWith("#") || phoneNumber.startsWith("*")) {
return false;
diff --git a/tools/aapt2/Android.bp b/tools/aapt2/Android.bp
index bf189492b082..b2f1f62647e6 100644
--- a/tools/aapt2/Android.bp
+++ b/tools/aapt2/Android.bp
@@ -160,7 +160,7 @@ cc_library_host_shared {
cc_test_host {
name: "aapt2_tests",
srcs: ["**/*_test.cpp"],
- static_libs: ["libaapt2"],
+ static_libs: ["libaapt2", "libgmock"],
defaults: ["aapt_defaults"],
}
diff --git a/tools/aapt2/Format.proto b/tools/aapt2/Format.proto
index 0917129ba90d..870b735f70a7 100644
--- a/tools/aapt2/Format.proto
+++ b/tools/aapt2/Format.proto
@@ -69,6 +69,7 @@ message SymbolStatus {
optional Visibility visibility = 1;
optional Source source = 2;
optional string comment = 3;
+ optional bool allow_new = 4;
}
message Entry {
diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp
index 0d1850fed26a..57ae2700127c 100644
--- a/tools/aapt2/ResourceParser.cpp
+++ b/tools/aapt2/ResourceParser.cpp
@@ -92,14 +92,14 @@ struct ParsedResource {
Source source;
ResourceId id;
Maybe<SymbolState> symbol_state;
+ bool allow_new = false;
std::string comment;
std::unique_ptr<Value> value;
std::list<ParsedResource> child_resources;
};
// Recursively adds resources to the ResourceTable.
-static bool AddResourcesToTable(ResourceTable* table, IDiagnostics* diag,
- ParsedResource* res) {
+static bool AddResourcesToTable(ResourceTable* table, IDiagnostics* diag, ParsedResource* res) {
StringPiece trimmed_comment = util::TrimWhitespace(res->comment);
if (trimmed_comment.size() != res->comment.size()) {
// Only if there was a change do we re-assign.
@@ -111,6 +111,7 @@ static bool AddResourcesToTable(ResourceTable* table, IDiagnostics* diag,
symbol.state = res->symbol_state.value();
symbol.source = res->source;
symbol.comment = res->comment;
+ symbol.allow_new = res->allow_new;
if (!table->SetSymbolState(res->name, res->id, symbol, diag)) {
return false;
}
@@ -121,8 +122,8 @@ static bool AddResourcesToTable(ResourceTable* table, IDiagnostics* diag,
res->value->SetComment(std::move(res->comment));
res->value->SetSource(std::move(res->source));
- if (!table->AddResource(res->name, res->id, res->config, res->product,
- std::move(res->value), diag)) {
+ if (!table->AddResource(res->name, res->id, res->config, res->product, std::move(res->value),
+ diag)) {
return false;
}
}
@@ -849,6 +850,7 @@ bool ResourceParser::ParseAddResource(xml::XmlPullParser* parser,
ParsedResource* out_resource) {
if (ParseSymbolImpl(parser, out_resource)) {
out_resource->symbol_state = SymbolState::kUndefined;
+ out_resource->allow_new = true;
return true;
}
return false;
diff --git a/tools/aapt2/ResourceParser_test.cpp b/tools/aapt2/ResourceParser_test.cpp
index faa660729237..e3abde6bef29 100644
--- a/tools/aapt2/ResourceParser_test.cpp
+++ b/tools/aapt2/ResourceParser_test.cpp
@@ -777,8 +777,7 @@ TEST_F(ResourceParserTest, ExternalTypesShouldOnlyBeReferences) {
ASSERT_FALSE(TestParse(input));
}
-TEST_F(ResourceParserTest,
- AddResourcesElementShouldAddEntryWithUndefinedSymbol) {
+TEST_F(ResourceParserTest, AddResourcesElementShouldAddEntryWithUndefinedSymbol) {
std::string input = R"EOF(<add-resource name="bar" type="string" />)EOF";
ASSERT_TRUE(TestParse(input));
@@ -788,6 +787,7 @@ TEST_F(ResourceParserTest,
const ResourceEntry* entry = result.value().entry;
ASSERT_NE(nullptr, entry);
EXPECT_EQ(SymbolState::kUndefined, entry->symbol_status.state);
+ EXPECT_TRUE(entry->symbol_status.allow_new);
}
TEST_F(ResourceParserTest, ParseItemElementWithFormat) {
diff --git a/tools/aapt2/ResourceTable.cpp b/tools/aapt2/ResourceTable.cpp
index 1947628e9267..168004f0b721 100644
--- a/tools/aapt2/ResourceTable.cpp
+++ b/tools/aapt2/ResourceTable.cpp
@@ -440,8 +440,7 @@ bool ResourceTable::AddResourceImpl(const ResourceNameRef& name, const ResourceI
return true;
}
-bool ResourceTable::SetSymbolState(const ResourceNameRef& name,
- const ResourceId& res_id,
+bool ResourceTable::SetSymbolState(const ResourceNameRef& name, const ResourceId& res_id,
const Symbol& symbol, IDiagnostics* diag) {
return SetSymbolStateImpl(name, res_id, symbol, ValidateName, diag);
}
@@ -489,8 +488,7 @@ bool ResourceTable::SetSymbolStateImpl(const ResourceNameRef& name, const Resour
diag->Error(DiagMessage(symbol.source)
<< "trying to add resource '" << name << "' with ID " << res_id
<< " but resource already has ID "
- << ResourceId(package->id.value(), type->id.value(),
- entry->id.value()));
+ << ResourceId(package->id.value(), type->id.value(), entry->id.value()));
return false;
}
@@ -505,6 +503,11 @@ bool ResourceTable::SetSymbolStateImpl(const ResourceNameRef& name, const Resour
type->symbol_status.state = SymbolState::kPublic;
}
+ if (symbol.allow_new) {
+ // This symbol can be added as a new resource when merging (if it belongs to an overlay).
+ entry->symbol_status.allow_new = true;
+ }
+
if (symbol.state == SymbolState::kUndefined &&
entry->symbol_status.state != SymbolState::kUndefined) {
// We can't undefine a symbol (remove its visibility). Ignore.
@@ -517,7 +520,10 @@ bool ResourceTable::SetSymbolStateImpl(const ResourceNameRef& name, const Resour
return true;
}
- entry->symbol_status = std::move(symbol);
+ // This symbol definition takes precedence, replace.
+ entry->symbol_status.state = symbol.state;
+ entry->symbol_status.source = symbol.source;
+ entry->symbol_status.comment = symbol.comment;
return true;
}
diff --git a/tools/aapt2/ResourceTable.h b/tools/aapt2/ResourceTable.h
index b0321214c6cc..4295d0674774 100644
--- a/tools/aapt2/ResourceTable.h
+++ b/tools/aapt2/ResourceTable.h
@@ -50,6 +50,10 @@ enum class SymbolState {
struct Symbol {
SymbolState state = SymbolState::kUndefined;
Source source;
+
+ // Whether this entry (originating from an overlay) can be added as a new resource.
+ bool allow_new = false;
+
std::string comment;
};
@@ -223,8 +227,7 @@ class ResourceTable {
bool SetSymbolState(const ResourceNameRef& name, const ResourceId& res_id,
const Symbol& symbol, IDiagnostics* diag);
- bool SetSymbolStateAllowMangled(const ResourceNameRef& name,
- const ResourceId& res_id,
+ bool SetSymbolStateAllowMangled(const ResourceNameRef& name, const ResourceId& res_id,
const Symbol& symbol, IDiagnostics* diag);
struct SearchResult {
diff --git a/tools/aapt2/ResourceUtils.cpp b/tools/aapt2/ResourceUtils.cpp
index 1bb7d9beee45..818c8cec30f9 100644
--- a/tools/aapt2/ResourceUtils.cpp
+++ b/tools/aapt2/ResourceUtils.cpp
@@ -496,19 +496,17 @@ Maybe<int> ParseSdkVersion(const StringPiece& str) {
std::unique_ptr<BinaryPrimitive> TryParseBool(const StringPiece& str) {
if (Maybe<bool> maybe_result = ParseBool(str)) {
- android::Res_value value = {};
- value.dataType = android::Res_value::TYPE_INT_BOOLEAN;
-
- if (maybe_result.value()) {
- value.data = 0xffffffffu;
- } else {
- value.data = 0;
- }
- return util::make_unique<BinaryPrimitive>(value);
+ const uint32_t data = maybe_result.value() ? 0xffffffffu : 0u;
+ return util::make_unique<BinaryPrimitive>(android::Res_value::TYPE_INT_BOOLEAN, data);
}
return {};
}
+std::unique_ptr<BinaryPrimitive> MakeBool(bool val) {
+ return util::make_unique<BinaryPrimitive>(android::Res_value::TYPE_INT_BOOLEAN,
+ val ? 0xffffffffu : 0u);
+}
+
std::unique_ptr<BinaryPrimitive> TryParseInt(const StringPiece& str) {
std::u16string str16 = util::Utf8ToUtf16(str);
android::Res_value value;
diff --git a/tools/aapt2/ResourceUtils.h b/tools/aapt2/ResourceUtils.h
index 48922b72fefa..da0fc8ee314a 100644
--- a/tools/aapt2/ResourceUtils.h
+++ b/tools/aapt2/ResourceUtils.h
@@ -147,6 +147,9 @@ std::unique_ptr<BinaryPrimitive> TryParseColor(const android::StringPiece& str);
*/
std::unique_ptr<BinaryPrimitive> TryParseBool(const android::StringPiece& str);
+// Returns a boolean BinaryPrimitive.
+std::unique_ptr<BinaryPrimitive> MakeBool(bool val);
+
/*
* Returns a BinaryPrimitve object representing an integer if the string was
* parsed as one.
diff --git a/tools/aapt2/ResourceValues.cpp b/tools/aapt2/ResourceValues.cpp
index 34bd2b4361ca..abfdec48df67 100644
--- a/tools/aapt2/ResourceValues.cpp
+++ b/tools/aapt2/ResourceValues.cpp
@@ -29,6 +29,11 @@
namespace aapt {
+std::ostream& operator<<(std::ostream& out, const Value& value) {
+ value.Print(&out);
+ return out;
+}
+
template <typename Derived>
void BaseValue<Derived>::Accept(RawValueVisitor* visitor) {
visitor->Visit(static_cast<Derived*>(this));
@@ -346,6 +351,15 @@ Attribute::Attribute(bool w, uint32_t t)
weak_ = w;
}
+std::ostream& operator<<(std::ostream& out, const Attribute::Symbol& s) {
+ if (s.symbol.name) {
+ out << s.symbol.name.value().entry;
+ } else {
+ out << "???";
+ }
+ return out << "=" << s.value;
+}
+
template <typename T>
constexpr T* add_pointer(T& val) {
return &val;
@@ -361,31 +375,27 @@ bool Attribute::Equals(const Value* value) const {
return false;
}
- if (type_mask != other->type_mask || min_int != other->min_int ||
- max_int != other->max_int) {
+ if (type_mask != other->type_mask || min_int != other->min_int || max_int != other->max_int) {
return false;
}
std::vector<const Symbol*> sorted_a;
std::transform(symbols.begin(), symbols.end(), std::back_inserter(sorted_a),
add_pointer<const Symbol>);
- std::sort(sorted_a.begin(), sorted_a.end(),
- [](const Symbol* a, const Symbol* b) -> bool {
- return a->symbol.name < b->symbol.name;
- });
+ std::sort(sorted_a.begin(), sorted_a.end(), [](const Symbol* a, const Symbol* b) -> bool {
+ return a->symbol.name < b->symbol.name;
+ });
std::vector<const Symbol*> sorted_b;
- std::transform(other->symbols.begin(), other->symbols.end(),
- std::back_inserter(sorted_b), add_pointer<const Symbol>);
- std::sort(sorted_b.begin(), sorted_b.end(),
- [](const Symbol* a, const Symbol* b) -> bool {
- return a->symbol.name < b->symbol.name;
- });
+ std::transform(other->symbols.begin(), other->symbols.end(), std::back_inserter(sorted_b),
+ add_pointer<const Symbol>);
+ std::sort(sorted_b.begin(), sorted_b.end(), [](const Symbol* a, const Symbol* b) -> bool {
+ return a->symbol.name < b->symbol.name;
+ });
return std::equal(sorted_a.begin(), sorted_a.end(), sorted_b.begin(),
[](const Symbol* a, const Symbol* b) -> bool {
- return a->symbol.Equals(&b->symbol) &&
- a->value == b->value;
+ return a->symbol.Equals(&b->symbol) && a->value == b->value;
});
}
@@ -588,14 +598,50 @@ bool Attribute::Matches(const Item* item, DiagMessage* out_msg) const {
return true;
}
+std::ostream& operator<<(std::ostream& out, const Style::Entry& entry) {
+ if (entry.key.name) {
+ out << entry.key.name.value();
+ } else if (entry.key.id) {
+ out << entry.key.id.value();
+ } else {
+ out << "???";
+ }
+ out << " = " << entry.value;
+ return out;
+}
+
+template <typename T>
+std::vector<T*> ToPointerVec(std::vector<T>& src) {
+ std::vector<T*> dst;
+ dst.reserve(src.size());
+ for (T& in : src) {
+ dst.push_back(&in);
+ }
+ return dst;
+}
+
+template <typename T>
+std::vector<const T*> ToPointerVec(const std::vector<T>& src) {
+ std::vector<const T*> dst;
+ dst.reserve(src.size());
+ for (const T& in : src) {
+ dst.push_back(&in);
+ }
+ return dst;
+}
+
+static bool KeyNameComparator(const Style::Entry* a, const Style::Entry* b) {
+ return a->key.name < b->key.name;
+}
+
bool Style::Equals(const Value* value) const {
const Style* other = ValueCast<Style>(value);
if (!other) {
return false;
}
+
if (bool(parent) != bool(other->parent) ||
- (parent && other->parent &&
- !parent.value().Equals(&other->parent.value()))) {
+ (parent && other->parent && !parent.value().Equals(&other->parent.value()))) {
return false;
}
@@ -603,26 +649,15 @@ bool Style::Equals(const Value* value) const {
return false;
}
- std::vector<const Entry*> sorted_a;
- std::transform(entries.begin(), entries.end(), std::back_inserter(sorted_a),
- add_pointer<const Entry>);
- std::sort(sorted_a.begin(), sorted_a.end(),
- [](const Entry* a, const Entry* b) -> bool {
- return a->key.name < b->key.name;
- });
+ std::vector<const Entry*> sorted_a = ToPointerVec(entries);
+ std::sort(sorted_a.begin(), sorted_a.end(), KeyNameComparator);
- std::vector<const Entry*> sorted_b;
- std::transform(other->entries.begin(), other->entries.end(),
- std::back_inserter(sorted_b), add_pointer<const Entry>);
- std::sort(sorted_b.begin(), sorted_b.end(),
- [](const Entry* a, const Entry* b) -> bool {
- return a->key.name < b->key.name;
- });
+ std::vector<const Entry*> sorted_b = ToPointerVec(other->entries);
+ std::sort(sorted_b.begin(), sorted_b.end(), KeyNameComparator);
return std::equal(sorted_a.begin(), sorted_a.end(), sorted_b.begin(),
[](const Entry* a, const Entry* b) -> bool {
- return a->key.Equals(&b->key) &&
- a->value->Equals(b->value.get());
+ return a->key.Equals(&b->key) && a->value->Equals(b->value.get());
});
}
@@ -633,8 +668,7 @@ Style* Style::Clone(StringPool* new_pool) const {
style->comment_ = comment_;
style->source_ = source_;
for (auto& entry : entries) {
- style->entries.push_back(
- Entry{entry.key, std::unique_ptr<Item>(entry.value->Clone(new_pool))});
+ style->entries.push_back(Entry{entry.key, std::unique_ptr<Item>(entry.value->Clone(new_pool))});
}
return style;
}
@@ -642,26 +676,73 @@ Style* Style::Clone(StringPool* new_pool) const {
void Style::Print(std::ostream* out) const {
*out << "(style) ";
if (parent && parent.value().name) {
- if (parent.value().private_reference) {
+ const Reference& parent_ref = parent.value();
+ if (parent_ref.private_reference) {
*out << "*";
}
- *out << parent.value().name.value();
+ *out << parent_ref.name.value();
}
*out << " [" << util::Joiner(entries, ", ") << "]";
}
-static ::std::ostream& operator<<(::std::ostream& out,
- const Style::Entry& value) {
- if (value.key.name) {
- out << value.key.name.value();
- } else if (value.key.id) {
- out << value.key.id.value();
- } else {
- out << "???";
+Style::Entry CloneEntry(const Style::Entry& entry, StringPool* pool) {
+ Style::Entry cloned_entry{entry.key};
+ if (entry.value != nullptr) {
+ cloned_entry.value.reset(entry.value->Clone(pool));
}
- out << " = ";
- value.value->Print(&out);
- return out;
+ return cloned_entry;
+}
+
+void Style::MergeWith(Style* other, StringPool* pool) {
+ if (other->parent) {
+ parent = other->parent;
+ }
+
+ // We can't assume that the entries are sorted alphabetically since they're supposed to be
+ // sorted by Resource Id. Not all Resource Ids may be set though, so we can't sort and merge
+ // them keying off that.
+ //
+ // Instead, sort the entries of each Style by their name in a separate structure. Then merge
+ // those.
+
+ std::vector<Entry*> this_sorted = ToPointerVec(entries);
+ std::sort(this_sorted.begin(), this_sorted.end(), KeyNameComparator);
+
+ std::vector<Entry*> other_sorted = ToPointerVec(other->entries);
+ std::sort(other_sorted.begin(), other_sorted.end(), KeyNameComparator);
+
+ auto this_iter = this_sorted.begin();
+ const auto this_end = this_sorted.end();
+
+ auto other_iter = other_sorted.begin();
+ const auto other_end = other_sorted.end();
+
+ std::vector<Entry> merged_entries;
+ while (this_iter != this_end) {
+ if (other_iter != other_end) {
+ if ((*this_iter)->key.name < (*other_iter)->key.name) {
+ merged_entries.push_back(std::move(**this_iter));
+ ++this_iter;
+ } else {
+ // The other overrides.
+ merged_entries.push_back(CloneEntry(**other_iter, pool));
+ if ((*this_iter)->key.name == (*other_iter)->key.name) {
+ ++this_iter;
+ }
+ ++other_iter;
+ }
+ } else {
+ merged_entries.push_back(std::move(**this_iter));
+ ++this_iter;
+ }
+ }
+
+ while (other_iter != other_end) {
+ merged_entries.push_back(CloneEntry(**other_iter, pool));
+ ++other_iter;
+ }
+
+ entries = std::move(merged_entries);
}
bool Array::Equals(const Value* value) const {
@@ -758,11 +839,6 @@ void Plural::Print(std::ostream* out) const {
}
}
-static ::std::ostream& operator<<(::std::ostream& out,
- const std::unique_ptr<Item>& item) {
- return out << *item;
-}
-
bool Styleable::Equals(const Value* value) const {
const Styleable* other = ValueCast<Styleable>(value);
if (!other) {
@@ -810,8 +886,7 @@ struct NameOnlyComparator {
void Styleable::MergeWith(Styleable* other) {
// Compare only names, because some References may already have their IDs
- // assigned
- // (framework IDs that don't change).
+ // assigned (framework IDs that don't change).
std::set<Reference, NameOnlyComparator> references;
references.insert(entries.begin(), entries.end());
references.insert(other->entries.begin(), other->entries.end());
diff --git a/tools/aapt2/ResourceValues.h b/tools/aapt2/ResourceValues.h
index 06f949f9555c..ac5795fb9774 100644
--- a/tools/aapt2/ResourceValues.h
+++ b/tools/aapt2/ResourceValues.h
@@ -40,7 +40,8 @@ struct RawValueVisitor;
// type specific operations is to check the Value's type() and
// cast it to the appropriate subclass. This isn't super clean,
// but it is the simplest strategy.
-struct Value {
+class Value {
+ public:
virtual ~Value() = default;
// Whether this value is weak and can be overridden without warning or error. Default is false.
@@ -82,6 +83,8 @@ struct Value {
// Human readable printout of this value.
virtual void Print(std::ostream* out) const = 0;
+ friend std::ostream& operator<<(std::ostream& out, const Value& value);
+
protected:
Source source_;
std::string comment_;
@@ -245,6 +248,8 @@ struct Attribute : public BaseValue<Attribute> {
struct Symbol {
Reference symbol;
uint32_t value;
+
+ friend std::ostream& operator<<(std::ostream& out, const Symbol& symbol);
};
uint32_t type_mask;
@@ -266,6 +271,8 @@ struct Style : public BaseValue<Style> {
struct Entry {
Reference key;
std::unique_ptr<Item> value;
+
+ friend std::ostream& operator<<(std::ostream& out, const Entry& entry);
};
Maybe<Reference> parent;
@@ -278,6 +285,10 @@ struct Style : public BaseValue<Style> {
bool Equals(const Value* value) const override;
Style* Clone(StringPool* new_pool) const override;
void Print(std::ostream* out) const override;
+
+ // Merges `style` into this Style. All identical attributes of `style` take precedence, including
+ // the parent, if there is one.
+ void MergeWith(Style* style, StringPool* pool);
};
struct Array : public BaseValue<Array> {
@@ -307,20 +318,15 @@ struct Styleable : public BaseValue<Styleable> {
void MergeWith(Styleable* styleable);
};
-// Stream operator for printing Value objects.
-inline ::std::ostream& operator<<(::std::ostream& out, const Value& value) {
- value.Print(&out);
- return out;
-}
-
-inline ::std::ostream& operator<<(::std::ostream& out,
- const Attribute::Symbol& s) {
- if (s.symbol.name) {
- out << s.symbol.name.value().entry;
+template <typename T>
+typename std::enable_if<std::is_base_of<Value, T>::value, std::ostream&>::type operator<<(
+ std::ostream& out, const std::unique_ptr<T>& value) {
+ if (value == nullptr) {
+ out << "NULL";
} else {
- out << "???";
+ value->Print(&out);
}
- return out << "=" << s.value;
+ return out;
}
} // namespace aapt
diff --git a/tools/aapt2/ResourceValues_test.cpp b/tools/aapt2/ResourceValues_test.cpp
index 692258003471..e154d93b6f85 100644
--- a/tools/aapt2/ResourceValues_test.cpp
+++ b/tools/aapt2/ResourceValues_test.cpp
@@ -148,4 +148,36 @@ TEST(ResourceValuesTest, StyleClone) {
EXPECT_TRUE(a->Equals(b.get()));
}
+TEST(ResourceValuesTest, StyleMerges) {
+ StringPool pool_a;
+ StringPool pool_b;
+
+ std::unique_ptr<Style> a =
+ test::StyleBuilder()
+ .SetParent("android:style/Parent")
+ .AddItem("android:attr/a", util::make_unique<String>(pool_a.MakeRef("FooA")))
+ .AddItem("android:attr/b", util::make_unique<String>(pool_a.MakeRef("FooB")))
+ .Build();
+
+ std::unique_ptr<Style> b =
+ test::StyleBuilder()
+ .SetParent("android:style/OverlayParent")
+ .AddItem("android:attr/c", util::make_unique<String>(pool_b.MakeRef("OverlayFooC")))
+ .AddItem("android:attr/a", util::make_unique<String>(pool_b.MakeRef("OverlayFooA")))
+ .Build();
+
+ a->MergeWith(b.get(), &pool_a);
+
+ StringPool pool;
+ std::unique_ptr<Style> expected =
+ test::StyleBuilder()
+ .SetParent("android:style/OverlayParent")
+ .AddItem("android:attr/a", util::make_unique<String>(pool.MakeRef("OverlayFooA")))
+ .AddItem("android:attr/b", util::make_unique<String>(pool.MakeRef("FooB")))
+ .AddItem("android:attr/c", util::make_unique<String>(pool.MakeRef("OverlayFooC")))
+ .Build();
+
+ EXPECT_TRUE(a->Equals(expected.get()));
+}
+
} // namespace aapt
diff --git a/tools/aapt2/cmd/Link.cpp b/tools/aapt2/cmd/Link.cpp
index dd4b2ba9ff16..740a401f9b57 100644
--- a/tools/aapt2/cmd/Link.cpp
+++ b/tools/aapt2/cmd/Link.cpp
@@ -440,7 +440,8 @@ static bool IsTransitionElement(const std::string& name) {
}
static bool IsVectorElement(const std::string& name) {
- return name == "vector" || name == "animated-vector";
+ return name == "vector" || name == "animated-vector" || name == "pathInterpolator" ||
+ name == "objectAnimator";
}
template <typename T>
diff --git a/tools/aapt2/link/TableMerger.cpp b/tools/aapt2/link/TableMerger.cpp
index 931109125263..10e837c725e5 100644
--- a/tools/aapt2/link/TableMerger.cpp
+++ b/tools/aapt2/link/TableMerger.cpp
@@ -179,32 +179,39 @@ static bool MergeEntry(IAaptContext* context, const Source& src,
return true;
}
-/**
- * Modified CollisionResolver which will merge Styleables. Used with overlays.
- *
- * Styleables are not actual resources, but they are treated as such during the
- * compilation phase. Styleables don't simply overlay each other, their
- * definitions merge
- * and accumulate. If both values are Styleables, we just merge them into the
- * existing value.
- */
-static ResourceTable::CollisionResult ResolveMergeCollision(Value* existing,
- Value* incoming) {
+// Modified CollisionResolver which will merge Styleables and Styles. Used with overlays.
+//
+// Styleables are not actual resources, but they are treated as such during the
+// compilation phase.
+//
+// Styleables and Styles don't simply overlay each other, their definitions merge
+// and accumulate. If both values are Styleables/Styles, we just merge them into the
+// existing value.
+static ResourceTable::CollisionResult ResolveMergeCollision(Value* existing, Value* incoming,
+ StringPool* pool) {
if (Styleable* existing_styleable = ValueCast<Styleable>(existing)) {
if (Styleable* incoming_styleable = ValueCast<Styleable>(incoming)) {
// Styleables get merged.
existing_styleable->MergeWith(incoming_styleable);
return ResourceTable::CollisionResult::kKeepOriginal;
}
+ } else if (Style* existing_style = ValueCast<Style>(existing)) {
+ if (Style* incoming_style = ValueCast<Style>(incoming)) {
+ // Styles get merged.
+ existing_style->MergeWith(incoming_style, pool);
+ return ResourceTable::CollisionResult::kKeepOriginal;
+ }
}
// Delegate to the default handler.
return ResourceTable::ResolveValueCollision(existing, incoming);
}
-static ResourceTable::CollisionResult MergeConfigValue(
- IAaptContext* context, const ResourceNameRef& res_name, const bool overlay,
- ResourceConfigValue* dst_config_value,
- ResourceConfigValue* src_config_value) {
+static ResourceTable::CollisionResult MergeConfigValue(IAaptContext* context,
+ const ResourceNameRef& res_name,
+ const bool overlay,
+ ResourceConfigValue* dst_config_value,
+ ResourceConfigValue* src_config_value,
+ StringPool* pool) {
using CollisionResult = ResourceTable::CollisionResult;
Value* dst_value = dst_config_value->value.get();
@@ -212,10 +219,9 @@ static ResourceTable::CollisionResult MergeConfigValue(
CollisionResult collision_result;
if (overlay) {
- collision_result = ResolveMergeCollision(dst_value, src_value);
+ collision_result = ResolveMergeCollision(dst_value, src_value, pool);
} else {
- collision_result =
- ResourceTable::ResolveValueCollision(dst_value, src_value);
+ collision_result = ResourceTable::ResolveValueCollision(dst_value, src_value);
}
if (collision_result == CollisionResult::kConflict) {
@@ -224,10 +230,9 @@ static ResourceTable::CollisionResult MergeConfigValue(
}
// Error!
- context->GetDiagnostics()->Error(
- DiagMessage(src_value->GetSource())
- << "resource '" << res_name << "' has a conflicting value for "
- << "configuration (" << src_config_value->config << ")");
+ context->GetDiagnostics()->Error(DiagMessage(src_value->GetSource())
+ << "resource '" << res_name << "' has a conflicting value for "
+ << "configuration (" << src_config_value->config << ")");
context->GetDiagnostics()->Note(DiagMessage(dst_value->GetSource())
<< "originally defined here");
return CollisionResult::kConflict;
@@ -243,8 +248,7 @@ bool TableMerger::DoMerge(const Source& src, ResourceTable* src_table,
bool error = false;
for (auto& src_type : src_package->types) {
- ResourceTableType* dst_type =
- master_package_->FindOrCreateType(src_type->type);
+ ResourceTableType* dst_type = master_package_->FindOrCreateType(src_type->type);
if (!MergeType(context_, src, dst_type, src_type.get())) {
error = true;
continue;
@@ -253,27 +257,24 @@ bool TableMerger::DoMerge(const Source& src, ResourceTable* src_table,
for (auto& src_entry : src_type->entries) {
std::string entry_name = src_entry->name;
if (mangle_package) {
- entry_name =
- NameMangler::MangleEntry(src_package->name, src_entry->name);
+ entry_name = NameMangler::MangleEntry(src_package->name, src_entry->name);
}
ResourceEntry* dst_entry;
- if (allow_new_resources) {
+ if (allow_new_resources || src_entry->symbol_status.allow_new) {
dst_entry = dst_type->FindOrCreateEntry(entry_name);
} else {
dst_entry = dst_type->FindEntry(entry_name);
}
- const ResourceNameRef res_name(src_package->name, src_type->type,
- src_entry->name);
+ const ResourceNameRef res_name(src_package->name, src_type->type, src_entry->name);
if (!dst_entry) {
- context_->GetDiagnostics()->Error(
- DiagMessage(src) << "resource " << res_name
- << " does not override an existing resource");
- context_->GetDiagnostics()->Note(
- DiagMessage(src) << "define an <add-resource> tag or use "
- << "--auto-add-overlay");
+ context_->GetDiagnostics()->Error(DiagMessage(src)
+ << "resource " << res_name
+ << " does not override an existing resource");
+ context_->GetDiagnostics()->Note(DiagMessage(src) << "define an <add-resource> tag or use "
+ << "--auto-add-overlay");
error = true;
continue;
}
@@ -291,7 +292,7 @@ bool TableMerger::DoMerge(const Source& src, ResourceTable* src_table,
if (dst_config_value) {
CollisionResult collision_result =
MergeConfigValue(context_, res_name, overlay, dst_config_value,
- src_config_value.get());
+ src_config_value.get(), &master_table_->string_pool);
if (collision_result == CollisionResult::kConflict) {
error = true;
continue;
@@ -299,25 +300,22 @@ bool TableMerger::DoMerge(const Source& src, ResourceTable* src_table,
continue;
}
} else {
- dst_config_value = dst_entry->FindOrCreateValue(
- src_config_value->config, src_config_value->product);
+ dst_config_value =
+ dst_entry->FindOrCreateValue(src_config_value->config, src_config_value->product);
}
// Continue if we're taking the new resource.
- if (FileReference* f =
- ValueCast<FileReference>(src_config_value->value.get())) {
+ if (FileReference* f = ValueCast<FileReference>(src_config_value->value.get())) {
std::unique_ptr<FileReference> new_file_ref;
if (mangle_package) {
new_file_ref = CloneAndMangleFile(src_package->name, *f);
} else {
- new_file_ref = std::unique_ptr<FileReference>(
- f->Clone(&master_table_->string_pool));
+ new_file_ref = std::unique_ptr<FileReference>(f->Clone(&master_table_->string_pool));
}
if (callback) {
- if (!callback(res_name, src_config_value->config,
- new_file_ref.get(), f)) {
+ if (!callback(res_name, src_config_value->config, new_file_ref.get(), f)) {
error = true;
continue;
}
@@ -341,18 +339,15 @@ std::unique_ptr<FileReference> TableMerger::CloneAndMangleFile(
std::string mangled_entry = NameMangler::MangleEntry(package, entry.to_string());
std::string newPath = prefix.to_string() + mangled_entry + suffix.to_string();
std::unique_ptr<FileReference> new_file_ref =
- util::make_unique<FileReference>(
- master_table_->string_pool.MakeRef(newPath));
+ util::make_unique<FileReference>(master_table_->string_pool.MakeRef(newPath));
new_file_ref->SetComment(file_ref.GetComment());
new_file_ref->SetSource(file_ref.GetSource());
return new_file_ref;
}
- return std::unique_ptr<FileReference>(
- file_ref.Clone(&master_table_->string_pool));
+ return std::unique_ptr<FileReference>(file_ref.Clone(&master_table_->string_pool));
}
-bool TableMerger::MergeFileImpl(const ResourceFile& file_desc, io::IFile* file,
- bool overlay) {
+bool TableMerger::MergeFileImpl(const ResourceFile& file_desc, io::IFile* file, bool overlay) {
ResourceTable table;
std::string path = ResourceUtils::BuildResourceFileName(file_desc);
std::unique_ptr<FileReference> file_ref =
diff --git a/tools/aapt2/link/TableMerger_test.cpp b/tools/aapt2/link/TableMerger_test.cpp
index 742f5a7a570a..45b01a494164 100644
--- a/tools/aapt2/link/TableMerger_test.cpp
+++ b/tools/aapt2/link/TableMerger_test.cpp
@@ -20,6 +20,14 @@
#include "io/FileSystem.h"
#include "test/Test.h"
+using ::aapt::test::ValueEq;
+using ::testing::Contains;
+using ::testing::NotNull;
+using ::testing::UnorderedElementsAreArray;
+using ::testing::Pointee;
+using ::testing::Field;
+using ::testing::Eq;
+
namespace aapt {
struct TableMergerTest : public ::testing::Test {
@@ -62,26 +70,20 @@ TEST_F(TableMergerTest, SimpleMerge) {
io::FileCollection collection;
ASSERT_TRUE(merger.Merge({}, table_a.get()));
- ASSERT_TRUE(
- merger.MergeAndMangle({}, "com.app.b", table_b.get(), &collection));
+ ASSERT_TRUE(merger.MergeAndMangle({}, "com.app.b", table_b.get(), &collection));
EXPECT_TRUE(merger.merged_packages().count("com.app.b") != 0);
// Entries from com.app.a should not be mangled.
- AAPT_EXPECT_TRUE(
- final_table.FindResource(test::ParseNameOrDie("com.app.a:id/foo")));
- AAPT_EXPECT_TRUE(
- final_table.FindResource(test::ParseNameOrDie("com.app.a:id/bar")));
- AAPT_EXPECT_TRUE(final_table.FindResource(
- test::ParseNameOrDie("com.app.a:styleable/view")));
+ EXPECT_TRUE(final_table.FindResource(test::ParseNameOrDie("com.app.a:id/foo")));
+ EXPECT_TRUE(final_table.FindResource(test::ParseNameOrDie("com.app.a:id/bar")));
+ EXPECT_TRUE(final_table.FindResource(test::ParseNameOrDie("com.app.a:styleable/view")));
// The unmangled name should not be present.
- AAPT_EXPECT_FALSE(
- final_table.FindResource(test::ParseNameOrDie("com.app.b:id/foo")));
+ EXPECT_FALSE(final_table.FindResource(test::ParseNameOrDie("com.app.b:id/foo")));
// Look for the mangled name.
- AAPT_EXPECT_TRUE(final_table.FindResource(
- test::ParseNameOrDie("com.app.a:id/com.app.b$foo")));
+ EXPECT_TRUE(final_table.FindResource(test::ParseNameOrDie("com.app.a:id/com.app.b$foo")));
}
TEST_F(TableMergerTest, MergeFile) {
@@ -100,7 +102,7 @@ TEST_F(TableMergerTest, MergeFile) {
FileReference* file = test::GetValueForConfig<FileReference>(
&final_table, "com.app.a:layout/main", test::ParseConfigOrDie("hdpi-v4"));
- ASSERT_NE(nullptr, file);
+ ASSERT_THAT(file, NotNull());
EXPECT_EQ(std::string("res/layout-hdpi-v4/main.xml"), *file->path);
}
@@ -137,17 +139,14 @@ TEST_F(TableMergerTest, MergeFileReferences) {
collection.InsertFile("res/xml/file.xml");
ASSERT_TRUE(merger.Merge({}, table_a.get()));
- ASSERT_TRUE(
- merger.MergeAndMangle({}, "com.app.b", table_b.get(), &collection));
+ ASSERT_TRUE(merger.MergeAndMangle({}, "com.app.b", table_b.get(), &collection));
- FileReference* f =
- test::GetValue<FileReference>(&final_table, "com.app.a:xml/file");
- ASSERT_NE(f, nullptr);
+ FileReference* f = test::GetValue<FileReference>(&final_table, "com.app.a:xml/file");
+ ASSERT_THAT(f, NotNull());
EXPECT_EQ(std::string("res/xml/file.xml"), *f->path);
- f = test::GetValue<FileReference>(&final_table,
- "com.app.a:xml/com.app.b$file");
- ASSERT_NE(f, nullptr);
+ f = test::GetValue<FileReference>(&final_table, "com.app.a:xml/com.app.b$file");
+ ASSERT_THAT(f, NotNull());
EXPECT_EQ(std::string("res/xml/com.app.b$file.xml"), *f->path);
}
@@ -171,10 +170,9 @@ TEST_F(TableMergerTest, OverrideResourceWithOverlay) {
ASSERT_TRUE(merger.Merge({}, base.get()));
ASSERT_TRUE(merger.MergeOverlay({}, overlay.get()));
- BinaryPrimitive* foo =
- test::GetValue<BinaryPrimitive>(&final_table, "com.app.a:bool/foo");
- ASSERT_NE(nullptr, foo);
- EXPECT_EQ(0x0u, foo->value.data);
+ BinaryPrimitive* foo = test::GetValue<BinaryPrimitive>(&final_table, "com.app.a:bool/foo");
+ ASSERT_THAT(foo,
+ Pointee(Field(&BinaryPrimitive::value, Field(&android::Res_value::data, Eq(0u)))));
}
TEST_F(TableMergerTest, OverrideSameResourceIdsWithOverlay) {
@@ -248,18 +246,18 @@ TEST_F(TableMergerTest, FailToOverrideConflictingEntryIdsWithOverlay) {
TEST_F(TableMergerTest, MergeAddResourceFromOverlay) {
std::unique_ptr<ResourceTable> table_a =
- test::ResourceTableBuilder()
- .SetPackageId("", 0x7f)
- .SetSymbolState("bool/foo", {}, SymbolState::kUndefined)
- .Build();
+ test::ResourceTableBuilder().SetPackageId("", 0x7f).Build();
std::unique_ptr<ResourceTable> table_b =
test::ResourceTableBuilder()
.SetPackageId("", 0x7f)
+ .SetSymbolState("bool/foo", {}, SymbolState::kUndefined, true /*allow new overlay*/)
.AddValue("bool/foo", ResourceUtils::TryParseBool("true"))
.Build();
ResourceTable final_table;
- TableMerger merger(context_.get(), &final_table, TableMergerOptions{});
+ TableMergerOptions options;
+ options.auto_add_overlay = false;
+ TableMerger merger(context_.get(), &final_table, options);
ASSERT_TRUE(merger.Merge({}, table_a.get()));
ASSERT_TRUE(merger.MergeOverlay({}, table_b.get()));
@@ -301,7 +299,7 @@ TEST_F(TableMergerTest, FailToMergeNewResourceWithoutAutoAddOverlay) {
ASSERT_FALSE(merger.MergeOverlay({}, table_b.get()));
}
-TEST_F(TableMergerTest, OverlaidStyleablesShouldBeMerged) {
+TEST_F(TableMergerTest, OverlaidStyleablesAndStylesShouldBeMerged) {
std::unique_ptr<ResourceTable> table_a =
test::ResourceTableBuilder()
.SetPackageId("com.app.a", 0x7f)
@@ -310,15 +308,27 @@ TEST_F(TableMergerTest, OverlaidStyleablesShouldBeMerged) {
.AddItem("com.app.a:attr/bar")
.AddItem("com.app.a:attr/foo", ResourceId(0x01010000))
.Build())
+ .AddValue("com.app.a:style/Theme",
+ test::StyleBuilder()
+ .SetParent("com.app.a:style/Parent")
+ .AddItem("com.app.a:attr/bar", util::make_unique<Id>())
+ .AddItem("com.app.a:attr/foo", ResourceUtils::MakeBool(false))
+ .Build())
.Build();
std::unique_ptr<ResourceTable> table_b =
test::ResourceTableBuilder()
.SetPackageId("com.app.a", 0x7f)
- .AddValue("com.app.a:styleable/Foo",
- test::StyleableBuilder()
- .AddItem("com.app.a:attr/bat")
- .AddItem("com.app.a:attr/foo")
+ .AddValue("com.app.a:styleable/Foo", test::StyleableBuilder()
+ .AddItem("com.app.a:attr/bat")
+ .AddItem("com.app.a:attr/foo")
+ .Build())
+ .AddValue("com.app.a:style/Theme",
+ test::StyleBuilder()
+ .SetParent("com.app.a:style/OverlayParent")
+ .AddItem("com.app.a:attr/bat", util::make_unique<Id>())
+ .AddItem("com.app.a:attr/foo", ResourceId(0x01010000),
+ ResourceUtils::MakeBool(true))
.Build())
.Build();
@@ -330,18 +340,29 @@ TEST_F(TableMergerTest, OverlaidStyleablesShouldBeMerged) {
ASSERT_TRUE(merger.Merge({}, table_a.get()));
ASSERT_TRUE(merger.MergeOverlay({}, table_b.get()));
- Styleable* styleable =
- test::GetValue<Styleable>(&final_table, "com.app.a:styleable/Foo");
- ASSERT_NE(nullptr, styleable);
+ Styleable* styleable = test::GetValue<Styleable>(&final_table, "com.app.a:styleable/Foo");
+ ASSERT_THAT(styleable, NotNull());
std::vector<Reference> expected_refs = {
Reference(test::ParseNameOrDie("com.app.a:attr/bar")),
Reference(test::ParseNameOrDie("com.app.a:attr/bat")),
- Reference(test::ParseNameOrDie("com.app.a:attr/foo"),
- ResourceId(0x01010000)),
+ Reference(test::ParseNameOrDie("com.app.a:attr/foo"), ResourceId(0x01010000)),
};
+ EXPECT_THAT(styleable->entries, UnorderedElementsAreArray(expected_refs));
+
+ Style* style = test::GetValue<Style>(&final_table, "com.app.a:style/Theme");
+ ASSERT_THAT(style, NotNull());
+
+ std::vector<Reference> extracted_refs;
+ for (const auto& entry : style->entries) {
+ extracted_refs.push_back(entry.key);
+ }
+ EXPECT_THAT(extracted_refs, UnorderedElementsAreArray(expected_refs));
- EXPECT_EQ(expected_refs, styleable->entries);
+ const auto expected = ResourceUtils::MakeBool(true);
+ EXPECT_THAT(style->entries, Contains(Field(&Style::Entry::value, Pointee(ValueEq(*expected)))));
+ EXPECT_THAT(style->parent,
+ Eq(make_value(Reference(test::ParseNameOrDie("com.app.a:style/OverlayParent")))));
}
} // namespace aapt
diff --git a/tools/aapt2/proto/TableProtoDeserializer.cpp b/tools/aapt2/proto/TableProtoDeserializer.cpp
index d93d495b106f..1d0041b2ac5a 100644
--- a/tools/aapt2/proto/TableProtoDeserializer.cpp
+++ b/tools/aapt2/proto/TableProtoDeserializer.cpp
@@ -32,8 +32,7 @@ class ReferenceIdToNameVisitor : public ValueVisitor {
public:
using ValueVisitor::Visit;
- explicit ReferenceIdToNameVisitor(
- const std::map<ResourceId, ResourceNameRef>* mapping)
+ explicit ReferenceIdToNameVisitor(const std::map<ResourceId, ResourceNameRef>* mapping)
: mapping_(mapping) {
CHECK(mapping_ != nullptr);
}
@@ -75,13 +74,11 @@ class PackagePbDeserializer {
std::map<ResourceId, ResourceNameRef> idIndex;
- ResourceTablePackage* pkg =
- table->CreatePackage(pbPackage.package_name(), id);
+ ResourceTablePackage* pkg = table->CreatePackage(pbPackage.package_name(), id);
for (const pb::Type& pbType : pbPackage.types()) {
const ResourceType* resType = ParseResourceType(pbType.name());
if (!resType) {
- diag_->Error(DiagMessage(source_) << "unknown type '" << pbType.name()
- << "'");
+ diag_->Error(DiagMessage(source_) << "unknown type '" << pbType.name() << "'");
return {};
}
@@ -95,21 +92,20 @@ class PackagePbDeserializer {
if (pbEntry.has_symbol_status()) {
const pb::SymbolStatus& pbStatus = pbEntry.symbol_status();
if (pbStatus.has_source()) {
- DeserializeSourceFromPb(pbStatus.source(), *source_pool_,
- &entry->symbol_status.source);
+ DeserializeSourceFromPb(pbStatus.source(), *source_pool_, &entry->symbol_status.source);
}
if (pbStatus.has_comment()) {
entry->symbol_status.comment = pbStatus.comment();
}
- SymbolState visibility =
- DeserializeVisibilityFromPb(pbStatus.visibility());
+ entry->symbol_status.allow_new = pbStatus.allow_new();
+
+ SymbolState visibility = DeserializeVisibilityFromPb(pbStatus.visibility());
entry->symbol_status.state = visibility;
if (visibility == SymbolState::kPublic) {
- // This is a public symbol, we must encode the ID now if there is
- // one.
+ // This is a public symbol, we must encode the ID now if there is one.
if (pbEntry.has_id()) {
entry->id = static_cast<uint16_t>(pbEntry.id());
}
@@ -142,16 +138,15 @@ class PackagePbDeserializer {
return {};
}
- ResourceConfigValue* configValue =
- entry->FindOrCreateValue(config, pbConfig.product());
+ ResourceConfigValue* configValue = entry->FindOrCreateValue(config, pbConfig.product());
if (configValue->value) {
// Duplicate config.
diag_->Error(DiagMessage(source_) << "duplicate configuration");
return {};
}
- configValue->value = DeserializeValueFromPb(
- pbConfigValue.value(), config, &table->string_pool);
+ configValue->value =
+ DeserializeValueFromPb(pbConfigValue.value(), config, &table->string_pool);
if (!configValue->value) {
return {};
}
diff --git a/tools/aapt2/proto/TableProtoSerializer.cpp b/tools/aapt2/proto/TableProtoSerializer.cpp
index 7230b55e10e3..de10bb80bf7e 100644
--- a/tools/aapt2/proto/TableProtoSerializer.cpp
+++ b/tools/aapt2/proto/TableProtoSerializer.cpp
@@ -250,19 +250,16 @@ std::unique_ptr<pb::ResourceTable> SerializeTableToPb(ResourceTable* table) {
// Write the SymbolStatus struct.
pb::SymbolStatus* pb_status = pb_entry->mutable_symbol_status();
- pb_status->set_visibility(
- SerializeVisibilityToPb(entry->symbol_status.state));
- SerializeSourceToPb(entry->symbol_status.source, &source_pool,
- pb_status->mutable_source());
+ pb_status->set_visibility(SerializeVisibilityToPb(entry->symbol_status.state));
+ SerializeSourceToPb(entry->symbol_status.source, &source_pool, pb_status->mutable_source());
pb_status->set_comment(entry->symbol_status.comment);
+ pb_status->set_allow_new(entry->symbol_status.allow_new);
for (auto& config_value : entry->values) {
pb::ConfigValue* pb_config_value = pb_entry->add_config_values();
- SerializeConfig(config_value->config,
- pb_config_value->mutable_config());
+ SerializeConfig(config_value->config, pb_config_value->mutable_config());
if (!config_value->product.empty()) {
- pb_config_value->mutable_config()->set_product(
- config_value->product);
+ pb_config_value->mutable_config()->set_product(config_value->product);
}
pb::Value* pb_value = pb_config_value->mutable_value();
diff --git a/tools/aapt2/proto/TableProtoSerializer_test.cpp b/tools/aapt2/proto/TableProtoSerializer_test.cpp
index fdd5197167ef..e6ce6d37b879 100644
--- a/tools/aapt2/proto/TableProtoSerializer_test.cpp
+++ b/tools/aapt2/proto/TableProtoSerializer_test.cpp
@@ -28,12 +28,11 @@ TEST(TableProtoSerializer, SerializeSinglePackage) {
std::unique_ptr<ResourceTable> table =
test::ResourceTableBuilder()
.SetPackageId("com.app.a", 0x7f)
- .AddFileReference("com.app.a:layout/main", ResourceId(0x7f020000),
- "res/layout/main.xml")
- .AddReference("com.app.a:layout/other", ResourceId(0x7f020001),
- "com.app.a:layout/main")
+ .AddFileReference("com.app.a:layout/main", ResourceId(0x7f020000), "res/layout/main.xml")
+ .AddReference("com.app.a:layout/other", ResourceId(0x7f020001), "com.app.a:layout/main")
.AddString("com.app.a:string/text", {}, "hi")
.AddValue("com.app.a:id/foo", {}, util::make_unique<Id>())
+ .SetSymbolState("com.app.a:bool/foo", {}, SymbolState::kUndefined, true /*allow_new*/)
.Build();
Symbol public_symbol;
@@ -94,21 +93,23 @@ TEST(TableProtoSerializer, SerializeSinglePackage) {
EXPECT_EQ(SymbolState::kPublic, result.value().type->symbol_status.state);
EXPECT_EQ(SymbolState::kPublic, result.value().entry->symbol_status.state);
+ result = new_table->FindResource(test::ParseNameOrDie("com.app.a:bool/foo"));
+ ASSERT_TRUE(result);
+ EXPECT_EQ(SymbolState::kUndefined, result.value().entry->symbol_status.state);
+ EXPECT_TRUE(result.value().entry->symbol_status.allow_new);
+
// Find the product-dependent values
BinaryPrimitive* prim = test::GetValueForConfigAndProduct<BinaryPrimitive>(
- new_table.get(), "com.app.a:integer/one", test::ParseConfigOrDie("land"),
- "");
+ new_table.get(), "com.app.a:integer/one", test::ParseConfigOrDie("land"), "");
ASSERT_NE(nullptr, prim);
EXPECT_EQ(123u, prim->value.data);
prim = test::GetValueForConfigAndProduct<BinaryPrimitive>(
- new_table.get(), "com.app.a:integer/one", test::ParseConfigOrDie("land"),
- "tablet");
+ new_table.get(), "com.app.a:integer/one", test::ParseConfigOrDie("land"), "tablet");
ASSERT_NE(nullptr, prim);
EXPECT_EQ(321u, prim->value.data);
- Reference* actual_ref =
- test::GetValue<Reference>(new_table.get(), "com.app.a:layout/abc");
+ Reference* actual_ref = test::GetValue<Reference>(new_table.get(), "com.app.a:layout/abc");
ASSERT_NE(nullptr, actual_ref);
AAPT_ASSERT_TRUE(actual_ref->name);
AAPT_ASSERT_TRUE(actual_ref->id);
diff --git a/tools/aapt2/readme.md b/tools/aapt2/readme.md
index ac09b5933ef6..0290e30dfced 100644
--- a/tools/aapt2/readme.md
+++ b/tools/aapt2/readme.md
@@ -3,6 +3,7 @@
## Version 2.17
### `aapt2 compile ...`
- Fixed an issue where symlinks would not be followed when compiling PNGs. (bug 62144459)
+- Fixed issue where overlays that declared `<add-resource>` did not compile. (bug 38355988)
## Version 2.16
### `aapt2 link ...`
diff --git a/tools/aapt2/test/Builders.h b/tools/aapt2/test/Builders.h
index 6888cf32fab8..02acedbd8ac5 100644
--- a/tools/aapt2/test/Builders.h
+++ b/tools/aapt2/test/Builders.h
@@ -117,12 +117,12 @@ class ResourceTableBuilder {
}
ResourceTableBuilder& SetSymbolState(const android::StringPiece& name, const ResourceId& id,
- SymbolState state) {
+ SymbolState state, bool allow_new = false) {
ResourceName res_name = ParseNameOrDie(name);
Symbol symbol;
symbol.state = state;
- CHECK(table_->SetSymbolStateAllowMangled(res_name, id, symbol,
- &diagnostics_));
+ symbol.allow_new = allow_new;
+ CHECK(table_->SetSymbolStateAllowMangled(res_name, id, symbol, &diagnostics_));
return *this;
}
diff --git a/tools/aapt2/test/Common.h b/tools/aapt2/test/Common.h
index 248921f3afea..a937de8869a6 100644
--- a/tools/aapt2/test/Common.h
+++ b/tools/aapt2/test/Common.h
@@ -22,12 +22,14 @@
#include "android-base/logging.h"
#include "android-base/macros.h"
#include "androidfw/StringPiece.h"
+#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "ConfigDescription.h"
#include "Debug.h"
#include "ResourceTable.h"
#include "ResourceUtils.h"
+#include "ResourceValues.h"
#include "ValueVisitor.h"
#include "io/File.h"
#include "process/IResourceTableConsumer.h"
@@ -51,13 +53,11 @@ struct DummyDiagnosticsImpl : public IDiagnostics {
return;
case Level::Warn:
- std::cerr << actual_msg.source << ": warn: " << actual_msg.message
- << "." << std::endl;
+ std::cerr << actual_msg.source << ": warn: " << actual_msg.message << "." << std::endl;
break;
case Level::Error:
- std::cerr << actual_msg.source << ": error: " << actual_msg.message
- << "." << std::endl;
+ std::cerr << actual_msg.source << ": error: " << actual_msg.message << "." << std::endl;
break;
}
}
@@ -84,11 +84,9 @@ template <typename T>
T* GetValueForConfigAndProduct(ResourceTable* table, const android::StringPiece& res_name,
const ConfigDescription& config,
const android::StringPiece& product) {
- Maybe<ResourceTable::SearchResult> result =
- table->FindResource(ParseNameOrDie(res_name));
+ Maybe<ResourceTable::SearchResult> result = table->FindResource(ParseNameOrDie(res_name));
if (result) {
- ResourceConfigValue* config_value =
- result.value().entry->FindValue(config, product);
+ ResourceConfigValue* config_value = result.value().entry->FindValue(config, product);
if (config_value) {
return ValueCast<T>(config_value->value.get());
}
@@ -111,9 +109,13 @@ class TestFile : public io::IFile {
public:
explicit TestFile(const android::StringPiece& path) : source_(path) {}
- std::unique_ptr<io::IData> OpenAsData() override { return {}; }
+ std::unique_ptr<io::IData> OpenAsData() override {
+ return {};
+ }
- const Source& GetSource() const override { return source_; }
+ const Source& GetSource() const override {
+ return source_;
+ }
private:
DISALLOW_COPY_AND_ASSIGN(TestFile);
@@ -122,6 +124,47 @@ class TestFile : public io::IFile {
};
} // namespace test
+
+// Workaround gtest bug (https://github.com/google/googletest/issues/443)
+// that does not select base class operator<< for derived class T.
+template <typename T>
+typename std::enable_if<std::is_base_of<Value, T>::value, std::ostream&>::type operator<<(
+ std::ostream& out, const T& value) {
+ value.Print(&out);
+ return out;
+}
+
+template std::ostream& operator<<<Item>(std::ostream&, const Item&);
+template std::ostream& operator<<<Reference>(std::ostream&, const Reference&);
+template std::ostream& operator<<<Id>(std::ostream&, const Id&);
+template std::ostream& operator<<<RawString>(std::ostream&, const RawString&);
+template std::ostream& operator<<<String>(std::ostream&, const String&);
+template std::ostream& operator<<<StyledString>(std::ostream&, const StyledString&);
+template std::ostream& operator<<<FileReference>(std::ostream&, const FileReference&);
+template std::ostream& operator<<<BinaryPrimitive>(std::ostream&, const BinaryPrimitive&);
+template std::ostream& operator<<<Attribute>(std::ostream&, const Attribute&);
+template std::ostream& operator<<<Style>(std::ostream&, const Style&);
+template std::ostream& operator<<<Array>(std::ostream&, const Array&);
+template std::ostream& operator<<<Plural>(std::ostream&, const Plural&);
+
+// Add a print method to Maybe.
+template <typename T>
+void PrintTo(const Maybe<T>& value, std::ostream* out) {
+ if (value) {
+ *out << ::testing::PrintToString(value.value());
+ } else {
+ *out << "Nothing";
+ }
+}
+
+namespace test {
+
+MATCHER_P(ValueEq, a,
+ std::string(negation ? "isn't" : "is") + " equal to " + ::testing::PrintToString(a)) {
+ return arg.Equals(&a);
+}
+
+} // namespace test
} // namespace aapt
#endif /* AAPT_TEST_COMMON_H */
diff --git a/tools/aapt2/test/Test.h b/tools/aapt2/test/Test.h
index ec07432fa51e..a24c01cd4137 100644
--- a/tools/aapt2/test/Test.h
+++ b/tools/aapt2/test/Test.h
@@ -17,6 +17,7 @@
#ifndef AAPT_TEST_TEST_H
#define AAPT_TEST_TEST_H
+#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "test/Builders.h"
diff --git a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
index 15fd2ceea5fa..deb0e09e6f72 100644
--- a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
+++ b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
@@ -18,6 +18,7 @@ package android.view;
import android.content.res.Configuration;
import android.graphics.Bitmap;
+import android.graphics.GraphicBuffer;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Bundle;
@@ -210,13 +211,13 @@ public class IWindowManagerImpl implements IWindowManager {
}
@Override
- public void overridePendingAppTransitionThumb(Bitmap srcThumb, int startX, int startY,
+ public void overridePendingAppTransitionThumb(GraphicBuffer srcThumb, int startX, int startY,
IRemoteCallback startedCallback, boolean scaleUp) throws RemoteException {
// TODO Auto-generated method stub
}
@Override
- public void overridePendingAppTransitionAspectScaledThumb(Bitmap srcThumb, int startX,
+ public void overridePendingAppTransitionAspectScaledThumb(GraphicBuffer srcThumb, int startX,
int startY, int targetWidth, int targetHeight, IRemoteCallback startedCallback,
boolean scaleUp) {
// TODO Auto-generated method stub
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index cfc1fd252fb3..58df4ee227f2 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -160,6 +160,8 @@ public class WifiManager {
*
* <p>Note: The broadcast is only delivered to registered receivers - no manifest registered
* components will be launched.
+ *
+ * @hide
*/
public static final String ACTION_PASSPOINT_ICON = "android.net.wifi.action.PASSPOINT_ICON";
/**
@@ -167,6 +169,8 @@ public class WifiManager {
* String representation.
*
* Retrieve with {@link android.content.Intent#getLongExtra(String, long)}.
+ *
+ * @hide
*/
public static final String EXTRA_BSSID_LONG = "android.net.wifi.extra.BSSID_LONG";
/**
@@ -174,12 +178,16 @@ public class WifiManager {
*
* Retrieve with {@link android.content.Intent#getParcelableExtra(String)} and cast into
* {@link android.graphics.drawable.Icon}.
+ *
+ * @hide
*/
public static final String EXTRA_ICON = "android.net.wifi.extra.ICON";
/**
* Name of a file.
*
* Retrieve with {@link android.content.Intent#getStringExtra(String)}.
+ *
+ * @hide
*/
public static final String EXTRA_FILENAME = "android.net.wifi.extra.FILENAME";
@@ -195,6 +203,7 @@ public class WifiManager {
* <p>Note: The broadcast is only delivered to registered receivers - no manifest registered
* components will be launched.
*
+ * @hide
*/
public static final String ACTION_PASSPOINT_OSU_PROVIDERS_LIST =
"android.net.wifi.action.PASSPOINT_OSU_PROVIDERS_LIST";
@@ -202,6 +211,8 @@ public class WifiManager {
* Raw binary data of an ANQP (Access Network Query Protocol) element.
*
* Retrieve with {@link android.content.Intent#getByteArrayExtra(String)}.
+ *
+ * @hide
*/
public static final String EXTRA_ANQP_ELEMENT_DATA =
"android.net.wifi.extra.ANQP_ELEMENT_DATA";
@@ -220,6 +231,7 @@ public class WifiManager {
* <p>Note: The broadcast is only delivered to registered receivers - no manifest registered
* components will be launched.
*
+ * @hide
*/
public static final String ACTION_PASSPOINT_DEAUTH_IMMINENT =
"android.net.wifi.action.PASSPOINT_DEAUTH_IMMINENT";
@@ -228,18 +240,24 @@ public class WifiManager {
* {@code true} for ESS.
*
* Retrieve with {@link android.content.Intent#getBooleanExtra(String, boolean)}.
+ *
+ * @hide
*/
public static final String EXTRA_ESS = "android.net.wifi.extra.ESS";
/**
* Delay in seconds.
*
* Retrieve with {@link android.content.Intent#getIntExtra(String, int)}.
+ *
+ * @hide
*/
public static final String EXTRA_DELAY = "android.net.wifi.extra.DELAY";
/**
* String representation of an URL.
*
* Retrieve with {@link android.content.Intent#getStringExtra(String)}.
+ *
+ * @hide
*/
public static final String EXTRA_URL = "android.net.wifi.extra.URL";
@@ -254,8 +272,10 @@ public class WifiManager {
*
* Receiver Required Permission: android.Manifest.permission.ACCESS_WIFI_STATE
*
- ** <p>Note: The broadcast is only delivered to registered receivers - no manifest registered
+ * <p>Note: The broadcast is only delivered to registered receivers - no manifest registered
* components will be launched.
+ *
+ * @hide
*/
public static final String ACTION_PASSPOINT_SUBSCRIPTION_REMEDIATION =
"android.net.wifi.action.PASSPOINT_SUBSCRIPTION_REMEDIATION";
@@ -265,6 +285,8 @@ public class WifiManager {
* 1 - SOAP XML SPP
*
* Retrieve with {@link android.content.Intent#getIntExtra(String, int)}.
+ *
+ * @hide
*/
public static final String EXTRA_SUBSCRIPTION_REMEDIATION_METHOD =
"android.net.wifi.extra.SUBSCRIPTION_REMEDIATION_METHOD";
@@ -1058,11 +1080,9 @@ public class WifiManager {
* Name). In the case when there is an existing configuration with the same
* FQDN, the new configuration will replace the existing configuration.
*
- * An {@link IllegalArgumentException} will be thrown on failure.
- * An {@link UnsupportedOperationException} will be thrown if Passpoint is not enabled
- * on the device.
- *
* @param config The Passpoint configuration to be added
+ * @throws IllegalArgumentException if configuration is invalid
+ * @throws UnsupportedOperationException if Passpoint is not enabled on the device.
*/
public void addOrUpdatePasspointConfiguration(PasspointConfiguration config) {
try {
@@ -1077,11 +1097,9 @@ public class WifiManager {
/**
* Remove the Passpoint configuration identified by its FQDN (Fully Qualified Domain Name).
*
- * An {@link IllegalArgumentException} will be thrown on failure.
- * An {@link UnsupportedOperationException} will be thrown if Passpoint is not enabled
- * on the device.
- *
* @param fqdn The FQDN of the Passpoint configuration to be removed
+ * @throws IllegalArgumentException if no configuration is associated with the given FQDN.
+ * @throws UnsupportedOperationException if Passpoint is not enabled on the device.
*/
public void removePasspointConfiguration(String fqdn) {
try {
@@ -1098,10 +1116,8 @@ public class WifiManager {
*
* An empty list will be returned when no configurations are installed.
*
- * An {@link UnsupportedOperationException} will be thrown if Passpoint is not enabled
- * on the device.
- *
* @return A list of {@link PasspointConfiguration}
+ * @throws UnsupportedOperationException if Passpoint is not enabled on the device.
*/
public List<PasspointConfiguration> getPasspointConfigurations() {
try {
@@ -1117,11 +1133,11 @@ public class WifiManager {
* {@link #EXTRA_ICON} will indicate the result of the request.
* A missing intent extra {@link #EXTRA_ICON} will indicate a failure.
*
- * An {@link UnsupportedOperationException} will be thrown if Passpoint is not enabled
- * on the device.
- *
* @param bssid The BSSID of the AP
* @param fileName Name of the icon file (remote file) to query from the AP
+ *
+ * @throws UnsupportedOperationException if Passpoint is not enabled on the device.
+ * @hide
*/
public void queryPasspointIcon(long bssid, String fileName) {
try {
@@ -1778,25 +1794,25 @@ public class WifiManager {
}
/**
- * Start AccessPoint mode with the specified
- * configuration. If the radio is already running in
- * AP mode, update the new configuration
- * Note that starting in access point mode disables station
- * mode operation
+ * This call will be deprecated and removed in an upcoming release. It is no longer used to
+ * start WiFi Tethering. Please use {@link ConnectivityManager#startTethering(int, boolean,
+ * ConnectivityManager#OnStartTetheringCallback)} if
+ * the caller has proper permissions. Callers can also use the LocalOnlyHotspot feature for a
+ * hotspot capable of communicating with co-located devices {@link
+ * WifiManager#startLocalOnlyHotspot(LocalOnlyHotspotCallback)}.
+ *
* @param wifiConfig SSID, security and channel details as
* part of WifiConfiguration
- * @return {@code true} if the operation succeeds, {@code false} otherwise
+ * @return {@code false}
*
* @hide
*/
@SystemApi
public boolean setWifiApEnabled(WifiConfiguration wifiConfig, boolean enabled) {
- try {
- mService.setWifiApEnabled(wifiConfig, enabled);
- return true;
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ String packageName = mContext.getOpPackageName();
+
+ Log.w(TAG, packageName + " attempted call to setWifiApEnabled: enabled = " + enabled);
+ return false;
}
/**
diff --git a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java
index f892bb0a3884..71d4173a389c 100644
--- a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java
+++ b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java
@@ -62,16 +62,36 @@ public final class PasspointConfiguration implements Parcelable {
* Configurations under HomeSp subtree.
*/
private HomeSp mHomeSp = null;
+ /**
+ * Set the Home SP (Service Provider) information.
+ *
+ * @param homeSp The Home SP information to set to
+ */
public void setHomeSp(HomeSp homeSp) { mHomeSp = homeSp; }
+ /**
+ * Get the Home SP (Service Provider) information.
+ *
+ * @return Home SP information
+ */
public HomeSp getHomeSp() { return mHomeSp; }
/**
* Configurations under Credential subtree.
*/
private Credential mCredential = null;
+ /**
+ * Set the credential information.
+ *
+ * @param credential The credential information to set to
+ */
public void setCredential(Credential credential) {
mCredential = credential;
}
+ /**
+ * Get the credential information.
+ *
+ * @return credential information
+ */
public Credential getCredential() {
return mCredential;
}
diff --git a/wifi/java/android/net/wifi/hotspot2/pps/Credential.java b/wifi/java/android/net/wifi/hotspot2/pps/Credential.java
index d712feb7c6d2..e8fcbfd6731e 100644
--- a/wifi/java/android/net/wifi/hotspot2/pps/Credential.java
+++ b/wifi/java/android/net/wifi/hotspot2/pps/Credential.java
@@ -97,9 +97,19 @@ public final class Credential implements Parcelable {
* comparing the realm specified in that hotspot's ANQP element.
*/
private String mRealm = null;
+ /**
+ * Set the realm associated with this credential.
+ *
+ * @param realm The realm to set to
+ */
public void setRealm(String realm) {
mRealm = realm;
}
+ /**
+ * Get the realm associated with this credential.
+ *
+ * @return the realm associated with this credential
+ */
public String getRealm() {
return mRealm;
}
@@ -162,9 +172,19 @@ public final class Credential implements Parcelable {
* Username of the credential.
*/
private String mUsername = null;
+ /**
+ * Set the username associated with this user credential.
+ *
+ * @param username The username to set to
+ */
public void setUsername(String username) {
mUsername = username;
}
+ /**
+ * Get the username associated with this user credential.
+ *
+ * @return the username associated with this user credential
+ */
public String getUsername() {
return mUsername;
}
@@ -173,9 +193,19 @@ public final class Credential implements Parcelable {
* Base64-encoded password.
*/
private String mPassword = null;
+ /**
+ * Set the Base64-encoded password associated with this user credential.
+ *
+ * @param password The password to set to
+ */
public void setPassword(String password) {
mPassword = password;
}
+ /**
+ * Get the Base64-encoded password associated with this user credential.
+ *
+ * @return the Base64-encoded password associated with this user credential
+ */
public String getPassword() {
return mPassword;
}
@@ -233,14 +263,30 @@ public final class Credential implements Parcelable {
/**
* EAP (Extensible Authentication Protocol) method type.
- * Refer to http://www.iana.org/assignments/eap-numbers/eap-numbers.xml#eap-numbers-4
- * for valid values.
+ * Refer to
+ * <a href="http://www.iana.org/assignments/eap-numbers/eap-numbers.xml#eap-numbers-4">
+ * EAP Numbers</a> for valid values.
* Using Integer.MIN_VALUE to indicate unset value.
*/
private int mEapType = Integer.MIN_VALUE;
+ /**
+ * Set the EAP (Extensible Authentication Protocol) method type associated with this
+ * user credential.
+ * Refer to
+ * <a href="http://www.iana.org/assignments/eap-numbers/eap-numbers.xml#eap-numbers-4">
+ * EAP Numbers</a> for valid values.
+ *
+ * @param eapType The EAP method type associated with this user credential
+ */
public void setEapType(int eapType) {
mEapType = eapType;
}
+ /**
+ * Get the EAP (Extensible Authentication Protocol) method type associated with this
+ * user credential.
+ *
+ * @return EAP method type
+ */
public int getEapType() {
return mEapType;
}
@@ -249,9 +295,19 @@ public final class Credential implements Parcelable {
* Non-EAP inner authentication method.
*/
private String mNonEapInnerMethod = null;
+ /**
+ * Set the inner non-EAP method associated with this user credential.
+ *
+ * @param nonEapInnerMethod The non-EAP inner method to set to
+ */
public void setNonEapInnerMethod(String nonEapInnerMethod) {
mNonEapInnerMethod = nonEapInnerMethod;
}
+ /**
+ * Get the inner non-EAP method associated with this user credential.
+ *
+ * @return Non-EAP inner method associated with this user credential
+ */
public String getNonEapInnerMethod() {
return mNonEapInnerMethod;
}
@@ -394,9 +450,19 @@ public final class Credential implements Parcelable {
};
}
private UserCredential mUserCredential = null;
+ /**
+ * Set the user credential information.
+ *
+ * @param userCredential The user credential to set to
+ */
public void setUserCredential(UserCredential userCredential) {
mUserCredential = userCredential;
}
+ /**
+ * Get the user credential information.
+ *
+ * @return user credential information
+ */
public UserCredential getUserCredential() {
return mUserCredential;
}
@@ -421,9 +487,19 @@ public final class Credential implements Parcelable {
* Certificate type.
*/
private String mCertType = null;
+ /**
+ * Set the certificate type associated with this certificate credential.
+ *
+ * @param certType The certificate type to set to
+ */
public void setCertType(String certType) {
mCertType = certType;
}
+ /**
+ * Get the certificate type associated with this certificate credential.
+ *
+ * @return certificate type
+ */
public String getCertType() {
return mCertType;
}
@@ -432,9 +508,19 @@ public final class Credential implements Parcelable {
* The SHA-256 fingerprint of the certificate.
*/
private byte[] mCertSha256Fingerprint = null;
+ /**
+ * Set the certificate SHA-256 fingerprint associated with this certificate credential.
+ *
+ * @param certSha256Fingerprint The certificate fingerprint to set to
+ */
public void setCertSha256Fingerprint(byte[] certSha256Fingerprint) {
mCertSha256Fingerprint = certSha256Fingerprint;
}
+ /**
+ * Get the certificate SHA-256 fingerprint associated with this certificate credential.
+ *
+ * @return certificate SHA-256 fingerprint
+ */
public byte[] getCertSha256Fingerprint() {
return mCertSha256Fingerprint;
}
@@ -530,9 +616,19 @@ public final class Credential implements Parcelable {
};
}
private CertificateCredential mCertCredential = null;
+ /**
+ * Set the certificate credential information.
+ *
+ * @param certCredential The certificate credential to set to
+ */
public void setCertCredential(CertificateCredential certCredential) {
mCertCredential = certCredential;
}
+ /**
+ * Get the certificate credential information.
+ *
+ * @return certificate credential information
+ */
public CertificateCredential getCertCredential() {
return mCertCredential;
}
@@ -553,9 +649,21 @@ public final class Credential implements Parcelable {
* cellular networks
*/
private String mImsi = null;
+ /**
+ * Set the IMSI (International Mobile Subscriber Identity) associated with this SIM
+ * credential.
+ *
+ * @param imsi The IMSI to set to
+ */
public void setImsi(String imsi) {
mImsi = imsi;
}
+ /**
+ * Get the IMSI (International Mobile Subscriber Identity) associated with this SIM
+ * credential.
+ *
+ * @return IMSI associated with this SIM credential
+ */
public String getImsi() {
return mImsi;
}
@@ -567,9 +675,21 @@ public final class Credential implements Parcelable {
* Using Integer.MIN_VALUE to indicate unset value.
*/
private int mEapType = Integer.MIN_VALUE;
+ /**
+ * Set the EAP (Extensible Authentication Protocol) method type associated with this
+ * SIM credential.
+ *
+ * @param eapType The EAP method type to set to
+ */
public void setEapType(int eapType) {
mEapType = eapType;
}
+ /**
+ * Get the EAP (Extensible Authentication Protocol) method type associated with this
+ * SIM credential.
+ *
+ * @return EAP method type associated with this SIM credential
+ */
public int getEapType() {
return mEapType;
}
@@ -704,9 +824,19 @@ public final class Credential implements Parcelable {
}
}
private SimCredential mSimCredential = null;
+ /**
+ * Set the SIM credential information.
+ *
+ * @param simCredential The SIM credential to set to
+ */
public void setSimCredential(SimCredential simCredential) {
mSimCredential = simCredential;
}
+ /**
+ * Get the SIM credential information.
+ *
+ * @return SIM credential information
+ */
public SimCredential getSimCredential() {
return mSimCredential;
}
@@ -715,9 +845,19 @@ public final class Credential implements Parcelable {
* CA (Certificate Authority) X509 certificate.
*/
private X509Certificate mCaCertificate = null;
+ /**
+ * Set the CA (Certification Authority) certificate associated with this credential.
+ *
+ * @param caCertificate The CA certificate to set to
+ */
public void setCaCertificate(X509Certificate caCertificate) {
mCaCertificate = caCertificate;
}
+ /**
+ * Get the CA (Certification Authority) certificate associated with this credential.
+ *
+ * @return CA certificate associated with this credential
+ */
public X509Certificate getCaCertificate() {
return mCaCertificate;
}
@@ -726,9 +866,19 @@ public final class Credential implements Parcelable {
* Client side X509 certificate chain.
*/
private X509Certificate[] mClientCertificateChain = null;
+ /**
+ * Set the client certificate chain associated with this credential.
+ *
+ * @param certificateChain The client certificate chain to set to
+ */
public void setClientCertificateChain(X509Certificate[] certificateChain) {
mClientCertificateChain = certificateChain;
}
+ /**
+ * Get the client certificate chain associated with this credential.
+ *
+ * @return client certificate chain associated with this credential
+ */
public X509Certificate[] getClientCertificateChain() {
return mClientCertificateChain;
}
@@ -737,9 +887,19 @@ public final class Credential implements Parcelable {
* Client side private key.
*/
private PrivateKey mClientPrivateKey = null;
+ /**
+ * Set the client private key associated with this credential.
+ *
+ * @param clientPrivateKey the client private key to set to
+ */
public void setClientPrivateKey(PrivateKey clientPrivateKey) {
mClientPrivateKey = clientPrivateKey;
}
+ /**
+ * Get the client private key associated with this credential.
+ *
+ * @return client private key associated with this credential.
+ */
public PrivateKey getClientPrivateKey() {
return mClientPrivateKey;
}
diff --git a/wifi/java/android/net/wifi/hotspot2/pps/HomeSp.java b/wifi/java/android/net/wifi/hotspot2/pps/HomeSp.java
index 2247860d23a5..d829ea81ed56 100644
--- a/wifi/java/android/net/wifi/hotspot2/pps/HomeSp.java
+++ b/wifi/java/android/net/wifi/hotspot2/pps/HomeSp.java
@@ -52,9 +52,19 @@ public final class HomeSp implements Parcelable {
* FQDN (Fully Qualified Domain Name) of this home service provider.
*/
private String mFqdn = null;
+ /**
+ * Set the FQDN (Fully Qualified Domain Name) associated with this home service provider.
+ *
+ * @param fqdn The FQDN to set to
+ */
public void setFqdn(String fqdn) {
mFqdn = fqdn;
}
+ /**
+ * Get the FQDN (Fully Qualified Domain Name) associated with this home service provider.
+ *
+ * @return the FQDN associated with this home service provider
+ */
public String getFqdn() {
return mFqdn;
}
@@ -63,9 +73,19 @@ public final class HomeSp implements Parcelable {
* Friendly name of this home service provider.
*/
private String mFriendlyName = null;
+ /**
+ * Set the friendly name associated with this home service provider.
+ *
+ * @param friendlyName The friendly name to set to
+ */
public void setFriendlyName(String friendlyName) {
mFriendlyName = friendlyName;
}
+ /**
+ * Get the friendly name associated with this home service provider.
+ *
+ * @return the friendly name associated with this home service provider
+ */
public String getFriendlyName() {
return mFriendlyName;
}
@@ -184,9 +204,21 @@ public final class HomeSp implements Parcelable {
* which this provider is a member.
*/
private long[] mRoamingConsortiumOis = null;
+ /**
+ * Set the Organization Identifiers (OIs) identifying a roaming consortium of which this
+ * provider is a member.
+ *
+ * @param roamingConsortiumOis Array of roaming consortium OIs
+ */
public void setRoamingConsortiumOis(long[] roamingConsortiumOis) {
mRoamingConsortiumOis = roamingConsortiumOis;
}
+ /**
+ * Get the Organization Identifiers (OIs) identifying a roaming consortium of which this
+ * provider is a member.
+ *
+ * @return array of roaming consortium OIs
+ */
public long[] getRoamingConsortiumOis() {
return mRoamingConsortiumOis;
}
diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
index 84ac1183c897..b235ccc7a89e 100644
--- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
@@ -778,4 +778,13 @@ public class WifiManagerTest {
verify(mWifiService).stopWatchLocalOnlyHotspot();
}
+ /**
+ * Verify that calls to setWifiApEnabled return false.
+ */
+ @Test
+ public void testSetWifiApEnabledReturnsFalse() throws Exception {
+ assertFalse(mWifiManager.setWifiApEnabled(null, true));
+ assertFalse(mWifiManager.setWifiApEnabled(null, false));
+ verify(mWifiService, never()).setWifiApEnabled(any(), anyBoolean());
+ }
}