summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xAndroid.bp2
-rw-r--r--ApiDocs.bp10
-rw-r--r--StubLibraries.bp2
-rw-r--r--apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java5
-rw-r--r--apex/jobscheduler/service/java/com/android/server/alarm/MetricsHelper.java6
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java18
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java45
-rw-r--r--core/api/test-current.txt1
-rw-r--r--core/java/android/app/ActivityThread.java28
-rw-r--r--core/java/android/app/ContextImpl.java3
-rw-r--r--core/java/android/app/Notification.java34
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java10
-rw-r--r--core/java/android/appwidget/AppWidgetManagerInternal.java14
-rw-r--r--core/java/android/bluetooth/BluetoothA2dp.java4
-rw-r--r--core/java/android/bluetooth/le/ScanFilter.java25
-rw-r--r--core/java/android/content/pm/PackageParserCacheHelper.java3
-rw-r--r--core/java/android/hardware/ISensorPrivacyManager.aidl4
-rw-r--r--core/java/android/hardware/SensorPrivacyManager.java33
-rw-r--r--core/java/android/hardware/camera2/CaptureRequest.java60
-rw-r--r--core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java12
-rw-r--r--core/java/android/hardware/camera2/impl/CameraDeviceImpl.java10
-rw-r--r--core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java50
-rw-r--r--core/java/android/hardware/camera2/impl/CameraExtensionUtils.java32
-rw-r--r--core/java/android/hardware/camera2/impl/CameraMetadataNative.java65
-rw-r--r--core/java/android/hardware/camera2/utils/SurfaceUtils.java14
-rw-r--r--core/java/android/hardware/face/FaceManager.java31
-rw-r--r--core/java/android/hardware/face/IFaceService.aidl2
-rw-r--r--core/java/android/os/FileUtils.java18
-rw-r--r--core/java/android/os/Process.java42
-rw-r--r--core/java/android/os/Trace.java2
-rw-r--r--core/java/android/permission/IPermissionManager.aidl6
-rw-r--r--core/java/android/permission/PermissionManager.java4
-rw-r--r--core/java/android/service/voice/HotwordDetectionService.java7
-rw-r--r--core/java/android/service/voice/SoftwareHotwordDetector.java2
-rw-r--r--core/java/android/service/wallpaper/WallpaperService.java9
-rw-r--r--core/java/android/view/SurfaceControl.java13
-rw-r--r--core/java/android/view/inputmethod/InputConnection.java6
-rw-r--r--core/java/android/widget/RemoteViews.java19
-rw-r--r--core/java/android/window/SplashScreenView.java83
-rw-r--r--core/java/android/window/StartingWindowInfo.java12
-rw-r--r--core/java/com/android/internal/app/AbstractResolverComparator.java26
-rw-r--r--core/java/com/android/internal/app/ChooserActivity.java12
-rw-r--r--core/java/com/android/internal/app/ResolverActivity.java32
-rw-r--r--core/java/com/android/internal/infra/AndroidFuture.java12
-rw-r--r--core/java/com/android/internal/os/BinderCallsStats.java5
-rw-r--r--core/java/com/android/internal/os/ProcLocksReader.java89
-rw-r--r--core/java/com/android/internal/util/ProcFileReader.java43
-rw-r--r--core/jni/android_view_SurfaceControl.cpp10
-rw-r--r--core/res/AndroidManifest.xml6
-rw-r--r--core/res/res/drawable/chooser_row_layer_list.xml6
-rw-r--r--core/res/res/layout/chooser_az_label_row.xml11
-rw-r--r--core/res/res/layout/splash_screen_view.xml3
-rw-r--r--core/res/res/values-ar/strings.xml2
-rw-r--r--core/res/res/values-be/strings.xml4
-rw-r--r--core/res/res/values-de/strings.xml2
-rw-r--r--core/res/res/values-en-rAU/strings.xml10
-rw-r--r--core/res/res/values-en-rCA/strings.xml10
-rw-r--r--core/res/res/values-en-rGB/strings.xml10
-rw-r--r--core/res/res/values-en-rIN/strings.xml10
-rw-r--r--core/res/res/values-es/strings.xml4
-rw-r--r--core/res/res/values-gu/strings.xml32
-rw-r--r--core/res/res/values-ne/strings.xml2
-rw-r--r--core/res/res/values-night/colors.xml3
-rw-r--r--core/res/res/values-sl/strings.xml20
-rw-r--r--core/res/res/values-sq/strings.xml8
-rw-r--r--core/res/res/values-sv/strings.xml22
-rw-r--r--core/res/res/values-te/strings.xml6
-rw-r--r--core/tests/coretests/src/com/android/internal/os/ProcLocksReaderTest.java90
-rw-r--r--core/tests/utiltests/src/com/android/internal/util/ProcFileReaderTest.java40
-rw-r--r--graphics/java/android/graphics/drawable/RippleAnimationSession.java13
-rw-r--r--graphics/java/android/graphics/drawable/RippleDrawable.java12
-rw-r--r--libs/WindowManager/Shell/res/values-ky/strings.xml2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedAnimationCallback.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedAnimationController.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizer.java268
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java11
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java8
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedSettingsUtil.java23
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTutorialHandler.java83
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java23
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java144
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenIconDrawableFactory.java160
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java10
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizerTest.java29
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java2
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedStateTest.java2
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTutorialHandlerTest.java2
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java1
-rw-r--r--media/java/android/media/ExifInterface.java9
-rw-r--r--media/java/android/media/MediaMetadataRetriever.java17
-rw-r--r--media/java/android/media/MediaPlayer.java13
-rw-r--r--media/java/android/media/MediaRouter2Manager.java3
-rw-r--r--media/java/android/media/metrics/PlaybackErrorEvent.java2
-rw-r--r--media/java/android/media/metrics/PlaybackMetrics.java4
-rw-r--r--native/android/performance_hint.cpp3
-rw-r--r--packages/EasterEgg/AndroidManifest.xml100
-rw-r--r--packages/EasterEgg/build.gradle8
-rw-r--r--packages/EasterEgg/gradle.properties2
-rw-r--r--packages/EasterEgg/res/drawable/android_s.xml23
-rw-r--r--packages/EasterEgg/res/drawable/icon.xml2
-rw-r--r--packages/EasterEgg/res/drawable/icon_bg.xml2
-rw-r--r--packages/EasterEgg/res/drawable/roundrect.xml7
-rw-r--r--packages/EasterEgg/res/layout/paint_chip.xml29
-rw-r--r--packages/EasterEgg/res/layout/paint_chips_grid.xml25
-rw-r--r--packages/EasterEgg/res/layout/paint_chips_widget_preview.xml79
-rw-r--r--packages/EasterEgg/res/values-night/themes.xml7
-rw-r--r--packages/EasterEgg/res/values/attrs.xml6
-rw-r--r--packages/EasterEgg/res/values/colors.xml7
-rw-r--r--packages/EasterEgg/res/values/dimens.xml9
-rw-r--r--packages/EasterEgg/res/values/strings.xml6
-rw-r--r--packages/EasterEgg/res/values/themes.xml7
-rw-r--r--packages/EasterEgg/res/xml/paint_chips_widget_info.xml24
-rw-r--r--packages/EasterEgg/src/com/android/egg/ComponentActivationActivity.java83
-rw-r--r--packages/EasterEgg/src/com/android/egg/neko/NekoActivationActivity.java66
-rw-r--r--packages/EasterEgg/src/com/android/egg/widget/PaintChipsActivity.kt67
-rw-r--r--packages/EasterEgg/src/com/android/egg/widget/PaintChipsWidget.kt293
-rw-r--r--packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/IllustrationPreference.java28
-rw-r--r--packages/SettingsLib/lint-baseline.xml22
-rw-r--r--packages/SettingsLib/res/values-be/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-gu/strings.xml28
-rw-r--r--packages/SettingsLib/res/values-it/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-ky/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-mn/strings.xml6
-rw-r--r--packages/SettingsLib/res/values-pl/arrays.xml2
-rw-r--r--packages/SettingsLib/res/values-pl/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-sl/strings.xml6
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/enterprise/ActionDisabledByAdminControllerFactory.java9
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/enterprise/ActionDisabledLearnMoreButtonLauncher.java20
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/enterprise/BiometricActionDisabledByAdminController.java4
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/enterprise/ManagedDeviceActionDisabledByAdminController.java75
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/ManagedDeviceActionDisabledByAdminControllerTest.java79
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/IllustrationPreferenceTest.java25
-rw-r--r--packages/SettingsProvider/res/values-gu/strings.xml2
-rw-r--r--packages/Shell/res/values-sl/strings.xml2
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java7
-rw-r--r--packages/SystemUI/res-keyguard/values-en-rAU/strings.xml2
-rw-r--r--packages/SystemUI/res-keyguard/values-en-rCA/strings.xml2
-rw-r--r--packages/SystemUI/res-keyguard/values-en-rGB/strings.xml2
-rw-r--r--packages/SystemUI/res-keyguard/values-en-rIN/strings.xml2
-rw-r--r--packages/SystemUI/res-keyguard/values-sv/strings.xml10
-rw-r--r--packages/SystemUI/res/drawable-nodpi/android_12.xml37
-rw-r--r--packages/SystemUI/res/drawable-nodpi/icon.xml2
-rw-r--r--packages/SystemUI/res/drawable-nodpi/icon_bg.xml2
-rw-r--r--packages/SystemUI/res/drawable/controls_icon.xml25
-rw-r--r--packages/SystemUI/res/drawable/fingerprint_bg.xml3
-rw-r--r--packages/SystemUI/res/drawable/ic_unlock.xml42
-rw-r--r--packages/SystemUI/res/drawable/keyguard_bottom_affordance_bg.xml (renamed from packages/SystemUI/res/drawable/wallet_lockscreen_bg.xml)0
-rwxr-xr-xpackages/SystemUI/res/layout/keyguard_bottom_area.xml20
-rw-r--r--packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml2
-rw-r--r--packages/SystemUI/res/layout/status_bar_expanded.xml20
-rw-r--r--packages/SystemUI/res/layout/udfps_keyguard_view.xml3
-rw-r--r--packages/SystemUI/res/values-af/strings.xml1
-rw-r--r--packages/SystemUI/res/values-af/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-am/strings.xml1
-rw-r--r--packages/SystemUI/res/values-am/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-ar/strings.xml1
-rw-r--r--packages/SystemUI/res/values-ar/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-as/strings.xml1
-rw-r--r--packages/SystemUI/res/values-as/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-az/strings.xml1
-rw-r--r--packages/SystemUI/res/values-az/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-b+sr+Latn/strings.xml1
-rw-r--r--packages/SystemUI/res/values-b+sr+Latn/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-be/strings.xml1
-rw-r--r--packages/SystemUI/res/values-be/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-bg/strings.xml1
-rw-r--r--packages/SystemUI/res/values-bg/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-bn/strings.xml1
-rw-r--r--packages/SystemUI/res/values-bn/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-bs/strings.xml1
-rw-r--r--packages/SystemUI/res/values-bs/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-ca/strings.xml1
-rw-r--r--packages/SystemUI/res/values-ca/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-cs/strings.xml1
-rw-r--r--packages/SystemUI/res/values-cs/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-da/strings.xml1
-rw-r--r--packages/SystemUI/res/values-da/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-de/strings.xml1
-rw-r--r--packages/SystemUI/res/values-de/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-el/strings.xml1
-rw-r--r--packages/SystemUI/res/values-el/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-en-rAU/strings.xml1
-rw-r--r--packages/SystemUI/res/values-en-rAU/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-en-rCA/strings.xml1
-rw-r--r--packages/SystemUI/res/values-en-rCA/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-en-rGB/strings.xml1
-rw-r--r--packages/SystemUI/res/values-en-rGB/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-en-rIN/strings.xml1
-rw-r--r--packages/SystemUI/res/values-en-rIN/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-en-rXC/strings.xml1
-rw-r--r--packages/SystemUI/res/values-en-rXC/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-es-rUS/strings.xml3
-rw-r--r--packages/SystemUI/res/values-es-rUS/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-es/strings.xml1
-rw-r--r--packages/SystemUI/res/values-es/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-et/strings.xml1
-rw-r--r--packages/SystemUI/res/values-et/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-eu/strings.xml1
-rw-r--r--packages/SystemUI/res/values-eu/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-fa/strings.xml1
-rw-r--r--packages/SystemUI/res/values-fa/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-fi/strings.xml1
-rw-r--r--packages/SystemUI/res/values-fi/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-fr-rCA/strings.xml1
-rw-r--r--packages/SystemUI/res/values-fr-rCA/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-fr/strings.xml1
-rw-r--r--packages/SystemUI/res/values-fr/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-gl/strings.xml1
-rw-r--r--packages/SystemUI/res/values-gl/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-gu/strings.xml41
-rw-r--r--packages/SystemUI/res/values-gu/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-hi/strings.xml1
-rw-r--r--packages/SystemUI/res/values-hi/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-hr/strings.xml1
-rw-r--r--packages/SystemUI/res/values-hr/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-hu/strings.xml1
-rw-r--r--packages/SystemUI/res/values-hu/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-hy/strings.xml1
-rw-r--r--packages/SystemUI/res/values-hy/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-in/strings.xml1
-rw-r--r--packages/SystemUI/res/values-in/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-is/strings.xml1
-rw-r--r--packages/SystemUI/res/values-is/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-it/strings.xml1
-rw-r--r--packages/SystemUI/res/values-it/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-iw/strings.xml1
-rw-r--r--packages/SystemUI/res/values-iw/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-ja/strings.xml1
-rw-r--r--packages/SystemUI/res/values-ja/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-ka/strings.xml1
-rw-r--r--packages/SystemUI/res/values-ka/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-kk/strings.xml1
-rw-r--r--packages/SystemUI/res/values-kk/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-km/strings.xml1
-rw-r--r--packages/SystemUI/res/values-km/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-kn/strings.xml1
-rw-r--r--packages/SystemUI/res/values-kn/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-ko/strings.xml3
-rw-r--r--packages/SystemUI/res/values-ko/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-ko/tiles_states_strings.xml4
-rw-r--r--packages/SystemUI/res/values-ky/strings.xml5
-rw-r--r--packages/SystemUI/res/values-ky/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-lo/strings.xml1
-rw-r--r--packages/SystemUI/res/values-lo/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-lt/strings.xml1
-rw-r--r--packages/SystemUI/res/values-lt/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-lv/strings.xml1
-rw-r--r--packages/SystemUI/res/values-lv/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-mk/strings.xml3
-rw-r--r--packages/SystemUI/res/values-mk/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-ml/strings.xml1
-rw-r--r--packages/SystemUI/res/values-ml/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-mn/strings.xml1
-rw-r--r--packages/SystemUI/res/values-mn/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-mr/strings.xml1
-rw-r--r--packages/SystemUI/res/values-mr/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-ms/strings.xml1
-rw-r--r--packages/SystemUI/res/values-ms/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-my/strings.xml1
-rw-r--r--packages/SystemUI/res/values-my/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-nb/strings.xml1
-rw-r--r--packages/SystemUI/res/values-nb/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-ne/strings.xml2
-rw-r--r--packages/SystemUI/res/values-ne/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-nl/strings.xml1
-rw-r--r--packages/SystemUI/res/values-nl/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-or/strings.xml1
-rw-r--r--packages/SystemUI/res/values-or/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-pa/strings.xml1
-rw-r--r--packages/SystemUI/res/values-pa/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-pl/strings.xml1
-rw-r--r--packages/SystemUI/res/values-pl/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-pt-rBR/strings.xml1
-rw-r--r--packages/SystemUI/res/values-pt-rBR/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-pt-rPT/strings.xml1
-rw-r--r--packages/SystemUI/res/values-pt-rPT/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-pt/strings.xml1
-rw-r--r--packages/SystemUI/res/values-pt/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-ro/strings.xml1
-rw-r--r--packages/SystemUI/res/values-ro/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-ru/strings.xml1
-rw-r--r--packages/SystemUI/res/values-ru/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-si/strings.xml1
-rw-r--r--packages/SystemUI/res/values-si/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-sk/strings.xml1
-rw-r--r--packages/SystemUI/res/values-sk/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-sl/strings.xml1
-rw-r--r--packages/SystemUI/res/values-sl/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-sq/strings.xml2
-rw-r--r--packages/SystemUI/res/values-sq/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-sr/strings.xml1
-rw-r--r--packages/SystemUI/res/values-sr/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-sv/strings.xml11
-rw-r--r--packages/SystemUI/res/values-sv/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-sw/strings.xml1
-rw-r--r--packages/SystemUI/res/values-sw/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-ta/strings.xml1
-rw-r--r--packages/SystemUI/res/values-ta/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-te/strings.xml3
-rw-r--r--packages/SystemUI/res/values-te/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-th/strings.xml3
-rw-r--r--packages/SystemUI/res/values-th/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-tl/strings.xml1
-rw-r--r--packages/SystemUI/res/values-tl/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-tr/strings.xml1
-rw-r--r--packages/SystemUI/res/values-tr/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-uk/strings.xml1
-rw-r--r--packages/SystemUI/res/values-uk/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-ur/strings.xml1
-rw-r--r--packages/SystemUI/res/values-ur/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-uz/strings.xml1
-rw-r--r--packages/SystemUI/res/values-uz/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-vi/strings.xml1
-rw-r--r--packages/SystemUI/res/values-vi/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-w390dp/config.xml19
-rw-r--r--packages/SystemUI/res/values-zh-rCN/strings.xml1
-rw-r--r--packages/SystemUI/res/values-zh-rCN/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-zh-rHK/strings.xml1
-rw-r--r--packages/SystemUI/res/values-zh-rHK/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-zh-rTW/strings.xml1
-rw-r--r--packages/SystemUI/res/values-zh-rTW/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values-zu/strings.xml1
-rw-r--r--packages/SystemUI/res/values-zu/strings_tv.xml6
-rw-r--r--packages/SystemUI/res/values/config.xml5
-rw-r--r--packages/SystemUI/res/values/dimens.xml6
-rw-r--r--packages/SystemUI/res/values/strings.xml3
-rw-r--r--packages/SystemUI/res/values/styles.xml4
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java5
-rwxr-xr-xpackages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java28
-rw-r--r--packages/SystemUI/src/com/android/keyguard/LockIconView.java47
-rw-r--r--packages/SystemUI/src/com/android/keyguard/LockIconViewController.java30
-rw-r--r--packages/SystemUI/src/com/android/systemui/BatteryMeterView.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/GuestResumeSessionReceiver.java55
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFaceToFingerprintView.java49
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFaceView.java38
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java169
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java44
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java25
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSFragment.java24
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSPanel.java60
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java20
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/TileLayout.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureClient.java54
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java69
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt84
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt85
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt14
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java34
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java130
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java141
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java133
-rw-r--r--packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/sensors/ProximitySensor.java22
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java30
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFaceToFingerprintViewTest.java49
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFaceViewTest.java8
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java88
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java30
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelSwitchToParentTest.kt162
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java81
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/screenshot/ScrollCaptureClientTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java11
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerTest.kt257
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/util/sensors/ProximitySensorDualTest.java55
-rw-r--r--packages/VpnDialogs/res/values-gu/strings.xml2
-rw-r--r--services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java60
-rw-r--r--services/autofill/java/com/android/server/autofill/Session.java16
-rw-r--r--services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java7
-rw-r--r--services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java32
-rw-r--r--services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java24
-rw-r--r--services/core/java/com/android/server/BluetoothManagerService.java28
-rw-r--r--services/core/java/com/android/server/PersistentDataBlockService.java27
-rw-r--r--services/core/java/com/android/server/SensorPrivacyService.java280
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java8
-rw-r--r--services/core/java/com/android/server/am/AppExitInfoTracker.java18
-rw-r--r--services/core/java/com/android/server/am/BatteryStatsService.java6
-rw-r--r--services/core/java/com/android/server/am/CachedAppOptimizer.java7
-rw-r--r--services/core/java/com/android/server/am/LmkdConnection.java2
-rw-r--r--services/core/java/com/android/server/am/LmkdStatsReporter.java5
-rw-r--r--services/core/java/com/android/server/am/PhantomProcessList.java5
-rw-r--r--services/core/java/com/android/server/am/ProcessStateRecord.java2
-rw-r--r--services/core/java/com/android/server/biometrics/BiometricService.java12
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java24
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/CoexCoordinator.java44
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/LoggableMonitor.java82
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/FaceService.java9
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/ServiceProvider.java2
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java8
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceEnrollClient.java3
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java4
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java5
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceAuthenticationClient.java8
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceEnrollClient.java2
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java15
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java2
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintAuthenticationClient.java15
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintEnrollClient.java2
-rw-r--r--services/core/java/com/android/server/display/DisplayManagerService.java3
-rw-r--r--services/core/java/com/android/server/infra/AbstractMasterSystemService.java2
-rw-r--r--services/core/java/com/android/server/input/InputManagerService.java15
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java7
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodManagerService.java12
-rw-r--r--services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java3
-rw-r--r--services/core/java/com/android/server/media/MediaServerUtils.java19
-rw-r--r--services/core/java/com/android/server/media/MediaSessionRecord.java3
-rw-r--r--services/core/java/com/android/server/media/MediaSessionService.java6
-rw-r--r--services/core/java/com/android/server/media/MediaSessionStack.java3
-rw-r--r--services/core/java/com/android/server/net/NetworkStatsService.java24
-rw-r--r--services/core/java/com/android/server/pm/IncrementalStates.java11
-rw-r--r--services/core/java/com/android/server/pm/permission/PermissionManagerService.java10
-rw-r--r--services/core/java/com/android/server/policy/PhoneWindowManager.java8
-rw-r--r--services/core/java/com/android/server/vcn/Vcn.java7
-rw-r--r--services/core/java/com/android/server/vcn/VcnGatewayConnection.java5
-rw-r--r--services/core/java/com/android/server/wm/ActivityMetricsLogger.java15
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java6
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java28
-rw-r--r--services/core/java/com/android/server/wm/FadeRotationAnimationController.java6
-rw-r--r--services/core/java/com/android/server/wm/InsetsPolicy.java46
-rw-r--r--services/core/java/com/android/server/wm/RootWindowContainer.java10
-rw-r--r--services/core/java/com/android/server/wm/Task.java13
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java3
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/am/ApplicationExitInfoTest.java2
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java54
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/gestures/TouchExplorerTest.java1
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java6
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/sensors/CoexCoordinatorTest.java119
-rw-r--r--services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java41
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java52
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/StubTransaction.java6
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java33
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java109
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerSessionPermissionsDecorator.java10
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java11
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java15
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceShellCommand.java18
-rw-r--r--telephony/java/android/telephony/AccessNetworkUtils.java12
-rw-r--r--telephony/java/android/telephony/CarrierConfigManager.java23
-rw-r--r--telephony/java/android/telephony/CellSignalStrengthNr.java2
-rw-r--r--telephony/java/android/telephony/PhysicalChannelConfig.java3
-rw-r--r--tests/vcn/java/com/android/server/vcn/VcnNetworkProviderTest.java4
459 files changed, 6116 insertions, 1877 deletions
diff --git a/Android.bp b/Android.bp
index 91ad2a339e6b..2f34f8c0a7aa 100755
--- a/Android.bp
+++ b/Android.bp
@@ -318,6 +318,7 @@ java_defaults {
],
include_dirs: [
"frameworks/av/aidl",
+ "frameworks/native/libs/permission/aidl",
"packages/modules/Connectivity/framework/aidl-export",
],
},
@@ -559,6 +560,7 @@ stubs_defaults {
],
include_dirs: [
"frameworks/av/aidl",
+ "frameworks/native/libs/permission/aidl",
"packages/modules/Connectivity/framework/aidl-export",
],
},
diff --git a/ApiDocs.bp b/ApiDocs.bp
index 0aed5d9abea9..aae4a7174d68 100644
--- a/ApiDocs.bp
+++ b/ApiDocs.bp
@@ -113,7 +113,10 @@ stubs_defaults {
// TODO(b/169090544): remove below aidl includes.
aidl: {
local_include_dirs: ["media/aidl"],
- include_dirs: ["frameworks/av/aidl"],
+ include_dirs: [
+ "frameworks/av/aidl",
+ "frameworks/native/libs/permission/aidl",
+ ],
},
}
@@ -199,7 +202,10 @@ doc_defaults {
// TODO(b/169090544): remove below aidl includes.
aidl: {
local_include_dirs: ["media/aidl"],
- include_dirs: ["frameworks/av/aidl"],
+ include_dirs: [
+ "frameworks/av/aidl",
+ "frameworks/native/libs/permission/aidl",
+ ],
},
}
diff --git a/StubLibraries.bp b/StubLibraries.bp
index 941a1fa033e4..44c55c26153d 100644
--- a/StubLibraries.bp
+++ b/StubLibraries.bp
@@ -410,7 +410,7 @@ java_library {
],
static_libs: [
"android-non-updatable.stubs.module_lib",
- "art.module.public.api.stubs",
+ "art.module.public.api.stubs.module_lib",
],
dist: {
dir: "apistubs/android/module-lib",
diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
index 98e963e113e6..95728081bdb9 100644
--- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
@@ -2052,10 +2052,11 @@ public class AlarmManagerService extends SystemService {
+ " -- package not allowed to start");
return;
}
+ final int callerProcState = mActivityManagerInternal.getUidProcessState(callingUid);
removeLocked(operation, directReceiver, REMOVE_REASON_UNDEFINED);
incrementAlarmCount(a.uid);
setImplLocked(a);
- MetricsHelper.pushAlarmScheduled(a);
+ MetricsHelper.pushAlarmScheduled(a, callerProcState);
}
/**
@@ -2602,7 +2603,7 @@ public class AlarmManagerService extends SystemService {
final int uid = mPackageManagerInternal.getPackageUid(packageName, 0, userId);
if (callingUid != uid && !UserHandle.isCore(callingUid)) {
throw new SecurityException("Uid " + callingUid
- + " cannot query hasScheduleExactAlarm for uid " + uid);
+ + " cannot query hasScheduleExactAlarm for package " + packageName);
}
return (uid > 0) ? hasScheduleExactAlarmInternal(packageName, uid) : false;
}
diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/MetricsHelper.java b/apex/jobscheduler/service/java/com/android/server/alarm/MetricsHelper.java
index 4e7311f10252..4c2f8d124566 100644
--- a/apex/jobscheduler/service/java/com/android/server/alarm/MetricsHelper.java
+++ b/apex/jobscheduler/service/java/com/android/server/alarm/MetricsHelper.java
@@ -22,6 +22,7 @@ import static com.android.internal.util.FrameworkStatsLog.ALARM_SCHEDULED__EXACT
import static com.android.internal.util.FrameworkStatsLog.ALARM_SCHEDULED__EXACT_ALARM_ALLOWED_REASON__PERMISSION;
import static com.android.server.alarm.AlarmManagerService.INDEFINITE_DELAY;
+import android.app.ActivityManager;
import android.app.AlarmManager;
import android.app.StatsManager;
import android.content.Context;
@@ -93,7 +94,7 @@ class MetricsHelper {
}
}
- static void pushAlarmScheduled(Alarm a) {
+ static void pushAlarmScheduled(Alarm a, int callerProcState) {
FrameworkStatsLog.write(
FrameworkStatsLog.ALARM_SCHEDULED,
a.uid,
@@ -103,7 +104,8 @@ class MetricsHelper {
a.alarmClock != null,
a.repeatInterval != 0,
reasonToStatsReason(a.mExactAllowReason),
- AlarmManagerService.isRtc(a.type));
+ AlarmManagerService.isRtc(a.type),
+ ActivityManager.processStateAmToProto(callerProcState));
}
static void pushAlarmBatchDelivered(int numAlarms, int wakeups) {
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
index 78670c7c73b1..591e8ba859fc 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
@@ -690,7 +690,6 @@ public class JobSchedulerService extends com.android.server.SystemService
@VisibleForTesting
class PendingJobComparator implements Comparator<JobStatus> {
- private final SparseBooleanArray mUidHasEjCache = new SparseBooleanArray();
private final SparseLongArray mEarliestRegEnqueueTimeCache = new SparseLongArray();
/**
@@ -699,14 +698,11 @@ public class JobSchedulerService extends com.android.server.SystemService
@GuardedBy("mLock")
@VisibleForTesting
void refreshLocked() {
- mUidHasEjCache.clear();
mEarliestRegEnqueueTimeCache.clear();
for (int i = 0; i < mPendingJobs.size(); ++i) {
final JobStatus job = mPendingJobs.get(i);
final int uid = job.getSourceUid();
- if (job.isRequestedExpeditedJob()) {
- mUidHasEjCache.put(uid, true);
- } else {
+ if (!job.isRequestedExpeditedJob()) {
final long earliestEnqueueTime =
mEarliestRegEnqueueTimeCache.get(uid, Long.MAX_VALUE);
mEarliestRegEnqueueTimeCache.put(uid,
@@ -736,9 +732,7 @@ public class JobSchedulerService extends com.android.server.SystemService
return o1EJ ? -1 : 1;
}
}
- final boolean uid1HasEj = mUidHasEjCache.get(o1.getSourceUid());
- final boolean uid2HasEj = mUidHasEjCache.get(o2.getSourceUid());
- if ((uid1HasEj || uid2HasEj) && (o1EJ || o2EJ)) {
+ if (o1EJ || o2EJ) {
// We MUST prioritize EJs ahead of regular jobs within a single app. Since we do
// that, in order to satisfy the transitivity constraint of the comparator, if
// any UID has an EJ, we must ensure that the EJ is ordered ahead of the regular
@@ -759,9 +753,13 @@ public class JobSchedulerService extends com.android.server.SystemService
} else if (uid1EarliestRegEnqueueTime > uid2EarliestRegEnqueueTime) {
return 1;
}
- } else if (o1EJ && uid1EarliestRegEnqueueTime < o2.enqueueTime) {
+ } else if (o1EJ && uid1EarliestRegEnqueueTime <= o2.enqueueTime) {
+ // Include = to ensure that if we sorted an EJ ahead of a regular job at time X
+ // then we make sure to sort it ahead of all regular jobs at time X.
return -1;
- } else if (o2EJ && uid2EarliestRegEnqueueTime < o1.enqueueTime) {
+ } else if (o2EJ && uid2EarliestRegEnqueueTime <= o1.enqueueTime) {
+ // Include = to ensure that if we sorted an EJ ahead of a regular job at time X
+ // then we make sure to sort it ahead of all regular jobs at time X.
return 1;
}
}
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java b/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
index 3fa1c12ce762..90baa8e54220 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
@@ -116,6 +116,16 @@ public final class JobServiceContext implements ServiceConnection {
@VisibleForTesting
int mVerb;
private boolean mCancelled;
+ /**
+ * True if the previous job on this context successfully finished (ie. called jobFinished or
+ * dequeueWork with no work left).
+ */
+ private boolean mPreviousJobHadSuccessfulFinish;
+ /**
+ * The last time a job on this context didn't finish successfully, in the elapsed realtime
+ * timebase.
+ */
+ private long mLastUnsuccessfulFinishElapsed;
/**
* All the information maintained about the job currently being executed.
@@ -439,7 +449,9 @@ public final class JobServiceContext implements ServiceConnection {
final long ident = Binder.clearCallingIdentity();
try {
synchronized (mLock) {
- assertCallerLocked(cb);
+ if (!assertCallerLocked(cb)) {
+ return null;
+ }
if (mVerb == VERB_STOPPING || mVerb == VERB_FINISHED) {
// This job is either all done, or on its way out. Either way, it
// should not dispatch any more work. We will pick up any remaining
@@ -465,7 +477,11 @@ public final class JobServiceContext implements ServiceConnection {
final long ident = Binder.clearCallingIdentity();
try {
synchronized (mLock) {
- assertCallerLocked(cb);
+ if (!assertCallerLocked(cb)) {
+ // Return true instead of false here so we don't just kick the
+ // Exception-throwing-can down the road to JobParameters.completeWork >:(
+ return true;
+ }
return mRunningJob.completeWorkLocked(workId);
}
} finally {
@@ -554,18 +570,34 @@ public final class JobServiceContext implements ServiceConnection {
return true;
}
- private void assertCallerLocked(JobCallback cb) {
+ /**
+ * Will throw a {@link SecurityException} if the callback is not for the currently running job,
+ * but may decide not to throw an exception if the call from the previous job appears to be an
+ * accident.
+ *
+ * @return true if the callback is for the current job, false otherwise
+ */
+ private boolean assertCallerLocked(JobCallback cb) {
if (!verifyCallerLocked(cb)) {
+ final long nowElapsed = sElapsedRealtimeClock.millis();
+ if (!mPreviousJobHadSuccessfulFinish
+ && (nowElapsed - mLastUnsuccessfulFinishElapsed) < 15_000L) {
+ // Don't punish apps for race conditions
+ return false;
+ }
+ // It's been long enough that the app should really not be calling into JS for the
+ // stopped job.
StringBuilder sb = new StringBuilder(128);
sb.append("Caller no longer running");
if (cb.mStoppedReason != null) {
sb.append(", last stopped ");
- TimeUtils.formatDuration(sElapsedRealtimeClock.millis() - cb.mStoppedTime, sb);
+ TimeUtils.formatDuration(nowElapsed - cb.mStoppedTime, sb);
sb.append(" because: ");
sb.append(cb.mStoppedReason);
}
throw new SecurityException(sb.toString());
}
+ return true;
}
/**
@@ -911,6 +943,11 @@ public final class JobServiceContext implements ServiceConnection {
applyStoppedReasonLocked(reason);
completedJob = mRunningJob;
final int internalStopReason = mParams.getInternalStopReasonCode();
+ mPreviousJobHadSuccessfulFinish =
+ (internalStopReason == JobParameters.INTERNAL_STOP_REASON_SUCCESSFUL_FINISH);
+ if (!mPreviousJobHadSuccessfulFinish) {
+ mLastUnsuccessfulFinishElapsed = sElapsedRealtimeClock.millis();
+ }
mJobPackageTracker.noteInactive(completedJob, internalStopReason, reason);
FrameworkStatsLog.write_non_chained(FrameworkStatsLog.SCHEDULED_JOB_STATE_CHANGED,
completedJob.getSourceUid(), null, completedJob.getBatteryName(),
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index a0799394177d..ea6d0cecfd73 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -3176,7 +3176,6 @@ package android.window {
public final class SplashScreenView extends android.widget.FrameLayout {
method @Nullable public android.view.View getBrandingView();
- method @ColorInt public int getIconBackgroundColor();
}
public final class StartingWindowInfo implements android.os.Parcelable {
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 3ff32589ca50..133082f24e18 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -370,11 +370,12 @@ public final class ActivityThread extends ClientTransactionHandler
@UnsupportedAppUsage(trackingBug = 176961850, maxTargetSdk = Build.VERSION_CODES.R,
publicAlternatives = "Use {@code Context#getResources()#getConfiguration()} instead.")
Configuration mConfiguration;
+ @GuardedBy("this")
+ private boolean mUpdateHttpProxyOnBind = false;
@UnsupportedAppUsage
Application mInitialApplication;
@UnsupportedAppUsage
- final ArrayList<Application> mAllApplications
- = new ArrayList<Application>();
+ final ArrayList<Application> mAllApplications = new ArrayList<>();
/**
* Bookkeeping of instantiated backup agents indexed first by user id, then by package name.
* Indexing by user id supports parallel backups across users on system packages as they run in
@@ -1188,8 +1189,18 @@ public final class ActivityThread extends ClientTransactionHandler
}
public void updateHttpProxy() {
- ActivityThread.updateHttpProxy(
- getApplication() != null ? getApplication() : getSystemContext());
+ final Application app;
+ synchronized (ActivityThread.this) {
+ app = getApplication();
+ if (null == app) {
+ // The app is not bound yet. Make a note to update the HTTP proxy when the
+ // app is bound.
+ mUpdateHttpProxyOnBind = true;
+ return;
+ }
+ }
+ // App is present, update the proxy inline.
+ ActivityThread.updateHttpProxy(app);
}
public void processInBackground() {
@@ -6704,6 +6715,15 @@ public final class ActivityThread extends ClientTransactionHandler
sendMessage(H.SET_CONTENT_CAPTURE_OPTIONS_CALLBACK, data.appInfo.packageName);
mInitialApplication = app;
+ final boolean updateHttpProxy;
+ synchronized (this) {
+ updateHttpProxy = mUpdateHttpProxyOnBind;
+ // This synchronized block ensures that any subsequent call to updateHttpProxy()
+ // will see a non-null mInitialApplication.
+ }
+ if (updateHttpProxy) {
+ ActivityThread.updateHttpProxy(app);
+ }
// don't bring up providers in restricted mode; they may depend on the
// app's custom Application class
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index f52fdc562b13..4db1f71e8256 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -26,6 +26,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UiContext;
import android.compat.annotation.UnsupportedAppUsage;
+import android.content.AttributionSource;
import android.content.AutofillOptions;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
@@ -60,7 +61,6 @@ import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.net.Uri;
-import android.content.AttributionSource;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
@@ -3120,6 +3120,7 @@ class ContextImpl extends Context {
mForceDisplayOverrideInResources = container.mForceDisplayOverrideInResources;
mIsConfigurationBasedContext = container.mIsConfigurationBasedContext;
mContextType = container.mContextType;
+ mContentCaptureOptions = container.mContentCaptureOptions;
} else {
mBasePackageName = packageInfo.mPackageName;
ApplicationInfo ainfo = packageInfo.getApplicationInfo();
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 9d149cf340e2..4b054f49d910 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -6122,28 +6122,29 @@ public class Notification implements Parcelable
// change the background bgColor
CharSequence title = action.title;
ColorStateList[] outResultColor = new ColorStateList[1];
- int background = getColors(p).getSecondaryAccentColor();
+ int buttonFillColor = getColors(p).getSecondaryAccentColor();
if (isLegacy()) {
title = ContrastColorUtil.clearColorSpans(title);
} else {
- title = ensureColorSpanContrast(title, background, outResultColor);
+ int notifBackgroundColor = getColors(p).getBackgroundColor();
+ title = ensureColorSpanContrast(title, notifBackgroundColor, outResultColor);
}
button.setTextViewText(R.id.action0, processTextSpans(title));
boolean hasColorOverride = outResultColor[0] != null;
if (hasColorOverride) {
// There's a span spanning the full text, let's take it and use it as the
// background color
- background = outResultColor[0].getDefaultColor();
+ buttonFillColor = outResultColor[0].getDefaultColor();
}
final int textColor = ContrastColorUtil.resolvePrimaryColor(mContext,
- background, mInNightMode);
+ buttonFillColor, mInNightMode);
button.setTextColor(R.id.action0, textColor);
// We only want about 20% alpha for the ripple
final int rippleColor = (textColor & 0x00ffffff) | 0x33000000;
button.setColorStateList(R.id.action0, "setRippleColor",
ColorStateList.valueOf(rippleColor));
button.setColorStateList(R.id.action0, "setButtonBackground",
- ColorStateList.valueOf(background));
+ ColorStateList.valueOf(buttonFillColor));
if (p.mCallStyleActions) {
button.setImageViewIcon(R.id.action0, action.getIcon());
boolean priority = action.getExtras().getBoolean(CallStyle.KEY_ACTION_PRIORITY);
@@ -6176,8 +6177,8 @@ public class Notification implements Parcelable
* there exists a full length color span.
* @return the contrasted charSequence
*/
- private CharSequence ensureColorSpanContrast(CharSequence charSequence, int background,
- ColorStateList[] outResultColor) {
+ private static CharSequence ensureColorSpanContrast(CharSequence charSequence,
+ int background, ColorStateList[] outResultColor) {
if (charSequence instanceof Spanned) {
Spanned ss = (Spanned) charSequence;
Object[] spans = ss.getSpans(0, ss.length(), Object.class);
@@ -6197,8 +6198,9 @@ public class Notification implements Parcelable
int[] colors = textColor.getColors();
int[] newColors = new int[colors.length];
for (int i = 0; i < newColors.length; i++) {
+ boolean isBgDark = isColorDark(background);
newColors[i] = ContrastColorUtil.ensureLargeTextContrast(
- colors[i], background, mInNightMode);
+ colors[i], background, isBgDark);
}
textColor = new ColorStateList(textColor.getStates().clone(),
newColors);
@@ -6217,8 +6219,9 @@ public class Notification implements Parcelable
} else if (resultSpan instanceof ForegroundColorSpan) {
ForegroundColorSpan originalSpan = (ForegroundColorSpan) resultSpan;
int foregroundColor = originalSpan.getForegroundColor();
+ boolean isBgDark = isColorDark(background);
foregroundColor = ContrastColorUtil.ensureLargeTextContrast(
- foregroundColor, background, mInNightMode);
+ foregroundColor, background, isBgDark);
if (fullLength) {
outResultColor[0] = ColorStateList.valueOf(foregroundColor);
resultSpan = null;
@@ -6238,6 +6241,19 @@ public class Notification implements Parcelable
}
/**
+ * Determines if the color is light or dark. Specifically, this is using the same metric as
+ * {@link ContrastColorUtil#resolvePrimaryColor(Context, int, boolean)} and peers so that
+ * the direction of color shift is consistent.
+ *
+ * @param color the color to check
+ * @return true if the color has higher contrast with white than black
+ */
+ private static boolean isColorDark(int color) {
+ // as per ContrastColorUtil.shouldUseDark, this uses the color contrast midpoint.
+ return ContrastColorUtil.calculateLuminance(color) <= 0.17912878474;
+ }
+
+ /**
* @return Whether we are currently building a notification from a legacy (an app that
* doesn't create material notifications by itself) app.
*/
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 549ab6e2df83..0e04ad3768c7 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -10997,6 +10997,16 @@ public class DevicePolicyManager {
* {@link #EXTRA_PROVISIONING_SENSORS_PERMISSION_GRANT_OPT_OUT} in the provisioning parameters.
* In that case the device owner's control will be limited do denying these permissions.
* <p>
+ * NOTE: On devices running {@link android.os.Build.VERSION_CODES#S} and above, control over
+ * the following permissions are restricted for managed profile owners:
+ * <ul>
+ * <li>Manifest.permission.READ_SMS</li>
+ * </ul>
+ * <p>
+ * A managed profile owner may not grant these permissions (i.e. call this method with any of
+ * the permissions listed above and {@code grantState} of
+ * {@code #PERMISSION_GRANT_STATE_GRANTED}), but may deny them.
+ * <p>
* Attempts by the admin to grant these permissions, when the admin is restricted from doing
* so, will be silently ignored (no exception will be thrown).
*
diff --git a/core/java/android/appwidget/AppWidgetManagerInternal.java b/core/java/android/appwidget/AppWidgetManagerInternal.java
index 5694ca860453..266e33af0e22 100644
--- a/core/java/android/appwidget/AppWidgetManagerInternal.java
+++ b/core/java/android/appwidget/AppWidgetManagerInternal.java
@@ -19,6 +19,8 @@ package android.appwidget;
import android.annotation.Nullable;
import android.util.ArraySet;
+import java.util.Set;
+
/**
* App widget manager local system service interface.
*
@@ -42,4 +44,16 @@ public abstract class AppWidgetManagerInternal {
* @param userId The user that is being unlocked.
*/
public abstract void unlockUser(int userId);
+
+ /**
+ * Updates all widgets, applying changes to Runtime Resource Overlay affecting the specified
+ * target packages.
+ *
+ * @param packageNames The names of all target packages for which an overlay was modified
+ * @param userId The user for which overlay modifications occurred.
+ * @param updateFrameworkRes Whether or not an overlay affected the values of framework
+ * resources.
+ */
+ public abstract void applyResourceOverlaysToWidgets(Set<String> packageNames, int userId,
+ boolean updateFrameworkRes);
}
diff --git a/core/java/android/bluetooth/BluetoothA2dp.java b/core/java/android/bluetooth/BluetoothA2dp.java
index 65cdca9eb7d8..1dd32fec2510 100644
--- a/core/java/android/bluetooth/BluetoothA2dp.java
+++ b/core/java/android/bluetooth/BluetoothA2dp.java
@@ -1025,6 +1025,10 @@ public final class BluetoothA2dp implements BluetoothProfile {
public boolean setBufferLengthMillis(@BluetoothCodecConfig.SourceCodecType int codec,
int value) {
if (VDBG) log("setBufferLengthMillis(" + codec + ", " + value + ")");
+ if (value < 0) {
+ Log.e(TAG, "Trying to set audio buffer length to a negative value: " + value);
+ return false;
+ }
try {
final IBluetoothA2dp service = getService();
if (service != null && isEnabled()) {
diff --git a/core/java/android/bluetooth/le/ScanFilter.java b/core/java/android/bluetooth/le/ScanFilter.java
index fc9fb1aa960b..f86d17ab7c61 100644
--- a/core/java/android/bluetooth/le/ScanFilter.java
+++ b/core/java/android/bluetooth/le/ScanFilter.java
@@ -190,6 +190,15 @@ public final class ScanFilter implements Parcelable {
dest.writeByteArray(mManufacturerDataMask);
}
}
+
+ // IRK
+ if (mDeviceAddress != null) {
+ dest.writeInt(mAddressType);
+ dest.writeInt(mIrk == null ? 0 : 1);
+ if (mIrk != null) {
+ dest.writeByteArray(mIrk);
+ }
+ }
dest.writeInt(mOrgId);
dest.writeInt(mOrgId < 0 ? 0 : 1);
if(mOrgId >= 0) {
@@ -221,8 +230,10 @@ public final class ScanFilter implements Parcelable {
if (in.readInt() == 1) {
builder.setDeviceName(in.readString());
}
+ String address = null;
+ // If we have a non-null address
if (in.readInt() == 1) {
- builder.setDeviceAddress(in.readString());
+ address = in.readString();
}
if (in.readInt() == 1) {
ParcelUuid uuid = in.readParcelable(ParcelUuid.class.getClassLoader());
@@ -279,6 +290,18 @@ public final class ScanFilter implements Parcelable {
}
}
+ // IRK
+ if (address != null) {
+ final int addressType = in.readInt();
+ if (in.readInt() == 1) {
+ final byte[] irk = new byte[16];
+ in.readByteArray(irk);
+ builder.setDeviceAddress(address, addressType, irk);
+ } else {
+ builder.setDeviceAddress(address, addressType);
+ }
+ }
+
int orgId = in.readInt();
if(in.readInt() == 1) {
int tdsFlags = in.readInt();
diff --git a/core/java/android/content/pm/PackageParserCacheHelper.java b/core/java/android/content/pm/PackageParserCacheHelper.java
index 8212224e114c..e03c3ee4fab9 100644
--- a/core/java/android/content/pm/PackageParserCacheHelper.java
+++ b/core/java/android/content/pm/PackageParserCacheHelper.java
@@ -56,6 +56,9 @@ public class PackageParserCacheHelper {
mStrings.clear();
final int poolPosition = mParcel.readInt();
+ if (poolPosition < 0) {
+ throw new IllegalStateException("Invalid string pool position: " + poolPosition);
+ }
final int startPosition = mParcel.dataPosition();
// The pool is at the end of the parcel.
diff --git a/core/java/android/hardware/ISensorPrivacyManager.aidl b/core/java/android/hardware/ISensorPrivacyManager.aidl
index debc074ea21a..d69a9e14b4bf 100644
--- a/core/java/android/hardware/ISensorPrivacyManager.aidl
+++ b/core/java/android/hardware/ISensorPrivacyManager.aidl
@@ -48,4 +48,8 @@ interface ISensorPrivacyManager {
void suppressIndividualSensorPrivacyReminders(int userId, int sensor, IBinder token,
boolean suppress);
+
+ void addUserGlobalIndividualSensorPrivacyListener(int sensor, in ISensorPrivacyListener listener);
+
+ void removeUserGlobalIndividualSensorPrivacyListener(int sensor, in ISensorPrivacyListener listener);
} \ No newline at end of file
diff --git a/core/java/android/hardware/SensorPrivacyManager.java b/core/java/android/hardware/SensorPrivacyManager.java
index b7d95e7dea74..fa7ce11c5414 100644
--- a/core/java/android/hardware/SensorPrivacyManager.java
+++ b/core/java/android/hardware/SensorPrivacyManager.java
@@ -29,6 +29,7 @@ import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.UserHandle;
import android.service.SensorPrivacyIndividualEnabledSensorProto;
import android.service.SensorPrivacyToggleSourceProto;
import android.util.ArrayMap;
@@ -247,8 +248,7 @@ public final class SensorPrivacyManager {
@RequiresPermission(Manifest.permission.OBSERVE_SENSOR_PRIVACY)
public void addSensorPrivacyListener(@Sensors.Sensor int sensor,
@NonNull OnSensorPrivacyChangedListener listener) {
- addSensorPrivacyListener(sensor, mContext.getUserId(), mContext.getMainExecutor(),
- listener);
+ addSensorPrivacyListener(sensor, mContext.getMainExecutor(), listener);
}
/**
@@ -283,7 +283,25 @@ public final class SensorPrivacyManager {
@RequiresPermission(Manifest.permission.OBSERVE_SENSOR_PRIVACY)
public void addSensorPrivacyListener(@Sensors.Sensor int sensor, @NonNull Executor executor,
@NonNull OnSensorPrivacyChangedListener listener) {
- addSensorPrivacyListener(sensor, mContext.getUserId(), executor, listener);
+ Pair<OnSensorPrivacyChangedListener, Integer> key = new Pair<>(listener, sensor);
+ synchronized (mIndividualListeners) {
+ ISensorPrivacyListener iListener = mIndividualListeners.get(key);
+ if (iListener == null) {
+ iListener = new ISensorPrivacyListener.Stub() {
+ @Override
+ public void onSensorPrivacyChanged(boolean enabled) {
+ executor.execute(() -> listener.onSensorPrivacyChanged(sensor, enabled));
+ }
+ };
+ mIndividualListeners.put(key, iListener);
+ }
+
+ try {
+ mService.addUserGlobalIndividualSensorPrivacyListener(sensor, iListener);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
}
/**
@@ -361,7 +379,7 @@ public final class SensorPrivacyManager {
@SystemApi
@RequiresPermission(Manifest.permission.OBSERVE_SENSOR_PRIVACY)
public boolean isSensorPrivacyEnabled(@Sensors.Sensor int sensor) {
- return isSensorPrivacyEnabled(sensor, mContext.getUserId());
+ return isSensorPrivacyEnabled(sensor, UserHandle.USER_CURRENT);
}
/**
@@ -392,7 +410,7 @@ public final class SensorPrivacyManager {
@RequiresPermission(Manifest.permission.MANAGE_SENSOR_PRIVACY)
public void setSensorPrivacy(@Sources.Source int source, @Sensors.Sensor int sensor,
boolean enable) {
- setSensorPrivacy(source, sensor, enable, mContext.getUserId());
+ setSensorPrivacy(source, sensor, enable, UserHandle.USER_CURRENT);
}
/**
@@ -428,7 +446,7 @@ public final class SensorPrivacyManager {
@RequiresPermission(Manifest.permission.MANAGE_SENSOR_PRIVACY)
public void setSensorPrivacyForProfileGroup(@Sources.Source int source,
@Sensors.Sensor int sensor, boolean enable) {
- setSensorPrivacyForProfileGroup(source , sensor, enable, mContext.getUserId());
+ setSensorPrivacyForProfileGroup(source , sensor, enable, UserHandle.USER_CURRENT);
}
/**
@@ -463,7 +481,7 @@ public final class SensorPrivacyManager {
@RequiresPermission(Manifest.permission.MANAGE_SENSOR_PRIVACY)
public void suppressSensorPrivacyReminders(int sensor,
boolean suppress) {
- suppressSensorPrivacyReminders(sensor, suppress, mContext.getUserId());
+ suppressSensorPrivacyReminders(sensor, suppress, UserHandle.USER_CURRENT);
}
/**
@@ -590,4 +608,5 @@ public final class SensorPrivacyManager {
throw e.rethrowFromSystemServer();
}
}
+
}
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index c78dd5366d31..b55a1cbe0bed 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -2318,6 +2318,51 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>>
new Key<Float>("android.control.zoomRatio", float.class);
/**
+ * <p>Framework-only private key which informs camera fwk that the AF regions has been set
+ * by the client and those regions need not be corrected when {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode} is
+ * set to MAXIMUM_RESOLUTION.</p>
+ * <p>This must be set to TRUE by the camera2 java fwk when the camera client sets
+ * {@link CaptureRequest#CONTROL_AF_REGIONS android.control.afRegions}.</p>
+ * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
+ *
+ * @see CaptureRequest#CONTROL_AF_REGIONS
+ * @see CaptureRequest#SENSOR_PIXEL_MODE
+ * @hide
+ */
+ public static final Key<Boolean> CONTROL_AF_REGIONS_SET =
+ new Key<Boolean>("android.control.afRegionsSet", boolean.class);
+
+ /**
+ * <p>Framework-only private key which informs camera fwk that the AE regions has been set
+ * by the client and those regions need not be corrected when {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode} is
+ * set to MAXIMUM_RESOLUTION.</p>
+ * <p>This must be set to TRUE by the camera2 java fwk when the camera client sets
+ * {@link CaptureRequest#CONTROL_AE_REGIONS android.control.aeRegions}.</p>
+ * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
+ *
+ * @see CaptureRequest#CONTROL_AE_REGIONS
+ * @see CaptureRequest#SENSOR_PIXEL_MODE
+ * @hide
+ */
+ public static final Key<Boolean> CONTROL_AE_REGIONS_SET =
+ new Key<Boolean>("android.control.aeRegionsSet", boolean.class);
+
+ /**
+ * <p>Framework-only private key which informs camera fwk that the AF regions has been set
+ * by the client and those regions need not be corrected when {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode} is
+ * set to MAXIMUM_RESOLUTION.</p>
+ * <p>This must be set to TRUE by the camera2 java fwk when the camera client sets
+ * {@link CaptureRequest#CONTROL_AWB_REGIONS android.control.awbRegions}.</p>
+ * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
+ *
+ * @see CaptureRequest#CONTROL_AWB_REGIONS
+ * @see CaptureRequest#SENSOR_PIXEL_MODE
+ * @hide
+ */
+ public static final Key<Boolean> CONTROL_AWB_REGIONS_SET =
+ new Key<Boolean>("android.control.awbRegionsSet", boolean.class);
+
+ /**
* <p>Operation mode for edge
* enhancement.</p>
* <p>Edge enhancement improves sharpness and details in the captured image. OFF means
@@ -3057,6 +3102,21 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>>
new Key<Integer>("android.scaler.rotateAndCrop", int.class);
/**
+ * <p>Framework-only private key which informs camera fwk that the scaler crop region
+ * ({@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}) has been set by the client and it need
+ * not be corrected when {@link CaptureRequest#SENSOR_PIXEL_MODE android.sensor.pixelMode} is set to MAXIMUM_RESOLUTION.</p>
+ * <p>This must be set to TRUE by the camera2 java fwk when the camera client sets
+ * {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}.</p>
+ * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
+ *
+ * @see CaptureRequest#SCALER_CROP_REGION
+ * @see CaptureRequest#SENSOR_PIXEL_MODE
+ * @hide
+ */
+ public static final Key<Boolean> SCALER_CROP_REGION_SET =
+ new Key<Boolean>("android.scaler.cropRegionSet", boolean.class);
+
+ /**
* <p>Duration each pixel is exposed to
* light.</p>
* <p>If the sensor can't expose this exact duration, it will shorten the
diff --git a/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java
index bfc1f2765c3b..d5a35bc31e68 100644
--- a/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java
@@ -446,10 +446,16 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes
}
}
- public void release() {
- synchronized (mInterfaceLock) {
+ @Override
+ protected void finalize() throws Throwable {
+ if (mHandlerThread != null) {
mHandlerThread.quitSafely();
+ }
+ super.finalize();
+ }
+ public void release() {
+ synchronized (mInterfaceLock) {
if (mSessionProcessor != null) {
try {
mSessionProcessor.deInitSession();
@@ -812,6 +818,8 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes
Log.e(TAG,"Failed to parcel buffer fence!");
}
}
+ parcelImage.width = img.getWidth();
+ parcelImage.height = img.getHeight();
parcelImage.format = img.getFormat();
parcelImage.timestamp = img.getTimestamp();
parcelImage.transform = img.getTransform();
diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
index 1699f697b181..c6f94ad975b8 100644
--- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
@@ -708,6 +708,16 @@ public class CameraDeviceImpl extends CameraDevice
mCurrentSession.replaceSessionClose();
}
+ if (mCurrentExtensionSession != null) {
+ mCurrentExtensionSession.release();
+ mCurrentExtensionSession = null;
+ }
+
+ if (mCurrentAdvancedExtensionSession != null) {
+ mCurrentAdvancedExtensionSession.release();
+ mCurrentAdvancedExtensionSession = null;
+ }
+
// TODO: dont block for this
boolean configureSuccess = true;
CameraAccessException pendingException = null;
diff --git a/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java
index 537b894d9a6a..7d29a7d275cf 100644
--- a/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java
@@ -49,8 +49,6 @@ import android.media.ImageWriter;
import android.os.Binder;
import android.os.Handler;
import android.os.HandlerThread;
-import android.os.IBinder;
-import android.os.IInterface;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.annotation.NonNull;
@@ -265,13 +263,6 @@ public final class CameraExtensionSessionImpl extends CameraExtensionSession {
} catch (ClassCastException e) {
throw new UnsupportedOperationException("Failed casting preview processor!");
}
- if (mClientRepeatingRequestSurface != null) {
- mPreviewRequestUpdateProcessor.onOutputSurface(mClientRepeatingRequestSurface,
- nativeGetSurfaceFormat(mClientRepeatingRequestSurface));
- mRepeatingRequestImageWriter = ImageWriter.newInstance(
- mClientRepeatingRequestSurface, PREVIEW_QUEUE_SIZE,
- CameraExtensionCharacteristics.NON_PROCESSING_INPUT_FORMAT);
- }
mRepeatingRequestImageReader = ImageReader.newInstance(repeatingSurfaceInfo.mWidth,
repeatingSurfaceInfo.mHeight,
CameraExtensionCharacteristics.NON_PROCESSING_INPUT_FORMAT,
@@ -285,11 +276,6 @@ public final class CameraExtensionSessionImpl extends CameraExtensionSession {
mPreviewRequestUpdateProcessor.onImageFormatUpdate(
CameraExtensionCharacteristics.NON_PROCESSING_INPUT_FORMAT);
} else {
- if (mClientRepeatingRequestSurface != null) {
- mRepeatingRequestImageWriter = ImageWriter.newInstance(
- mClientRepeatingRequestSurface, PREVIEW_QUEUE_SIZE,
- CameraExtensionCharacteristics.NON_PROCESSING_INPUT_FORMAT);
- }
mRepeatingRequestImageReader = ImageReader.newInstance(repeatingSurfaceInfo.mWidth,
repeatingSurfaceInfo.mHeight,
CameraExtensionCharacteristics.NON_PROCESSING_INPUT_FORMAT,
@@ -320,7 +306,6 @@ public final class CameraExtensionSessionImpl extends CameraExtensionSession {
mBurstCaptureImageReader = ImageReader.newInstance(surfaceInfo.mWidth,
surfaceInfo.mHeight, CameraExtensionCharacteristics.PROCESSING_INPUT_FORMAT,
mImageExtender.getMaxCaptureStage());
- mImageProcessor.onOutputSurface(mClientCaptureSurface, surfaceInfo.mFormat);
} else {
// The client doesn't intend to trigger multi-frame capture, however the
// image extender still needs to get initialized and the camera still capture
@@ -367,6 +352,29 @@ public final class CameraExtensionSessionImpl extends CameraExtensionSession {
}
}
+ private void finishPipelineInitialization() throws RemoteException {
+ if (mClientRepeatingRequestSurface != null) {
+ if (mPreviewProcessorType == IPreviewExtenderImpl.PROCESSOR_TYPE_REQUEST_UPDATE_ONLY) {
+ mPreviewRequestUpdateProcessor.onOutputSurface(mClientRepeatingRequestSurface,
+ nativeGetSurfaceFormat(mClientRepeatingRequestSurface));
+ mRepeatingRequestImageWriter = ImageWriter.newInstance(
+ mClientRepeatingRequestSurface,
+ PREVIEW_QUEUE_SIZE,
+ CameraExtensionCharacteristics.NON_PROCESSING_INPUT_FORMAT);
+ } else if (mPreviewProcessorType == IPreviewExtenderImpl.PROCESSOR_TYPE_NONE) {
+ mRepeatingRequestImageWriter = ImageWriter.newInstance(
+ mClientRepeatingRequestSurface,
+ PREVIEW_QUEUE_SIZE,
+ CameraExtensionCharacteristics.NON_PROCESSING_INPUT_FORMAT);
+ }
+ }
+ if ((mImageProcessor != null) && (mClientCaptureSurface != null)) {
+ CameraExtensionUtils.SurfaceInfo surfaceInfo = CameraExtensionUtils.querySurface(
+ mClientCaptureSurface);
+ mImageProcessor.onOutputSurface(mClientCaptureSurface, surfaceInfo.mFormat);
+ }
+ }
+
/**
* @hide
*/
@@ -622,11 +630,18 @@ public final class CameraExtensionSessionImpl extends CameraExtensionSession {
new CameraExtensionUtils.HandlerExecutor(mHandler), requestHandler);
}
+ @Override
+ protected void finalize() throws Throwable {
+ if (mHandlerThread != null) {
+ mHandlerThread.quitSafely();
+ }
+ super.finalize();
+ }
+
/** @hide */
public void release() {
synchronized (mInterfaceLock) {
mInternalRepeatingRequestEnabled = false;
- mHandlerThread.quitSafely();
try {
mPreviewExtender.onDeInit();
@@ -750,6 +765,7 @@ public final class CameraExtensionSessionImpl extends CameraExtensionSession {
synchronized (mInterfaceLock) {
mCaptureSession = session;
try {
+ finishPipelineInitialization();
CameraExtensionCharacteristics.initializeSession(mInitializeHandler);
} catch (RemoteException e) {
Log.e(TAG, "Failed to initialize session! Extension service does"
@@ -1640,6 +1656,8 @@ public final class CameraExtensionSessionImpl extends CameraExtensionSession {
Log.e(TAG,"Failed to parcel buffer fence!");
}
}
+ parcelImage.width = img.getWidth();
+ parcelImage.height = img.getHeight();
parcelImage.format = img.getFormat();
parcelImage.timestamp = img.getTimestamp();
parcelImage.transform = img.getTransform();
diff --git a/core/java/android/hardware/camera2/impl/CameraExtensionUtils.java b/core/java/android/hardware/camera2/impl/CameraExtensionUtils.java
index 950d716b05e8..9acf9bf0c803 100644
--- a/core/java/android/hardware/camera2/impl/CameraExtensionUtils.java
+++ b/core/java/android/hardware/camera2/impl/CameraExtensionUtils.java
@@ -20,7 +20,6 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.graphics.ImageFormat;
import android.graphics.PixelFormat;
-import android.hardware.HardwareBuffer;
import android.hardware.camera2.CameraExtensionCharacteristics;
import android.hardware.camera2.params.OutputConfiguration;
import android.hardware.camera2.params.StreamConfigurationMap;
@@ -78,41 +77,20 @@ public final class CameraExtensionUtils {
SurfaceInfo surfaceInfo = new SurfaceInfo();
int nativeFormat = SurfaceUtils.getSurfaceFormat(s);
int dataspace = SurfaceUtils.getSurfaceDataspace(s);
+ Size surfaceSize = SurfaceUtils.getSurfaceSize(s);
+ surfaceInfo.mFormat = nativeFormat;
+ surfaceInfo.mWidth = surfaceSize.getWidth();
+ surfaceInfo.mHeight = surfaceSize.getHeight();
+ surfaceInfo.mUsage = SurfaceUtils.getSurfaceUsage(s);
// Jpeg surfaces cannot be queried for their usage and other parameters
// in the usual way below. A buffer can only be de-queued after the
// producer overrides the surface dimensions to (width*height) x 1.
if ((nativeFormat == StreamConfigurationMap.HAL_PIXEL_FORMAT_BLOB) &&
(dataspace == StreamConfigurationMap.HAL_DATASPACE_V0_JFIF)) {
surfaceInfo.mFormat = ImageFormat.JPEG;
- Size surfaceSize = SurfaceUtils.getSurfaceSize(s);
- surfaceInfo.mWidth = surfaceSize.getWidth();
- surfaceInfo.mHeight = surfaceSize.getHeight();
return surfaceInfo;
}
- HardwareBuffer buffer = null;
- try {
- writer = ImageWriter.newInstance(s, 1);
- img = writer.dequeueInputImage();
- buffer = img.getHardwareBuffer();
- surfaceInfo.mFormat = buffer.getFormat();
- surfaceInfo.mWidth = buffer.getWidth();
- surfaceInfo.mHeight = buffer.getHeight();
- surfaceInfo.mUsage = buffer.getUsage();
- } catch (Exception e) {
- Log.e(TAG, "Failed to query surface, returning defaults!");
- } finally {
- if (buffer != null) {
- buffer.close();
- }
- if (img != null) {
- img.close();
- }
- if (writer != null) {
- writer.close();
- }
- }
-
return surfaceInfo;
}
diff --git a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
index 6cbe107c96f5..8fd9a6abf7b6 100644
--- a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
+++ b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
@@ -53,6 +53,7 @@ import android.hardware.camera2.params.Capability;
import android.hardware.camera2.params.Face;
import android.hardware.camera2.params.HighSpeedVideoConfiguration;
import android.hardware.camera2.params.LensShadingMap;
+import android.hardware.camera2.params.MeteringRectangle;
import android.hardware.camera2.params.MandatoryStreamCombination;
import android.hardware.camera2.params.MultiResolutionStreamConfigurationMap;
import android.hardware.camera2.params.OisSample;
@@ -1708,6 +1709,34 @@ public class CameraMetadataNative implements Parcelable {
metadata.setGpsLocation((Location) value);
}
});
+ sSetCommandMap.put(CaptureRequest.SCALER_CROP_REGION.getNativeKey(),
+ new SetCommand() {
+ @Override
+ public <T> void setValue(CameraMetadataNative metadata, T value) {
+ metadata.setScalerCropRegion((Rect) value);
+ }
+ });
+ sSetCommandMap.put(CaptureRequest.CONTROL_AWB_REGIONS.getNativeKey(),
+ new SetCommand() {
+ @Override
+ public <T> void setValue(CameraMetadataNative metadata, T value) {
+ metadata.setAWBRegions((MeteringRectangle[]) value);
+ }
+ });
+ sSetCommandMap.put(CaptureRequest.CONTROL_AF_REGIONS.getNativeKey(),
+ new SetCommand() {
+ @Override
+ public <T> void setValue(CameraMetadataNative metadata, T value) {
+ metadata.setAFRegions((MeteringRectangle[]) value);
+ }
+ });
+ sSetCommandMap.put(CaptureRequest.CONTROL_AE_REGIONS.getNativeKey(),
+ new SetCommand() {
+ @Override
+ public <T> void setValue(CameraMetadataNative metadata, T value) {
+ metadata.setAERegions((MeteringRectangle[]) value);
+ }
+ });
}
private boolean setAvailableFormats(int[] value) {
@@ -1777,6 +1806,42 @@ public class CameraMetadataNative implements Parcelable {
return true;
}
+ private <T> boolean setScalerCropRegion(Rect cropRegion) {
+ if (cropRegion == null) {
+ return false;
+ }
+ setBase(CaptureRequest.SCALER_CROP_REGION_SET, true);
+ setBase(CaptureRequest.SCALER_CROP_REGION, cropRegion);
+ return true;
+ }
+
+ private <T> boolean setAFRegions(MeteringRectangle[] afRegions) {
+ if (afRegions == null) {
+ return false;
+ }
+ setBase(CaptureRequest.CONTROL_AF_REGIONS_SET, true);
+ setBase(CaptureRequest.CONTROL_AF_REGIONS, afRegions);
+ return true;
+ }
+
+ private <T> boolean setAERegions(MeteringRectangle[] aeRegions) {
+ if (aeRegions == null) {
+ return false;
+ }
+ setBase(CaptureRequest.CONTROL_AE_REGIONS_SET, true);
+ setBase(CaptureRequest.CONTROL_AE_REGIONS, aeRegions);
+ return true;
+ }
+
+ private <T> boolean setAWBRegions(MeteringRectangle[] awbRegions) {
+ if (awbRegions == null) {
+ return false;
+ }
+ setBase(CaptureRequest.CONTROL_AWB_REGIONS_SET, true);
+ setBase(CaptureRequest.CONTROL_AWB_REGIONS, awbRegions);
+ return true;
+ }
+
private void updateNativeAllocation() {
long currentBufferSize = nativeGetBufferSize(mMetadataPtr);
diff --git a/core/java/android/hardware/camera2/utils/SurfaceUtils.java b/core/java/android/hardware/camera2/utils/SurfaceUtils.java
index bde33e10e46c..bb1d10972cc3 100644
--- a/core/java/android/hardware/camera2/utils/SurfaceUtils.java
+++ b/core/java/android/hardware/camera2/utils/SurfaceUtils.java
@@ -110,6 +110,20 @@ public class SurfaceUtils {
}
/**
+ * Get the surface usage bits.
+ *
+ * @param surface The surface to be queried for usage.
+ * @return the native object id of the surface, 0 if surface is not backed by a native object.
+ */
+ public static long getSurfaceUsage(Surface surface) {
+ checkNotNull(surface);
+ try {
+ return nativeDetectSurfaceUsageFlags(surface);
+ } catch (IllegalArgumentException e) {
+ return 0;
+ }
+ }
+ /**
* Get the Surface size.
*
* @param surface The surface to be queried for size.
diff --git a/core/java/android/hardware/face/FaceManager.java b/core/java/android/hardware/face/FaceManager.java
index c2a2c4c0678c..3c3ba595f3fb 100644
--- a/core/java/android/hardware/face/FaceManager.java
+++ b/core/java/android/hardware/face/FaceManager.java
@@ -169,31 +169,6 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
}
/**
- * Request authentication of a crypto object. This call operates the face recognition hardware
- * and starts capturing images. It terminates when
- * {@link AuthenticationCallback#onAuthenticationError(int, CharSequence)} or
- * {@link AuthenticationCallback#onAuthenticationSucceeded(AuthenticationResult)} is called, at
- * which point the object is no longer valid. The operation can be canceled by using the
- * provided cancel object.
- *
- * @param crypto object associated with the call or null if none required.
- * @param cancel an object that can be used to cancel authentication
- * @param callback an object to receive authentication events
- * @param handler an optional handler to handle callback events
- * @throws IllegalArgumentException if the crypto operation is not supported or is not backed
- * by
- * <a href="{@docRoot}training/articles/keystore.html">Android
- * Keystore facility</a>.
- * @throws IllegalStateException if the crypto primitive is not initialized.
- * @hide
- */
- @RequiresPermission(USE_BIOMETRIC_INTERNAL)
- public void authenticate(@Nullable CryptoObject crypto, @Nullable CancellationSignal cancel,
- @NonNull AuthenticationCallback callback, @Nullable Handler handler) {
- authenticate(crypto, cancel, callback, handler, mContext.getUserId());
- }
-
- /**
* Use the provided handler thread for events.
*/
private void useHandler(Handler handler) {
@@ -224,8 +199,10 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
* @throws IllegalStateException if the crypto primitive is not initialized.
* @hide
*/
+ @RequiresPermission(USE_BIOMETRIC_INTERNAL)
public void authenticate(@Nullable CryptoObject crypto, @Nullable CancellationSignal cancel,
- @NonNull AuthenticationCallback callback, @Nullable Handler handler, int userId) {
+ @NonNull AuthenticationCallback callback, @Nullable Handler handler, int userId,
+ boolean isKeyguardBypassEnabled) {
if (callback == null) {
throw new IllegalArgumentException("Must supply an authentication callback");
}
@@ -247,7 +224,7 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
final long operationId = crypto != null ? crypto.getOpId() : 0;
Trace.beginSection("FaceManager#authenticate");
mService.authenticate(mToken, operationId, userId, mServiceReceiver,
- mContext.getOpPackageName());
+ mContext.getOpPackageName(), isKeyguardBypassEnabled);
} catch (RemoteException e) {
Slog.w(TAG, "Remote exception while authenticating: ", e);
if (callback != null) {
diff --git a/core/java/android/hardware/face/IFaceService.aidl b/core/java/android/hardware/face/IFaceService.aidl
index b9a49c6ced09..db02a0ef2a10 100644
--- a/core/java/android/hardware/face/IFaceService.aidl
+++ b/core/java/android/hardware/face/IFaceService.aidl
@@ -46,7 +46,7 @@ interface IFaceService {
// Authenticate the given sessionId with a face
void authenticate(IBinder token, long operationId, int userId, IFaceServiceReceiver receiver,
- String opPackageName);
+ String opPackageName, boolean isKeyguardBypassEnabled);
// Uses the face hardware to detect for the presence of a face, without giving details
// about accept/reject/lockout.
diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java
index f3e0ce9cd19e..1bc64951ad96 100644
--- a/core/java/android/os/FileUtils.java
+++ b/core/java/android/os/FileUtils.java
@@ -1460,15 +1460,15 @@ public final class FileUtils {
/** {@hide} */
@VisibleForTesting
public static ParcelFileDescriptor convertToModernFd(FileDescriptor fd) {
- try {
- Context context = AppGlobals.getInitialApplication();
- if (UserHandle.getAppId(Process.myUid()) == getMediaProviderAppId(context)) {
- // Never convert modern fd for MediaProvider, because this requires
- // MediaStore#scanFile and can cause infinite loops when MediaProvider scans
- return null;
- }
- return MediaStore.getOriginalMediaFormatFileDescriptor(context,
- ParcelFileDescriptor.dup(fd));
+ Context context = AppGlobals.getInitialApplication();
+ if (UserHandle.getAppId(Process.myUid()) == getMediaProviderAppId(context)) {
+ // Never convert modern fd for MediaProvider, because this requires
+ // MediaStore#scanFile and can cause infinite loops when MediaProvider scans
+ return null;
+ }
+
+ try (ParcelFileDescriptor dupFd = ParcelFileDescriptor.dup(fd)) {
+ return MediaStore.getOriginalMediaFormatFileDescriptor(context, dupFd);
} catch (Exception e) {
Log.d(TAG, "Failed to convert to modern format file descriptor", e);
return null;
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index 269c920f1193..1945a54128b6 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -34,12 +34,9 @@ import dalvik.system.VMRuntime;
import libcore.io.IoUtils;
-import java.io.BufferedReader;
import java.io.FileDescriptor;
-import java.io.FileReader;
import java.io.IOException;
import java.util.Map;
-import java.util.StringTokenizer;
import java.util.concurrent.TimeoutException;
/**
@@ -1497,43 +1494,4 @@ public class Process {
}
private static native int nativePidFdOpen(int pid, int flags) throws ErrnoException;
-
- /**
- * Checks if a process corresponding to a specific pid owns any file locks.
- * @param pid The process ID for which we want to know the existence of file locks.
- * @return true If the process holds any file locks, false otherwise.
- * @throws IOException if /proc/locks can't be accessed.
- *
- * @hide
- */
- public static boolean hasFileLocks(int pid) throws Exception {
- BufferedReader br = null;
-
- try {
- br = new BufferedReader(new FileReader("/proc/locks"));
- String line;
-
- while ((line = br.readLine()) != null) {
- StringTokenizer st = new StringTokenizer(line);
-
- for (int i = 0; i < 5 && st.hasMoreTokens(); i++) {
- String str = st.nextToken();
- try {
- if (i == 4 && Integer.parseInt(str) == pid) {
- return true;
- }
- } catch (NumberFormatException nfe) {
- throw new Exception("Exception parsing /proc/locks at \" "
- + line + " \", token #" + i);
- }
- }
- }
-
- return false;
- } finally {
- if (br != null) {
- br.close();
- }
- }
- }
}
diff --git a/core/java/android/os/Trace.java b/core/java/android/os/Trace.java
index c8cbc517b226..ddb6533547bb 100644
--- a/core/java/android/os/Trace.java
+++ b/core/java/android/os/Trace.java
@@ -102,8 +102,6 @@ public final class Trace {
/** @hide */
public static final long TRACE_TAG_RRO = 1L << 26;
/** @hide */
- public static final long TRACE_TAG_SYSPROP = 1L << 27;
- /** @hide */
public static final long TRACE_TAG_APEX_MANAGER = 1L << 18;
private static final long TRACE_TAG_NOT_READY = 1L << 63;
diff --git a/core/java/android/permission/IPermissionManager.aidl b/core/java/android/permission/IPermissionManager.aidl
index 9ab69552f1a0..4a94c32501a1 100644
--- a/core/java/android/permission/IPermissionManager.aidl
+++ b/core/java/android/permission/IPermissionManager.aidl
@@ -16,7 +16,7 @@
package android.permission;
-import android.content.AttributionSource;
+import android.content.AttributionSourceState;
import android.content.pm.ParceledListSlice;
import android.content.pm.PermissionGroupInfo;
import android.content.pm.PermissionInfo;
@@ -87,7 +87,7 @@ interface IPermissionManager {
boolean isAutoRevokeExempted(String packageName, int userId);
- void registerAttributionSource(in AttributionSource source);
+ void registerAttributionSource(in AttributionSourceState source);
- boolean isRegisteredAttributionSource(in AttributionSource source);
+ boolean isRegisteredAttributionSource(in AttributionSourceState source);
}
diff --git a/core/java/android/permission/PermissionManager.java b/core/java/android/permission/PermissionManager.java
index a52ede87880e..63bcc9c89ca9 100644
--- a/core/java/android/permission/PermissionManager.java
+++ b/core/java/android/permission/PermissionManager.java
@@ -1177,7 +1177,7 @@ public final class PermissionManager {
// enforcement we need to replace the binder with a unique one.
final AttributionSource registeredSource = source.withToken(new Binder());
try {
- mPermissionManager.registerAttributionSource(registeredSource);
+ mPermissionManager.registerAttributionSource(registeredSource.asState());
} catch (RemoteException e) {
e.rethrowFromSystemServer();
}
@@ -1196,7 +1196,7 @@ public final class PermissionManager {
*/
public boolean isRegisteredAttributionSource(@NonNull AttributionSource source) {
try {
- return mPermissionManager.isRegisteredAttributionSource(source);
+ return mPermissionManager.isRegisteredAttributionSource(source.asState());
} catch (RemoteException e) {
e.rethrowFromSystemServer();
}
diff --git a/core/java/android/service/voice/HotwordDetectionService.java b/core/java/android/service/voice/HotwordDetectionService.java
index a43523974480..e3bb589c9a19 100644
--- a/core/java/android/service/voice/HotwordDetectionService.java
+++ b/core/java/android/service/voice/HotwordDetectionService.java
@@ -72,8 +72,7 @@ import java.util.function.IntConsumer;
@SystemApi
public abstract class HotwordDetectionService extends Service {
private static final String TAG = "HotwordDetectionService";
- // TODO (b/177502877): Set the Debug flag to false before shipping.
- private static final boolean DBG = true;
+ private static final boolean DBG = false;
private static final long UPDATE_TIMEOUT_MILLIS = 5000;
@@ -151,9 +150,7 @@ public abstract class HotwordDetectionService extends Service {
@Override
public void updateState(PersistableBundle options, SharedMemory sharedMemory,
IRemoteCallback callback) throws RemoteException {
- if (DBG) {
- Log.d(TAG, "#updateState");
- }
+ Log.v(TAG, "#updateState" + (callback != null ? " with callback" : ""));
HotwordDetectionService.this.onUpdateStateInternal(
options,
sharedMemory,
diff --git a/core/java/android/service/voice/SoftwareHotwordDetector.java b/core/java/android/service/voice/SoftwareHotwordDetector.java
index fb540b1622e6..02294e5720ae 100644
--- a/core/java/android/service/voice/SoftwareHotwordDetector.java
+++ b/core/java/android/service/voice/SoftwareHotwordDetector.java
@@ -47,7 +47,7 @@ import java.io.PrintWriter;
**/
class SoftwareHotwordDetector extends AbstractHotwordDetector {
private static final String TAG = SoftwareHotwordDetector.class.getSimpleName();
- private static final boolean DEBUG = true;
+ private static final boolean DEBUG = false;
private final IVoiceInteractionManagerService mManagerService;
private final HotwordDetector.Callback mCallback;
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index 60eb4b67ce87..b8363c93933f 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -776,8 +776,10 @@ public abstract class WallpaperService extends Service {
WallpaperColors color = colors.get(i);
RectF area = regions.get(i);
if (color == null || area == null) {
- Log.wtf(TAG, "notifyLocalColorsChanged null values. color: "
- + color + " area " + area);
+ if (DEBUG) {
+ Log.e(TAG, "notifyLocalColorsChanged null values. color: "
+ + color + " area " + area);
+ }
continue;
}
try {
@@ -1033,6 +1035,9 @@ public abstract class WallpaperService extends Service {
.build();
updateSurfaceDimming();
}
+ // Propagate transform hint from WM so we can use the right hint for the
+ // first frame.
+ mBbqSurfaceControl.setTransformHint(mSurfaceControl.getTransformHint());
Surface blastSurface = getOrCreateBLASTSurface(mSurfaceSize.x,
mSurfaceSize.y, mFormat);
// If blastSurface == null that means it hasn't changed since the last
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 388ba5e1f7e0..b4e0de2cf7cf 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -148,6 +148,8 @@ public final class SurfaceControl implements Parcelable {
float width, float height, float vecX, float vecY,
float maxStretchAmountX, float maxStretchAmountY, float childRelativeLeft,
float childRelativeTop, float childRelativeRight, float childRelativeBottom);
+ private static native void nativeSetTrustedOverlay(long transactionObj, long nativeObject,
+ boolean isTrustedOverlay);
private static native boolean nativeClearContentFrameStats(long nativeObject);
private static native boolean nativeGetContentFrameStats(long nativeObject, WindowContentFrameStats outStats);
@@ -3416,6 +3418,17 @@ public final class SurfaceControl implements Parcelable {
return this;
}
+ /**
+ * Sets the trusted overlay state on this SurfaceControl and it is inherited to all the
+ * children. The caller must hold the ACCESS_SURFACE_FLINGER permission.
+ * @hide
+ */
+ public Transaction setTrustedOverlay(SurfaceControl sc, boolean isTrustedOverlay) {
+ checkPreconditions(sc);
+ nativeSetTrustedOverlay(mNativeObject, sc.mNativeObject, isTrustedOverlay);
+ return this;
+ }
+
/**
* Merge the other transaction into this transaction, clearing the
* other transaction as if it had been applied.
diff --git a/core/java/android/view/inputmethod/InputConnection.java b/core/java/android/view/inputmethod/InputConnection.java
index 38019c9a34f8..5f036a348808 100644
--- a/core/java/android/view/inputmethod/InputConnection.java
+++ b/core/java/android/view/inputmethod/InputConnection.java
@@ -1013,8 +1013,10 @@ public interface InputConnection {
*
* @param imeConsumesInput {@code true} when the IME is consuming input and the cursor should be
* hidden, {@code false} when input to the editor resumes and the cursor should be shown again.
- * @return {@code true} on success, {@code false} if the input connection is no longer valid, or
- * the protocol is not supported.
+ * @return For editor authors, the return value will always be ignored. For IME authors, this
+ * method returns {@code true} if the request was sent (whether or not the associated
+ * editor does something based on this request), {@code false} if the input connection
+ * is no longer valid.
*/
default boolean setImeConsumesInput(boolean imeConsumesInput) {
return false;
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index e827f0a31bfd..91fc5a56d979 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -5824,6 +5824,25 @@ public class RemoteViews implements Parcelable, Filter {
return false;
}
+ /** @hide */
+ public void updateAppInfo(@NonNull ApplicationInfo info) {
+ if (mApplication != null && mApplication.sourceDir.equals(info.sourceDir)) {
+ // Overlay paths are generated against a particular version of an application.
+ // The overlays paths of a newly upgraded application are incompatible with the
+ // old version of the application.
+ mApplication = info;
+ }
+ if (hasSizedRemoteViews()) {
+ for (RemoteViews layout : mSizedRemoteViews) {
+ layout.updateAppInfo(info);
+ }
+ }
+ if (hasLandscapeAndPortraitLayouts()) {
+ mLandscape.updateAppInfo(info);
+ mPortrait.updateAppInfo(info);
+ }
+ }
+
private Context getContextForResources(Context context) {
if (mApplication != null) {
if (context.getUserId() == UserHandle.getUserId(mApplication.uid)
diff --git a/core/java/android/window/SplashScreenView.java b/core/java/android/window/SplashScreenView.java
index 1efd2e381289..acf20d701eeb 100644
--- a/core/java/android/window/SplashScreenView.java
+++ b/core/java/android/window/SplashScreenView.java
@@ -89,11 +89,11 @@ public final class SplashScreenView extends FrameLayout {
private boolean mNotCopyable;
private boolean mIsCopied;
private int mInitBackgroundColor;
- private int mInitIconBackgroundColor;
private View mIconView;
private Bitmap mParceledIconBitmap;
private View mBrandingImageView;
private Bitmap mParceledBrandingBitmap;
+ private Bitmap mParceledIconBackgroundBitmap;
private Duration mIconAnimationDuration;
private Instant mIconAnimationStart;
@@ -130,11 +130,12 @@ public final class SplashScreenView extends FrameLayout {
private final Context mContext;
private int mIconSize;
private @ColorInt int mBackgroundColor;
- private @ColorInt int mIconBackground;
private Bitmap mParceledIconBitmap;
+ private Bitmap mParceledIconBackgroundBitmap;
private Drawable mIconDrawable;
// It is only set for legacy splash screen which won't be sent across processes.
private Drawable mOverlayDrawable;
+ private Drawable mIconBackground;
private SurfaceControlViewHost.SurfacePackage mSurfacePackage;
private RemoteCallback mClientCallback;
private int mBrandingImageWidth;
@@ -155,7 +156,6 @@ public final class SplashScreenView extends FrameLayout {
public Builder createFromParcel(SplashScreenViewParcelable parcelable) {
mIconSize = parcelable.getIconSize();
mBackgroundColor = parcelable.getBackgroundColor();
- mIconBackground = parcelable.getIconBackground();
mSurfacePackage = parcelable.mSurfacePackage;
if (mSurfacePackage == null && parcelable.mIconBitmap != null) {
// We only create a Bitmap copies of immobile icons since animated icon are using
@@ -163,6 +163,11 @@ public final class SplashScreenView extends FrameLayout {
mIconDrawable = new BitmapDrawable(mContext.getResources(), parcelable.mIconBitmap);
mParceledIconBitmap = parcelable.mIconBitmap;
}
+ if (parcelable.mIconBackground != null) {
+ mIconBackground = new BitmapDrawable(mContext.getResources(),
+ parcelable.mIconBackground);
+ mParceledIconBackgroundBitmap = parcelable.mIconBackground;
+ }
if (parcelable.mBrandingBitmap != null) {
setBrandingDrawable(new BitmapDrawable(mContext.getResources(),
parcelable.mBrandingBitmap), parcelable.mBrandingWidth,
@@ -213,8 +218,8 @@ public final class SplashScreenView extends FrameLayout {
/**
* Set the background color for the icon.
*/
- public Builder setIconBackground(int color) {
- mIconBackground = color;
+ public Builder setIconBackground(Drawable iconBackground) {
+ mIconBackground = iconBackground;
return this;
}
@@ -245,7 +250,6 @@ public final class SplashScreenView extends FrameLayout {
final SplashScreenView view = (SplashScreenView)
layoutInflater.inflate(R.layout.splash_screen_view, null, false);
view.mInitBackgroundColor = mBackgroundColor;
- view.mInitIconBackgroundColor = mIconBackground;
if (mOverlayDrawable != null) {
view.setBackground(mOverlayDrawable);
} else {
@@ -263,25 +267,29 @@ public final class SplashScreenView extends FrameLayout {
mIconAnimationDuration != null ? mIconAnimationDuration.toMillis() : 0);
view.mIconAnimationStart = mIconAnimationStart;
view.mIconAnimationDuration = mIconAnimationDuration;
- } else {
- view.mIconView = view.findViewById(R.id.splashscreen_icon_view);
- if (mIconSize != 0) {
- final ViewGroup.LayoutParams params = view.mIconView.getLayoutParams();
- params.width = mIconSize;
- params.height = mIconSize;
- view.mIconView.setLayoutParams(params);
- if (mIconDrawable != null) {
- view.mIconView.setBackground(mIconDrawable);
- }
+ } else if (mIconSize != 0) {
+ ImageView imageView = view.findViewById(R.id.splashscreen_icon_view);
+ assert imageView != null;
+
+ final ViewGroup.LayoutParams params = imageView.getLayoutParams();
+ params.width = mIconSize;
+ params.height = mIconSize;
+ imageView.setLayoutParams(params);
+ if (mIconDrawable != null) {
+ imageView.setImageDrawable(mIconDrawable);
}
+ if (mIconBackground != null) {
+ imageView.setBackground(mIconBackground);
+ }
+ view.mIconView = imageView;
}
if (mOverlayDrawable != null || mIconDrawable == null) {
view.setNotCopyable();
}
- if (mParceledIconBitmap != null) {
- view.mParceledIconBitmap = mParceledIconBitmap;
- }
+ view.mParceledIconBackgroundBitmap = mParceledIconBackgroundBitmap;
+ view.mParceledIconBitmap = mParceledIconBitmap;
+
// branding image
if (mBrandingImageHeight > 0 && mBrandingImageWidth > 0 && mBrandingDrawable != null) {
final ViewGroup.LayoutParams params = view.mBrandingImageView.getLayoutParams();
@@ -310,6 +318,7 @@ public final class SplashScreenView extends FrameLayout {
private SurfaceView createSurfaceView(@NonNull SplashScreenView view) {
final SurfaceView surfaceView = new SurfaceView(view.getContext());
surfaceView.setPadding(0, 0, 0, 0);
+ surfaceView.setBackground(mIconBackground);
if (mSurfacePackage == null) {
if (DEBUG) {
Log.d(TAG,
@@ -475,7 +484,11 @@ public final class SplashScreenView extends FrameLayout {
}
setVisibility(GONE);
if (mParceledIconBitmap != null) {
- mIconView.setBackground(null);
+ if (mIconView instanceof ImageView) {
+ ((ImageView) mIconView).setImageDrawable(null);
+ } else if (mIconView != null) {
+ mIconView.setBackground(null);
+ }
mParceledIconBitmap.recycle();
mParceledIconBitmap = null;
}
@@ -484,6 +497,13 @@ public final class SplashScreenView extends FrameLayout {
mParceledBrandingBitmap.recycle();
mParceledBrandingBitmap = null;
}
+ if (mParceledIconBackgroundBitmap != null) {
+ if (mIconView != null) {
+ mIconView.setBackground(null);
+ }
+ mParceledIconBackgroundBitmap.recycle();
+ mParceledIconBackgroundBitmap = null;
+ }
if (mWindow != null) {
final DecorView decorView = (DecorView) mWindow.peekDecorView();
if (DEBUG) {
@@ -600,15 +620,6 @@ public final class SplashScreenView extends FrameLayout {
}
/**
- * Get the icon background color
- * @hide
- */
- @TestApi
- public @ColorInt int getIconBackgroundColor() {
- return mInitIconBackgroundColor;
- }
-
- /**
* Get the initial background color of this view.
* @hide
*/
@@ -637,7 +648,7 @@ public final class SplashScreenView extends FrameLayout {
public static class SplashScreenViewParcelable implements Parcelable {
private int mIconSize;
private int mBackgroundColor;
- private int mIconBackground;
+ private Bitmap mIconBackground;
private Bitmap mIconBitmap = null;
private int mBrandingWidth;
@@ -653,11 +664,11 @@ public final class SplashScreenView extends FrameLayout {
public SplashScreenViewParcelable(SplashScreenView view) {
mIconSize = view.mIconView.getWidth();
mBackgroundColor = view.getInitBackgroundColor();
- mIconBackground = view.getIconBackgroundColor();
+ mIconBackground = copyDrawable(view.getIconView().getBackground());
mSurfacePackage = view.mSurfacePackageCopy;
if (mSurfacePackage == null) {
// We only need to copy the drawable if we are not using a SurfaceView
- mIconBitmap = copyDrawable(view.getIconView().getBackground());
+ mIconBitmap = copyDrawable(((ImageView) view.getIconView()).getDrawable());
}
mBrandingBitmap = copyDrawable(view.getBrandingView().getBackground());
@@ -703,7 +714,7 @@ public final class SplashScreenView extends FrameLayout {
mBrandingBitmap = source.readTypedObject(Bitmap.CREATOR);
mIconAnimationStartMillis = source.readLong();
mIconAnimationDurationMillis = source.readLong();
- mIconBackground = source.readInt();
+ mIconBackground = source.readTypedObject(Bitmap.CREATOR);
mSurfacePackage = source.readTypedObject(SurfaceControlViewHost.SurfacePackage.CREATOR);
mClientCallback = source.readTypedObject(RemoteCallback.CREATOR);
}
@@ -723,7 +734,7 @@ public final class SplashScreenView extends FrameLayout {
dest.writeTypedObject(mBrandingBitmap, flags);
dest.writeLong(mIconAnimationStartMillis);
dest.writeLong(mIconAnimationDurationMillis);
- dest.writeInt(mIconBackground);
+ dest.writeTypedObject(mIconBackground, flags);
dest.writeTypedObject(mSurfacePackage, flags);
dest.writeTypedObject(mClientCallback, flags);
}
@@ -760,10 +771,6 @@ public final class SplashScreenView extends FrameLayout {
return mBackgroundColor;
}
- int getIconBackground() {
- return mIconBackground;
- }
-
/**
* Sets the {@link RemoteCallback} that will be called by the client to notify the shell
* of the removal of the {@link SplashScreenView}.
diff --git a/core/java/android/window/StartingWindowInfo.java b/core/java/android/window/StartingWindowInfo.java
index 566f154fba3b..8c64474dc887 100644
--- a/core/java/android/window/StartingWindowInfo.java
+++ b/core/java/android/window/StartingWindowInfo.java
@@ -22,6 +22,7 @@ import android.annotation.Nullable;
import android.annotation.TestApi;
import android.app.ActivityManager;
import android.app.TaskInfo;
+import android.content.pm.ActivityInfo;
import android.os.Parcel;
import android.os.Parcelable;
import android.view.InsetsState;
@@ -78,6 +79,14 @@ public final class StartingWindowInfo implements Parcelable {
public ActivityManager.RunningTaskInfo taskInfo;
/**
+ * The {@link ActivityInfo} of the target activity which to create the starting window.
+ * It can be null if the info is the same as the top in task info.
+ * @hide
+ */
+ @Nullable
+ public ActivityInfo targetActivityInfo;
+
+ /**
* InsetsState of TopFullscreenOpaqueWindow
* @hide
*/
@@ -174,6 +183,7 @@ public final class StartingWindowInfo implements Parcelable {
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeTypedObject(taskInfo, flags);
+ dest.writeTypedObject(targetActivityInfo, flags);
dest.writeInt(startingWindowTypeParameter);
dest.writeTypedObject(topOpaqueWindowInsetsState, flags);
dest.writeTypedObject(topOpaqueWindowLayoutParams, flags);
@@ -185,6 +195,7 @@ public final class StartingWindowInfo implements Parcelable {
void readFromParcel(@NonNull Parcel source) {
taskInfo = source.readTypedObject(ActivityManager.RunningTaskInfo.CREATOR);
+ targetActivityInfo = source.readTypedObject(ActivityInfo.CREATOR);
startingWindowTypeParameter = source.readInt();
topOpaqueWindowInsetsState = source.readTypedObject(InsetsState.CREATOR);
topOpaqueWindowLayoutParams = source.readTypedObject(
@@ -198,6 +209,7 @@ public final class StartingWindowInfo implements Parcelable {
@Override
public String toString() {
return "StartingWindowInfo{taskId=" + taskInfo.taskId
+ + " targetActivityInfo=" + targetActivityInfo
+ " displayId=" + taskInfo.displayId
+ " topActivityType=" + taskInfo.topActivityType
+ " preferredStartingWindowType="
diff --git a/core/java/com/android/internal/app/AbstractResolverComparator.java b/core/java/com/android/internal/app/AbstractResolverComparator.java
index 40ada0b2ffdc..c00d16ca143e 100644
--- a/core/java/com/android/internal/app/AbstractResolverComparator.java
+++ b/core/java/com/android/internal/app/AbstractResolverComparator.java
@@ -22,6 +22,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
+import android.os.BadParcelableException;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
@@ -109,17 +110,22 @@ public abstract class AbstractResolverComparator implements Comparator<ResolvedC
// get annotations of content from intent.
private void getContentAnnotations(Intent intent) {
- ArrayList<String> annotations = intent.getStringArrayListExtra(
- Intent.EXTRA_CONTENT_ANNOTATIONS);
- if (annotations != null) {
- int size = annotations.size();
- if (size > NUM_OF_TOP_ANNOTATIONS_TO_USE) {
- size = NUM_OF_TOP_ANNOTATIONS_TO_USE;
- }
- mAnnotations = new String[size];
- for (int i = 0; i < size; i++) {
- mAnnotations[i] = annotations.get(i);
+ try {
+ ArrayList<String> annotations = intent.getStringArrayListExtra(
+ Intent.EXTRA_CONTENT_ANNOTATIONS);
+ if (annotations != null) {
+ int size = annotations.size();
+ if (size > NUM_OF_TOP_ANNOTATIONS_TO_USE) {
+ size = NUM_OF_TOP_ANNOTATIONS_TO_USE;
+ }
+ mAnnotations = new String[size];
+ for (int i = 0; i < size; i++) {
+ mAnnotations[i] = annotations.get(i);
+ }
}
+ } catch (BadParcelableException e) {
+ Log.i(TAG, "Couldn't unparcel intent annotations. Ignoring.");
+ mAnnotations = new String[0];
}
}
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index eeceafae531d..786af5f0823e 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -1269,7 +1269,8 @@ public class ChooserActivity extends ResolverActivity implements
SELECTION_TYPE_NEARBY,
"",
-1);
- safelyStartActivity(ti);
+ // Action bar is user-independent, always start as primary
+ safelyStartActivityAsUser(ti, getPersonalProfileUserHandle());
finish();
}
);
@@ -1290,7 +1291,8 @@ public class ChooserActivity extends ResolverActivity implements
SELECTION_TYPE_EDIT,
"",
-1);
- safelyStartActivity(ti);
+ // Action bar is user-independent, always start as primary
+ safelyStartActivityAsUser(ti, getPersonalProfileUserHandle());
finish();
}
);
@@ -3452,8 +3454,6 @@ public class ChooserActivity extends ResolverActivity implements
private View createProfileView(ViewGroup parent) {
View profileRow = mLayoutInflater.inflate(R.layout.chooser_profile_row, parent, false);
- profileRow.setBackground(
- getResources().getDrawable(R.drawable.chooser_row_layer_list, null));
mProfileView = profileRow.findViewById(R.id.profile_button);
mProfileView.setOnClickListener(ChooserActivity.this::onProfileClick);
updateProfileViewButton();
@@ -3599,10 +3599,6 @@ public class ChooserActivity extends ResolverActivity implements
final ViewGroup viewGroup = (ViewGroup) holder.itemView;
int start = getListPosition(position);
int startType = getRowType(start);
- if (viewGroup.getForeground() == null && position > 0) {
- viewGroup.setForeground(
- getResources().getDrawable(R.drawable.chooser_row_layer_list, null));
- }
int columnCount = holder.getColumnCount();
int end = start + columnCount - 1;
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 6f9da6fa94a3..d08f21c9f257 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -1257,13 +1257,32 @@ public class ResolverActivity extends Activity implements
// don't kill ourselves.
StrictMode.disableDeathOnFileUriExposure();
try {
- safelyStartActivityInternal(cti);
+ UserHandle currentUserHandle = mMultiProfilePagerAdapter.getCurrentUserHandle();
+ safelyStartActivityInternal(cti, currentUserHandle);
} finally {
StrictMode.enableDeathOnFileUriExposure();
}
}
- private void safelyStartActivityInternal(TargetInfo cti) {
+ /**
+ * Start activity as a fixed user handle.
+ * @param cti TargetInfo to be launched.
+ * @param user User to launch this activity as.
+ */
+ @VisibleForTesting
+ public void safelyStartActivityAsUser(TargetInfo cti, UserHandle user) {
+ // We're dispatching intents that might be coming from legacy apps, so
+ // don't kill ourselves.
+ StrictMode.disableDeathOnFileUriExposure();
+ try {
+ safelyStartActivityInternal(cti, user);
+ } finally {
+ StrictMode.enableDeathOnFileUriExposure();
+ }
+ }
+
+
+ private void safelyStartActivityInternal(TargetInfo cti, UserHandle user) {
// If the target is suspended, the activity will not be successfully launched.
// Do not unregister from package manager updates in this case
if (!cti.isSuspended() && mRegistered) {
@@ -1280,18 +1299,17 @@ public class ResolverActivity extends Activity implements
if (mProfileSwitchMessageId != -1) {
Toast.makeText(this, getString(mProfileSwitchMessageId), Toast.LENGTH_LONG).show();
}
- UserHandle currentUserHandle = mMultiProfilePagerAdapter.getCurrentUserHandle();
if (!mSafeForwardingMode) {
- if (cti.startAsUser(this, null, currentUserHandle)) {
+ if (cti.startAsUser(this, null, user)) {
onActivityStarted(cti);
- maybeLogCrossProfileTargetLaunch(cti, currentUserHandle);
+ maybeLogCrossProfileTargetLaunch(cti, user);
}
return;
}
try {
- if (cti.startAsCaller(this, null, currentUserHandle.getIdentifier())) {
+ if (cti.startAsCaller(this, null, user.getIdentifier())) {
onActivityStarted(cti);
- maybeLogCrossProfileTargetLaunch(cti, currentUserHandle);
+ maybeLogCrossProfileTargetLaunch(cti, user);
}
} catch (RuntimeException e) {
Slog.wtf(TAG, "Unable to launch as uid " + mLaunchedFromUid
diff --git a/core/java/com/android/internal/infra/AndroidFuture.java b/core/java/com/android/internal/infra/AndroidFuture.java
index db5d06635e94..84391c169941 100644
--- a/core/java/com/android/internal/infra/AndroidFuture.java
+++ b/core/java/com/android/internal/infra/AndroidFuture.java
@@ -24,6 +24,7 @@ import android.os.Looper;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.RemoteException;
+import android.util.EventLog;
import android.util.Log;
import com.android.internal.annotations.GuardedBy;
@@ -601,9 +602,14 @@ public class AndroidFuture<T> extends CompletableFuture<T> implements Parcelable
String messageWithStackTrace = message + '\n' + stackTrace;
Throwable throwable;
try {
- Class<?> clazz = Class.forName(className);
- Constructor<?> constructor = clazz.getConstructor(String.class);
- throwable = (Throwable) constructor.newInstance(messageWithStackTrace);
+ Class<?> clazz = Class.forName(className, true, Parcelable.class.getClassLoader());
+ if (Throwable.class.isAssignableFrom(clazz)) {
+ Constructor<?> constructor = clazz.getConstructor(String.class);
+ throwable = (Throwable) constructor.newInstance(messageWithStackTrace);
+ } else {
+ android.util.EventLog.writeEvent(0x534e4554, "186530450", -1, "");
+ throwable = new RuntimeException(className + ": " + messageWithStackTrace);
+ }
} catch (Throwable t) {
throwable = new RuntimeException(className + ": " + messageWithStackTrace);
throwable.addSuppressed(t);
diff --git a/core/java/com/android/internal/os/BinderCallsStats.java b/core/java/com/android/internal/os/BinderCallsStats.java
index 6ce7cea12dfa..be91aaca5d39 100644
--- a/core/java/com/android/internal/os/BinderCallsStats.java
+++ b/core/java/com/android/internal/os/BinderCallsStats.java
@@ -220,8 +220,9 @@ public class BinderCallsStats implements BinderInternal.Observer {
public CallSession callStarted(Binder binder, int code, int workSourceUid) {
noteNativeThreadId();
+ boolean collectCpu = canCollect();
// We always want to collect data for latency if it's enabled, regardless of device state.
- if (!mCollectLatencyData && !canCollect()) {
+ if (!mCollectLatencyData && !collectCpu) {
return null;
}
@@ -233,7 +234,7 @@ public class BinderCallsStats implements BinderInternal.Observer {
s.timeStarted = -1;
s.recordedCall = shouldRecordDetailedData();
- if (mRecordingAllTransactionsForUid || s.recordedCall) {
+ if (collectCpu && (mRecordingAllTransactionsForUid || s.recordedCall)) {
s.cpuTimeStarted = getThreadTimeMicro();
s.timeStarted = getElapsedRealtimeMicro();
} else if (mCollectLatencyData) {
diff --git a/core/java/com/android/internal/os/ProcLocksReader.java b/core/java/com/android/internal/os/ProcLocksReader.java
new file mode 100644
index 000000000000..bd3115fc5d4c
--- /dev/null
+++ b/core/java/com/android/internal/os/ProcLocksReader.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2021 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 com.android.internal.util.ProcFileReader;
+
+import libcore.io.IoUtils;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+
+/**
+ * Reads and parses {@code locks} files in the {@code proc} filesystem.
+ * A typical example of /proc/locks
+ *
+ * 1: POSIX ADVISORY READ 18403 fd:09:9070 1073741826 1073742335
+ * 2: POSIX ADVISORY WRITE 18292 fd:09:34062 0 EOF
+ * 2: -> POSIX ADVISORY WRITE 18291 fd:09:34062 0 EOF
+ * 2: -> POSIX ADVISORY WRITE 18293 fd:09:34062 0 EOF
+ * 3: POSIX ADVISORY READ 3888 fd:09:13992 128 128
+ * 4: POSIX ADVISORY READ 3888 fd:09:14230 1073741826 1073742335
+ */
+public class ProcLocksReader {
+ private final String mPath;
+
+ public ProcLocksReader() {
+ mPath = "/proc/locks";
+ }
+
+ public ProcLocksReader(String path) {
+ mPath = path;
+ }
+
+ /**
+ * Checks if a process corresponding to a specific pid owns any file locks.
+ * @param pid The process ID for which we want to know the existence of file locks.
+ * @return true If the process holds any file locks, false otherwise.
+ * @throws IOException if /proc/locks can't be accessed.
+ */
+ public boolean hasFileLocks(int pid) throws Exception {
+ ProcFileReader reader = null;
+ long last = -1;
+ long id; // ordinal position of the lock in the list
+ int owner; // the PID of the process that owns the lock
+
+ try {
+ reader = new ProcFileReader(new FileInputStream(mPath));
+
+ while (reader.hasMoreData()) {
+ id = reader.nextLong(true); // lock id
+ if (id == last) {
+ reader.finishLine(); // blocked lock
+ continue;
+ }
+
+ reader.nextIgnored(); // lock type: POSIX?
+ reader.nextIgnored(); // lock type: MANDATORY?
+ reader.nextIgnored(); // lock type: RW?
+
+ owner = reader.nextInt(); // pid
+ if (owner == pid) {
+ return true;
+ }
+ reader.finishLine();
+ last = id;
+ }
+ } catch (IOException e) {
+ // TODO: let ProcFileReader log the failed line
+ throw new Exception("Exception parsing /proc/locks");
+ } finally {
+ IoUtils.closeQuietly(reader);
+ }
+ return false;
+ }
+}
diff --git a/core/java/com/android/internal/util/ProcFileReader.java b/core/java/com/android/internal/util/ProcFileReader.java
index ead58c7de611..0dd8ad89df61 100644
--- a/core/java/com/android/internal/util/ProcFileReader.java
+++ b/core/java/com/android/internal/util/ProcFileReader.java
@@ -28,8 +28,8 @@ import java.nio.charset.StandardCharsets;
* requires each line boundary to be explicitly acknowledged using
* {@link #finishLine()}. Assumes {@link StandardCharsets#US_ASCII} encoding.
* <p>
- * Currently doesn't support formats based on {@code \0}, tabs, or repeated
- * delimiters.
+ * Currently doesn't support formats based on {@code \0}, tabs.
+ * Consecutive spaces are treated as a single delimiter.
*/
public class ProcFileReader implements Closeable {
private final InputStream mStream;
@@ -75,6 +75,11 @@ public class ProcFileReader implements Closeable {
private void consumeBuf(int count) throws IOException {
// TODO: consider moving to read pointer, but for now traceview says
// these copies aren't a bottleneck.
+
+ // skip all consecutive delimiters.
+ while (count < mTail && mBuffer[count] == ' ') {
+ count++;
+ }
System.arraycopy(mBuffer, count, mBuffer, 0, mTail - count);
mTail -= count;
if (mTail == 0) {
@@ -159,11 +164,18 @@ public class ProcFileReader implements Closeable {
* Parse and return next token as base-10 encoded {@code long}.
*/
public long nextLong() throws IOException {
+ return nextLong(false);
+ }
+
+ /**
+ * Parse and return next token as base-10 encoded {@code long}.
+ */
+ public long nextLong(boolean stopAtInvalid) throws IOException {
final int tokenIndex = nextTokenIndex();
if (tokenIndex == -1) {
throw new ProtocolException("Missing required long");
} else {
- return parseAndConsumeLong(tokenIndex);
+ return parseAndConsumeLong(tokenIndex, stopAtInvalid);
}
}
@@ -176,7 +188,7 @@ public class ProcFileReader implements Closeable {
if (tokenIndex == -1) {
return def;
} else {
- return parseAndConsumeLong(tokenIndex);
+ return parseAndConsumeLong(tokenIndex, false);
}
}
@@ -186,7 +198,10 @@ public class ProcFileReader implements Closeable {
return s;
}
- private long parseAndConsumeLong(int tokenIndex) throws IOException {
+ /**
+ * If stopAtInvalid is true, don't throw IOException but return whatever parsed so far.
+ */
+ private long parseAndConsumeLong(int tokenIndex, boolean stopAtInvalid) throws IOException {
final boolean negative = mBuffer[0] == '-';
// TODO: refactor into something like IntegralToString
@@ -194,7 +209,11 @@ public class ProcFileReader implements Closeable {
for (int i = negative ? 1 : 0; i < tokenIndex; i++) {
final int digit = mBuffer[i] - '0';
if (digit < 0 || digit > 9) {
- throw invalidLong(tokenIndex);
+ if (stopAtInvalid) {
+ break;
+ } else {
+ throw invalidLong(tokenIndex);
+ }
}
// always parse as negative number and apply sign later; this
@@ -226,6 +245,18 @@ public class ProcFileReader implements Closeable {
return (int) value;
}
+ /**
+ * Bypass the next token.
+ */
+ public void nextIgnored() throws IOException {
+ final int tokenIndex = nextTokenIndex();
+ if (tokenIndex == -1) {
+ throw new ProtocolException("Missing required token");
+ } else {
+ consumeBuf(tokenIndex + 1);
+ }
+ }
+
@Override
public void close() throws IOException {
mStream.close();
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 1695e1af9270..8d12df226ffe 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -823,6 +823,14 @@ static void nativeSetShadowRadius(JNIEnv* env, jclass clazz, jlong transactionOb
transaction->setShadowRadius(ctrl, shadowRadius);
}
+static void nativeSetTrustedOverlay(JNIEnv* env, jclass clazz, jlong transactionObj,
+ jlong nativeObject, jboolean isTrustedOverlay) {
+ auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+
+ SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
+ transaction->setTrustedOverlay(ctrl, isTrustedOverlay);
+}
+
static void nativeSetFrameRate(JNIEnv* env, jclass clazz, jlong transactionObj, jlong nativeObject,
jfloat frameRate, jint compatibility, jint changeFrameRateStrategy) {
auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
@@ -1984,6 +1992,8 @@ static const JNINativeMethod sSurfaceControlMethods[] = {
(void*)nativeSetTransformHint },
{"nativeGetTransformHint", "(J)I",
(void*)nativeGetTransformHint },
+ {"nativeSetTrustedOverlay", "(JJZ)V",
+ (void*)nativeSetTrustedOverlay },
// clang-format on
};
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index a530093def91..7ccc2f1a08aa 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -649,7 +649,11 @@
<protected-broadcast android:name="com.android.server.fingerprint.ACTION_LOCKOUT_RESET" />
<protected-broadcast android:name="android.net.wifi.PASSPOINT_ICON_RECEIVED" />
+
<protected-broadcast android:name="com.android.server.notification.CountdownConditionProvider" />
+ <protected-broadcast android:name="android.server.notification.action.ENABLE_NAS" />
+ <protected-broadcast android:name="android.server.notification.action.DISABLE_NAS" />
+ <protected-broadcast android:name="android.server.notification.action.LEARNMORE_NAS" />
<protected-broadcast android:name="com.android.internal.location.ALARM_WAKEUP" />
<protected-broadcast android:name="com.android.internal.location.ALARM_TIMEOUT" />
@@ -3541,7 +3545,7 @@
use by third party apps.
@hide -->
<permission android:name="android.permission.UPDATE_APP_OPS_STATS"
- android:protectionLevel="signature|privileged|installer" />
+ android:protectionLevel="signature|privileged|installer|role" />
<!-- @SystemApi Allows an application to update the user app op restrictions.
Not for use by third party apps.
diff --git a/core/res/res/drawable/chooser_row_layer_list.xml b/core/res/res/drawable/chooser_row_layer_list.xml
index 080081521ddf..f5ba1e9d633b 100644
--- a/core/res/res/drawable/chooser_row_layer_list.xml
+++ b/core/res/res/drawable/chooser_row_layer_list.xml
@@ -17,9 +17,11 @@
*/
-->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:bottom="-5dp" android:left="-5dp" android:right="-5dp">
+ <item>
<shape android:shape="rectangle">
- <stroke android:width="1dp" android:color="@color/chooser_row_divider"/>
+ <solid android:color="?android:attr/colorAccentSecondary"/>
+ <size android:width="128dp" android:height="2dp"/>
+ <corners android:radius="2dp" />
</shape>
</item>
</layer-list>
diff --git a/core/res/res/layout/chooser_az_label_row.xml b/core/res/res/layout/chooser_az_label_row.xml
index 1b733fc907cc..baf07cec9875 100644
--- a/core/res/res/layout/chooser_az_label_row.xml
+++ b/core/res/res/layout/chooser_az_label_row.xml
@@ -15,17 +15,12 @@
~ limitations under the License
-->
-<!-- Separator applied as background -->
-<TextView xmlns:android="http://schemas.android.com/apk/res/android"
- android:text="@string/chooser_all_apps_button_label"
+<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:contentDescription="@string/chooser_all_apps_button_label"
- android:background="@drawable/chooser_row_layer_list"
- android:textAppearance="?attr/textAppearanceSmall"
- android:textColor="?attr/textColorSecondary"
- android:textSize="14sp"
- android:singleLine="true"
+ android:src="@drawable/chooser_row_layer_list"
android:paddingTop="16dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:scaleType="center"
android:gravity="center"/>
diff --git a/core/res/res/layout/splash_screen_view.xml b/core/res/res/layout/splash_screen_view.xml
index 0b7b49cdea83..aa050f3a364d 100644
--- a/core/res/res/layout/splash_screen_view.xml
+++ b/core/res/res/layout/splash_screen_view.xml
@@ -21,12 +21,11 @@
android:padding="0dp"
android:orientation="vertical">
- <View android:id="@+id/splashscreen_icon_view"
+ <ImageView android:id="@+id/splashscreen_icon_view"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_gravity="center"
android:padding="0dp"
- android:background="@null"
android:contentDescription="@string/splash_screen_view_icon_description"/>
<View android:id="@+id/splashscreen_branding_view"
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index cf2f677dfb35..0310b181398d 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -2079,7 +2079,7 @@
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"قطع الاتصال"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"مكالمة واردة"</string>
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"مكالمة جارية"</string>
- <string name="call_notification_screening_text" msgid="8396931408268940208">"رصد مكالمة واردة"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"يتم فحص المكالمة الواردة"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="zero">تم اختيار <xliff:g id="COUNT_1">%1$d</xliff:g> عنصر</item>
<item quantity="two">تم اختيار عنصرين (<xliff:g id="COUNT_1">%1$d</xliff:g>)</item>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 0970fc50da49..2d94ffe2b0eb 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -1248,9 +1248,9 @@
<string name="whichImageCaptureApplication" msgid="2737413019463215284">"Зрабіць здымак з дапамогай"</string>
<string name="whichImageCaptureApplicationNamed" msgid="8820702441847612202">"Зрабіць здымак з дапамогай %1$s"</string>
<string name="whichImageCaptureApplicationLabel" msgid="6505433734824988277">"Зрабіць здымак"</string>
- <string name="alwaysUse" msgid="3153558199076112903">"Выкарыстоўваць па змаўчанні для гэтага дзеяння."</string>
+ <string name="alwaysUse" msgid="3153558199076112903">"Выкарыстоўваць стандартна для гэтага дзеяння."</string>
<string name="use_a_different_app" msgid="4987790276170972776">"Выкарыстоўваць іншую праграму"</string>
- <string name="clearDefaultHintMsg" msgid="1325866337702524936">"Ачысціць па змаўчанні ў раздзеле \"Налады сістэмы &gt; Прыкладанні &gt; Спампаваныя\"."</string>
+ <string name="clearDefaultHintMsg" msgid="1325866337702524936">"Ачысціць стандартныя налады ў раздзеле \"Налады сістэмы &gt; Праграмы &gt; Спампаваныя\"."</string>
<string name="chooseActivity" msgid="8563390197659779956">"Выберыце дзеянне"</string>
<string name="chooseUsbActivity" msgid="2096269989990986612">"Выберыце прыкладанне для USB-прылады"</string>
<string name="noApplications" msgid="1186909265235544019">"Няма прыкладанняў, якія могуць выконваць гэты працэс."</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 542387f2047e..199e82f9d170 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -984,7 +984,7 @@
<string name="js_dialog_before_unload" msgid="7213364985774778744">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nMöchtest du diese Seite wirklich verlassen?"</string>
<string name="save_password_label" msgid="9161712335355510035">"Bestätigen"</string>
<string name="double_tap_toast" msgid="7065519579174882778">"Tipp: Zum Vergrößern und Verkleinern doppeltippen"</string>
- <string name="autofill_this_form" msgid="3187132440451621492">"AutoFill"</string>
+ <string name="autofill_this_form" msgid="3187132440451621492">"Automatisches Ausfüllen"</string>
<string name="setup_autofill" msgid="5431369130866618567">"Autom.Ausfüll.konf."</string>
<string name="autofill_window_title" msgid="4379134104008111961">"Mit <xliff:g id="SERVICENAME">%1$s</xliff:g> automatisch ausfüllen"</string>
<string name="autofill_address_name_separator" msgid="8190155636149596125">" "</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 141cf4e60e94..8cf968d503a7 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -700,8 +700,8 @@
<string name="permdesc_bindConditionProviderService" msgid="6106018791256120258">"Allows the holder to bind to the top-level interface of a condition provider service. Should never be needed for normal apps."</string>
<string name="permlab_bindDreamService" msgid="4776175992848982706">"bind to a dream service"</string>
<string name="permdesc_bindDreamService" msgid="9129615743300572973">"Allows the holder to bind to the top-level interface of a dream service. Should never be needed for normal apps."</string>
- <string name="permlab_invokeCarrierSetup" msgid="5098810760209818140">"invoke the carrier-provided configuration app"</string>
- <string name="permdesc_invokeCarrierSetup" msgid="4790845896063237887">"Allows the holder to invoke the carrier-provided configuration app. Should never be needed for normal apps."</string>
+ <string name="permlab_invokeCarrierSetup" msgid="5098810760209818140">"invoke the operator-provided configuration app"</string>
+ <string name="permdesc_invokeCarrierSetup" msgid="4790845896063237887">"Allows the holder to invoke the operator-provided configuration app. Should never be needed for normal apps."</string>
<string name="permlab_accessNetworkConditions" msgid="1270732533356286514">"listen for observations on network conditions"</string>
<string name="permdesc_accessNetworkConditions" msgid="2959269186741956109">"Allows an application to listen for observations on network conditions. Should never be needed for normal apps."</string>
<string name="permlab_setInputCalibration" msgid="932069700285223434">"change input device calibration"</string>
@@ -712,8 +712,8 @@
<string name="permdesc_handoverStatus" msgid="3842269451732571070">"Allows this application to receive information about current Android Beam transfers"</string>
<string name="permlab_removeDrmCertificates" msgid="710576248717404416">"remove DRM certificates"</string>
<string name="permdesc_removeDrmCertificates" msgid="4068445390318355716">"Allows an application to remove DRM certficates. Should never be needed for normal apps."</string>
- <string name="permlab_bindCarrierMessagingService" msgid="3363450860593096967">"bind to a carrier messaging service"</string>
- <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Allows the holder to bind to the top-level interface of a carrier messaging service. Should never be needed for normal apps."</string>
+ <string name="permlab_bindCarrierMessagingService" msgid="3363450860593096967">"bind to an operator messaging service"</string>
+ <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Allows the holder to bind to the top-level interface of an operator messaging service. Should never be needed for normal apps."</string>
<string name="permlab_bindCarrierServices" msgid="2395596978626237474">"bind to operator services"</string>
<string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Allows the holder to bind to operator services. Should never be needed for normal apps."</string>
<string name="permlab_access_notification_policy" msgid="5524112842876975537">"access Do Not Disturb"</string>
@@ -1655,7 +1655,7 @@
<string name="kg_sim_pin_instructions" msgid="6479401489471690359">"Enter SIM PIN"</string>
<string name="kg_pin_instructions" msgid="7355933174673539021">"Enter PIN"</string>
<string name="kg_password_instructions" msgid="7179782578809398050">"Enter Password"</string>
- <string name="kg_puk_enter_puk_hint" msgid="6696187482616360994">"SIM is now disabled. Enter PUK code to continue. Contact carrier for details."</string>
+ <string name="kg_puk_enter_puk_hint" msgid="6696187482616360994">"SIM is now disabled. Enter PUK code to continue. Contact operator for details."</string>
<string name="kg_puk_enter_pin_hint" msgid="8190982314659429770">"Enter desired PIN code"</string>
<string name="kg_enter_confirm_pin_hint" msgid="6372557107414074580">"Confirm desired PIN code"</string>
<string name="kg_sim_unlock_progress_dialog_message" msgid="8871937892678885545">"Unlocking SIM card…"</string>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index 2b1d3e0708f2..b772335a6438 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -700,8 +700,8 @@
<string name="permdesc_bindConditionProviderService" msgid="6106018791256120258">"Allows the holder to bind to the top-level interface of a condition provider service. Should never be needed for normal apps."</string>
<string name="permlab_bindDreamService" msgid="4776175992848982706">"bind to a dream service"</string>
<string name="permdesc_bindDreamService" msgid="9129615743300572973">"Allows the holder to bind to the top-level interface of a dream service. Should never be needed for normal apps."</string>
- <string name="permlab_invokeCarrierSetup" msgid="5098810760209818140">"invoke the carrier-provided configuration app"</string>
- <string name="permdesc_invokeCarrierSetup" msgid="4790845896063237887">"Allows the holder to invoke the carrier-provided configuration app. Should never be needed for normal apps."</string>
+ <string name="permlab_invokeCarrierSetup" msgid="5098810760209818140">"invoke the operator-provided configuration app"</string>
+ <string name="permdesc_invokeCarrierSetup" msgid="4790845896063237887">"Allows the holder to invoke the operator-provided configuration app. Should never be needed for normal apps."</string>
<string name="permlab_accessNetworkConditions" msgid="1270732533356286514">"listen for observations on network conditions"</string>
<string name="permdesc_accessNetworkConditions" msgid="2959269186741956109">"Allows an application to listen for observations on network conditions. Should never be needed for normal apps."</string>
<string name="permlab_setInputCalibration" msgid="932069700285223434">"change input device calibration"</string>
@@ -712,8 +712,8 @@
<string name="permdesc_handoverStatus" msgid="3842269451732571070">"Allows this application to receive information about current Android Beam transfers"</string>
<string name="permlab_removeDrmCertificates" msgid="710576248717404416">"remove DRM certificates"</string>
<string name="permdesc_removeDrmCertificates" msgid="4068445390318355716">"Allows an application to remove DRM certficates. Should never be needed for normal apps."</string>
- <string name="permlab_bindCarrierMessagingService" msgid="3363450860593096967">"bind to a carrier messaging service"</string>
- <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Allows the holder to bind to the top-level interface of a carrier messaging service. Should never be needed for normal apps."</string>
+ <string name="permlab_bindCarrierMessagingService" msgid="3363450860593096967">"bind to an operator messaging service"</string>
+ <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Allows the holder to bind to the top-level interface of an operator messaging service. Should never be needed for normal apps."</string>
<string name="permlab_bindCarrierServices" msgid="2395596978626237474">"bind to operator services"</string>
<string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Allows the holder to bind to operator services. Should never be needed for normal apps."</string>
<string name="permlab_access_notification_policy" msgid="5524112842876975537">"access Do Not Disturb"</string>
@@ -1655,7 +1655,7 @@
<string name="kg_sim_pin_instructions" msgid="6479401489471690359">"Enter SIM PIN"</string>
<string name="kg_pin_instructions" msgid="7355933174673539021">"Enter PIN"</string>
<string name="kg_password_instructions" msgid="7179782578809398050">"Enter Password"</string>
- <string name="kg_puk_enter_puk_hint" msgid="6696187482616360994">"SIM is now disabled. Enter PUK code to continue. Contact carrier for details."</string>
+ <string name="kg_puk_enter_puk_hint" msgid="6696187482616360994">"SIM is now disabled. Enter PUK code to continue. Contact operator for details."</string>
<string name="kg_puk_enter_pin_hint" msgid="8190982314659429770">"Enter desired PIN code"</string>
<string name="kg_enter_confirm_pin_hint" msgid="6372557107414074580">"Confirm desired PIN code"</string>
<string name="kg_sim_unlock_progress_dialog_message" msgid="8871937892678885545">"Unlocking SIM card…"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 01d8b392e90a..e1e81870cfa3 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -700,8 +700,8 @@
<string name="permdesc_bindConditionProviderService" msgid="6106018791256120258">"Allows the holder to bind to the top-level interface of a condition provider service. Should never be needed for normal apps."</string>
<string name="permlab_bindDreamService" msgid="4776175992848982706">"bind to a dream service"</string>
<string name="permdesc_bindDreamService" msgid="9129615743300572973">"Allows the holder to bind to the top-level interface of a dream service. Should never be needed for normal apps."</string>
- <string name="permlab_invokeCarrierSetup" msgid="5098810760209818140">"invoke the carrier-provided configuration app"</string>
- <string name="permdesc_invokeCarrierSetup" msgid="4790845896063237887">"Allows the holder to invoke the carrier-provided configuration app. Should never be needed for normal apps."</string>
+ <string name="permlab_invokeCarrierSetup" msgid="5098810760209818140">"invoke the operator-provided configuration app"</string>
+ <string name="permdesc_invokeCarrierSetup" msgid="4790845896063237887">"Allows the holder to invoke the operator-provided configuration app. Should never be needed for normal apps."</string>
<string name="permlab_accessNetworkConditions" msgid="1270732533356286514">"listen for observations on network conditions"</string>
<string name="permdesc_accessNetworkConditions" msgid="2959269186741956109">"Allows an application to listen for observations on network conditions. Should never be needed for normal apps."</string>
<string name="permlab_setInputCalibration" msgid="932069700285223434">"change input device calibration"</string>
@@ -712,8 +712,8 @@
<string name="permdesc_handoverStatus" msgid="3842269451732571070">"Allows this application to receive information about current Android Beam transfers"</string>
<string name="permlab_removeDrmCertificates" msgid="710576248717404416">"remove DRM certificates"</string>
<string name="permdesc_removeDrmCertificates" msgid="4068445390318355716">"Allows an application to remove DRM certficates. Should never be needed for normal apps."</string>
- <string name="permlab_bindCarrierMessagingService" msgid="3363450860593096967">"bind to a carrier messaging service"</string>
- <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Allows the holder to bind to the top-level interface of a carrier messaging service. Should never be needed for normal apps."</string>
+ <string name="permlab_bindCarrierMessagingService" msgid="3363450860593096967">"bind to an operator messaging service"</string>
+ <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Allows the holder to bind to the top-level interface of an operator messaging service. Should never be needed for normal apps."</string>
<string name="permlab_bindCarrierServices" msgid="2395596978626237474">"bind to operator services"</string>
<string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Allows the holder to bind to operator services. Should never be needed for normal apps."</string>
<string name="permlab_access_notification_policy" msgid="5524112842876975537">"access Do Not Disturb"</string>
@@ -1655,7 +1655,7 @@
<string name="kg_sim_pin_instructions" msgid="6479401489471690359">"Enter SIM PIN"</string>
<string name="kg_pin_instructions" msgid="7355933174673539021">"Enter PIN"</string>
<string name="kg_password_instructions" msgid="7179782578809398050">"Enter Password"</string>
- <string name="kg_puk_enter_puk_hint" msgid="6696187482616360994">"SIM is now disabled. Enter PUK code to continue. Contact carrier for details."</string>
+ <string name="kg_puk_enter_puk_hint" msgid="6696187482616360994">"SIM is now disabled. Enter PUK code to continue. Contact operator for details."</string>
<string name="kg_puk_enter_pin_hint" msgid="8190982314659429770">"Enter desired PIN code"</string>
<string name="kg_enter_confirm_pin_hint" msgid="6372557107414074580">"Confirm desired PIN code"</string>
<string name="kg_sim_unlock_progress_dialog_message" msgid="8871937892678885545">"Unlocking SIM card…"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 3ed0279fb8f2..892041c2332d 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -700,8 +700,8 @@
<string name="permdesc_bindConditionProviderService" msgid="6106018791256120258">"Allows the holder to bind to the top-level interface of a condition provider service. Should never be needed for normal apps."</string>
<string name="permlab_bindDreamService" msgid="4776175992848982706">"bind to a dream service"</string>
<string name="permdesc_bindDreamService" msgid="9129615743300572973">"Allows the holder to bind to the top-level interface of a dream service. Should never be needed for normal apps."</string>
- <string name="permlab_invokeCarrierSetup" msgid="5098810760209818140">"invoke the carrier-provided configuration app"</string>
- <string name="permdesc_invokeCarrierSetup" msgid="4790845896063237887">"Allows the holder to invoke the carrier-provided configuration app. Should never be needed for normal apps."</string>
+ <string name="permlab_invokeCarrierSetup" msgid="5098810760209818140">"invoke the operator-provided configuration app"</string>
+ <string name="permdesc_invokeCarrierSetup" msgid="4790845896063237887">"Allows the holder to invoke the operator-provided configuration app. Should never be needed for normal apps."</string>
<string name="permlab_accessNetworkConditions" msgid="1270732533356286514">"listen for observations on network conditions"</string>
<string name="permdesc_accessNetworkConditions" msgid="2959269186741956109">"Allows an application to listen for observations on network conditions. Should never be needed for normal apps."</string>
<string name="permlab_setInputCalibration" msgid="932069700285223434">"change input device calibration"</string>
@@ -712,8 +712,8 @@
<string name="permdesc_handoverStatus" msgid="3842269451732571070">"Allows this application to receive information about current Android Beam transfers"</string>
<string name="permlab_removeDrmCertificates" msgid="710576248717404416">"remove DRM certificates"</string>
<string name="permdesc_removeDrmCertificates" msgid="4068445390318355716">"Allows an application to remove DRM certficates. Should never be needed for normal apps."</string>
- <string name="permlab_bindCarrierMessagingService" msgid="3363450860593096967">"bind to a carrier messaging service"</string>
- <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Allows the holder to bind to the top-level interface of a carrier messaging service. Should never be needed for normal apps."</string>
+ <string name="permlab_bindCarrierMessagingService" msgid="3363450860593096967">"bind to an operator messaging service"</string>
+ <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Allows the holder to bind to the top-level interface of an operator messaging service. Should never be needed for normal apps."</string>
<string name="permlab_bindCarrierServices" msgid="2395596978626237474">"bind to operator services"</string>
<string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Allows the holder to bind to operator services. Should never be needed for normal apps."</string>
<string name="permlab_access_notification_policy" msgid="5524112842876975537">"access Do Not Disturb"</string>
@@ -1655,7 +1655,7 @@
<string name="kg_sim_pin_instructions" msgid="6479401489471690359">"Enter SIM PIN"</string>
<string name="kg_pin_instructions" msgid="7355933174673539021">"Enter PIN"</string>
<string name="kg_password_instructions" msgid="7179782578809398050">"Enter Password"</string>
- <string name="kg_puk_enter_puk_hint" msgid="6696187482616360994">"SIM is now disabled. Enter PUK code to continue. Contact carrier for details."</string>
+ <string name="kg_puk_enter_puk_hint" msgid="6696187482616360994">"SIM is now disabled. Enter PUK code to continue. Contact operator for details."</string>
<string name="kg_puk_enter_pin_hint" msgid="8190982314659429770">"Enter desired PIN code"</string>
<string name="kg_enter_confirm_pin_hint" msgid="6372557107414074580">"Confirm desired PIN code"</string>
<string name="kg_sim_unlock_progress_dialog_message" msgid="8871937892678885545">"Unlocking SIM card…"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 8c465f174a96..9a29addc10b0 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -244,7 +244,7 @@
<string name="global_actions" product="default" msgid="6410072189971495460">"Opciones del teléfono"</string>
<string name="global_action_lock" msgid="6949357274257655383">"Bloqueo de pantalla"</string>
<string name="global_action_power_off" msgid="4404936470711393203">"Apagar"</string>
- <string name="global_action_power_options" msgid="1185286119330160073">"Encender o apagar"</string>
+ <string name="global_action_power_options" msgid="1185286119330160073">"Apagar o reiniciar"</string>
<string name="global_action_restart" msgid="4678451019561687074">"Reiniciar"</string>
<string name="global_action_emergency" msgid="1387617624177105088">"Emergencia"</string>
<string name="global_action_bug_report" msgid="5127867163044170003">"Informe de errores"</string>
@@ -271,7 +271,7 @@
<string name="global_action_settings" msgid="4671878836947494217">"Ajustes"</string>
<string name="global_action_assist" msgid="2517047220311505805">"Asistencia"</string>
<string name="global_action_voice_assist" msgid="6655788068555086695">"Asistente voz"</string>
- <string name="global_action_lockdown" msgid="2475471405907902963">"Bloqueo seguro"</string>
+ <string name="global_action_lockdown" msgid="2475471405907902963">"Bloqueo de seguridad"</string>
<string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"&gt; 999"</string>
<string name="notification_hidden_text" msgid="2835519769868187223">"Notificación nueva"</string>
<string name="notification_channel_virtual_keyboard" msgid="6465975799223304567">"Teclado virtual"</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 5add36bd2005..e473ab670e75 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -34,7 +34,7 @@
<string name="defaultMsisdnAlphaTag" msgid="2285034592902077488">"MSISDN1"</string>
<string name="mmiError" msgid="2862759606579822246">"કનેક્શન સમસ્યા અથવા અમાન્ય MMI કોડ."</string>
<string name="mmiFdnError" msgid="3975490266767565852">"ઑપરેશન ફક્ત સ્થિર ડાયલિંગ નંબર્સ પર પ્રતિબંધિત છે."</string>
- <string name="mmiErrorWhileRoaming" msgid="1204173664713870114">"તમે રોમિંગમાં હોવ તે વખતે તમારા ફોન પરથી કૉલ ફોરવર્ડિગ સેટિંગ્સ બદલી શકતાં નથી."</string>
+ <string name="mmiErrorWhileRoaming" msgid="1204173664713870114">"તમે રોમિંગમાં હો તે વખતે તમારા ફોન પરથી કૉલ ફૉરવર્ડિગ સેટિંગ બદલી શકતાં નથી."</string>
<string name="serviceEnabled" msgid="7549025003394765639">"સેવા સક્ષમ હતી."</string>
<string name="serviceEnabledFor" msgid="1463104778656711613">"સેવા આ માટે સક્ષમ હતી:"</string>
<string name="serviceDisabled" msgid="641878791205871379">"સેવા અક્ષમ કરવામાં આવી છે."</string>
@@ -124,7 +124,7 @@
<string name="roamingTextSearching" msgid="5323235489657753486">"સેવા શોધી રહ્યું છે"</string>
<string name="wfcRegErrorTitle" msgid="3193072971584858020">"વાઇ-ફાઇ કૉલિંગ સેટ કરી શકાયું નથી"</string>
<string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="468830943567116703">"વાઇ-ફાઇ પરથી કૉલ કરવા અને સંદેશા મોકલવા માટે પહેલાં તમારા કૅરિઅરને આ સેવા સેટ કરવા માટે કહો. પછી સેટિંગ્સમાંથી વાઇ-ફાઇ કૉલિંગ ફરીથી ચાલુ કરો. (ભૂલ કોડ: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
+ <item msgid="468830943567116703">"વાઇ-ફાઇ પરથી કૉલ કરવા અને સંદેશા મોકલવા માટે પહેલાં તમારા કૅરિઅરને આ સેવા સેટ કરવા માટે કહો. પછી સેટિંગમાંથી વાઇ-ફાઇ કૉલિંગ ફરીથી ચાલુ કરો. (ભૂલ કોડ: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
<item msgid="4795145070505729156">"તમારા કૅરિઅરમાં વાઇ-ફાઇ કૉલિંગ રજિસ્ટર કરવામાં સમસ્યા આવી: <xliff:g id="CODE">%1$s</xliff:g>"</item>
@@ -401,7 +401,7 @@
<string name="permlab_getPackageSize" msgid="375391550792886641">"ઍપ્લિકેશન સંગ્રહ સ્થાન માપો"</string>
<string name="permdesc_getPackageSize" msgid="742743530909966782">"એપ્લિકેશનને તેનો કોડ, ડેટા અને કેશ કદ પુનઃપ્રાપ્ત કરવાની મંજૂરી આપે છે."</string>
<string name="permlab_writeSettings" msgid="8057285063719277394">"સિસ્ટમ સેટિંગમાં ફેરફાર કરો"</string>
- <string name="permdesc_writeSettings" msgid="8293047411196067188">"એપ્લિકેશનને તમારા સિસ્ટમના સેટિંગ્સ ડેટાને સંશોધિત કરવાની મંજૂરી આપે છે. દુર્ભાવનાપૂર્ણ ઍપ્લિકેશનો તમારા સિસ્ટમની ગોઠવણીને દૂષિત કરી શકે છે."</string>
+ <string name="permdesc_writeSettings" msgid="8293047411196067188">"ઍપને તમારા સિસ્ટમના સેટિંગ ડેટાને સંશોધિત કરવાની મંજૂરી આપે છે. દુર્ભાવનાપૂર્ણ ઍપ તમારા સિસ્ટમની ગોઠવણીને દૂષિત કરી શકે છે."</string>
<string name="permlab_receiveBootCompleted" msgid="6643339400247325379">"સ્ટાર્ટઅપ પર શરૂ કરો"</string>
<string name="permdesc_receiveBootCompleted" product="tablet" msgid="5565659082718177484">"એપ્લિકેશનને સિસ્ટમ બૂટ થવાનું સમાપ્ત કરી લે કે તરત જ પોતાની જાતે પ્રારંભ થવાની મંજૂરી આપે છે. આનાથી ટેબ્લેટને પ્રારંભ થવામાં વધુ લાંબો સમય લાગી શકે છે અને એપ્લિકેશનને હંમેશા ચાલુ રહીને ટેબ્લેટને એકંદર ધીમું કરવાની મંજૂરી આપી શકે છે."</string>
<string name="permdesc_receiveBootCompleted" product="tv" msgid="4900842256047614307">"ઍપને સિસ્ટમ બૂટ થવાનું સમાપ્ત કરી લે કે તરત જ પોતાની જાતે પ્રારંભ થવાની મંજૂરી આપે છે. આનાથી તમારા Android TV ડિવાઇસને શરૂ થવામાં વધુ સમય લાગી શકે છે અને ઍપને હંમેશાં ચાલુ રહીને ડિવાઇસને એકંદર ધીમું કરવાની મંજૂરી આપે છે."</string>
@@ -442,8 +442,8 @@
<string name="permdesc_accessCoarseLocation" msgid="778521847873199160">"ઍપ ઉપયોગમાં હોય તે વખતે સ્થાન સેવાઓમાંથી આ ઍપ તમારું અંદાજિત સ્થાન મેળવી શકે છે. ઍપ સ્થાન મેળવી શકે તે માટે તમારા ડિવાઇસમાં સ્થાન સેવાઓ ચાલુ કરેલી હોવી જરૂરી છે."</string>
<string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"બૅકગ્રાઉન્ડમાં સ્થાન ઍક્સેસ કરો"</string>
<string name="permdesc_accessBackgroundLocation" msgid="8264885066095638105">"આ ઍપ કોઈપણ સમયે સ્થાનને ઍક્સેસ કરી શકે છે, પછી ભલેને આ ઍપ ઉપયોગમાં ન હોય."</string>
- <string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"તમારી ઑડિઓ સેટિંગ્સ બદલો"</string>
- <string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"એપ્લિકેશનને વૈશ્વિક ઑડિઓ સેટિંગ્સને સંશોધિત કરવાની મંજૂરી આપે છે, જેમ કે વૉલ્યૂમ અને આઉટપુટ માટે કયા સ્પીકરનો ઉપયોગ કરવો."</string>
+ <string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"તમારા ઑડિયો સેટિંગ બદલો"</string>
+ <string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"ઍપને વૈશ્વિક ઑડિયો સેટિંગમાં ફેરફાર કરવાની મંજૂરી આપે છે, જેમ કે વૉલ્યૂમ અને આઉટપુટ માટે કયા સ્પીકરનો ઉપયોગ કરવો."</string>
<string name="permlab_recordAudio" msgid="1208457423054219147">"ઑડિઓ રેકોર્ડ કરવાની"</string>
<string name="permdesc_recordAudio" msgid="5857246765327514062">"આ ઍપ ઉપયોગમાં હોય ત્યારે તે માઇક્રોફોનનો ઉપયોગ કરીને ઑડિયો રેકોર્ડ કરી શકે છે."</string>
<string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"બૅકગ્રાઉન્ડમાં ઑડિયો રેકોર્ડ કરો"</string>
@@ -519,7 +519,7 @@
<string name="permdesc_changeWifiMulticastState" product="tablet" msgid="191079868596433554">"એપ્લિકેશનને ફક્ત તમારા ટેબ્લેટ પર નહીં, પણ મલ્ટિકાસ્ટ સરનામાંનો ઉપયોગ કરીને વાઇ-ફાઇ નેટવર્ક પરના તમામ ઉપકરણોને મોકલાયેલ પૅકેટ્સ પ્રાપ્ત કરવાની મંજૂરી આપે છે. તે બિન-મલ્ટિકાસ્ટ મોડ કરતાં વધુ પાવર વાપરે છે."</string>
<string name="permdesc_changeWifiMulticastState" product="tv" msgid="1336952358450652595">"ઍપને ફક્ત તમારા Android TV ડિવાઇસ પર નહીં, પણ મલ્ટિકાસ્ટ ઍડ્રેસનો ઉપયોગ કરીને વાઇ-ફાઇ નેટવર્ક પરના તમામ ડિવાઇસને મોકલાયેલા પૅકેટ પ્રાપ્ત કરવાની મંજૂરી આપે છે. તે બિન-મલ્ટિકાસ્ટ મોડ કરતાં વધુ પાવર વાપરે છે."</string>
<string name="permdesc_changeWifiMulticastState" product="default" msgid="8296627590220222740">"એપ્લિકેશનને ફક્ત તમારા ફોન પર નહીં, પણ મલ્ટિકાસ્ટ સરનામાંનો ઉપયોગ કરીને વાઇ-ફાઇ નેટવર્ક પર તમામ ઉપકરણોને મોકલાયેલ પૅકેટ્સ પ્રાપ્ત કરવાની મંજૂરી આપે છે. તે બિન-મલ્ટિકાસ્ટ મોડ કરતાં વધુ પાવર વાપરે છે."</string>
- <string name="permlab_bluetoothAdmin" msgid="6490373569441946064">"બ્લૂટૂથ સેટિંગ્સ ઍક્સેસ કરો"</string>
+ <string name="permlab_bluetoothAdmin" msgid="6490373569441946064">"બ્લૂટૂથ સેટિંગ ઍક્સેસ કરો"</string>
<string name="permdesc_bluetoothAdmin" product="tablet" msgid="5370837055438574863">"એપ્લિકેશનને સ્થાનિક બ્લૂટૂથ ટેબ્લેટ ગોઠવવાની અને રિમોટ ઉપકરણો શોધવા અને તેમની સાથે જોડી કરવાની મંજૂરી આપે છે."</string>
<string name="permdesc_bluetoothAdmin" product="tv" msgid="1623992984547014588">"ઍપને તમારા Android TV ડિવાઇસ પર બ્લૂટૂથને ગોઠવવાની અને રિમોટ ડિવાઇસ શોધવા અને તેમની સાથે જોડાણ કરવાની મંજૂરી આપે છે."</string>
<string name="permdesc_bluetoothAdmin" product="default" msgid="7381341743021234863">"એપ્લિકેશનને સ્થાનિક બ્લૂટૂથ ફોન ગોઠવવાની અને રિમોટ ઉપકરણો શોધવા અને તેમની સાથે જોડી કરવાની મંજૂરી આપે છે."</string>
@@ -662,10 +662,10 @@
<string-array name="face_error_vendor">
</string-array>
<string name="face_icon_content_description" msgid="465030547475916280">"ચહેરા આઇકન"</string>
- <string name="permlab_readSyncSettings" msgid="6250532864893156277">"સમન્વયન સેટિંગ્સ વાંચો"</string>
- <string name="permdesc_readSyncSettings" msgid="1325658466358779298">"ઍપ્લિકેશનને એકાઉન્ટ માટે સમન્વયન સેટિંગ્સને વાંચવાની મંજૂરી આપે છે. ઉદાહરણ તરીકે, આ એકાઉન્ટ સાથે લોકો ઍપ્લિકેશન સમન્વયિત થઈ છે કે કેમ તે નિર્ધારિત કરી શકે છે."</string>
+ <string name="permlab_readSyncSettings" msgid="6250532864893156277">"સિંક સેટિંગ વાંચો"</string>
+ <string name="permdesc_readSyncSettings" msgid="1325658466358779298">"ઍપને એકાઉન્ટ માટે સિંક સેટિંગને વાંચવાની મંજૂરી આપે છે. ઉદાહરણ તરીકે, આ એકાઉન્ટ સાથે લોકો ઍપ સિંક થઈ છે કે કેમ તે નિર્ધારિત કરી શકે છે."</string>
<string name="permlab_writeSyncSettings" msgid="6583154300780427399">"સમન્વયન ચાલુ અને બંધ ટોગલ કરો"</string>
- <string name="permdesc_writeSyncSettings" msgid="6029151549667182687">"એપ્લિકેશનને એકાઉન્ટ માટે સમન્વયન સેટિંગ્સ સંશોધિત કરવાની મંજૂરી આપે છે. ઉદાહરણ તરીકે, આનો ઉપયોગ એકાઉન્ટ સાથે લોકો એપ્લિકેશનના સમન્વયનને સક્ષમ કરવા માટે થઈ શકે છે."</string>
+ <string name="permdesc_writeSyncSettings" msgid="6029151549667182687">"ઍપને એકાઉન્ટ માટે સિંક સેટિંગમાં ફેરફાર કરવાની મંજૂરી આપે છે. ઉદાહરણ તરીકે, આનો ઉપયોગ એકાઉન્ટ સાથે લોકો ઍપના સિંકને ચાલુ કરવા માટે થઈ શકે છે."</string>
<string name="permlab_readSyncStats" msgid="3747407238320105332">"સમન્વયન આંકડા વાંચો"</string>
<string name="permdesc_readSyncStats" msgid="3867809926567379434">"એપ્લિકેશનને સમન્વયન ઇવેન્ટ્સનો ઇતિહાસ અને કેટલો ડેટા સમન્વયિત થયો છે તે સહિત કોઈ એકાઉન્ટ માટેનાં સમન્વયન આંકડા વાંચવાની મંજૂરી આપે છે."</string>
<string name="permlab_sdcardRead" msgid="5791467020950064920">"તમારા શેર કરેલા સ્ટોરેજના કન્ટેન્ટને વાંચો"</string>
@@ -1210,7 +1210,7 @@
<string name="whichImageCaptureApplicationLabel" msgid="6505433734824988277">"છબી કૅપ્ચર કરો"</string>
<string name="alwaysUse" msgid="3153558199076112903">"આ ક્રિયા માટે ડિફોલ્ટ તરીકે ઉપયોગમાં લો."</string>
<string name="use_a_different_app" msgid="4987790276170972776">"અલગ એપ્લિકેશનનો ઉપયોગ કરો"</string>
- <string name="clearDefaultHintMsg" msgid="1325866337702524936">"સિસ્ટમ સેટિંગ્સ &gt; ઍપ્લિકેશનો &gt; ડાઉનલોડ કરેલમાં ડિફોલ્ટ સાફ કરો."</string>
+ <string name="clearDefaultHintMsg" msgid="1325866337702524936">"સિસ્ટમ સેટિંગ &gt; ઍપ &gt; ડાઉનલોડ કરેલામાં ડિફૉલ્ટ સાફ કરો."</string>
<string name="chooseActivity" msgid="8563390197659779956">"એક ક્રિયા પસંદ કરો"</string>
<string name="chooseUsbActivity" msgid="2096269989990986612">"USB ઉપકરણ માટે ઍપ્લિકેશન પસંદ કરો"</string>
<string name="noApplications" msgid="1186909265235544019">"કોઈ ઍપ્લિકેશન આ ક્રિયા કરી શકતી નથી."</string>
@@ -1238,8 +1238,8 @@
<string name="launch_warning_original" msgid="3332206576800169626">"<xliff:g id="APP_NAME">%1$s</xliff:g> મૂળરૂપે લોંચ થઈ હતી."</string>
<string name="screen_compat_mode_scale" msgid="8627359598437527726">"સ્કેલ"</string>
<string name="screen_compat_mode_show" msgid="5080361367584709857">"હંમેશા બતાવો"</string>
- <string name="screen_compat_mode_hint" msgid="4032272159093750908">"આને સિસ્ટમ સેટિંગ્સ &gt; ઍપ્લિકેશનો &gt; ડાઉનલોડ કરેલમાં ફરીથી સક્ષમ કરો."</string>
- <string name="unsupported_display_size_message" msgid="7265211375269394699">"<xliff:g id="APP_NAME">%1$s</xliff:g> વર્તમાન પ્રદર્શન કદની સેટિંગનું સમર્થન કરતું નથી અને અનપેક્ષિત રીતે વર્તી શકે છે."</string>
+ <string name="screen_compat_mode_hint" msgid="4032272159093750908">"આને સિસ્ટમ સેટિંગ &gt; ઍપ &gt; ડાઉનલોડ કરેલામાં ફરીથી ચાલુ કરો."</string>
+ <string name="unsupported_display_size_message" msgid="7265211375269394699">"<xliff:g id="APP_NAME">%1$s</xliff:g> વર્તમાન ડિસ્પ્લે કદની સેટિંગને સપોર્ટ કરતું નથી અને અનપેક્ષિત રીતે વર્તી શકે છે."</string>
<string name="unsupported_display_size_show" msgid="980129850974919375">"હંમેશાં બતાવો"</string>
<string name="unsupported_compile_sdk_message" msgid="7326293500707890537">"<xliff:g id="APP_NAME">%1$s</xliff:g>ને Android OSના અસંગત વર્ઝન માટે બનાવવામાં આવ્યું હતું અને તે અનપેક્ષિત રીતે કાર્ય કરી શકે છે. ઍપનું અપડેટ કરેલ વર્ઝન ઉપલબ્ધ હોઈ શકે છે."</string>
<string name="unsupported_compile_sdk_show" msgid="1601210057960312248">"હંમેશાં બતાવો"</string>
@@ -1335,7 +1335,7 @@
<string name="sms_short_code_confirm_allow" msgid="920477594325526691">"મોકલો"</string>
<string name="sms_short_code_confirm_deny" msgid="1356917469323768230">"રદ કરો"</string>
<string name="sms_short_code_remember_choice" msgid="1374526438647744862">"મારી પસંદગી યાદ રાખો"</string>
- <string name="sms_short_code_remember_undo_instruction" msgid="2620984439143080410">"તમે પછીથી આને સેટિંગ્સ &gt; એપ્લિકેશન્સમાં બદલી શકો છો"</string>
+ <string name="sms_short_code_remember_undo_instruction" msgid="2620984439143080410">"તમે પછીથી આને સેટિંગ &gt; ઍપમાં બદલી શકો છો"</string>
<string name="sms_short_code_confirm_always_allow" msgid="2223014893129755950">"હંમેશા મંજૂરી આપો"</string>
<string name="sms_short_code_confirm_never_allow" msgid="2688828813521652079">"ક્યારેય મંજૂરી આપશો નહીં"</string>
<string name="sim_removed_title" msgid="5387212933992546283">"સિમ કાર્ડ કાઢી નાખ્યો"</string>
@@ -1502,7 +1502,7 @@
<string name="vpn_lockdown_connected" msgid="2853127976590658469">"હંમેશા-ચાલુ VPN કનેક્ટ થયું"</string>
<string name="vpn_lockdown_disconnected" msgid="5573611651300764955">"હંમેશાં-ચાલુ VPN થી ડિસ્કનેક્ટ થયું"</string>
<string name="vpn_lockdown_error" msgid="4453048646854247947">"હંમેશાં-ચાલુ VPN સાથે કનેક્ટ કરી શકાયું નથી"</string>
- <string name="vpn_lockdown_config" msgid="8331697329868252169">"નેટવર્ક અથવા VPN સેટિંગ્સ બદલો"</string>
+ <string name="vpn_lockdown_config" msgid="8331697329868252169">"નેટવર્ક અથવા VPN સેટિંગ બદલો"</string>
<string name="upload_file" msgid="8651942222301634271">"ફાઇલ પસંદ કરો"</string>
<string name="no_file_chosen" msgid="4146295695162318057">"કોઈ ફાઇલ પસંદ કરેલી નથી"</string>
<string name="reset" msgid="3865826612628171429">"ફરીથી સેટ કરો"</string>
@@ -1616,7 +1616,7 @@
<string name="SetupCallDefault" msgid="5581740063237175247">"કૉલ સ્વીકારીએ?"</string>
<string name="activity_resolver_use_always" msgid="5575222334666843269">"હંમેશાં"</string>
<string name="activity_resolver_use_once" msgid="948462794469672658">"ફક્ત એક વાર"</string>
- <string name="activity_resolver_work_profiles_support" msgid="4071345609235361269">"%1$s કાર્ય પ્રોફાઇલનું સમર્થન કરતું નથી"</string>
+ <string name="activity_resolver_work_profiles_support" msgid="4071345609235361269">"%1$s ઑફિસની પ્રોફાઇલને સપોર્ટ કરતું નથી"</string>
<string name="default_audio_route_name" product="tablet" msgid="367936735632195517">"ટેબ્લેટ"</string>
<string name="default_audio_route_name" product="tv" msgid="4908971385068087367">"TV"</string>
<string name="default_audio_route_name" product="default" msgid="9213546147739983977">"ફોન"</string>
@@ -2067,7 +2067,7 @@
<string name="popup_window_default_title" msgid="6907717596694826919">"પૉપઅપ વિંડો"</string>
<string name="slice_more_content" msgid="3377367737876888459">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
<string name="shortcut_restored_on_lower_version" msgid="9206301954024286063">"આ ઍપનું વર્ઝન ડાઉનગ્રેડ કરવામાં આવ્યું છે અથવા આ શૉર્ટકટ સાથે સુસંગત નથી"</string>
- <string name="shortcut_restore_not_supported" msgid="4763198938588468400">"શૉર્ટકટ ફરી મેળવી શકાયો નથી કારણ કે ઍપ બૅકઅપ અને ફરી મેળવવાનું સમર્થન કરતી નથી"</string>
+ <string name="shortcut_restore_not_supported" msgid="4763198938588468400">"શૉર્ટકટ ફરી મેળવી શકાયો નથી કારણ કે ઍપ બૅકઅપ અને ફરી મેળવવાને સપોર્ટ કરતી નથી"</string>
<string name="shortcut_restore_signature_mismatch" msgid="579345304221605479">"શૉર્ટકટ ફરી મેળવી શકાયો નથી કારણ કે ઍપમાં છે તે સહી મેળ ખાતી નથી"</string>
<string name="shortcut_restore_unknown_issue" msgid="2478146134395982154">"શૉર્ટકટ પાછો મેળવી શકાયો નથી"</string>
<string name="shortcut_disabled_reason_unknown" msgid="753074793553599166">"શૉર્ટકટને બંધ કરવામાં આવ્યો છે"</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 12f8cd427d7f..6da40726d123 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -1951,7 +1951,7 @@
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
<string name="call_notification_answer_action" msgid="5999246836247132937">"जवाफ दिनुहोस्"</string>
<string name="call_notification_answer_video_action" msgid="2086030940195382249">"भिडियो"</string>
- <string name="call_notification_decline_action" msgid="3700345945214000726">"अस्वीकार गर्नुहोस्"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"काट्नुहोस्"</string>
<string name="call_notification_hang_up_action" msgid="9130720590159188131">"फोन राख्नुहोस्"</string>
<string name="call_notification_incoming_text" msgid="6143109825406638201">"आगमन कल"</string>
<string name="call_notification_ongoing_text" msgid="3880832933933020875">"भइरहेको कल"</string>
diff --git a/core/res/res/values-night/colors.xml b/core/res/res/values-night/colors.xml
index 816ddd41ccd3..2e4578c39430 100644
--- a/core/res/res/values-night/colors.xml
+++ b/core/res/res/values-night/colors.xml
@@ -29,5 +29,8 @@
<color name="resolver_empty_state_text">#FFFFFF</color>
<color name="resolver_empty_state_icon">#FFFFFF</color>
+ <color name="call_notification_decline_color">#E66A5E</color>
+ <color name="call_notification_answer_color">#5DBA80</color>
+
<color name="personal_apps_suspension_notification_color">#8AB4F8</color>
</resources>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 93f2d7420124..d632e0c53b6f 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -434,7 +434,7 @@
<string name="permdesc_bodySensors" product="default" msgid="2365357960407973997">"Aplikaciji omogoča dostop do podatkov tipal, ki nadzirajo vaše fizično stanje, med drugim vaš srčni utrip."</string>
<string name="permlab_readCalendar" msgid="6408654259475396200">"Branje dogodkov v koledarjih in podrobnosti koledarjev"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Ta aplikacija lahko prebere vse dogodke v koledarju, ki so shranjeni v tabličnem računalniku, ter shrani podatke koledarja ali jih deli z drugimi."</string>
- <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Ta aplikacija lahko prebere vse dogodke v koledarju, ki so shranjeni v napravi Android TV, ter shrani podatke koledarja ali jih da v skupno rabo z drugimi."</string>
+ <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Ta aplikacija lahko prebere vse dogodke v koledarju, ki so shranjeni v napravi Android TV, ter shrani podatke koledarja ali jih deli z drugimi."</string>
<string name="permdesc_readCalendar" product="default" msgid="9118823807655829957">"Ta aplikacija lahko prebere vse dogodke v koledarju, ki so shranjeni v telefonu, ter shrani podatke koledarja ali jih deli z drugimi."</string>
<string name="permlab_writeCalendar" msgid="6422137308329578076">"dodajanje ali spreminjanje dogodkov v koledarju in pošiljanje e-pošte gostom brez vedenja lastnikov"</string>
<string name="permdesc_writeCalendar" product="tablet" msgid="8722230940717092850">"Ta aplikacija lahko dodaja, odstranjuje in spreminja dogodke v koledarju, ki so shranjeni v tabličnem računalniku. Ta aplikacija lahko pošilja sporočila, ki bodo morda videti, kot da prihajajo od lastnikov koledarjev, ali spreminja dogodke brez vednosti lastnikov."</string>
@@ -932,7 +932,7 @@
<string name="lockscreen_forgot_pattern_button_text" msgid="8362442730606839031">"Ali ste pozabili vzorec?"</string>
<string name="lockscreen_glogin_forgot_pattern" msgid="9218940117797602518">"Odklepanje računa"</string>
<string name="lockscreen_glogin_too_many_attempts" msgid="3775904917743034195">"Preveč poskusov vzorca"</string>
- <string name="lockscreen_glogin_instructions" msgid="4695162942525531700">"Če želite odkleniti telefon, se prijavite z Google Računom."</string>
+ <string name="lockscreen_glogin_instructions" msgid="4695162942525531700">"Če želite odkleniti telefon, se prijavite z računom Google."</string>
<string name="lockscreen_glogin_username_hint" msgid="6916101478673157045">"Uporabniško ime (e-pošta)"</string>
<string name="lockscreen_glogin_password_hint" msgid="3031027901286812848">"Geslo"</string>
<string name="lockscreen_glogin_submit_button" msgid="3590556636347843733">"Prijava"</string>
@@ -1237,8 +1237,8 @@
<string name="whichEditApplicationNamed" msgid="8096494987978521514">"Urejanje z aplikacijo %1$s"</string>
<string name="whichEditApplicationLabel" msgid="1463288652070140285">"Urejanje"</string>
<string name="whichSendApplication" msgid="4143847974460792029">"Deljenje z drugimi"</string>
- <string name="whichSendApplicationNamed" msgid="4470386782693183461">"Skupna raba z aplikacijo %1$s"</string>
- <string name="whichSendApplicationLabel" msgid="7467813004769188515">"Skupna raba"</string>
+ <string name="whichSendApplicationNamed" msgid="4470386782693183461">"Deljenje z aplikacijo %1$s"</string>
+ <string name="whichSendApplicationLabel" msgid="7467813004769188515">"Deljenje"</string>
<string name="whichSendToApplication" msgid="77101541959464018">"Pošiljanje z aplikacijo"</string>
<string name="whichSendToApplicationNamed" msgid="3385686512014670003">"Pošiljanje z aplikacijo %1$s"</string>
<string name="whichSendToApplicationLabel" msgid="3543240188816513303">"Pošiljanje"</string>
@@ -1400,14 +1400,14 @@
<string name="perm_costs_money" msgid="749054595022779685">"to je lahko plačljivo"</string>
<string name="dlg_ok" msgid="5103447663504839312">"V redu"</string>
<string name="usb_charging_notification_title" msgid="1674124518282666955">"Polnjenje naprave prek USB-ja"</string>
- <string name="usb_supplying_notification_title" msgid="5378546632408101811">"Polnjenje akumulatorja v povezani napravi prek USB-ja"</string>
+ <string name="usb_supplying_notification_title" msgid="5378546632408101811">"Polnjenje baterije v povezani napravi prek USB-ja"</string>
<string name="usb_mtp_notification_title" msgid="1065989144124499810">"Vklopljen je prenos datotek prek USB-ja"</string>
<string name="usb_ptp_notification_title" msgid="5043437571863443281">"Vklopljen je način PTP prek USB-ja"</string>
<string name="usb_tether_notification_title" msgid="8828527870612663771">"Vklopljen je internet prek USB-ja"</string>
<string name="usb_midi_notification_title" msgid="7404506788950595557">"Vklopljen je način MIDI prek USB-ja"</string>
<string name="usb_accessory_notification_title" msgid="1385394660861956980">"Dodatek USB je priključen"</string>
<string name="usb_notification_message" msgid="4715163067192110676">"Dotaknite se za več možnosti."</string>
- <string name="usb_power_notification_message" msgid="7284765627437897702">"Polnjenje akumulatorja v povezani napravi. Dotaknite se za več možnosti."</string>
+ <string name="usb_power_notification_message" msgid="7284765627437897702">"Polnjenje baterije v povezani napravi. Dotaknite se za več možnosti."</string>
<string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"Zaznana je analogna dodatna zvočna oprema"</string>
<string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"Priključena naprava ni združljiva s tem telefonom. Dotaknite se za več informacij."</string>
<string name="adb_active_notification_title" msgid="408390247354560331">"Iskanje napak prek USB-ja je povezano"</string>
@@ -1427,8 +1427,8 @@
<string name="taking_remote_bugreport_notification_title" msgid="1582531382166919850">"Zajemanje poročila o napakah …"</string>
<string name="share_remote_bugreport_notification_title" msgid="6708897723753334999">"Želite poslati poročilo o napakah?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="3077385149217638550">"Pošiljanje poročila o napakah …"</string>
- <string name="share_remote_bugreport_notification_message_finished" msgid="7325635795739260135">"Skrbnik je zahteval poročilo o napakah za pomoč pri odpravljanju napak v tej napravi. Aplikacije in podatki bodo morda dani v skupno rabo."</string>
- <string name="share_remote_bugreport_action" msgid="7630880678785123682">"SKUPNA RABA"</string>
+ <string name="share_remote_bugreport_notification_message_finished" msgid="7325635795739260135">"Skrbnik je zahteval poročilo o napakah za pomoč pri odpravljanju napak v tej napravi. Aplikacije in podatki bodo morda deljeni."</string>
+ <string name="share_remote_bugreport_action" msgid="7630880678785123682">"DELJENJE"</string>
<string name="decline_remote_bugreport_action" msgid="4040894777519784346">"NE SPREJMEM"</string>
<string name="select_input_method" msgid="3971267998568587025">"Izberite način vnosa"</string>
<string name="show_ime" msgid="6406112007347443383">"Ohrani na zaslonu, dokler je aktivna fizična tipkovnica"</string>
@@ -1616,7 +1616,7 @@
<string name="action_menu_overflow_description" msgid="4579536843510088170">"Več možnosti"</string>
<string name="action_bar_home_description_format" msgid="5087107531331621803">"%1$s, %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="4346835454749569826">"%1$s, %2$s, %3$s"</string>
- <string name="storage_internal" msgid="8490227947584914460">"Notranja shramba v skupni rabi"</string>
+ <string name="storage_internal" msgid="8490227947584914460">"Notranja deljena shramba"</string>
<string name="storage_sd_card" msgid="3404740277075331881">"Kartica SD"</string>
<string name="storage_sd_card_label" msgid="7526153141147470509">"Kartica SD <xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
<string name="storage_usb_drive" msgid="448030813201444573">"Pogon USB"</string>
@@ -1709,7 +1709,7 @@
<string name="kg_invalid_puk" msgid="4809502818518963344">"Vnovič vnesite pravilno kodo PUK. Večkratni poskusi bodo trajno onemogočili kartico SIM."</string>
<string name="kg_invalid_confirm_pin_hint" product="default" msgid="4705368340409816254">"Kodi PIN se ne ujemata"</string>
<string name="kg_login_too_many_attempts" msgid="699292728290654121">"Preveč poskusov vzorca"</string>
- <string name="kg_login_instructions" msgid="3619844310339066827">"Če želite odkleniti napravo, se prijavite z Google Računom."</string>
+ <string name="kg_login_instructions" msgid="3619844310339066827">"Če želite odkleniti napravo, se prijavite z računom Google."</string>
<string name="kg_login_username_hint" msgid="1765453775467133251">"Uporabniško ime (e-pošta)"</string>
<string name="kg_login_password_hint" msgid="3330530727273164402">"Geslo"</string>
<string name="kg_login_submit_button" msgid="893611277617096870">"Prijava"</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 25e2820611f6..239c9f8709da 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -1197,7 +1197,7 @@
<string name="whichEditApplicationNamed" msgid="8096494987978521514">"Redakto me %1$s"</string>
<string name="whichEditApplicationLabel" msgid="1463288652070140285">"Redakto"</string>
<string name="whichSendApplication" msgid="4143847974460792029">"Ndaj"</string>
- <string name="whichSendApplicationNamed" msgid="4470386782693183461">"Shpërnda publikisht me %1$s"</string>
+ <string name="whichSendApplicationNamed" msgid="4470386782693183461">"Shpërndaj me %1$s"</string>
<string name="whichSendApplicationLabel" msgid="7467813004769188515">"Ndaj"</string>
<string name="whichSendToApplication" msgid="77101541959464018">"Dërgo me"</string>
<string name="whichSendToApplicationNamed" msgid="3385686512014670003">"Dërgo me %1$s"</string>
@@ -1565,8 +1565,8 @@
<string name="keyboardview_keycode_enter" msgid="168054869339091055">"Enter"</string>
<string name="activitychooserview_choose_application" msgid="3500574466367891463">"Zgjidh një aplikacion"</string>
<string name="activitychooserview_choose_application_error" msgid="6937782107559241734">"Nuk mundi ta hapte <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
- <string name="shareactionprovider_share_with" msgid="2753089758467748982">"Shpërnda publikisht me"</string>
- <string name="shareactionprovider_share_with_application" msgid="4902832247173666973">"Shpërnda me <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+ <string name="shareactionprovider_share_with" msgid="2753089758467748982">"Shpërndaj me"</string>
+ <string name="shareactionprovider_share_with_application" msgid="4902832247173666973">"Shpërndaj me <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
<string name="content_description_sliding_handle" msgid="982510275422590757">"Dorezë me rrëshqitje. Preke dhe mbaje të shtypur."</string>
<string name="description_target_unlock_tablet" msgid="7431571180065859551">"Rrëshqit për të shkyçur."</string>
<string name="action_bar_home_description" msgid="1501655419158631974">"Orientohu për në shtëpi"</string>
@@ -1610,7 +1610,7 @@
<string name="sha1_fingerprint" msgid="2339915142825390774">"Gjurma e gishtit SHA-1:"</string>
<string name="activity_chooser_view_see_all" msgid="3917045206812726099">"Shikoji të gjitha"</string>
<string name="activity_chooser_view_dialog_title_default" msgid="8880731437191978314">"Zgjidh aktivitetin"</string>
- <string name="share_action_provider_share_with" msgid="1904096863622941880">"Shpërnda publikisht me"</string>
+ <string name="share_action_provider_share_with" msgid="1904096863622941880">"Shpërndaj me"</string>
<string name="sending" msgid="206925243621664438">"Po dërgon…"</string>
<string name="launchBrowserDefault" msgid="6328349989932924119">"Të hapet shfletuesi?"</string>
<string name="SetupCallDefault" msgid="5581740063237175247">"Dëshiron ta pranosh telefonatën?"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index cb0b420d7f17..940ee568228d 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -572,7 +572,7 @@
<string name="biometric_error_user_canceled" msgid="6732303949695293730">"Autentiseringen avbröts"</string>
<string name="biometric_not_recognized" msgid="5106687642694635888">"Identifierades inte"</string>
<string name="biometric_error_canceled" msgid="8266582404844179778">"Autentiseringen avbröts"</string>
- <string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Pinkod, grafiskt lösenord eller lösenord har inte angetts"</string>
+ <string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Pinkod, mönster eller lösenord har inte angetts"</string>
<string name="biometric_error_generic" msgid="6784371929985434439">"Ett fel uppstod vid autentiseringen"</string>
<string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Använd skärmlåset"</string>
<string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Fortsätt med hjälp av ditt skärmlås"</string>
@@ -881,7 +881,7 @@
<string name="lockscreen_screen_locked" msgid="7364905540516041817">"Skärmen har låsts."</string>
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Tryck på Menu för att låsa upp eller ringa nödsamtal."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Tryck på Menu för att låsa upp."</string>
- <string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Rita grafiskt lösenord för att låsa upp"</string>
+ <string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Rita mönster för att låsa upp"</string>
<string name="lockscreen_emergency_call" msgid="7549683825868928636">"Nödsamtal"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Tillbaka till samtal"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Korrekt!"</string>
@@ -925,7 +925,7 @@
<string name="lockscreen_too_many_failed_attempts_countdown" msgid="6807200118164539589">"Försök igen om <xliff:g id="NUMBER">%d</xliff:g> sekunder."</string>
<string name="lockscreen_forgot_pattern_button_text" msgid="8362442730606839031">"Glömt ditt grafiska lösenord?"</string>
<string name="lockscreen_glogin_forgot_pattern" msgid="9218940117797602518">"Lås upp konto"</string>
- <string name="lockscreen_glogin_too_many_attempts" msgid="3775904917743034195">"För många försök med grafiskt lösenord"</string>
+ <string name="lockscreen_glogin_too_many_attempts" msgid="3775904917743034195">"För många försök med mönster"</string>
<string name="lockscreen_glogin_instructions" msgid="4695162942525531700">"Logga in med ditt Google-konto om du vill låsa upp."</string>
<string name="lockscreen_glogin_username_hint" msgid="6916101478673157045">"Användarnamn (e-post)"</string>
<string name="lockscreen_glogin_password_hint" msgid="3031027901286812848">"Lösenord"</string>
@@ -936,12 +936,12 @@
<string name="lockscreen_unlock_label" msgid="4648257878373307582">"Lås upp"</string>
<string name="lockscreen_sound_on_label" msgid="1660281470535492430">"Ljud på"</string>
<string name="lockscreen_sound_off_label" msgid="2331496559245450053">"Ljud av"</string>
- <string name="lockscreen_access_pattern_start" msgid="3778502525702613399">"Skriver grafiskt lösenord"</string>
- <string name="lockscreen_access_pattern_cleared" msgid="7493849102641167049">"Grafiskt lösenord har tagits bort"</string>
+ <string name="lockscreen_access_pattern_start" msgid="3778502525702613399">"Ritar mönster"</string>
+ <string name="lockscreen_access_pattern_cleared" msgid="7493849102641167049">"Mönster har tagits bort"</string>
<string name="lockscreen_access_pattern_cell_added" msgid="6746676335293144163">"En cell har lagts till"</string>
<string name="lockscreen_access_pattern_cell_added_verbose" msgid="2931364927622563465">"Cell <xliff:g id="CELL_INDEX">%1$s</xliff:g> har lagts till"</string>
- <string name="lockscreen_access_pattern_detected" msgid="3931150554035194012">"Grafiskt lösenord har slutförts"</string>
- <string name="lockscreen_access_pattern_area" msgid="1288780416685002841">"Fält för grafiskt lösenord."</string>
+ <string name="lockscreen_access_pattern_detected" msgid="3931150554035194012">"Mönster har slutförts"</string>
+ <string name="lockscreen_access_pattern_area" msgid="1288780416685002841">"Fält för mönster."</string>
<string name="keyguard_accessibility_widget_changed" msgid="7298011259508200234">"%1$s. Widget %2$d av %3$d."</string>
<string name="keyguard_accessibility_add_widget" msgid="8245795023551343672">"Lägg till en widget."</string>
<string name="keyguard_accessibility_widget_empty_slot" msgid="544239307077644480">"Tom"</string>
@@ -957,13 +957,13 @@
<string name="keyguard_accessibility_widget_deleted" msgid="1509738950119878705">"Widgeten <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> har tagits bort."</string>
<string name="keyguard_accessibility_expand_lock_area" msgid="4215280881346033434">"Expandera upplåsningsytan."</string>
<string name="keyguard_accessibility_slide_unlock" msgid="2968195219692413046">"Lås upp genom att dra."</string>
- <string name="keyguard_accessibility_pattern_unlock" msgid="8669128146589233293">"Lås upp med grafiskt lösenord."</string>
+ <string name="keyguard_accessibility_pattern_unlock" msgid="8669128146589233293">"Lås upp med mönster."</string>
<string name="keyguard_accessibility_face_unlock" msgid="4533832120787386728">"Ansiktslås."</string>
<string name="keyguard_accessibility_pin_unlock" msgid="4020864007967340068">"Lås upp med PIN-kod."</string>
<string name="keyguard_accessibility_sim_pin_unlock" msgid="4895939120871890557">"Lås upp med SIM-kortets pinkod."</string>
<string name="keyguard_accessibility_sim_puk_unlock" msgid="3459003464041899101">"Lås upp med SIM-kortets PUK-kod."</string>
<string name="keyguard_accessibility_password_unlock" msgid="6130186108581153265">"Lås upp med lösenord."</string>
- <string name="keyguard_accessibility_pattern_area" msgid="1419570880512350689">"Fält för grafiskt lösenord."</string>
+ <string name="keyguard_accessibility_pattern_area" msgid="1419570880512350689">"Fält för mönster."</string>
<string name="keyguard_accessibility_slide_area" msgid="4331399051142520176">"Fält med dragreglage."</string>
<string name="password_keyboard_label_symbol_key" msgid="2716255580853511949">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="5294837425652726684">"ABC"</string>
@@ -1644,7 +1644,7 @@
<string name="display_manager_overlay_display_title" msgid="1480158037150469170">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
<string name="display_manager_overlay_display_secure_suffix" msgid="2810034719482834679">", säker"</string>
<string name="kg_forgot_pattern_button_text" msgid="406145459223122537">"Har du glömt ditt grafiska lösenord?"</string>
- <string name="kg_wrong_pattern" msgid="1342812634464179931">"Fel grafiskt lösenord"</string>
+ <string name="kg_wrong_pattern" msgid="1342812634464179931">"Fel mönster"</string>
<string name="kg_wrong_password" msgid="2384677900494439426">"Fel lösenord"</string>
<string name="kg_wrong_pin" msgid="3680925703673166482">"Fel PIN-kod"</string>
<plurals name="kg_too_many_failed_attempts_countdown" formatted="false" msgid="236717428673283568">
@@ -1664,7 +1664,7 @@
<string name="kg_invalid_sim_puk_hint" msgid="2539364558870734339">"PUK-koden ska vara åtta siffror."</string>
<string name="kg_invalid_puk" msgid="4809502818518963344">"Ange rätt PUK-kod igen. Om försöken upprepas inaktiveras SIM-kortet permanent."</string>
<string name="kg_invalid_confirm_pin_hint" product="default" msgid="4705368340409816254">"PIN-koderna stämmer inte överens"</string>
- <string name="kg_login_too_many_attempts" msgid="699292728290654121">"För många försök med grafiskt lösenord"</string>
+ <string name="kg_login_too_many_attempts" msgid="699292728290654121">"För många försök med mönster"</string>
<string name="kg_login_instructions" msgid="3619844310339066827">"Logga in med ditt Google-konto om du vill låsa upp."</string>
<string name="kg_login_username_hint" msgid="1765453775467133251">"Användarnamn (e-post)"</string>
<string name="kg_login_password_hint" msgid="3330530727273164402">"Lösenord"</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index d68c088d5867..893aedae146d 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -87,7 +87,7 @@
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"ప్రాధాన్య నెట్‌వర్క్‌ను మార్చుకోవడానికి ప్రయత్నించండి. మార్చడానికి నొక్కండి."</string>
<string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"అత్యవసర కాలింగ్ అందుబాటులో లేదు"</string>
<string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Wi-Fiతో అత్యవసర కాల్‌లు చేయలేరు"</string>
- <string name="notification_channel_network_alert" msgid="4788053066033851841">"హెచ్చరికలు"</string>
+ <string name="notification_channel_network_alert" msgid="4788053066033851841">"అలర్ట్‌లు"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"కాల్ ఫార్వార్డింగ్"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"అత్యవసర కాల్‌బ్యాక్ మోడ్"</string>
<string name="notification_channel_mobile_data_status" msgid="1941911162076442474">"మొబైల్ డేటా స్థితి"</string>
@@ -287,7 +287,7 @@
<string name="notification_channel_network_available" msgid="6083697929214165169">"నెట్‌వర్క్ అందుబాటులో ఉంది"</string>
<string name="notification_channel_vpn" msgid="1628529026203808999">"VPN స్థితి"</string>
<string name="notification_channel_device_admin" msgid="6384932669406095506">"మీ IT నిర్వాహకుల నుండి వచ్చే హెచ్చరికలు"</string>
- <string name="notification_channel_alerts" msgid="5070241039583668427">"హెచ్చరికలు"</string>
+ <string name="notification_channel_alerts" msgid="5070241039583668427">"అలర్ట్‌లు"</string>
<string name="notification_channel_retail_mode" msgid="3732239154256431213">"రిటైల్ డెమో"</string>
<string name="notification_channel_usb" msgid="1528280969406244896">"USB కనెక్షన్"</string>
<string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"యాప్ అమలవుతోంది"</string>
@@ -815,7 +815,7 @@
<string name="phoneTypeTtyTdd" msgid="532038552105328779">"TTY TDD"</string>
<string name="phoneTypeWorkMobile" msgid="7522314392003565121">"కార్యాలయ మొబైల్"</string>
<string name="phoneTypeWorkPager" msgid="3748332310638505234">"కార్యాలయ పేజర్"</string>
- <string name="phoneTypeAssistant" msgid="757550783842231039">"Assistant"</string>
+ <string name="phoneTypeAssistant" msgid="757550783842231039">"అసిస్టెంట్"</string>
<string name="phoneTypeMms" msgid="1799747455131365989">"MMS"</string>
<string name="eventTypeCustom" msgid="3257367158986466481">"అనుకూలం"</string>
<string name="eventTypeBirthday" msgid="7770026752793912283">"పుట్టినరోజు"</string>
diff --git a/core/tests/coretests/src/com/android/internal/os/ProcLocksReaderTest.java b/core/tests/coretests/src/com/android/internal/os/ProcLocksReaderTest.java
new file mode 100644
index 000000000000..d800c2c3c66e
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/os/ProcLocksReaderTest.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.os;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.content.Context;
+import android.os.FileUtils;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.File;
+import java.nio.file.Files;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class ProcLocksReaderTest {
+ private File mProcDirectory;
+
+ @Before
+ public void setUp() {
+ Context context = InstrumentationRegistry.getContext();
+ mProcDirectory = context.getDir("proc", Context.MODE_PRIVATE);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ FileUtils.deleteContents(mProcDirectory);
+ }
+
+ @Test
+ public void testRunSimpleLocks() throws Exception {
+ String simpleLocks =
+ "1: POSIX ADVISORY READ 18403 fd:09:9070 1073741826 1073742335\n" +
+ "2: POSIX ADVISORY WRITE 18292 fd:09:34062 0 EOF\n";
+ assertFalse(runHasFileLocks(simpleLocks, 18402));
+ assertFalse(runHasFileLocks(simpleLocks, 18404));
+ assertTrue(runHasFileLocks(simpleLocks, 18403));
+ assertTrue(runHasFileLocks(simpleLocks, 18292));
+ }
+
+ @Test
+ public void testRunBlockedLocks() throws Exception {
+ String blockedLocks =
+ "1: POSIX ADVISORY READ 18403 fd:09:9070 1073741826 1073742335\n" +
+ "2: POSIX ADVISORY WRITE 18292 fd:09:34062 0 EOF\n" +
+ "2: -> POSIX ADVISORY WRITE 18291 fd:09:34062 0 EOF\n" +
+ "2: -> POSIX ADVISORY WRITE 18293 fd:09:34062 0 EOF\n" +
+ "3: POSIX ADVISORY READ 3888 fd:09:13992 128 128\n" +
+ "4: POSIX ADVISORY READ 3888 fd:09:14230 1073741826 1073742335\n";
+ assertFalse(runHasFileLocks(blockedLocks, 18402));
+ assertFalse(runHasFileLocks(blockedLocks, 18404));
+ assertTrue(runHasFileLocks(blockedLocks, 18403));
+ assertTrue(runHasFileLocks(blockedLocks, 18292));
+
+ assertFalse(runHasFileLocks(blockedLocks, 18291));
+ assertFalse(runHasFileLocks(blockedLocks, 18293));
+ assertTrue(runHasFileLocks(blockedLocks, 3888));
+ }
+
+ private boolean runHasFileLocks(String fileContents, int pid) throws Exception {
+ File tempFile = File.createTempFile("locks", null, mProcDirectory);
+ Files.write(tempFile.toPath(), fileContents.getBytes());
+ boolean result = new ProcLocksReader(tempFile.toString()).hasFileLocks(pid);
+ Files.delete(tempFile.toPath());
+ return result;
+ }
+}
diff --git a/core/tests/utiltests/src/com/android/internal/util/ProcFileReaderTest.java b/core/tests/utiltests/src/com/android/internal/util/ProcFileReaderTest.java
index b6da1954ba79..0532628ba16d 100644
--- a/core/tests/utiltests/src/com/android/internal/util/ProcFileReaderTest.java
+++ b/core/tests/utiltests/src/com/android/internal/util/ProcFileReaderTest.java
@@ -166,6 +166,46 @@ public class ProcFileReaderTest extends AndroidTestCase {
assertEquals(-1L, reader.nextOptionalLong(-1L));
}
+ public void testInvalidLongs() throws Exception {
+ final ProcFileReader reader = buildReader("12: 34\n56 78@#\n");
+
+ assertEquals(12L, reader.nextLong(true));
+ assertEquals(34L, reader.nextLong(true));
+ reader.finishLine();
+ assertTrue(reader.hasMoreData());
+
+ assertEquals(56L, reader.nextLong(true));
+ assertEquals(78L, reader.nextLong(true));
+ reader.finishLine();
+ assertFalse(reader.hasMoreData());
+ }
+
+ public void testConsecutiveDelimiters() throws Exception {
+ final ProcFileReader reader = buildReader("1 2 3 4 5\n");
+
+ assertEquals(1L, reader.nextLong());
+ assertEquals(2L, reader.nextLong());
+ assertEquals(3L, reader.nextLong());
+ assertEquals(4L, reader.nextLong());
+ assertEquals(5L, reader.nextLong());
+ reader.finishLine();
+ assertFalse(reader.hasMoreData());
+ }
+
+ public void testIgnore() throws Exception {
+ final ProcFileReader reader = buildReader("a b c\n");
+
+ assertEquals("a", reader.nextString());
+ assertTrue(reader.hasMoreData());
+
+ reader.nextIgnored();
+ assertTrue(reader.hasMoreData());
+
+ assertEquals("c", reader.nextString());
+ reader.finishLine();
+ assertFalse(reader.hasMoreData());
+ }
+
private static ProcFileReader buildReader(String string) throws IOException {
return buildReader(string, 2048);
}
diff --git a/graphics/java/android/graphics/drawable/RippleAnimationSession.java b/graphics/java/android/graphics/drawable/RippleAnimationSession.java
index 74fb618f8fd7..492520910afd 100644
--- a/graphics/java/android/graphics/drawable/RippleAnimationSession.java
+++ b/graphics/java/android/graphics/drawable/RippleAnimationSession.java
@@ -53,6 +53,7 @@ public final class RippleAnimationSession {
private long mStartTime;
private boolean mForceSoftware;
private Animator mLoopAnimation;
+ private Animator mCurrentAnimation;
RippleAnimationSession(@NonNull AnimationProperties<Float, Paint> properties,
boolean forceSoftware) {
@@ -74,6 +75,12 @@ public final class RippleAnimationSession {
return this;
}
+ void end() {
+ if (mCurrentAnimation != null) {
+ mCurrentAnimation.end();
+ }
+ }
+
@NonNull RippleAnimationSession exit(Canvas canvas) {
if (isHwAccelerated(canvas)) exitHardware((RecordingCanvas) canvas);
else exitSoftware();
@@ -114,10 +121,12 @@ public final class RippleAnimationSession {
if (mLoopAnimation != null) mLoopAnimation.cancel();
Consumer<RippleAnimationSession> onEnd = mOnSessionEnd;
if (onEnd != null) onEnd.accept(RippleAnimationSession.this);
+ if (mCurrentAnimation == expand) mCurrentAnimation = null;
}
});
expand.setInterpolator(LINEAR_INTERPOLATOR);
expand.start();
+ mCurrentAnimation = expand;
}
private long computeDelay() {
@@ -147,6 +156,7 @@ public final class RippleAnimationSession {
if (mLoopAnimation != null) mLoopAnimation.cancel();
Consumer<RippleAnimationSession> onEnd = mOnSessionEnd;
if (onEnd != null) onEnd.accept(RippleAnimationSession.this);
+ if (mCurrentAnimation == exit) mCurrentAnimation = null;
}
});
exit.setTarget(canvas);
@@ -155,6 +165,7 @@ public final class RippleAnimationSession {
long delay = computeDelay();
exit.setStartDelay(delay);
exit.start();
+ mCurrentAnimation = exit;
}
private void enterHardware(RecordingCanvas canvas) {
@@ -167,6 +178,7 @@ public final class RippleAnimationSession {
mStartTime + MAX_NOISE_PHASE);
loop.setTarget(canvas);
startAnimation(expand, loop);
+ mCurrentAnimation = expand;
}
private void startAnimation(Animator expand, Animator loop) {
@@ -200,6 +212,7 @@ public final class RippleAnimationSession {
mProperties.getShader().setNoisePhase((float) loop.getAnimatedValue());
});
startAnimation(expand, loop);
+ mCurrentAnimation = expand;
}
void setRadius(float radius) {
diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java
index b994ad20320b..d3cff5cb81ff 100644
--- a/graphics/java/android/graphics/drawable/RippleDrawable.java
+++ b/graphics/java/android/graphics/drawable/RippleDrawable.java
@@ -278,6 +278,15 @@ public class RippleDrawable extends LayerDrawable {
}
cancelExitingRipples();
+ endPatternedAnimations();
+ }
+
+ private void endPatternedAnimations() {
+ for (int i = 0; i < mRunningAnimations.size(); i++) {
+ RippleAnimationSession session = mRunningAnimations.get(i);
+ session.end();
+ }
+ mRunningAnimations.clear();
}
private void cancelExitingRipples() {
@@ -291,7 +300,6 @@ public class RippleDrawable extends LayerDrawable {
Arrays.fill(ripples, 0, count, null);
}
mExitingRipplesCount = 0;
- mExitingAnimation = true;
// Always draw an additional "clean" frame after canceling animations.
invalidateSelf(false);
}
@@ -714,7 +722,7 @@ public class RippleDrawable extends LayerDrawable {
}
cancelExitingRipples();
- exitPatternedAnimation();
+ endPatternedAnimations();
}
@Override
diff --git a/libs/WindowManager/Shell/res/values-ky/strings.xml b/libs/WindowManager/Shell/res/values-ky/strings.xml
index c16041d87149..8056d15de3f4 100644
--- a/libs/WindowManager/Shell/res/values-ky/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ky/strings.xml
@@ -46,7 +46,7 @@
<string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"Үстүнкү экранды 30%"</string>
<string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"Ылдыйкы экранды толук экран режимине өткөрүү"</string>
<string name="one_handed_tutorial_title" msgid="4583241688067426350">"Бир кол режимин колдонуу"</string>
- <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Чыгуу үчүн экранды ылдый жагынан өйдө көздөй сүрүңүз же колдонмонун өйдө жагын басыңыз"</string>
+ <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Чыгуу үчүн экранды ылдый жагынан өйдө сүрүңүз же колдонмонун өйдө жагын басыңыз"</string>
<string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Бир кол режимин баштоо"</string>
<string name="accessibility_action_stop_one_handed" msgid="1369940261782179442">"Бир кол режиминен чыгуу"</string>
<string name="bubbles_settings_button_description" msgid="1301286017420516912">"<xliff:g id="APP_NAME">%1$s</xliff:g> калкып чыкма билдирмелер жөндөөлөрү"</string>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedAnimationCallback.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedAnimationCallback.java
index 24e511143cff..8969cc8a7da9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedAnimationCallback.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedAnimationCallback.java
@@ -46,7 +46,7 @@ public interface OneHandedAnimationCallback {
/**
* Called when OneHanded animator is updating position
*/
- default void onAnimationUpdate(float xPos, float yPos) {
+ default void onAnimationUpdate(SurfaceControl.Transaction tx, float xPos, float yPos) {
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedAnimationController.java
index bfb2cc6a8fc5..4b7832845a1d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedAnimationController.java
@@ -182,10 +182,10 @@ public class OneHandedAnimationController {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
final SurfaceControl.Transaction tx = newSurfaceControlTransaction();
- applySurfaceControlTransaction(mLeash, tx, animation.getAnimatedFraction());
mOneHandedAnimationCallbacks.forEach(
- (callback) -> callback.onAnimationUpdate(0f, mCurrentValue)
+ (callback) -> callback.onAnimationUpdate(tx, 0f, mCurrentValue)
);
+ applySurfaceControlTransaction(mLeash, tx, animation.getAnimatedFraction());
}
void onStartTransaction(SurfaceControl leash, SurfaceControl.Transaction tx) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizer.java
index 3ccb9e7570d5..97461e607e66 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizer.java
@@ -16,12 +16,14 @@
package com.android.wm.shell.onehanded;
+import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.view.SurfaceControl;
import android.view.SurfaceSession;
+import android.view.animation.LinearInterpolator;
import android.window.DisplayAreaAppearedInfo;
import android.window.DisplayAreaInfo;
import android.window.DisplayAreaOrganizer;
@@ -29,8 +31,8 @@ import android.window.DisplayAreaOrganizer;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
+import androidx.appcompat.view.ContextThemeWrapper;
-import com.android.internal.annotations.GuardedBy;
import com.android.wm.shell.R;
import com.android.wm.shell.common.DisplayLayout;
@@ -44,194 +46,212 @@ import java.util.concurrent.Executor;
* the screen has entered one handed mode.
*/
public class OneHandedBackgroundPanelOrganizer extends DisplayAreaOrganizer
- implements OneHandedTransitionCallback {
+ implements OneHandedAnimationCallback {
private static final String TAG = "OneHandedBackgroundPanelOrganizer";
private static final int THEME_COLOR_OFFSET = 10;
+ private static final int ALPHA_ANIMATION_DURATION = 200;
private final Context mContext;
- private final Object mLock = new Object();
private final SurfaceSession mSurfaceSession = new SurfaceSession();
- private final Executor mMainExecutor;
private final OneHandedSurfaceTransactionHelper.SurfaceControlTransactionFactory
- mSurfaceControlTransactionFactory;
+ mTransactionFactory;
- private float[] mDefaultColor;
+ private ValueAnimator mAlphaAnimator;
+
+ private float mTranslationFraction;
+ private float[] mThemeColor;
/**
* The background to distinguish the boundary of translated windows and empty region when
* one handed mode triggered.
*/
private Rect mBkgBounds;
- @VisibleForTesting
- @GuardedBy("mLock")
- boolean mIsShowing;
+ private Rect mStableInsets;
+
@Nullable
- @GuardedBy("mLock")
- private SurfaceControl mBackgroundSurface;
+ @VisibleForTesting
+ SurfaceControl mBackgroundSurface;
@Nullable
- @GuardedBy("mLock")
private SurfaceControl mParentLeash;
- private final OneHandedAnimationCallback mOneHandedAnimationCallback =
- new OneHandedAnimationCallback() {
- @Override
- public void onOneHandedAnimationStart(
- OneHandedAnimationController.OneHandedTransitionAnimator animator) {
- mMainExecutor.execute(() -> showBackgroundPanelLayer());
- }
- };
-
- @Override
- public void onStopFinished(Rect bounds) {
- mMainExecutor.execute(() -> removeBackgroundPanelLayer());
- }
-
public OneHandedBackgroundPanelOrganizer(Context context, DisplayLayout displayLayout,
- Executor executor) {
+ OneHandedSettingsUtil settingsUtil, Executor executor) {
super(executor);
mContext = context;
- // Ensure the mBkgBounds is portrait, due to OHM only support on portrait
- if (displayLayout.height() > displayLayout.width()) {
- mBkgBounds = new Rect(0, 0, displayLayout.width(), displayLayout.height());
- } else {
- mBkgBounds = new Rect(0, 0, displayLayout.height(), displayLayout.width());
- }
+ mTranslationFraction = settingsUtil.getTranslationFraction(context);
+ mTransactionFactory = SurfaceControl.Transaction::new;
updateThemeColors();
- mMainExecutor = executor;
- mSurfaceControlTransactionFactory = SurfaceControl.Transaction::new;
}
@Override
public void onDisplayAreaAppeared(@NonNull DisplayAreaInfo displayAreaInfo,
@NonNull SurfaceControl leash) {
- synchronized (mLock) {
- if (mParentLeash == null) {
- mParentLeash = leash;
- } else {
- throw new RuntimeException("There should be only one DisplayArea for "
- + "the one-handed mode background panel");
- }
- }
- }
-
- OneHandedAnimationCallback getOneHandedAnimationCallback() {
- return mOneHandedAnimationCallback;
+ mParentLeash = leash;
}
@Override
public List<DisplayAreaAppearedInfo> registerOrganizer(int displayAreaFeature) {
- synchronized (mLock) {
- final List<DisplayAreaAppearedInfo> displayAreaInfos;
- displayAreaInfos = super.registerOrganizer(displayAreaFeature);
- for (int i = 0; i < displayAreaInfos.size(); i++) {
- final DisplayAreaAppearedInfo info = displayAreaInfos.get(i);
- onDisplayAreaAppeared(info.getDisplayAreaInfo(), info.getLeash());
- }
- return displayAreaInfos;
+ final List<DisplayAreaAppearedInfo> displayAreaInfos;
+ displayAreaInfos = super.registerOrganizer(displayAreaFeature);
+ for (int i = 0; i < displayAreaInfos.size(); i++) {
+ final DisplayAreaAppearedInfo info = displayAreaInfos.get(i);
+ onDisplayAreaAppeared(info.getDisplayAreaInfo(), info.getLeash());
}
+ return displayAreaInfos;
}
@Override
public void unregisterOrganizer() {
- synchronized (mLock) {
- super.unregisterOrganizer();
- mParentLeash = null;
- }
+ super.unregisterOrganizer();
+ removeBackgroundPanelLayer();
+ mParentLeash = null;
+ }
+
+ @Override
+ public void onAnimationUpdate(SurfaceControl.Transaction tx, float xPos, float yPos) {
+ final int yTopPos = (mStableInsets.top - mBkgBounds.height()) + Math.round(yPos);
+ tx.setPosition(mBackgroundSurface, 0, yTopPos);
}
@Nullable
@VisibleForTesting
- SurfaceControl getBackgroundSurface() {
- synchronized (mLock) {
- if (mParentLeash == null) {
- return null;
- }
-
- if (mBackgroundSurface == null) {
- mBackgroundSurface = new SurfaceControl.Builder(mSurfaceSession)
- .setParent(mParentLeash)
- .setBufferSize(mBkgBounds.width(), mBkgBounds.height())
- .setColorLayer()
- .setFormat(PixelFormat.RGB_888)
- .setOpaque(true)
- .setName("one-handed-background-panel")
- .setCallsite("OneHandedBackgroundPanelOrganizer")
- .build();
- }
- return mBackgroundSurface;
+ boolean isRegistered() {
+ return mParentLeash != null;
+ }
+
+ void createBackgroundSurface() {
+ mBackgroundSurface = new SurfaceControl.Builder(mSurfaceSession)
+ .setBufferSize(mBkgBounds.width(), mBkgBounds.height())
+ .setColorLayer()
+ .setFormat(PixelFormat.RGB_888)
+ .setOpaque(true)
+ .setName("one-handed-background-panel")
+ .setCallsite("OneHandedBackgroundPanelOrganizer")
+ .build();
+
+ // TODO(185890335) Avoid Dimming for mid-range luminance wallpapers flash.
+ mAlphaAnimator = ValueAnimator.ofFloat(1.0f, 0.0f);
+ mAlphaAnimator.setInterpolator(new LinearInterpolator());
+ mAlphaAnimator.setDuration(ALPHA_ANIMATION_DURATION);
+ mAlphaAnimator.addUpdateListener(
+ animator -> detachBackgroundFromParent(animator));
+ }
+
+ void detachBackgroundFromParent(ValueAnimator animator) {
+ if (mBackgroundSurface == null || mParentLeash == null) {
+ return;
+ }
+ // TODO(185890335) Avoid Dimming for mid-range luminance wallpapers flash.
+ final float currentValue = (float) animator.getAnimatedValue();
+ final SurfaceControl.Transaction tx = mTransactionFactory.getTransaction();
+ if (currentValue == 0.0f) {
+ tx.reparent(mBackgroundSurface, null).apply();
+ } else {
+ tx.setAlpha(mBackgroundSurface, (float) animator.getAnimatedValue()).apply();
}
}
+ /**
+ * Called when onDisplayAdded() or onDisplayRemoved() callback.
+ *
+ * @param displayLayout The latest {@link DisplayLayout} representing current displayId
+ */
+ public void onDisplayChanged(DisplayLayout displayLayout) {
+ mStableInsets = displayLayout.stableInsets();
+ // Ensure the mBkgBounds is portrait, due to OHM only support on portrait
+ if (displayLayout.height() > displayLayout.width()) {
+ mBkgBounds = new Rect(0, 0, displayLayout.width(),
+ Math.round(displayLayout.height() * mTranslationFraction) + mStableInsets.top);
+ } else {
+ mBkgBounds = new Rect(0, 0, displayLayout.height(),
+ Math.round(displayLayout.width() * mTranslationFraction) + mStableInsets.top);
+ }
+ }
+
+ @VisibleForTesting
+ void onStart() {
+ if (mBackgroundSurface == null) {
+ createBackgroundSurface();
+ }
+ showBackgroundPanelLayer();
+ }
+
+ /**
+ * Called when transition finished.
+ */
+ public void onStopFinished() {
+ mAlphaAnimator.start();
+ }
+
@VisibleForTesting
void showBackgroundPanelLayer() {
- synchronized (mLock) {
- if (mIsShowing) {
- return;
- }
-
- if (getBackgroundSurface() == null) {
- return;
- }
-
- SurfaceControl.Transaction transaction =
- mSurfaceControlTransactionFactory.getTransaction();
- transaction.setLayer(mBackgroundSurface, -1 /* at bottom-most layer */)
- .setColor(mBackgroundSurface, mDefaultColor)
- .show(mBackgroundSurface)
- .apply();
- transaction.close();
- mIsShowing = true;
+ if (mParentLeash == null) {
+ return;
+ }
+
+ if (mBackgroundSurface == null) {
+ createBackgroundSurface();
}
+
+ // TODO(185890335) Avoid Dimming for mid-range luminance wallpapers flash.
+ if (mAlphaAnimator.isRunning()) {
+ mAlphaAnimator.end();
+ }
+
+ mTransactionFactory.getTransaction()
+ .reparent(mBackgroundSurface, mParentLeash)
+ .setAlpha(mBackgroundSurface, 1.0f)
+ .setLayer(mBackgroundSurface, -1 /* at bottom-most layer */)
+ .setColor(mBackgroundSurface, mThemeColor)
+ .show(mBackgroundSurface)
+ .apply();
}
@VisibleForTesting
void removeBackgroundPanelLayer() {
- synchronized (mLock) {
- if (mBackgroundSurface == null) {
- return;
- }
-
- SurfaceControl.Transaction transaction =
- mSurfaceControlTransactionFactory.getTransaction();
- transaction.remove(mBackgroundSurface).apply();
- transaction.close();
- mBackgroundSurface = null;
- mIsShowing = false;
+ if (mBackgroundSurface == null) {
+ return;
}
+
+ mTransactionFactory.getTransaction()
+ .remove(mBackgroundSurface)
+ .apply();
+ mBackgroundSurface = null;
}
/**
* onConfigurationChanged events for updating tutorial text.
*/
public void onConfigurationChanged() {
- synchronized (mLock) {
- if (mBackgroundSurface == null) {
- getBackgroundSurface();
- } else {
- removeBackgroundPanelLayer();
- }
- updateThemeColors();
- showBackgroundPanelLayer();
- }
+ updateThemeColors();
+ showBackgroundPanelLayer();
}
private void updateThemeColors() {
- synchronized (mLock) {
- final int themeColor = mContext.getColor(R.color.one_handed_tutorial_background_color);
- mDefaultColor = new float[]{(Color.red(themeColor) - THEME_COLOR_OFFSET) / 255.0f,
- (Color.green(themeColor) - THEME_COLOR_OFFSET) / 255.0f,
- (Color.blue(themeColor) - THEME_COLOR_OFFSET) / 255.0f};
- }
+ final Context themedContext = new ContextThemeWrapper(mContext,
+ com.android.internal.R.style.Theme_DeviceDefault_DayNight);
+ final int themeColor = themedContext.getColor(
+ R.color.one_handed_tutorial_background_color);
+ mThemeColor = new float[]{
+ adjustColor(Color.red(themeColor)),
+ adjustColor(Color.green(themeColor)),
+ adjustColor(Color.blue(themeColor))};
+ }
+
+ private float adjustColor(int origColor) {
+ return Math.max(origColor - THEME_COLOR_OFFSET, 0) / 255.0f;
}
void dump(@NonNull PrintWriter pw) {
final String innerPrefix = " ";
pw.println(TAG);
- pw.print(innerPrefix + "mIsShowing=");
- pw.println(mIsShowing);
+ pw.print(innerPrefix + "mBackgroundSurface=");
+ pw.println(mBackgroundSurface);
pw.print(innerPrefix + "mBkgBounds=");
pw.println(mBkgBounds);
- pw.print(innerPrefix + "mDefaultColor=");
- pw.println(mDefaultColor);
+ pw.print(innerPrefix + "mThemeColor=");
+ pw.println(mThemeColor);
+ pw.print(innerPrefix + "mTranslationFraction=");
+ pw.println(mTranslationFraction);
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java
index 09cde38a0cfc..b0fe856df7c8 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java
@@ -180,6 +180,7 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
public void onStopFinished(Rect bounds) {
mState.setState(STATE_NONE);
notifyShortcutStateChanged(STATE_NONE);
+ mBackgroundPanelOrganizer.onStopFinished();
}
};
@@ -223,13 +224,14 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
OneHandedTimeoutHandler timeoutHandler = new OneHandedTimeoutHandler(mainExecutor);
OneHandedState transitionState = new OneHandedState();
OneHandedTutorialHandler tutorialHandler = new OneHandedTutorialHandler(context,
- windowManager);
+ settingsUtil, windowManager);
OneHandedAnimationController animationController =
new OneHandedAnimationController(context);
OneHandedTouchHandler touchHandler = new OneHandedTouchHandler(timeoutHandler,
mainExecutor);
OneHandedBackgroundPanelOrganizer oneHandedBackgroundPanelOrganizer =
- new OneHandedBackgroundPanelOrganizer(context, displayLayout, mainExecutor);
+ new OneHandedBackgroundPanelOrganizer(context, displayLayout, settingsUtil,
+ mainExecutor);
OneHandedDisplayAreaOrganizer organizer = new OneHandedDisplayAreaOrganizer(
context, displayLayout, settingsUtil, animationController, tutorialHandler,
oneHandedBackgroundPanelOrganizer, mainExecutor);
@@ -386,6 +388,7 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
mDisplayAreaOrganizer.getDisplayLayout().height() * mOffSetFraction);
mOneHandedAccessibilityUtil.announcementForScreenReader(
mOneHandedAccessibilityUtil.getOneHandedStartDescription());
+ mBackgroundPanelOrganizer.onStart();
mDisplayAreaOrganizer.scheduleOffset(0, yOffSet);
mTimeoutHandler.resetTimer();
mOneHandedUiEventLogger.writeEvent(
@@ -423,7 +426,6 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
stopOneHanded(OneHandedUiEventLogger.EVENT_ONE_HANDED_TRIGGER_OVERSPACE_OUT));
mDisplayAreaOrganizer.registerTransitionCallback(mTouchHandler);
mDisplayAreaOrganizer.registerTransitionCallback(mTutorialHandler);
- mDisplayAreaOrganizer.registerTransitionCallback(mBackgroundPanelOrganizer);
mDisplayAreaOrganizer.registerTransitionCallback(mTransitionCallBack);
if (mTaskChangeToExit) {
mTaskStackListener.addListener(mTaskStackListenerCallback);
@@ -469,6 +471,7 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
final DisplayLayout newDisplayLayout = mDisplayController.getDisplayLayout(displayId);
mDisplayAreaOrganizer.setDisplayLayout(newDisplayLayout);
mTutorialHandler.onDisplayChanged(newDisplayLayout);
+ mBackgroundPanelOrganizer.onDisplayChanged(newDisplayLayout);
}
private ContentObserver getObserver(Runnable onChangeRunnable) {
@@ -606,7 +609,7 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
OneHandedDisplayAreaOrganizer.FEATURE_ONE_HANDED);
}
- if (mBackgroundPanelOrganizer.getBackgroundSurface() == null) {
+ if (!mBackgroundPanelOrganizer.isRegistered()) {
mBackgroundPanelOrganizer.registerOrganizer(
OneHandedBackgroundPanelOrganizer.FEATURE_ONE_HANDED_BACKGROUND_PANEL);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java
index 03a90c6d4677..c2bbd9e99bac 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java
@@ -135,8 +135,8 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer {
SystemProperties.getInt(ONE_HANDED_MODE_TRANSLATE_ANIMATION_DURATION,
animationDurationConfig);
mSurfaceControlTransactionFactory = SurfaceControl.Transaction::new;
- mTutorialHandler = tutorialHandler;
mBackgroundPanelOrganizer = oneHandedBackgroundGradientOrganizer;
+ mTutorialHandler = tutorialHandler;
}
@Override
@@ -249,9 +249,8 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer {
if (animator != null) {
animator.setTransitionDirection(direction)
.addOneHandedAnimationCallback(mOneHandedAnimationCallback)
- .addOneHandedAnimationCallback(mTutorialHandler.getAnimationCallback())
- .addOneHandedAnimationCallback(
- mBackgroundPanelOrganizer.getOneHandedAnimationCallback())
+ .addOneHandedAnimationCallback(mTutorialHandler)
+ .addOneHandedAnimationCallback(mBackgroundPanelOrganizer)
.setDuration(durationMs)
.start();
}
@@ -267,7 +266,6 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer {
mLastVisualDisplayBounds.offsetTo(0, Math.round(mLastVisualOffset));
for (int i = mTransitionCallbacks.size() - 1; i >= 0; i--) {
final OneHandedTransitionCallback cb = mTransitionCallbacks.get(i);
- cb.onStartTransition(false /* isTransitioning */);
if (direction == TRANSITION_DIRECTION_TRIGGER) {
cb.onStartFinished(getLastVisualDisplayBounds());
} else {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedSettingsUtil.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedSettingsUtil.java
index 5911f8d66b32..60074b8cdb47 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedSettingsUtil.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedSettingsUtil.java
@@ -20,6 +20,7 @@ import static com.android.internal.accessibility.AccessibilityShortcutController
import android.annotation.IntDef;
import android.content.ContentResolver;
+import android.content.Context;
import android.database.ContentObserver;
import android.net.Uri;
import android.provider.Settings;
@@ -27,6 +28,8 @@ import android.text.TextUtils;
import androidx.annotation.Nullable;
+import com.android.wm.shell.R;
+
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -36,7 +39,6 @@ import java.lang.annotation.RetentionPolicy;
*/
public final class OneHandedSettingsUtil {
private static final String TAG = "OneHandedSettingsUtil";
-
private static final String ONE_HANDED_MODE_TARGET_NAME =
ONE_HANDED_COMPONENT_NAME.getShortClassName();
@@ -204,6 +206,25 @@ public final class OneHandedSettingsUtil {
Settings.Secure.ONE_HANDED_MODE_ACTIVATED, state, userId);
}
+ /**
+ * Obtains one-handed mode transition duration from resource config.
+ *
+ * @return durationMs The duration in milli-seconds
+ */
+ public int getTransitionDuration(Context context) {
+ return context.getResources().getInteger(
+ R.integer.config_one_handed_translate_animation_duration);
+ }
+
+ /**
+ * Obtains one-handed mode offset fraction from resource config.
+ *
+ * @return fraction The fraction of offset of the whole screen.
+ */
+ public float getTranslationFraction(Context context) {
+ return context.getResources().getFraction(R.fraction.config_one_handed_offset, 1, 1);
+ }
+
void dump(PrintWriter pw, String prefix, ContentResolver resolver,
int userId) {
final String innerPrefix = " ";
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTutorialHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTutorialHandler.java
index 97e04b5a7abd..f58c6b173af9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTutorialHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTutorialHandler.java
@@ -32,9 +32,9 @@ import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.graphics.PixelFormat;
import android.graphics.Rect;
-import android.os.SystemProperties;
import android.view.Gravity;
import android.view.LayoutInflater;
+import android.view.SurfaceControl;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
@@ -58,66 +58,54 @@ import java.io.PrintWriter;
* detach TargetViewContainer from window after exiting one handed mode.
*/
public class OneHandedTutorialHandler implements OneHandedTransitionCallback,
- OneHandedState.OnStateChangedListener {
+ OneHandedState.OnStateChangedListener, OneHandedAnimationCallback {
private static final String TAG = "OneHandedTutorialHandler";
- private static final String OFFSET_PERCENTAGE = "persist.debug.one_handed_offset_percentage";
- private static final String TRANSLATE_ANIMATION_DURATION =
- "persist.debug.one_handed_translate_animation_duration";
- private static final float START_TRANSITION_FRACTION = 0.7f;
+ private static final float START_TRANSITION_FRACTION = 0.6f;
private final float mTutorialHeightRatio;
private final WindowManager mWindowManager;
- private final OneHandedAnimationCallback mAnimationCallback;
private @OneHandedState.State int mCurrentState;
private int mTutorialAreaHeight;
private Context mContext;
private Rect mDisplayBounds;
+ private ValueAnimator mAlphaAnimator;
private @Nullable View mTutorialView;
private @Nullable ViewGroup mTargetViewContainer;
private float mAlphaTransitionStart;
- private ValueAnimator mAlphaAnimator;
private int mAlphaAnimationDurationMs;
- public OneHandedTutorialHandler(Context context, WindowManager windowManager) {
+ public OneHandedTutorialHandler(Context context, OneHandedSettingsUtil settingsUtil,
+ WindowManager windowManager) {
mContext = context;
mWindowManager = windowManager;
- final float offsetPercentageConfig = context.getResources().getFraction(
- R.fraction.config_one_handed_offset, 1, 1);
- final int sysPropPercentageConfig = SystemProperties.getInt(
- OFFSET_PERCENTAGE, Math.round(offsetPercentageConfig * 100.0f));
- mTutorialHeightRatio = sysPropPercentageConfig / 100.0f;
- final int animationDuration = context.getResources().getInteger(
- R.integer.config_one_handed_translate_animation_duration);
- mAlphaAnimationDurationMs = SystemProperties.getInt(TRANSLATE_ANIMATION_DURATION,
- animationDuration);
- mAnimationCallback = new OneHandedAnimationCallback() {
- @Override
- public void onOneHandedAnimationCancel(
- OneHandedAnimationController.OneHandedTransitionAnimator animator) {
- if (mAlphaAnimator != null) {
- mAlphaAnimator.cancel();
- }
- }
+ mTutorialHeightRatio = settingsUtil.getTranslationFraction(context);
+ mAlphaAnimationDurationMs = settingsUtil.getTransitionDuration(context);
+ }
- @Override
- public void onAnimationUpdate(float xPos, float yPos) {
- if (!isAttached()) {
- return;
- }
- if (yPos < mAlphaTransitionStart) {
- checkTransitionEnd();
- return;
- }
- if (mAlphaAnimator == null || mAlphaAnimator.isStarted()
- || mAlphaAnimator.isRunning()) {
- return;
- }
- mAlphaAnimator.start();
- }
- };
+ @Override
+ public void onOneHandedAnimationCancel(
+ OneHandedAnimationController.OneHandedTransitionAnimator animator) {
+ if (mAlphaAnimator != null) {
+ mAlphaAnimator.cancel();
+ }
+ }
+
+ @Override
+ public void onAnimationUpdate(SurfaceControl.Transaction tx, float xPos, float yPos) {
+ if (!isAttached()) {
+ return;
+ }
+ if (yPos < mAlphaTransitionStart) {
+ checkTransitionEnd();
+ return;
+ }
+ if (mAlphaAnimator == null || mAlphaAnimator.isStarted() || mAlphaAnimator.isRunning()) {
+ return;
+ }
+ mAlphaAnimator.start();
}
@Override
@@ -145,6 +133,7 @@ public class OneHandedTutorialHandler implements OneHandedTransitionCallback,
/**
* Called when onDisplayAdded() or onDisplayRemoved() callback.
+ *
* @param displayLayout The latest {@link DisplayLayout} representing current displayId
*/
public void onDisplayChanged(DisplayLayout displayLayout) {
@@ -196,10 +185,6 @@ public class OneHandedTutorialHandler implements OneHandedTransitionCallback,
mTargetViewContainer = null;
}
- @Nullable OneHandedAnimationCallback getAnimationCallback() {
- return mAnimationCallback;
- }
-
/**
* Returns layout params for the dismiss target, using the latest display metrics.
*/
@@ -264,15 +249,17 @@ public class OneHandedTutorialHandler implements OneHandedTransitionCallback,
private void setupAlphaTransition(boolean isEntering) {
final float start = isEntering ? 0.0f : 1.0f;
final float end = isEntering ? 1.0f : 0.0f;
+ final int duration = isEntering ? mAlphaAnimationDurationMs : Math.round(
+ mAlphaAnimationDurationMs * (1.0f - mTutorialHeightRatio));
mAlphaAnimator = ValueAnimator.ofFloat(start, end);
mAlphaAnimator.setInterpolator(new LinearInterpolator());
- mAlphaAnimator.setDuration(mAlphaAnimationDurationMs);
+ mAlphaAnimator.setDuration(duration);
mAlphaAnimator.addUpdateListener(
animator -> mTargetViewContainer.setAlpha((float) animator.getAnimatedValue()));
}
private void checkTransitionEnd() {
- if (mAlphaAnimator != null && mAlphaAnimator.isRunning()) {
+ if (mAlphaAnimator != null && (mAlphaAnimator.isRunning() || mAlphaAnimator.isStarted())) {
mAlphaAnimator.end();
mAlphaAnimator.removeAllUpdateListeners();
mAlphaAnimator = null;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
index 5a506193b8a1..f2bad6caf3e8 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
@@ -1384,11 +1384,20 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
final ValueAnimator animator = ValueAnimator.ofFloat(1.0f, 0.0f);
animator.setDuration(mCrossFadeAnimationDuration);
animator.addUpdateListener(animation -> {
- final float alpha = (float) animation.getAnimatedValue();
- final SurfaceControl.Transaction transaction =
- mSurfaceControlTransactionFactory.getTransaction();
- transaction.setAlpha(surface, alpha);
- transaction.apply();
+ if (mState == State.UNDEFINED) {
+ // Could happen if onTaskVanished happens during the animation since we may have
+ // set a start delay on this animation.
+ Log.d(TAG, "Task vanished, skip fadeOutAndRemoveOverlay");
+ animation.removeAllListeners();
+ animation.removeAllUpdateListeners();
+ animation.cancel();
+ } else {
+ final float alpha = (float) animation.getAnimatedValue();
+ final SurfaceControl.Transaction transaction =
+ mSurfaceControlTransactionFactory.getTransaction();
+ transaction.setAlpha(surface, alpha);
+ transaction.apply();
+ }
});
animator.addListener(new AnimatorListenerAdapter() {
@Override
@@ -1401,6 +1410,10 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
}
private void removeContentOverlay(SurfaceControl surface, Runnable callback) {
+ if (mState == State.UNDEFINED) {
+ // Avoid double removal, which is fatal.
+ return;
+ }
final SurfaceControl.Transaction tx =
mSurfaceControlTransactionFactory.getTransaction();
tx.remove(surface);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java
index 56ad2be11853..29326ec90e31 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java
@@ -23,7 +23,9 @@ import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_LEGACY_SPLA
import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_SPLASH_SCREEN;
import android.annotation.ColorInt;
+import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.app.ActivityThread;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -64,6 +66,7 @@ import com.android.wm.shell.common.TransactionPool;
import java.util.List;
import java.util.function.Consumer;
+import java.util.function.IntPredicate;
import java.util.function.IntSupplier;
import java.util.function.Supplier;
import java.util.function.UnaryOperator;
@@ -132,7 +135,6 @@ public class SplashscreenContentDrawer {
* @param splashScreenViewConsumer Receiving the SplashScreenView object, which will also be
* executed on splash screen thread. Note that the view can be
* null if failed.
- * @param bgColorConsumer Receiving the background color once it's estimated complete.
*/
void createContentView(Context context, @StartingWindowType int suggestType, ActivityInfo info,
int taskId, Consumer<SplashScreenView> splashScreenViewConsumer) {
@@ -209,9 +211,9 @@ public class SplashscreenContentDrawer {
}
private static int estimateWindowBGColor(Drawable themeBGDrawable) {
- final DrawableColorTester themeBGTester =
- new DrawableColorTester(themeBGDrawable, true /* filterTransparent */);
- if (themeBGTester.nonTransparentRatio() == 0) {
+ final DrawableColorTester themeBGTester = new DrawableColorTester(
+ themeBGDrawable, DrawableColorTester.TRANSPARENT_FILTER /* filterType */);
+ if (themeBGTester.passFilterRatio() == 0) {
// the window background is transparent, unable to draw
Slog.w(TAG, "Window background is transparent, fill background with black color");
return getSystemBGColor();
@@ -314,7 +316,7 @@ public class SplashscreenContentDrawer {
private Drawable mOverlayDrawable;
private int mSuggestType;
private int mThemeColor;
- private Drawable mFinalIconDrawable;
+ private Drawable[] mFinalIconDrawables;
private int mFinalIconSize = mIconSize;
StartingWindowViewBuilder(@NonNull Context context, @NonNull ActivityInfo aInfo) {
@@ -346,12 +348,13 @@ public class SplashscreenContentDrawer {
animationDuration = 0;
mFinalIconSize = 0;
} else if (mTmpAttrs.mSplashScreenIcon != null) {
- // replaced icon, don't process
+ // Using the windowSplashScreenAnimatedIcon attribute
iconDrawable = mTmpAttrs.mSplashScreenIcon;
animationDuration = mTmpAttrs.mAnimationDuration;
// There is no background below the icon, so scale the icon up
- if (mTmpAttrs.mIconBgColor == Color.TRANSPARENT) {
+ if (mTmpAttrs.mIconBgColor == Color.TRANSPARENT
+ || mTmpAttrs.mIconBgColor == mThemeColor) {
mFinalIconSize *= NO_BACKGROUND_SCALE;
}
createIconDrawable(iconDrawable, false);
@@ -382,7 +385,7 @@ public class SplashscreenContentDrawer {
animationDuration = 0;
}
- return fillViewWithIcon(mFinalIconSize, mFinalIconDrawable, animationDuration);
+ return fillViewWithIcon(mFinalIconSize, mFinalIconDrawables, animationDuration);
}
private class ShapeIconFactory extends BaseIconFactory {
@@ -393,12 +396,11 @@ public class SplashscreenContentDrawer {
private void createIconDrawable(Drawable iconDrawable, boolean legacy) {
if (legacy) {
- mFinalIconDrawable = SplashscreenIconDrawableFactory.makeLegacyIconDrawable(
+ mFinalIconDrawables = SplashscreenIconDrawableFactory.makeLegacyIconDrawable(
iconDrawable, mDefaultIconSize, mFinalIconSize, mSplashscreenWorkerHandler);
} else {
- mFinalIconDrawable = SplashscreenIconDrawableFactory.makeIconDrawable(
- mTmpAttrs.mIconBgColor != Color.TRANSPARENT
- ? mTmpAttrs.mIconBgColor : mThemeColor,
+ mFinalIconDrawables = SplashscreenIconDrawableFactory.makeIconDrawable(
+ mTmpAttrs.mIconBgColor, mThemeColor,
iconDrawable, mDefaultIconSize, mFinalIconSize, mSplashscreenWorkerHandler);
}
}
@@ -414,7 +416,8 @@ public class SplashscreenContentDrawer {
final ColorCache.IconColor iconColor = mColorCache.getIconColor(
mActivityInfo.packageName, mActivityInfo.getIconResource(),
mLastPackageContextConfigHash,
- () -> new DrawableColorTester(iconForeground, true /* filterTransparent */),
+ () -> new DrawableColorTester(iconForeground,
+ DrawableColorTester.TRANSLUCENT_FILTER /* filterType */),
() -> new DrawableColorTester(adaptiveIconDrawable.getBackground()));
if (DEBUG) {
@@ -443,7 +446,7 @@ public class SplashscreenContentDrawer {
// Reference AdaptiveIcon description, outer is 108 and inner is 72, so we
// scale by 192/160 if we only draw adaptiveIcon's foreground.
final float noBgScale =
- iconColor.mFgNonTransparentRatio < ENLARGE_FOREGROUND_ICON_THRESHOLD
+ iconColor.mFgNonTranslucentRatio < ENLARGE_FOREGROUND_ICON_THRESHOLD
? NO_BACKGROUND_SCALE : 1f;
// Using AdaptiveIconDrawable here can help keep the shape consistent with the
// current settings.
@@ -459,18 +462,24 @@ public class SplashscreenContentDrawer {
return true;
}
- private SplashScreenView fillViewWithIcon(int iconSize, Drawable iconDrawable,
+ private SplashScreenView fillViewWithIcon(int iconSize, @Nullable Drawable[] iconDrawable,
int animationDuration) {
- Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "fillViewWithIcon");
- final SplashScreenView.Builder builder = new SplashScreenView.Builder(mContext);
- builder.setBackgroundColor(mThemeColor);
- builder.setOverlayDrawable(mOverlayDrawable);
+ Drawable foreground = null;
+ Drawable background = null;
if (iconDrawable != null) {
- builder.setIconSize(iconSize)
- .setIconBackground(mTmpAttrs.mIconBgColor)
- .setCenterViewDrawable(iconDrawable)
- .setAnimationDurationMillis(animationDuration);
+ foreground = iconDrawable.length > 0 ? iconDrawable[0] : null;
+ background = iconDrawable.length > 1 ? iconDrawable[1] : null;
}
+
+ Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "fillViewWithIcon");
+ final SplashScreenView.Builder builder = new SplashScreenView.Builder(mContext)
+ .setBackgroundColor(mThemeColor)
+ .setOverlayDrawable(mOverlayDrawable)
+ .setIconSize(iconSize)
+ .setIconBackground(background)
+ .setCenterViewDrawable(foreground)
+ .setAnimationDurationMillis(animationDuration);
+
if (mSuggestType == STARTING_WINDOW_TYPE_SPLASH_SCREEN
&& mTmpAttrs.mBrandingImage != null) {
builder.setBrandingDrawable(mTmpAttrs.mBrandingImage, mBrandingImageWidth,
@@ -545,13 +554,26 @@ public class SplashscreenContentDrawer {
}
private static class DrawableColorTester {
+ private static final int NO_ALPHA_FILTER = 0;
+ // filter out completely invisible pixels
+ private static final int TRANSPARENT_FILTER = 1;
+ // filter out translucent and invisible pixels
+ private static final int TRANSLUCENT_FILTER = 2;
+
+ @IntDef(flag = true, value = {
+ NO_ALPHA_FILTER,
+ TRANSPARENT_FILTER,
+ TRANSLUCENT_FILTER
+ })
+ private @interface QuantizerFilterType {}
+
private final ColorTester mColorChecker;
DrawableColorTester(Drawable drawable) {
- this(drawable, false /* filterTransparent */);
+ this(drawable, NO_ALPHA_FILTER /* filterType */);
}
- DrawableColorTester(Drawable drawable, boolean filterTransparent) {
+ DrawableColorTester(Drawable drawable, @QuantizerFilterType int filterType) {
// Some applications use LayerDrawable for their windowBackground. To ensure that we
// only get the real background, so that the color is not affected by the alpha of the
// upper layer, try to get the lower layer here. This can also speed up the calculation.
@@ -570,12 +592,12 @@ public class SplashscreenContentDrawer {
} else {
mColorChecker = drawable instanceof ColorDrawable
? new SingleColorTester((ColorDrawable) drawable)
- : new ComplexDrawableTester(drawable, filterTransparent);
+ : new ComplexDrawableTester(drawable, filterType);
}
}
- public float nonTransparentRatio() {
- return mColorChecker.nonTransparentRatio();
+ public float passFilterRatio() {
+ return mColorChecker.passFilterRatio();
}
public boolean isComplexColor() {
@@ -594,7 +616,7 @@ public class SplashscreenContentDrawer {
* A help class to check the color information from a Drawable.
*/
private interface ColorTester {
- float nonTransparentRatio();
+ float passFilterRatio();
boolean isComplexColor();
@@ -622,7 +644,7 @@ public class SplashscreenContentDrawer {
}
@Override
- public float nonTransparentRatio() {
+ public float passFilterRatio() {
final int alpha = mColorDrawable.getAlpha();
return (float) (alpha / 255);
}
@@ -651,15 +673,21 @@ public class SplashscreenContentDrawer {
private static final int MAX_BITMAP_SIZE = 40;
private final Palette mPalette;
private final boolean mFilterTransparent;
- private static final TransparentFilterQuantizer TRANSPARENT_FILTER_QUANTIZER =
- new TransparentFilterQuantizer();
-
- ComplexDrawableTester(Drawable drawable, boolean filterTransparent) {
+ private static final AlphaFilterQuantizer ALPHA_FILTER_QUANTIZER =
+ new AlphaFilterQuantizer();
+
+ /**
+ * @param drawable The test target.
+ * @param filterType Targeting to filter out transparent or translucent pixels,
+ * this would be needed if want to check
+ * {@link #passFilterRatio()}, also affecting the estimated result
+ * of the dominant color.
+ */
+ ComplexDrawableTester(Drawable drawable, @QuantizerFilterType int filterType) {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "ComplexDrawableTester");
final Rect initialBounds = drawable.copyBounds();
int width = drawable.getIntrinsicWidth();
int height = drawable.getIntrinsicHeight();
-
// Some drawables do not have intrinsic dimensions
if (width <= 0 || height <= 0) {
width = MAX_BITMAP_SIZE;
@@ -680,9 +708,10 @@ public class SplashscreenContentDrawer {
// The Palette API will ignore Alpha, so it cannot handle transparent pixels, but
// sometimes we will need this information to know if this Drawable object is
// transparent.
- mFilterTransparent = filterTransparent;
+ mFilterTransparent = filterType != NO_ALPHA_FILTER;
if (mFilterTransparent) {
- builder = new Palette.Builder(bitmap, TRANSPARENT_FILTER_QUANTIZER)
+ ALPHA_FILTER_QUANTIZER.setFilter(filterType);
+ builder = new Palette.Builder(bitmap, ALPHA_FILTER_QUANTIZER)
.maximumColorCount(5);
} else {
builder = new Palette.Builder(bitmap, null)
@@ -694,8 +723,8 @@ public class SplashscreenContentDrawer {
}
@Override
- public float nonTransparentRatio() {
- return mFilterTransparent ? TRANSPARENT_FILTER_QUANTIZER.mNonTransparentRatio : 1;
+ public float passFilterRatio() {
+ return mFilterTransparent ? ALPHA_FILTER_QUANTIZER.mPassFilterRatio : 1;
}
@Override
@@ -726,17 +755,34 @@ public class SplashscreenContentDrawer {
return true;
}
- private static class TransparentFilterQuantizer implements Quantizer {
+ private static class AlphaFilterQuantizer implements Quantizer {
private static final int NON_TRANSPARENT = 0xFF000000;
private final Quantizer mInnerQuantizer = new VariationalKMeansQuantizer();
- private float mNonTransparentRatio;
+ private final IntPredicate mTransparentFilter = i -> (i & NON_TRANSPARENT) != 0;
+ private final IntPredicate mTranslucentFilter = i ->
+ (i & NON_TRANSPARENT) == NON_TRANSPARENT;
+
+ private IntPredicate mFilter = mTransparentFilter;
+ private float mPassFilterRatio;
+
+ void setFilter(@QuantizerFilterType int filterType) {
+ switch (filterType) {
+ case TRANSLUCENT_FILTER:
+ mFilter = mTranslucentFilter;
+ break;
+ case TRANSPARENT_FILTER:
+ default:
+ mFilter = mTransparentFilter;
+ break;
+ }
+ }
@Override
public void quantize(final int[] pixels, final int maxColors) {
- mNonTransparentRatio = 0;
+ mPassFilterRatio = 0;
int realSize = 0;
for (int i = pixels.length - 1; i > 0; i--) {
- if ((pixels[i] & NON_TRANSPARENT) != 0) {
+ if (mFilter.test(pixels[i])) {
realSize++;
}
}
@@ -747,11 +793,11 @@ public class SplashscreenContentDrawer {
mInnerQuantizer.quantize(pixels, maxColors);
return;
}
- mNonTransparentRatio = (float) realSize / pixels.length;
+ mPassFilterRatio = (float) realSize / pixels.length;
final int[] samplePixels = new int[realSize];
int rowIndex = 0;
for (int i = pixels.length - 1; i > 0; i--) {
- if ((pixels[i] & NON_TRANSPARENT) == NON_TRANSPARENT) {
+ if (mFilter.test(pixels[i])) {
samplePixels[rowIndex] = pixels[i];
rowIndex++;
}
@@ -810,16 +856,16 @@ public class SplashscreenContentDrawer {
final int mBgColor;
final boolean mIsBgComplex;
final boolean mIsBgGrayscale;
- final float mFgNonTransparentRatio;
+ final float mFgNonTranslucentRatio;
IconColor(int hash, int fgColor, int bgColor, boolean isBgComplex,
- boolean isBgGrayscale, float fgNonTransparentRatio) {
+ boolean isBgGrayscale, float fgNonTranslucnetRatio) {
super(hash);
mFgColor = fgColor;
mBgColor = bgColor;
mIsBgComplex = isBgComplex;
mIsBgGrayscale = isBgGrayscale;
- mFgNonTransparentRatio = fgNonTransparentRatio;
+ mFgNonTranslucentRatio = fgNonTranslucnetRatio;
}
}
@@ -905,7 +951,7 @@ public class SplashscreenContentDrawer {
final DrawableColorTester bgTester = bgColorTesterSupplier.get();
final IconColor iconColor = new IconColor(hash, fgTester.getDominateColor(),
bgTester.getDominateColor(), bgTester.isComplexColor(), bgTester.isGrayscale(),
- fgTester.nonTransparentRatio());
+ fgTester.passFilterRatio());
colors.mIconColors[leastUsedIndex[0]] = iconColor;
return iconColor;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenIconDrawableFactory.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenIconDrawableFactory.java
index ba9123dca999..951b97e791c9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenIconDrawableFactory.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenIconDrawableFactory.java
@@ -22,9 +22,11 @@ import android.animation.Animator;
import android.animation.ValueAnimator;
import android.annotation.ColorInt;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
+import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Matrix;
import android.graphics.Paint;
@@ -33,7 +35,6 @@ import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.drawable.AdaptiveIconDrawable;
import android.graphics.drawable.Animatable;
-import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Trace;
@@ -44,32 +45,55 @@ import com.android.internal.R;
/**
* Creating a lightweight Drawable object used for splash screen.
+ *
* @hide
*/
public class SplashscreenIconDrawableFactory {
- static Drawable makeIconDrawable(@ColorInt int backgroundColor,
+ /**
+ * @return An array containing the foreground drawable at index 0 and if needed a background
+ * drawable at index 1.
+ */
+ static Drawable[] makeIconDrawable(@ColorInt int backgroundColor, @ColorInt int themeColor,
@NonNull Drawable foregroundDrawable, int srcIconSize, int iconSize,
Handler splashscreenWorkerHandler) {
+ Drawable foreground;
+ Drawable background = null;
+ boolean drawBackground =
+ backgroundColor != Color.TRANSPARENT && backgroundColor != themeColor;
+
if (foregroundDrawable instanceof Animatable) {
- return new AnimatableIconAnimateListener(backgroundColor, foregroundDrawable);
+ foreground = new AnimatableIconAnimateListener(foregroundDrawable);
} else if (foregroundDrawable instanceof AdaptiveIconDrawable) {
- return new ImmobileIconDrawable(foregroundDrawable,
+ // If the icon is Adaptive, we already use the icon background.
+ drawBackground = false;
+ foreground = new ImmobileIconDrawable(foregroundDrawable,
srcIconSize, iconSize, splashscreenWorkerHandler);
} else {
- // single layer icon
- return new ImmobileIconDrawable(new AdaptiveIconDrawable(
- new ColorDrawable(backgroundColor), foregroundDrawable),
+ // Adaptive icon don't handle transparency so we draw the background of the adaptive
+ // icon with the same color as the window background color instead of using two layers
+ foreground = new ImmobileIconDrawable(
+ new AdaptiveForegroundDrawable(foregroundDrawable),
srcIconSize, iconSize, splashscreenWorkerHandler);
}
+
+ if (drawBackground) {
+ background = new MaskBackgroundDrawable(backgroundColor);
+ }
+
+ return new Drawable[]{foreground, background};
}
- static Drawable makeLegacyIconDrawable(@NonNull Drawable iconDrawable, int srcIconSize,
+ static Drawable[] makeLegacyIconDrawable(@NonNull Drawable iconDrawable, int srcIconSize,
int iconSize, Handler splashscreenWorkerHandler) {
- return new ImmobileIconDrawable(iconDrawable, srcIconSize, iconSize,
- splashscreenWorkerHandler);
+ return new Drawable[]{new ImmobileIconDrawable(iconDrawable, srcIconSize, iconSize,
+ splashscreenWorkerHandler)};
}
+ /**
+ * Drawable pre-drawing the scaled icon in a separate thread to increase the speed of the
+ * final drawing.
+ */
private static class ImmobileIconDrawable extends Drawable {
private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG
| Paint.FILTER_BITMAP_FLAG);
@@ -121,8 +145,10 @@ public class SplashscreenIconDrawableFactory {
}
}
- // Base class the draw the circle background
- private abstract static class MaskBackgroundDrawable extends Drawable {
+ /**
+ * Base class the draw a background clipped by the system mask.
+ */
+ public static class MaskBackgroundDrawable extends Drawable {
private static final float MASK_SIZE = AdaptiveIconDrawable.MASK_SIZE;
private static final float EXTRA_INSET_PERCENTAGE = 1 / 4f;
static final float DEFAULT_VIEW_PORT_SCALE = 1f / (1 + 2 * EXTRA_INSET_PERCENTAGE);
@@ -132,17 +158,24 @@ public class SplashscreenIconDrawableFactory {
private static Path sMask;
private final Path mMaskScaleOnly;
private final Matrix mMaskMatrix;
- private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG
- | Paint.FILTER_BITMAP_FLAG);
- MaskBackgroundDrawable(@ColorInt int backgroundColor) {
+ @Nullable
+ private final Paint mBackgroundPaint;
+
+ public MaskBackgroundDrawable(@ColorInt int backgroundColor) {
final Resources r = Resources.getSystem();
sMask = PathParser.createPathFromPathData(r.getString(R.string.config_icon_mask));
Path mask = new Path(sMask);
mMaskScaleOnly = new Path(mask);
mMaskMatrix = new Matrix();
- mPaint.setColor(backgroundColor);
- mPaint.setStyle(Paint.Style.FILL);
+ if (backgroundColor != Color.TRANSPARENT) {
+ mBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG
+ | Paint.FILTER_BITMAP_FLAG);
+ mBackgroundPaint.setColor(backgroundColor);
+ mBackgroundPaint.setStyle(Paint.Style.FILL);
+ } else {
+ mBackgroundPaint = null;
+ }
}
@Override
@@ -162,40 +195,80 @@ public class SplashscreenIconDrawableFactory {
@Override
public void draw(Canvas canvas) {
canvas.clipPath(mMaskScaleOnly);
- if (mMaskScaleOnly != null) {
- canvas.drawPath(mMaskScaleOnly, mPaint);
+ if (mBackgroundPaint != null) {
+ canvas.drawPath(mMaskScaleOnly, mBackgroundPaint);
}
}
@Override
public void setAlpha(int alpha) {
- mPaint.setAlpha(alpha);
+ if (mBackgroundPaint != null) {
+ mBackgroundPaint.setAlpha(alpha);
+ }
}
@Override
public int getOpacity() {
return PixelFormat.RGBA_8888;
}
+
+ @Override
+ public void setColorFilter(ColorFilter colorFilter) {
+ }
+ }
+
+ private static class AdaptiveForegroundDrawable extends MaskBackgroundDrawable {
+
+ @NonNull
+ protected final Drawable mForegroundDrawable;
+ private final Rect mTmpOutRect = new Rect();
+
+ AdaptiveForegroundDrawable(@NonNull Drawable foregroundDrawable) {
+ super(Color.TRANSPARENT);
+ mForegroundDrawable = foregroundDrawable;
+ }
+
+ @Override
+ protected void updateLayerBounds(Rect bounds) {
+ super.updateLayerBounds(bounds);
+ int cX = bounds.width() / 2;
+ int cY = bounds.height() / 2;
+
+ int insetWidth = (int) (bounds.width() / (DEFAULT_VIEW_PORT_SCALE * 2));
+ int insetHeight = (int) (bounds.height() / (DEFAULT_VIEW_PORT_SCALE * 2));
+ final Rect outRect = mTmpOutRect;
+ outRect.set(cX - insetWidth, cY - insetHeight, cX + insetWidth, cY + insetHeight);
+ if (mForegroundDrawable != null) {
+ mForegroundDrawable.setBounds(outRect);
+ }
+ invalidateSelf();
+ }
+
+ @Override
+ public void draw(Canvas canvas) {
+ super.draw(canvas);
+ mForegroundDrawable.draw(canvas);
+ }
+
+ @Override
+ public void setColorFilter(ColorFilter colorFilter) {
+ mForegroundDrawable.setColorFilter(colorFilter);
+ }
}
/**
* A lightweight AdaptiveIconDrawable which support foreground to be Animatable, and keep this
* drawable masked by config_icon_mask.
*/
- private static class AnimatableIconAnimateListener extends MaskBackgroundDrawable
+ private static class AnimatableIconAnimateListener extends AdaptiveForegroundDrawable
implements SplashScreenView.IconAnimateListener {
- private final Drawable mForegroundDrawable;
private Animatable mAnimatableIcon;
private Animator mIconAnimator;
private boolean mAnimationTriggered;
- private final Rect mTmpOutRect = new Rect();
- AnimatableIconAnimateListener(@ColorInt int backgroundColor, Drawable foregroundDrawable) {
- super(backgroundColor);
- mForegroundDrawable = foregroundDrawable;
- if (mForegroundDrawable != null) {
- mForegroundDrawable.setCallback(mCallback);
- }
+ AnimatableIconAnimateListener(@NonNull Drawable foregroundDrawable) {
+ super(foregroundDrawable);
+ mForegroundDrawable.setCallback(mCallback);
}
@Override
@@ -231,22 +304,6 @@ public class SplashscreenIconDrawableFactory {
return true;
}
- @Override
- protected void updateLayerBounds(Rect bounds) {
- super.updateLayerBounds(bounds);
- int cX = bounds.width() / 2;
- int cY = bounds.height() / 2;
-
- int insetWidth = (int) (bounds.width() / (DEFAULT_VIEW_PORT_SCALE * 2));
- int insetHeight = (int) (bounds.height() / (DEFAULT_VIEW_PORT_SCALE * 2));
- final Rect outRect = mTmpOutRect;
- outRect.set(cX - insetWidth, cY - insetHeight, cX + insetWidth, cY + insetHeight);
- if (mForegroundDrawable != null) {
- mForegroundDrawable.setBounds(outRect);
- }
- invalidateSelf();
- }
-
private final Callback mCallback = new Callback() {
@Override
public void invalidateDrawable(@NonNull Drawable who) {
@@ -276,19 +333,8 @@ public class SplashscreenIconDrawableFactory {
@Override
public void draw(Canvas canvas) {
+ ensureAnimationStarted();
super.draw(canvas);
- if (mForegroundDrawable != null) {
- ensureAnimationStarted();
- mForegroundDrawable.draw(canvas);
- }
- }
-
- @Override
- public void setColorFilter(ColorFilter colorFilter) {
- if (mForegroundDrawable != null) {
- mForegroundDrawable.setColorFilter(colorFilter);
- }
}
}
-
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
index 243751fe13e8..fc7c86d669cb 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
@@ -168,16 +168,14 @@ public class StartingSurfaceDrawer {
void addSplashScreenStartingWindow(StartingWindowInfo windowInfo, IBinder appToken,
@StartingWindowType int suggestType) {
final RunningTaskInfo taskInfo = windowInfo.taskInfo;
- final ActivityInfo activityInfo = taskInfo.topActivityInfo;
- if (activityInfo == null) {
+ final ActivityInfo activityInfo = windowInfo.targetActivityInfo != null
+ ? windowInfo.targetActivityInfo
+ : taskInfo.topActivityInfo;
+ if (activityInfo == null || activityInfo.packageName == null) {
return;
}
final int displayId = taskInfo.displayId;
- if (activityInfo.packageName == null) {
- return;
- }
-
final int taskId = taskInfo.taskId;
Context context = mContext;
// replace with the default theme if the application didn't set
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizerTest.java
index 3f47c040dd8d..99c610765c04 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizerTest.java
@@ -22,7 +22,10 @@ import static android.window.DisplayAreaOrganizer.FEATURE_ONE_HANDED_BACKGROUND_
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.testing.AndroidTestingRunner;
@@ -54,17 +57,17 @@ public class OneHandedBackgroundPanelOrganizerTest extends OneHandedTestCase {
private OneHandedBackgroundPanelOrganizer mSpiedBackgroundPanelOrganizer;
private WindowContainerToken mToken;
private SurfaceControl mLeash;
- private TestableLooper mTestableLooper;
@Mock
IWindowContainerToken mMockRealToken;
@Mock
DisplayController mMockDisplayController;
+ @Mock
+ OneHandedSettingsUtil mMockSettingsUtil;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- mTestableLooper = TestableLooper.get(this);
mToken = new WindowContainerToken(mMockRealToken);
mLeash = new SurfaceControl();
mDisplay = mContext.getDisplay();
@@ -74,32 +77,36 @@ public class OneHandedBackgroundPanelOrganizerTest extends OneHandedTestCase {
FEATURE_ONE_HANDED_BACKGROUND_PANEL);
mSpiedBackgroundPanelOrganizer = spy(
- new OneHandedBackgroundPanelOrganizer(mContext, mDisplayLayout, Runnable::run));
+ new OneHandedBackgroundPanelOrganizer(mContext, mDisplayLayout, mMockSettingsUtil,
+ Runnable::run));
+ mSpiedBackgroundPanelOrganizer.onDisplayChanged(mDisplayLayout);
}
@Test
public void testOnDisplayAreaAppeared() {
mSpiedBackgroundPanelOrganizer.onDisplayAreaAppeared(mDisplayAreaInfo, mLeash);
- mTestableLooper.processAllMessages();
- assertThat(mSpiedBackgroundPanelOrganizer.getBackgroundSurface()).isNotNull();
+ assertThat(mSpiedBackgroundPanelOrganizer.isRegistered()).isTrue();
+ verify(mSpiedBackgroundPanelOrganizer, never()).showBackgroundPanelLayer();
}
@Test
public void testShowBackgroundLayer() {
- mSpiedBackgroundPanelOrganizer.onDisplayAreaAppeared(mDisplayAreaInfo, mLeash);
- mSpiedBackgroundPanelOrganizer.showBackgroundPanelLayer();
- mTestableLooper.processAllMessages();
+ mSpiedBackgroundPanelOrganizer.onDisplayAreaAppeared(mDisplayAreaInfo, null);
+ mSpiedBackgroundPanelOrganizer.onStart();
- assertThat(mSpiedBackgroundPanelOrganizer.mIsShowing).isTrue();
+ verify(mSpiedBackgroundPanelOrganizer).showBackgroundPanelLayer();
}
@Test
public void testRemoveBackgroundLayer() {
mSpiedBackgroundPanelOrganizer.onDisplayAreaAppeared(mDisplayAreaInfo, mLeash);
+
+ assertThat(mSpiedBackgroundPanelOrganizer.isRegistered()).isNotNull();
+
+ reset(mSpiedBackgroundPanelOrganizer);
mSpiedBackgroundPanelOrganizer.removeBackgroundPanelLayer();
- mTestableLooper.processAllMessages();
- assertThat(mSpiedBackgroundPanelOrganizer.mIsShowing).isFalse();
+ assertThat(mSpiedBackgroundPanelOrganizer.mBackgroundSurface).isNull();
}
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java
index b224ae6a19b5..911fe0753845 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java
@@ -110,7 +110,7 @@ public class OneHandedControllerTest extends OneHandedTestCase {
when(mMockDisplayController.getDisplay(anyInt())).thenReturn(mDisplay);
when(mMockDisplayAreaOrganizer.getDisplayAreaTokenMap()).thenReturn(new ArrayMap<>());
when(mMockDisplayAreaOrganizer.isReady()).thenReturn(true);
- when(mMockBackgroundOrganizer.getBackgroundSurface()).thenReturn(mMockLeash);
+ when(mMockBackgroundOrganizer.isRegistered()).thenReturn(true);
when(mMockSettingsUitl.getSettingsOneHandedModeEnabled(any(), anyInt())).thenReturn(
mDefaultEnabled);
when(mMockSettingsUitl.getSettingsOneHandedModeTimeout(any(), anyInt())).thenReturn(
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedStateTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedStateTest.java
index e61f0617852a..bea69c5d80ef 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedStateTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedStateTest.java
@@ -102,7 +102,7 @@ public class OneHandedStateTest extends OneHandedTestCase {
when(mMockDisplayController.getDisplay(anyInt())).thenReturn(mDisplay);
when(mMockDisplayAreaOrganizer.getDisplayAreaTokenMap()).thenReturn(new ArrayMap<>());
- when(mMockBackgroundOrganizer.getBackgroundSurface()).thenReturn(mMockLeash);
+ when(mMockBackgroundOrganizer.isRegistered()).thenReturn(true);
when(mMockSettingsUitl.getSettingsOneHandedModeEnabled(any(), anyInt())).thenReturn(
mDefaultEnabled);
when(mMockSettingsUitl.getSettingsOneHandedModeTimeout(any(), anyInt())).thenReturn(
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTutorialHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTutorialHandlerTest.java
index ae1d3b2a4c41..b1434ca325b7 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTutorialHandlerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTutorialHandlerTest.java
@@ -66,7 +66,7 @@ public class OneHandedTutorialHandlerTest extends OneHandedTestCase {
mDisplayLayout = new DisplayLayout(mContext, mDisplay);
mSpiedTransitionState = spy(new OneHandedState());
mSpiedTutorialHandler = spy(
- new OneHandedTutorialHandler(mContext, mMockWindowManager));
+ new OneHandedTutorialHandler(mContext, mMockSettingsUtil, mMockWindowManager));
mTimeoutHandler = new OneHandedTimeoutHandler(mMockShellMainExecutor);
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java
index 284f384a3d26..d536adb9f8ae 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawerTests.java
@@ -214,6 +214,7 @@ public class StartingSurfaceDrawerTests {
final ActivityManager.RunningTaskInfo taskInfo = new ActivityManager.RunningTaskInfo();
taskInfo.topActivityInfo = info;
taskInfo.taskId = taskId;
+ windowInfo.targetActivityInfo = info;
windowInfo.taskInfo = taskInfo;
return windowInfo;
}
diff --git a/media/java/android/media/ExifInterface.java b/media/java/android/media/ExifInterface.java
index d746c850a018..37054b8383b1 100644
--- a/media/java/android/media/ExifInterface.java
+++ b/media/java/android/media/ExifInterface.java
@@ -1573,6 +1573,9 @@ public class ExifInterface {
if (isFdDuped) {
closeFileDescriptor(fileDescriptor);
}
+ if (modernFd != null) {
+ modernFd.close();
+ }
}
}
@@ -2554,12 +2557,13 @@ public class ExifInterface {
private void initForFilename(String filename) throws IOException {
FileInputStream in = null;
+ ParcelFileDescriptor modernFd = null;
mAssetInputStream = null;
mFilename = filename;
mIsInputStream = false;
try {
in = new FileInputStream(filename);
- ParcelFileDescriptor modernFd = FileUtils.convertToModernFd(in.getFD());
+ modernFd = FileUtils.convertToModernFd(in.getFD());
if (modernFd != null) {
closeQuietly(in);
in = new FileInputStream(modernFd.getFileDescriptor());
@@ -2570,6 +2574,9 @@ public class ExifInterface {
loadAttributes(in);
} finally {
closeQuietly(in);
+ if (modernFd != null) {
+ modernFd.close();
+ }
}
}
diff --git a/media/java/android/media/MediaMetadataRetriever.java b/media/java/android/media/MediaMetadataRetriever.java
index 2943eee5b1da..a15529e99d15 100644
--- a/media/java/android/media/MediaMetadataRetriever.java
+++ b/media/java/android/media/MediaMetadataRetriever.java
@@ -36,6 +36,7 @@ import android.os.IBinder;
import android.os.ParcelFileDescriptor;
import android.os.SystemProperties;
import android.text.TextUtils;
+import android.util.Log;
import java.io.FileDescriptor;
import java.io.FileInputStream;
@@ -52,6 +53,8 @@ import java.util.Map;
* frame and meta data from an input media file.
*/
public class MediaMetadataRetriever implements AutoCloseable {
+ private static final String TAG = "MediaMetadataRetriever";
+
// borrowed from ExoPlayer
private static final String[] STANDARD_GENRES = new String[] {
// These are the official ID3v1 genres.
@@ -301,11 +304,15 @@ public class MediaMetadataRetriever implements AutoCloseable {
*/
public void setDataSource(FileDescriptor fd, long offset, long length)
throws IllegalArgumentException {
- ParcelFileDescriptor modernFd = FileUtils.convertToModernFd(fd);
- if (modernFd == null) {
- _setDataSource(fd, offset, length);
- } else {
- _setDataSource(modernFd.getFileDescriptor(), offset, length);
+
+ try (ParcelFileDescriptor modernFd = FileUtils.convertToModernFd(fd)) {
+ if (modernFd == null) {
+ _setDataSource(fd, offset, length);
+ } else {
+ _setDataSource(modernFd.getFileDescriptor(), offset, length);
+ }
+ } catch (IOException e) {
+ Log.w(TAG, "Ignoring IO error while setting data source", e);
}
}
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 4f761ba0bf6a..26eb2a9dc109 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -1271,11 +1271,14 @@ public class MediaPlayer extends PlayerBase
*/
public void setDataSource(FileDescriptor fd, long offset, long length)
throws IOException, IllegalArgumentException, IllegalStateException {
- ParcelFileDescriptor modernFd = FileUtils.convertToModernFd(fd);
- if (modernFd == null) {
- _setDataSource(fd, offset, length);
- } else {
- _setDataSource(modernFd.getFileDescriptor(), offset, length);
+ try (ParcelFileDescriptor modernFd = FileUtils.convertToModernFd(fd)) {
+ if (modernFd == null) {
+ _setDataSource(fd, offset, length);
+ } else {
+ _setDataSource(modernFd.getFileDescriptor(), offset, length);
+ }
+ } catch (IOException e) {
+ Log.w(TAG, "Ignoring IO error while setting data source", e);
}
}
diff --git a/media/java/android/media/MediaRouter2Manager.java b/media/java/android/media/MediaRouter2Manager.java
index 628f7eef84f9..7f7fb6023b07 100644
--- a/media/java/android/media/MediaRouter2Manager.java
+++ b/media/java/android/media/MediaRouter2Manager.java
@@ -292,8 +292,7 @@ public final class MediaRouter2Manager {
}
synchronized (mRoutesLock) {
for (MediaRoute2Info route : mRoutes.values()) {
- if (sessionInfo.getSelectedRoutes().contains(route.getId())
- || sessionInfo.getTransferableRoutes().contains(route.getId())) {
+ if (sessionInfo.getTransferableRoutes().contains(route.getId())) {
routes.add(route);
continue;
}
diff --git a/media/java/android/media/metrics/PlaybackErrorEvent.java b/media/java/android/media/metrics/PlaybackErrorEvent.java
index 184b35913783..4e3b426c0630 100644
--- a/media/java/android/media/metrics/PlaybackErrorEvent.java
+++ b/media/java/android/media/metrics/PlaybackErrorEvent.java
@@ -317,7 +317,7 @@ public final class PlaybackErrorEvent extends Event implements Parcelable {
*/
public static final class Builder {
private @Nullable Exception mException;
- private int mErrorCode;
+ private int mErrorCode = ERROR_UNKNOWN;
private int mSubErrorCode;
private long mTimeSinceCreatedMillis = -1;
private Bundle mMetricsBundle = new Bundle();
diff --git a/media/java/android/media/metrics/PlaybackMetrics.java b/media/java/android/media/metrics/PlaybackMetrics.java
index bbcc48480e68..e71ee204f564 100644
--- a/media/java/android/media/metrics/PlaybackMetrics.java
+++ b/media/java/android/media/metrics/PlaybackMetrics.java
@@ -502,9 +502,9 @@ public final class PlaybackMetrics implements Parcelable {
private long mMediaDurationMillis = -1;
private int mStreamSource = STREAM_SOURCE_UNKNOWN;
private int mStreamType = STREAM_TYPE_UNKNOWN;
- private int mPlaybackType = PLAYBACK_TYPE_OTHER;
+ private int mPlaybackType = PLAYBACK_TYPE_UNKNOWN;
private int mDrmType = DRM_TYPE_NONE;
- private int mContentType = CONTENT_TYPE_OTHER;
+ private int mContentType = CONTENT_TYPE_UNKNOWN;
private @Nullable String mPlayerName;
private @Nullable String mPlayerVersion;
private @NonNull List<Long> mExperimentIds = new ArrayList<>();
diff --git a/native/android/performance_hint.cpp b/native/android/performance_hint.cpp
index 95a2da9226d9..51a0c99af66e 100644
--- a/native/android/performance_hint.cpp
+++ b/native/android/performance_hint.cpp
@@ -111,8 +111,7 @@ APerformanceHintManager* APerformanceHintManager::create(sp<IHintManager> manage
return nullptr;
}
if (preferredRateNanos <= 0) {
- ALOGE("%s: PerformanceHint invalid preferred rate.", __FUNCTION__);
- return nullptr;
+ preferredRateNanos = -1L;
}
return new APerformanceHintManager(std::move(manager), preferredRateNanos);
}
diff --git a/packages/EasterEgg/AndroidManifest.xml b/packages/EasterEgg/AndroidManifest.xml
index 3d62af020627..9d3ce348f013 100644
--- a/packages/EasterEgg/AndroidManifest.xml
+++ b/packages/EasterEgg/AndroidManifest.xml
@@ -1,26 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.egg"
- android:versionCode="1"
+ android:versionCode="12"
android:versionName="1.0">
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<!-- used for cat notifications -->
<uses-permission android:name="android.permission.SUBSTITUTE_NOTIFICATION_APP_NAME" />
+
<!-- used to save cat images -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+
<!-- controls -->
<uses-permission android:name="android.permission.BIND_CONTROLS" />
<application
android:icon="@drawable/icon"
android:label="@string/app_name">
-
- <activity android:name=".quares.QuaresActivity"
+ <activity
+ android:name=".quares.QuaresActivity"
+ android:exported="true"
android:icon="@drawable/q_icon"
android:label="@string/q_egg_name"
- android:exported="true"
android:theme="@style/QuaresTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
@@ -29,9 +31,9 @@
<activity
android:name=".paint.PaintActivity"
android:configChanges="orientation|keyboardHidden|screenSize|uiMode"
+ android:exported="true"
android:icon="@drawable/p_icon"
android:label="@string/p_egg_name"
- android:exported="true"
android:theme="@style/AppTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
@@ -39,13 +41,15 @@
</activity>
<!-- Android N easter egg bits -->
- <activity android:name=".neko.NekoLand"
- android:theme="@android:style/Theme.Material.NoActionBar"
+ <activity
+ android:name=".neko.NekoLand"
android:exported="true"
- android:label="@string/app_name">
+ android:label="@string/app_name"
+ android:theme="@android:style/Theme.Material.NoActionBar">
<intent-filter>
<action android:name="android.service.quicksettings.action.QS_TILE_PREFERENCES" />
<action android:name="android.intent.action.MAIN" />
+
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
@@ -54,25 +58,24 @@
<service
android:name=".neko.NekoService"
android:enabled="true"
- android:permission="android.permission.BIND_JOB_SERVICE"
- android:exported="true" >
- </service>
-
+ android:exported="true"
+ android:permission="android.permission.BIND_JOB_SERVICE" />
<!-- Used to show over lock screen -->
- <activity android:name=".neko.NekoLockedActivity"
+ <activity
+ android:name=".neko.NekoLockedActivity"
android:excludeFromRecents="true"
android:exported="true"
- android:theme="@android:style/Theme.Material.Light.Dialog.NoActionBar"
- android:showOnLockScreen="true" />
-
+ android:showOnLockScreen="true"
+ android:theme="@android:style/Theme.Material.Light.Dialog.NoActionBar" />
<!-- Used to enable easter egg -->
- <activity android:name=".neko.NekoActivationActivity"
+ <activity
+ android:name=".ComponentActivationActivity"
android:excludeFromRecents="true"
android:exported="true"
- android:theme="@android:style/Theme.NoDisplay"
- >
+ android:theme="@android:style/Theme.NoDisplay">
<intent-filter>
- <action android:name="android.intent.action.MAIN"/>
+ <action android:name="android.intent.action.MAIN" />
+
<category android:name="android.intent.category.DEFAULT" />
<category android:name="com.android.internal.category.PLATLOGO" />
</intent-filter>
@@ -81,37 +84,66 @@
<!-- The quick settings tile, disabled by default -->
<service
android:name=".neko.NekoTile"
- android:permission="android.permission.BIND_QUICK_SETTINGS_TILE"
- android:icon="@drawable/stat_icon"
android:enabled="false"
android:exported="true"
- android:label="@string/default_tile_name">
+ android:icon="@drawable/stat_icon"
+ android:label="@string/default_tile_name"
+ android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">
<intent-filter>
<action android:name="android.service.quicksettings.action.QS_TILE" />
</intent-filter>
</service>
-
- <service android:name=".neko.NekoControlsService"
- android:permission="android.permission.BIND_CONTROLS"
- android:label="@string/r_egg_name"
- android:icon="@drawable/ic_fullcat_icon"
+ <service
+ android:name=".neko.NekoControlsService"
android:enabled="false"
- android:exported="true">
+ android:exported="true"
+ android:icon="@drawable/ic_fullcat_icon"
+ android:label="@string/r_egg_name"
+ android:permission="android.permission.BIND_CONTROLS">
<intent-filter>
<action android:name="android.service.controls.ControlsProviderService" />
</intent-filter>
- </service>
-
- <!-- FileProvider for sending pictures -->
+ </service> <!-- FileProvider for sending pictures -->
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.android.egg.fileprovider"
- android:grantUriPermissions="true"
- android:exported="false">
+ android:exported="false"
+ android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths" />
</provider>
+
+ <!-- Android S easter egg bits -->
+
+ <!-- List of all system theme colors on the device. -->
+ <activity
+ android:name=".widget.PaintChipsActivity"
+ android:theme="@android:style/Theme.Material.Wallpaper.NoTitleBar"
+ android:configChanges="orientation|keyboardHidden|screenSize|uiMode"
+ android:label="@string/s_egg_name"
+ android:enabled="false"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ </intent-filter>
+ </activity>
+
+ <!-- Homescreen widget also showing paint chips (may be affected by the exact position in
+ the workspace) -->
+ <receiver
+ android:name=".widget.PaintChipsWidget"
+ android:label="@string/s_egg_name"
+ android:exported="true"
+ android:enabled="false">
+ <intent-filter>
+ <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
+ </intent-filter>
+
+ <meta-data
+ android:name="android.appwidget.provider"
+ android:resource="@xml/paint_chips_widget_info" />
+ </receiver>
</application>
</manifest>
diff --git a/packages/EasterEgg/build.gradle b/packages/EasterEgg/build.gradle
index 20b469898498..0565369fe81f 100644
--- a/packages/EasterEgg/build.gradle
+++ b/packages/EasterEgg/build.gradle
@@ -7,8 +7,8 @@ buildscript {
}
dependencies {
- classpath 'com.android.tools.build:gradle:4.0.0'
- classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+ classpath 'com.android.tools.build:gradle:7.0.0-alpha08'
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.30"
}
}
@@ -62,6 +62,9 @@ android {
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
+ buildFeatures {
+ viewBinding true
+ }
}
@@ -74,6 +77,7 @@ dependencies {
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.6'
implementation "androidx.recyclerview:recyclerview:${ANDROID_X_VERSION}"
implementation "androidx.dynamicanimation:dynamicanimation:${ANDROID_X_VERSION}"
+ implementation 'com.google.android.material:material:1.3.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
diff --git a/packages/EasterEgg/gradle.properties b/packages/EasterEgg/gradle.properties
index e8e6450e2943..0b5a73677b3b 100644
--- a/packages/EasterEgg/gradle.properties
+++ b/packages/EasterEgg/gradle.properties
@@ -19,5 +19,5 @@ android.enableJetifier=true
kotlin.code.style=official
ANDROID_X_VERSION=1+
-COMPILE_SDK=android-30
+COMPILE_SDK=android-S
BUILD_TOOLS_VERSION=28.0.3
diff --git a/packages/EasterEgg/res/drawable/android_s.xml b/packages/EasterEgg/res/drawable/android_s.xml
new file mode 100644
index 000000000000..9cecab103ac8
--- /dev/null
+++ b/packages/EasterEgg/res/drawable/android_s.xml
@@ -0,0 +1,23 @@
+<vector android:height="108dp" android:viewportHeight="48"
+ android:viewportWidth="48" android:width="108dp" xmlns:android="http://schemas.android.com/apk/res/android">
+ <group>
+ <clip-path android:pathData="M17,14h14v20h-14z"/>
+ <path android:fillColor="#00000000"
+ android:pathData="M18,21C18,21.7956 18.3161,22.5587 18.8787,23.1213C19.4413,23.6839 20.2044,24 21,24H27C27.7956,24 28.5587,24.3161 29.1213,24.8787C29.6839,25.4413 30,26.2044 30,27"
+ android:strokeColor="#ffffff" android:strokeWidth="2"/>
+ <path android:fillColor="#ffffff" android:pathData="M22,21C22.5523,21 23,20.5523 23,20C23,19.4477 22.5523,19 22,19C21.4477,19 21,19.4477 21,20C21,20.5523 21.4477,21 22,21Z"/>
+ <path android:fillColor="#ffffff" android:pathData="M26,21C26.5523,21 27,20.5523 27,20C27,19.4477 26.5523,19 26,19C25.4477,19 25,19.4477 25,20C25,20.5523 25.4477,21 26,21Z"/>
+ <path android:fillColor="#00000000"
+ android:pathData="M19.5,16.5L18,15"
+ android:strokeColor="#ffffff" android:strokeLineCap="round" android:strokeWidth="2"/>
+ <path android:fillColor="#00000000"
+ android:pathData="M28.5,16.5L30,15"
+ android:strokeColor="#ffffff" android:strokeLineCap="round" android:strokeWidth="2"/>
+ <path android:fillColor="#00000000"
+ android:pathData="M29.92,20C29.8637,19.6605 29.7801,19.3261 29.67,19C29.205,17.6561 28.2777,16.5211 27.0536,15.7973C25.8294,15.0735 24.388,14.8081 22.9864,15.0483C21.5847,15.2885 20.314,16.0188 19.4007,17.1088C18.4874,18.1989 17.991,19.5779 18,21"
+ android:strokeColor="#ffffff" android:strokeLineCap="round" android:strokeWidth="2"/>
+ <path android:fillColor="#00000000"
+ android:pathData="M18.08,28C18.1363,28.3395 18.2199,28.6739 18.33,29C18.795,30.3439 19.7223,31.4789 20.9464,32.2027C22.1705,32.9265 23.612,33.1919 25.0136,32.9517C26.4153,32.7115 27.686,31.9812 28.5993,30.8912C29.5126,29.8011 30.009,28.4221 30,27"
+ android:strokeColor="#ffffff" android:strokeLineCap="round" android:strokeWidth="2"/>
+ </group>
+</vector>
diff --git a/packages/EasterEgg/res/drawable/icon.xml b/packages/EasterEgg/res/drawable/icon.xml
index 7f8d4fa8833f..7054962b3503 100644
--- a/packages/EasterEgg/res/drawable/icon.xml
+++ b/packages/EasterEgg/res/drawable/icon.xml
@@ -15,5 +15,5 @@ Copyright (C) 2018 The Android Open Source Project
-->
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/icon_bg"/>
- <foreground android:drawable="@drawable/android_11_dial"/>
+ <foreground android:drawable="@drawable/android_s"/>
</adaptive-icon>
diff --git a/packages/EasterEgg/res/drawable/icon_bg.xml b/packages/EasterEgg/res/drawable/icon_bg.xml
index 31b2a7f9a333..d08e160ea312 100644
--- a/packages/EasterEgg/res/drawable/icon_bg.xml
+++ b/packages/EasterEgg/res/drawable/icon_bg.xml
@@ -14,5 +14,5 @@ Copyright (C) 2018 The Android Open Source Project
limitations under the License.
-->
<color xmlns:android="http://schemas.android.com/apk/res/android"
- android:color="#073042" />
+ android:color="@android:color/system_accent2_500" />
diff --git a/packages/EasterEgg/res/drawable/roundrect.xml b/packages/EasterEgg/res/drawable/roundrect.xml
new file mode 100644
index 000000000000..070adadf3814
--- /dev/null
+++ b/packages/EasterEgg/res/drawable/roundrect.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle">
+ <solid android:color="#FF000000" />
+ <corners
+ android:radius="12dp" />
+</shape> \ No newline at end of file
diff --git a/packages/EasterEgg/res/layout/paint_chip.xml b/packages/EasterEgg/res/layout/paint_chip.xml
new file mode 100644
index 000000000000..d5745b94d163
--- /dev/null
+++ b/packages/EasterEgg/res/layout/paint_chip.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2021 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.
+-->
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/chip"
+ android:layout_width="10dp" android:layout_height="10dp"
+ android:layout_gravity="fill" android:layout_columnWeight="1" android:layout_rowWeight="1"
+ android:text="A1-500"
+ android:backgroundTint="@android:color/system_accent1_500"
+ android:background="@drawable/roundrect"
+ android:gravity="center"
+ android:textColor="?android:attr/textColorPrimary"
+ android:fontFamily="?android:attr/textAppearanceLarge"
+ android:layout_margin="2dp"
+ android:singleLine="true"
+ /> \ No newline at end of file
diff --git a/packages/EasterEgg/res/layout/paint_chips_grid.xml b/packages/EasterEgg/res/layout/paint_chips_grid.xml
new file mode 100644
index 000000000000..79f701322149
--- /dev/null
+++ b/packages/EasterEgg/res/layout/paint_chips_grid.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright (C) 2021 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.
+-->
+<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/paint_grid"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:padding="0dp"
+ android:orientation="vertical"
+ android:alignmentMode="alignBounds"
+ android:rowOrderPreserved="false"
+ >
+</GridLayout>
diff --git a/packages/EasterEgg/res/layout/paint_chips_widget_preview.xml b/packages/EasterEgg/res/layout/paint_chips_widget_preview.xml
new file mode 100644
index 000000000000..9893ec054992
--- /dev/null
+++ b/packages/EasterEgg/res/layout/paint_chips_widget_preview.xml
@@ -0,0 +1,79 @@
+<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="300dp"
+ android:layout_height="50dp"
+ android:alignmentMode="alignBounds"
+ android:columnCount="5"
+ android:padding="0dp"
+ android:rowCount="1"
+ android:rowOrderPreserved="false">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_rowWeight="1"
+ android:layout_columnWeight="1"
+ android:layout_gravity="fill"
+ android:layout_margin="2dp"
+ android:background="@drawable/roundrect"
+ android:backgroundTint="@android:color/system_neutral1_500"
+ android:fontFamily="?android:attr/textAppearanceLarge"
+ android:gravity="center"
+ android:text="N1-500"
+ android:textColor="?android:attr/textColorPrimary" />
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_rowWeight="1"
+ android:layout_columnWeight="1"
+ android:layout_gravity="fill"
+ android:layout_margin="2dp"
+ android:background="@drawable/roundrect"
+ android:backgroundTint="@android:color/system_neutral2_500"
+ android:fontFamily="?android:attr/textAppearanceLarge"
+ android:gravity="center"
+ android:text="N2-500"
+ android:textColor="?android:attr/textColorPrimary" />
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_rowWeight="1"
+ android:layout_columnWeight="1"
+ android:layout_gravity="fill"
+ android:layout_margin="2dp"
+ android:background="@drawable/roundrect"
+ android:backgroundTint="@android:color/system_accent1_500"
+ android:fontFamily="?android:attr/textAppearanceLarge"
+ android:gravity="center"
+ android:text="A1-500"
+ android:textColor="?android:attr/textColorPrimary" />
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_rowWeight="1"
+ android:layout_columnWeight="1"
+ android:layout_gravity="fill"
+ android:layout_margin="2dp"
+ android:background="@drawable/roundrect"
+ android:backgroundTint="@android:color/system_accent2_500"
+ android:fontFamily="?android:attr/textAppearanceLarge"
+ android:gravity="center"
+ android:text="A2-500"
+ android:textColor="?android:attr/textColorPrimary" />
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_rowWeight="1"
+ android:layout_columnWeight="1"
+ android:layout_gravity="fill"
+ android:layout_margin="2dp"
+ android:background="@drawable/roundrect"
+ android:backgroundTint="@android:color/system_accent3_500"
+ android:fontFamily="?android:attr/textAppearanceLarge"
+ android:gravity="center"
+ android:text="A3-500"
+ android:textColor="?android:attr/textColorPrimary" />
+</GridLayout>
diff --git a/packages/EasterEgg/res/values-night/themes.xml b/packages/EasterEgg/res/values-night/themes.xml
new file mode 100644
index 000000000000..83ec7a5557c3
--- /dev/null
+++ b/packages/EasterEgg/res/values-night/themes.xml
@@ -0,0 +1,7 @@
+<resources>
+
+ <style name="ThemeOverlay.EasterEgg.AppWidgetContainer" parent="">
+ <item name="appWidgetBackgroundColor">@color/light_blue_900</item>
+ <item name="appWidgetTextColor">@color/light_blue_200</item>
+ </style>
+</resources> \ No newline at end of file
diff --git a/packages/EasterEgg/res/values/attrs.xml b/packages/EasterEgg/res/values/attrs.xml
new file mode 100644
index 000000000000..97531a25692c
--- /dev/null
+++ b/packages/EasterEgg/res/values/attrs.xml
@@ -0,0 +1,6 @@
+<resources>
+ <declare-styleable name="AppWidgetAttrs">
+ <attr name="appWidgetBackgroundColor" format="color" />
+ <attr name="appWidgetTextColor" format="color" />
+ </declare-styleable>
+</resources> \ No newline at end of file
diff --git a/packages/EasterEgg/res/values/colors.xml b/packages/EasterEgg/res/values/colors.xml
index 1a5388b738dd..d79e83b8af0c 100644
--- a/packages/EasterEgg/res/values/colors.xml
+++ b/packages/EasterEgg/res/values/colors.xml
@@ -1,5 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="utf-8"?><!--
Copyright (C) 2018 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,4 +17,8 @@
<color name="toolbar_bg_color">#FFDDDDDD</color>
<color name="paper_color">#FFFFFFFF</color>
<color name="paint_color">#FF000000</color>
+ <color name="light_blue_50">#FFE1F5FE</color>
+ <color name="light_blue_200">#FF81D4FA</color>
+ <color name="light_blue_600">#FF039BE5</color>
+ <color name="light_blue_900">#FF01579B</color>
</resources> \ No newline at end of file
diff --git a/packages/EasterEgg/res/values/dimens.xml b/packages/EasterEgg/res/values/dimens.xml
index e9dcebd27f7b..0de2c3cb7b43 100644
--- a/packages/EasterEgg/res/values/dimens.xml
+++ b/packages/EasterEgg/res/values/dimens.xml
@@ -1,5 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="utf-8"?><!--
Copyright (C) 2016 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,4 +15,10 @@ Copyright (C) 2016 The Android Open Source Project
-->
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<dimen name="neko_display_size">64dp</dimen>
+
+ <!--
+Refer to App Widget Documentation for margin information
+http://developer.android.com/guide/topics/appwidgets/index.html#CreatingLayout
+ -->
+ <dimen name="widget_margin">0dp</dimen>
</resources>
diff --git a/packages/EasterEgg/res/values/strings.xml b/packages/EasterEgg/res/values/strings.xml
index 25f94215d433..743947ad281e 100644
--- a/packages/EasterEgg/res/values/strings.xml
+++ b/packages/EasterEgg/res/values/strings.xml
@@ -14,7 +14,7 @@ Copyright (C) 2018 The Android Open Source Project
limitations under the License.
-->
<resources xmlns:android="http://schemas.android.com/apk/res/android">
- <string name="app_name" translatable="false">Android R Easter Egg</string>
+ <string name="app_name" translatable="false">Android S Easter Egg</string>
<!-- name of the Q easter egg, a nonogram-style icon puzzle -->
<string name="q_egg_name" translatable="false">Icon Quiz</string>
@@ -23,4 +23,8 @@ Copyright (C) 2018 The Android Open Source Project
<string name="p_egg_name" translatable="false">PAINT.APK</string>
<string name="r_egg_name" translatable="false">Cat Controls</string>
+
+ <!-- name of the S easter egg, a widget that displays the system color palette
+ in a manner similar to a set of paint samples from a hardware store -->
+ <string name="s_egg_name" translatable="false">Paint Chips</string>
</resources>
diff --git a/packages/EasterEgg/res/values/themes.xml b/packages/EasterEgg/res/values/themes.xml
new file mode 100644
index 000000000000..5b163043a356
--- /dev/null
+++ b/packages/EasterEgg/res/values/themes.xml
@@ -0,0 +1,7 @@
+<resources>
+
+ <style name="ThemeOverlay.EasterEgg.AppWidgetContainer" parent="">
+ <item name="appWidgetBackgroundColor">@color/light_blue_600</item>
+ <item name="appWidgetTextColor">@color/light_blue_50</item>
+ </style>
+</resources> \ No newline at end of file
diff --git a/packages/EasterEgg/res/xml/paint_chips_widget_info.xml b/packages/EasterEgg/res/xml/paint_chips_widget_info.xml
new file mode 100644
index 000000000000..7780a757f01c
--- /dev/null
+++ b/packages/EasterEgg/res/xml/paint_chips_widget_info.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2021 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.
+-->
+<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
+ android:initialLayout="@layout/paint_chip"
+ android:previewLayout="@layout/paint_chips_widget_preview"
+ android:minWidth="50dp"
+ android:minHeight="50dp"
+ android:resizeMode="horizontal|vertical"
+ android:updatePeriodMillis="86400000"
+ android:widgetCategory="home_screen"></appwidget-provider> \ No newline at end of file
diff --git a/packages/EasterEgg/src/com/android/egg/ComponentActivationActivity.java b/packages/EasterEgg/src/com/android/egg/ComponentActivationActivity.java
new file mode 100644
index 000000000000..5820b5a75894
--- /dev/null
+++ b/packages/EasterEgg/src/com/android/egg/ComponentActivationActivity.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2021 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.egg;
+
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.pm.PackageManager;
+import android.provider.Settings;
+import android.util.Log;
+import android.widget.Toast;
+
+import com.android.egg.neko.NekoControlsService;
+import com.android.egg.widget.PaintChipsActivity;
+import com.android.egg.widget.PaintChipsWidget;
+
+/**
+ * Launched from the PlatLogoActivity. Enables everything else in this easter egg.
+ */
+public class ComponentActivationActivity extends Activity {
+ private static final String TAG = "EasterEgg";
+
+ private static final String S_EGG_UNLOCK_SETTING = "egg_mode_s";
+
+ private void toastUp(String s) {
+ Toast toast = Toast.makeText(this, s, Toast.LENGTH_SHORT);
+ toast.show();
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+
+ final PackageManager pm = getPackageManager();
+ final ComponentName[] cns = new ComponentName[] {
+ new ComponentName(this, NekoControlsService.class),
+ new ComponentName(this, PaintChipsActivity.class),
+ new ComponentName(this, PaintChipsWidget.class)
+ };
+ final long unlockValue = Settings.System.getLong(getContentResolver(),
+ S_EGG_UNLOCK_SETTING, 0);
+ for (ComponentName cn : cns) {
+ final boolean componentEnabled = pm.getComponentEnabledSetting(cn)
+ == PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
+ if (unlockValue == 0) {
+ if (componentEnabled) {
+ Log.v(TAG, "Disabling component: " + cn);
+ pm.setComponentEnabledSetting(cn,
+ PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
+ PackageManager.DONT_KILL_APP);
+ //toastUp("\uD83D\uDEAB");
+ } else {
+ Log.v(TAG, "Already disabled: " + cn);
+ }
+ } else {
+ if (!componentEnabled) {
+ Log.v(TAG, "Enabling component: " + cn);
+ pm.setComponentEnabledSetting(cn,
+ PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
+ PackageManager.DONT_KILL_APP);
+ //toastUp("\uD83D\uDC31");
+ } else {
+ Log.v(TAG, "Already enabled: " + cn);
+ }
+ }
+ }
+
+ finish();
+ }
+}
diff --git a/packages/EasterEgg/src/com/android/egg/neko/NekoActivationActivity.java b/packages/EasterEgg/src/com/android/egg/neko/NekoActivationActivity.java
deleted file mode 100644
index df461c6878f0..000000000000
--- a/packages/EasterEgg/src/com/android/egg/neko/NekoActivationActivity.java
+++ /dev/null
@@ -1,66 +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.
- */
-
-package com.android.egg.neko;
-
-import android.app.Activity;
-import android.content.ComponentName;
-import android.content.pm.PackageManager;
-import android.provider.Settings;
-import android.util.Log;
-import android.widget.Toast;
-
-import com.android.internal.logging.MetricsLogger;
-
-public class NekoActivationActivity extends Activity {
- private static final String R_EGG_UNLOCK_SETTING = "egg_mode_r";
-
- private void toastUp(String s) {
- Toast toast = Toast.makeText(this, s, Toast.LENGTH_SHORT);
- toast.show();
- }
-
- @Override
- public void onStart() {
- super.onStart();
-
- final PackageManager pm = getPackageManager();
- final ComponentName cn = new ComponentName(this, NekoControlsService.class);
- final boolean componentEnabled = pm.getComponentEnabledSetting(cn)
- == PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
- if (Settings.System.getLong(getContentResolver(),
- R_EGG_UNLOCK_SETTING, 0) == 0) {
- if (componentEnabled) {
- Log.v("Neko", "Disabling controls.");
- pm.setComponentEnabledSetting(cn, PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
- PackageManager.DONT_KILL_APP);
- MetricsLogger.histogram(this, "egg_neko_enable", 0);
- toastUp("\uD83D\uDEAB");
- } else {
- Log.v("Neko", "Controls already disabled.");
- }
- } else {
- if (!componentEnabled) {
- Log.v("Neko", "Enabling controls.");
- pm.setComponentEnabledSetting(cn, PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
- PackageManager.DONT_KILL_APP);
- MetricsLogger.histogram(this, "egg_neko_enable", 1);
- toastUp("\uD83D\uDC31");
- } else {
- Log.v("Neko", "Controls already enabled.");
- }
- }
- finish();
- }
-}
diff --git a/packages/EasterEgg/src/com/android/egg/widget/PaintChipsActivity.kt b/packages/EasterEgg/src/com/android/egg/widget/PaintChipsActivity.kt
new file mode 100644
index 000000000000..8799aecf5516
--- /dev/null
+++ b/packages/EasterEgg/src/com/android/egg/widget/PaintChipsActivity.kt
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2021 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.egg.widget
+
+import android.app.Activity
+import android.content.res.Configuration
+import android.os.Bundle
+import android.widget.FrameLayout
+
+/**
+ * Activity to show off the current dynamic system theme in all its glory.
+ */
+class PaintChipsActivity : Activity() {
+ private lateinit var layout: FrameLayout
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ window.navigationBarColor = 0
+ window.statusBarColor = 0
+ actionBar?.hide()
+
+ layout = FrameLayout(this)
+ layout.setPadding(dp2px(8f), dp2px(8f), dp2px(8f), dp2px(8f))
+ rebuildGrid()
+
+ setContentView(layout)
+ }
+
+ fun dp2px(dp: Float): Int {
+ return (dp * resources.displayMetrics.density).toInt()
+ }
+
+ override fun onResume() {
+ super.onResume()
+
+ rebuildGrid()
+ }
+
+ override fun onConfigurationChanged(newConfig: Configuration) {
+ super.onConfigurationChanged(newConfig)
+
+ rebuildGrid()
+ }
+
+ private fun rebuildGrid() {
+ layout.removeAllViews()
+ val grid = buildFullWidget(this, ClickBehavior.SHARE)
+ val asView = grid.apply(this, layout)
+ layout.addView(asView, FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,
+ FrameLayout.LayoutParams.MATCH_PARENT))
+ }
+}
diff --git a/packages/EasterEgg/src/com/android/egg/widget/PaintChipsWidget.kt b/packages/EasterEgg/src/com/android/egg/widget/PaintChipsWidget.kt
new file mode 100644
index 000000000000..c15cabbb0eb6
--- /dev/null
+++ b/packages/EasterEgg/src/com/android/egg/widget/PaintChipsWidget.kt
@@ -0,0 +1,293 @@
+/*
+ * Copyright (C) 2021 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.egg.widget
+
+import android.app.PendingIntent
+import android.appwidget.AppWidgetManager
+import android.appwidget.AppWidgetProvider
+import android.content.ComponentName
+import android.content.Context
+import android.content.Intent
+import android.os.Bundle
+import android.util.Log
+import android.util.SizeF
+import android.widget.RemoteViews
+
+import com.android.egg.R
+
+/**
+ * A homescreen widget to explore the current dynamic system theme.
+ */
+class PaintChipsWidget : AppWidgetProvider() {
+ override fun onUpdate(
+ context: Context,
+ appWidgetManager: AppWidgetManager,
+ appWidgetIds: IntArray
+ ) {
+ for (appWidgetId in appWidgetIds) {
+ updateAppWidget(context, appWidgetManager, appWidgetId)
+ }
+ }
+
+ override fun onAppWidgetOptionsChanged(
+ context: Context,
+ appWidgetManager: AppWidgetManager,
+ appWidgetId: Int,
+ newOptions: Bundle?
+ ) {
+ // Log.v(TAG, "onAppWidgetOptionsChanged: id=${appWidgetId}")
+ updateAppWidget(context, appWidgetManager, appWidgetId)
+ super.onAppWidgetOptionsChanged(context, appWidgetManager, appWidgetId, newOptions)
+ }
+}
+
+const val TAG = "PaintChips"
+
+val SHADE_NUMBERS = intArrayOf(0, 10, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000)
+
+val COLORS_NEUTRAL1 = intArrayOf(
+ android.R.color.system_neutral1_0,
+ android.R.color.system_neutral1_10,
+ android.R.color.system_neutral1_50,
+ android.R.color.system_neutral1_100,
+ android.R.color.system_neutral1_200,
+ android.R.color.system_neutral1_300,
+ android.R.color.system_neutral1_400,
+ android.R.color.system_neutral1_500,
+ android.R.color.system_neutral1_600,
+ android.R.color.system_neutral1_700,
+ android.R.color.system_neutral1_800,
+ android.R.color.system_neutral1_900,
+ android.R.color.system_neutral1_1000
+)
+
+val COLORS_NEUTRAL2 = intArrayOf(
+ android.R.color.system_neutral2_0,
+ android.R.color.system_neutral2_10,
+ android.R.color.system_neutral2_50,
+ android.R.color.system_neutral2_100,
+ android.R.color.system_neutral2_200,
+ android.R.color.system_neutral2_300,
+ android.R.color.system_neutral2_400,
+ android.R.color.system_neutral2_500,
+ android.R.color.system_neutral2_600,
+ android.R.color.system_neutral2_700,
+ android.R.color.system_neutral2_800,
+ android.R.color.system_neutral2_900,
+ android.R.color.system_neutral2_1000
+)
+
+var COLORS_ACCENT1 = intArrayOf(
+ android.R.color.system_accent1_0,
+ android.R.color.system_accent1_10,
+ android.R.color.system_accent1_50,
+ android.R.color.system_accent1_100,
+ android.R.color.system_accent1_200,
+ android.R.color.system_accent1_300,
+ android.R.color.system_accent1_400,
+ android.R.color.system_accent1_500,
+ android.R.color.system_accent1_600,
+ android.R.color.system_accent1_700,
+ android.R.color.system_accent1_800,
+ android.R.color.system_accent1_900,
+ android.R.color.system_accent1_1000
+)
+
+var COLORS_ACCENT2 = intArrayOf(
+ android.R.color.system_accent2_0,
+ android.R.color.system_accent2_10,
+ android.R.color.system_accent2_50,
+ android.R.color.system_accent2_100,
+ android.R.color.system_accent2_200,
+ android.R.color.system_accent2_300,
+ android.R.color.system_accent2_400,
+ android.R.color.system_accent2_500,
+ android.R.color.system_accent2_600,
+ android.R.color.system_accent2_700,
+ android.R.color.system_accent2_800,
+ android.R.color.system_accent2_900,
+ android.R.color.system_accent2_1000
+)
+
+var COLORS_ACCENT3 = intArrayOf(
+ android.R.color.system_accent3_0,
+ android.R.color.system_accent3_10,
+ android.R.color.system_accent3_50,
+ android.R.color.system_accent3_100,
+ android.R.color.system_accent3_200,
+ android.R.color.system_accent3_300,
+ android.R.color.system_accent3_400,
+ android.R.color.system_accent3_500,
+ android.R.color.system_accent3_600,
+ android.R.color.system_accent3_700,
+ android.R.color.system_accent3_800,
+ android.R.color.system_accent3_900,
+ android.R.color.system_accent3_1000
+)
+
+var COLOR_NAMES = arrayOf(
+ "N1", "N2", "A1", "A2", "A3"
+)
+
+var COLORS = arrayOf(
+ COLORS_NEUTRAL1,
+ COLORS_NEUTRAL2,
+ COLORS_ACCENT1,
+ COLORS_ACCENT2,
+ COLORS_ACCENT3
+)
+
+internal fun updateAppWidget(
+ context: Context,
+ appWidgetManager: AppWidgetManager,
+ appWidgetId: Int
+) {
+ // val opts = appWidgetManager.getAppWidgetOptions(appWidgetId)
+ // Log.v(TAG, "requested sizes=${opts[OPTION_APPWIDGET_SIZES]}")
+
+ val allSizes = mapOf(
+ SizeF(50f, 50f)
+ to buildWidget(context, 1, 1, ClickBehavior.LAUNCH),
+ SizeF(100f, 50f)
+ to buildWidget(context, 1, 2, ClickBehavior.LAUNCH),
+ SizeF(150f, 50f)
+ to buildWidget(context, 1, 3, ClickBehavior.LAUNCH),
+ SizeF(200f, 50f)
+ to buildWidget(context, 1, 4, ClickBehavior.LAUNCH),
+ SizeF(250f, 50f)
+ to buildWidget(context, 1, 5, ClickBehavior.LAUNCH),
+
+ SizeF(50f, 120f)
+ to buildWidget(context, 3, 1, ClickBehavior.LAUNCH),
+ SizeF(100f, 120f)
+ to buildWidget(context, 3, 2, ClickBehavior.LAUNCH),
+ SizeF(150f, 120f)
+ to buildWidget(context, 3, 3, ClickBehavior.LAUNCH),
+ SizeF(200f, 120f)
+ to buildWidget(context, 3, 4, ClickBehavior.LAUNCH),
+ SizeF(250f, 120f)
+ to buildWidget(context, 3, 5, ClickBehavior.LAUNCH),
+
+ SizeF(50f, 250f)
+ to buildWidget(context, 5, 1, ClickBehavior.LAUNCH),
+ SizeF(100f, 250f)
+ to buildWidget(context, 5, 2, ClickBehavior.LAUNCH),
+ SizeF(150f, 250f)
+ to buildWidget(context, 5, 3, ClickBehavior.LAUNCH),
+ SizeF(200f, 250f)
+ to buildWidget(context, 5, 4, ClickBehavior.LAUNCH),
+ SizeF(250f, 250f)
+ to buildWidget(context, 5, 5, ClickBehavior.LAUNCH),
+
+ SizeF(300f, 300f)
+ to buildWidget(context, SHADE_NUMBERS.size, COLORS.size, ClickBehavior.LAUNCH)
+ )
+
+ // Instruct the widget manager to update the widget
+ appWidgetManager.updateAppWidget(appWidgetId, RemoteViews(allSizes))
+}
+
+fun buildFullWidget(context: Context, clickable: ClickBehavior): RemoteViews {
+ return buildWidget(context, SHADE_NUMBERS.size, COLORS.size, clickable)
+}
+
+fun buildWidget(context: Context, numShades: Int, numColors: Int, clickable: ClickBehavior):
+ RemoteViews {
+ val grid = RemoteViews(context.packageName, R.layout.paint_chips_grid)
+
+ // shouldn't be necessary but sometimes the RV instructions get played twice in launcher.
+ grid.removeAllViews(R.id.paint_grid)
+
+ grid.setInt(R.id.paint_grid, "setRowCount", numShades)
+ grid.setInt(R.id.paint_grid, "setColumnCount", numColors)
+
+ Log.v(TAG, "building widget: shade rows=$numShades, color columns=$numColors")
+
+ COLORS.forEachIndexed colorLoop@{ i, colorlist ->
+ when (colorlist) {
+ COLORS_NEUTRAL1 -> if (numColors < 2) return@colorLoop
+ COLORS_NEUTRAL2 -> if (numColors < 4) return@colorLoop
+ COLORS_ACCENT2 -> if (numColors < 3) return@colorLoop
+ COLORS_ACCENT3 -> if (numColors < 5) return@colorLoop
+ else -> {} // always do ACCENT1
+ }
+ colorlist.forEachIndexed shadeLoop@{ j, resId ->
+ when (SHADE_NUMBERS[j]) {
+ 500 -> {}
+ 300, 700 -> if (numShades < 3) return@shadeLoop
+ 100, 900 -> if (numShades < 5) return@shadeLoop
+ else -> if (numShades < SHADE_NUMBERS.size) return@shadeLoop
+ }
+ val cell = RemoteViews(context.packageName, R.layout.paint_chip)
+ cell.setTextViewText(R.id.chip, "${COLOR_NAMES[i]}-${SHADE_NUMBERS[j]}")
+ val textColor = if (SHADE_NUMBERS[j] > 500)
+ colorlist[0]
+ else colorlist[colorlist.size - 1]
+ cell.setTextColor(R.id.chip, context.getColor(textColor))
+ cell.setColorStateList(R.id.chip, "setBackgroundTintList", resId)
+ val text = """
+ ${COLOR_NAMES[i]}-${SHADE_NUMBERS[j]} (@${
+ context.resources.getResourceName(resId) })
+ currently: #${ String.format("%06x", context.getColor(resId) and 0xFFFFFF) }
+ """.trimIndent()
+ when (clickable) {
+ ClickBehavior.SHARE -> cell.setOnClickPendingIntent(
+ R.id.chip,
+ makeTextSharePendingIntent(context, text)
+ )
+ ClickBehavior.LAUNCH -> cell.setOnClickPendingIntent(
+ R.id.chip,
+ makeActivityLaunchPendingIntent(context)
+ )
+ ClickBehavior.NONE -> { }
+ }
+ grid.addView(R.id.paint_grid, cell)
+ }
+ }
+
+ return grid
+}
+
+enum class ClickBehavior {
+ NONE,
+ SHARE,
+ LAUNCH
+}
+
+fun makeTextSharePendingIntent(context: Context, text: String): PendingIntent {
+ val shareIntent: Intent = Intent().apply {
+ action = Intent.ACTION_SEND
+ putExtra(Intent.EXTRA_TEXT, text)
+ type = "text/plain"
+ }
+
+ val chooserIntent = Intent.createChooser(shareIntent, null).apply {
+ identifier = text // incredible quality-of-life improvement, thanks framework team
+ }
+
+ return PendingIntent.getActivity(context, 0, chooserIntent,
+ PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT)
+}
+
+fun makeActivityLaunchPendingIntent(context: Context): PendingIntent {
+ return PendingIntent.getActivity(context, 0,
+ Intent().apply {
+ component = ComponentName(context, PaintChipsActivity::class.java)
+ action = Intent.ACTION_MAIN
+ },
+ PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT)
+}
diff --git a/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/IllustrationPreference.java b/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/IllustrationPreference.java
index f04b0e338959..266fc78b2b6a 100644
--- a/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/IllustrationPreference.java
+++ b/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/IllustrationPreference.java
@@ -267,26 +267,22 @@ public class IllustrationPreference extends Preference {
private static void startLottieAnimationWith(LottieAnimationView illustrationView,
Uri imageUri) {
- try {
- final InputStream inputStream =
- getInputStreamFromUri(illustrationView.getContext(), imageUri);
- illustrationView.setAnimation(inputStream, /* cacheKey= */ null);
- illustrationView.setRepeatCount(LottieDrawable.INFINITE);
- illustrationView.playAnimation();
- } catch (IllegalStateException e) {
- Log.w(TAG, "Invalid illustration image uri: " + imageUri, e);
- }
+ final InputStream inputStream =
+ getInputStreamFromUri(illustrationView.getContext(), imageUri);
+ illustrationView.setFailureListener(
+ result -> Log.w(TAG, "Invalid illustration image uri: " + imageUri, result));
+ illustrationView.setAnimation(inputStream, /* cacheKey= */ null);
+ illustrationView.setRepeatCount(LottieDrawable.INFINITE);
+ illustrationView.playAnimation();
}
private static void startLottieAnimationWith(LottieAnimationView illustrationView,
@RawRes int rawRes) {
- try {
- illustrationView.setAnimation(rawRes);
- illustrationView.setRepeatCount(LottieDrawable.INFINITE);
- illustrationView.playAnimation();
- } catch (IllegalStateException e) {
- Log.w(TAG, "Invalid illustration resource id: " + rawRes, e);
- }
+ illustrationView.setFailureListener(
+ result -> Log.w(TAG, "Invalid illustration resource id: " + rawRes, result));
+ illustrationView.setAnimation(rawRes);
+ illustrationView.setRepeatCount(LottieDrawable.INFINITE);
+ illustrationView.playAnimation();
}
private static void resetAnimations(LottieAnimationView illustrationView) {
diff --git a/packages/SettingsLib/lint-baseline.xml b/packages/SettingsLib/lint-baseline.xml
index f6d6ca62e78c..d6ea73d1ef3d 100644
--- a/packages/SettingsLib/lint-baseline.xml
+++ b/packages/SettingsLib/lint-baseline.xml
@@ -892,4 +892,26 @@
column="59"/>
</issue>
+ <issue
+ id="NewApi"
+ message="Call requires API level S (current min is 29): `android.os.UserManager#isUserForeground`"
+ errorLine1=" .getSystemService(UserManager.class).isUserForeground();"
+ errorLine2=" ~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/enterprise/ManagedDeviceActionDisabledByAdminController.java"
+ line="120"
+ column="54"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 29): `android.os.UserManager#isUserForeground`"
+ errorLine1=" .getSystemService(UserManager.class).isUserForeground();"
+ errorLine2=" ~~~~~~~~~~~~~~~~">
+ <location
+ file="frameworks/base/packages/SettingsLib/src/com/android/settingslib/enterprise/ManagedDeviceActionDisabledByAdminController.java"
+ line="120"
+ column="54"/>
+ </issue>
+
</issues>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index 710ca3229e00..08ca17fd802d 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -172,7 +172,7 @@
<string name="tts_engine_security_warning" msgid="3372432853837988146">"Гэты модуль сінтэзу гаворкі можа збіраць увесь тэкст, які будзе прамоўлены, у тым ліку асабістыя дадзеныя, напрыклад паролі і нумары крэдытных карт. Ён адносіцца да модуля <xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g>. Уключыць гэты модуль сінтэзу гаворкі?"</string>
<string name="tts_engine_network_required" msgid="8722087649733906851">"Гэта мова патрабуе актыўнага падключэння да сеткі, каб выконваць функцыю прамаўлення тэксту."</string>
<string name="tts_default_sample_string" msgid="6388016028292967973">"Гэта прыклад сінтэзу гаворкі"</string>
- <string name="tts_status_title" msgid="8190784181389278640">"Статус мовы па змаўчанні"</string>
+ <string name="tts_status_title" msgid="8190784181389278640">"Статус стандартнай мовы"</string>
<string name="tts_status_ok" msgid="8583076006537547379">"<xliff:g id="LOCALE">%1$s</xliff:g> цалкам падтрымліваецца"</string>
<string name="tts_status_requires_network" msgid="8327617638884678896">"Для <xliff:g id="LOCALE">%1$s</xliff:g> патрабуецца падлучэнне да сеткі"</string>
<string name="tts_status_not_supported" msgid="2702997696245523743">"<xliff:g id="LOCALE">%1$s</xliff:g> не падтрымліваецца"</string>
@@ -388,7 +388,7 @@
<string name="local_backup_password_toast_validation_failure" msgid="714669442363647122">"Збой пры ўсталёўцы паролю для рэзервовага капіявання"</string>
<string name="loading_injected_setting_summary" msgid="8394446285689070348">"Ідзе загрузка…"</string>
<string-array name="color_mode_names">
- <item msgid="3836559907767149216">"Сочны (па змаўчанні)"</item>
+ <item msgid="3836559907767149216">"Насычаны (стандартна)"</item>
<item msgid="9112200311983078311">"Натуральныя"</item>
<item msgid="6564241960833766170">"Стандартны"</item>
</string-array>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index 8052e2aa2984..ac078fdcb585 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -85,7 +85,7 @@
<string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"મીડિયા ઑડિયો"</string>
<string name="bluetooth_profile_headset" msgid="5395952236133499331">"ફોન કૉલ"</string>
<string name="bluetooth_profile_opp" msgid="6692618568149493430">"ફાઇલ સ્થાનાંતરણ"</string>
- <string name="bluetooth_profile_hid" msgid="2969922922664315866">"ઇનપુટ ઉપકરણ"</string>
+ <string name="bluetooth_profile_hid" msgid="2969922922664315866">"ઇનપુટ ડિવાઇસ"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"ઇન્ટરનેટ ઍક્સેસ"</string>
<string name="bluetooth_profile_pbap" msgid="7064307749579335765">"સંપર્ક શેરિંગ"</string>
<string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"સંપર્ક શેરિંગ માટે ઉપયોગ કરો"</string>
@@ -102,7 +102,7 @@
<string name="bluetooth_map_profile_summary_connected" msgid="4141725591784669181">"નકશા સાથે કનેક્ટ થયું"</string>
<string name="bluetooth_sap_profile_summary_connected" msgid="1280297388033001037">"SAP થી કનેક્ટ કરેલ"</string>
<string name="bluetooth_opp_profile_summary_not_connected" msgid="3959741824627764954">"ફાઇલ સ્થાનાંતરણ સેવાથી કનેક્ટ થયેલ નથી"</string>
- <string name="bluetooth_hid_profile_summary_connected" msgid="3923653977051684833">"ઇનપુટ ઉપકરણ સાથે કનેક્ટ થયાં"</string>
+ <string name="bluetooth_hid_profile_summary_connected" msgid="3923653977051684833">"ઇનપુટ ડિવાઇસ સાથે કનેક્ટ થયાં"</string>
<string name="bluetooth_pan_user_profile_summary_connected" msgid="380469653827505727">"ઇન્ટરનેટ ઍક્સેસ માટે ઉપકરણથી કનેક્ટેડ છીએ"</string>
<string name="bluetooth_pan_nap_profile_summary_connected" msgid="3744773111299503493">"ઉપકરણ સાથે સ્થાનિક ઇન્ટરનેટ કનેક્શન શેર કરી રહ્યાં છીએ"</string>
<string name="bluetooth_pan_profile_summary_use_for" msgid="7422039765025340313">"ઇન્ટરનેટ ઍક્સેસ માટે ઉપયોગ કરો"</string>
@@ -155,7 +155,7 @@
<string name="running_process_item_user_label" msgid="3988506293099805796">"વપરાશકર્તા: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
<string name="launch_defaults_some" msgid="3631650616557252926">"કેટલાંક ડિફોલ્ટ્સ સેટ કરેલ છે"</string>
<string name="launch_defaults_none" msgid="8049374306261262709">"કોઈ ડિફૉલ્ટ સેટ કરેલા નથી"</string>
- <string name="tts_settings" msgid="8130616705989351312">"ટેક્સ્ટ-ટુ-સ્પીચ સેટિંગ્સ"</string>
+ <string name="tts_settings" msgid="8130616705989351312">"ટેક્સ્ટ ટૂ સ્પીચ સેટિંગ"</string>
<string name="tts_settings_title" msgid="7602210956640483039">"ટેક્સ્ટ ટુ સ્પીચ આઉટપુટ"</string>
<string name="tts_default_rate_title" msgid="3964187817364304022">"વાણી દર"</string>
<string name="tts_default_rate_summary" msgid="3781937042151716987">"ટેક્સ્ટ બોલાયેલ છે તે ઝડપ"</string>
@@ -177,8 +177,8 @@
<string name="tts_status_requires_network" msgid="8327617638884678896">"<xliff:g id="LOCALE">%1$s</xliff:g> નેટવર્ક કનેક્શનની આવશ્યકતા છે"</string>
<string name="tts_status_not_supported" msgid="2702997696245523743">"<xliff:g id="LOCALE">%1$s</xliff:g> સમર્થિત નથી"</string>
<string name="tts_status_checking" msgid="8026559918948285013">"તપાસી રહ્યું છે..."</string>
- <string name="tts_engine_settings_title" msgid="7849477533103566291">"<xliff:g id="TTS_ENGINE_NAME">%s</xliff:g> માટેની સેટિંગ્સ"</string>
- <string name="tts_engine_settings_button" msgid="477155276199968948">"એન્જિન સેટિંગ્સ લોંચ કરો"</string>
+ <string name="tts_engine_settings_title" msgid="7849477533103566291">"<xliff:g id="TTS_ENGINE_NAME">%s</xliff:g> માટેના સેટિંગ"</string>
+ <string name="tts_engine_settings_button" msgid="477155276199968948">"એન્જિન સેટિંગ લૉન્ચ કરો"</string>
<string name="tts_engine_preference_section_title" msgid="3861562305498624904">"મનપસંદ એન્જિન"</string>
<string name="tts_general_section_title" msgid="8919671529502364567">"સામાન્ય"</string>
<string name="tts_reset_speech_pitch_title" msgid="7149398585468413246">"સ્પીચની પિચ ફરીથી સેટ કરો"</string>
@@ -201,9 +201,9 @@
<string name="development_settings_enable" msgid="4285094651288242183">"વિકાસકર્તાનાં વિકલ્પો સક્ષમ કરો"</string>
<string name="development_settings_summary" msgid="8718917813868735095">"ઍપ્લિકેશન વિકાસ માટે વિકલ્પો સેટ કરો"</string>
<string name="development_settings_not_available" msgid="355070198089140951">"આ વપરાશકર્તા માટે વિકાસકર્તા વિકલ્પો ઉપલબ્ધ નથી"</string>
- <string name="vpn_settings_not_available" msgid="2894137119965668920">"આ વપરાશકર્તા માટે VPN સેટિંગ્સ ઉપલબ્ધ નથી"</string>
- <string name="tethering_settings_not_available" msgid="266821736434699780">"આ વપરાશકર્તા માટે ટિથરિંગ સેટિંગ્સ ઉપલબ્ધ નથી"</string>
- <string name="apn_settings_not_available" msgid="1147111671403342300">"અ‍ૅક્સેસ પોઇન્ટનું નામ સેટિંગ્સ આ વપરાશકર્તા માટે ઉપલબ્ધ નથી"</string>
+ <string name="vpn_settings_not_available" msgid="2894137119965668920">"આ વપરાશકર્તા માટે VPN સેટિંગ ઉપલબ્ધ નથી"</string>
+ <string name="tethering_settings_not_available" msgid="266821736434699780">"આ વપરાશકર્તા માટે ટિથરિંગ સેટિંગ ઉપલબ્ધ નથી"</string>
+ <string name="apn_settings_not_available" msgid="1147111671403342300">"અ‍ૅક્સેસ પૉઇન્ટનું નામ સેટિંગ આ વપરાશકર્તા માટે ઉપલબ્ધ નથી"</string>
<string name="enable_adb" msgid="8072776357237289039">"USB ડિબગીંગ"</string>
<string name="enable_adb_summary" msgid="3711526030096574316">"જ્યારે USB કનેક્ટ કરેલું હોય ત્યારે ડિબગ મોડ"</string>
<string name="clear_adb_keys" msgid="3010148733140369917">"USB ડીબગિંગ પ્રમાણીકરણોને રદબાતલ કરો"</string>
@@ -259,7 +259,7 @@
<string name="bluetooth_disable_absolute_volume" msgid="1452342324349203434">"ચોક્કસ વૉલ્યૂમને બંધ કરો"</string>
<string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Gabeldorsche ચાલુ કરો"</string>
<string name="bluetooth_select_avrcp_version_string" msgid="1710571610177659127">"બ્લૂટૂથ AVRCP વર્ઝન"</string>
- <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"બ્લૂટૂથ AVRCP સંસ્કરણ પસંદ કરો"</string>
+ <string name="bluetooth_select_avrcp_version_dialog_title" msgid="7846922290083709633">"બ્લૂટૂથ AVRCP વર્ઝન પસંદ કરો"</string>
<string name="bluetooth_select_map_version_string" msgid="526308145174175327">"બ્લૂટૂથ MAP વર્ઝન"</string>
<string name="bluetooth_select_map_version_dialog_title" msgid="7085934373987428460">"બ્લૂટૂથ MAP વર્ઝન પસંદ કરો"</string>
<string name="bluetooth_select_a2dp_codec_type" msgid="952001408455456494">"બ્લૂટૂથ ઑડિયો કોડેક"</string>
@@ -301,12 +301,12 @@
<string name="mobile_data_always_on_summary" msgid="1112156365594371019">"વાઇ-ફાઇ સક્રિય હોય ત્યારે પણ, હંમેશા મોબાઇલ ડેટાને સક્રિય રાખો (ઝડપી નેટવર્ક સ્વિચિંગ માટે)."</string>
<string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"જો ટિથરિંગ માટે હાર્ડવેર ગતિવૃદ્ધિ ઉપલબ્ધ હોય તો તેનો ઉપયોગ કરો"</string>
<string name="adb_warning_title" msgid="7708653449506485728">"USB ડિબગિંગને મંજૂરી આપીએ?"</string>
- <string name="adb_warning_message" msgid="8145270656419669221">"USB ડિબગીંગ ફક્ત વિકાસ હેતુઓ માટે જ બનાવાયેલ છે. તેનો ઉપયોગ તમારા કમ્પ્યુટર અને તમારા ઉપકરણ વચ્ચે ડેટાને કૉપિ કરવા, નોટિફિકેશન વગર તમારા ઉપકરણ પર ઍપ્લિકેશનો ઇન્સ્ટોલ કરવા અને લૉગ ડેટા વાંચવા માટે કરો."</string>
+ <string name="adb_warning_message" msgid="8145270656419669221">"USB ડિબગીંગ ફક્ત વિકાસ હેતુઓ માટે જ બનાવાયેલ છે. તેનો ઉપયોગ તમારા કમ્પ્યુટર અને તમારા ડિવાઇસ વચ્ચે ડેટાને કૉપિ કરવા, નોટિફિકેશન વગર તમારા ડિવાઇસ પર ઍપ ઇન્સ્ટોલ કરવા અને લૉગ ડેટા વાંચવા માટે કરો."</string>
<string name="adbwifi_warning_title" msgid="727104571653031865">"વાયરલેસ ડિબગીંગને મંજૂરી આપીએ?"</string>
<string name="adbwifi_warning_message" msgid="8005936574322702388">"વાયરલેસ ડિબગીંગ ફક્ત ડેવલપમેન્ટના હેતુઓ માટે જ બનાવાયું છે. તેનો ઉપયોગ તમારા કમ્પ્યુટર અને તમારા ડિવાઇસ વચ્ચે ડેટાને કૉપિ કરવા, નોટિફિકેશન વગર તમારા ડિવાઇસ પર ઍપને ઇન્સ્ટૉલ કરવા અને લૉગ ડેટા વાંચવા માટે કરો."</string>
<string name="adb_keys_warning_message" msgid="2968555274488101220">"તમે અગાઉ અધિકૃત કરેલા તમામ કમ્પ્યુટર્સમાંથી USB ડિબગિંગ પરની અ‍ૅક્સેસ રદબાતલ કરીએ?"</string>
- <string name="dev_settings_warning_title" msgid="8251234890169074553">"વિકાસ સેટિંગ્સને મંજૂરી આપીએ?"</string>
- <string name="dev_settings_warning_message" msgid="37741686486073668">"આ સેટિંગ્સ ફક્ત વિકાસનાં ઉપયોગ માટે જ હેતુબદ્ધ છે. તે તમારા ઉપકરણ અને તેના પરની એપ્લિકેશન્સનાં ભંગ થવા અથવા ખરાબ વર્તનનું કારણ બની શકે છે."</string>
+ <string name="dev_settings_warning_title" msgid="8251234890169074553">"ડેવલપમેન્ટ સેટિંગને મંજૂરી આપીએ?"</string>
+ <string name="dev_settings_warning_message" msgid="37741686486073668">"આ સેટિંગ ફક્ત વિકાસનાં ઉપયોગ માટે જ હેતુબદ્ધ છે. તે તમારા ડિવાઇસ અને તેના પરની ઍપના ભંગ થવા અથવા ખરાબ વર્તનનું કારણ બની શકે છે."</string>
<string name="verify_apps_over_usb_title" msgid="6031809675604442636">"USB પર ઍપ ચકાસો"</string>
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"હાનિકારક વર્તણૂંક માટે ADB/ADT મારફતે ઇન્સ્ટોલ કરવામાં આવેલી ઍપ તપાસો."</string>
<string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"નામ વગરના (ફક્ત MAC ઍડ્રેસવાળા) બ્લૂટૂથ ડિવાઇસ બતાવવામાં આવશે"</string>
@@ -468,7 +468,7 @@
<string name="external_source_trusted" msgid="1146522036773132905">"મંજૂરી છે"</string>
<string name="external_source_untrusted" msgid="5037891688911672227">"મંજૂરી નથી"</string>
<string name="install_other_apps" msgid="3232595082023199454">"અજાણી ઍપ ઇન્સ્ટૉલ કરો"</string>
- <string name="home" msgid="973834627243661438">"સેટિંગ્સ હોમ"</string>
+ <string name="home" msgid="973834627243661438">"સેટિંગ હોમ"</string>
<string-array name="battery_labels">
<item msgid="7878690469765357158">"0%"</item>
<item msgid="8894873528875953317">"50%"</item>
@@ -488,7 +488,7 @@
<string name="retail_demo_reset_title" msgid="1866911701095959800">"પાસવર્ડ આવશ્યક છે"</string>
<string name="active_input_method_subtypes" msgid="4232680535471633046">"ઇનપુટ પદ્ધતિઓ સક્રિય કરો"</string>
<string name="use_system_language_to_select_input_method_subtypes" msgid="4865195835541387040">"સિસ્ટમ ભાષાઓનો ઉપયોગ કરો"</string>
- <string name="failed_to_open_app_settings_toast" msgid="764897252657692092">"<xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> માટેની સેટિંગ્સ ખોલવામાં નિષ્ફળ"</string>
+ <string name="failed_to_open_app_settings_toast" msgid="764897252657692092">"<xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> માટેના સેટિંગ ખોલવામાં નિષ્ફળ"</string>
<string name="ime_security_warning" msgid="6547562217880551450">"આ ઇનપુટ પદ્ધતિ પાસવર્ડ્સ અને ક્રેડિટ કાર્ડ નંબર જેવી વ્યક્તિગત માહિતી સહિત તમે લખો છો તે તમામ ટેક્સ્ટ એકત્રિત કરવા માટે સક્ષમ હોઈ શકે છે. તે ઍપ્લિકેશન <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g> માંથી આવે છે. આ ઇનપુટ પદ્ધતિ વાપરીએ?"</string>
<string name="direct_boot_unaware_dialog_message" msgid="7845398276735021548">"નોંધ: રીબૂટ કર્યાં પછી, જ્યાં સુધી તમે તમારો ફોન અનલૉક કરશો નહીં ત્યાં સુધી આ ઍપ્લિકેશન શરૂ થઈ શકશે નહીં"</string>
<string name="ims_reg_title" msgid="8197592958123671062">"IMS રજિસ્ટ્રેશનની સ્થિતિ"</string>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index b3bdf8977227..65992a7048b8 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -444,7 +444,7 @@
<string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Carica residua: meno di <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string>
<string name="power_remaining_less_than_duration" msgid="318215464914990578">"Carica residua: meno di <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Tempo residuo: più di <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
- <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Tempo residuo: più di <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Tempo rimanente: più di <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Il telefono potrebbe spegnersi a breve"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Il tablet potrebbe spegnersi a breve"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Il dispositivo potrebbe spegnersi a breve"</string>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index b1aee5047fab..7387985cf457 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -309,7 +309,7 @@
<string name="dev_settings_warning_message" msgid="37741686486073668">"Бул орнотуулар өндүрүүчүлөр үчүн гана берилген. Булар түзмөгүңүздүн колдонмолорун бузулушуна же туура эмес иштешине алып келиши мүмкүн."</string>
<string name="verify_apps_over_usb_title" msgid="6031809675604442636">"Орнотулуучу колдонмону текшерүү"</string>
<string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"ADB/ADT аркылуу орнотулган колдонмолордун коопсуздугу текшерилет."</string>
- <string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Аталышсыз Bluetooth түзмөктөрү (MAC даректери менен гана) көрсөтүлөт"</string>
+ <string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Аталышсыз Bluetooth түзмөктөрү (MAC даректери менен гана) көрүнөт"</string>
<string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Алыскы түзмөктөр өтө катуу добуш чыгарып же көзөмөлдөнбөй жатса Bluetooth \"Үндүн абсолюттук деңгээли\" функциясын өчүрөт."</string>
<string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Bluetooth Gabeldorsche функциясынын топтомун иштетет."</string>
<string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Жакшыртылган туташуу функциясын иштетет."</string>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index 5ac22ffbf751..25769936ebfc 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -155,8 +155,8 @@
<string name="running_process_item_user_label" msgid="3988506293099805796">"Хэрэглэгч: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
<string name="launch_defaults_some" msgid="3631650616557252926">"Зарим үндсэн тохиргоонуудыг суулгасан"</string>
<string name="launch_defaults_none" msgid="8049374306261262709">"Ямар ч үндсэн тохиргоог суулгаагүй байна"</string>
- <string name="tts_settings" msgid="8130616705989351312">"Текст-ярианы тохиргоо"</string>
- <string name="tts_settings_title" msgid="7602210956640483039">"Текстийг яриа болгон гаргах"</string>
+ <string name="tts_settings" msgid="8130616705989351312">"Бичвэрийг ярианд хувиргах тохиргоо"</string>
+ <string name="tts_settings_title" msgid="7602210956640483039">"Бичвэрийг ярианд хувиргах"</string>
<string name="tts_default_rate_title" msgid="3964187817364304022">"Ярианы түвшин"</string>
<string name="tts_default_rate_summary" msgid="3781937042151716987">"Текстийг унших хурд"</string>
<string name="tts_default_pitch_title" msgid="6988592215554485479">"Авиа тон"</string>
@@ -170,7 +170,7 @@
<string name="tts_install_data_title" msgid="1829942496472751703">"Хоолойн өгөгдлийг суулгах"</string>
<string name="tts_install_data_summary" msgid="3608874324992243851">"Яриа үүсгэхэд шаардлагатай дууны өгөгдлийг суулгах"</string>
<string name="tts_engine_security_warning" msgid="3372432853837988146">"Энэ яриа үүсгүүр нь нууц үг, зээлийн картын дугаар гэх мэт таны хувийн мэдээллийг оруулан унших бүх текстийг цуглуулах боломжтой. Үүнийг <xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g> үүсгүүрээс нийлүүлдэг. Энэ яриа үүсгүүрийн ашиглалтыг идэвхжүүлэх үү?"</string>
- <string name="tts_engine_network_required" msgid="8722087649733906851">"Энэ хэл нь текстээс дуунд хөрвүүлэхэд ажлын сүлжээний холболтыг шаарддаг."</string>
+ <string name="tts_engine_network_required" msgid="8722087649733906851">"Энэ хэл нь бичвэрийг ярианд хувиргахад ажлын сүлжээний холболт шаардана."</string>
<string name="tts_default_sample_string" msgid="6388016028292967973">"Энэ бол яриа үүсгэх жишээ юм."</string>
<string name="tts_status_title" msgid="8190784181389278640">"Үндсэн хэлний статус"</string>
<string name="tts_status_ok" msgid="8583076006537547379">"<xliff:g id="LOCALE">%1$s</xliff:g> бүрэн дэмжигдсэн"</string>
diff --git a/packages/SettingsLib/res/values-pl/arrays.xml b/packages/SettingsLib/res/values-pl/arrays.xml
index 6493975b2fcd..95ec079429e3 100644
--- a/packages/SettingsLib/res/values-pl/arrays.xml
+++ b/packages/SettingsLib/res/values-pl/arrays.xml
@@ -251,7 +251,7 @@
<item msgid="5023908510820531131">"W: <xliff:g id="AS_TYPED_COMMAND">adb shell dumpsys gfxinfo</xliff:g>"</item>
</string-array>
<string-array name="debug_hw_overdraw_entries">
- <item msgid="1968128556747588800">"Wył."</item>
+ <item msgid="1968128556747588800">"Wyłączone"</item>
<item msgid="3033215374382962216">"Pokaż przerysowywane obszary"</item>
<item msgid="3474333938380896988">"Pokaż obszary dostosowane do deuteranomalii"</item>
</string-array>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index fea9601952e9..2bdd617e9e58 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -443,8 +443,8 @@
<string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Bateria może się wyczerpać do <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Pozostało mniej niż <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string>
<string name="power_remaining_less_than_duration" msgid="318215464914990578">"Pozostało mniej niż <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
- <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Pozostało mniej niż <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
- <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Pozostało mniej niż <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
+ <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Pozostało ponad <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"Pozostało ponad <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="137330009791560774">"Wkrótce telefon może się wyłączyć"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="145489081521468132">"Tablet może się wkrótce wyłączyć"</string>
<string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="1070562682853942350">"Urządzenie może się wkrótce wyłączyć"</string>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index 490d3aaef0e2..055760dae173 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -88,8 +88,8 @@
<string name="bluetooth_profile_hid" msgid="2969922922664315866">"Vnosna naprava"</string>
<string name="bluetooth_profile_pan" msgid="1006235139308318188">"Internetni dostop"</string>
<string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Deljenje stikov"</string>
- <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Uporabi za dajanje stikov v skupno rabo"</string>
- <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Skupna raba internetne povezave"</string>
+ <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Uporabi za deljenje stikov"</string>
+ <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Deljenje internetne povezave"</string>
<string name="bluetooth_profile_map" msgid="8907204701162107271">"Sporočila SMS"</string>
<string name="bluetooth_profile_sap" msgid="8304170950447934386">"Dostop do kartice SIM"</string>
<string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"Zvok visoke kakovosti: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
@@ -104,7 +104,7 @@
<string name="bluetooth_opp_profile_summary_not_connected" msgid="3959741824627764954">"Povezava s strežnikom za prenos datotek ni vzpostavljena"</string>
<string name="bluetooth_hid_profile_summary_connected" msgid="3923653977051684833">"Povezava z vnosno napravo je vzpostavljena"</string>
<string name="bluetooth_pan_user_profile_summary_connected" msgid="380469653827505727">"Povezava z napravo za internetni dostop"</string>
- <string name="bluetooth_pan_nap_profile_summary_connected" msgid="3744773111299503493">"Skupna raba lok. internetne povezave z napravo"</string>
+ <string name="bluetooth_pan_nap_profile_summary_connected" msgid="3744773111299503493">"Deljenje lok. internetne povezave z napravo"</string>
<string name="bluetooth_pan_profile_summary_use_for" msgid="7422039765025340313">"Uporabi za dostop do interneta"</string>
<string name="bluetooth_map_profile_summary_use_for" msgid="4453622103977592583">"Uporabi za zemljevid"</string>
<string name="bluetooth_sap_profile_summary_use_for" msgid="6204902866176714046">"Uporablja se za dostop do kartice SIM"</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/enterprise/ActionDisabledByAdminControllerFactory.java b/packages/SettingsLib/src/com/android/settingslib/enterprise/ActionDisabledByAdminControllerFactory.java
index bd9e0d341b2e..7275d6be99ad 100644
--- a/packages/SettingsLib/src/com/android/settingslib/enterprise/ActionDisabledByAdminControllerFactory.java
+++ b/packages/SettingsLib/src/com/android/settingslib/enterprise/ActionDisabledByAdminControllerFactory.java
@@ -18,6 +18,9 @@ package com.android.settingslib.enterprise;
import static android.app.admin.DevicePolicyManager.DEVICE_OWNER_TYPE_FINANCED;
+import static com.android.settingslib.enterprise.ActionDisabledLearnMoreButtonLauncher.DEFAULT_RESOLVE_ACTIVITY_CHECKER;
+import static com.android.settingslib.enterprise.ManagedDeviceActionDisabledByAdminController.DEFAULT_FOREGROUND_USER_CHECKER;
+
import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.hardware.biometrics.BiometricAuthenticator;
@@ -43,7 +46,11 @@ public final class ActionDisabledByAdminControllerFactory {
} else if (isFinancedDevice(context)) {
return new FinancedDeviceActionDisabledByAdminController(stringProvider);
} else {
- return new ManagedDeviceActionDisabledByAdminController(stringProvider, userHandle);
+ return new ManagedDeviceActionDisabledByAdminController(
+ stringProvider,
+ userHandle,
+ DEFAULT_FOREGROUND_USER_CHECKER,
+ DEFAULT_RESOLVE_ACTIVITY_CHECKER);
}
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/enterprise/ActionDisabledLearnMoreButtonLauncher.java b/packages/SettingsLib/src/com/android/settingslib/enterprise/ActionDisabledLearnMoreButtonLauncher.java
index 411487976fe5..f9d3aaf6b383 100644
--- a/packages/SettingsLib/src/com/android/settingslib/enterprise/ActionDisabledLearnMoreButtonLauncher.java
+++ b/packages/SettingsLib/src/com/android/settingslib/enterprise/ActionDisabledLearnMoreButtonLauncher.java
@@ -22,6 +22,7 @@ import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.UserHandle;
import android.os.UserManager;
@@ -34,6 +35,17 @@ import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
*/
public abstract class ActionDisabledLearnMoreButtonLauncher {
+ public static ResolveActivityChecker DEFAULT_RESOLVE_ACTIVITY_CHECKER =
+ (packageManager, url, userHandle) -> packageManager.resolveActivityAsUser(
+ createLearnMoreIntent(url),
+ PackageManager.MATCH_DEFAULT_ONLY,
+ userHandle.getIdentifier()) != null;
+
+ interface ResolveActivityChecker {
+ boolean canResolveActivityAsUser(
+ PackageManager packageManager, String url, UserHandle userHandle);
+ }
+
/**
* Sets up a "learn more" button which shows a screen with device policy settings
*/
@@ -111,6 +123,14 @@ public abstract class ActionDisabledLearnMoreButtonLauncher {
finishSelf();
}
+ protected final boolean canLaunchHelpPage(
+ PackageManager packageManager,
+ String url,
+ UserHandle userHandle,
+ ResolveActivityChecker resolveActivityChecker) {
+ return resolveActivityChecker.canResolveActivityAsUser(packageManager, url, userHandle);
+ }
+
private void showAdminPolicies(Context context, EnforcedAdmin enforcedAdmin) {
if (enforcedAdmin.component != null) {
launchShowAdminPolicies(context, enforcedAdmin.user, enforcedAdmin.component);
diff --git a/packages/SettingsLib/src/com/android/settingslib/enterprise/BiometricActionDisabledByAdminController.java b/packages/SettingsLib/src/com/android/settingslib/enterprise/BiometricActionDisabledByAdminController.java
index 1472980efd4e..e0339dacf5ac 100644
--- a/packages/SettingsLib/src/com/android/settingslib/enterprise/BiometricActionDisabledByAdminController.java
+++ b/packages/SettingsLib/src/com/android/settingslib/enterprise/BiometricActionDisabledByAdminController.java
@@ -64,9 +64,9 @@ public class BiometricActionDisabledByAdminController extends BaseActionDisabled
return (dialog, which) -> {
Log.d(TAG, "Positive button clicked, component: " + enforcedAdmin.component);
final Intent intent = new Intent(ACTION_LEARN_MORE)
- .setComponent(enforcedAdmin.component)
.putExtra(EXTRA_SETTING_KEY, EXTRA_SETTING_VALUE)
- .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+ .setPackage(enforcedAdmin.component.getPackageName());
context.startActivity(intent);
};
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/enterprise/ManagedDeviceActionDisabledByAdminController.java b/packages/SettingsLib/src/com/android/settingslib/enterprise/ManagedDeviceActionDisabledByAdminController.java
index 93e811d6baaa..c2034f89e18a 100644
--- a/packages/SettingsLib/src/com/android/settingslib/enterprise/ManagedDeviceActionDisabledByAdminController.java
+++ b/packages/SettingsLib/src/com/android/settingslib/enterprise/ManagedDeviceActionDisabledByAdminController.java
@@ -20,13 +20,14 @@ import static java.util.Objects.requireNonNull;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
+import android.content.pm.PackageManager;
import android.os.UserHandle;
import android.os.UserManager;
import android.text.TextUtils;
import androidx.annotation.Nullable;
-import java.util.Objects;
+import com.android.settingslib.enterprise.ActionDisabledLearnMoreButtonLauncher.ResolveActivityChecker;
/**
@@ -35,17 +36,37 @@ import java.util.Objects;
final class ManagedDeviceActionDisabledByAdminController
extends BaseActionDisabledByAdminController {
- private final UserHandle mUserHandle;
+ interface ForegroundUserChecker {
+ boolean isUserForeground(Context context, UserHandle userHandle);
+ }
+
+ public final static ForegroundUserChecker DEFAULT_FOREGROUND_USER_CHECKER =
+ ManagedDeviceActionDisabledByAdminController::isUserForeground;
+
+ /**
+ * The {@link UserHandle} which is preferred for launching the web help page in
+ * <p>If not able to launch the web help page in this user, the current user will be used as
+ * fallback instead. If the current user cannot open it either, the admin policies page will
+ * be used instead.
+ */
+ private final UserHandle mPreferredUserHandle;
+
+ private final ForegroundUserChecker mForegroundUserChecker;
+ private final ResolveActivityChecker mResolveActivityChecker;
/**
* Constructs a {@link ManagedDeviceActionDisabledByAdminController}
- * @param userHandle - user on which to launch the help web page, if necessary
+ * @param preferredUserHandle - user on which to launch the help web page, if necessary
*/
ManagedDeviceActionDisabledByAdminController(
DeviceAdminStringProvider stringProvider,
- UserHandle userHandle) {
+ UserHandle preferredUserHandle,
+ ForegroundUserChecker foregroundUserChecker,
+ ResolveActivityChecker resolveActivityChecker) {
super(stringProvider);
- mUserHandle = requireNonNull(userHandle);
+ mPreferredUserHandle = requireNonNull(preferredUserHandle);
+ mForegroundUserChecker = requireNonNull(foregroundUserChecker);
+ mResolveActivityChecker = requireNonNull(resolveActivityChecker);
}
@Override
@@ -53,14 +74,52 @@ final class ManagedDeviceActionDisabledByAdminController
assertInitialized();
String url = mStringProvider.getLearnMoreHelpPageUrl();
- if (TextUtils.isEmpty(url)) {
+
+ if (!TextUtils.isEmpty(url)
+ && canLaunchHelpPageInPreferredOrCurrentUser(context, url, mPreferredUserHandle)) {
+ setupLearnMoreButtonToLaunchHelpPage(context, url, mPreferredUserHandle);
+ } else {
mLauncher.setupLearnMoreButtonToShowAdminPolicies(context, mEnforcementAdminUserId,
mEnforcedAdmin);
- } else {
- mLauncher.setupLearnMoreButtonToLaunchHelpPage(context, url, mUserHandle);
}
}
+ private boolean canLaunchHelpPageInPreferredOrCurrentUser(
+ Context context, String url, UserHandle preferredUserHandle) {
+ PackageManager packageManager = context.getPackageManager();
+ if (mLauncher.canLaunchHelpPage(
+ packageManager, url, preferredUserHandle, mResolveActivityChecker)
+ && mForegroundUserChecker.isUserForeground(context, preferredUserHandle)) {
+ return true;
+ }
+ return mLauncher.canLaunchHelpPage(
+ packageManager, url, context.getUser(), mResolveActivityChecker);
+ }
+
+ /**
+ * Sets up the "Learn more" button to launch the web help page in the {@code
+ * preferredUserHandle} user. If not possible to launch it there, it sets up the button to
+ * launch it in the current user instead.
+ */
+ private void setupLearnMoreButtonToLaunchHelpPage(
+ Context context, String url, UserHandle preferredUserHandle) {
+ PackageManager packageManager = context.getPackageManager();
+ if (mLauncher.canLaunchHelpPage(
+ packageManager, url, preferredUserHandle, mResolveActivityChecker)
+ && mForegroundUserChecker.isUserForeground(context, preferredUserHandle)) {
+ mLauncher.setupLearnMoreButtonToLaunchHelpPage(context, url, preferredUserHandle);
+ }
+ if (mLauncher.canLaunchHelpPage(
+ packageManager, url, context.getUser(), mResolveActivityChecker)) {
+ mLauncher.setupLearnMoreButtonToLaunchHelpPage(context, url, context.getUser());
+ }
+ }
+
+ private static boolean isUserForeground(Context context, UserHandle userHandle) {
+ return context.createContextAsUser(userHandle, /* flags= */ 0)
+ .getSystemService(UserManager.class).isUserForeground();
+ }
+
@Override
public String getAdminSupportTitle(@Nullable String restriction) {
if (restriction == null) {
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/ManagedDeviceActionDisabledByAdminControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/ManagedDeviceActionDisabledByAdminControllerTest.java
index d9be4f336797..509e12d241dd 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/ManagedDeviceActionDisabledByAdminControllerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/ManagedDeviceActionDisabledByAdminControllerTest.java
@@ -30,6 +30,8 @@ import static com.google.common.truth.Truth.assertThat;
import android.app.Activity;
import android.content.Context;
+import android.content.pm.ResolveInfo;
+import android.os.UserHandle;
import android.os.UserManager;
import androidx.test.core.app.ApplicationProvider;
@@ -45,9 +47,11 @@ import org.robolectric.android.controller.ActivityController;
@RunWith(RobolectricTestRunner.class)
public class ManagedDeviceActionDisabledByAdminControllerTest {
+ private static UserHandle MANAGED_USER = UserHandle.of(123);
private static final String RESTRICTION = UserManager.DISALLOW_ADJUST_VOLUME;
private static final String EMPTY_URL = "";
private static final String SUPPORT_TITLE_FOR_RESTRICTION = DISALLOW_ADJUST_VOLUME_TITLE;
+ public static final ResolveInfo TEST_RESULT_INFO = new ResolveInfo();
private final Context mContext = ApplicationProvider.getApplicationContext();
private final Activity mActivity = ActivityController.of(new Activity()).get();
@@ -60,8 +64,21 @@ public class ManagedDeviceActionDisabledByAdminControllerTest {
}
@Test
- public void setupLearnMoreButton_validUrl_negativeButtonSet() {
- ManagedDeviceActionDisabledByAdminController controller = createController(URL);
+ public void setupLearnMoreButton_noUrl_negativeButtonSet() {
+ ManagedDeviceActionDisabledByAdminController controller = createController(EMPTY_URL);
+
+ controller.setupLearnMoreButton(mContext);
+
+ mTestUtils.assertLearnMoreAction(LEARN_MORE_ACTION_SHOW_ADMIN_POLICIES);
+ }
+
+ @Test
+ public void setupLearnMoreButton_validUrl_foregroundUser_launchesHelpPage() {
+ ManagedDeviceActionDisabledByAdminController controller = createController(
+ URL,
+ /* isUserForeground= */ true,
+ /* preferredUserHandle= */ MANAGED_USER,
+ /* userContainingBrowser= */ MANAGED_USER);
controller.setupLearnMoreButton(mContext);
@@ -69,8 +86,38 @@ public class ManagedDeviceActionDisabledByAdminControllerTest {
}
@Test
- public void setupLearnMoreButton_noUrl_negativeButtonSet() {
- ManagedDeviceActionDisabledByAdminController controller = createController(EMPTY_URL);
+ public void setupLearnMoreButton_validUrl_browserInPreferredUser_notForeground_showsAdminPolicies() {
+ ManagedDeviceActionDisabledByAdminController controller = createController(
+ URL,
+ /* isUserForeground= */ false,
+ /* preferredUserHandle= */ MANAGED_USER,
+ /* userContainingBrowser= */ MANAGED_USER);
+
+ controller.setupLearnMoreButton(mContext);
+
+ mTestUtils.assertLearnMoreAction(LEARN_MORE_ACTION_SHOW_ADMIN_POLICIES);
+ }
+
+ @Test
+ public void setupLearnMoreButton_validUrl_browserInCurrentUser_launchesHelpPage() {
+ ManagedDeviceActionDisabledByAdminController controller = createController(
+ URL,
+ /* isUserForeground= */ false,
+ /* preferredUserHandle= */ MANAGED_USER,
+ /* userContainingBrowser= */ mContext.getUser());
+
+ controller.setupLearnMoreButton(mContext);
+
+ mTestUtils.assertLearnMoreAction(LEARN_MORE_ACTION_LAUNCH_HELP_PAGE);
+ }
+
+ @Test
+ public void setupLearnMoreButton_validUrl_browserNotOnAnyUser_showsAdminPolicies() {
+ ManagedDeviceActionDisabledByAdminController controller = createController(
+ URL,
+ /* isUserForeground= */ false,
+ /* preferredUserHandle= */ MANAGED_USER,
+ /* userContainingBrowser= */ null);
controller.setupLearnMoreButton(mContext);
@@ -110,13 +157,33 @@ public class ManagedDeviceActionDisabledByAdminControllerTest {
}
private ManagedDeviceActionDisabledByAdminController createController() {
- return createController(/* url= */ null);
+ return createController(
+ /* url= */ null,
+ /* foregroundUserChecker= */ true,
+ mContext.getUser(),
+ /* userContainingBrowser= */ null);
}
private ManagedDeviceActionDisabledByAdminController createController(String url) {
+ return createController(
+ url,
+ /* foregroundUserChecker= */ true,
+ mContext.getUser(),
+ /* userContainingBrowser= */ null);
+ }
+
+ private ManagedDeviceActionDisabledByAdminController createController(
+ String url,
+ boolean isUserForeground,
+ UserHandle preferredUserHandle,
+ UserHandle userContainingBrowser) {
ManagedDeviceActionDisabledByAdminController controller =
new ManagedDeviceActionDisabledByAdminController(
- new FakeDeviceAdminStringProvider(url), mContext.getUser());
+ new FakeDeviceAdminStringProvider(url),
+ preferredUserHandle,
+ /* foregroundUserChecker= */ (context, userHandle) -> isUserForeground,
+ /* resolveActivityChecker= */ (packageManager, __, userHandle) ->
+ userHandle.equals(userContainingBrowser));
controller.initialize(mTestUtils.createLearnMoreButtonLauncher());
controller.updateEnforcedAdmin(ENFORCED_ADMIN, ENFORCEMENT_ADMIN_USER_ID);
return controller;
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/IllustrationPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/IllustrationPreferenceTest.java
index ea9be04527be..9e3312ae2ddf 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/IllustrationPreferenceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/IllustrationPreferenceTest.java
@@ -18,6 +18,8 @@ package com.android.settingslib.widget;
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
@@ -130,4 +132,27 @@ public class IllustrationPreferenceTest {
verify(drawable).start();
}
+
+ @Test
+ public void playLottieAnimationWithUri_verifyFailureListener() {
+ doReturn(null).when(mAnimationView).getDrawable();
+
+ mPreference.setImageUri(mImageUri);
+ mPreference.onBindViewHolder(mViewHolder);
+
+ verify(mAnimationView).setFailureListener(any());
+ }
+
+ @Test
+ public void playLottieAnimationWithResource_verifyFailureListener() {
+ // fake the valid lottie image
+ final int fakeValidResId = 111;
+ doNothing().when(mAnimationView).setImageResource(fakeValidResId);
+ doReturn(null).when(mAnimationView).getDrawable();
+
+ mPreference.setLottieAnimationResId(fakeValidResId);
+ mPreference.onBindViewHolder(mViewHolder);
+
+ verify(mAnimationView).setFailureListener(any());
+ }
}
diff --git a/packages/SettingsProvider/res/values-gu/strings.xml b/packages/SettingsProvider/res/values-gu/strings.xml
index 1f91f71be546..dded10ea7006 100644
--- a/packages/SettingsProvider/res/values-gu/strings.xml
+++ b/packages/SettingsProvider/res/values-gu/strings.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="app_label" msgid="4567566098528588863">"સેટિંગ્સ સંગ્રહ"</string>
+ <string name="app_label" msgid="4567566098528588863">"સેટિંગ સ્ટોરેજ"</string>
<string name="wifi_softap_config_change" msgid="5688373762357941645">"હૉટસ્પૉટ સેટિંગ બદલાઈ ગઈ છે"</string>
<string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"વિગતો જોવા માટે ટૅપ કરો"</string>
</resources>
diff --git a/packages/Shell/res/values-sl/strings.xml b/packages/Shell/res/values-sl/strings.xml
index 1fc27ca3d391..76702d6ccba2 100644
--- a/packages/Shell/res/values-sl/strings.xml
+++ b/packages/Shell/res/values-sl/strings.xml
@@ -24,7 +24,7 @@
<string name="bugreport_updating_wait" msgid="3322151947853929470">"Počakajte ..."</string>
<string name="bugreport_finished_text" product="watch" msgid="1223616207145252689">"Poročilo o napakah bo kmalu prikazano v telefonu"</string>
<string name="bugreport_finished_text" product="tv" msgid="5758325479058638893">"Izberite za pošiljanje poročila o napakah"</string>
- <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Dotaknite se, če želite poročilo o napaki dati v skupno rabo"</string>
+ <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Dotaknite se, če želite deliti poročilo o napaki"</string>
<string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"Izberite za pošiljanje poročila o napakah brez posnetka zaslona ali počakajte, da se ta dokonča"</string>
<string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Dotaknite se za pošiljanje poročila o napakah brez posnetka zaslona ali počakajte, da se ta dokonča"</string>
<string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Dotaknite se za pošiljanje poročila o napakah brez posnetka zaslona ali počakajte, da se ta dokonča"</string>
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java
index bd2209b0d292..0424382a1b88 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java
@@ -52,13 +52,6 @@ public interface QS extends FragmentBase {
void setListening(boolean listening);
boolean isShowingDetail();
void closeDetail();
-
- /**
- * Set that we're currently pulse expanding
- *
- * @param pulseExpanding if we're currently expanding during pulsing
- */
- default void setPulseExpanding(boolean pulseExpanding) {}
void animateHeaderSlidingOut();
void setQsExpansion(float qsExpansionFraction, float headerTranslation);
void setHeaderListening(boolean listening);
diff --git a/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml b/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml
index 1abd3931ce7b..009b7cbcaf19 100644
--- a/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml
@@ -74,7 +74,7 @@
<string name="kg_sim_lock_esim_instructions" msgid="5577169988158738030">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> Disable eSIM to use device without mobile service."</string>
<string name="kg_pin_instructions" msgid="822353548385014361">"Enter PIN"</string>
<string name="kg_password_instructions" msgid="324455062831719903">"Enter Password"</string>
- <string name="kg_puk_enter_puk_hint" msgid="3005288372875367017">"SIM is now disabled. Enter PUK code to continue. Contact carrier for details."</string>
+ <string name="kg_puk_enter_puk_hint" msgid="3005288372875367017">"SIM is now disabled. Enter PUK code to continue. Contact operator for details."</string>
<string name="kg_puk_enter_puk_hint_multi" msgid="4876780689904862943">"SIM \"<xliff:g id="CARRIER">%1$s</xliff:g>\" is now disabled. Enter PUK code to continue. Contact operator for details."</string>
<string name="kg_puk_enter_pin_hint" msgid="6028432138916150399">"Enter desired PIN code"</string>
<string name="kg_enter_confirm_pin_hint" msgid="4261064020391799132">"Confirm desired PIN code"</string>
diff --git a/packages/SystemUI/res-keyguard/values-en-rCA/strings.xml b/packages/SystemUI/res-keyguard/values-en-rCA/strings.xml
index c3e8e61cf81d..21f32cf59ad1 100644
--- a/packages/SystemUI/res-keyguard/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-en-rCA/strings.xml
@@ -74,7 +74,7 @@
<string name="kg_sim_lock_esim_instructions" msgid="5577169988158738030">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> Disable eSIM to use device without mobile service."</string>
<string name="kg_pin_instructions" msgid="822353548385014361">"Enter PIN"</string>
<string name="kg_password_instructions" msgid="324455062831719903">"Enter Password"</string>
- <string name="kg_puk_enter_puk_hint" msgid="3005288372875367017">"SIM is now disabled. Enter PUK code to continue. Contact carrier for details."</string>
+ <string name="kg_puk_enter_puk_hint" msgid="3005288372875367017">"SIM is now disabled. Enter PUK code to continue. Contact operator for details."</string>
<string name="kg_puk_enter_puk_hint_multi" msgid="4876780689904862943">"SIM \"<xliff:g id="CARRIER">%1$s</xliff:g>\" is now disabled. Enter PUK code to continue. Contact operator for details."</string>
<string name="kg_puk_enter_pin_hint" msgid="6028432138916150399">"Enter desired PIN code"</string>
<string name="kg_enter_confirm_pin_hint" msgid="4261064020391799132">"Confirm desired PIN code"</string>
diff --git a/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml b/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml
index 1abd3931ce7b..009b7cbcaf19 100644
--- a/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml
@@ -74,7 +74,7 @@
<string name="kg_sim_lock_esim_instructions" msgid="5577169988158738030">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> Disable eSIM to use device without mobile service."</string>
<string name="kg_pin_instructions" msgid="822353548385014361">"Enter PIN"</string>
<string name="kg_password_instructions" msgid="324455062831719903">"Enter Password"</string>
- <string name="kg_puk_enter_puk_hint" msgid="3005288372875367017">"SIM is now disabled. Enter PUK code to continue. Contact carrier for details."</string>
+ <string name="kg_puk_enter_puk_hint" msgid="3005288372875367017">"SIM is now disabled. Enter PUK code to continue. Contact operator for details."</string>
<string name="kg_puk_enter_puk_hint_multi" msgid="4876780689904862943">"SIM \"<xliff:g id="CARRIER">%1$s</xliff:g>\" is now disabled. Enter PUK code to continue. Contact operator for details."</string>
<string name="kg_puk_enter_pin_hint" msgid="6028432138916150399">"Enter desired PIN code"</string>
<string name="kg_enter_confirm_pin_hint" msgid="4261064020391799132">"Confirm desired PIN code"</string>
diff --git a/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml b/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml
index 1abd3931ce7b..009b7cbcaf19 100644
--- a/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml
@@ -74,7 +74,7 @@
<string name="kg_sim_lock_esim_instructions" msgid="5577169988158738030">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> Disable eSIM to use device without mobile service."</string>
<string name="kg_pin_instructions" msgid="822353548385014361">"Enter PIN"</string>
<string name="kg_password_instructions" msgid="324455062831719903">"Enter Password"</string>
- <string name="kg_puk_enter_puk_hint" msgid="3005288372875367017">"SIM is now disabled. Enter PUK code to continue. Contact carrier for details."</string>
+ <string name="kg_puk_enter_puk_hint" msgid="3005288372875367017">"SIM is now disabled. Enter PUK code to continue. Contact operator for details."</string>
<string name="kg_puk_enter_puk_hint_multi" msgid="4876780689904862943">"SIM \"<xliff:g id="CARRIER">%1$s</xliff:g>\" is now disabled. Enter PUK code to continue. Contact operator for details."</string>
<string name="kg_puk_enter_pin_hint" msgid="6028432138916150399">"Enter desired PIN code"</string>
<string name="kg_enter_confirm_pin_hint" msgid="4261064020391799132">"Confirm desired PIN code"</string>
diff --git a/packages/SystemUI/res-keyguard/values-sv/strings.xml b/packages/SystemUI/res-keyguard/values-sv/strings.xml
index 0b1efa84e369..fb2571e157b2 100644
--- a/packages/SystemUI/res-keyguard/values-sv/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sv/strings.xml
@@ -61,7 +61,7 @@
<string name="error_disable_esim_msg" msgid="2441188596467999327">"Det gick inte att inaktivera eSIM-kortet på grund av ett fel."</string>
<string name="keyboardview_keycode_enter" msgid="6727192265631761174">"Retur"</string>
<string name="kg_forgot_pattern_button_text" msgid="3304688032024541260">"Har du glömt ditt grafiska lösenord?"</string>
- <string name="kg_wrong_pattern" msgid="5907301342430102842">"Fel grafiskt lösenord"</string>
+ <string name="kg_wrong_pattern" msgid="5907301342430102842">"Fel mönster"</string>
<string name="kg_wrong_password" msgid="4143127991071670512">"Fel lösenord"</string>
<string name="kg_wrong_pin" msgid="4160978845968732624">"Fel pinkod"</string>
<plurals name="kg_too_many_failed_attempts_countdown" formatted="false" msgid="991400408675793914">
@@ -82,7 +82,7 @@
<string name="kg_invalid_sim_pin_hint" msgid="2762202646949552978">"Ange en pinkod med fyra till åtta siffror."</string>
<string name="kg_invalid_sim_puk_hint" msgid="5319756880543857694">"PUK-koden ska vara minst åtta siffror."</string>
<string name="kg_invalid_puk" msgid="1774337070084931186">"Ange rätt PUK-kod. Om försöken upprepas inaktiveras SIM-kortet permanent."</string>
- <string name="kg_login_too_many_attempts" msgid="4519957179182578690">"För många försök med grafiskt lösenord"</string>
+ <string name="kg_login_too_many_attempts" msgid="4519957179182578690">"För många försök med mönster"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="544687656831558971">"Du har angett fel pinkod <xliff:g id="NUMBER_0">%1$d</xliff:g> gånger. \n\nFörsök igen om <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunder."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="190984061975729494">"Du har angett fel lösenord <xliff:g id="NUMBER_0">%1$d</xliff:g> gånger. \n\nFörsök igen om <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunder."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4252405904570284368">"Du har ritat ditt grafiska lösenord fel <xliff:g id="NUMBER_0">%1$d</xliff:g> gånger. \n\nFörsök igen om <xliff:g id="NUMBER_1">%2$d</xliff:g> sekunder."</string>
@@ -102,13 +102,13 @@
<string name="keyguard_carrier_default" msgid="6359808469637388586">"Ingen tjänst."</string>
<string name="accessibility_ime_switch_button" msgid="9082358310194861329">"Byt inmatningsmetod"</string>
<string name="airplane_mode" msgid="2528005343938497866">"Flygplansläge"</string>
- <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Du måste ange grafiskt lösenord när du har startat om enheten"</string>
+ <string name="kg_prompt_reason_restart_pattern" msgid="4720554342633852066">"Du måste rita mönster när du har startat om enheten"</string>
<string name="kg_prompt_reason_restart_pin" msgid="1587671566498057656">"Du måste ange pinkod när du har startat om enheten"</string>
<string name="kg_prompt_reason_restart_password" msgid="8061279087240952002">"Du måste ange lösenord när du har startat om enheten"</string>
- <string name="kg_prompt_reason_timeout_pattern" msgid="9170360502528959889">"Du måste ange grafiskt lösenord för ytterligare säkerhet"</string>
+ <string name="kg_prompt_reason_timeout_pattern" msgid="9170360502528959889">"Du måste rita mönster för ytterligare säkerhet"</string>
<string name="kg_prompt_reason_timeout_pin" msgid="5945186097160029201">"Du måste ange pinkod för ytterligare säkerhet"</string>
<string name="kg_prompt_reason_timeout_password" msgid="2258263949430384278">"Du måste ange lösenord för ytterligare säkerhet"</string>
- <string name="kg_prompt_reason_switch_profiles_pattern" msgid="1922016914701991230">"Du måste ange grafiskt lösenord när du byter profil"</string>
+ <string name="kg_prompt_reason_switch_profiles_pattern" msgid="1922016914701991230">"Du måste rita mönster när du byter profil"</string>
<string name="kg_prompt_reason_switch_profiles_pin" msgid="6490434826361055400">"Du måste ange pinkod när du byter profil"</string>
<string name="kg_prompt_reason_switch_profiles_password" msgid="1680374696393804441">"Du måste ange lösenord när du byter profil"</string>
<string name="kg_prompt_reason_device_admin" msgid="6961159596224055685">"Administratören har låst enheten"</string>
diff --git a/packages/SystemUI/res/drawable-nodpi/android_12.xml b/packages/SystemUI/res/drawable-nodpi/android_12.xml
new file mode 100644
index 000000000000..bdeeced2d290
--- /dev/null
+++ b/packages/SystemUI/res/drawable-nodpi/android_12.xml
@@ -0,0 +1,37 @@
+<!--
+Copyright (C) 2021 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2 (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="48dp"
+ android:height="48dp"
+ android:viewportWidth="48"
+ android:viewportHeight="48">
+ <group>
+ <clip-path
+ android:pathData="M14,14h21v20h-21z"/>
+ <path
+ android:pathData="M15,15C15.7956,15 16.5587,15.3161 17.1213,15.8787C17.6839,16.4413 18,17.2044 18,18V33"
+ android:strokeWidth="2"
+ android:fillColor="#00000000"
+ android:strokeColor="#ffffff"
+ android:strokeLineCap="round"/>
+ <path
+ android:pathData="M34,33H22V30C22,28.4087 22.6321,26.8826 23.7574,25.7574C24.8826,24.6321 26.4087,24 28,24H31C31.7956,24 32.5587,23.6839 33.1213,23.1213C33.6839,22.5587 34,21.7957 34,21C34.009,19.5779 33.5126,18.1989 32.5993,17.1088C31.686,16.0188 30.4153,15.2885 29.0136,15.0483C27.612,14.8081 26.1706,15.0735 24.9464,15.7973C23.7223,16.5211 22.795,17.6561 22.33,19C22.2199,19.3261 22.1363,19.6605 22.08,20"
+ android:strokeWidth="2"
+ android:fillColor="#00000000"
+ android:strokeColor="#ffffff"
+ android:strokeLineCap="round"/>
+ </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable-nodpi/icon.xml b/packages/SystemUI/res/drawable-nodpi/icon.xml
index 7f8d4fa8833f..997249632709 100644
--- a/packages/SystemUI/res/drawable-nodpi/icon.xml
+++ b/packages/SystemUI/res/drawable-nodpi/icon.xml
@@ -15,5 +15,5 @@ Copyright (C) 2018 The Android Open Source Project
-->
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/icon_bg"/>
- <foreground android:drawable="@drawable/android_11_dial"/>
+ <foreground android:drawable="@drawable/android_12"/>
</adaptive-icon>
diff --git a/packages/SystemUI/res/drawable-nodpi/icon_bg.xml b/packages/SystemUI/res/drawable-nodpi/icon_bg.xml
index 31b2a7f9a333..ff7cbae16ab2 100644
--- a/packages/SystemUI/res/drawable-nodpi/icon_bg.xml
+++ b/packages/SystemUI/res/drawable-nodpi/icon_bg.xml
@@ -14,5 +14,5 @@ Copyright (C) 2018 The Android Open Source Project
limitations under the License.
-->
<color xmlns:android="http://schemas.android.com/apk/res/android"
- android:color="#073042" />
+ android:color="@android:color/system_accent1_500" />
diff --git a/packages/SystemUI/res/drawable/controls_icon.xml b/packages/SystemUI/res/drawable/controls_icon.xml
new file mode 100644
index 000000000000..f1814a228665
--- /dev/null
+++ b/packages/SystemUI/res/drawable/controls_icon.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2021 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="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M12,3L4,9v12h16L20,9l-8,-6zM18,19h-3v-6L9,13v6L6,19v-9l6,-4.5 6,4.5v9z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/fingerprint_bg.xml b/packages/SystemUI/res/drawable/fingerprint_bg.xml
index 2b0ab6f9a8d2..558ec08b2ceb 100644
--- a/packages/SystemUI/res/drawable/fingerprint_bg.xml
+++ b/packages/SystemUI/res/drawable/fingerprint_bg.xml
@@ -14,10 +14,11 @@
-->
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:shape="oval">
<solid
- android:color="?android:attr/colorBackground"/>
+ android:color="?androidprv:attr/colorSurface"/>
<size
android:width="64dp"
diff --git a/packages/SystemUI/res/drawable/ic_unlock.xml b/packages/SystemUI/res/drawable/ic_unlock.xml
new file mode 100644
index 000000000000..c3b34699e8e2
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_unlock.xml
@@ -0,0 +1,42 @@
+<!--
+ Copyright (C) 2021 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="65dp" android:width="46dp" android:viewportHeight="65" android:viewportWidth="46">
+ <group android:translateX="8.625" android:translateY="13.625">
+ <path
+ android:strokeColor="#FF000000"
+ android:strokeLineCap="round"
+ android:strokeLineJoin="round"
+ android:strokeWidth="2.5"
+ android:pathData="M4.75 15 C4.75,15 23.25,15 23.25,15 C24.35,15 25.25,15.9 25.25,17 C25.25,17 25.25,33 25.25,33 C25.25,34.1 24.35,35 23.25,35 C23.25,35 4.75,35 4.75,35 C3.65,35 2.75,34.1 2.75,33 C2.75,33 2.75,17 2.75,17 C2.75,15.9 3.65,15 4.75,15c " />
+ </group>
+ <group android:translateX="14" android:translateY="13.5">
+ <path
+ android:strokeColor="#FF000000"
+ android:strokeLineCap="round"
+ android:strokeLineJoin="round"
+ android:strokeWidth="2.5"
+ android:pathData="M27.19 14.81 C27.19,14.81 27.19,8.3 27.19,8.3 C27.19,4.92 24.44,2.88 21.19,2.75 C17.74,2.62 15,4.74 15,8.11 C15,8.11 15,15 15,15 " />
+ </group>
+ <group android:translateX="20" android:translateY="35.75">
+ <path
+ android:fillColor="#FF000000"
+ android:fillAlpha="1"
+ android:fillType="nonZero"
+ android:pathData=" M2.75 5.25 C4.13,5.25 5.25,4.13 5.25,2.75 C5.25,1.37 4.13,0.25 2.75,0.25 C1.37,0.25 0.25,1.37 0.25,2.75 C0.25,4.13 1.37,5.25 2.75,5.25c " />
+ </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/wallet_lockscreen_bg.xml b/packages/SystemUI/res/drawable/keyguard_bottom_affordance_bg.xml
index 1535e7276a6f..1535e7276a6f 100644
--- a/packages/SystemUI/res/drawable/wallet_lockscreen_bg.xml
+++ b/packages/SystemUI/res/drawable/keyguard_bottom_affordance_bg.xml
diff --git a/packages/SystemUI/res/layout/keyguard_bottom_area.xml b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
index 611fa91eb769..7aeca7f30639 100755
--- a/packages/SystemUI/res/layout/keyguard_bottom_area.xml
+++ b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
@@ -91,18 +91,32 @@
<ImageView
android:id="@+id/wallet_button"
- android:layout_height="@dimen/keyguard_affordance_wallet_height"
- android:layout_width="@dimen/keyguard_affordance_wallet_width"
+ android:layout_height="@dimen/keyguard_affordance_fixed_height"
+ android:layout_width="@dimen/keyguard_affordance_fixed_width"
android:layout_gravity="bottom|end"
android:scaleType="center"
android:tint="?android:attr/textColorPrimary"
android:src="@drawable/ic_wallet_lockscreen"
- android:background="@drawable/wallet_lockscreen_bg"
+ android:background="@drawable/keyguard_bottom_affordance_bg"
android:layout_marginEnd="@dimen/keyguard_affordance_horizontal_offset"
android:layout_marginBottom="@dimen/keyguard_affordance_vertical_offset"
android:contentDescription="@string/accessibility_wallet_button"
android:visibility="gone" />
+ <ImageView
+ android:id="@+id/controls_button"
+ android:layout_height="@dimen/keyguard_affordance_fixed_height"
+ android:layout_width="@dimen/keyguard_affordance_fixed_width"
+ android:layout_gravity="bottom|start"
+ android:scaleType="center"
+ android:tint="?android:attr/textColorPrimary"
+ android:src="@drawable/controls_icon"
+ android:background="@drawable/keyguard_bottom_affordance_bg"
+ android:layout_marginStart="@dimen/keyguard_affordance_horizontal_offset"
+ android:layout_marginBottom="@dimen/keyguard_affordance_vertical_offset"
+ android:contentDescription="@string/quick_controls_title"
+ android:visibility="gone" />
+
<FrameLayout
android:id="@+id/overlay_container"
android:layout_width="match_parent"
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 f9dcd390cd51..f3b8b0bfaf36 100644
--- a/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
+++ b/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
@@ -55,7 +55,7 @@
android:clipChildren="false"
android:clipToPadding="false"
android:focusable="true"
- android:paddingBottom="10dp"
+ android:paddingBottom="24dp"
android:importantForAccessibility="yes" />
</RelativeLayout>
diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml
index 1a912023e33c..b0f1f487b260 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded.xml
@@ -55,9 +55,23 @@
android:id="@+id/lock_icon_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:padding="48px"
- android:layout_gravity="center"
- android:scaleType="centerCrop"/>
+ android:layout_gravity="center">
+ <!-- Background protection -->
+ <ImageView
+ android:id="@+id/lock_icon_bg"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@drawable/fingerprint_bg"
+ android:visibility="invisible"/>
+
+ <ImageView
+ android:id="@+id/lock_icon"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:padding="48px"
+ android:layout_gravity="center"
+ android:scaleType="centerCrop"/>
+ </com.android.keyguard.LockIconView>
<com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer
android:layout_width="match_parent"
diff --git a/packages/SystemUI/res/layout/udfps_keyguard_view.xml b/packages/SystemUI/res/layout/udfps_keyguard_view.xml
index 8834ac040b54..1851790673e3 100644
--- a/packages/SystemUI/res/layout/udfps_keyguard_view.xml
+++ b/packages/SystemUI/res/layout/udfps_keyguard_view.xml
@@ -26,8 +26,7 @@
android:id="@+id/udfps_keyguard_fp_bg"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:background="@drawable/fingerprint_bg"
- android:visibility="gone"/>
+ android:src="@drawable/fingerprint_bg"/>
<!-- Fingerprint -->
<!-- AOD dashed fingerprint icon with moving dashes -->
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 3506057bd5ac..5a4a8ea20891 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Tik weer om oop te maak"</string>
<string name="tap_again" msgid="1315420114387908655">"Tik weer"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Swiep op om oop te maak"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"Druk om oop te maak"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Swiep op om weer te probeer"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"Ontsluit om NFC te gebruik"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Hierdie toestel behoort aan jou organisasie"</string>
diff --git a/packages/SystemUI/res/values-af/strings_tv.xml b/packages/SystemUI/res/values-af/strings_tv.xml
index 2e9400e2e5b6..c20d01e885f2 100644
--- a/packages/SystemUI/res/values-af/strings_tv.xml
+++ b/packages/SystemUI/res/values-af/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Via <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Kennisgewings"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Geen kennisgewings nie"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"Mikrofoon neem tans op"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"Kamera neem tans op"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Kamera en mikrofoon neem tans op"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Mikrofoon het opname gestop"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Kamera het opname gestop"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Kamera en mikrofoon het opname gestop"</string>
</resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 74009bf50bbc..3a3938fc16d3 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"ለመክፈት ዳግም መታ ያድርጉ"</string>
<string name="tap_again" msgid="1315420114387908655">"እንደገና መታ ያድርጉ"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"ለመክፈት በጣት ወደ ላይ ጠረግ ያድርጉ"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"ለመክፈት ይጫኑ"</string>
<string name="keyguard_retry" msgid="886802522584053523">"እንደገና ለመሞከር ወደ ላይ ይጥረጉ"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFCን ለመጠቀም ይክፈቱ"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"ይህ መሣሪያ የድርጅትዎ ነው"</string>
diff --git a/packages/SystemUI/res/values-am/strings_tv.xml b/packages/SystemUI/res/values-am/strings_tv.xml
index 71d887d09752..39429e4a20ac 100644
--- a/packages/SystemUI/res/values-am/strings_tv.xml
+++ b/packages/SystemUI/res/values-am/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"በ<xliff:g id="VPN_APP">%1$s</xliff:g> በኩል"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"ማሳወቂያዎች"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"ምንም ማሳወቂያዎች የሉም"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"ማይክሮፎን እየቀዳ ነው"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"ካሜራ እየቀረጸ ነው"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"ካሜራ እየቀረጸ እና ማይክሮፎን እየቀዳ ነው"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"ማይክሮፎን መቅዳት አቁሟል"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"ካሜራ መቅረጽ አቁሟል"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"ካሜራ መቅረጽ እና ማይክሮፎን መቅዳት አቁመዋል"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 993ee39ab808..72279a6ed89d 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -460,6 +460,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"انقر مرة أخرى للفتح"</string>
<string name="tap_again" msgid="1315420114387908655">"انقر مرة أخرى"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"يمكنك الفتح بالتمرير سريعًا لأعلى."</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"اضغط لفتح الجهاز."</string>
<string name="keyguard_retry" msgid="886802522584053523">"مرِّر سريعًا للأعلى لإعادة المحاولة."</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"‏افتح قفل الشاشة لاستخدام تقنية NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"هذا الجهاز يخص مؤسستك."</string>
diff --git a/packages/SystemUI/res/values-ar/strings_tv.xml b/packages/SystemUI/res/values-ar/strings_tv.xml
index 769999f5f902..13f23f019f1b 100644
--- a/packages/SystemUI/res/values-ar/strings_tv.xml
+++ b/packages/SystemUI/res/values-ar/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"عبر <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"الإشعارات"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"ما من إشعارات"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"جارٍ التسجيل بالميكرفون"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"جارٍ التسجيل بالكاميرا"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"جارٍ التسجيل بالكاميرا والميكروفون"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"توقف التسجيل بالميكرفون."</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"توقف التسجيل بالكاميرا."</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"توقف التسجيل بالكاميرا والميكروفون."</string>
</resources>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index 20023c0b36d0..7fe06e3bfe2b 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"খুলিবলৈ পুনৰাই টিপক"</string>
<string name="tap_again" msgid="1315420114387908655">"পুনৰ টিপক"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"খুলিবলৈ ওপৰলৈ ছোৱাইপ কৰক"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"খুলিবলৈ টিপক"</string>
<string name="keyguard_retry" msgid="886802522584053523">"পুনৰ চেষ্টা কৰিবলৈ ওপৰলৈ ছোৱাইপ কৰক"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC ব্যৱহাৰ কৰিবলৈ আনলক কৰক"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"এই ডিভাইচটো আপোনাৰ প্ৰতিষ্ঠানৰ"</string>
diff --git a/packages/SystemUI/res/values-as/strings_tv.xml b/packages/SystemUI/res/values-as/strings_tv.xml
index 859ea2c65093..733e2e6c72e7 100644
--- a/packages/SystemUI/res/values-as/strings_tv.xml
+++ b/packages/SystemUI/res/values-as/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"<xliff:g id="VPN_APP">%1$s</xliff:g>ৰ জৰিয়তে"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"জাননী"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"কোনো জাননী নাই"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"মাইক্ৰ’ফ’নটোৱে ৰেক’ৰ্ড কৰি আছে"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"কেমেৰাটোৱে ৰেক’ৰ্ড কৰি আছে"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"কেমেৰা আৰু মাইক্ৰ’ফ’নটোৱে ৰেক’ৰ্ড কৰি আছে"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"মাইক্ৰ’ফ’নটোৱে ৰেক’ৰ্ড কৰাটো বন্ধ কৰিছে"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"কেমেৰাটোৱে ৰেক’ৰ্ড কৰাটো বন্ধ কৰিছে"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"কেমেৰা আৰু মাইক্ৰ’ফ’নটোৱে ৰেক’ৰ্ড কৰাটো বন্ধ কৰিছে"</string>
</resources>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index 71f90fd519aa..0b97347d70f1 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Açmaq üçün yenidən tıklayın"</string>
<string name="tap_again" msgid="1315420114387908655">"Yenidən toxunun"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Açmaq üçün yuxarı sürüşdürün"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"Açmaq üçün basın"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Yenidən cəhd etmək üçün yuxarı sürüşdürün"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC istifadə etmək üçün kiliddən çıxarın"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Bu cihaz təşkilatınıza məxsusdur"</string>
diff --git a/packages/SystemUI/res/values-az/strings_tv.xml b/packages/SystemUI/res/values-az/strings_tv.xml
index 1f1b6491b533..cd8b46c7a901 100644
--- a/packages/SystemUI/res/values-az/strings_tv.xml
+++ b/packages/SystemUI/res/values-az/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"<xliff:g id="VPN_APP">%1$s</xliff:g> vasitəsilə"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Bildirişlər"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Bildiriş yoxdur"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"Mikrofon yazır"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"Kamera yazır"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Kamera və mikrofon yazır"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Mikrofon yazmağı dayandırıb"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Kamera yazmağı dayandırıb"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Kamera və mikrofon yazmağı dayandırıb"</string>
</resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 7402594b3c59..2aff0a34271c 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -454,6 +454,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Dodirnite ponovo da biste otvorili"</string>
<string name="tap_again" msgid="1315420114387908655">"Dodirnite ponovo"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Prevucite nagore da biste otvorili"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"Pritisnite da biste otvorili"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Prevucite nagore da biste probali ponovo"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"Otključajte da biste koristili NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Ovaj uređaj pripada organizaciji"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings_tv.xml b/packages/SystemUI/res/values-b+sr+Latn/strings_tv.xml
index 2eaa4996b101..31a37dbd54e3 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings_tv.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Preko: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Obaveštenja"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Nema obaveštenja"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"Mikrofon snima"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"Kamera snima"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Kamera i mikrofon snimaju"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Snimanje mikrofonom je zaustavljeno"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Snimanje kamerom je zaustavljeno"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Snimanje kamerom i mikrofonom je zaustavljeno"</string>
</resources>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 7688e06dba25..ac37b8e8451e 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -456,6 +456,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Дакраніцеся яшчэ раз, каб адкрыць"</string>
<string name="tap_again" msgid="1315420114387908655">"Націсніце яшчэ раз"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Каб адкрыць, прагарніце ўверх"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"Націсніце, каб адкрыць"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Прагартайце ўверх, каб паўтарыць спробу"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"Разблакіруйце, каб выкарыстоўваць NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Гэта прылада належыць вашай арганізацыі"</string>
diff --git a/packages/SystemUI/res/values-be/strings_tv.xml b/packages/SystemUI/res/values-be/strings_tv.xml
index 21a2e6ed1d42..410c1202c9ed 100644
--- a/packages/SystemUI/res/values-be/strings_tv.xml
+++ b/packages/SystemUI/res/values-be/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Праз <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Апавяшчэнні"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Апавяшчэнняў няма"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"Ідзе запіс з выкарыстаннем мікрафона"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"Ідзе запіс з выкарыстаннем камеры"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Ідзе запіс з выкарыстаннем камеры і мікрафона"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Запіс з выкарыстаннем мікрафона спынены"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Запіс з выкарыстаннем камеры спынены"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Запіс з выкарыстаннем камеры і мікрафона спынены"</string>
</resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 386fbd6a8520..73724a8ba617 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Докоснете отново, за да отворите"</string>
<string name="tap_again" msgid="1315420114387908655">"Докоснете отново"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Прекарайте пръст нагоре, за да отключите"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"Натиснете за отваряне"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Плъзнете бързо нагоре, за да опитате отново"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"Отключете, за да използвате NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Това устройство принадлежи на организацията ви"</string>
diff --git a/packages/SystemUI/res/values-bg/strings_tv.xml b/packages/SystemUI/res/values-bg/strings_tv.xml
index b7af7cb26c41..981ab95c80ce 100644
--- a/packages/SystemUI/res/values-bg/strings_tv.xml
+++ b/packages/SystemUI/res/values-bg/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Чрез <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Известия"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Няма известия"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"Микрофонът записва"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"Камерата записва"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Камерата и микрофонът записват"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Микрофонът спря да записва"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Камерата спря да записва"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Камерата и микрофонът спряха да записват"</string>
</resources>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index d26912604bb5..a70fa8d18b25 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"খোলার জন্য আবার আলতো চাপুন"</string>
<string name="tap_again" msgid="1315420114387908655">"আবার ট্যাপ করুন"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"খোলার জন্য উপরে সোয়াইপ করুন"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"আনলক করার জন্য প্রেস করুন"</string>
<string name="keyguard_retry" msgid="886802522584053523">"আবার চেষ্টা করতে উপরের দিকে সোয়াইপ করুন"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC ব্যবহার করতে আনলক করুন"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"এই ডিভাইসটি আপনার প্রতিষ্ঠানের"</string>
diff --git a/packages/SystemUI/res/values-bn/strings_tv.xml b/packages/SystemUI/res/values-bn/strings_tv.xml
index 38c24ace782e..5d252b17aea6 100644
--- a/packages/SystemUI/res/values-bn/strings_tv.xml
+++ b/packages/SystemUI/res/values-bn/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"<xliff:g id="VPN_APP">%1$s</xliff:g>-এর মাধ্যমে"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"বিজ্ঞপ্তি"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"কোনও বিজ্ঞপ্তি নেই"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"মাইক্রোফোনে রেকর্ড করা হচ্ছে"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"ক্যামেরায় রেকর্ড করা হচ্ছে"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"ক্যামেরা ও মাইক্রোফোনে রেকর্ড করা হচ্ছে"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"মাইক্রোফোনে রেকর্ড করা বন্ধ হয়ে গেছে"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"ক্যামেরায় রেকর্ড করা বন্ধ হয়ে গেছে"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"ক্যামেরা ও মাইক্রোফোনে রেকর্ড করা বন্ধ হয়ে গেছে"</string>
</resources>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 2857eccd0633..afc21b5a605c 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -454,6 +454,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Dodirnite ponovo da otvorite"</string>
<string name="tap_again" msgid="1315420114387908655">"Ponovo dodirnite"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Prevucite da otvorite"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"Pritisnite da otvorite"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Prevucite prema gore da pokušate ponovo"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"Otključajte da koristite NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Ovaj uređaj pripada vašoj organizaciji"</string>
diff --git a/packages/SystemUI/res/values-bs/strings_tv.xml b/packages/SystemUI/res/values-bs/strings_tv.xml
index 01916a1dea8c..341c12508236 100644
--- a/packages/SystemUI/res/values-bs/strings_tv.xml
+++ b/packages/SystemUI/res/values-bs/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Putem: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Obavještenja"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Nema obavještenja"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"Mikrofon snima"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"Kamera snima"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Kamera i mikrofon snimaju"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Mikrofon je prestao snimati"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Kamera je prestala snimati"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Kamera i mikrofon su prestali snimati"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index c25dca5c91e6..e9da15559214 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Torna a tocar per obrir-la."</string>
<string name="tap_again" msgid="1315420114387908655">"Torna a tocar"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Llisca cap amunt per obrir"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"Prem per obrir"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Llisca cap a dalt per tornar-ho a provar"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desbloqueja per utilitzar l\'NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Aquest dispositiu pertany a la teva organització"</string>
diff --git a/packages/SystemUI/res/values-ca/strings_tv.xml b/packages/SystemUI/res/values-ca/strings_tv.xml
index a0607854c0e2..6a28c837f7e3 100644
--- a/packages/SystemUI/res/values-ca/strings_tv.xml
+++ b/packages/SystemUI/res/values-ca/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Mitjançant <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Notificacions"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Cap notificació"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"El micròfon està gravant"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"La càmera està gravant"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"La càmera i el micròfon estan gravant"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"El micròfon ha deixat de gravar"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"La càmera ha deixat de gravar"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"La càmera i el micròfon han deixat de gravar"</string>
</resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 5fed1b3e3f30..3463586f3c5e 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -456,6 +456,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Oznámení otevřete opětovným klepnutím"</string>
<string name="tap_again" msgid="1315420114387908655">"Znovu klepněte"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Otevřete přejetím prstem nahoru"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"Stisknutím otevřete"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Přejetím nahoru to zkusíte znovu"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC vyžaduje odemknutou obrazovku"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Toto zařízení patří vaší organizaci"</string>
diff --git a/packages/SystemUI/res/values-cs/strings_tv.xml b/packages/SystemUI/res/values-cs/strings_tv.xml
index eeab0d9d95a2..115c875f8194 100644
--- a/packages/SystemUI/res/values-cs/strings_tv.xml
+++ b/packages/SystemUI/res/values-cs/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Přes <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Oznámení"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Žádná oznámení"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"Mikrofon nahrává"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"Kamera nahrává"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Kamera a mikrofon nahrávají"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Mikrofon přestal nahrávat"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Kamera přestala nahrávat"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Kamera a mikrofon přestaly nahrávat"</string>
</resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index facedf0ff039..8367077445ff 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Tryk igen for at åbne"</string>
<string name="tap_again" msgid="1315420114387908655">"Tryk igen"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Stryg opad for at åbne"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"Tryk for at åbne"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Stryg opad for at prøve igen"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"Lås op for at bruge NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Denne enhed tilhører din organisation"</string>
diff --git a/packages/SystemUI/res/values-da/strings_tv.xml b/packages/SystemUI/res/values-da/strings_tv.xml
index fb0bc2d513f9..af489467df89 100644
--- a/packages/SystemUI/res/values-da/strings_tv.xml
+++ b/packages/SystemUI/res/values-da/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Via <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Notifikationer"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Ingen notifikationer"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"Mikrofonen optager"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"Kameraet optager"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Kameraet og mikrofonen optager"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Mikrofonen er stoppet med at optage"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Kameraet er stoppet med at optage"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Kameraet og mikrofonen er stoppet med at optage"</string>
</resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 5d10eb4b25b9..f2cb79a300ff 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Erneut tippen, um Benachrichtigung zu öffnen"</string>
<string name="tap_again" msgid="1315420114387908655">"Noch einmal tippen"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Zum Öffnen nach oben wischen"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"Zum Öffnen klicken"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Zum Wiederholen nach oben wischen"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"Zur Verwendung von NFC entsperren"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Dieses Gerät gehört deiner Organisation"</string>
diff --git a/packages/SystemUI/res/values-de/strings_tv.xml b/packages/SystemUI/res/values-de/strings_tv.xml
index 0345c804f35a..e8e8dcd2226e 100644
--- a/packages/SystemUI/res/values-de/strings_tv.xml
+++ b/packages/SystemUI/res/values-de/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Über <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Benachrichtigungen"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Keine Benachrichtigungen"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"Mikrofon nimmt auf"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"Kamera nimmt auf"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Kamera und Mikrofon nehmen auf"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Aufnahme des Mikrofons gestoppt"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Aufnahme der Kamera gestoppt"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Aufnahme von Kamera und Mikrofon gestoppt"</string>
</resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index cfda46f64eda..ef7771df0295 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Πατήστε ξανά για να ανοίξετε"</string>
<string name="tap_again" msgid="1315420114387908655">"Πατήστε ξανά"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Σύρετε προς τα επάνω για άνοιγμα"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"Πατήστε για άνοιγμα"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Σύρετε προς τα πάνω για να δοκιμάσετε ξανά"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"Ξεκλείδωμα για χρήση του NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Αυτή η συσκευή ανήκει στον οργανισμό σας."</string>
diff --git a/packages/SystemUI/res/values-el/strings_tv.xml b/packages/SystemUI/res/values-el/strings_tv.xml
index cd9277234bd7..01def2b2418b 100644
--- a/packages/SystemUI/res/values-el/strings_tv.xml
+++ b/packages/SystemUI/res/values-el/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Μέσω <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Ειδοποιήσεις"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Δεν υπάρχουν ειδοποιήσεις."</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"Πραγματοποιείται εγγραφή από το μικρόφωνο"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"Πραγματοποιείται εγγραφή από την κάμερα"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Πραγματοποιείται εγγραφή από την κάμερα και το μικρόφωνο"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Η εγγραφή από το μικρόφωνο διακόπηκε"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Η εγγραφή από την κάμερα διακόπηκε"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Η εγγραφή από την κάμερα και το μικρόφωνο διακόπηκε"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 9af2d89ce21d..905beaedc642 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Tap again to open"</string>
<string name="tap_again" msgid="1315420114387908655">"Tap again"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Swipe up to open"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"Press to open"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Swipe up to try again"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"Unlock to use NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"This device belongs to your organisation"</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings_tv.xml b/packages/SystemUI/res/values-en-rAU/strings_tv.xml
index 3b3e2d6fef48..08fc8a67b032 100644
--- a/packages/SystemUI/res/values-en-rAU/strings_tv.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Via <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Notifications"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"No notifications"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"Microphone is recording"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"Camera is recording"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Camera and microphone are recording"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Microphone stopped recording"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Camera stopped recording"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Camera and microphone stopped recording"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index 398420a68f5c..51ed681f4676 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Tap again to open"</string>
<string name="tap_again" msgid="1315420114387908655">"Tap again"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Swipe up to open"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"Press to open"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Swipe up to try again"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"Unlock to use NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"This device belongs to your organisation"</string>
diff --git a/packages/SystemUI/res/values-en-rCA/strings_tv.xml b/packages/SystemUI/res/values-en-rCA/strings_tv.xml
index 3b3e2d6fef48..08fc8a67b032 100644
--- a/packages/SystemUI/res/values-en-rCA/strings_tv.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Via <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Notifications"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"No notifications"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"Microphone is recording"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"Camera is recording"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Camera and microphone are recording"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Microphone stopped recording"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Camera stopped recording"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Camera and microphone stopped recording"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 9af2d89ce21d..905beaedc642 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Tap again to open"</string>
<string name="tap_again" msgid="1315420114387908655">"Tap again"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Swipe up to open"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"Press to open"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Swipe up to try again"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"Unlock to use NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"This device belongs to your organisation"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings_tv.xml b/packages/SystemUI/res/values-en-rGB/strings_tv.xml
index 3b3e2d6fef48..08fc8a67b032 100644
--- a/packages/SystemUI/res/values-en-rGB/strings_tv.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Via <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Notifications"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"No notifications"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"Microphone is recording"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"Camera is recording"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Camera and microphone are recording"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Microphone stopped recording"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Camera stopped recording"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Camera and microphone stopped recording"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 9af2d89ce21d..905beaedc642 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Tap again to open"</string>
<string name="tap_again" msgid="1315420114387908655">"Tap again"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Swipe up to open"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"Press to open"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Swipe up to try again"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"Unlock to use NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"This device belongs to your organisation"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings_tv.xml b/packages/SystemUI/res/values-en-rIN/strings_tv.xml
index 3b3e2d6fef48..08fc8a67b032 100644
--- a/packages/SystemUI/res/values-en-rIN/strings_tv.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Via <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Notifications"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"No notifications"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"Microphone is recording"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"Camera is recording"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Camera and microphone are recording"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Microphone stopped recording"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Camera stopped recording"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Camera and microphone stopped recording"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index b21102657db8..8cd587e04166 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‎‎‎‏‎‎‎‏‎‏‎‏‎‎‎‎‏‎‎‏‎‎‏‏‎‎‎‏‏‎‎‎‎‎‎‎‏‏‎‎‏‎‏‏‏‎‎‎‏‎‎‏‎‎‎‎‏‎Tap again to open‎‏‎‎‏‎"</string>
<string name="tap_again" msgid="1315420114387908655">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‎‎‏‎‎‎‎‎‏‎‏‎‎‏‏‏‏‏‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‎‎‎‎‎‏‎‏‏‏‏‎Tap again‎‏‎‎‏‎"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‏‎‏‏‏‎‏‎‎‏‏‏‏‎‏‏‎‏‏‏‎‎‏‏‏‏‎‏‎‎‎‎‎‏‏‏‎‏‏‏‎‎‎‏‎‎‏‎‎‎‎‎‏‎Swipe up to open‎‏‎‎‏‎"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‎‏‏‎‎‏‎‏‎‏‏‎‏‏‏‎‏‏‏‎‏‏‏‏‎‏‏‏‏‎‎‏‎‏‎‏‏‎‏‏‏‏‏‎‏‎‏‎‎‎‏‎‎‎Press to open‎‏‎‎‏‎"</string>
<string name="keyguard_retry" msgid="886802522584053523">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‎‎‏‎‎‏‏‏‎‏‎‎‎‏‏‏‎‎‎‏‏‎‎‏‎‎‎‏‎‎‎‎‎‏‎‎‎‏‎‏‎‏‏‏‏‎‏‏‏‎‎‎‏‎‎‏‏‎Swipe up to try again‎‏‎‎‏‎"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‏‏‎‏‎‏‏‏‎‏‎‎‏‏‎‏‎‏‏‏‏‏‏‎‎‎‎‏‏‏‏‏‎‎‎‎‏‎‏‎‎‏‏‏‏‎Unlock to use NFC‎‏‎‎‏‎"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‏‏‏‎‎‏‏‏‏‎‎‏‏‎‏‎‎‏‎‏‏‏‏‎‎‎‏‎‏‎‎‏‎‎‏‏‎‏‎‏‏‎‎‏‎‏‏‏‏‎‏‏‏‏‏‎This device belongs to your organization‎‏‎‎‏‎"</string>
diff --git a/packages/SystemUI/res/values-en-rXC/strings_tv.xml b/packages/SystemUI/res/values-en-rXC/strings_tv.xml
index 34882b31129d..c030833a4eaf 100644
--- a/packages/SystemUI/res/values-en-rXC/strings_tv.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‏‏‏‎‎‎‎‎‏‏‎‎‎‏‏‎‏‏‎‎‎‎‎‎‎‎‎‎‎‏‎‏‎‎‏‏‎‎‎‏‎‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‎Via ‎‏‎‎‏‏‎<xliff:g id="VPN_APP">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‎‏‏‎‏‎‎‏‎‏‎‎‏‎‎‏‎‏‏‎‎‏‎‎‏‎‏‏‎‏‎‏‎‎‎‎‎‏‎‎‎‏‏‏‏‎‏‎‎‏‏‏‎‏‎‎Notifications‎‏‎‎‏‎"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‏‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‏‏‎‏‎‎‎‏‎‎‏‎‏‎‎‎‎‏‎‏‏‎‎No Notifications‎‏‎‎‏‎"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‎‎‏‎‏‎‏‏‏‎‎‎‎‎‏‎‏‏‏‎‎‏‎‎‏‎‎‏‎‏‎‏‏‎‏‎‏‎‎‏‎‎‏‎‏‏‏‎‎‏‏‏‏‏‎Microphone is recording‎‏‎‎‏‎"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‏‏‏‎‏‎‎‏‎‎‎‏‏‏‎‏‎‎‎‏‏‎‏‎‎‏‎‎‏‏‏‏‎‎‎‎‏‎‎‏‎‎‎‏‏‎‎‎‎‎‏‎‎‎‎Camera is recording‎‏‎‎‏‎"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‏‎‏‏‎‏‎‎‏‏‎‏‏‎‏‏‎‎‎‏‏‏‎‎‏‎‏‎‎‏‎‏‎‏‎‏‎‏‎‎‎‏‎‎‏‎‏‏‏‏‎‏‏‎Camera and Microphone are recording‎‏‎‎‏‎"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‏‎‏‎‏‎‎‎‏‎‎‎‏‎‏‎‎‏‏‏‎‎‎‏‎‎‎‎‎‏‏‎‏‏‏‏‎‏‎‎‎‏‎‎‎‏‎‎‏‎‏‏‎‏‎‎Microphone stopped recording‎‏‎‎‏‎"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‎‎‎‏‎‏‏‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‎‏‏‏‏‎‎‎‏‎‏‏‏‎‏‎‎‏‎‏‏‎‎‏‏‏‏‎‎‎‎‏‎Camera stopped recording‎‏‎‎‏‎"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‎‏‏‎‏‎‏‏‏‎‎‏‎‎‏‏‏‏‎‏‏‏‎‎‏‎‎‏‎‎‏‏‎‏‎‎‎‎‏‎‎‎‏‎‏‏‏‏‎‎‎‏‎‎‎Camera and Microphone stopped recording‎‏‎‎‏‎"</string>
</resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 55b0f98fc859..c1323ce57994 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Presiona de nuevo para abrir"</string>
<string name="tap_again" msgid="1315420114387908655">"Presiona otra vez"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Desliza el dedo hacia arriba para abrir"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"Presiona para abrir"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Desliza el dedo hacia arriba para volver a intentarlo"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desbloquea el dispositivo para usar NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Este dispositivo pertenece a tu organización"</string>
@@ -534,7 +535,7 @@
<string name="quick_settings_disclosure_named_management_vpns" msgid="4046375645500668555">"Este dispositivo pertenece a <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> y está conectado a VPN"</string>
<string name="quick_settings_disclosure_managed_profile_monitoring" msgid="1423899084754272514">"Tu organización puede controlar el tráfico de red en tu perfil de trabajo"</string>
<string name="quick_settings_disclosure_named_managed_profile_monitoring" msgid="8321469176706219860">"Es posible que <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> controle el tráfico de red en tu perfil de trabajo"</string>
- <string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"El administrador de IT puede ver la actividad de red de tu perfil de trabajo"</string>
+ <string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"El administrador de TI puede ver la actividad de red de tu perfil de trabajo"</string>
<string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Es posible que la red esté supervisada"</string>
<string name="quick_settings_disclosure_vpns" msgid="7213546797022280246">"Este dispositivo está conectado a VPN"</string>
<string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="8117568745060010789">"Tu perfil de trabajo está conectado a <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings_tv.xml b/packages/SystemUI/res/values-es-rUS/strings_tv.xml
index a0a355b8bc7a..f2f06015e366 100644
--- a/packages/SystemUI/res/values-es-rUS/strings_tv.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"A través de <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Notificaciones"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"No hay notificaciones"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"El micrófono está grabando"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"La cámara está grabando"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"La cámara y el micrófono están grabando"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"El micrófono dejó de grabar"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"La cámara dejó de grabar"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"La cámara y el micrófono dejaron de grabar"</string>
</resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index c5096e9c1a35..bcac5cb4e008 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Toca de nuevo para abrir"</string>
<string name="tap_again" msgid="1315420114387908655">"Toca de nuevo"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Desliza el dedo hacia arriba para abrir"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"Pulsa para abrirlo"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Desliza el dedo hacia arriba para volverlo a intentar"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desbloquea para usar el NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Este dispositivo pertenece a tu organización"</string>
diff --git a/packages/SystemUI/res/values-es/strings_tv.xml b/packages/SystemUI/res/values-es/strings_tv.xml
index 4607ad5d4fcb..cc78cf21663d 100644
--- a/packages/SystemUI/res/values-es/strings_tv.xml
+++ b/packages/SystemUI/res/values-es/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"A través de <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Notificaciones"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Sin notificaciones"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"El micrófono está grabando"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"La cámara está grabando"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"La cámara y el micrófono están grabando"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"El micrófono ha dejado de grabar"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"La cámara ha dejado de grabar"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"La cámara y el micrófono han dejado de grabar"</string>
</resources>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index ee7c76039408..83fd5e559023 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Avamiseks puudutage uuesti"</string>
<string name="tap_again" msgid="1315420114387908655">"Puudutage uuesti"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Pühkige avamiseks üles"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"Avamiseks vajutage"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Uuesti proovimiseks pühkige üles"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC kasutamiseks avage."</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"See seade kuulub teie organisatsioonile"</string>
diff --git a/packages/SystemUI/res/values-et/strings_tv.xml b/packages/SystemUI/res/values-et/strings_tv.xml
index 593298efc8d1..6f020c60d9a4 100644
--- a/packages/SystemUI/res/values-et/strings_tv.xml
+++ b/packages/SystemUI/res/values-et/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Teenuse <xliff:g id="VPN_APP">%1$s</xliff:g> kaudu"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Märguanded"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Märguandeid pole"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"Mikrofon salvestab"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"Kaamera salvestab"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Kaamera ja mikrofon salvestavad"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Mikrofon peatas salvestamise"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Kaamera peatas salvestamise"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Kaamera ja mikrofon peatasid salvestamise"</string>
</resources>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 0972c26b9ed1..7a36b9b657c1 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Irekitzeko, ukitu berriro"</string>
<string name="tap_again" msgid="1315420114387908655">"Sakatu berriro"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Pasatu hatza gora irekitzeko"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"Sakatu irekitzeko"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Berriro saiatzeko, pasatu hatza gora"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desblokea ezazu NFC erabiltzeko"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Gailu hau zure erakundearena da"</string>
diff --git a/packages/SystemUI/res/values-eu/strings_tv.xml b/packages/SystemUI/res/values-eu/strings_tv.xml
index e1c4fcc73ee4..c9c30c726c7f 100644
--- a/packages/SystemUI/res/values-eu/strings_tv.xml
+++ b/packages/SystemUI/res/values-eu/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"<xliff:g id="VPN_APP">%1$s</xliff:g> bidez"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Jakinarazpenak"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Ez dago jakinarazpenik"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"Mikrofonoa grabatzen ari da"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"Kamera grabatzen ari da"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Kamera eta mikrofonoa grabatzen ari dira"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Mikrofonoak grabatzeari utzi dio"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Kamerak grabatzeari utzi dio"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Kamerak eta mikrofonoak grabatzeari utzi diote"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 2899e173e11c..f8e1378c4768 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"دوباره ضربه بزنید تا باز شود"</string>
<string name="tap_again" msgid="1315420114387908655">"دوباره ضربه بزنید"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"برای باز کردن، انگشتتان را تند به‌بالا بکشید"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"برای باز کردن فشار دهید"</string>
<string name="keyguard_retry" msgid="886802522584053523">"برای امتحان مجدد، انگشتتان را تند به‌بالا بکشید"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"‏برای استفاده از NFC، قفل را باز کنید"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"این دستگاه به سازمان شما تعلق دارد"</string>
diff --git a/packages/SystemUI/res/values-fa/strings_tv.xml b/packages/SystemUI/res/values-fa/strings_tv.xml
index 5ad12dfd9d53..3ba9b4e5ca2c 100644
--- a/packages/SystemUI/res/values-fa/strings_tv.xml
+++ b/packages/SystemUI/res/values-fa/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"ازطریق <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"اعلان‌ها"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"اعلانی ندارید"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"میکروفون درحال ضبط کردن است"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"دوربین درحال ضبط کردن است"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"دوربین و میکروفون درحال ضبط کردن هستند"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"ضبط میکروفون متوقف شد"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"ضبط دوربین متوقف شد"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"ضبط دوربین و میکروفون متوقف شد"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index dc49957d6773..d4449f1b57f5 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Avaa napauttamalla uudelleen"</string>
<string name="tap_again" msgid="1315420114387908655">"Napauta uudelleen"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Avaa pyyhkäisemällä ylös"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"Avaa painamalla"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Yritä uudelleen pyyhkäisemällä ylös"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"Avaa lukitus, jotta voit käyttää NFC:tä"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Organisaatiosi omistaa tämän laitteen"</string>
diff --git a/packages/SystemUI/res/values-fi/strings_tv.xml b/packages/SystemUI/res/values-fi/strings_tv.xml
index 61cd5ab16d88..63128371c0f0 100644
--- a/packages/SystemUI/res/values-fi/strings_tv.xml
+++ b/packages/SystemUI/res/values-fi/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Palvelun <xliff:g id="VPN_APP">%1$s</xliff:g> kautta"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Ilmoitukset"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Ei ilmoituksia"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"Mikrofoni tallentaa"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"Kamera kuvaa"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Kamera ja mikrofoni tallentavat"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Mikrofoni lopetti tallentamisen"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Kamera lopetti kuvaamisen"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Kamera ja mikrofoni lopettivat tallentamisen"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 83c0ef4da28d..c1dd1046dc6f 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Touchez à nouveau pour ouvrir"</string>
<string name="tap_again" msgid="1315420114387908655">"Toucher de nouveau"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Balayez l\'écran vers le haut pour ouvrir"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"Appuyez pour ouvrir"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Balayez l\'écran vers le haut pour réessayer"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"Déverrouillez l\'écran pour utiliser la CCP"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Cet appareil appartient à votre organisation"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings_tv.xml b/packages/SystemUI/res/values-fr-rCA/strings_tv.xml
index a667d76a834a..0925abeb5a00 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings_tv.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Par <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Notifications"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Aucune notification"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"Le microphone enregistre"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"L\'appareil photo enregistre"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"L\'appareil photo et le microphone enregistrent"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Le microphone a arrêté l\'enregistrement"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"L\'appareil photo a arrêté l\'enregistrement"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"L\'appareil photo et le microphone ont arrêté l\'enregistrement"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index bb3183e3761b..c06c62f004a9 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Appuyer à nouveau pour ouvrir"</string>
<string name="tap_again" msgid="1315420114387908655">"Appuyer à nouveau"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Balayer vers le haut pour ouvrir"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"Appuyez pour ouvrir"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Balayez l\'écran vers le haut pour réessayer"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"Déverrouillez l\'écran pour pouvoir utiliser NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Cet appareil appartient à votre organisation"</string>
diff --git a/packages/SystemUI/res/values-fr/strings_tv.xml b/packages/SystemUI/res/values-fr/strings_tv.xml
index 25fab4e5d6d9..3a33aad577e3 100644
--- a/packages/SystemUI/res/values-fr/strings_tv.xml
+++ b/packages/SystemUI/res/values-fr/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Via <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Notifications"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Aucune notification"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"Le micro enregistre…"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"La caméra enregistre…"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"La caméra et le micro enregistrent…"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Le micro a arrêté l\'enregistrement"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"La caméra a arrêté l\'enregistrement"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"La caméra et le micro ont arrêté l\'enregistrement"</string>
</resources>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index d8fe4b8249d1..f70dd3cbe4c4 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Toca de novo para abrir"</string>
<string name="tap_again" msgid="1315420114387908655">"Toca de novo"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Pasa o dedo cara arriba para abrir"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"Preme para abrir"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Pasa o dedo cara arriba para tentalo de novo"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desbloquea o dispositivo para utilizar a NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Este dispositivo pertence á túa organización."</string>
diff --git a/packages/SystemUI/res/values-gl/strings_tv.xml b/packages/SystemUI/res/values-gl/strings_tv.xml
index cd12b94e779d..679c21da5032 100644
--- a/packages/SystemUI/res/values-gl/strings_tv.xml
+++ b/packages/SystemUI/res/values-gl/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"A través de <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Notificacións"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Non hai notificacións"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"O micrófono está gravando"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"A cámara está gravando"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"A cámara e o micrófono están gravando"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"O micrófono deixou de gravar"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"A cámara deixou de gravar"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"A cámara e o micrófono deixaron de gravar"</string>
</resources>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 408e79827d32..fe16c9593e9f 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -230,7 +230,7 @@
<string name="accessibility_battery_level" msgid="5143715405241138822">"બૅટરી <xliff:g id="NUMBER">%d</xliff:g> ટકા."</string>
<string name="accessibility_battery_level_with_estimate" msgid="4843119982547599452">"તમારા વપરાશના આધારે બૅટરી <xliff:g id="PERCENTAGE">%1$s</xliff:g> ટકા, જે લગભગ <xliff:g id="TIME">%2$s</xliff:g> સુધી ચાલે તેટલી બચી છે"</string>
<string name="accessibility_battery_level_charging" msgid="8892191177774027364">"બૅટરી ચાર્જ થઈ રહી છે, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
- <string name="accessibility_settings_button" msgid="2197034218538913880">"સિસ્ટમ સેટિંગ્સ."</string>
+ <string name="accessibility_settings_button" msgid="2197034218538913880">"સિસ્ટમ સેટિંગ."</string>
<string name="accessibility_notifications_button" msgid="3960913924189228831">"નોટિફિકેશન."</string>
<string name="accessibility_overflow_action" msgid="8555835828182509104">"બધી સૂચના જુઓ"</string>
<string name="accessibility_remove_notification" msgid="1641455251495815527">"સૂચના સાફ કરો."</string>
@@ -245,7 +245,7 @@
<skip />
<string name="accessibility_notification_dismissed" msgid="4411652015138892952">"સૂચના કાઢી નાખી."</string>
<string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"નોટિફિકેશન શેડ."</string>
- <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"ઝડપી સેટિંગ્સ."</string>
+ <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"ઝડપી સેટિંગ."</string>
<string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"લૉક સ્ક્રીન."</string>
<string name="accessibility_desc_settings" msgid="6728577365389151969">"સેટિંગ"</string>
<string name="accessibility_desc_recent_apps" msgid="1748675199348914194">"ઝલક."</string>
@@ -315,7 +315,7 @@
<item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> વધુ સૂચના અંદર છે.</item>
</plurals>
<string name="notification_summary_message_format" msgid="5158219088501909966">"<xliff:g id="CONTACT_NAME">%1$s</xliff:g>: <xliff:g id="MESSAGE_CONTENT">%2$s</xliff:g>"</string>
- <string name="status_bar_notification_inspect_item_title" msgid="6818779631806163080">"સૂચનાઓની સેટિંગ્સ"</string>
+ <string name="status_bar_notification_inspect_item_title" msgid="6818779631806163080">"નોટિફિકેશન સેટિંગ"</string>
<string name="status_bar_notification_app_settings_title" msgid="5050006438806013903">"<xliff:g id="APP_NAME">%s</xliff:g> સેટિંગ"</string>
<string name="accessibility_rotation_lock_off" msgid="3880436123632448930">"સ્ક્રીન ઑટોમૅટિક રીતે ફરશે."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"સ્ક્રીન લેન્ડસ્કેપ ઓરિએન્ટેશનમાં લૉક કરેલ છે."</string>
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"ખોલવા માટે ફરીથી ટૅપ કરો"</string>
<string name="tap_again" msgid="1315420114387908655">"ફરીથી ટૅપ કરો"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"ખોલવા માટે ઉપરની તરફ સ્વાઇપ કરો"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"અનલૉક કરવા માટે દબાવો"</string>
<string name="keyguard_retry" msgid="886802522584053523">"ફરી પ્રયાસ કરવા માટે ઉપરની તરફ સ્વાઇપ કરો"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFCનો ઉપયોગ કરવા માટે અનલૉક કરો"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"આ ડિવાઇસ તમારી સંસ્થાની માલિકીનું છે"</string>
@@ -565,12 +566,12 @@
<string name="monitoring_description_personal_profile_named_vpn" msgid="8179722332380953673">"તમારી વ્યક્તિગત પ્રોફાઇલ <xliff:g id="VPN_APP">%1$s</xliff:g> સાથે કનેક્ટ કરેલ છે, જે ઇમેઇલ, ઍપ્લિકેશનો અને વેબસાઇટો સહિતની તમારી નેટવર્ક પ્રવૃત્તિનું નિયમન કરી શકે છે."</string>
<string name="monitoring_description_do_header_generic" msgid="6130190408164834986">"તમારું ડિવાઇસ <xliff:g id="DEVICE_OWNER_APP">%1$s</xliff:g> દ્વારા મેનેજ થાય છે."</string>
<string name="monitoring_description_do_header_with_name" msgid="2696255132542779511">"<xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>, તમારા ઉપકરણનું સંચાલન કરવા માટે <xliff:g id="DEVICE_OWNER_APP">%2$s</xliff:g> નો ઉપયોગ કરે છે."</string>
- <string name="monitoring_description_do_body" msgid="7700878065625769970">"વ્યવસ્થાપક સેટિંગ્સ, કૉર્પોરેટ ઍક્સેસ, ઍપ્સ, તમારા ઉપકરણ સંબંદ્ધ ડેટા અને ઉપકરણની સ્થાન માહિતીનું નિરીક્ષણ અને સંચાલન કરી શકે છે."</string>
+ <string name="monitoring_description_do_body" msgid="7700878065625769970">"વ્યવસ્થાપક સેટિંગ, કૉર્પોરેટ ઍક્સેસ, ઍપ, તમારા ડિવાઇસ સંબંધિત ડેટા અને ડિવાઇસની સ્થાન માહિતીને મૉનિટર અને મેનેજ કરી શકે છે."</string>
<string name="monitoring_description_do_learn_more_separator" msgid="1467280496376492558">" "</string>
<string name="monitoring_description_do_learn_more" msgid="645149183455573790">"વધુ જાણો"</string>
<string name="monitoring_description_do_body_vpn" msgid="7699280130070502303">"તમે <xliff:g id="VPN_APP">%1$s</xliff:g> સાથે કનેક્ટ થયાં છો, જે ઇમેઇલ્સ, ઍપ્લિકેશનો અને વેબસાઇટ્સ સહિત તમારી નેટવર્ક પ્રવૃત્તિને મૉનિટર કરી શકે છે."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
- <string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"VPNની સેટિંગ્સ ખોલો"</string>
+ <string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"VPN સેટિંગ ખોલો"</string>
<string name="monitoring_description_ca_cert_settings_separator" msgid="7107390013344435439">" "</string>
<string name="monitoring_description_ca_cert_settings" msgid="8329781950135541003">"વિશ્વસનીય ઓળખપત્ર ખોલો"</string>
<string name="monitoring_description_network_logging" msgid="577305979174002252">"તમારા વ્યવસ્થાપકે નેટવર્ક લૉગિંગ ચાલુ કર્યુ છે, જે તમારા ઉપકરણ પર ટ્રાફિકનું નિરીક્ષણ કરે છે.\n\nવધુ માહિતી માટે, તમારા વ્યવસ્થાપકનો સંપર્ક કરો."</string>
@@ -617,7 +618,7 @@
<string name="screen_pinning_start" msgid="7483998671383371313">"ઍપ પિન કરી"</string>
<string name="screen_pinning_exit" msgid="4553787518387346893">"ઍપ અનપિન કરી"</string>
<string name="quick_settings_reset_confirmation_title" msgid="463533331480997595">"<xliff:g id="TILE_LABEL">%1$s</xliff:g> ને છુપાવીએ?"</string>
- <string name="quick_settings_reset_confirmation_message" msgid="2320586180785674186">"તે સેટિંગ્સમાં તમે તેને ચાલુ કરશો ત્યારે આગલી વખતે ફરીથી દેખાશે."</string>
+ <string name="quick_settings_reset_confirmation_message" msgid="2320586180785674186">"તે સેટિંગમાં તમે તેને ચાલુ કરશો ત્યારે આગલી વખતે ફરીથી દેખાશે."</string>
<string name="quick_settings_reset_confirmation_button" msgid="3341477479055016776">"છુપાવો"</string>
<string name="stream_voice_call" msgid="7468348170702375660">"કૉલ કરો"</string>
<string name="stream_system" msgid="7663148785370565134">"સિસ્ટમ"</string>
@@ -655,7 +656,7 @@
<string name="system_ui_tuner" msgid="1471348823289954729">"સિસ્ટમ UI ટ્યૂનર"</string>
<string name="show_battery_percentage" msgid="6235377891802910455">"એમ્બેડ કરેલ બૅટરી ટકા બતાવો"</string>
<string name="show_battery_percentage_summary" msgid="9053024758304102915">"જ્યારે ચાર્જ ન થઈ રહ્યું હોય ત્યારે સ્ટેટસ બાર આયકનની અંદર બૅટરી સ્તર ટકા બતાવો"</string>
- <string name="quick_settings" msgid="6211774484997470203">"ઝડપી સેટિંગ્સ"</string>
+ <string name="quick_settings" msgid="6211774484997470203">"ઝડપી સેટિંગ"</string>
<string name="status_bar" msgid="4357390266055077437">"સ્ટેટસ બાર"</string>
<string name="overview" msgid="3522318590458536816">"ઝલક"</string>
<string name="demo_mode" msgid="263484519766901593">"સિસ્ટમ UI ડેમો મોડ"</string>
@@ -680,21 +681,21 @@
<string name="zen_alarm_warning" msgid="7844303238486849503">"તમે <xliff:g id="WHEN">%1$s</xliff:g> એ તમારો આગલો એલાર્મ સાંભળશો નહીં"</string>
<string name="alarm_template" msgid="2234991538018805736">"<xliff:g id="WHEN">%1$s</xliff:g> વાગ્યે"</string>
<string name="alarm_template_far" msgid="3561752195856839456">"<xliff:g id="WHEN">%1$s</xliff:g> એ"</string>
- <string name="accessibility_quick_settings_detail" msgid="544463655956179791">"ઝડપી સેટિંગ્સ, <xliff:g id="TITLE">%s</xliff:g>."</string>
+ <string name="accessibility_quick_settings_detail" msgid="544463655956179791">"ઝડપી સેટિંગ, <xliff:g id="TITLE">%s</xliff:g>."</string>
<string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"હૉટસ્પૉટ"</string>
<string name="accessibility_managed_profile" msgid="4703836746209377356">"ઑફિસની પ્રોફાઇલ"</string>
<string name="tuner_warning_title" msgid="7721976098452135267">"કેટલાક માટે મજા પરંતુ બધા માટે નહીં"</string>
<string name="tuner_warning" msgid="1861736288458481650">"સિસ્ટમ UI ટ્યૂનર તમને Android વપરાશકર્તા ઇન્ટરફેસને ટ્વીક અને કસ્ટમાઇઝ કરવાની વધારાની રીતો આપે છે. ભાવિ રીલિઝેસમાં આ પ્રાયોગિક સુવિધાઓ બદલાઈ, ભંગ અથવા અદૃશ્ય થઈ શકે છે. સાવધાની સાથે આગળ વધો."</string>
<string name="tuner_persistent_warning" msgid="230466285569307806">"ભાવિ રીલિઝેસમાં આ પ્રાયોગિક સુવિધાઓ બદલાઈ, ભંગ અથવા અદૃશ્ય થઈ શકે છે. સાવધાની સાથે આગળ વધો."</string>
<string name="got_it" msgid="477119182261892069">"સમજાઈ ગયું"</string>
- <string name="tuner_toast" msgid="3812684836514766951">"અભિનંદન! સિસ્ટમ UI ટ્યૂનરને સેટિંગ્સમાં ઉમેરવામાં આવ્યું છે"</string>
- <string name="remove_from_settings" msgid="633775561782209994">"સેટિંગ્સમાંથી દૂર કરો"</string>
- <string name="remove_from_settings_prompt" msgid="551565437265615426">"સેટિંગ્સમાંથી સિસ્ટમ UI ટ્યૂનર દૂર કરી અને તેની તમામ સુવિધાઓનો ઉપયોગ કરવાનું બંધ કરીએ?"</string>
+ <string name="tuner_toast" msgid="3812684836514766951">"અભિનંદન! સિસ્ટમ UI ટ્યૂનરને સેટિંગમાં ઉમેરવામાં આવ્યું છે"</string>
+ <string name="remove_from_settings" msgid="633775561782209994">"સેટિંગમાંથી કાઢી નાખો"</string>
+ <string name="remove_from_settings_prompt" msgid="551565437265615426">"સેટિંગમાંથી સિસ્ટમ UI ટ્યૂનર કાઢી નાખી અને તેની તમામ સુવિધાઓનો ઉપયોગ કરવાનું બંધ કરીએ?"</string>
<string name="activity_not_found" msgid="8711661533828200293">"તમારા ઉપકરણ પર ઍપ્લિકેશન ઇન્સ્ટોલ થયેલ નથી"</string>
<string name="clock_seconds" msgid="8709189470828542071">"ઘડિયાળ સેકન્ડ બતાવો"</string>
<string name="clock_seconds_desc" msgid="2415312788902144817">"ઘડિયાળ સેકન્ડ સ્થિતિ બારમાં બતાવો. બૅટરીની આવરદા પર અસર કરી શકે છે."</string>
- <string name="qs_rearrange" msgid="484816665478662911">"ઝડપી સેટિંગ્સને ફરીથી ગોઠવો"</string>
- <string name="show_brightness" msgid="6700267491672470007">"ઝડપી સેટિંગ્સમાં તેજ બતાવો"</string>
+ <string name="qs_rearrange" msgid="484816665478662911">"ઝડપી સેટિંગને ફરીથી ગોઠવો"</string>
+ <string name="show_brightness" msgid="6700267491672470007">"ઝડપી સેટિંગમાં બ્રાઇટનેસ બતાવો"</string>
<string name="experimental" msgid="3549865454812314826">"પ્રાયોગિક"</string>
<string name="enable_bluetooth_title" msgid="866883307336662596">"બ્લૂટૂથ ચાલુ કરવુ છે?"</string>
<string name="enable_bluetooth_message" msgid="6740938333772779717">"તમારા ટેબ્લેટ સાથે કીબોર્ડ કનેક્ટ કરવા માટે, તમારે પહેલાં બ્લૂટૂથ ચાલુ કરવાની જરૂર પડશે."</string>
@@ -916,19 +917,19 @@
<string name="accessibility_qs_edit_position" msgid="4509277359815711830">"જગ્યા <xliff:g id="POSITION">%1$d</xliff:g>"</string>
<string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"ટાઇલ ઉમેરી"</string>
<string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"ટાઇલ કાઢી નાખી"</string>
- <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ઝડપી સેટિંગ્સ સંપાદક."</string>
+ <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ઝડપી સેટિંગ એડિટર."</string>
<string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"<xliff:g id="ID_1">%1$s</xliff:g> નોટિફિકેશન: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
- <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"સેટિંગ્સ ખોલો."</string>
- <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"ઝડપી સેટિંગ્સ ખોલો."</string>
- <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"ઝડપી સેટિંગ્સ બંધ કરો."</string>
+ <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"સેટિંગ ખોલો."</string>
+ <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"ઝડપી સેટિંગ ખોલો."</string>
+ <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"ઝડપી સેટિંગ બંધ કરો."</string>
<string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"એલાર્મ સેટ કર્યો."</string>
<string name="accessibility_quick_settings_user" msgid="505821942882668619">"<xliff:g id="ID_1">%s</xliff:g> તરીકે સાઇન ઇન કર્યું"</string>
<string name="accessibility_quick_settings_choose_user_action" msgid="4554388498186576087">"વપરાશકર્તા પસંદ કરો"</string>
<string name="data_connection_no_internet" msgid="691058178914184544">"કોઈ ઇન્ટરનેટ નથી"</string>
<string name="accessibility_quick_settings_open_details" msgid="4879279912389052142">"વિગતો ખોલો."</string>
<string name="accessibility_quick_settings_not_available" msgid="6860875849497473854">"<xliff:g id="REASON">%s</xliff:g>ને કારણે અનુપલબ્ધ છે"</string>
- <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g> સેટિંગ્સ ખોલો."</string>
- <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"સેટિંગ્સનો ક્રમ સંપાદિત કરો."</string>
+ <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"<xliff:g id="ID_1">%s</xliff:g> સેટિંગ ખોલો."</string>
+ <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"સેટિંગના ક્રમમાં ફેરફાર કરો."</string>
<string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"પાવર મેનૂ"</string>
<string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g> માંથી <xliff:g id="ID_1">%1$d</xliff:g> પૃષ્ઠ"</string>
<string name="tuner_lock_screen" msgid="2267383813241144544">"લૉક સ્ક્રીન"</string>
@@ -986,7 +987,7 @@
<string name="mobile_data_disable_title" msgid="5366476131671617790">"મોબાઇલ ડેટા બંધ કરીએ?"</string>
<string name="mobile_data_disable_message" msgid="8604966027899770415">"તમને <xliff:g id="CARRIER">%s</xliff:g> મારફતે ડેટા અથવા ઇન્ટરનેટનો ઍક્સેસ મળશે નહીં. ઇન્ટરનેટ માત્ર વાઇ-ફાઇ દ્વારા ઉપલબ્ધ થશે."</string>
<string name="mobile_data_disable_message_default_carrier" msgid="6496033312431658238">"તમારા કૅરિઅર"</string>
- <string name="touch_filtered_warning" msgid="8119511393338714836">"એક ઍપ પરવાનગી વિનંતીને અસ્પષ્ટ કરતી હોવાને કારણે, સેટિંગ્સ તમારા પ્રતિસાદને ચકાસી શકતી નથી."</string>
+ <string name="touch_filtered_warning" msgid="8119511393338714836">"કોઈ ઍપ પરવાનગી વિનંતીને અસ્પષ્ટ કરતી હોવાને કારણે, સેટિંગ તમારા પ્રતિસાદને ચકાસી શકતું નથી."</string>
<string name="slice_permission_title" msgid="3262615140094151017">"<xliff:g id="APP_0">%1$s</xliff:g>ને <xliff:g id="APP_2">%2$s</xliff:g> સ્લાઇસ બતાવવાની મંજૂરી આપીએ?"</string>
<string name="slice_permission_text_1" msgid="6675965177075443714">"- મારાથી <xliff:g id="APP">%1$s</xliff:g>ની માહિતી વાંચી શકાતી નથી"</string>
<string name="slice_permission_text_2" msgid="6758906940360746983">"- મારાથી <xliff:g id="APP">%1$s</xliff:g>ની અંદર ક્રિયાઓ કરી શકાતી નથી"</string>
diff --git a/packages/SystemUI/res/values-gu/strings_tv.xml b/packages/SystemUI/res/values-gu/strings_tv.xml
index a53e9838b4a0..e22650386327 100644
--- a/packages/SystemUI/res/values-gu/strings_tv.xml
+++ b/packages/SystemUI/res/values-gu/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"<xliff:g id="VPN_APP">%1$s</xliff:g> મારફતે"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"નોટિફિકેશન"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"કોઈ નોટિફિકેશન નથી"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"માઇક્રોફોનનું રેકોર્ડિંગ ચાલુ છે"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"કૅમેરાનું રેકોર્ડિંગ ચાલુ છે"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"કૅમેરા અને માઇક્રોફોનનું રેકોર્ડિંગ ચાલુ છે"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"માઇક્રોફોનનું રેકોર્ડિંગ બંધ થઈ ગયું"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"કૅમેરાનું રેકોર્ડિંગ બંધ થઈ ગયું"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"કૅમેરા અને માઇક્રોફોનનું રેકોર્ડિંગ બંધ થઈ ગયું"</string>
</resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index ac4a9035f3d3..464a7976b80c 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"खोलने के लिए फिर से टैप करें"</string>
<string name="tap_again" msgid="1315420114387908655">"फिर से टैप करें"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"खोलने के लिए ऊपर स्वाइप करें"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"अनलॉक करने के लिए दबाएं"</string>
<string name="keyguard_retry" msgid="886802522584053523">"फिर से कोशिश करने के लिए ऊपर की ओर स्वाइप करें"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"एनएफ़सी इस्तेमाल करने के लिए स्क्रीन को अनलॉक करें"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"इस डिवाइस का मालिकाना हक आपके संगठन के पास है"</string>
diff --git a/packages/SystemUI/res/values-hi/strings_tv.xml b/packages/SystemUI/res/values-hi/strings_tv.xml
index fedaae3f4710..cc9a56251098 100644
--- a/packages/SystemUI/res/values-hi/strings_tv.xml
+++ b/packages/SystemUI/res/values-hi/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"<xliff:g id="VPN_APP">%1$s</xliff:g> के ज़रिए"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"सूचनाएं"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"कोई सूचना नहीं है"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"माइक्रोफ़ोन रिकॉर्ड कर रहा है"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"कैमरा रिकॉर्ड कर रहा है"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"कैमरा और माइक्रोफ़ोन रिकॉर्ड कर रहे हैं"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"माइक्रोफ़ोन ने रिकॉर्ड करना बंद कर दिया है"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"कैमरे ने रिकॉर्ड करना बंद कर दिया है"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"कैमरे और माइक्रोफ़ोन ने रिकॉर्ड करना बंद कर दिया है"</string>
</resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 571ca2427e35..118927a0d411 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -454,6 +454,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Dodirnite opet za otvaranje"</string>
<string name="tap_again" msgid="1315420114387908655">"Dodirnite ponovo"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Prijeđite prstom prema gore da biste otvorili"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"Pritisnite da biste otvorili"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Prijeđite prstom prema gore za ponovni pokušaj"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"Otključajte da biste upotrijebili NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Ovaj uređaj pripada vašoj organizaciji"</string>
diff --git a/packages/SystemUI/res/values-hr/strings_tv.xml b/packages/SystemUI/res/values-hr/strings_tv.xml
index 3bfdf7038018..633847c8d3ca 100644
--- a/packages/SystemUI/res/values-hr/strings_tv.xml
+++ b/packages/SystemUI/res/values-hr/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Putem mreže <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Obavijesti"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Nema obavijesti"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"Mikrofon snima"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"Kamera snima"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Kamera i mikrofon snimaju"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Mikrofon je prestao snimati"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Kamera je prestala snimati"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Kamera i mikrofon prestali su snimati"</string>
</resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 9a7ca9d6d3a5..6ee8db5770ff 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Koppintson ismét a megnyitáshoz"</string>
<string name="tap_again" msgid="1315420114387908655">"Koppintson újra"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Csúsztasson felfelé a megnyitáshoz"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"A megnyitáshoz nyomja meg"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Az újrapróbálkozáshoz csúsztassa felfelé az ujját"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"Az NFC használatához oldja fel a képernyőzárat"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Ez az eszköz az Ön szervezetének tulajdonában van"</string>
diff --git a/packages/SystemUI/res/values-hu/strings_tv.xml b/packages/SystemUI/res/values-hu/strings_tv.xml
index 91183af142a5..97c375aff4bd 100644
--- a/packages/SystemUI/res/values-hu/strings_tv.xml
+++ b/packages/SystemUI/res/values-hu/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Ezzel: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Értesítések"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Nincs értesítés"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"A mikrofon felvételt készít…"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"A kamera felvételt készít…"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"A kamera és a mikrofon felvételt készít…"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"A mikrofon befejezte a felvételkészítést"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"A kamera befejezte a felvételkészítést"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"A kamera és a mikrofon befejezte a felvételkészítést"</string>
</resources>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 74ab34df000b..982527716a4d 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Կրկին հպեք՝ բացելու համար"</string>
<string name="tap_again" msgid="1315420114387908655">"Նորից հպեք"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Բացելու համար սահեցրեք վերև"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"Սեղմեք՝ բացելու համար"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Սահեցրեք վերև՝ նորից փորձելու համար"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"Ապակողպեք՝ NFC-ն օգտագործելու համար"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Այս սարքը պատկանում է ձեր կազմակերպությանը"</string>
diff --git a/packages/SystemUI/res/values-hy/strings_tv.xml b/packages/SystemUI/res/values-hy/strings_tv.xml
index cf4eb90faff2..3f46b901d150 100644
--- a/packages/SystemUI/res/values-hy/strings_tv.xml
+++ b/packages/SystemUI/res/values-hy/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"<xliff:g id="VPN_APP">%1$s</xliff:g>-ի միջոցով"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Ծանուցումներ"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Ծանուցումներ չկան"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"Խոսափողը ձայնագրում է"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"Տեսախցիկը տեսագրում է"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Տեսախցիկն ու խոսափողը տեսաձայնագրում են"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Խոսափողն այլևս չի ձայնագրում"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Տեսախցիկն այլևս չի տեսագրում"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Տեսախցիկն ու խոսափողը այլևս չեն տեսաձայնագրում"</string>
</resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 204484c8b58a..0e056bba8df9 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Ketuk lagi untuk membuka"</string>
<string name="tap_again" msgid="1315420114387908655">"Ketuk lagi"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Geser ke atas untuk membuka"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"Tekan untuk membuka"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Geser ke atas untuk mencoba lagi"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"Buka kunci untuk menggunakan NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Perangkat ini milik organisasi Anda"</string>
diff --git a/packages/SystemUI/res/values-in/strings_tv.xml b/packages/SystemUI/res/values-in/strings_tv.xml
index 3b446ad23ed5..d58cdc89832e 100644
--- a/packages/SystemUI/res/values-in/strings_tv.xml
+++ b/packages/SystemUI/res/values-in/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Melalui <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Notifikasi"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Tidak Ada Notifikasi"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"Mikrofon sedang merekam"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"Kamera sedang merekam"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Kamera dan Mikrofon sedang merekam"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Mikrofon berhenti merekam"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Kamera berhenti merekam"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Kamera dan Mikrofon berhenti merekam"</string>
</resources>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index 5afc8bc41f34..fa3310b228db 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Ýttu aftur til að opna"</string>
<string name="tap_again" msgid="1315420114387908655">"Ýttu aftur"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Strjúktu upp til að opna"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"Ýttu til að opna"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Strjúktu upp til að reyna aftur"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"Taktu úr lás til að nota NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Þetta tæki tilheyrir fyrirtækinu þínu"</string>
diff --git a/packages/SystemUI/res/values-is/strings_tv.xml b/packages/SystemUI/res/values-is/strings_tv.xml
index 7c23e62dfdcf..eb0f45016113 100644
--- a/packages/SystemUI/res/values-is/strings_tv.xml
+++ b/packages/SystemUI/res/values-is/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Í gegnum <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Tilkynningar"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Engar tilkynningar"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"Hljóðnemi er að taka upp"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"Myndavél er að taka upp"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Myndavél og hljóðnemi eru að taka upp"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Hljóðnemi er hættur að taka upp"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Myndavél er hætt að taka upp"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Myndavél og hljóðnemi eru hætt að taka upp"</string>
</resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 9c283634b81e..abf708f2da7f 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Tocca ancora per aprire"</string>
<string name="tap_again" msgid="1315420114387908655">"Tocca di nuovo"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Scorri verso l\'alto per aprire"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"Premi per aprire"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Scorri verso l\'alto per riprovare"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"Sblocca per usare NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Questo dispositivo appartiene alla tua organizzazione"</string>
diff --git a/packages/SystemUI/res/values-it/strings_tv.xml b/packages/SystemUI/res/values-it/strings_tv.xml
index 57931b02d58a..45d336923acb 100644
--- a/packages/SystemUI/res/values-it/strings_tv.xml
+++ b/packages/SystemUI/res/values-it/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Tramite <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Notifiche"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Nessuna notifica"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"Registrazione in corso con il microfono"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"Registrazione in corso con la fotocamera"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Registrazione in corso con fotocamera e microfono"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Registrazione con il microfono interrotta"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Registrazione con la fotocamera interrotta"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Registrazione con fotocamera e microfono interrotta"</string>
</resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index b7153b12ff3e..f03420270737 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -456,6 +456,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"יש להקיש שוב כדי לפתוח את ההתראה"</string>
<string name="tap_again" msgid="1315420114387908655">"צריך להקיש פעם נוספת"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"צריך להחליק כדי לפתוח"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"יש להקיש כדי לפתוח"</string>
<string name="keyguard_retry" msgid="886802522584053523">"יש להחליק למעלה כדי לנסות שוב"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"‏יש לבטל את הנעילה כדי להשתמש ב-NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"המכשיר הזה שייך לארגון שלך"</string>
diff --git a/packages/SystemUI/res/values-iw/strings_tv.xml b/packages/SystemUI/res/values-iw/strings_tv.xml
index f01321efc967..5c091d35bfd3 100644
--- a/packages/SystemUI/res/values-iw/strings_tv.xml
+++ b/packages/SystemUI/res/values-iw/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"דרך <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"התראות"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"אין התראות"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"המיקרופון מקליט"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"המצלמה מקליטה"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"המצלמה והמיקרופון מקליטים"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"המיקרופון הפסיק להקליט"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"המצלמה הפסיקה להקליט"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"המצלמה והמיקרופון הפסיקו להקליט"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index a8fb87d40e1a..7d00c5be4d44 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"開くにはもう一度タップしてください"</string>
<string name="tap_again" msgid="1315420114387908655">"もう一度タップしてください"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"開くには上にスワイプします"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"押すと開きます"</string>
<string name="keyguard_retry" msgid="886802522584053523">"上にスワイプしてもう一度お試しください"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC を使用するには、ロックを解除してください"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"これは組織が所有するデバイスです"</string>
diff --git a/packages/SystemUI/res/values-ja/strings_tv.xml b/packages/SystemUI/res/values-ja/strings_tv.xml
index 7f676b5acbe2..c37958f2b02a 100644
--- a/packages/SystemUI/res/values-ja/strings_tv.xml
+++ b/packages/SystemUI/res/values-ja/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"<xliff:g id="VPN_APP">%1$s</xliff:g> 経由"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"通知"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"通知はありません"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"マイクで録音しています"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"カメラで録画しています"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"カメラとマイクで録画、録音しています"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"マイクが録音を停止しました"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"カメラが録画を停止しました"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"カメラとマイクが録画、録音を停止しました"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index da4f5bc855f6..4363876e5e6c 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"შეეხეთ ისევ გასახსნელად"</string>
<string name="tap_again" msgid="1315420114387908655">"შეეხეთ ხელახლა"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"გასახსნელად გადაფურცლეთ ზემოთ"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"დააჭირეთ გასახსნელად"</string>
<string name="keyguard_retry" msgid="886802522584053523">"ხელახლა საცდელად გადაფურცლეთ ზემოთ"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"განბლოკეთ NFC-ის გამოსაყენებლად"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"ამ მოწყობილობას ფლობს თქვენი ორგანიზაცია"</string>
diff --git a/packages/SystemUI/res/values-ka/strings_tv.xml b/packages/SystemUI/res/values-ka/strings_tv.xml
index 081978125ee3..8db4b1be7da1 100644
--- a/packages/SystemUI/res/values-ka/strings_tv.xml
+++ b/packages/SystemUI/res/values-ka/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"<xliff:g id="VPN_APP">%1$s</xliff:g>-ის მიერ"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"შეტყობინებები"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"შეტყობინებები არ არის"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"მიკროფონი იწერს"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"კამერა იწერს"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"კამერა და მიკროფონი იწერს"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"მიკროფონმა ჩაწერა შეწყვიტა"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"კამერამ ჩაწერა შეწყვიტა"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"კამერამ და მიკროფონმა ჩაწერა შეწყვიტა"</string>
</resources>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index c15c6be99669..6dc3b327d0a9 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Ашу үшін қайта түртіңіз"</string>
<string name="tap_again" msgid="1315420114387908655">"Қайта түртіңіз."</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Ашу үшін жоғары қарай сырғытыңыз."</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"Ашу үшін басыңыз."</string>
<string name="keyguard_retry" msgid="886802522584053523">"Әрекетті қайталау үшін жоғары сырғытыңыз."</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC пайдалану үшін құлыпты ашыңыз."</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Бұл құрылғы ұйымыңызға тиесілі."</string>
diff --git a/packages/SystemUI/res/values-kk/strings_tv.xml b/packages/SystemUI/res/values-kk/strings_tv.xml
index 768e3ac19316..a56b4aad9731 100644
--- a/packages/SystemUI/res/values-kk/strings_tv.xml
+++ b/packages/SystemUI/res/values-kk/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"<xliff:g id="VPN_APP">%1$s</xliff:g> арқылы жалғанған"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Хабарландырулар"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Хабарландырулар жоқ"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"Микрофон жазып жатыр."</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"Камера жазып жатыр."</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Камера мен микрофон жазып жатыр."</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Микрофон жазуды тоқтатты."</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Камера жазуды тоқтатты."</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Камера мен микрофон жазуды тоқтатты."</string>
</resources>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 31de2be76e46..9210e624de69 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"ប៉ះ​ម្ដង​ទៀត ដើម្បី​បើក"</string>
<string name="tap_again" msgid="1315420114387908655">"ចុច​ម្ដងទៀត"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"អូសឡើងលើ​ដើម្បីបើក"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"ចុច ដើម្បីបើក"</string>
<string name="keyguard_retry" msgid="886802522584053523">"អូសឡើងលើ ដើម្បី​ព្យាយាម​ម្ដងទៀត"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"ដោះសោ ដើម្បីប្រើ NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"ឧបករណ៍​នេះគឺជា​កម្មសិទ្ធិរបស់​ស្ថាប័ន​អ្នក"</string>
diff --git a/packages/SystemUI/res/values-km/strings_tv.xml b/packages/SystemUI/res/values-km/strings_tv.xml
index 0dec2d65e5bf..c654e6d770c5 100644
--- a/packages/SystemUI/res/values-km/strings_tv.xml
+++ b/packages/SystemUI/res/values-km/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"តាម​រយៈ <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"ការ​ជូនដំណឹង"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"គ្មាន​ការជូនដំណឹងទេ"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"មីក្រូហ្វូនកំពុងថត"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"កាមេរ៉ាកំពុងថត"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"កាមេរ៉ា និងមីក្រូហ្វូនកំពុងថត"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"មីក្រូហ្វូនបានឈប់ថត"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"កាមេរ៉ាបានឈប់ថត"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"កាមេរ៉ា និងមីក្រូហ្វូនបានឈប់ថត"</string>
</resources>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index 9b9138c44119..e32bddd6534b 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"ತೆರೆಯಲು ಮತ್ತೆ ಟ್ಯಾಪ್‌ ಮಾಡಿ"</string>
<string name="tap_again" msgid="1315420114387908655">"ಪುನಃ ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"ತೆರೆಯಲು ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"ತೆರೆಯಲು ಒತ್ತಿ"</string>
<string name="keyguard_retry" msgid="886802522584053523">"ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಲು ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC ಬಳಸಲು ಅನ್‌ಲಾಕ್ ಮಾಡಿ"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"ಈ ಸಾಧನವು ನಿಮ್ಮ ಸಂಸ್ಥೆಗೆ ಸೇರಿದೆ"</string>
diff --git a/packages/SystemUI/res/values-kn/strings_tv.xml b/packages/SystemUI/res/values-kn/strings_tv.xml
index ef10e3a2a664..3955a09deac3 100644
--- a/packages/SystemUI/res/values-kn/strings_tv.xml
+++ b/packages/SystemUI/res/values-kn/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"<xliff:g id="VPN_APP">%1$s</xliff:g> ಮೂಲಕ"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"ಅಧಿಸೂಚನೆಗಳು"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"ಯಾವುದೇ ಅಧಿಸೂಚನೆಗಳಿಲ್ಲ"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"ಮೈಕ್ರೊಫೋನ್ ರೆಕಾರ್ಡಿಂಗ್ ಆಗುತ್ತಿದೆ"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"ಕ್ಯಾಮರಾ ರೆಕಾರ್ಡಿಂಗ್ ಆಗುತ್ತಿದೆ"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"ಕ್ಯಾಮರಾ ಮತ್ತು ಮೈಕ್ರೊಫೋನ್ ರೆಕಾರ್ಡಿಂಗ್ ಆಗುತ್ತಿವೆ"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"ಮೈಕ್ರೊಫೋನ್ ರೆಕಾರ್ಡಿಂಗ್ ನಿಲ್ಲಿಸಿದೆ"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"ಕ್ಯಾಮರಾ ರೆಕಾರ್ಡಿಂಗ್ ನಿಲ್ಲಿಸಲಾಗಿದೆ"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"ಕ್ಯಾಮರಾ ಮತ್ತು ಮೈಕ್ರೊಫೋನ್ ರೆಕಾರ್ಡಿಂಗ್ ನಿಲ್ಲಿಸಿವೆ"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 044086e1114c..1dc505443b03 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -353,7 +353,7 @@
<string name="quick_settings_location_off_label" msgid="7923929131443915919">"위치 사용 중지"</string>
<string name="quick_settings_camera_label" msgid="5612076679385269339">"카메라 액세스"</string>
<string name="quick_settings_mic_label" msgid="8392773746295266375">"마이크 액세스"</string>
- <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"허용됨"</string>
+ <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"사용 가능"</string>
<string name="quick_settings_camera_mic_blocked" msgid="4710884905006788281">"차단됨"</string>
<string name="quick_settings_media_device_label" msgid="8034019242363789941">"미디어 기기"</string>
<string name="quick_settings_rssi_label" msgid="3397615415140356701">"RSSI"</string>
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"다시 탭하여 열기"</string>
<string name="tap_again" msgid="1315420114387908655">"다시 탭하세요."</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"위로 스와이프하여 열기"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"열려면 누르세요"</string>
<string name="keyguard_retry" msgid="886802522584053523">"위로 스와이프하여 다시 시도해 주세요"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"잠금 해제하여 NFC 사용"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"내 조직에 속한 기기입니다."</string>
diff --git a/packages/SystemUI/res/values-ko/strings_tv.xml b/packages/SystemUI/res/values-ko/strings_tv.xml
index f9c723a3b33b..b9fb537eb12c 100644
--- a/packages/SystemUI/res/values-ko/strings_tv.xml
+++ b/packages/SystemUI/res/values-ko/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"<xliff:g id="VPN_APP">%1$s</xliff:g>에 연결됨"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"알림"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"알림 없음"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"마이크 녹음 중"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"카메라 녹화 중"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"카메라 녹화 및 마이크 녹음 중"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"마이크 녹음 중단됨"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"카메라 녹화 중단됨"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"카메라 녹화 및 마이크 녹음 중단됨"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ko/tiles_states_strings.xml b/packages/SystemUI/res/values-ko/tiles_states_strings.xml
index 38c0185222e1..b583f242cff8 100644
--- a/packages/SystemUI/res/values-ko/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ko/tiles_states_strings.xml
@@ -48,8 +48,8 @@
</string-array>
<string-array name="tile_states_battery">
<item msgid="6311253873330062961">"이용 불가"</item>
- <item msgid="7838121007534579872">"꺼짐"</item>
- <item msgid="1578872232501319194">"켜짐"</item>
+ <item msgid="7838121007534579872">"사용 안함"</item>
+ <item msgid="1578872232501319194">"사용"</item>
</string-array>
<string-array name="tile_states_dnd">
<item msgid="467587075903158357">"이용 불가"</item>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index 9c2929d731e2..f62d9dac7984 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Ачуу үчүн кайра таптап коюңуз"</string>
<string name="tap_again" msgid="1315420114387908655">"Кайра таптап коюңуз"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Ачуу үчүн өйдө сүрүңүз"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"Ачуу үчүн басыңыз"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Кайталоо үчүн экранды өйдө сүрүңүз"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC колдонуу үчүн түзмөктүн кулпусун ачыңыз"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Бул түзмөк уюмуңузга таандык"</string>
@@ -1017,8 +1018,8 @@
<string name="device_services" msgid="1549944177856658705">"Түзмөк кызматтары"</string>
<string name="music_controls_no_title" msgid="4166497066552290938">"Аталышы жок"</string>
<string name="bubble_accessibility_action_move" msgid="3185080443743819178">"Жылдыруу"</string>
- <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Тутум чабыттоосу жаңырды. Өзгөртүү үчүн, Жөндөөлөргө өтүңүз."</string>
- <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Тутум чабыттоосун жаңыртуу үчүн Жөндөөлөргө өтүңүз"</string>
+ <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Тутум чабыттоосу жаңырды. Өзгөртүү үчүн, жөндөөлөргө өтүңүз."</string>
+ <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Тутум чабыттоосун жаңыртуу үчүн жөндөөлөргө өтүңүз"</string>
<string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Көшүү режими"</string>
<string name="magnification_window_title" msgid="4863914360847258333">"Чоңойтуу терезеси"</string>
<string name="magnification_controls_title" msgid="8421106606708891519">"Чоңойтуу терезесин башкаруу каражаттары"</string>
diff --git a/packages/SystemUI/res/values-ky/strings_tv.xml b/packages/SystemUI/res/values-ky/strings_tv.xml
index 1dba865803d2..52b237514991 100644
--- a/packages/SystemUI/res/values-ky/strings_tv.xml
+++ b/packages/SystemUI/res/values-ky/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"<xliff:g id="VPN_APP">%1$s</xliff:g> аркылуу"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Билдирмелер"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Билдирме жок"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"Микрофон жаздырууда"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"Камера жаздырууда"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Камера менен микрофон жаздырууда"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Микрофон жаздырууну токтотту"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Камера жаздырууну токтотту"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Камера менен микрофон жаздырууну токтотту"</string>
</resources>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 53a0ace0ee33..bb6b235065de 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"ແຕະ​ອີກ​ຄັ້ງ​ເພື່ອ​ເປີດ"</string>
<string name="tap_again" msgid="1315420114387908655">"ແຕະອີກເທື່ອໜຶ່ງ"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"ປັດຂຶ້ນເພື່ອເປີດ"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"ກົດເພື່ອເປີດ"</string>
<string name="keyguard_retry" msgid="886802522584053523">"ປັດຂຶ້ນເພື່ອລອງໃໝ່"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"ປົດລັອກເພື່ອໃຊ້ NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"ອຸປະກອນນີ້ເປັນຂອງອົງການທ່ານ"</string>
diff --git a/packages/SystemUI/res/values-lo/strings_tv.xml b/packages/SystemUI/res/values-lo/strings_tv.xml
index a45fb45cc76f..d2de1253f472 100644
--- a/packages/SystemUI/res/values-lo/strings_tv.xml
+++ b/packages/SystemUI/res/values-lo/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"ຜ່ານ <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"ການແຈ້ງເຕືອນ"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"ບໍ່ມີການແຈ້ງເຕືອນ"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"ໄມໂຄຣໂຟນກຳລັງບັນທຶກ"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"ກ້ອງຖ່າຍຮູບກຳລັງບັນທຶກ"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"ກ້ອງຖ່າຍຮູບ ແລະ ໄມໂຄຣໂຟນກຳລັງບັນທຶກ"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"ໄມໂຄຣໂຟນຢຸດການບັນທຶກແລ້ວ"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"ກ້ອງຖ່າຍຮູບຢຸດການບັນທຶກແລ້ວ"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"ກ້ອງຖ່າຍຮູບ ແລະ ໄມໂຄຣໂຟນຢຸດການບັນທຶກແລ້ວ"</string>
</resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 56f187e2d352..3469b3e89496 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -456,6 +456,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Palieskite dar kartą, kad atidarytumėte"</string>
<string name="tap_again" msgid="1315420114387908655">"Palieskite dar kartą"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Perbraukite aukštyn, kad atidarytumėte"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"Paspauskite, kad atidarytumėte"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Jei norite bandyti dar kartą, perbraukite aukštyn"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"Norėdami naudoti NFC, atrakinkite"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Šis įrenginys priklauso jūsų organizacijai"</string>
diff --git a/packages/SystemUI/res/values-lt/strings_tv.xml b/packages/SystemUI/res/values-lt/strings_tv.xml
index 8c329f961b5c..df23a616bae8 100644
--- a/packages/SystemUI/res/values-lt/strings_tv.xml
+++ b/packages/SystemUI/res/values-lt/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Per „<xliff:g id="VPN_APP">%1$s</xliff:g>“"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Pranešimai"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Nėra jokių pranešimų"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"Mikrofonas įrašo"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"Kamera įrašo"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Kamera ir mikrofonas įrašo"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Mikrofonas nebeįrašo"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Kamera nebeįrašo"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Kamera ir mikrofonas nebeįrašo"</string>
</resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 4522b98dbba3..cec582cb6a66 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -454,6 +454,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Pieskarieties vēlreiz, lai atvērtu"</string>
<string name="tap_again" msgid="1315420114387908655">"Pieskarieties vēlreiz"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Velciet augšup, lai atvērtu"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"Nospiediet, lai atvērtu"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Velciet augšup, lai mēģinātu vēlreiz"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"Atbloķējiet ierīci, lai izmantotu NFC."</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Šī ierīce pieder jūsu organizācijai."</string>
diff --git a/packages/SystemUI/res/values-lv/strings_tv.xml b/packages/SystemUI/res/values-lv/strings_tv.xml
index 758d28cddc82..e343a77a13da 100644
--- a/packages/SystemUI/res/values-lv/strings_tv.xml
+++ b/packages/SystemUI/res/values-lv/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Izmantojot: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Paziņojumi"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Nav paziņojumu"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"Notiek ierakstīšana ar mikrofonu"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"Notiek ierakstīšana ar kameru"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Notiek ierakstīšana ar kameru un mikrofonu"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Ierakstīšana ar mikrofonu apturēta"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Ierakstīšana ar kameru apturēta"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Ierakstīšana ar kameru un mikrofonu apturēta"</string>
</resources>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 5317bca72c53..2a2e121fb134 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -243,7 +243,7 @@
<skip />
<!-- no translation found for accessibility_work_mode (1280025758672376313) -->
<skip />
- <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Известувањето е отфрлено."</string>
+ <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Известувањето е отфрлено"</string>
<string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Панел за известување"</string>
<string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Брзи поставки."</string>
<string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Заклучи екран."</string>
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Допрете повторно за да се отвори"</string>
<string name="tap_again" msgid="1315420114387908655">"Допрете повторно"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Повлечете за да отворите"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"Притиснете за да отворите"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Повлечете нагоре за да се обидете повторно"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"Отклучете за да користите NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Уредов е во сопственост на организацијата"</string>
diff --git a/packages/SystemUI/res/values-mk/strings_tv.xml b/packages/SystemUI/res/values-mk/strings_tv.xml
index 0dfbd79de131..f39f1fae81b8 100644
--- a/packages/SystemUI/res/values-mk/strings_tv.xml
+++ b/packages/SystemUI/res/values-mk/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Преку <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Известувања"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Нема известувања"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"Микрофонот снима"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"Камерата снима"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Камерата и микрофонот снимаат"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Микрофонот прекина со снимање"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Камерата прекина со снимање"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Камерата и микрофонот прекинаа со снимање"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index e798c7d61dfe..95aec7d86b9d 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"തുറക്കുന്നതിന് വീണ്ടും ടാപ്പുചെയ്യുക"</string>
<string name="tap_again" msgid="1315420114387908655">"വീണ്ടും ടാപ്പ് ചെയ്യുക"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"തുറക്കാൻ മുകളിലോട്ട് സ്വൈപ്പ് ചെയ്യുക"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"തുറക്കാൻ അമർത്തുക"</string>
<string name="keyguard_retry" msgid="886802522584053523">"വീണ്ടും ശ്രമിക്കാൻ മുകളിലേക്ക് സ്വൈപ്പ് ചെയ്യുക"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC ഉപയോഗിക്കാൻ അൺലോക്ക് ചെയ്യുക"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"ഈ ഉപകരണം നിങ്ങളുടെ സ്ഥാപനത്തിന്റേതാണ്"</string>
diff --git a/packages/SystemUI/res/values-ml/strings_tv.xml b/packages/SystemUI/res/values-ml/strings_tv.xml
index 70cced8e810c..50d0280c7ff8 100644
--- a/packages/SystemUI/res/values-ml/strings_tv.xml
+++ b/packages/SystemUI/res/values-ml/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"<xliff:g id="VPN_APP">%1$s</xliff:g> വഴി"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"അറിയിപ്പുകൾ"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"അറിയിപ്പുകൾ ഒന്നുമില്ല"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"മൈക്രോഫോൺ റെക്കോർഡ് ചെയ്യുകയാണ്"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"ക്യാമറ റെക്കോർഡ് ചെയ്യുകയാണ്"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"ക്യാമറയും മൈക്രോഫോണും റെക്കോർഡ് ചെയ്യുകയാണ്"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"മൈക്രോഫോൺ റെക്കോർഡ് ചെയ്യുന്നത് നിർത്തി"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"ക്യാമറ റെക്കോർഡ് ചെയ്യുന്നത് നിർത്തി"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"ക്യാമറയും മൈക്രോഫോണും റെക്കോർഡ് ചെയ്യുന്നത് നിർത്തി"</string>
</resources>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 0e4cac02ea2d..1665e456ecbc 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Нээхийн тулд дахин товшино уу"</string>
<string name="tap_again" msgid="1315420114387908655">"Дaхин товшино уу"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Нээхийн тулд дээш шударна уу"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"Нээхийн тулд дарна уу"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Дахин оролдохын тулд дээш шударна уу"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC-г ашиглахын тулд түгжээг тайлна уу"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Энэ төхөөрөмж танай байгууллагад харьяалагддаг"</string>
diff --git a/packages/SystemUI/res/values-mn/strings_tv.xml b/packages/SystemUI/res/values-mn/strings_tv.xml
index 221d8ae058f9..1b20d84a680b 100644
--- a/packages/SystemUI/res/values-mn/strings_tv.xml
+++ b/packages/SystemUI/res/values-mn/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"<xliff:g id="VPN_APP">%1$s</xliff:g>-р"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Мэдэгдэл"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Мэдэгдэл байхгүй байна"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"Микрофон бичиж байна"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"Камер бичиж байна"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Камер болон микрофон бичиж байна"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Микрофон бичихээ зогсоосон"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Камер бичихээ зогсоосон"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Камер болон микрофон бичихээ зогсоосон"</string>
</resources>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 45a9a1bed0e5..0a79f48ffd4a 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"उघडण्यासाठी पुन्हा टॅप करा"</string>
<string name="tap_again" msgid="1315420114387908655">"पुन्हा टॅप करा"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"उघडण्यासाठी वर स्वाइप करा"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"उघडण्यासाठी दाबा"</string>
<string name="keyguard_retry" msgid="886802522584053523">"पुन्हा प्रयत्न करण्यासाठी वर स्‍वाइप करा"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC वापरण्यासाठी स्क्रीन अनलॉक करा"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"हे डिव्हाइस तुमच्या संस्थेचे आहे"</string>
diff --git a/packages/SystemUI/res/values-mr/strings_tv.xml b/packages/SystemUI/res/values-mr/strings_tv.xml
index ac0cad132fd0..2d79d4a77d3b 100644
--- a/packages/SystemUI/res/values-mr/strings_tv.xml
+++ b/packages/SystemUI/res/values-mr/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"<xliff:g id="VPN_APP">%1$s</xliff:g> द्वारे"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"सूचना"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"सूचना नाहीत"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"मायक्रोफोन रेकॉर्ड करत आहे"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"कॅमेरा रेकॉर्ड करत आहे"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"कॅमेरा आणि मायक्रोफोन रेकॉर्ड करत आहेत"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"मायक्रोफोनने रेकॉर्ड करणे थांबवले"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"कॅमेराने रेकॉर्ड करणे थांबवले"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"कॅमेरा आणि मायक्रोफोनने रेकॉर्ड करणे थांबवले"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 2349e286b491..65cf32142770 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Ketik lagi untuk membuka"</string>
<string name="tap_again" msgid="1315420114387908655">"Ketik sekali lagi"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Leret ke atas untuk buka"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"Tekan untuk buka"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Leret ke atas untuk mencuba lagi"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"Buka kunci untuk menggunakan NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Peranti ini milik organisasi anda"</string>
diff --git a/packages/SystemUI/res/values-ms/strings_tv.xml b/packages/SystemUI/res/values-ms/strings_tv.xml
index 46e345efc16b..9064ec4e6c2f 100644
--- a/packages/SystemUI/res/values-ms/strings_tv.xml
+++ b/packages/SystemUI/res/values-ms/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Melalui <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Pemberitahuan"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Tiada Pemberitahuan"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"Mikrofon sedang merakam"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"Kamera sedang merakam"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Kamera dan Mikrofon sedang merakam"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Mikrofon berhenti merakam"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Kamera berhenti merakam"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Kamera dan Mikrofon berhenti merakam"</string>
</resources>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 23de47fba55d..07f3a75dced5 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"ဖွင့်ရန် ထပ်ပြီး ပုတ်ပါ"</string>
<string name="tap_again" msgid="1315420114387908655">"ထပ်တို့ပါ"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"ဖွင့်ရန် အပေါ်သို့ပွတ်ဆွဲပါ"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"ဖွင့်ရန် နှိပ်ပါ"</string>
<string name="keyguard_retry" msgid="886802522584053523">"ထပ်စမ်းကြည့်ရန် အပေါ်သို့ပွတ်ဆွဲပါ"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC ကို အသုံးပြုရန် လော့ခ်ဖွင့်ပါ"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"ဤစက်ကို သင့်အဖွဲ့အစည်းက ပိုင်ဆိုင်သည်"</string>
diff --git a/packages/SystemUI/res/values-my/strings_tv.xml b/packages/SystemUI/res/values-my/strings_tv.xml
index 268c5540ef5b..1aca9eb72364 100644
--- a/packages/SystemUI/res/values-my/strings_tv.xml
+++ b/packages/SystemUI/res/values-my/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"<xliff:g id="VPN_APP">%1$s</xliff:g> မှတစ်ဆင့်"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"အကြောင်းကြားချက်များ"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"အကြောင်းကြားချက်များ မရှိပါ"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"မိုက်ခရိုဖုန်း မှတ်တမ်းတင်နေသည်"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"ကင်မရာ မှတ်တမ်းတင်နေသည်"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"ကင်မရာနှင့် မိုက်ခရိုဖုန်းက မှတ်တမ်းတင်နေသည်"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"မိုက်ခရိုဖုန်း မှတ်တမ်းတင်ခြင်းကို ရပ်ထားသည်"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"ကင်မရာ မှတ်တမ်းတင်ခြင်းကို ရပ်ထားသည်"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"ကင်မရာနှင့် မိုက်ခရိုဖုန်းက မှတ်တမ်းတင်ခြင်းကို ရပ်ထားသည်"</string>
</resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 9c18b95f3387..6c234001ade9 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Trykk på nytt for å åpne"</string>
<string name="tap_again" msgid="1315420114387908655">"Trykk igjen"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Sveip opp for å åpne"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"Trykk for å åpne"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Sveip opp for å prøve igjen"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"Lås opp for å bruke NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Denne enheten tilhører organisasjonen din"</string>
diff --git a/packages/SystemUI/res/values-nb/strings_tv.xml b/packages/SystemUI/res/values-nb/strings_tv.xml
index c5767dd94c03..7eb6a29788c7 100644
--- a/packages/SystemUI/res/values-nb/strings_tv.xml
+++ b/packages/SystemUI/res/values-nb/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Via <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Varsler"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Ingen varsler"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"Mikrofonen tar opp"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"Kameraet tar opp"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Kameraet og mikrofonen tar opp"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Mikrofonen stoppet opptaket"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Kameraet stoppet opptaket"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Kameraet og mikrofonen stoppet opptaket"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index 9ae2d43e26ed..c503ebdb368e 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -452,6 +452,8 @@
<string name="notification_tap_again" msgid="4477318164947497249">"खोल्न पुनः ट्याप गर्नुहोस्"</string>
<string name="tap_again" msgid="1315420114387908655">"फेरि ट्याप गर्नुहोस्"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"खोल्न माथितिर स्वाइप गर्नुहोस्"</string>
+ <!-- no translation found for keyguard_unlock_press (8488350566398524740) -->
+ <skip />
<string name="keyguard_retry" msgid="886802522584053523">"फेरि प्रयास गर्न माथितिर स्वाइप गर्नुहोस्"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC प्रयोग गर्न स्क्रिन अनलक गर्नुहोस्"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"यो डिभाइस तपाईंको सङ्गठनको स्वामित्वमा छ"</string>
diff --git a/packages/SystemUI/res/values-ne/strings_tv.xml b/packages/SystemUI/res/values-ne/strings_tv.xml
index 925f7b76c12e..410f26f0287b 100644
--- a/packages/SystemUI/res/values-ne/strings_tv.xml
+++ b/packages/SystemUI/res/values-ne/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"<xliff:g id="VPN_APP">%1$s</xliff:g> मार्फत"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"सूचनाहरू"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"कुनै पनि सूचना छैन"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"माइक्रोफोनले रेकर्ड गर्दै छ"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"क्यामेराले रेकर्ड गर्दै छ"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"क्यामेरा र माइक्रोफोनले रेकर्ड गर्दै छन्"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"माइक्रोफोनले रेकर्ड गर्न छाड्यो"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"क्यामेराले रेकर्ड गर्न छाड्यो"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"क्यामेरा र माइक्रोफोनले रेकर्ड गर्न छाडे"</string>
</resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 155d1ad6975d..6614638253f3 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Tik nog eens om te openen"</string>
<string name="tap_again" msgid="1315420114387908655">"Tik nog een keer"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Swipe omhoog om te openen"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"Druk om te openen"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Swipe omhoog om het opnieuw te proberen"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"Ontgrendel het apparaat om NFC te gebruiken"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Dit apparaat is eigendom van je organisatie"</string>
diff --git a/packages/SystemUI/res/values-nl/strings_tv.xml b/packages/SystemUI/res/values-nl/strings_tv.xml
index 22d3b8806bbd..7aeeabfdc7e7 100644
--- a/packages/SystemUI/res/values-nl/strings_tv.xml
+++ b/packages/SystemUI/res/values-nl/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Via <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Meldingen"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Geen meldingen"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"Microfoon neemt op"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"Camera neemt op"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Camera en microfoon nemen op"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Microfoon neemt niet meer op"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Camera neemt niet meer op"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Camera en microfoon nemen niet meer op"</string>
</resources>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 4d44690b5951..fab0ac601c69 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"ଖୋଲିବା ପାଇଁ ପୁଣି ଟାପ୍‍ କରନ୍ତୁ"</string>
<string name="tap_again" msgid="1315420114387908655">"ପୁଣି ଟାପ୍ କରନ୍ତୁ"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"ଖୋଲିବା ପାଇଁ ଉପରକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"ଖୋଲିବାକୁ ଦବାନ୍ତୁ"</string>
<string name="keyguard_retry" msgid="886802522584053523">"ପୁଣି ଚେଷ୍ଟା କରିବା ପାଇଁ ଉପରକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC ବ୍ୟବହାର କରିବାକୁ ଅନଲକ୍ କରନ୍ତୁ"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"ଏହି ଡିଭାଇସଟି ଆପଣଙ୍କ ସଂସ୍ଥାର ଅଟେ"</string>
diff --git a/packages/SystemUI/res/values-or/strings_tv.xml b/packages/SystemUI/res/values-or/strings_tv.xml
index 707c49e183c7..2669a5aaa7f5 100644
--- a/packages/SystemUI/res/values-or/strings_tv.xml
+++ b/packages/SystemUI/res/values-or/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"<xliff:g id="VPN_APP">%1$s</xliff:g> ମାଧ୍ୟମରେ"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"କୌଣସି ବିଜ୍ଞପ୍ତି ନାହିଁ"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"ମାଇକ୍ରୋଫୋନ୍ ରେକର୍ଡିଂ କରୁଛି"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"କ୍ୟାମେରା ରେକର୍ଡିଂ କରୁଛି"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"କ୍ୟାମେରା ଏବଂ ମାଇକ୍ରୋଫୋନ୍ ରେକର୍ଡିଂ କରୁଛି"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"ମାଇକ୍ରୋଫୋନ୍ ରେକର୍ଡିଂ ବନ୍ଦ କରିଛି"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"କ୍ୟାମେରା ରେକର୍ଡିଂ ବନ୍ଦ କରିଛି"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"କ୍ୟାମେରା ଏବଂ ମାଇକ୍ରୋଫୋନ୍ ରେକର୍ଡିଂ ବନ୍ଦ କରିଛି"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 7bb60a0a80f9..7e64a2407fd4 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"ਖੋਲ੍ਹਣ ਲਈ ਦੁਬਾਰਾ ਟੈਪ ਕਰੋ"</string>
<string name="tap_again" msgid="1315420114387908655">"ਦੁਬਾਰਾ ਟੈਪ ਕਰੋ"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"ਖੋਲ੍ਹਣ ਲਈ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰੋ"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"ਖੋਲ੍ਹਣ ਲਈ ਦਬਾਓ"</string>
<string name="keyguard_retry" msgid="886802522584053523">"ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰਨ ਲਈ ਉੱਤੇ ਵੱਲ ਸਵਾਈਪ ਕਰੋ"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC ਵਰਤਣ ਲਈ ਅਣਲਾਕ ਕਰੋ"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"ਇਹ ਡੀਵਾਈਸ ਤੁਹਾਡੀ ਸੰਸਥਾ ਨਾਲ ਸੰਬੰਧਿਤ ਹੈ"</string>
diff --git a/packages/SystemUI/res/values-pa/strings_tv.xml b/packages/SystemUI/res/values-pa/strings_tv.xml
index c0761942b2ee..3443cfac4d70 100644
--- a/packages/SystemUI/res/values-pa/strings_tv.xml
+++ b/packages/SystemUI/res/values-pa/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"<xliff:g id="VPN_APP">%1$s</xliff:g> ਰਾਹੀਂ"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"ਸੂਚਨਾਵਾਂ"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"ਕੋਈ ਸੂਚਨਾ ਨਹੀਂ"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਰਿਕਾਰਡ ਕਰ ਰਿਹਾ ਹੈ"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"ਕੈਮਰਾ ਰਿਕਾਰਡ ਕਰ ਰਿਹਾ ਹੈ"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"ਕੈਮਰਾ ਅਤੇ ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਰਿਕਾਰਡ ਕਰ ਰਹੇ ਹਨ"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਨੇ ਰਿਕਾਰਡ ਕਰਨਾ ਬੰਦ ਕਰ ਦਿੱਤਾ ਹੈ"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"ਕੈਮਰੇ ਨੇ ਰਿਕਾਰਡ ਕਰਨਾ ਬੰਦ ਕਰ ਦਿੱਤਾ ਹੈ"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"ਕੈਮਰੇ ਅਤੇ ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਨੇ ਰਿਕਾਰਡ ਕਰਨਾ ਬੰਦ ਕਰ ਦਿੱਤਾ ਹੈ"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index ea6f2252c0cd..7c0da9d29596 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -456,6 +456,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Kliknij ponownie, by otworzyć"</string>
<string name="tap_again" msgid="1315420114387908655">"Kliknij jeszcze raz"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Przesuń w górę, by otworzyć"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"Naciśnij, by otworzyć"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Przesuń w górę, by spróbować ponownie"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"Odblokuj, by użyć komunikacji NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"To urządzenie należy do Twojej organizacji"</string>
diff --git a/packages/SystemUI/res/values-pl/strings_tv.xml b/packages/SystemUI/res/values-pl/strings_tv.xml
index e63aadee9d65..12b3777af5f8 100644
--- a/packages/SystemUI/res/values-pl/strings_tv.xml
+++ b/packages/SystemUI/res/values-pl/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Przez: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Powiadomienia"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Brak powiadomień"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"Mikrofon rejestruje"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"Aparat rejestruje"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Aparat i mikrofon rejestrują"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Mikrofon przestał rejestrować"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Aparat przestał rejestrować"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Aparat i mikrofon przestały rejestrować"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index 2f1501b26c6c..1bfb7012aa39 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Toque novamente para abrir"</string>
<string name="tap_again" msgid="1315420114387908655">"Toque novamente"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Deslize para cima para abrir"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"Pressione para abrir"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Deslize para cima para tentar novamente"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desbloqueie para usar a NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Este dispositivo pertence à sua organização"</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings_tv.xml b/packages/SystemUI/res/values-pt-rBR/strings_tv.xml
index 2ea81526feed..d29bc6a34386 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings_tv.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Via <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Notificações"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Nenhuma notificação"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"O microfone está gravando"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"A câmera está gravando"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"A câmera e o microfone estão gravando"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"O microfone parou de gravar"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"A câmera parou de gravar"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"A câmera e o microfone pararam de gravar"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 563e99d56547..80f4bc649ba9 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Toque novamente para abrir"</string>
<string name="tap_again" msgid="1315420114387908655">"Toque novamente"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Deslize rapidamente para cima para abrir"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"Prima para abrir"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Deslize rapidamente para cima para tentar novamente."</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desbloquear para utilizar o NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Este dispositivo pertence à sua entidade."</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings_tv.xml b/packages/SystemUI/res/values-pt-rPT/strings_tv.xml
index 8ce3e307c659..3ae7daf30828 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings_tv.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Através de <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Notificações"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Sem notificações"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"O microfone está a gravar"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"A câmara está a gravar"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"A câmara e o microfone estão a gravar"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"O microfone parou a gravação"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"A câmara parou a gravação"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"A câmara e o microfone pararam a gravação"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 2f1501b26c6c..1bfb7012aa39 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Toque novamente para abrir"</string>
<string name="tap_again" msgid="1315420114387908655">"Toque novamente"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Deslize para cima para abrir"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"Pressione para abrir"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Deslize para cima para tentar novamente"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desbloqueie para usar a NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Este dispositivo pertence à sua organização"</string>
diff --git a/packages/SystemUI/res/values-pt/strings_tv.xml b/packages/SystemUI/res/values-pt/strings_tv.xml
index 2ea81526feed..d29bc6a34386 100644
--- a/packages/SystemUI/res/values-pt/strings_tv.xml
+++ b/packages/SystemUI/res/values-pt/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Via <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Notificações"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Nenhuma notificação"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"O microfone está gravando"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"A câmera está gravando"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"A câmera e o microfone estão gravando"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"O microfone parou de gravar"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"A câmera parou de gravar"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"A câmera e o microfone pararam de gravar"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 21026001e0fc..d82626bb44be 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -454,6 +454,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Atingeți din nou pentru a deschide"</string>
<string name="tap_again" msgid="1315420114387908655">"Atingeți din nou"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Glisați în sus pentru a deschide"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"Apăsați pentru a deschide"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Glisați pentru a încerca din nou"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"Deblocați pentru a folosi NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Dispozitivul aparține organizației dvs."</string>
diff --git a/packages/SystemUI/res/values-ro/strings_tv.xml b/packages/SystemUI/res/values-ro/strings_tv.xml
index c64a492c59e4..54dd985cfc0f 100644
--- a/packages/SystemUI/res/values-ro/strings_tv.xml
+++ b/packages/SystemUI/res/values-ro/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Prin <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Notificări"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Nicio notificare"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"Microfonul înregistrează"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"Camera foto înregistrează"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Camera foto și microfonul înregistrează"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Microfonul nu mai înregistrează"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Camera foto a oprit înregistrarea"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Camera foto și microfonul nu mai înregistrează"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index eeb1f3e392aa..f3768280313a 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -456,6 +456,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Нажмите ещё раз, чтобы открыть"</string>
<string name="tap_again" msgid="1315420114387908655">"Нажмите ещё раз"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Проведите вверх, чтобы открыть"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"Нажмите, чтобы открыть."</string>
<string name="keyguard_retry" msgid="886802522584053523">"Чтобы повторить попытку, проведите вверх"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"Чтобы использовать NFC, разблокируйте устройство."</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Это устройство принадлежит вашей организации"</string>
diff --git a/packages/SystemUI/res/values-ru/strings_tv.xml b/packages/SystemUI/res/values-ru/strings_tv.xml
index 8ce0dc203923..befb5d2115d9 100644
--- a/packages/SystemUI/res/values-ru/strings_tv.xml
+++ b/packages/SystemUI/res/values-ru/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Через приложение <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Уведомления"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Уведомлений нет."</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"Выполняется запись с микрофона"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"Выполняется запись с камеры"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Выполняется запись с камеры и микрофона"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Запись с микрофона остановлена"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Запись с камеры остановлена"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Запись с камеры и микрофона остановлена"</string>
</resources>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index 247b7a544cdd..1f4813ea5f38 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"විවෘත කිරීමට නැවත තට්ටු කරන්න"</string>
<string name="tap_again" msgid="1315420114387908655">"නැවත තට්ටු කරන්න"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"විවෘත කිරීමට ස්වයිප් කරන්න"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"විවෘත කිරීමට ඔබන්න"</string>
<string name="keyguard_retry" msgid="886802522584053523">"නැවත උත්සාහ කිරීමට ඉහළට ස්වයිප් කරන්න"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC භාවිත කිරීමට අගුලු හරින්න"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"මෙම උපාංගය ඔබේ සංවිධානයට අයිතිය"</string>
diff --git a/packages/SystemUI/res/values-si/strings_tv.xml b/packages/SystemUI/res/values-si/strings_tv.xml
index 3067be345c7d..92257c7e7c76 100644
--- a/packages/SystemUI/res/values-si/strings_tv.xml
+++ b/packages/SystemUI/res/values-si/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"<xliff:g id="VPN_APP">%1$s</xliff:g> හරහා"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"දැනුම්දීම්"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"දැනුම්දීම් නැත"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"මයික්‍රෆෝනය පටිගත කරයි"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"කැමරාව පටිගත කරයි"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"කැමරාව සහ මයික්‍රෆෝනය පටිගත කරයි"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"මයික්‍රෆෝනය පටිගත කිරීම නැවැත්වීය"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"කැමරාව පටිගත කිරීම නැවැත්වීය"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"කැමරාව සහ මයික්‍රෆෝනය පටිගත කිරීම නැවැත්වීය"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 74b24bdd531c..966745b3789e 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -456,6 +456,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Upozornenie otvoríte opätovným klepnutím"</string>
<string name="tap_again" msgid="1315420114387908655">"Klepnite znova"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Otvorte potiahnutím prstom nahor"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"Stlačením otvoríte"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Potiahnutím nahor to skúste znova"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"Ak chcete použiť NFC, odomknite"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Toto zariadenie patrí vašej organizácii"</string>
diff --git a/packages/SystemUI/res/values-sk/strings_tv.xml b/packages/SystemUI/res/values-sk/strings_tv.xml
index b37648da0e7d..6910079bbadf 100644
--- a/packages/SystemUI/res/values-sk/strings_tv.xml
+++ b/packages/SystemUI/res/values-sk/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Cez: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Upozornenia"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Žiadne upozornenia"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"Mikrofón nahráva"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"Kamera nahráva"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Kamera a mikrofón nahrávajú"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Mikrofón prestal nahrávať"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Kamera prestala nahrávať"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Kamera a mikrofón prestali nahrávať"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index cfb89d4c8194..7af0970e322d 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -456,6 +456,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Znova se dotaknite, da odprete"</string>
<string name="tap_again" msgid="1315420114387908655">"Znova se dotaknite možnosti"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Povlecite navzgor, da odprete"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"Pritisnite, če želite odpreti."</string>
<string name="keyguard_retry" msgid="886802522584053523">"Povlecite navzgor za vnovičen poskus"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"Odklenite napravo, če želite uporabljati NFC."</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Ta naprava pripada vaši organizaciji"</string>
diff --git a/packages/SystemUI/res/values-sl/strings_tv.xml b/packages/SystemUI/res/values-sl/strings_tv.xml
index 1f66138c175a..10050790fa1a 100644
--- a/packages/SystemUI/res/values-sl/strings_tv.xml
+++ b/packages/SystemUI/res/values-sl/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Prek storitve <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Obvestila"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Ni obvestil"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"Snemanje z mikrofonom"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"Snemanje s fotoaparatom"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Snemanje s fotoaparatom in mikrofonom"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Ustavljeno snemanje z mikrofonom"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Ustavljeno snemanje s fotoaparatom"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Ustavljeno snemanje s fotoaparatom in mikrofonom"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index f7753c7a5086..6845b5b5877d 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -452,6 +452,8 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Trokit përsëri për ta hapur"</string>
<string name="tap_again" msgid="1315420114387908655">"Trokit sërish"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Rrëshqit lart për ta hapur"</string>
+ <!-- no translation found for keyguard_unlock_press (8488350566398524740) -->
+ <skip />
<string name="keyguard_retry" msgid="886802522584053523">"Rrëshqit lart për të provuar përsëri"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"Shkyçe për të përdorur NFC-në"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Kjo pajisje i përket organizatës sate"</string>
diff --git a/packages/SystemUI/res/values-sq/strings_tv.xml b/packages/SystemUI/res/values-sq/strings_tv.xml
index fb74e38b4f38..c5ce63114508 100644
--- a/packages/SystemUI/res/values-sq/strings_tv.xml
+++ b/packages/SystemUI/res/values-sq/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Nëpërmjet <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Njoftimet"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Asnjë njoftim"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"\"Mikrofoni\" po regjistron"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"\"Kamera\" po regjistron"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"\"Kamera\" dhe \"Mikrofoni\" po regjistrojnë"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"\"Mikrofoni\" ndaloi së regjistruari"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"\"Kamera\" ndaloi së regjistruari"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"\"Kamera\" dhe \"Mikrofoni\" ndaluan së regjistruari"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 73ecc4c7b72b..499c4e1d1489 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -454,6 +454,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Додирните поново да бисте отворили"</string>
<string name="tap_again" msgid="1315420114387908655">"Додирните поново"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Превуците нагоре да бисте отворили"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"Притисните да бисте отворили"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Превуците нагоре да бисте пробали поново"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"Откључајте да бисте користили NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Овај уређај припада организацији"</string>
diff --git a/packages/SystemUI/res/values-sr/strings_tv.xml b/packages/SystemUI/res/values-sr/strings_tv.xml
index 59151da2677f..d35ff3c1e746 100644
--- a/packages/SystemUI/res/values-sr/strings_tv.xml
+++ b/packages/SystemUI/res/values-sr/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Преко: <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Обавештења"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Нема обавештења"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"Микрофон снима"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"Камера снима"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Камера и микрофон снимају"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Снимање микрофоном је заустављено"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Снимање камером је заустављено"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Снимање камером и микрофоном је заустављено"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 1f60b3a5c581..86333f0e3a5c 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -158,21 +158,21 @@
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"Slutför genom att trycka på Bekräfta"</string>
<string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentiserad"</string>
<string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Använd pinkod"</string>
- <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Använd grafiskt lösenord"</string>
+ <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Använd mönster"</string>
<string name="biometric_dialog_use_password" msgid="3445033859393474779">"Använd lösenord"</string>
<string name="biometric_dialog_wrong_pin" msgid="1878539073972762803">"Fel pinkod"</string>
- <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Fel grafiskt lösenord"</string>
+ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Fel mönster"</string>
<string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Fel lösenord"</string>
<string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"För många felaktiga försök.\nFörsök igen om <xliff:g id="NUMBER">%d</xliff:g> sekunder."</string>
<string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Försök igen. Försök <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> av <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string>
<string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Din data raderas."</string>
- <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Enhetens data raderas om du anger fel grafiskt lösenord vid nästa försök."</string>
+ <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Enhetens data raderas om du ritar fel mönster vid nästa försök."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_device" msgid="9151756675698215723">"Enhetens data raderas om du anger fel pinkod vid nästa försök."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_device" msgid="2363778585575998317">"Enhetens data raderas om du anger fel lösenord vid nästa försök."</string>
- <string name="biometric_dialog_last_pattern_attempt_before_wipe_user" msgid="8400180746043407270">"Användaren raderas om du anger fel grafiskt lösenord vid nästa försök."</string>
+ <string name="biometric_dialog_last_pattern_attempt_before_wipe_user" msgid="8400180746043407270">"Användaren raderas om du ritar fel mönster vid nästa försök."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_user" msgid="4159878829962411168">"Användaren raderas om du anger fel pinkod vid nästa försök."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_user" msgid="4695682515465063885">"Den här användaren raderas om du anger fel lösenord vid nästa försök."</string>
- <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Jobbprofilen och dess data raderas om du anger fel grafiskt lösenord vid nästa försök."</string>
+ <string name="biometric_dialog_last_pattern_attempt_before_wipe_profile" msgid="6045224069529284686">"Jobbprofilen och dess data raderas om du ritar fel mönster vid nästa försök."</string>
<string name="biometric_dialog_last_pin_attempt_before_wipe_profile" msgid="545567685899091757">"Jobbprofilen och dess data raderas om du anger fel pinkod vid nästa försök."</string>
<string name="biometric_dialog_last_password_attempt_before_wipe_profile" msgid="8538032972389729253">"Din jobbprofil och dess data raderas om du anger fel lösenord vid nästa försök."</string>
<string name="biometric_dialog_failed_attempts_now_wiping_device" msgid="6585503524026243042">"För många felaktiga försök. Enhetens data raderas."</string>
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Tryck igen för att öppna"</string>
<string name="tap_again" msgid="1315420114387908655">"Tryck igen"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Öppna genom att svepa uppåt"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"Tryck för att öppna"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Svep uppåt om du vill försöka igen"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"Lås upp om du vill använda NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Den här enheten tillhör organisationen"</string>
diff --git a/packages/SystemUI/res/values-sv/strings_tv.xml b/packages/SystemUI/res/values-sv/strings_tv.xml
index fd8fa4b1bb8e..346d5d21e9b8 100644
--- a/packages/SystemUI/res/values-sv/strings_tv.xml
+++ b/packages/SystemUI/res/values-sv/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"via <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Aviseringar"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Inga aviseringar"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"Mikrofonen spelar in"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"Kameran spelar in"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Kameran och mikrofonen spelar in"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Mikrofonen slutade spela in"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Kameran slutade spela in"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Kameran och mikrofonen slutade spelade in"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 7ac26be4c614..6b938e41d392 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Gusa tena ili ufungue"</string>
<string name="tap_again" msgid="1315420114387908655">"Gusa tena"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Telezesha kidole juu ili ufungue"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"Bofya ili ufungue"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Telezesha kidole juu ili ujaribu tena"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"Fungua ili utumie NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Kifaa hiki kinamilikiwa na shirika lako"</string>
diff --git a/packages/SystemUI/res/values-sw/strings_tv.xml b/packages/SystemUI/res/values-sw/strings_tv.xml
index 8f6880d4bd0b..a585e692ff34 100644
--- a/packages/SystemUI/res/values-sw/strings_tv.xml
+++ b/packages/SystemUI/res/values-sw/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Kupitia <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Arifa"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Hakuna Arifa"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"Maikrofoni inarekodi"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"Kamera inarekodi"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Kamera na Maikrofoni zinarekodi"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Maikrofoni imeacha kurekodi"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Kamera imeacha kurekodi"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Kamera na Maikrofoni zimeacha kurekodi"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index 426ddd4b3e83..b9115a74910d 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"திறக்க, மீண்டும் தட்டவும்"</string>
<string name="tap_again" msgid="1315420114387908655">"மீண்டும் தட்டவும்"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"திறப்பதற்கு மேல் நோக்கி ஸ்வைப் செய்யவும்"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"திறப்பதற்கு அழுத்தவும்"</string>
<string name="keyguard_retry" msgid="886802522584053523">"மீண்டும் முயல மேல்நோக்கி ஸ்வைப் செய்யவும்"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFCயைப் பயன்படுத்த அன்லாக் செய்யவும்"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"இந்த சாதனம் உங்கள் நிறுவனத்துக்கு சொந்தமானது"</string>
diff --git a/packages/SystemUI/res/values-ta/strings_tv.xml b/packages/SystemUI/res/values-ta/strings_tv.xml
index 9c62d8cf7b96..1dc581d1f692 100644
--- a/packages/SystemUI/res/values-ta/strings_tv.xml
+++ b/packages/SystemUI/res/values-ta/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"<xliff:g id="VPN_APP">%1$s</xliff:g> வழியாக"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"அறிவிப்புகள்"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"அறிவிப்புகள் எதுவுமில்லை"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"மைக்ரோஃபோன் ரெக்கார்டு செய்கிறது"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"கேமரா ரெக்கார்டு செய்கிறது"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"கேமராவும் மைக்ரோஃபோனும் ரெக்கார்டு செய்கின்றன"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"மைக்ரோஃபோன் ரெக்கார்டு செய்வதை நிறுத்திவிட்டது"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"கேமரா ரெக்கார்டு செய்வதை நிறுத்திவிட்டது"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"கேமராவும் மைக்ரோஃபோனும் ரெக்கார்டு செய்வதை நிறுத்திவிட்டன"</string>
</resources>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 020d9b462c45..bcc5404af2f0 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"తెరవడానికి మళ్లీ నొక్కండి"</string>
<string name="tap_again" msgid="1315420114387908655">"మళ్లీ ట్యాప్ చేయండి"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"తెరవడానికి, పైకి స్వైప్ చేయండి"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"తెరవడానికి నొక్కండి"</string>
<string name="keyguard_retry" msgid="886802522584053523">"మళ్ళీ ప్రయత్నించడానికి పైకి స్వైప్ చేయండి"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFCని ఉపయోగించడానికి అన్‌లాక్ చేయండి"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"ఈ పరికరం మీ సంస్థకు చెందినది"</string>
@@ -957,7 +958,7 @@
<string name="tuner_right" msgid="8247571132790812149">"కుడి"</string>
<string name="tuner_menu" msgid="363690665924769420">"మెనూ"</string>
<string name="tuner_app" msgid="6949280415826686972">"<xliff:g id="APP">%1$s</xliff:g> అనురవర్తనం"</string>
- <string name="notification_channel_alerts" msgid="3385787053375150046">"హెచ్చరికలు"</string>
+ <string name="notification_channel_alerts" msgid="3385787053375150046">"అలర్ట్‌లు"</string>
<string name="notification_channel_battery" msgid="9219995638046695106">"బ్యాటరీ"</string>
<string name="notification_channel_screenshot" msgid="7665814998932211997">"స్క్రీన్‌షాట్‌లు"</string>
<string name="notification_channel_general" msgid="4384774889645929705">"సాధారణ సందేశాలు"</string>
diff --git a/packages/SystemUI/res/values-te/strings_tv.xml b/packages/SystemUI/res/values-te/strings_tv.xml
index 1879edd8d96b..7eded1eaaa65 100644
--- a/packages/SystemUI/res/values-te/strings_tv.xml
+++ b/packages/SystemUI/res/values-te/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"<xliff:g id="VPN_APP">%1$s</xliff:g> ద్వారా"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"నోటిఫికేషన్‌లు"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"నోటిఫికేషన్‌లు లేవు"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"మైక్రోఫోన్ రికార్డింగ్ చేస్తోంది"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"కెమెరా రికార్డింగ్ చేస్తోంది"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"కెమెరా, మైక్రోఫోన్ రికార్డింగ్ చేస్తున్నాయి"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"మైక్రోఫోన్ రికార్డింగ్ చేయడం ఆపివేసింది"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"కెమెరా రికార్డింగ్ చేయడం ఆపివేసింది"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"కెమెరా, మైక్రోఫోన్ రికార్డింగ్ చేయడం ఆపివేశాయి"</string>
</resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index ce469f7f7178..6f7df9fdcf3f 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -353,7 +353,7 @@
<string name="quick_settings_location_off_label" msgid="7923929131443915919">"ปิดตำแหน่ง"</string>
<string name="quick_settings_camera_label" msgid="5612076679385269339">"สิทธิ์เข้าถึงกล้อง"</string>
<string name="quick_settings_mic_label" msgid="8392773746295266375">"สิทธิ์เข้าถึงไมโครโฟน"</string>
- <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"มี"</string>
+ <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"พร้อมให้ใช้งาน"</string>
<string name="quick_settings_camera_mic_blocked" msgid="4710884905006788281">"ถูกบล็อก"</string>
<string name="quick_settings_media_device_label" msgid="8034019242363789941">"อุปกรณ์สื่อ"</string>
<string name="quick_settings_rssi_label" msgid="3397615415140356701">"RSSI"</string>
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"แตะอีกครั้งเพื่อเปิด"</string>
<string name="tap_again" msgid="1315420114387908655">"แตะอีกครั้ง"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"เลื่อนขึ้นเพื่อเปิด"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"กดเพื่อเปิด"</string>
<string name="keyguard_retry" msgid="886802522584053523">"เลื่อนขึ้นเพื่อลองอีกครั้ง"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"ปลดล็อกเพื่อใช้ NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"องค์กรของคุณเป็นเจ้าของอุปกรณ์นี้"</string>
diff --git a/packages/SystemUI/res/values-th/strings_tv.xml b/packages/SystemUI/res/values-th/strings_tv.xml
index 072482176363..458dc7e8425b 100644
--- a/packages/SystemUI/res/values-th/strings_tv.xml
+++ b/packages/SystemUI/res/values-th/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"ผ่าน <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"การแจ้งเตือน"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"ไม่มีการแจ้งเตือน"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"ไมโครโฟนกำลังบันทึก"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"กล้องกำลังบันทึก"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"กล้องและไมโครโฟนกำลังบันทึก"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"ไมโครโฟนหยุดบันทึกแล้ว"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"กล้องหยุดบันทึกแล้ว"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"กล้องและไมโครโฟนหยุดบันทึกแล้ว"</string>
</resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 8d0a8475122c..d0312b3a99f6 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"I-tap ulit upang buksan"</string>
<string name="tap_again" msgid="1315420114387908655">"I-tap ulit"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Mag-swipe pataas para buksan"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"Pindutin para buksan"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Mag-swipe pataas para subukan ulit"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"I-unlock para magamit ang NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Pagmamay-ari ng iyong organisasyon ang device na ito"</string>
diff --git a/packages/SystemUI/res/values-tl/strings_tv.xml b/packages/SystemUI/res/values-tl/strings_tv.xml
index 8dcc22f2d36b..b45d62b96309 100644
--- a/packages/SystemUI/res/values-tl/strings_tv.xml
+++ b/packages/SystemUI/res/values-tl/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Sa pamamagitan ng <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Mga Notification"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Walang Notification"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"Nagre-record ang Mikropono"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"Nagre-record ang Camera"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Nagre-record ang Camera at Mikropono"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Huminto sa pag-record ang Mikropono"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Huminto sa pag-record ang Camera"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Huminto sa pag-record ang Camera at Mikropono"</string>
</resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 6b55d1c7e1d6..33eb5f3f9af2 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Açmak için tekrar dokunun"</string>
<string name="tap_again" msgid="1315420114387908655">"Tekrar dokunun"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Açmak için yukarı kaydırın"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"Açmak için basın"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Tekrar denemek için yukarı kaydırın"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC\'yi kullanmak için kilidi açın"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Bu cihaz, kuruluşunuza ait"</string>
diff --git a/packages/SystemUI/res/values-tr/strings_tv.xml b/packages/SystemUI/res/values-tr/strings_tv.xml
index 49e76af004ab..54f24c388021 100644
--- a/packages/SystemUI/res/values-tr/strings_tv.xml
+++ b/packages/SystemUI/res/values-tr/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"<xliff:g id="VPN_APP">%1$s</xliff:g> üzerinden"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Bildirimler"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Bildirim Yok"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"Mikrofon kaydediyor"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"Kamera kaydediyor"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Kamera ve Mikrofon kaydediyor"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Mikrofon kaydı durdu"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Kamera kaydı durdu"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Kamera ve Mikrofon kaydı durdu"</string>
</resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 0a5992bf1b48..24650f751319 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -456,6 +456,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Торкніться знову, щоб відкрити"</string>
<string name="tap_again" msgid="1315420114387908655">"Натисніть знову"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Проведіть пальцем угору, щоб відкрити"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"Натисніть, щоб відкрити"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Проведіть пальцем угору, щоб повторити спробу"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"Розблокуйте екран, щоб скористатись NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Цей пристрій належить вашій організації"</string>
diff --git a/packages/SystemUI/res/values-uk/strings_tv.xml b/packages/SystemUI/res/values-uk/strings_tv.xml
index 170b06805355..2ec6d9a59d38 100644
--- a/packages/SystemUI/res/values-uk/strings_tv.xml
+++ b/packages/SystemUI/res/values-uk/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Через <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Сповіщення"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Немає сповіщень"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"Мікрофон записує"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"Камера записує"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Камера й мікрофон записують"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Мікрофон припинив запис"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Камера припинила запис"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Камера й мікрофон припинили запис"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 5a96fa876031..5afb43d42a69 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"کھولنے کیلئے دوبارہ تھپتھپائیں"</string>
<string name="tap_again" msgid="1315420114387908655">"دوبارہ تھپتھپائیں"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"کھولنے کے لیے اوپر سوائپ کريں"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"کھولنے کے لیے دبائیں"</string>
<string name="keyguard_retry" msgid="886802522584053523">"دوبارہ کوشش کرنے کے لیے اوپر سوائپ کريں"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"‏NFC استعمال کرنے کیلئے غیر مقفل کریں"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"یہ آلہ آپ کی تنظیم کا ہے"</string>
diff --git a/packages/SystemUI/res/values-ur/strings_tv.xml b/packages/SystemUI/res/values-ur/strings_tv.xml
index fbaa3f628bf3..566b33fe633b 100644
--- a/packages/SystemUI/res/values-ur/strings_tv.xml
+++ b/packages/SystemUI/res/values-ur/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"بذریعہ <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"اطلاعات"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"کوئی اطلاع نہیں ہے"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"مائیکروفون ریکارڈ کر رہا ہے"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"کیمرا ریکارڈ کر رہا ہے"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"کیمرا اور مائیکروفون ریکارڈ کر رہا ہے"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"مائیکروفون نے ریکارڈ کرنا بند کر دیا"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"کیمرے نے ریکارڈ کرنا بند کر دیا"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"کیمرے اور مائیکروفون نے ریکارڈ کرنا بند کر دیا"</string>
</resources>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index d96ea064aaac..7968452ec284 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Ochish uchun yana bosing"</string>
<string name="tap_again" msgid="1315420114387908655">"Yana bosing"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Ochish uchun tepaga suring"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"Ochish uchun bosing"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Qayta urinish uchun tepaga suring"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC ishlatish uchun qurilma qulfini oching"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Bu qurilma tashkilotingizga tegishli"</string>
diff --git a/packages/SystemUI/res/values-uz/strings_tv.xml b/packages/SystemUI/res/values-uz/strings_tv.xml
index f4b4b0853e69..afa82bc99a89 100644
--- a/packages/SystemUI/res/values-uz/strings_tv.xml
+++ b/packages/SystemUI/res/values-uz/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"<xliff:g id="VPN_APP">%1$s</xliff:g> orqali"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Bildirishnomalar"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Bildirishnomalar yoʻq"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"Mikrofon yozib olmoqda"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"Kamera yozib olmoqda"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Kamera va mikrofon yozib olmoqda"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Mikrofon yozib olishni toʻxtatdi"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Kamera yozib olishni toʻxtatdi"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Kamera va mikrofon yozib olishni toʻxtatdi"</string>
</resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 54b49671be36..50e45cb9c114 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Nhấn lại để mở"</string>
<string name="tap_again" msgid="1315420114387908655">"Nhấn lại"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Vuốt lên để mở"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"Nhấn để mở"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Vuốt lên để thử lại"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"Mở khóa để sử dụng NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Thiết bị này thuộc về tổ chức của bạn"</string>
diff --git a/packages/SystemUI/res/values-vi/strings_tv.xml b/packages/SystemUI/res/values-vi/strings_tv.xml
index 3dfc8c186205..014488441d73 100644
--- a/packages/SystemUI/res/values-vi/strings_tv.xml
+++ b/packages/SystemUI/res/values-vi/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Thông qua <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Thông báo"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Không có thông báo"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"Micrô đang ghi"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"Máy ảnh đang ghi"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Máy ảnh và micrô đang ghi"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Micrô đã dừng ghi"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Máy ảnh đã dừng ghi"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Máy ảnh và micrô đã dừng ghi"</string>
</resources>
diff --git a/packages/SystemUI/res/values-w390dp/config.xml b/packages/SystemUI/res/values-w390dp/config.xml
new file mode 100644
index 000000000000..222d8484ce22
--- /dev/null
+++ b/packages/SystemUI/res/values-w390dp/config.xml
@@ -0,0 +1,19 @@
+<!--
+ ~ Copyright (C) 2021 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<resources>
+ <bool name="config_showBatteryEstimateQSBH">true</bool>
+</resources> \ No newline at end of file
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 3cbcf3119437..2291902333ba 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"再次点按即可打开"</string>
<string name="tap_again" msgid="1315420114387908655">"请再点按一次"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"向上滑动即可打开"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"按一下即可打开"</string>
<string name="keyguard_retry" msgid="886802522584053523">"向上滑动即可重试"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"需要解锁才能使用 NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"此设备归贵单位所有"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings_tv.xml b/packages/SystemUI/res/values-zh-rCN/strings_tv.xml
index 1e599cabcd0b..ed914c90e627 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings_tv.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"通过“<xliff:g id="VPN_APP">%1$s</xliff:g>”"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"通知"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"没有通知"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"麦克风正在录制"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"相机正在录制"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"相机和麦克风正在录制"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"麦克风已停止录制"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"相机已停止录制"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"相机和麦克风已停止录制"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 726947ff2e53..38228895297b 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"再次輕按即可開啟"</string>
<string name="tap_again" msgid="1315420114387908655">"再次輕按"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"向上滑動即可開啟"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"按下即可開啟"</string>
<string name="keyguard_retry" msgid="886802522584053523">"請向上滑動以再試一次"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"解鎖方可使用 NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"此裝置屬於您的機構"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings_tv.xml b/packages/SystemUI/res/values-zh-rHK/strings_tv.xml
index 92b176261f7b..dfc34e5f098d 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings_tv.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"透過 <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"通知"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"沒有通知"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"麥克風正在錄音"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"相機正在錄影"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"相機和麥克風正在錄影及錄音"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"麥克風已停止錄音"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"相機已停止錄影"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"相機和麥克風已停止錄影及錄音"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 437bece4a6c3..fd6ad7ad5bd7 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"再次輕觸即可開啟"</string>
<string name="tap_again" msgid="1315420114387908655">"再輕觸一次"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"向上滑動即可開啟"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"按下即可開啟"</string>
<string name="keyguard_retry" msgid="886802522584053523">"向上滑動即可重試"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"如要使用 NFC,請先解鎖"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"這部裝置的擁有者為貴機構"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings_tv.xml b/packages/SystemUI/res/values-zh-rTW/strings_tv.xml
index db0781acf3b5..869ac483d5d8 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings_tv.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"透過「<xliff:g id="VPN_APP">%1$s</xliff:g>」"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"通知"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"沒有通知"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"麥克風正在錄音"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"相機正在錄影"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"相機和麥克風正在錄影及錄音"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"麥克風已停止錄音"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"相機已停止錄影"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"相機和麥克風已停止錄影及錄音"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 6b7d577e3db9..58ecc7c3b147 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -452,6 +452,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Thepha futhi ukuze uvule"</string>
<string name="tap_again" msgid="1315420114387908655">"Thepha futhi"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Swayiphela phezulu ukuze uvule"</string>
+ <string name="keyguard_unlock_press" msgid="8488350566398524740">"Chofoza ukuze uvule"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Swayiphela phezulu ukuze uzame futhi"</string>
<string name="require_unlock_for_nfc" msgid="1305686454823018831">"Vula ukuze usebenzise i-NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Le divayisi eyenhlangano yakho"</string>
diff --git a/packages/SystemUI/res/values-zu/strings_tv.xml b/packages/SystemUI/res/values-zu/strings_tv.xml
index a9b759766078..a3e525524582 100644
--- a/packages/SystemUI/res/values-zu/strings_tv.xml
+++ b/packages/SystemUI/res/values-zu/strings_tv.xml
@@ -26,4 +26,10 @@
<string name="notification_disclosure_vpn_text" msgid="3873532735584866236">"Nge-<xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
<string name="tv_notification_panel_title" msgid="5311050946506276154">"Izaziso"</string>
<string name="tv_notification_panel_no_notifications" msgid="9115191912267270678">"Azikho Izaziso"</string>
+ <string name="mic_recording_announcement" msgid="7587123608060316575">"Imakrofoni iyarekhoda"</string>
+ <string name="camera_recording_announcement" msgid="7240177719403759112">"Ikhamera iyarekhoda"</string>
+ <string name="mic_and_camera_recording_announcement" msgid="8599231390508812667">"Ikhamera nemakrofoni kuyarekhoda"</string>
+ <string name="mic_stopped_recording_announcement" msgid="7301537004900721242">"Imakrofoni iyekile ukurekhoda"</string>
+ <string name="camera_stopped_recording_announcement" msgid="8540496432367032801">"Ikhamera iyeke ukurekhoda"</string>
+ <string name="mic_camera_stopped_recording_announcement" msgid="8708524579599977412">"Ikhemera nemakrofoni kuyekile ukurekhoda"</string>
</resources>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 47fe579883bd..4a6efddd87c3 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -543,6 +543,11 @@
<item>@*android:string/status_bar_headset</item>
</string-array>
+
+ <!-- Whether to show estimate in QS header. Default to false in case there's not enough
+ space -->
+ <bool name="config_showBatteryEstimateQSBH">false</bool>
+
<!-- A path similar to frameworks/base/core/res/res/values/config.xml
config_mainBuiltInDisplayCutout that describes a path larger than the exact path of a display
cutout. If present as well as config_enableDisplayCutoutProtection is set to true, then
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index ae09f2689d92..34f8503ac1dd 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -906,8 +906,8 @@
<dimen name="keyguard_affordance_height">48dp</dimen>
<dimen name="keyguard_affordance_width">48dp</dimen>
- <dimen name="keyguard_affordance_wallet_height">48dp</dimen>
- <dimen name="keyguard_affordance_wallet_width">48dp</dimen>
+ <dimen name="keyguard_affordance_fixed_height">48dp</dimen>
+ <dimen name="keyguard_affordance_fixed_width">48dp</dimen>
<dimen name="keyguard_affordance_horizontal_offset">32dp</dimen>
<dimen name="keyguard_affordance_vertical_offset">32dp</dimen>
@@ -1456,7 +1456,7 @@
<dimen name="lockscreen_shade_notification_movement">24dp</dimen>
<!-- Maximum overshoot for the pulse expansion -->
- <dimen name="pulse_expansion_max_top_overshoot">16dp</dimen>
+ <dimen name="pulse_expansion_max_top_overshoot">32dp</dimen>
<dimen name="people_space_widget_radius">28dp</dimen>
<dimen name="people_space_image_radius">20dp</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 5aff817baf7c..04e5dd15c5c5 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1064,6 +1064,9 @@
<!-- Message shown when lock screen is tapped or face authentication fails. [CHAR LIMIT=60] -->
<string name="keyguard_unlock">Swipe up to open</string>
+ <!-- Message shown when lock screen is tapped or face authentication fails. Provides extra instructions for how the user can enter their device (unlock or proceed to home) [CHAR LIMIT=60] -->
+ <string name="keyguard_unlock_press">Press to open</string>
+
<!-- Message shown when face authentication fails and the pin pad is visible. [CHAR LIMIT=60] -->
<string name="keyguard_retry">Swipe up to try again</string>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 70ed81788e58..51eabf60385e 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -764,6 +764,8 @@
<item name="android:windowBackground">@android:color/black</item>
<item name="android:windowAnimationStyle">@null</item>
<item name="android:statusBarColor">@android:color/black</item>
+ <!-- Setting a placeholder will avoid using the SystemUI icon on the splash screen -->
+ <item name="android:windowSplashScreenAnimatedIcon">@drawable/ic_blank</item>
<item name="wallpaperTextColor">@*android:color/primary_text_material_dark</item>
</style>
@@ -898,5 +900,7 @@
<style name="Wallet.Theme" parent="@android:style/Theme.DeviceDefault">
<item name="android:colorBackground">@android:color/system_neutral1_900</item>
<item name="android:itemBackground">@android:color/system_neutral1_800</item>
+ <!-- Setting a placeholder will avoid using the SystemUI icon on the splash screen. -->
+ <item name="android:windowSplashScreenAnimatedIcon">@drawable/ic_blank</item>
</style>
</resources>
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java
index 90c1e402d248..3a3d30861132 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java
@@ -209,6 +209,11 @@ public class KeyguardPasswordView extends KeyguardAbsKeyInputView {
@Override
public void onCancelled(
@Nullable WindowInsetsAnimationController controller) {
+ // It is possible to be denied control of ime insets, which means onReady
+ // is never called. We still need to notify the runnables in order to
+ // complete the bouncer disappearing
+ runOnFinishImeAnimationRunnable();
+ finishRunnable.run();
}
});
return true;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 1f803aa97948..84accf809abe 100755
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -150,7 +150,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
private static final boolean DEBUG_SIM_STATES = KeyguardConstants.DEBUG_SIM_STATES;
private static final boolean DEBUG_FACE = Build.IS_DEBUGGABLE;
private static final boolean DEBUG_SPEW = false;
- private static final int LOW_BATTERY_THRESHOLD = 20;
+ private static final int FINGERPRINT_LOCKOUT_RESET_DELAY_MS = 600;
private static final String ACTION_FACE_UNLOCK_STARTED
= "com.android.facelock.FACE_UNLOCK_STARTED";
@@ -838,7 +838,18 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
private void handleFingerprintLockoutReset() {
mFingerprintLockedOut = false;
mFingerprintLockedOutPermanent = false;
- updateFingerprintListeningState();
+
+ if (isUdfpsEnrolled()) {
+ // TODO(b/194825098): update the reset signal(s)
+ // A successful unlock will trigger a lockout reset, but there is no guarantee
+ // that the events will arrive in a particular order. Add a delay here in case
+ // an unlock is in progress. In this is a normal unlock the extra delay won't
+ // be noticeable.
+ mHandler.postDelayed(this::updateFingerprintListeningState,
+ FINGERPRINT_LOCKOUT_RESET_DELAY_MS);
+ } else {
+ updateFingerprintListeningState();
+ }
}
private void setFingerprintRunningState(int fingerprintRunningState) {
@@ -2073,6 +2084,15 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
}
/**
+ * @return if udfps is available on this device. will return true even if the user hasn't
+ * enrolled udfps.
+ */
+ public boolean isUdfpsAvailable() {
+ return mAuthController.getUdfpsProps() != null
+ && !mAuthController.getUdfpsProps().isEmpty();
+ }
+
+ /**
* @return true if there's at least one face enrolled
*/
public boolean isFaceEnrolled() {
@@ -2403,8 +2423,10 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
if (isEncryptedOrLockdown(userId) && supportsFaceDetection) {
mFaceManager.detectFace(mFaceCancelSignal, mFaceDetectionCallback, userId);
} else {
+ final boolean isBypassEnabled = mKeyguardBypassController != null
+ && mKeyguardBypassController.isBypassEnabled();
mFaceManager.authenticate(null /* crypto */, mFaceCancelSignal,
- mFaceAuthenticationCallback, null /* handler */, userId);
+ mFaceAuthenticationCallback, null /* handler */, userId, isBypassEnabled);
}
setFaceRunningState(BIOMETRIC_STATE_RUNNING);
}
diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconView.java b/packages/SystemUI/src/com/android/keyguard/LockIconView.java
index c1d448db1e63..622419a86bfc 100644
--- a/packages/SystemUI/src/com/android/keyguard/LockIconView.java
+++ b/packages/SystemUI/src/com/android/keyguard/LockIconView.java
@@ -17,15 +17,21 @@
package com.android.keyguard;
import android.content.Context;
+import android.content.res.ColorStateList;
import android.graphics.PointF;
import android.graphics.RectF;
+import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
+import android.view.Gravity;
+import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import androidx.annotation.NonNull;
+import com.android.settingslib.Utils;
import com.android.systemui.Dumpable;
+import com.android.systemui.R;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -33,16 +39,47 @@ import java.io.PrintWriter;
/**
* A view positioned under the notification shade.
*/
-public class LockIconView extends ImageView implements Dumpable {
+public class LockIconView extends FrameLayout implements Dumpable {
@NonNull private final RectF mSensorRect;
@NonNull private PointF mLockIconCenter = new PointF(0f, 0f);
private int mRadius;
+ private ImageView mLockIcon;
+ private ImageView mUnlockBgView;
+
+ private int mLockIconColor;
+
public LockIconView(Context context, AttributeSet attrs) {
super(context, attrs);
mSensorRect = new RectF();
}
+ @Override
+ public void onFinishInflate() {
+ super.onFinishInflate();
+ mLockIcon = findViewById(R.id.lock_icon);
+ mUnlockBgView = findViewById(R.id.lock_icon_bg);
+ }
+
+ void updateColorAndBackgroundVisibility(boolean useBackground) {
+ if (useBackground) {
+ mLockIconColor = Utils.getColorAttrDefaultColor(getContext(),
+ android.R.attr.textColorPrimary);
+ mUnlockBgView.setBackground(getContext().getDrawable(R.drawable.fingerprint_bg));
+ mUnlockBgView.setVisibility(View.VISIBLE);
+ } else {
+ mLockIconColor = Utils.getColorAttrDefaultColor(getContext(),
+ R.attr.wallpaperTextColorAccent);
+ mUnlockBgView.setVisibility(View.GONE);
+ }
+
+ mLockIcon.setImageTintList(ColorStateList.valueOf(mLockIconColor));
+ }
+
+ void setImageDrawable(Drawable drawable) {
+ mLockIcon.setImageDrawable(drawable);
+ }
+
void setCenterLocation(@NonNull PointF center, int radius) {
mLockIconCenter = center;
mRadius = radius;
@@ -56,9 +93,12 @@ public class LockIconView extends ImageView implements Dumpable {
setX(mSensorRect.left);
setY(mSensorRect.top);
- setLayoutParams(new FrameLayout.LayoutParams(
+
+ final FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
(int) (mSensorRect.right - mSensorRect.left),
- (int) (mSensorRect.bottom - mSensorRect.top)));
+ (int) (mSensorRect.bottom - mSensorRect.top));
+ lp.gravity = Gravity.CENTER;
+ setLayoutParams(lp);
}
@Override
@@ -70,7 +110,6 @@ public class LockIconView extends ImageView implements Dumpable {
return mLockIconCenter.y - mRadius;
}
-
@Override
public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args) {
pw.println("Center in px (x, y)= (" + mLockIconCenter.x + ", " + mLockIconCenter.y + ")");
diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
index 9c8582fa334d..4317e258d8f7 100644
--- a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
@@ -43,7 +43,6 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
-import com.android.settingslib.Utils;
import com.android.systemui.Dumpable;
import com.android.systemui.R;
import com.android.systemui.biometrics.AuthController;
@@ -97,8 +96,8 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
@NonNull private final AnimatedVectorDrawable mLockToUnlockIcon;
@NonNull private final Drawable mLockIcon;
@NonNull private final Drawable mUnlockIcon;
- @NonNull private final CharSequence mUnlockedLabel;
- @NonNull private final CharSequence mLockedLabel;
+ @NonNull private CharSequence mUnlockedLabel;
+ @NonNull private CharSequence mLockedLabel;
@Nullable private final Vibrator mVibrator;
private boolean mIsDozing;
@@ -111,7 +110,7 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
private boolean mUserUnlockedWithBiometric;
private Runnable mCancelDelayedUpdateVisibilityRunnable;
- private boolean mHasUdfps;
+ private boolean mUdfpsSupported;
private float mHeightPixels;
private float mWidthPixels;
private int mBottomPadding; // in pixels
@@ -152,9 +151,8 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
final Context context = view.getContext();
mUnlockIcon = mView.getContext().getResources().getDrawable(
- R.anim.lock_to_unlock,
+ R.drawable.ic_unlock,
mView.getContext().getTheme());
- ((AnimatedVectorDrawable) mUnlockIcon).start();
mLockIcon = mView.getContext().getResources().getDrawable(
R.anim.lock_to_unlock,
mView.getContext().getTheme());
@@ -177,7 +175,7 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
protected void onViewAttached() {
// we check this here instead of onInit since the FingerprintManager + FaceManager may not
// have started up yet onInit
- mHasUdfps = mAuthController.getUdfpsSensorLocation() != null;
+ mUdfpsSupported = mAuthController.getUdfpsSensorLocation() != null;
updateConfiguration();
updateKeyguardShowing();
@@ -307,12 +305,7 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
}
private void updateColors() {
- final int color = Utils.getColorAttrDefaultColor(mView.getContext(),
- R.attr.wallpaperTextColorAccent);
- mFpToUnlockIcon.setTint(color);
- mLockToUnlockIcon.setTint(color);
- mLockIcon.setTint(color);
- mUnlockIcon.setTint(color);
+ mView.updateColorAndBackgroundVisibility(mUdfpsSupported);
}
private void updateConfiguration() {
@@ -321,11 +314,17 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
mHeightPixels = metrics.heightPixels;
mBottomPadding = mView.getContext().getResources().getDimensionPixelSize(
R.dimen.lock_icon_margin_bottom);
+
+ mUnlockedLabel = mView.getContext().getResources().getString(
+ R.string.accessibility_unlock_button);
+ mLockedLabel = mView.getContext()
+ .getResources().getString(R.string.accessibility_lock_icon);
+
updateLockIconLocation();
}
private void updateLockIconLocation() {
- if (mHasUdfps) {
+ if (mUdfpsSupported) {
FingerprintSensorPropertiesInternal props = mAuthController.getUdfpsProps().get(0);
mView.setCenterLocation(new PointF(props.sensorLocationX, props.sensorLocationY),
props.sensorRadius);
@@ -467,6 +466,7 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
@Override
public void onConfigChanged(Configuration newConfig) {
updateConfiguration();
+ updateColors();
}
};
@@ -560,7 +560,7 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
}
private boolean isClickable() {
- return mUdfpsEnrolled || mShowUnlockIcon;
+ return mUdfpsSupported || mShowUnlockIcon;
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
index 54e78cf0ab74..deceb951c2bb 100644
--- a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
@@ -195,6 +195,7 @@ public class BatteryMeterView extends LinearLayout implements
* @param mode desired mode (none, on, off)
*/
public void setPercentShowMode(@BatteryPercentMode int mode) {
+ if (mode == mShowPercentMode) return;
mShowPercentMode = mode;
updateShowPercent();
}
@@ -330,7 +331,7 @@ public class BatteryMeterView extends LinearLayout implements
if (mBatteryPercentView == null) {
return;
}
- if (estimate != null) {
+ if (estimate != null && mShowPercentMode == MODE_ESTIMATE) {
mBatteryPercentView.setText(estimate);
setContentDescription(getContext().getString(
R.string.accessibility_battery_level_with_estimate,
@@ -485,6 +486,7 @@ public class BatteryMeterView extends LinearLayout implements
pw.println(" mTextColor: #" + Integer.toHexString(mTextColor));
pw.println(" mBatteryStateUnknown: " + mBatteryStateUnknown);
pw.println(" mLevel: " + mLevel);
+ pw.println(" mMode: " + mShowPercentMode);
}
private final class SettingObserver extends ContentObserver {
diff --git a/packages/SystemUI/src/com/android/systemui/GuestResumeSessionReceiver.java b/packages/SystemUI/src/com/android/systemui/GuestResumeSessionReceiver.java
index 0ae89bc10290..b5b6b1340108 100644
--- a/packages/SystemUI/src/com/android/systemui/GuestResumeSessionReceiver.java
+++ b/packages/SystemUI/src/com/android/systemui/GuestResumeSessionReceiver.java
@@ -16,25 +16,24 @@
package com.android.systemui;
-import android.app.ActivityManager;
-import android.app.Dialog;
+import android.app.AlertDialog;
import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.UserInfo;
-import android.os.RemoteException;
import android.os.UserHandle;
-import android.provider.Settings;
import android.util.Log;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.UiEventLogger;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.qs.QSUserSwitcherEvent;
+import com.android.systemui.settings.UserTracker;
import com.android.systemui.statusbar.phone.SystemUIDialog;
import com.android.systemui.statusbar.policy.UserSwitcherController;
+import com.android.systemui.util.settings.SecureSettings;
/**
* Manages notification when a guest session is resumed.
@@ -43,16 +42,23 @@ public class GuestResumeSessionReceiver extends BroadcastReceiver {
private static final String TAG = "GuestResumeSessionReceiver";
- private static final String SETTING_GUEST_HAS_LOGGED_IN = "systemui.guest_has_logged_in";
+ @VisibleForTesting
+ public static final String SETTING_GUEST_HAS_LOGGED_IN = "systemui.guest_has_logged_in";
- private Dialog mNewSessionDialog;
+ @VisibleForTesting
+ public AlertDialog mNewSessionDialog;
+ private final UserTracker mUserTracker;
private final UserSwitcherController mUserSwitcherController;
private final UiEventLogger mUiEventLogger;
+ private final SecureSettings mSecureSettings;
public GuestResumeSessionReceiver(UserSwitcherController userSwitcherController,
- UiEventLogger uiEventLogger) {
+ UserTracker userTracker, UiEventLogger uiEventLogger,
+ SecureSettings secureSettings) {
mUserSwitcherController = userSwitcherController;
+ mUserTracker = userTracker;
mUiEventLogger = uiEventLogger;
+ mSecureSettings = secureSettings;
}
/**
@@ -78,26 +84,19 @@ public class GuestResumeSessionReceiver extends BroadcastReceiver {
return;
}
- UserInfo currentUser;
- try {
- currentUser = ActivityManager.getService().getCurrentUser();
- } catch (RemoteException e) {
- return;
- }
+ UserInfo currentUser = mUserTracker.getUserInfo();
if (!currentUser.isGuest()) {
return;
}
- ContentResolver cr = context.getContentResolver();
- int notFirstLogin = Settings.System.getIntForUser(
- cr, SETTING_GUEST_HAS_LOGGED_IN, 0, userId);
+ int notFirstLogin = mSecureSettings.getIntForUser(
+ SETTING_GUEST_HAS_LOGGED_IN, 0, userId);
if (notFirstLogin != 0) {
mNewSessionDialog = new ResetSessionDialog(context, mUserSwitcherController,
mUiEventLogger, userId);
mNewSessionDialog.show();
} else {
- Settings.System.putIntForUser(
- cr, SETTING_GUEST_HAS_LOGGED_IN, 1, userId);
+ mSecureSettings.putIntForUser(SETTING_GUEST_HAS_LOGGED_IN, 1, userId);
}
}
}
@@ -109,18 +108,26 @@ public class GuestResumeSessionReceiver extends BroadcastReceiver {
}
}
- private static class ResetSessionDialog extends SystemUIDialog implements
+ /**
+ * Dialog shown when user when asking for confirmation before deleting guest user.
+ */
+ @VisibleForTesting
+ public static class ResetSessionDialog extends SystemUIDialog implements
DialogInterface.OnClickListener {
- private static final int BUTTON_WIPE = BUTTON_NEGATIVE;
- private static final int BUTTON_DONTWIPE = BUTTON_POSITIVE;
+ @VisibleForTesting
+ public static final int BUTTON_WIPE = BUTTON_NEGATIVE;
+ @VisibleForTesting
+ public static final int BUTTON_DONTWIPE = BUTTON_POSITIVE;
private final UserSwitcherController mUserSwitcherController;
private final UiEventLogger mUiEventLogger;
private final int mUserId;
- ResetSessionDialog(Context context, UserSwitcherController userSwitcherController,
- UiEventLogger uiEventLogger, int userId) {
+ ResetSessionDialog(Context context,
+ UserSwitcherController userSwitcherController,
+ UiEventLogger uiEventLogger,
+ int userId) {
super(context);
setTitle(context.getString(R.string.guest_wipe_session_title));
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFaceToFingerprintView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFaceToFingerprintView.java
index 205054d68280..98ad87506819 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFaceToFingerprintView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFaceToFingerprintView.java
@@ -93,6 +93,8 @@ public class AuthBiometricFaceToFingerprintView extends AuthBiometricFaceView {
@Nullable private ModalityListener mModalityListener;
@Nullable private FingerprintSensorPropertiesInternal mFingerprintSensorProps;
@Nullable private UdfpsDialogMeasureAdapter mUdfpsMeasureAdapter;
+ @Nullable @VisibleForTesting UdfpsIconController mUdfpsIconController;
+
public AuthBiometricFaceToFingerprintView(Context context) {
super(context);
@@ -107,6 +109,12 @@ public class AuthBiometricFaceToFingerprintView extends AuthBiometricFaceView {
super(context, attrs, injector);
}
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ mUdfpsIconController = new UdfpsIconController(mContext, mIconView, mIndicatorView);
+ }
+
@Modality
int getActiveSensorType() {
return mActiveSensorType;
@@ -168,35 +176,26 @@ public class AuthBiometricFaceToFingerprintView extends AuthBiometricFaceView {
}
@Override
- @NonNull
- protected IconController getIconController() {
- if (mActiveSensorType == TYPE_FINGERPRINT) {
- if (!(mIconController instanceof UdfpsIconController)) {
- mIconController = createUdfpsIconController();
- }
- return mIconController;
- }
- return super.getIconController();
- }
-
- @NonNull
- protected IconController createUdfpsIconController() {
- return new UdfpsIconController(getContext(), mIconView, mIndicatorView);
- }
-
- @Override
public void updateState(@BiometricState int newState) {
- if (mState == STATE_HELP || mState == STATE_ERROR) {
- @Modality final int currentType = mActiveSensorType;
- mActiveSensorType = TYPE_FINGERPRINT;
+ if (mActiveSensorType == TYPE_FACE) {
+ if (newState == STATE_HELP || newState == STATE_ERROR) {
+ mActiveSensorType = TYPE_FINGERPRINT;
+
+ setRequireConfirmation(false);
+ mConfirmButton.setEnabled(false);
+ mConfirmButton.setVisibility(View.GONE);
- setRequireConfirmation(false);
- mConfirmButton.setEnabled(false);
- mConfirmButton.setVisibility(View.GONE);
+ if (mModalityListener != null) {
+ mModalityListener.onModalitySwitched(TYPE_FACE, mActiveSensorType);
+ }
- if (mModalityListener != null && currentType != mActiveSensorType) {
- mModalityListener.onModalitySwitched(currentType, mActiveSensorType);
+ // Deactivate the face icon controller so it stops drawing to the view
+ mFaceIconController.deactivate();
+ // Then, activate this icon controller. We need to start in the "error" state
+ mUdfpsIconController.updateState(mState, newState);
}
+ } else { // Fingerprint
+ mUdfpsIconController.updateState(mState, newState);
}
super.updateState(newState);
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFaceView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFaceView.java
index e8da7c51bf0d..c32c1a2f3e53 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFaceView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFaceView.java
@@ -49,6 +49,7 @@ public class AuthBiometricFaceView extends AuthBiometricView {
protected Handler mHandler;
protected boolean mLastPulseLightToDark; // false = dark to light, true = light to dark
protected @BiometricState int mState;
+ protected boolean mDeactivated;
protected IconController(Context context, ImageView iconView, TextView textView) {
mContext = context;
@@ -67,6 +68,11 @@ public class AuthBiometricFaceView extends AuthBiometricView {
}
protected void animateIcon(int iconRes, boolean repeat) {
+ Log.d(TAG, "animateIcon, state: " + mState + ", deactivated: " + mDeactivated);
+ if (mDeactivated) {
+ return;
+ }
+
final AnimatedVectorDrawable icon =
(AnimatedVectorDrawable) mContext.getDrawable(iconRes);
mIconView.setImageDrawable(icon);
@@ -92,12 +98,26 @@ public class AuthBiometricFaceView extends AuthBiometricView {
@Override
public void onAnimationEnd(Drawable drawable) {
super.onAnimationEnd(drawable);
+ Log.d(TAG, "onAnimationEnd, mState: " + mState + ", deactivated: " + mDeactivated);
+ if (mDeactivated) {
+ return;
+ }
+
if (mState == STATE_AUTHENTICATING || mState == STATE_HELP) {
pulseInNextDirection();
}
}
+ protected void deactivate() {
+ mDeactivated = true;
+ }
+
protected void updateState(int lastState, int newState) {
+ if (mDeactivated) {
+ Log.w(TAG, "Ignoring updateState when deactivated: " + newState);
+ return;
+ }
+
final boolean lastStateIsErrorIcon =
lastState == STATE_ERROR || lastState == STATE_HELP;
@@ -142,7 +162,7 @@ public class AuthBiometricFaceView extends AuthBiometricView {
}
}
- protected IconController mIconController;
+ @Nullable @VisibleForTesting IconController mFaceIconController;
public AuthBiometricFaceView(Context context) {
this(context, null);
@@ -158,6 +178,12 @@ public class AuthBiometricFaceView extends AuthBiometricView {
}
@Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ mFaceIconController = new IconController(mContext, mIconView, mIndicatorView);
+ }
+
+ @Override
protected int getDelayAfterAuthenticatedDurationMs() {
return HIDE_DELAY_MS;
}
@@ -187,17 +213,9 @@ public class AuthBiometricFaceView extends AuthBiometricView {
return true;
}
- @NonNull
- protected IconController getIconController() {
- if (mIconController == null) {
- mIconController = new IconController(mContext, mIconView, mIndicatorView);
- }
- return mIconController;
- }
-
@Override
public void updateState(@BiometricState int newState) {
- getIconController().updateState(mState, newState);
+ mFaceIconController.updateState(mState, newState);
if (newState == STATE_AUTHENTICATING_ANIMATING_IN ||
(newState == STATE_AUTHENTICATING && getSize() == AuthDialog.SIZE_MEDIUM)) {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index 950bd8319755..e612fb4712fc 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -72,6 +72,7 @@ import com.android.systemui.statusbar.LockscreenShadeTransitionController;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
+import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.concurrency.DelayableExecutor;
import com.android.systemui.util.concurrency.Execution;
@@ -123,6 +124,7 @@ public class UdfpsController implements DozeReceiver {
@NonNull private final LockscreenShadeTransitionController mLockscreenShadeTransitionController;
@Nullable private final UdfpsHbmProvider mHbmProvider;
@NonNull private final KeyguardBypassController mKeyguardBypassController;
+ @NonNull private final ConfigurationController mConfigurationController;
@VisibleForTesting @NonNull final BiometricOrientationEventListener mOrientationListener;
// Currently the UdfpsController supports a single UDFPS sensor. If devices have multiple
// sensors, this, in addition to a lot of the code here, will be updated.
@@ -522,7 +524,8 @@ public class UdfpsController implements DozeReceiver {
@NonNull KeyguardStateController keyguardStateController,
@NonNull KeyguardBypassController keyguardBypassController,
@NonNull DisplayManager displayManager,
- @Main Handler mainHandler) {
+ @Main Handler mainHandler,
+ @NonNull ConfigurationController configurationController) {
mContext = context;
mExecution = execution;
// TODO (b/185124905): inject main handler and vibrator once done prototyping
@@ -557,6 +560,7 @@ public class UdfpsController implements DozeReceiver {
displayManager,
mainHandler);
mKeyguardBypassController = keyguardBypassController;
+ mConfigurationController = configurationController;
mSensorProps = findFirstUdfps();
// At least one UDFPS sensor exists
@@ -776,6 +780,7 @@ public class UdfpsController implements DozeReceiver {
mDumpManager,
mKeyguardViewMediator,
mLockscreenShadeTransitionController,
+ mConfigurationController,
this
);
case IUdfpsOverlayController.REASON_AUTH_BP:
@@ -883,11 +888,16 @@ public class UdfpsController implements DozeReceiver {
private void onFingerDown(int x, int y, float minor, float major) {
mExecution.assertIsMainThread();
- mKeyguardBypassController.setUserHasDeviceEntryIntent(true);
if (mView == null) {
Log.w(TAG, "Null view in onFingerDown");
return;
}
+
+ if (mView.getAnimationViewController() instanceof UdfpsKeyguardViewController
+ && !mStatusBarStateController.isDozing()) {
+ mKeyguardBypassController.setUserHasDeviceEntryIntent(true);
+ }
+
if (!mOnFingerDown) {
playStartHaptic();
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java
index eb02aa0d9cdf..d122610c395d 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java
@@ -22,7 +22,6 @@ import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInProgressOff
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
-import android.animation.ArgbEvaluator;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
@@ -51,17 +50,14 @@ public class UdfpsKeyguardView extends UdfpsAnimationView {
private UdfpsDrawable mFingerprintDrawable; // placeholder
private LottieAnimationView mAodFp;
private LottieAnimationView mLockScreenFp;
- private int mUdfpsBouncerColor;
- private int mWallpaperTextColor;
private int mStatusBarState;
// used when highlighting fp icon:
private int mTextColorPrimary;
private ImageView mBgProtection;
boolean mUdfpsRequested;
- int mUdfpsRequestedColor;
- private AnimatorSet mAnimatorSet;
+ private AnimatorSet mBackgroundInAnimator = new AnimatorSet();
private int mAlpha; // 0-255
// AOD anti-burn-in offsets
@@ -89,20 +85,15 @@ public class UdfpsKeyguardView extends UdfpsAnimationView {
super.onFinishInflate();
mAodFp = findViewById(R.id.udfps_aod_fp);
mLockScreenFp = findViewById(R.id.udfps_lockscreen_fp);
-
mBgProtection = findViewById(R.id.udfps_keyguard_fp_bg);
- mWallpaperTextColor = Utils.getColorAttrDefaultColor(mContext,
- R.attr.wallpaperTextColorAccent);
- mTextColorPrimary = Utils.getColorAttrDefaultColor(mContext,
- android.R.attr.textColorPrimary);
+ updateColor();
- // requires call to invalidate to update the color (see #updateColor)
+ // requires call to invalidate to update the color
mLockScreenFp.addValueCallback(
new KeyPath("**"), LottieProperty.COLOR_FILTER,
- frameInfo -> new PorterDuffColorFilter(getColor(), PorterDuff.Mode.SRC_ATOP)
+ frameInfo -> new PorterDuffColorFilter(mTextColorPrimary, PorterDuff.Mode.SRC_ATOP)
);
- mUdfpsRequested = false;
mHintAnimator = ObjectAnimator.ofFloat(mLockScreenFp, "progress", 1f, 0f, 1f);
mHintAnimator.setDuration(4000);
@@ -148,13 +139,7 @@ public class UdfpsKeyguardView extends UdfpsAnimationView {
}
void requestUdfps(boolean request, int color) {
- if (request) {
- mUdfpsRequestedColor = color;
- } else {
- mUdfpsRequestedColor = -1;
- }
mUdfpsRequested = request;
- updateColor();
}
void setStatusBarState(int statusBarState) {
@@ -162,31 +147,10 @@ public class UdfpsKeyguardView extends UdfpsAnimationView {
}
void updateColor() {
- mWallpaperTextColor = Utils.getColorAttrDefaultColor(mContext,
- R.attr.wallpaperTextColorAccent);
mTextColorPrimary = Utils.getColorAttrDefaultColor(mContext,
android.R.attr.textColorPrimary);
- mLockScreenFp.invalidate();
- mBgProtection.setBackground(getContext().getDrawable(R.drawable.fingerprint_bg));
- }
-
- private boolean showingUdfpsBouncer() {
- return mBgProtection.getVisibility() == View.VISIBLE;
- }
-
-
- private int getColor() {
- if (isUdfpsColorRequested()) {
- return mUdfpsRequestedColor;
- } else if (showingUdfpsBouncer()) {
- return mUdfpsBouncerColor;
- } else {
- return mWallpaperTextColor;
- }
- }
-
- private boolean isUdfpsColorRequested() {
- return mUdfpsRequested && mUdfpsRequestedColor != -1;
+ mBgProtection.setImageDrawable(getContext().getDrawable(R.drawable.fingerprint_bg));
+ mLockScreenFp.invalidate(); // updated with a valueCallback
}
/**
@@ -200,7 +164,13 @@ public class UdfpsKeyguardView extends UdfpsAnimationView {
@Override
protected int updateAlpha() {
int alpha = super.updateAlpha();
- mLockScreenFp.setImageAlpha(alpha);
+ mLockScreenFp.setAlpha(alpha / 255f);
+ if (mInterpolatedDarkAmount != 0f) {
+ mBgProtection.setAlpha(1f - mInterpolatedDarkAmount);
+ } else {
+ mBgProtection.setAlpha(alpha / 255f);
+ }
+
return alpha;
}
@@ -215,6 +185,7 @@ public class UdfpsKeyguardView extends UdfpsAnimationView {
void onDozeAmountChanged(float linear, float eased) {
mHintAnimator.cancel();
mInterpolatedDarkAmount = eased;
+ updateAlpha();
updateBurnInOffsets();
}
@@ -228,52 +199,21 @@ public class UdfpsKeyguardView extends UdfpsAnimationView {
/**
* Animates in the bg protection circle behind the fp icon to highlight the icon.
*/
- void animateUdfpsBouncer(Runnable onEndAnimation) {
- if (showingUdfpsBouncer() && mBgProtection.getAlpha() == 1f) {
- // already fully highlighted, don't re-animate
+ void animateInUdfpsBouncer(Runnable onEndAnimation) {
+ if (mBackgroundInAnimator.isRunning()) {
+ // already animating in
return;
}
- if (mAnimatorSet != null) {
- mAnimatorSet.cancel();
- }
-
- mAnimatorSet = new AnimatorSet();
- mAnimatorSet.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
- mAnimatorSet.setDuration(500);
- mAnimatorSet.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationStart(Animator animation) {
- mBgProtection.setVisibility(View.VISIBLE);
- }
- });
-
- ValueAnimator fpIconColorAnim;
- if (isShadeLocked()) {
- // set color and fade in since we weren't showing before
- mUdfpsBouncerColor = mTextColorPrimary;
- fpIconColorAnim = ValueAnimator.ofInt(0, 255);
- fpIconColorAnim.addUpdateListener(valueAnimator ->
- mLockScreenFp.setImageAlpha((int) valueAnimator.getAnimatedValue()));
- } else {
- // update icon color
- fpIconColorAnim = new ValueAnimator();
- fpIconColorAnim.setIntValues(
- isUdfpsColorRequested() ? mUdfpsRequestedColor : mWallpaperTextColor,
- mTextColorPrimary);
- fpIconColorAnim.setEvaluator(ArgbEvaluator.getInstance());
- fpIconColorAnim.addUpdateListener(valueAnimator -> {
- mUdfpsBouncerColor = (int) valueAnimator.getAnimatedValue();
- updateColor();
- });
- }
-
- mAnimatorSet.playTogether(
+ // fade in and scale up
+ mBackgroundInAnimator = new AnimatorSet();
+ mBackgroundInAnimator.playTogether(
ObjectAnimator.ofFloat(mBgProtection, View.ALPHA, 0f, 1f),
ObjectAnimator.ofFloat(mBgProtection, View.SCALE_X, 0f, 1f),
- ObjectAnimator.ofFloat(mBgProtection, View.SCALE_Y, 0f, 1f),
- fpIconColorAnim);
- mAnimatorSet.addListener(new AnimatorListenerAdapter() {
+ ObjectAnimator.ofFloat(mBgProtection, View.SCALE_Y, 0f, 1f));
+ mBackgroundInAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
+ mBackgroundInAnimator.setDuration(500);
+ mBackgroundInAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
if (onEndAnimation != null) {
@@ -281,66 +221,7 @@ public class UdfpsKeyguardView extends UdfpsAnimationView {
}
}
});
- mAnimatorSet.start();
- }
-
- /**
- * Animates out the bg protection circle behind the fp icon to unhighlight the icon.
- */
- void animateAwayUdfpsBouncer(@Nullable Runnable onEndAnimation) {
- if (!showingUdfpsBouncer()) {
- // already hidden
- return;
- }
-
- if (mAnimatorSet != null) {
- mAnimatorSet.cancel();
- }
-
- ValueAnimator fpIconColorAnim;
- if (isShadeLocked()) {
- // fade out
- mUdfpsBouncerColor = mTextColorPrimary;
- fpIconColorAnim = ValueAnimator.ofInt(255, 0);
- fpIconColorAnim.addUpdateListener(valueAnimator ->
- mLockScreenFp.setImageAlpha((int) valueAnimator.getAnimatedValue()));
- } else {
- // update icon color
- fpIconColorAnim = new ValueAnimator();
- fpIconColorAnim.setIntValues(
- mTextColorPrimary,
- isUdfpsColorRequested() ? mUdfpsRequestedColor : mWallpaperTextColor);
- fpIconColorAnim.setEvaluator(ArgbEvaluator.getInstance());
- fpIconColorAnim.addUpdateListener(valueAnimator -> {
- mUdfpsBouncerColor = (int) valueAnimator.getAnimatedValue();
- updateColor();
- });
- }
-
- mAnimatorSet = new AnimatorSet();
- mAnimatorSet.playTogether(
- ObjectAnimator.ofFloat(mBgProtection, View.ALPHA, 1f, 0f),
- ObjectAnimator.ofFloat(mBgProtection, View.SCALE_X, 1f, 0f),
- ObjectAnimator.ofFloat(mBgProtection, View.SCALE_Y, 1f, 0f),
- fpIconColorAnim);
- mAnimatorSet.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
- mAnimatorSet.setDuration(500);
-
- mAnimatorSet.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- mBgProtection.setVisibility(View.GONE);
- if (onEndAnimation != null) {
- onEndAnimation.run();
- }
- }
- });
-
- mAnimatorSet.start();
- }
-
- boolean isAnimating() {
- return mAnimatorSet != null && mAnimatorSet.isRunning();
+ mBackgroundInAnimator.start();
}
private boolean isShadeLocked() {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java
index 6435bdd69872..58f1254da563 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java
@@ -19,6 +19,7 @@ package com.android.systemui.biometrics;
import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
import android.annotation.NonNull;
+import android.content.res.Configuration;
import android.hardware.biometrics.BiometricSourceType;
import android.util.MathUtils;
import android.view.MotionEvent;
@@ -36,6 +37,7 @@ import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.phone.KeyguardBouncer;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
+import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.util.concurrency.DelayableExecutor;
import java.io.FileDescriptor;
@@ -57,6 +59,7 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
@NonNull private final DelayableExecutor mExecutor;
@NonNull private final KeyguardViewMediator mKeyguardViewMediator;
@NonNull private final LockscreenShadeTransitionController mLockScreenShadeTransitionController;
+ @NonNull private final ConfigurationController mConfigurationController;
@NonNull private final UdfpsController mUdfpsController;
@Nullable private Runnable mCancelDelayedHintRunnable;
@@ -87,6 +90,7 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
@NonNull DumpManager dumpManager,
@NonNull KeyguardViewMediator keyguardViewMediator,
@NonNull LockscreenShadeTransitionController transitionController,
+ @NonNull ConfigurationController configurationController,
@NonNull UdfpsController udfpsController) {
super(view, statusBarStateController, statusBar, dumpManager);
mKeyguardViewManager = statusBarKeyguardViewManager;
@@ -94,6 +98,7 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
mExecutor = mainDelayableExecutor;
mKeyguardViewMediator = keyguardViewMediator;
mLockScreenShadeTransitionController = transitionController;
+ mConfigurationController = configurationController;
mUdfpsController = udfpsController;
}
@@ -120,6 +125,7 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
mQsExpanded = mKeyguardViewManager.isQsExpanded();
mInputBouncerHiddenAmount = KeyguardBouncer.EXPANSION_HIDDEN;
mIsBouncerVisible = mKeyguardViewManager.bouncerIsOrWillBeShowing();
+ mConfigurationController.addCallback(mConfigurationListener);
updateAlpha();
updatePauseAuth();
@@ -136,6 +142,7 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
mStatusBarStateController.removeCallback(mStateListener);
mKeyguardViewManager.removeAlternateAuthInterceptor(mAlternateAuthInterceptor);
mKeyguardUpdateMonitor.requestFaceAuthOnOccludingApp(false);
+ mConfigurationController.removeCallback(mConfigurationListener);
if (mLockScreenShadeTransitionController.getUdfpsKeyguardViewController() == this) {
mLockScreenShadeTransitionController.setUdfpsKeyguardViewController(null);
}
@@ -158,7 +165,6 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
pw.println("mAlpha=" + mView.getAlpha());
pw.println("mUdfpsRequested=" + mUdfpsRequested);
pw.println("mView.mUdfpsRequested=" + mView.mUdfpsRequested);
- pw.println("mView.mUdfpsRequestedColor=" + mView.mUdfpsRequestedColor);
}
/**
@@ -173,12 +179,17 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
mShowingUdfpsBouncer = show;
updatePauseAuth();
if (mShowingUdfpsBouncer) {
- mView.animateUdfpsBouncer(() ->
- mKeyguardUpdateMonitor.requestFaceAuthOnOccludingApp(true));
+ if (mStatusBarState == StatusBarState.SHADE_LOCKED) {
+ mView.animateInUdfpsBouncer(null);
+ }
+
+ if (mKeyguardViewManager.isOccluded()) {
+ mKeyguardUpdateMonitor.requestFaceAuthOnOccludingApp(true);
+ }
+
mView.announceForAccessibility(mView.getContext().getString(
R.string.accessibility_fingerprint_bouncer));
} else {
- mView.animateAwayUdfpsBouncer(null);
mKeyguardUpdateMonitor.requestFaceAuthOnOccludingApp(false);
}
return true;
@@ -366,7 +377,7 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
@Override
public boolean isAnimating() {
- return mView.isAnimating();
+ return false;
}
@Override
@@ -407,4 +418,27 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
pw.println(getTag());
}
};
+
+ private final ConfigurationController.ConfigurationListener mConfigurationListener =
+ new ConfigurationController.ConfigurationListener() {
+ @Override
+ public void onUiModeChanged() {
+ mView.updateColor();
+ }
+
+ @Override
+ public void onThemeChanged() {
+ mView.updateColor();
+ }
+
+ @Override
+ public void onOverlayChanged() {
+ mView.updateColor();
+ }
+
+ @Override
+ public void onConfigChanged(Configuration newConfig) {
+ mView.updateColor();
+ }
+ };
}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java
index 239a77eb2f45..9cb9a362d460 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java
@@ -39,6 +39,7 @@ import com.android.systemui.plugins.qs.QSFactory;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.power.EnhancedEstimates;
import com.android.systemui.power.EnhancedEstimatesImpl;
+import com.android.systemui.power.dagger.PowerModule;
import com.android.systemui.qs.dagger.QSModule;
import com.android.systemui.qs.tileimpl.QSFactoryImpl;
import com.android.systemui.recents.Recents;
@@ -80,6 +81,7 @@ import dagger.Provides;
*/
@Module(includes = {
MediaModule.class,
+ PowerModule.class,
QSModule.class
})
public abstract class SystemUIDefaultModule {
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
index 556f95642deb..46ab5f68abe9 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
@@ -41,7 +41,6 @@ import com.android.systemui.log.dagger.LogModule;
import com.android.systemui.model.SysUiState;
import com.android.systemui.plugins.BcSmartspaceDataPlugin;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.power.dagger.PowerModule;
import com.android.systemui.recents.Recents;
import com.android.systemui.screenshot.dagger.ScreenshotModule;
import com.android.systemui.settings.dagger.SettingsModule;
@@ -102,7 +101,6 @@ import dagger.Provides;
FalsingModule.class,
LogModule.class,
PeopleHubModule.class,
- PowerModule.class,
PluginModule.class,
ScreenshotModule.class,
SensorModule.class,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 277ecdfef52f..ae2602baf6c7 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -402,6 +402,12 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable,
private boolean mPendingLock;
/**
+ * When starting to go away, flag a need to show the PIN lock so the keyguard can be brought
+ * back.
+ */
+ private boolean mPendingPinLock = false;
+
+ /**
* Whether a power button gesture (such as double tap for camera) has been detected. This is
* delivered directly from {@link KeyguardService}, immediately upon the gesture being detected.
* This is used in {@link #onStartedWakingUp} to decide whether to execute the pending lock, or
@@ -475,6 +481,19 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable,
KeyguardUpdateMonitorCallback mUpdateCallback = new KeyguardUpdateMonitorCallback() {
@Override
+ public void onKeyguardVisibilityChanged(boolean showing) {
+ synchronized (KeyguardViewMediator.this) {
+ if (!showing && mPendingPinLock) {
+ Log.i(TAG, "PIN lock requested, starting keyguard");
+
+ // Bring the keyguard back in order to show the PIN lock
+ mPendingPinLock = false;
+ doKeyguardLocked(null);
+ }
+ }
+ }
+
+ @Override
public void onUserSwitching(int userId) {
if (DEBUG) Log.d(TAG, String.format("onUserSwitching %d", userId));
// Note that the mLockPatternUtils user has already been updated from setCurrentUser.
@@ -617,6 +636,7 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable,
+ "showing; need to show keyguard so user can enter sim pin");
doKeyguardLocked(null);
} else {
+ mPendingPinLock = true;
resetStateLocked();
}
}
@@ -765,6 +785,9 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable,
@Override
public void onBouncerVisiblityChanged(boolean shown) {
synchronized (KeyguardViewMediator.this) {
+ if (shown) {
+ mPendingPinLock = false;
+ }
adjustStatusBarLocked(shown, false);
}
}
@@ -2813,7 +2836,7 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable,
}
}
- private void setShowingLocked(boolean showing) {
+ void setShowingLocked(boolean showing) {
setShowingLocked(showing, false /* forceCallbacks */);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
index a3180738fa60..4fcd46c96fe3 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
@@ -423,6 +423,9 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
if (mQsPanelController.shouldUseHorizontalLayout()
&& mQsPanelController.mMediaHost.hostView != null) {
builder.addFloat(mQsPanelController.mMediaHost.hostView, "alpha", 0, 1);
+ } else {
+ // In portrait, media view should always be visible
+ mQsPanelController.mMediaHost.hostView.setAlpha(1.0f);
}
mAllPagesDelayedAnimator = builder.build();
mAllViews.add(mSecurityFooter.getView());
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
index e9b19e5cfa6f..59e5eb8d6ac8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
@@ -28,13 +28,17 @@ import android.view.View;
import android.view.WindowInsets;
import android.widget.FrameLayout;
+import com.android.systemui.Dumpable;
import com.android.systemui.R;
import com.android.systemui.qs.customize.QSCustomizer;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
/**
* Wrapper view with background which contains {@link QSPanel} and {@link QuickStatusBarHeader}
*/
-public class QSContainerImpl extends FrameLayout {
+public class QSContainerImpl extends FrameLayout implements Dumpable {
private final Point mSizePoint = new Point();
private int mFancyClippingTop;
@@ -296,4 +300,11 @@ public class QSContainerImpl extends FrameLayout {
mFancyClippingBottom, mFancyClippingRadii, Path.Direction.CW);
invalidate();
}
+
+ @Override
+ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ pw.println(getClass().getSimpleName() + " updateClippingPath: top("
+ + mFancyClippingTop + ") bottom(" + mFancyClippingBottom + ") mClippingEnabled("
+ + mClippingEnabled + ")");
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
index 0a1e9d04fab0..c9230d684b1b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
@@ -36,8 +36,10 @@ import android.widget.FrameLayout.LayoutParams;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
+import com.android.systemui.Dumpable;
import com.android.systemui.R;
import com.android.systemui.animation.Interpolators;
+import com.android.systemui.dump.DumpManager;
import com.android.systemui.media.MediaHost;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.qs.QS;
@@ -48,6 +50,7 @@ import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer;
import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
import com.android.systemui.util.InjectionInflationController;
@@ -69,6 +72,7 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
private final Rect mQsBounds = new Rect();
private final StatusBarStateController mStatusBarStateController;
private final FalsingManager mFalsingManager;
+ private final KeyguardBypassController mBypassController;
private boolean mQsExpanded;
private boolean mHeaderAnimating;
private boolean mStackScrollerOverscrolling;
@@ -129,14 +133,17 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
*/
private boolean mAnimateNextQsUpdate;
+ private DumpManager mDumpManager;
+
@Inject
public QSFragment(RemoteInputQuickSettingsDisabler remoteInputQsDisabler,
InjectionInflationController injectionInflater, QSTileHost qsTileHost,
StatusBarStateController statusBarStateController, CommandQueue commandQueue,
QSDetailDisplayer qsDetailDisplayer, @Named(QS_PANEL) MediaHost qsMediaHost,
@Named(QUICK_QS_PANEL) MediaHost qqsMediaHost,
+ KeyguardBypassController keyguardBypassController,
QSFragmentComponent.Factory qsComponentFactory, FeatureFlags featureFlags,
- FalsingManager falsingManager) {
+ FalsingManager falsingManager, DumpManager dumpManager) {
mRemoteInputQuickSettingsDisabler = remoteInputQsDisabler;
mInjectionInflater = injectionInflater;
mCommandQueue = commandQueue;
@@ -148,7 +155,9 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
mHost = qsTileHost;
mFeatureFlags = featureFlags;
mFalsingManager = falsingManager;
+ mBypassController = keyguardBypassController;
mStatusBarStateController = statusBarStateController;
+ mDumpManager = dumpManager;
}
@Override
@@ -193,6 +202,7 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
mQSContainerImplController = qsFragmentComponent.getQSContainerImplController();
mQSContainerImplController.init();
mContainer = mQSContainerImplController.getView();
+ mDumpManager.registerDumpable(mContainer.getClass().getName(), mContainer);
mQSDetail.setQsPanel(mQSPanelController, mHeader, mFooter, mFalsingManager);
mQSAnimator = qsFragmentComponent.getQSAnimator();
@@ -244,6 +254,7 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
mQSCustomizerController.setQs(null);
mQsDetailDisplayer.setQsPanelController(null);
mScrollListener = null;
+ mDumpManager.unregisterDumpable(mContainer.getClass().getName());
}
@Override
@@ -380,16 +391,8 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
return mStatusBarStateController.getState() == StatusBarState.KEYGUARD;
}
- @Override
- public void setPulseExpanding(boolean pulseExpanding) {
- if (pulseExpanding != mPulseExpanding) {
- mPulseExpanding = pulseExpanding;
- updateShowCollapsedOnKeyguard();
- }
- }
-
private void updateShowCollapsedOnKeyguard() {
- boolean showCollapsed = mPulseExpanding || mTransitioningToFullShade;
+ boolean showCollapsed = mBypassController.getBypassEnabled() || mTransitioningToFullShade;
if (showCollapsed != mShowCollapsedOnKeyguard) {
mShowCollapsedOnKeyguard = showCollapsed;
updateQsState();
@@ -719,5 +722,6 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
public void onStateChanged(int newState) {
mState = newState;
setKeyguardShowing(newState == StatusBarState.KEYGUARD);
+ updateShowCollapsedOnKeyguard();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index 7c7f56658919..1b4ee734a491 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -27,12 +27,15 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
+import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
+import androidx.annotation.VisibleForTesting;
+
import com.android.internal.logging.UiEventLogger;
import com.android.internal.widget.RemeasuringLinearLayout;
import com.android.systemui.R;
@@ -56,6 +59,8 @@ public class QSPanel extends LinearLayout implements Tunable {
private static final String TAG = "QSPanel";
protected final Context mContext;
+ private final int mMediaTopMargin;
+ private final int mMediaTotalBottomMargin;
/**
* The index where the content starts that needs to be moved between parents
@@ -99,13 +104,14 @@ public class QSPanel extends LinearLayout implements Tunable {
protected LinearLayout mHorizontalContentContainer;
protected QSTileLayout mTileLayout;
- private int mMediaTotalBottomMargin;
public QSPanel(Context context, AttributeSet attrs) {
super(context, attrs);
mUsingMediaPlayer = useQsMediaPlayer(context);
mMediaTotalBottomMargin = getResources().getDimensionPixelSize(
R.dimen.quick_settings_bottom_margin_media);
+ mMediaTopMargin = getResources().getDimensionPixelSize(
+ R.dimen.qs_tile_margin_vertical);
mContext = context;
setOrientation(VERTICAL);
@@ -328,7 +334,7 @@ public class QSPanel extends LinearLayout implements Tunable {
private void updateHorizontalLinearLayoutMargins() {
if (mHorizontalLinearLayout != null && !displayMediaMarginsOnMedia()) {
LayoutParams lp = (LayoutParams) mHorizontalLinearLayout.getLayoutParams();
- lp.bottomMargin = mMediaTotalBottomMargin - getPaddingBottom();
+ lp.bottomMargin = Math.max(mMediaTotalBottomMargin - getPaddingBottom(), 0);
mHorizontalLinearLayout.setLayoutParams(lp);
}
}
@@ -343,6 +349,13 @@ public class QSPanel extends LinearLayout implements Tunable {
return true;
}
+ /**
+ * @return true if the media view needs margin on the top to separate it from the qs tiles
+ */
+ protected boolean mediaNeedsTopMargin() {
+ return false;
+ }
+
private boolean needsDynamicRowsAndColumns() {
return true;
}
@@ -376,19 +389,18 @@ public class QSPanel extends LinearLayout implements Tunable {
if (mediaView != null) {
index = indexOfChild(mediaView);
}
+ if (mSecurityFooter.getParent() == this && indexOfChild(mSecurityFooter) < index) {
+ // When we remove the securityFooter to rearrange, the index of media will go
+ // down by one, so we correct it
+ index--;
+ }
switchToParent(mSecurityFooter, this, index);
}
}
}
private void switchToParent(View child, ViewGroup parent, int index) {
- ViewGroup currentParent = (ViewGroup) child.getParent();
- if (currentParent != parent || currentParent.indexOfChild(child) != index) {
- if (currentParent != null) {
- currentParent.removeView(child);
- }
- parent.addView(child, index);
- }
+ switchToParent(child, parent, index, getDumpableTag());
}
/** Call when orientation has changed and MediaHost needs to be adjusted. */
@@ -411,7 +423,9 @@ public class QSPanel extends LinearLayout implements Tunable {
// necessary if the view isn't horizontal, since otherwise the padding is
// carried in the parent of this view (to ensure correct vertical alignment)
layoutParams.bottomMargin = !horizontal || displayMediaMarginsOnMedia()
- ? mMediaTotalBottomMargin - getPaddingBottom() : 0;
+ ? Math.max(mMediaTotalBottomMargin - getPaddingBottom(), 0) : 0;
+ layoutParams.topMargin = mediaNeedsTopMargin() && !horizontal
+ ? mMediaTopMargin : 0;
}
}
@@ -674,6 +688,7 @@ public class QSPanel extends LinearLayout implements Tunable {
mTileLayout.setMaxColumns(horizontal ? 2 : 4);
}
updateMargins(mediaHostView);
+ mHorizontalLinearLayout.setVisibility(horizontal ? View.VISIBLE : View.GONE);
}
}
@@ -754,4 +769,29 @@ public class QSPanel extends LinearLayout implements Tunable {
interface OnConfigurationChangedListener {
void onConfigurationChange(Configuration newConfig);
}
+
+ @VisibleForTesting
+ static void switchToParent(View child, ViewGroup parent, int index, String tag) {
+ if (parent == null) {
+ Log.w(tag, "Trying to move view to null parent",
+ new IllegalStateException());
+ return;
+ }
+ ViewGroup currentParent = (ViewGroup) child.getParent();
+ if (currentParent != parent) {
+ if (currentParent != null) {
+ currentParent.removeView(child);
+ }
+ parent.addView(child, index);
+ return;
+ }
+ // Same parent, we are just changing indices
+ int currentIndex = parent.indexOfChild(child);
+ if (currentIndex == index) {
+ // We want to be in the same place. Nothing to do here
+ return;
+ }
+ parent.removeView(child);
+ parent.addView(child, index);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
index 4cd4048f7286..985943bc8b05 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
@@ -73,6 +73,11 @@ public class QuickQSPanel extends QSPanel {
}
@Override
+ protected boolean mediaNeedsTopMargin() {
+ return true;
+ }
+
+ @Override
protected void updatePadding() {
// QS Panel is setting a top padding by default, which we don't need.
}
@@ -180,7 +185,6 @@ public class QuickQSPanel extends QSPanel {
LayoutParams.WRAP_CONTENT);
setLayoutParams(lp);
setMaxColumns(4);
- mLastRowPadding = true;
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
index cd9db614e477..77906abce625 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
@@ -95,6 +95,9 @@ public class QuickStatusBarHeader extends FrameLayout {
private List<String> mRssiIgnoredSlots;
private boolean mIsSingleCarrier;
+ private boolean mHasCenterCutout;
+ private boolean mConfigShowBatteryEstimate;
+
public QuickStatusBarHeader(Context context, AttributeSet attrs) {
super(context, attrs);
}
@@ -203,9 +206,19 @@ public class QuickStatusBarHeader extends FrameLayout {
mPrivacyContainer.setLayoutParams(lp);
}
+ private void updateBatteryMode() {
+ if (mConfigShowBatteryEstimate && !mHasCenterCutout) {
+ mBatteryRemainingIcon.setPercentShowMode(BatteryMeterView.MODE_ESTIMATE);
+ } else {
+ mBatteryRemainingIcon.setPercentShowMode(BatteryMeterView.MODE_ON);
+ }
+ }
+
void updateResources() {
Resources resources = mContext.getResources();
+ mConfigShowBatteryEstimate = resources.getBoolean(R.bool.config_showBatteryEstimateQSBH);
+
mRoundedCornerPadding = resources.getDimensionPixelSize(
R.dimen.rounded_corner_content_padding);
@@ -246,6 +259,7 @@ public class QuickStatusBarHeader extends FrameLayout {
.getDimensionPixelSize(R.dimen.qqs_layout_margin_top);
mHeaderQsPanel.setLayoutParams(qqsLP);
+ updateBatteryMode();
updateHeadersPadding();
updateAnimators();
}
@@ -384,14 +398,14 @@ public class QuickStatusBarHeader extends FrameLayout {
mClockIconsSeparatorLayoutParams.width = 0;
setSeparatorVisibility(false);
mShowClockIconsSeparator = false;
- mBatteryRemainingIcon.setPercentShowMode(BatteryMeterView.MODE_ESTIMATE);
+ mHasCenterCutout = false;
} else {
datePrivacySeparatorLayoutParams.width = topCutout.width();
mDatePrivacySeparator.setVisibility(View.VISIBLE);
mClockIconsSeparatorLayoutParams.width = topCutout.width();
mShowClockIconsSeparator = true;
setSeparatorVisibility(mKeyguardExpansionFraction == 0f);
- mBatteryRemainingIcon.setPercentShowMode(BatteryMeterView.MODE_ON);
+ mHasCenterCutout = true;
}
}
mDatePrivacySeparator.setLayoutParams(datePrivacySeparatorLayoutParams);
@@ -399,6 +413,8 @@ public class QuickStatusBarHeader extends FrameLayout {
mCutOutPaddingLeft = padding.first;
mCutOutPaddingRight = padding.second;
mWaterfallTopInset = cutout == null ? 0 : cutout.getWaterfallInsets().top;
+
+ updateBatteryMode();
updateHeadersPadding();
return super.onApplyWindowInsets(insets);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
index 2b96a34967f4..1a890a7ad07b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
@@ -31,7 +31,6 @@ public class TileLayout extends ViewGroup implements QSTileLayout {
protected int mCellMarginVertical;
protected int mSidePadding;
protected int mRows = 1;
- protected boolean mLastRowPadding = false;
protected final ArrayList<TileRecord> mRecords = new ArrayList<>();
protected boolean mListening;
@@ -168,9 +167,7 @@ public class TileLayout extends ViewGroup implements QSTileLayout {
}
int height = (mCellHeight + mCellMarginVertical) * mRows;
- if (!mLastRowPadding) {
- height -= mCellMarginVertical;
- }
+ height -= mCellMarginVertical;
if (height < 0) height = 0;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt
index f66b7226fbae..bc21b2d0fba7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt
@@ -69,7 +69,7 @@ class DeviceControlsTile @Inject constructor(
private var hasControlsApps = AtomicBoolean(false)
- private val icon = ResourceIcon.get(R.drawable.ic_device_light)
+ private val icon = ResourceIcon.get(R.drawable.controls_icon)
private val listingCallback = object : ControlsListingController.ControlsListingCallback {
override fun onServicesUpdated(serviceInfos: List<ControlsServiceInfo>) {
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureClient.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureClient.java
index ce6e46937c25..93e5021fd6e0 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureClient.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureClient.java
@@ -45,9 +45,12 @@ import androidx.concurrent.futures.CallbackToFutureAdapter;
import androidx.concurrent.futures.CallbackToFutureAdapter.Completer;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.dagger.qualifiers.Background;
import com.google.common.util.concurrent.ListenableFuture;
+import java.util.concurrent.Executor;
+
import javax.inject.Inject;
/**
@@ -63,6 +66,8 @@ public class ScrollCaptureClient {
private static final String TAG = LogConfig.logTag(ScrollCaptureClient.class);
+ private final Executor mBgExecutor;
+
/**
* Represents the connection to a target window and provides a mechanism for requesting tiles.
*/
@@ -155,8 +160,10 @@ public class ScrollCaptureClient {
private IBinder mHostWindowToken;
@Inject
- public ScrollCaptureClient(@UiContext Context context, IWindowManager windowManagerService) {
+ public ScrollCaptureClient(IWindowManager windowManagerService,
+ @Background Executor bgExecutor, @UiContext Context context) {
requireNonNull(context.getDisplay(), "context must be associated with a Display!");
+ mBgExecutor = bgExecutor;
mWindowManagerService = windowManagerService;
}
@@ -220,21 +227,25 @@ public class ScrollCaptureClient {
return "";
}
SessionWrapper session = new SessionWrapper(connection, response.getWindowBounds(),
- response.getBoundsInWindow(), maxPages);
+ response.getBoundsInWindow(), maxPages, mBgExecutor);
session.start(completer);
return "IScrollCaptureCallbacks#onCaptureStarted";
});
}
private static class SessionWrapper extends IScrollCaptureCallbacks.Stub implements Session,
- IBinder.DeathRecipient {
+ IBinder.DeathRecipient, ImageReader.OnImageAvailableListener {
private IScrollCaptureConnection mConnection;
+ private final Executor mBgExecutor;
+ private final Object mLock = new Object();
private ImageReader mReader;
private final int mTileHeight;
private final int mTileWidth;
private Rect mRequestRect;
+ private Rect mCapturedArea;
+ private Image mCapturedImage;
private boolean mStarted;
private final int mTargetHeight;
@@ -247,7 +258,8 @@ public class ScrollCaptureClient {
private Completer<Void> mEndCompleter;
private SessionWrapper(IScrollCaptureConnection connection, Rect windowBounds,
- Rect boundsInWindow, float maxPages) throws RemoteException {
+ Rect boundsInWindow, float maxPages, Executor bgExecutor)
+ throws RemoteException {
mConnection = requireNonNull(connection);
mConnection.asBinder().linkToDeath(SessionWrapper.this, 0);
mWindowBounds = requireNonNull(windowBounds);
@@ -259,7 +271,7 @@ public class ScrollCaptureClient {
mTileWidth = mBoundsInWindow.width();
mTileHeight = pxPerTile / mBoundsInWindow.width();
mTargetHeight = (int) (mBoundsInWindow.height() * maxPages);
-
+ mBgExecutor = bgExecutor;
if (DEBUG_SCROLL) {
Log.d(TAG, "boundsInWindow: " + mBoundsInWindow);
Log.d(TAG, "tile size: " + mTileWidth + "x" + mTileHeight);
@@ -289,6 +301,7 @@ public class ScrollCaptureClient {
mReader = ImageReader.newInstance(mTileWidth, mTileHeight, PixelFormat.RGBA_8888,
MAX_TILES, HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE);
mStartCompleter = completer;
+ mReader.setOnImageAvailableListenerWithExecutor(this, mBgExecutor);
try {
mCancellationSignal = mConnection.startCapture(mReader.getSurface(), this);
completer.addCancellationListener(() -> {
@@ -339,9 +352,34 @@ public class ScrollCaptureClient {
@BinderThread
@Override
- public void onImageRequestCompleted(int flags, Rect contentArea) {
- Image image = mReader.acquireLatestImage();
- mTileRequestCompleter.set(new CaptureResult(image, mRequestRect, contentArea));
+ public void onImageRequestCompleted(int flagsUnused, Rect contentArea) {
+ synchronized (mLock) {
+ mCapturedArea = contentArea;
+ if (mCapturedImage != null || (mCapturedArea == null || mCapturedArea.isEmpty())) {
+ completeCaptureRequest();
+ }
+ }
+ }
+
+ /** @see ImageReader.OnImageAvailableListener */
+ @Override
+ public void onImageAvailable(ImageReader reader) {
+ synchronized (mLock) {
+ mCapturedImage = mReader.acquireLatestImage();
+ if (mCapturedArea != null) {
+ completeCaptureRequest();
+ }
+ }
+ }
+
+ /** Produces a result for the caller as soon as both asynchronous results are received. */
+ private void completeCaptureRequest() {
+ CaptureResult result =
+ new CaptureResult(mCapturedImage, mRequestRect, mCapturedArea);
+ mCapturedImage = null;
+ mRequestRect = null;
+ mCapturedArea = null;
+ mTileRequestCompleter.set(result);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index 120121ce7f0e..3890c1aa4e4f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -77,6 +77,7 @@ import com.android.systemui.keyguard.KeyguardIndication;
import com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.KeyguardIndicationTextView;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -100,7 +101,7 @@ public class KeyguardIndicationController {
private static final boolean DEBUG_CHARGING_SPEED = false;
private static final int MSG_HIDE_TRANSIENT = 1;
- private static final int MSG_SWIPE_UP_TO_UNLOCK = 2;
+ private static final int MSG_SHOW_ACTION_TO_UNLOCK = 2;
private static final long TRANSIENT_BIOMETRIC_ERROR_TIMEOUT = 1300;
private static final float BOUNCE_ANIMATION_FINAL_Y = 0f;
@@ -121,6 +122,7 @@ public class KeyguardIndicationController {
private final LockPatternUtils mLockPatternUtils;
private final IActivityManager mIActivityManager;
private final FalsingManager mFalsingManager;
+ private final KeyguardBypassController mKeyguardBypassController;
protected KeyguardIndicationRotateTextViewController mRotateTextViewController;
private BroadcastReceiver mBroadcastReceiver;
@@ -175,7 +177,8 @@ public class KeyguardIndicationController {
@Main DelayableExecutor executor,
FalsingManager falsingManager,
LockPatternUtils lockPatternUtils,
- IActivityManager iActivityManager) {
+ IActivityManager iActivityManager,
+ KeyguardBypassController keyguardBypassController) {
mContext = context;
mBroadcastDispatcher = broadcastDispatcher;
mDevicePolicyManager = devicePolicyManager;
@@ -191,6 +194,7 @@ public class KeyguardIndicationController {
mLockPatternUtils = lockPatternUtils;
mIActivityManager = iActivityManager;
mFalsingManager = falsingManager;
+ mKeyguardBypassController = keyguardBypassController;
}
@@ -593,7 +597,7 @@ public class KeyguardIndicationController {
mTransientIndication = transientIndication;
mHideTransientMessageOnScreenOff = hideOnScreenOff && transientIndication != null;
mHandler.removeMessages(MSG_HIDE_TRANSIENT);
- mHandler.removeMessages(MSG_SWIPE_UP_TO_UNLOCK);
+ mHandler.removeMessages(MSG_SHOW_ACTION_TO_UNLOCK);
if (mDozing && !TextUtils.isEmpty(mTransientIndication)) {
// Make sure this doesn't get stuck and burns in. Acquire wakelock until its cleared.
mWakeLock.setAcquired(true);
@@ -785,27 +789,45 @@ public class KeyguardIndicationController {
public void handleMessage(Message msg) {
if (msg.what == MSG_HIDE_TRANSIENT) {
hideTransientIndication();
- } else if (msg.what == MSG_SWIPE_UP_TO_UNLOCK) {
- showSwipeUpToUnlock();
+ } else if (msg.what == MSG_SHOW_ACTION_TO_UNLOCK) {
+ showActionToUnlock();
}
}
};
- private void showSwipeUpToUnlock() {
+ /**
+ * Show message on the keyguard for how the user can unlock/enter their device.
+ */
+ public void showActionToUnlock() {
if (mDozing) {
return;
}
if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
if (mStatusBarKeyguardViewManager.isShowingAlternateAuth()) {
- return; // udfps affordance is highlighted, no need to surface face auth error
- } else {
+ return; // udfps affordance is highlighted, no need to show action to unlock
+ } else if (mKeyguardUpdateMonitor.isFaceEnrolled()) {
String message = mContext.getString(R.string.keyguard_retry);
mStatusBarKeyguardViewManager.showBouncerMessage(message, mInitialTextColorState);
}
} else if (mKeyguardUpdateMonitor.isScreenOn()) {
- showTransientIndication(mContext.getString(R.string.keyguard_unlock),
- false /* isError */, true /* hideOnScreenOff */);
+ if (mKeyguardUpdateMonitor.isUdfpsAvailable()) {
+ showTransientIndication(mContext.getString(R.string.keyguard_unlock_press),
+ false /* isError */, true /* hideOnScreenOff */);
+ } else {
+ showTransientIndication(mContext.getString(R.string.keyguard_unlock),
+ false /* isError */, true /* hideOnScreenOff */);
+ }
+ }
+ }
+
+ private void showTryFingerprintMsg() {
+ if (mKeyguardUpdateMonitor.isUdfpsAvailable()) {
+ // if udfps available, there will always be a tappable affordance to unlock
+ // For example, the lock icon
+ showTransientIndication(R.string.keyguard_unlock_press);
+ } else {
+ showTransientIndication(R.string.keyguard_try_fingerprint);
}
}
@@ -879,7 +901,7 @@ public class KeyguardIndicationController {
return;
}
- boolean showSwipeToUnlock =
+ boolean showActionToUnlock =
msgId == KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_RECOGNIZED;
if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
mStatusBarKeyguardViewManager.showBouncerMessage(helpString,
@@ -887,14 +909,12 @@ public class KeyguardIndicationController {
} else if (mKeyguardUpdateMonitor.isScreenOn()) {
if (biometricSourceType == BiometricSourceType.FACE
&& shouldSuppressFaceMsgAndShowTryFingerprintMsg()) {
- // suggest trying fingerprint
- showTransientIndication(R.string.keyguard_try_fingerprint);
+ showTryFingerprintMsg();
return;
}
- showTransientIndication(helpString, false /* isError */, showSwipeToUnlock);
- }
- if (showSwipeToUnlock) {
- mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_SWIPE_UP_TO_UNLOCK),
+ showTransientIndication(helpString, false /* isError */, showActionToUnlock);
+ } else if (showActionToUnlock) {
+ mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_SHOW_ACTION_TO_UNLOCK),
TRANSIENT_BIOMETRIC_ERROR_TIMEOUT);
}
}
@@ -909,8 +929,7 @@ public class KeyguardIndicationController {
&& shouldSuppressFaceMsgAndShowTryFingerprintMsg()
&& !mStatusBarKeyguardViewManager.isBouncerShowing()
&& mKeyguardUpdateMonitor.isScreenOn()) {
- // suggest trying fingerprint
- showTransientIndication(R.string.keyguard_try_fingerprint);
+ showTryFingerprintMsg();
return;
}
if (msgId == FaceManager.FACE_ERROR_TIMEOUT) {
@@ -919,16 +938,15 @@ public class KeyguardIndicationController {
if (!mStatusBarKeyguardViewManager.isBouncerShowing()
&& mKeyguardUpdateMonitor.isUdfpsEnrolled()
&& mKeyguardUpdateMonitor.isFingerprintDetectionRunning()) {
- // suggest trying fingerprint
- showTransientIndication(R.string.keyguard_try_fingerprint);
+ showTryFingerprintMsg();
} else if (mStatusBarKeyguardViewManager.isShowingAlternateAuth()) {
mStatusBarKeyguardViewManager.showBouncerMessage(
- mContext.getResources().getString(R.string.keyguard_try_fingerprint),
+ mContext.getResources().getString(R.string.keyguard_unlock_press),
mInitialTextColorState
);
} else {
// suggest swiping up to unlock (try face auth again or swipe up to bouncer)
- showSwipeUpToUnlock();
+ showActionToUnlock();
}
} else if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
mStatusBarKeyguardViewManager.showBouncerMessage(errString, mInitialTextColorState);
@@ -1010,6 +1028,11 @@ public class KeyguardIndicationController {
boolean isStrongBiometric) {
super.onBiometricAuthenticated(userId, biometricSourceType, isStrongBiometric);
mHandler.sendEmptyMessage(MSG_HIDE_TRANSIENT);
+
+ if (biometricSourceType == BiometricSourceType.FACE
+ && !mKeyguardBypassController.canBypass()) {
+ mHandler.sendEmptyMessage(MSG_SHOW_ACTION_TO_UNLOCK);
+ }
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
index 6f4a73ec4516..6fa06a76dc5e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
@@ -65,6 +65,7 @@ class LockscreenShadeTransitionController @Inject constructor(
configurationController: ConfigurationController,
falsingManager: FalsingManager
) {
+ private var pulseHeight: Float = 0f
private var useSplitShade: Boolean = false
private lateinit var nsslController: NotificationStackScrollLayoutController
lateinit var notificationPanelController: NotificationPanelViewController
@@ -88,6 +89,12 @@ class LockscreenShadeTransitionController @Inject constructor(
internal var dragDownAnimator: ValueAnimator? = null
/**
+ * The current pulse height animator if any
+ */
+ @VisibleForTesting
+ internal var pulseHeightAnimator: ValueAnimator? = null
+
+ /**
* Distance that the full shade transition takes in order for scrim to fully transition to
* the shade (in alpha)
*/
@@ -110,6 +117,12 @@ class LockscreenShadeTransitionController @Inject constructor(
private var nextHideKeyguardNeedsNoAnimation = false
/**
+ * The distance until we're showing the notifications when pulsing
+ */
+ val distanceUntilShowingPulsingNotifications
+ get() = scrimTransitionDistance
+
+ /**
* The udfpsKeyguardViewController if it exists.
*/
var udfpsKeyguardViewController: UdfpsKeyguardViewController? = null
@@ -286,22 +299,26 @@ class LockscreenShadeTransitionController @Inject constructor(
nsslController.setTransitionToFullShadeAmount(field)
notificationPanelController.setTransitionToFullShadeAmount(field,
false /* animate */, 0 /* delay */)
- val scrimProgress = MathUtils.saturate(field / scrimTransitionDistance)
- scrimController.setTransitionToFullShadeProgress(scrimProgress)
// TODO: appear qs also in split shade
val qsAmount = if (useSplitShade) 0f else field
qS.setTransitionToFullShadeAmount(qsAmount, false /* animate */)
// TODO: appear media also in split shade
val mediaAmount = if (useSplitShade) 0f else field
mediaHierarchyManager.setTransitionToFullShadeAmount(mediaAmount)
- // Fade out all content only visible on the lockscreen
- notificationPanelController.setKeyguardOnlyContentAlpha(1.0f - scrimProgress)
- depthController.transitionToFullShadeProgress = scrimProgress
- udfpsKeyguardViewController?.setTransitionToFullShadeProgress(scrimProgress)
+ transitionToShadeAmountCommon(field)
}
}
}
+ private fun transitionToShadeAmountCommon(dragDownAmount: Float) {
+ val scrimProgress = MathUtils.saturate(dragDownAmount / scrimTransitionDistance)
+ scrimController.setTransitionToFullShadeProgress(scrimProgress)
+ // Fade out all content only visible on the lockscreen
+ notificationPanelController.setKeyguardOnlyContentAlpha(1.0f - scrimProgress)
+ depthController.transitionToFullShadeProgress = scrimProgress
+ udfpsKeyguardViewController?.setTransitionToFullShadeProgress(scrimProgress)
+ }
+
private fun setDragDownAmountAnimated(
target: Float,
delay: Long = 0,
@@ -453,15 +470,19 @@ class LockscreenShadeTransitionController @Inject constructor(
/**
* Notify this handler that the keyguard was just dismissed and that a animation to
* the full shade should happen.
+ *
+ * @param delay the delay to do the animation with
+ * @param previousState which state were we in when we hid the keyguard?
*/
- fun onHideKeyguard(delay: Long) {
+ fun onHideKeyguard(delay: Long, previousState: Int) {
if (animationHandlerOnKeyguardDismiss != null) {
animationHandlerOnKeyguardDismiss!!.invoke(delay)
animationHandlerOnKeyguardDismiss = null
} else {
if (nextHideKeyguardNeedsNoAnimation) {
nextHideKeyguardNeedsNoAnimation = false
- } else {
+ } else if (previousState != StatusBarState.SHADE_LOCKED) {
+ // No animation necessary if we already were in the shade locked!
performDefaultGoToFullShadeAnimation(delay)
}
}
@@ -479,6 +500,53 @@ class LockscreenShadeTransitionController @Inject constructor(
notificationPanelController.animateToFullShade(delay)
animateAppear(delay)
}
+
+ //
+ // PULSE EXPANSION
+ //
+
+ /**
+ * Set the height how tall notifications are pulsing. This is only set whenever we are expanding
+ * from a pulse and determines how much the notifications are expanded.
+ */
+ fun setPulseHeight(height: Float, animate: Boolean = false) {
+ if (animate) {
+ val pulseHeightAnimator = ValueAnimator.ofFloat(pulseHeight, height)
+ pulseHeightAnimator.interpolator = Interpolators.FAST_OUT_SLOW_IN
+ pulseHeightAnimator.duration = SPRING_BACK_ANIMATION_LENGTH_MS
+ pulseHeightAnimator.addUpdateListener { animation: ValueAnimator ->
+ setPulseHeight(animation.animatedValue as Float)
+ }
+ pulseHeightAnimator.start()
+ this.pulseHeightAnimator = pulseHeightAnimator
+ } else {
+ pulseHeight = height
+ val overflow = nsslController.setPulseHeight(height)
+ notificationPanelController.setOverStrechAmount(overflow)
+ val transitionHeight = if (keyguardBypassController.bypassEnabled) height else 0.0f
+ transitionToShadeAmountCommon(transitionHeight)
+ }
+ }
+
+ /**
+ * Finish the pulse animation when the touch interaction finishes
+ * @param cancelled was the interaction cancelled and this is a reset?
+ */
+ fun finishPulseAnimation(cancelled: Boolean) {
+ if (cancelled) {
+ setPulseHeight(0f, animate = true)
+ } else {
+ notificationPanelController.onPulseExpansionFinished()
+ setPulseHeight(0f, animate = false)
+ }
+ }
+
+ /**
+ * Notify this class that a pulse expansion is starting
+ */
+ fun onPulseExpansionStarted() {
+ pulseHeightAnimator?.cancel()
+ }
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt b/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt
index b34bfad499f8..761a20326200 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt
@@ -19,8 +19,8 @@ package com.android.systemui.statusbar
import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.animation.ObjectAnimator
-import android.animation.ValueAnimator
import android.content.Context
+import android.content.res.Configuration
import android.os.PowerManager
import android.os.PowerManager.WAKE_REASON_GESTURE
import android.os.SystemClock
@@ -42,6 +42,7 @@ import com.android.systemui.statusbar.notification.stack.NotificationRoundnessMa
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
import com.android.systemui.statusbar.phone.HeadsUpManagerPhone
import com.android.systemui.statusbar.phone.KeyguardBypassController
+import com.android.systemui.statusbar.policy.ConfigurationController
import javax.inject.Inject
import kotlin.math.max
@@ -56,18 +57,17 @@ constructor(
private val bypassController: KeyguardBypassController,
private val headsUpManager: HeadsUpManagerPhone,
private val roundnessManager: NotificationRoundnessManager,
+ private val configurationController: ConfigurationController,
private val statusBarStateController: StatusBarStateController,
private val falsingManager: FalsingManager,
private val lockscreenShadeTransitionController: LockscreenShadeTransitionController,
private val falsingCollector: FalsingCollector
) : Gefingerpoken {
companion object {
- private val RUBBERBAND_FACTOR_STATIC = 0.25f
private val SPRING_BACK_ANIMATION_LENGTH_MS = 375
}
private val mPowerManager: PowerManager?
- private val mMinDragDistance: Int
private var mInitialTouchX: Float = 0.0f
private var mInitialTouchY: Float = 0.0f
var isExpanding: Boolean = false
@@ -81,6 +81,7 @@ constructor(
topEntry?.let {
roundnessManager.setTrackingHeadsUp(it.row)
}
+ lockscreenShadeTransitionController.onPulseExpansionStarted()
} else {
roundnessManager.setTrackingHeadsUp(null)
if (!leavingLockscreen) {
@@ -93,8 +94,8 @@ constructor(
}
var leavingLockscreen: Boolean = false
private set
- private val mTouchSlop: Float
- private lateinit var overStretchHandler: OverStretchHandler
+ private var touchSlop = 0f
+ private var minDragDistance = 0
private lateinit var stackScrollerController: NotificationStackScrollLayoutController
private val mTemp2 = IntArray(2)
private var mDraggedFarEnough: Boolean = false
@@ -102,9 +103,7 @@ constructor(
private var mPulsing: Boolean = false
var isWakingToShadeLocked: Boolean = false
private set
- private var overStretchAmount: Float = 0.0f
- private var mWakeUpHeight: Float = 0.0f
- private var mReachedWakeUpHeight: Boolean = false
+
private var velocityTracker: VelocityTracker? = null
private val isFalseTouch: Boolean
@@ -114,12 +113,21 @@ constructor(
var bouncerShowing: Boolean = false
init {
- mMinDragDistance = context.resources.getDimensionPixelSize(
- R.dimen.keyguard_drag_down_min_distance)
- mTouchSlop = ViewConfiguration.get(context).scaledTouchSlop.toFloat()
+ initResources(context)
+ configurationController.addCallback(object : ConfigurationController.ConfigurationListener {
+ override fun onConfigChanged(newConfig: Configuration?) {
+ initResources(context)
+ }
+ })
mPowerManager = context.getSystemService(PowerManager::class.java)
}
+ private fun initResources(context: Context) {
+ minDragDistance = context.resources.getDimensionPixelSize(
+ R.dimen.keyguard_drag_down_min_distance)
+ touchSlop = ViewConfiguration.get(context).scaledTouchSlop.toFloat()
+ }
+
override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
return canHandleMotionEvent() && startExpansion(event)
}
@@ -148,14 +156,12 @@ constructor(
MotionEvent.ACTION_MOVE -> {
val h = y - mInitialTouchY
- if (h > mTouchSlop && h > Math.abs(x - mInitialTouchX)) {
+ if (h > touchSlop && h > Math.abs(x - mInitialTouchX)) {
falsingCollector.onStartExpandingFromPulse()
isExpanding = true
captureStartingChild(mInitialTouchX, mInitialTouchY)
mInitialTouchY = y
mInitialTouchX = x
- mWakeUpHeight = wakeUpCoordinator.getWakeUpHeight()
- mReachedWakeUpHeight = false
return true
}
}
@@ -216,7 +222,6 @@ constructor(
}
private fun finishExpansion() {
- resetClock()
val startingChild = mStartingChild
if (mStartingChild != null) {
setUserLocked(mStartingChild!!, false)
@@ -230,6 +235,7 @@ constructor(
}
lockscreenShadeTransitionController.goToLockedShade(startingChild,
needsQSAnimation = false)
+ lockscreenShadeTransitionController.finishPulseAnimation(cancelled = false)
leavingLockscreen = true
isExpanding = false
if (mStartingChild is ExpandableNotificationRow) {
@@ -240,24 +246,19 @@ constructor(
private fun updateExpansionHeight(height: Float) {
var expansionHeight = max(height, 0.0f)
- if (!mReachedWakeUpHeight && height > mWakeUpHeight) {
- mReachedWakeUpHeight = true
- }
if (mStartingChild != null) {
val child = mStartingChild!!
val newHeight = Math.min((child.collapsedHeight + expansionHeight).toInt(),
child.maxContentHeight)
child.actualHeight = newHeight
- expansionHeight = max(newHeight.toFloat(), expansionHeight)
} else {
- val target = if (mReachedWakeUpHeight) mWakeUpHeight else 0.0f
- wakeUpCoordinator.setNotificationsVisibleForExpansion(height > target,
- true /* animate */,
- true /* increaseSpeed */)
- expansionHeight = max(mWakeUpHeight, expansionHeight)
+ wakeUpCoordinator.setNotificationsVisibleForExpansion(
+ height
+ > lockscreenShadeTransitionController.distanceUntilShowingPulsingNotifications,
+ true /* animate */,
+ true /* increaseSpeed */)
}
- val dragDownAmount = wakeUpCoordinator.setPulseHeight(expansionHeight)
- setOverStretchAmount(dragDownAmount)
+ lockscreenShadeTransitionController.setPulseHeight(expansionHeight, animate = false)
}
private fun captureStartingChild(x: Float, y: Float) {
@@ -269,11 +270,6 @@ constructor(
}
}
- private fun setOverStretchAmount(amount: Float) {
- overStretchAmount = amount
- overStretchHandler.setOverStretchAmount(amount)
- }
-
private fun reset(child: ExpandableView) {
if (child.actualHeight == child.collapsedHeight) {
setUserLocked(child, false)
@@ -297,25 +293,14 @@ constructor(
}
}
- private fun resetClock() {
- val anim = ValueAnimator.ofFloat(overStretchAmount, 0f)
- anim.interpolator = Interpolators.FAST_OUT_SLOW_IN
- anim.duration = SPRING_BACK_ANIMATION_LENGTH_MS.toLong()
- anim.addUpdateListener {
- animation -> setOverStretchAmount(animation.animatedValue as Float)
- }
- anim.start()
- }
-
private fun cancelExpansion() {
isExpanding = false
falsingCollector.onExpansionFromPulseStopped()
if (mStartingChild != null) {
reset(mStartingChild!!)
mStartingChild = null
- } else {
- resetClock()
}
+ lockscreenShadeTransitionController.finishPulseAnimation(cancelled = true)
wakeUpCoordinator.setNotificationsVisibleForExpansion(false /* visible */,
true /* animate */,
false /* increaseSpeed */)
@@ -333,11 +318,7 @@ constructor(
} else null
}
- fun setUp(
- stackScrollerController: NotificationStackScrollLayoutController,
- overStrechHandler: OverStretchHandler
- ) {
- this.overStretchHandler = overStrechHandler
+ fun setUp(stackScrollerController: NotificationStackScrollLayoutController) {
this.stackScrollerController = stackScrollerController
}
@@ -348,12 +329,4 @@ constructor(
fun onStartedWakingUp() {
isWakingToShadeLocked = false
}
-
- interface OverStretchHandler {
-
- /**
- * Set the overstretch amount in pixels This will be rubberbanded later
- */
- fun setOverStretchAmount(amount: Float)
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
index b0a7767accfc..a2c9ffc6bdc4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
@@ -374,10 +374,6 @@ class NotificationWakeUpCoordinator @Inject constructor(
}
}
- fun getWakeUpHeight(): Float {
- return mStackScrollerController.wakeUpHeight
- }
-
private fun updateHideAmount() {
val linearAmount = min(1.0f - mLinearVisibilityAmount, mLinearDozeAmount)
val amount = min(1.0f - mVisibilityAmount, mDozeAmount)
@@ -395,16 +391,6 @@ class NotificationWakeUpCoordinator @Inject constructor(
}
}
- /**
- * Set the height how tall notifications are pulsing. This is only set whenever we are expanding
- * from a pulse and determines how much the notifications are expanded.
- */
- fun setPulseHeight(height: Float): Float {
- val overflow = mStackScrollerController.setPulseHeight(height)
- // no overflow for the bypass experience
- return if (bypassController.bypassEnabled) 0.0f else overflow
- }
-
override fun onHeadsUpStateChanged(entry: NotificationEntry, isHeadsUp: Boolean) {
var animate = shouldAnimateVisibility()
if (!isHeadsUp) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
index 9846b28ba5f9..41c88cc0a74a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
@@ -154,15 +154,6 @@ public class AmbientState {
return mStackHeight;
}
- /**
- * @return Height of notifications panel, with the animation from pulseHeight accounted for.
- */
- // TODO(b/192348384): move this logic to getStackHeight, and remove this and getInnerHeight
- public float getPulseStackHeight() {
- float pulseHeight = Math.min(mPulseHeight, mStackHeight);
- return MathUtils.lerp(mStackHeight, pulseHeight, mDozeAmount);
- }
-
/** Tracks the state from AlertingNotificationManager#hasNotifications() */
private boolean mHasAlertEntries;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index 4ad72027b046..289c32f17b31 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -5138,12 +5138,17 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
* @return the overflow how much the height is further than he lowest notification
*/
public float setPulseHeight(float height) {
+ float overflow;
mAmbientState.setPulseHeight(height);
if (mKeyguardBypassEnabledProvider.getBypassEnabled()) {
notifyAppearChangedListeners();
+ overflow = Math.max(0, height - getIntrinsicPadding());
+ } else {
+ overflow = Math.max(0, height
+ - mAmbientState.getInnerHeight(true /* ignorePulseHeight */));
}
requestChildrenUpdate();
- return Math.max(0, height - mAmbientState.getInnerHeight(true /* ignorePulseHeight */));
+ return overflow;
}
public float getPulseHeight() {
@@ -5203,12 +5208,9 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
public float calculateAppearFractionBypass() {
float pulseHeight = getPulseHeight();
- float wakeUpHeight = getWakeUpHeight();
- float dragDownAmount = pulseHeight - wakeUpHeight;
-
// The total distance required to fully reveal the header
float totalDistance = getIntrinsicPadding();
- return MathUtils.smoothStep(0, totalDistance, dragDownAmount);
+ return MathUtils.smoothStep(0, totalDistance, pulseHeight);
}
public void setController(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
index 09afedb6de59..9e4adce47e0c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
@@ -885,10 +885,6 @@ public class NotificationStackScrollLayoutController {
mView.setDozeAmount(amount);
}
- public float getWakeUpHeight() {
- return mView.getWakeUpHeight();
- }
-
public int getSpeedBumpIndex() {
return mView.getSpeedBumpIndex();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
index d0507e1e136c..1b4ae9ea3f32 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
@@ -274,7 +274,9 @@ public class StackScrollAlgorithm {
// expanded. Consider updating these states in updateContentView instead so that we don't
// have to recalculate in every frame.
float currentY = -ambientState.getScrollY();
- if (!ambientState.isOnKeyguard()) {
+ if (!ambientState.isOnKeyguard()
+ || (ambientState.isBypassEnabled() && ambientState.isPulseExpanding())) {
+ // add top padding at the start as long as we're not on the lock screen
currentY += mNotificationScrimPadding;
}
state.firstViewInShelf = null;
@@ -324,7 +326,8 @@ public class StackScrollAlgorithm {
*/
private void updatePositionsForState(StackScrollAlgorithmState algorithmState,
AmbientState ambientState) {
- if (!ambientState.isOnKeyguard()) {
+ if (!ambientState.isOnKeyguard()
+ || (ambientState.isBypassEnabled() && ambientState.isPulseExpanding())) {
algorithmState.mCurrentYPosition += mNotificationScrimPadding;
algorithmState.mCurrentExpandedYPosition += mNotificationScrimPadding;
}
@@ -355,7 +358,9 @@ public class StackScrollAlgorithm {
&& algorithmState.firstViewInShelf != null;
final float shelfHeight = showingShelf ? ambientState.getShelf().getIntrinsicHeight() : 0f;
- final float scrimPadding = ambientState.isOnKeyguard() ? 0 : mNotificationScrimPadding;
+ final float scrimPadding = ambientState.isOnKeyguard()
+ && (!ambientState.isBypassEnabled() || !ambientState.isPulseExpanding())
+ ? 0 : mNotificationScrimPadding;
final float stackHeight = ambientState.getStackHeight() - shelfHeight - scrimPadding;
final float stackEndHeight = ambientState.getStackEndHeight() - shelfHeight - scrimPadding;
@@ -442,19 +447,16 @@ public class StackScrollAlgorithm {
// to shelf start, thereby hiding all notifications (except the first one, which
// we later unhide in updatePulsingState)
// TODO(b/192348384): merge InnerHeight with StackHeight
- final int stackBottom;
- if (ambientState.isBypassEnabled()) {
- // We want to use the stackHeight when pulse expanding, since the animation
- // isn't currently optimized if the pulseHeight is continuously changing
- // Let's improve this when we're merging the heights above
- stackBottom = ambientState.isPulseExpanding()
- ? (int) ambientState.getStackHeight()
- : ambientState.getInnerHeight();
- } else {
- stackBottom = !ambientState.isShadeExpanded() || ambientState.isDozing()
- ? ambientState.getInnerHeight()
- : (int) ambientState.getPulseStackHeight();
- }
+ // Note: Bypass pulse looks different, but when it is not expanding, we need
+ // to use the innerHeight which doesn't update continuously, otherwise we show
+ // more notifications than we should during this special transitional states.
+ boolean bypassPulseNotExpanding = ambientState.isBypassEnabled()
+ && ambientState.isOnKeyguard() && !ambientState.isPulseExpanding();
+ final int stackBottom =
+ !ambientState.isShadeExpanded() || ambientState.isDozing()
+ || bypassPulseNotExpanding
+ ? ambientState.getInnerHeight()
+ : (int) ambientState.getStackHeight();
final int shelfStart =
stackBottom - ambientState.getShelf().getIntrinsicHeight();
viewState.yTranslation = Math.min(viewState.yTranslation, shelfStart);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
index 596fce5f7009..6d12a1cf10f5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
@@ -202,6 +202,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
public void onDestroyView() {
super.onDestroyView();
mStatusBarIconController.removeIconGroup(mDarkIconManager);
+ mAnimationScheduler.removeCallback(this);
if (mNetworkController.hasEmergencyCryptKeeperText()) {
mNetworkController.removeCallback(mSignalCallback);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index f6c475690c1d..bb48d1aba4d4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -19,6 +19,7 @@ package com.android.systemui.statusbar.phone;
import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLICK;
import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
+import static com.android.systemui.controls.dagger.ControlsComponent.Visibility.AVAILABLE;
import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInOffset;
import static com.android.systemui.tuner.LockscreenFragment.LOCKSCREEN_LEFT_BUTTON;
import static com.android.systemui.tuner.LockscreenFragment.LOCKSCREEN_LEFT_UNLOCK;
@@ -40,6 +41,7 @@ import android.content.ServiceConnection;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
+import android.content.res.ColorStateList;
import android.content.res.Configuration;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
@@ -82,6 +84,11 @@ import com.android.systemui.R;
import com.android.systemui.animation.Interpolators;
import com.android.systemui.assist.AssistManager;
import com.android.systemui.camera.CameraIntents;
+import com.android.systemui.controls.ControlsServiceInfo;
+import com.android.systemui.controls.dagger.ControlsComponent;
+import com.android.systemui.controls.management.ControlsListingController;
+import com.android.systemui.controls.ui.ControlsActivity;
+import com.android.systemui.controls.ui.ControlsUiController;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.IntentButtonProvider;
@@ -99,6 +106,8 @@ import com.android.systemui.tuner.TunerService;
import com.android.systemui.wallet.controller.QuickAccessWalletController;
import com.android.systemui.wallet.ui.WalletActivity;
+import java.util.List;
+
/**
* Implementation for the bottom area of the Keyguard, including camera/phone affordance and status
* text.
@@ -136,9 +145,12 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
private KeyguardAffordanceView mLeftAffordanceView;
private ImageView mWalletButton;
+ private ImageView mControlsButton;
private boolean mHasCard = false;
private WalletCardRetriever mCardRetriever = new WalletCardRetriever();
private QuickAccessWalletController mQuickAccessWalletController;
+ private ControlsComponent mControlsComponent;
+ private boolean mControlServicesAvailable = false;
private ViewGroup mIndicationArea;
private TextView mIndicationText;
@@ -191,6 +203,19 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
private ActivityIntentHelper mActivityIntentHelper;
private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+ private ControlsListingController.ControlsListingCallback mListingCallback =
+ new ControlsListingController.ControlsListingCallback() {
+ public void onServicesUpdated(List<ControlsServiceInfo> serviceInfos) {
+ boolean available = !serviceInfos.isEmpty();
+
+ if (available != mControlServicesAvailable) {
+ mControlServicesAvailable = available;
+ updateControlsVisibility();
+ updateAffordanceColors();
+ }
+ }
+ };
+
public KeyguardBottomAreaView(Context context) {
this(context, null);
}
@@ -257,6 +282,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
mRightAffordanceView = findViewById(R.id.camera_button);
mLeftAffordanceView = findViewById(R.id.left_button);
mWalletButton = findViewById(R.id.wallet_button);
+ mControlsButton = findViewById(R.id.controls_button);
mIndicationArea = findViewById(R.id.keyguard_indication_area);
mIndicationText = findViewById(R.id.keyguard_indication_text);
mIndicationTextBottom = findViewById(R.id.keyguard_indication_text_bottom);
@@ -280,6 +306,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
mIndicationPadding = getResources().getDimensionPixelSize(
R.dimen.keyguard_indication_area_padding);
updateWalletVisibility();
+ updateControlsVisibility();
}
/**
@@ -332,6 +359,11 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
mQuickAccessWalletController.unregisterWalletChangeObservers(
WALLET_PREFERENCE_CHANGE, DEFAULT_PAYMENT_APP_CHANGE);
}
+
+ if (mControlsComponent != null) {
+ mControlsComponent.getControlsListingController().ifPresent(
+ c -> c.removeCallback(mListingCallback));
+ }
}
private void initAccessibility() {
@@ -373,13 +405,20 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
updateLeftAffordanceIcon();
lp = mWalletButton.getLayoutParams();
- lp.width = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_wallet_width);
- lp.height = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_wallet_width);
+ lp.width = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_fixed_width);
+ lp.height = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_fixed_height);
mWalletButton.setLayoutParams(lp);
+ lp = mControlsButton.getLayoutParams();
+ lp.width = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_fixed_width);
+ lp.height = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_fixed_height);
+ mControlsButton.setLayoutParams(lp);
+
mIndicationPadding = getResources().getDimensionPixelSize(
R.dimen.keyguard_indication_area_padding);
+
updateWalletVisibility();
+ updateAffordanceColors();
}
private void updateRightAffordanceIcon() {
@@ -458,22 +497,38 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
|| !mQuickAccessWalletController.isWalletEnabled()
|| !mHasCard) {
mWalletButton.setVisibility(GONE);
- mIndicationArea.setPadding(0, 0, 0, 0);
- } else {
- Drawable tileIcon = mQuickAccessWalletController.getWalletClient().getTileIcon();
- if (tileIcon != null) {
- mWalletButton.setImageDrawable(tileIcon);
+
+ if (mControlsButton.getVisibility() == GONE) {
+ mIndicationArea.setPadding(0, 0, 0, 0);
}
- mWalletButton.getDrawable().setTint(
- Utils.getColorAttr(
- mContext,
- com.android.internal.R.attr.textColorPrimary).getDefaultColor());
+ } else {
mWalletButton.setVisibility(VISIBLE);
mWalletButton.setOnClickListener(this::onWalletClick);
mIndicationArea.setPadding(mIndicationPadding, 0, mIndicationPadding, 0);
}
}
+ private void updateControlsVisibility() {
+ if (mControlsComponent == null) return;
+
+ boolean hasFavorites = mControlsComponent.getControlsController()
+ .map(c -> c.getFavorites().size() > 0)
+ .orElse(false);
+ if (mDozing
+ || !hasFavorites
+ || !mControlServicesAvailable
+ || mControlsComponent.getVisibility() != AVAILABLE) {
+ mControlsButton.setVisibility(GONE);
+ if (mWalletButton.getVisibility() == GONE) {
+ mIndicationArea.setPadding(0, 0, 0, 0);
+ }
+ } else {
+ mControlsButton.setVisibility(VISIBLE);
+ mControlsButton.setOnClickListener(this::onControlsClick);
+ mIndicationArea.setPadding(mIndicationPadding, 0, mIndicationPadding, 0);
+ }
+ }
+
public boolean isLeftVoiceAssist() {
return mLeftIsVoiceAssist;
}
@@ -755,6 +810,9 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
if (mWalletButton.getVisibility() == View.VISIBLE) {
startFinishDozeAnimationElement(mWalletButton, delay);
}
+ if (mControlsButton.getVisibility() == View.VISIBLE) {
+ startFinishDozeAnimationElement(mControlsButton, delay);
+ }
if (mLeftAffordanceView.getVisibility() == View.VISIBLE) {
startFinishDozeAnimationElement(mLeftAffordanceView, delay);
delay += DOZE_ANIMATION_STAGGER_DELAY;
@@ -828,6 +886,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
updateCameraVisibility();
updateLeftAffordanceIcon();
updateWalletVisibility();
+ updateControlsVisibility();
if (dozing) {
mOverlayContainer.setVisibility(INVISIBLE);
@@ -863,6 +922,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
mRightAffordanceView.setAlpha(alpha);
mIndicationArea.setAlpha(alpha);
mWalletButton.setAlpha(alpha);
+ mControlsButton.setAlpha(alpha);
mEmergencyCarrierArea.setAlpha(alpha);
}
@@ -957,6 +1017,32 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
mQuickAccessWalletController.queryWalletCards(mCardRetriever);
updateWalletVisibility();
+ updateAffordanceColors();
+ }
+
+ private void updateAffordanceColors() {
+ int iconColor = Utils.getColorAttrDefaultColor(
+ mContext,
+ com.android.internal.R.attr.textColorPrimary);
+ mWalletButton.getDrawable().setTint(iconColor);
+ mControlsButton.getDrawable().setTint(iconColor);
+
+ ColorStateList bgColor = Utils.getColorAttr(
+ mContext,
+ com.android.internal.R.attr.colorSurface);
+ mWalletButton.setBackgroundTintList(bgColor);
+ mControlsButton.setBackgroundTintList(bgColor);
+ }
+
+ /**
+ * Initialize controls via the ControlsComponent
+ */
+ public void initControls(ControlsComponent controlsComponent) {
+ mControlsComponent = controlsComponent;
+ mControlsComponent.getControlsListingController().ifPresent(
+ c -> c.addCallback(mListingCallback));
+
+ updateAffordanceColors();
}
private void onWalletClick(View v) {
@@ -981,19 +1067,41 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
}
}
+ private void onControlsClick(View v) {
+ if (mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
+ return;
+ }
+
+ Intent intent = new Intent(mContext, ControlsActivity.class)
+ .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK)
+ .putExtra(ControlsUiController.EXTRA_ANIMATE, true);
+
+ if (mControlsComponent.getVisibility() == AVAILABLE) {
+ mContext.startActivity(intent);
+ } else {
+ mActivityStarter.postStartActivityDismissingKeyguard(intent, 0 /* delay */);
+ }
+ }
+
private class WalletCardRetriever implements
QuickAccessWalletClient.OnWalletCardsRetrievedCallback {
@Override
public void onWalletCardsRetrieved(@NonNull GetWalletCardsResponse response) {
mHasCard = !response.getWalletCards().isEmpty();
+ Drawable tileIcon = mQuickAccessWalletController.getWalletClient().getTileIcon();
+ if (tileIcon != null) {
+ mWalletButton.setImageDrawable(tileIcon);
+ }
updateWalletVisibility();
+ updateAffordanceColors();
}
@Override
public void onWalletCardRetrievalError(@NonNull GetWalletCardsError error) {
mHasCard = false;
updateWalletVisibility();
+ updateAffordanceColors();
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt
index ec669711e2db..3a4a819bc623 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt
@@ -222,6 +222,7 @@ open class KeyguardBypassController : Dumpable, StackScrollAlgorithm.BypassContr
pw.println(" launchingAffordance: $launchingAffordance")
pw.println(" qSExpanded: $qSExpanded")
pw.println(" hasFaceFeature: $hasFaceFeature")
+ pw.println(" userHasDeviceEntryIntent: $userHasDeviceEntryIntent")
}
companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
index ad4213d212a0..f77c0520cdb1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
@@ -211,7 +211,7 @@ public class KeyguardClockPositionAlgorithm {
private int getStackScrollerPadding(int clockYPosition) {
if (mBypassEnabled) {
- return mUnlockedStackScrollerPadding;
+ return (int) (mUnlockedStackScrollerPadding + mOverStretchAmount);
} else if (mIsSplitShade) {
return clockYPosition;
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
index cfe95e06fb61..6516abd143ed 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
@@ -165,14 +165,14 @@ public class NotificationIconAreaController implements
* Called by the Keyguard*ViewController whose view contains the aod icons.
*/
public void setupAodIcons(@NonNull NotificationIconContainer aodIcons) {
- boolean changed = mAodIcons != null;
+ boolean changed = mAodIcons != null && aodIcons != mAodIcons;
if (changed) {
mAodIcons.setAnimationsEnabled(false);
mAodIcons.removeAllViews();
}
mAodIcons = aodIcons;
mAodIcons.setOnLockScreen(true);
- updateAodIconsVisibility(false /* animate */);
+ updateAodIconsVisibility(false /* animate */, changed);
updateAnimations();
if (changed) {
updateAodNotificationIcons();
@@ -587,7 +587,7 @@ public class NotificationIconAreaController implements
@Override
public void onStateChanged(int newState) {
- updateAodIconsVisibility(false /* animate */);
+ updateAodIconsVisibility(false /* animate */, false /* force */);
updateAnimations();
}
@@ -663,18 +663,18 @@ public class NotificationIconAreaController implements
// since otherwise the unhide animation overlaps
animate &= fullyHidden;
}
- updateAodIconsVisibility(animate);
+ updateAodIconsVisibility(animate, false /* force */);
updateAodNotificationIcons();
}
@Override
public void onPulseExpansionChanged(boolean expandingChanged) {
if (expandingChanged) {
- updateAodIconsVisibility(true /* animate */);
+ updateAodIconsVisibility(true /* animate */, false /* force */);
}
}
- private void updateAodIconsVisibility(boolean animate) {
+ private void updateAodIconsVisibility(boolean animate, boolean forceUpdate) {
if (mAodIcons == null) {
return;
}
@@ -688,10 +688,11 @@ public class NotificationIconAreaController implements
&& !mUnlockedScreenOffAnimationController.isScreenOffAnimationPlaying()) {
visible = false;
}
- if (visible && mWakeUpCoordinator.isPulseExpanding()) {
+ if (visible && mWakeUpCoordinator.isPulseExpanding()
+ && !mBypassController.getBypassEnabled()) {
visible = false;
}
- if (mAodIconsVisible != visible) {
+ if (mAodIconsVisible != visible || forceUpdate) {
mAodIconsVisible = visible;
mAodIcons.animate().cancel();
if (animate) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
index 0fb26a2d0470..0ce7c2d2c3fe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -99,6 +99,7 @@ import com.android.systemui.animation.Interpolators;
import com.android.systemui.biometrics.AuthController;
import com.android.systemui.classifier.Classifier;
import com.android.systemui.classifier.FalsingCollector;
+import com.android.systemui.controls.dagger.ControlsComponent;
import com.android.systemui.dagger.qualifiers.DisplayId;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.doze.DozeLog;
@@ -323,6 +324,7 @@ public class NotificationPanelViewController extends PanelViewController {
private final ScrimController mScrimController;
private final PrivacyDotViewController mPrivacyDotViewController;
private final QuickAccessWalletController mQuickAccessWalletController;
+ private final ControlsComponent mControlsComponent;
private final NotificationRemoteInputManager mRemoteInputManager;
// Maximum # notifications to show on Keyguard; extras will be collapsed in an overflow card.
@@ -611,6 +613,11 @@ public class NotificationPanelViewController extends PanelViewController {
* Is the current animator resetting the qs translation.
*/
private boolean mIsQsTranslationResetAnimator;
+
+ /**
+ * Is the current animator resetting the pulse expansion after a drag down
+ */
+ private boolean mIsPulseExpansionResetAnimator;
private final Rect mKeyguardStatusAreaClipBounds = new Rect();
private final Region mQsInterceptRegion = new Region();
@@ -629,6 +636,9 @@ public class NotificationPanelViewController extends PanelViewController {
private int mScreenCornerRadius;
private boolean mQSAnimatingHiddenFromCollapsed;
+ private int mQsClipTop;
+ private int mQsClipBottom;
+ private boolean mQsVisible;
private final ContentResolver mContentResolver;
private final Executor mUiExecutor;
@@ -722,8 +732,9 @@ public class NotificationPanelViewController extends PanelViewController {
@Main Executor uiExecutor,
SecureSettings secureSettings,
UnlockedScreenOffAnimationController unlockedScreenOffAnimationController,
- EmergencyButtonController.Factory emergencyButtonControllerFactory,
- NotificationRemoteInputManager remoteInputManager) {
+ NotificationRemoteInputManager remoteInputManager,
+ ControlsComponent controlsComponent,
+ EmergencyButtonController.Factory emergencyButtonControllerFactory) {
super(view, falsingManager, dozeLog, keyguardStateController,
(SysuiStatusBarStateController) statusBarStateController, vibratorHelper,
statusBarKeyguardViewManager, latencyTracker, flingAnimationUtilsBuilder.get(),
@@ -733,6 +744,7 @@ public class NotificationPanelViewController extends PanelViewController {
mKeyguardMediaController = keyguardMediaController;
mPrivacyDotViewController = privacyDotViewController;
mQuickAccessWalletController = quickAccessWalletController;
+ mControlsComponent = controlsComponent;
mMetricsLogger = metricsLogger;
mActivityManager = activityManager;
mConfigurationController = configurationController;
@@ -887,14 +899,7 @@ public class NotificationPanelViewController extends PanelViewController {
mWakeUpCoordinator.setStackScroller(mNotificationStackScrollLayoutController);
mQsFrame = mView.findViewById(R.id.qs_frame);
- mPulseExpansionHandler.setUp(mNotificationStackScrollLayoutController,
- amount -> {
- float progress = amount / mView.getHeight();
- float overstretch = Interpolators.getOvershootInterpolation(progress,
- (float) mMaxOverscrollAmountForPulse / mView.getHeight(),
- 0.2f);
- setOverStrechAmount(overstretch);
- });
+ mPulseExpansionHandler.setUp(mNotificationStackScrollLayoutController);
mWakeUpCoordinator.addListener(new NotificationWakeUpCoordinator.WakeUpListener() {
@Override
public void onFullyHiddenChanged(boolean isFullyHidden) {
@@ -906,7 +911,6 @@ public class NotificationPanelViewController extends PanelViewController {
if (mKeyguardBypassController.getBypassEnabled()) {
// Position the notifications while dragging down while pulsing
requestScrollerTopPaddingUpdate(false /* animate */);
- updateQSPulseExpansion();
}
}
});
@@ -944,8 +948,6 @@ public class NotificationPanelViewController extends PanelViewController {
R.dimen.notification_panel_min_side_margin);
mIndicationBottomPadding = mResources.getDimensionPixelSize(
R.dimen.keyguard_indication_bottom_padding);
- mQsNotificationTopPadding = mResources.getDimensionPixelSize(
- R.dimen.qs_notification_padding);
mShelfHeight = mResources.getDimensionPixelSize(R.dimen.notification_shelf_height);
mDarkIconSize = mResources.getDimensionPixelSize(R.dimen.status_bar_icon_drawing_size_dark);
int statusbarHeight = mResources.getDimensionPixelSize(
@@ -1184,6 +1186,7 @@ public class NotificationPanelViewController extends PanelViewController {
mKeyguardBottomArea.setUserSetupComplete(mUserSetupComplete);
mKeyguardBottomArea.setFalsingManager(mFalsingManager);
mKeyguardBottomArea.initWallet(mQuickAccessWalletController);
+ mKeyguardBottomArea.initControls(mControlsComponent);
EmergencyButton emergencyButton =
mKeyguardBottomArea.findViewById(R.id.emergency_call_button);
mEmergencyButtonController = mEmergencyButtonControllerFactory.create(emergencyButton);
@@ -1347,8 +1350,7 @@ public class NotificationPanelViewController extends PanelViewController {
* @return the padding of the stackscroller when unlocked
*/
private int getUnlockedStackScrollerPadding() {
- return (mQs != null ? mQs.getHeader().getHeight() : 0) + mQsPeekHeight
- + mQsNotificationTopPadding;
+ return (mQs != null ? mQs.getHeader().getHeight() : 0) + mQsPeekHeight;
}
/**
@@ -2245,7 +2247,7 @@ public class NotificationPanelViewController extends PanelViewController {
}
}
- protected void updateQsExpansion() {
+ private void updateQsExpansion() {
if (mQs == null) return;
float qsExpansionFraction = computeQsExpansionFraction();
mQs.setQsExpansion(qsExpansionFraction, getHeaderTranslation());
@@ -2304,9 +2306,20 @@ public class NotificationPanelViewController extends PanelViewController {
top = mTransitionToFullShadeQSPosition;
} else {
final float notificationTop = getQSEdgePosition();
- top = (int) (isOnKeyguard() ? Math.min(qsPanelBottomY, notificationTop)
- : notificationTop);
+ if (isOnKeyguard()) {
+ if (mKeyguardBypassController.getBypassEnabled()) {
+ // When bypassing on the keyguard, let's use the panel bottom.
+ // this should go away once we unify the stackY position and don't have
+ // to do this min anymore below.
+ top = qsPanelBottomY;
+ } else {
+ top = (int) Math.min(qsPanelBottomY, notificationTop);
+ }
+ } else {
+ top = (int) notificationTop;
+ }
}
+ top += mOverStretchAmount;
bottom = getView().getBottom();
// notification bounds should take full screen width regardless of insets
left = 0;
@@ -2337,6 +2350,9 @@ public class NotificationPanelViewController extends PanelViewController {
final int startTop = mKeyguardStatusAreaClipBounds.top;
final int startRight = mKeyguardStatusAreaClipBounds.right;
final int startBottom = mKeyguardStatusAreaClipBounds.bottom;
+ if (mQsClippingAnimation != null) {
+ mQsClippingAnimation.cancel();
+ }
mQsClippingAnimation = ValueAnimator.ofFloat(0.0f, 1.0f);
mQsClippingAnimation.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
mQsClippingAnimation.setDuration(mNotificationBoundsAnimationDuration);
@@ -2359,6 +2375,7 @@ public class NotificationPanelViewController extends PanelViewController {
public void onAnimationEnd(Animator animation) {
mQsClippingAnimation = null;
mIsQsTranslationResetAnimator = false;
+ mIsPulseExpansionResetAnimator = false;
}
});
mQsClippingAnimation.start();
@@ -2384,16 +2401,27 @@ public class NotificationPanelViewController extends PanelViewController {
}
if (mQs != null) {
float qsTranslation = 0;
- if (mTransitioningToFullShadeProgress > 0.0f || (mQsClippingAnimation != null
- && mIsQsTranslationResetAnimator)) {
- qsTranslation = (top - mQs.getHeader().getHeight()) * QS_PARALLAX_AMOUNT;
+ boolean pulseExpanding = mPulseExpansionHandler.isExpanding();
+ if (mTransitioningToFullShadeProgress > 0.0f || pulseExpanding
+ || (mQsClippingAnimation != null
+ && (mIsQsTranslationResetAnimator || mIsPulseExpansionResetAnimator))) {
+ if (pulseExpanding || mIsPulseExpansionResetAnimator) {
+ // qsTranslation should only be positive during pulse expansion because it's
+ // already translating in from the top
+ qsTranslation = Math.max(0, (top - mQs.getHeader().getHeight()) / 2.0f);
+ } else {
+ qsTranslation = (top - mQs.getHeader().getHeight()) * QS_PARALLAX_AMOUNT;
+ }
}
mQsTranslationForFullShadeTransition = qsTranslation;
updateQsFrameTranslation();
float currentTranslation = mQsFrame.getTranslationY();
- mQs.setFancyClipping((
- int) (top - currentTranslation),
- (int) (bottom - currentTranslation),
+ mQsClipTop = (int) (top - currentTranslation);
+ mQsClipBottom = (int) (bottom - currentTranslation);
+ mQsVisible = qsVisible;
+ mQs.setFancyClipping(
+ mQsClipTop,
+ mQsClipBottom,
radius, qsVisible
&& !mShouldUseSplitNotificationShade);
}
@@ -2453,7 +2481,7 @@ public class NotificationPanelViewController extends PanelViewController {
private float calculateNotificationsTopPadding() {
if (mShouldUseSplitNotificationShade && !mKeyguardShowing) {
- return mSplitShadeNotificationsTopPadding + mQsNotificationTopPadding;
+ return mSplitShadeNotificationsTopPadding;
}
if (mKeyguardShowing && (mQsExpandImmediate
|| mIsExpanding && mQsExpandedWhenExpandingStarted)) {
@@ -2464,7 +2492,7 @@ public class NotificationPanelViewController extends PanelViewController {
// panel. We need to take the maximum and linearly interpolate with the panel expansion
// for a nice motion.
int maxNotificationPadding = getKeyguardNotificationStaticPadding();
- int maxQsPadding = mQsMaxExpansionHeight + mQsNotificationTopPadding;
+ int maxQsPadding = mQsMaxExpansionHeight;
int max = mBarState == KEYGUARD ? Math.max(
maxNotificationPadding, maxQsPadding) : maxQsPadding;
return (int) MathUtils.lerp((float) mQsMinExpansionHeight, (float) max,
@@ -2477,10 +2505,10 @@ public class NotificationPanelViewController extends PanelViewController {
// We can only do the smoother transition on Keyguard when we also are not collapsing
// from a scrolled quick settings.
return MathUtils.lerp((float) getKeyguardNotificationStaticPadding(),
- (float) (mQsMaxExpansionHeight + mQsNotificationTopPadding),
+ (float) (mQsMaxExpansionHeight),
computeQsExpansionFraction());
} else {
- return mQsExpansionHeight + mQsNotificationTopPadding;
+ return mQsExpansionHeight;
}
}
@@ -2515,14 +2543,6 @@ public class NotificationPanelViewController extends PanelViewController {
}
}
- private void updateQSPulseExpansion() {
- if (mQs != null) {
- mQs.setPulseExpanding(
- mKeyguardShowing && mKeyguardBypassController.getBypassEnabled()
- && mNotificationStackScrollLayoutController.isPulseExpanding());
- }
- }
-
/**
* Set the amount of pixels we have currently dragged down if we're transitioning to the full
* shade. 0.0f means we're not transitioning yet.
@@ -2574,6 +2594,15 @@ public class NotificationPanelViewController extends PanelViewController {
}
/**
+ * Notify the panel that the pulse expansion has finished and that we're going to the full
+ * shade
+ */
+ public void onPulseExpansionFinished() {
+ animateNextNotificationBounds(StackStateAnimator.ANIMATION_DURATION_GO_TO_FULL_SHADE, 0);
+ mIsPulseExpansionResetAnimator = true;
+ }
+
+ /**
* Set the alpha of the keyguard elements which only show on the lockscreen, but not in
* shade locked / shade. This is used when dragging down to the full shade.
*/
@@ -2866,10 +2895,6 @@ public class NotificationPanelViewController extends PanelViewController {
}
int maxQsHeight = mQsMaxExpansionHeight;
- if (mKeyguardShowing) {
- maxQsHeight += mQsNotificationTopPadding;
- }
-
// If an animation is changing the size of the QS panel, take the animated value.
if (mQsSizeChangeAnimator != null) {
maxQsHeight = (int) mQsSizeChangeAnimator.getAnimatedValue();
@@ -2934,19 +2959,7 @@ public class NotificationPanelViewController extends PanelViewController {
startHeight = -mQsExpansionHeight * QS_PARALLAX_AMOUNT;
}
if (mKeyguardBypassController.getBypassEnabled() && isOnKeyguard()) {
- if (mNotificationStackScrollLayoutController.isPulseExpanding()) {
- if (!mPulseExpansionHandler.isExpanding()
- && !mPulseExpansionHandler.getLeavingLockscreen()) {
- // If we aborted the expansion we need to make sure the header doesn't reappear
- // again after the header has animated away
- appearAmount = 0;
- } else {
- appearAmount = mNotificationStackScrollLayoutController
- .calculateAppearFractionBypass();
- }
- } else {
- appearAmount = 0.0f;
- }
+ appearAmount = mNotificationStackScrollLayoutController.calculateAppearFractionBypass();
startHeight = -mQs.getQsMinExpansionHeight();
}
float translation = MathUtils.lerp(startHeight, 0, Math.min(1.0f, appearAmount));
@@ -3246,7 +3259,10 @@ public class NotificationPanelViewController extends PanelViewController {
switch (mBarState) {
case KEYGUARD:
if (!mDozingOnDown) {
- if (mKeyguardBypassController.getBypassEnabled()) {
+ if (mUpdateMonitor.isFaceEnrolled()
+ && !mUpdateMonitor.isFaceDetectionRunning()
+ && !mUpdateMonitor.getUserCanSkipBouncer(
+ KeyguardUpdateMonitor.getCurrentUser())) {
mUpdateMonitor.requestFaceAuth(true);
} else {
mLockscreenGestureLogger.write(MetricsEvent.ACTION_LS_HINT,
@@ -3549,7 +3565,6 @@ public class NotificationPanelViewController extends PanelViewController {
mQs.setPanelView(mHeightListener);
mQs.setExpandClickListener(mOnClickListener);
mQs.setHeaderClickable(isQsExpansionEnabled());
- updateQSPulseExpansion();
mQs.setOverscrolling(mStackScrollerOverscrolling);
mQs.setTranslateWhileExpanding(mShouldUseSplitNotificationShade);
@@ -3738,7 +3753,10 @@ public class NotificationPanelViewController extends PanelViewController {
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
super.dump(fd, pw, args);
- pw.println(" gestureExclusionRect: " + calculateGestureExclusionRect());
+ pw.println(" gestureExclusionRect: " + calculateGestureExclusionRect()
+ + " applyQSClippingImmediately: top(" + mQsClipTop + ") bottom(" + mQsClipBottom
+ + ") qsVisible(" + mQsVisible
+ );
if (mKeyguardStatusBar != null) {
mKeyguardStatusBar.dump(fd, pw, args);
}
@@ -4310,8 +4328,7 @@ public class NotificationPanelViewController extends PanelViewController {
if (mAccessibilityManager.isEnabled()) {
mView.setAccessibilityPaneTitle(determineAccessibilityPaneTitle());
}
- mNotificationStackScrollLayoutController.setMaxTopPadding(
- mQsMaxExpansionHeight + mQsNotificationTopPadding);
+ mNotificationStackScrollLayoutController.setMaxTopPadding(mQsMaxExpansionHeight);
}
}
@@ -4429,7 +4446,6 @@ public class NotificationPanelViewController extends PanelViewController {
updateMaxDisplayedNotifications(false);
// The update needs to happen after the headerSlide in above, otherwise the translation
// would reset
- updateQSPulseExpansion();
maybeAnimateBottomAreaAlpha();
resetHorizontalPanelPosition();
updateQsState();
@@ -4464,7 +4480,9 @@ public class NotificationPanelViewController extends PanelViewController {
* Sets the overstretch amount in raw pixels when dragging down.
*/
public void setOverStrechAmount(float amount) {
- mOverStretchAmount = amount;
+ float progress = amount / mView.getHeight();
+ float overstretch = Interpolators.getOvershootInterpolation(progress);
+ mOverStretchAmount = overstretch * mMaxOverscrollAmountForPulse;
positionClockAndNotifications(true /* forceUpdate */);
}
@@ -4518,8 +4536,7 @@ public class NotificationPanelViewController extends PanelViewController {
if (mQs != null) {
updateQSMinHeight();
mQsMaxExpansionHeight = mQs.getDesiredHeight();
- mNotificationStackScrollLayoutController.setMaxTopPadding(
- mQsMaxExpansionHeight + mQsNotificationTopPadding);
+ mNotificationStackScrollLayoutController.setMaxTopPadding(mQsMaxExpansionHeight);
}
positionClockAndNotifications();
if (mQsExpanded && mQsFullyExpanded) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java
index 5e105bb64350..246810a2d70b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java
@@ -296,8 +296,7 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW
if (mKeyguardPreferredRefreshRate > 0) {
boolean onKeyguard = state.mStatusBarState == StatusBarState.KEYGUARD
- && !state.mKeyguardFadingAway && !state.mKeyguardGoingAway
- && !state.mDozing;
+ && !state.mKeyguardFadingAway && !state.mKeyguardGoingAway;
if (onKeyguard
&& mAuthController.isUdfpsEnrolled(KeyguardUpdateMonitor.getCurrentUser())) {
mLpChanged.preferredMaxDisplayRefreshRate = mKeyguardPreferredRefreshRate;
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 173eec18ecc5..d257165ae24e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -3616,6 +3616,7 @@ public class StatusBar extends SystemUI implements DemoMode,
mIsKeyguard = false;
Trace.beginSection("StatusBar#hideKeyguard");
boolean staying = mStatusBarStateController.leaveOpenOnKeyguardHide();
+ int previousState = mStatusBarStateController.getState();
if (!(mStatusBarStateController.setState(StatusBarState.SHADE, force))) {
//TODO: StatusBarStateController should probably know about hiding the keyguard and
// notify listeners.
@@ -3628,7 +3629,7 @@ public class StatusBar extends SystemUI implements DemoMode,
mStatusBarStateController.setLeaveOpenOnKeyguardHide(false);
}
long delay = mKeyguardStateController.calculateGoingToFullShadeDelay();
- mLockscreenShadeTransitionController.onHideKeyguard(delay);
+ mLockscreenShadeTransitionController.onHideKeyguard(delay, previousState);
// Disable layout transitions in navbar for this transition because the load is just
// too heavy for the CPU and GPU on any device.
@@ -3983,7 +3984,7 @@ public class StatusBar extends SystemUI implements DemoMode,
public void onUnlockHintStarted() {
mFalsingCollector.onUnlockHintStarted();
- mKeyguardIndicationController.showTransientIndication(R.string.keyguard_unlock);
+ mKeyguardIndicationController.showActionToUnlock();
}
public void onHintFinished() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
index c94eaeda3906..8f1a5782e779 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
@@ -23,6 +23,7 @@ import static com.android.systemui.DejankUtils.whitelistIpcs;
import android.annotation.UserIdInt;
import android.app.ActivityManager;
+import android.app.AlertDialog;
import android.app.Dialog;
import android.app.IActivityTaskManager;
import android.content.BroadcastReceiver;
@@ -64,16 +65,18 @@ import com.android.systemui.R;
import com.android.systemui.SystemUISecondaryUserService;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.dagger.qualifiers.UiBackground;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.qs.DetailAdapter;
import com.android.systemui.qs.QSUserSwitcherEvent;
import com.android.systemui.qs.tiles.UserDetailView;
+import com.android.systemui.settings.UserTracker;
import com.android.systemui.statusbar.phone.SystemUIDialog;
import com.android.systemui.telephony.TelephonyListenerManager;
import com.android.systemui.user.CreateUserActivity;
+import com.android.systemui.util.settings.SecureSettings;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -104,9 +107,12 @@ public class UserSwitcherController implements Dumpable {
private static final String PERMISSION_SELF = "com.android.systemui.permission.SELF";
protected final Context mContext;
+ protected final UserTracker mUserTracker;
protected final UserManager mUserManager;
+ private final ContentObserver mSettingsObserver;
private final ArrayList<WeakReference<BaseUserAdapter>> mAdapters = new ArrayList<>();
- private final GuestResumeSessionReceiver mGuestResumeSessionReceiver;
+ @VisibleForTesting
+ final GuestResumeSessionReceiver mGuestResumeSessionReceiver;
private final KeyguardStateController mKeyguardStateController;
protected final Handler mHandler;
private final ActivityStarter mActivityStarter;
@@ -115,27 +121,33 @@ public class UserSwitcherController implements Dumpable {
private final IActivityTaskManager mActivityTaskManager;
private ArrayList<UserRecord> mUsers = new ArrayList<>();
- private Dialog mExitGuestDialog;
- private Dialog mAddUserDialog;
+ @VisibleForTesting
+ AlertDialog mExitGuestDialog;
+ @VisibleForTesting
+ Dialog mAddUserDialog;
private int mLastNonGuestUser = UserHandle.USER_SYSTEM;
private boolean mResumeUserOnGuestLogout = true;
private boolean mSimpleUserSwitcher;
// When false, there won't be any visual affordance to add a new user from the keyguard even if
// the user is unlocked
private boolean mAddUsersFromLockScreen;
- private boolean mPauseRefreshUsers;
+ @VisibleForTesting
+ boolean mPauseRefreshUsers;
private int mSecondaryUser = UserHandle.USER_NULL;
private Intent mSecondaryUserServiceIntent;
private SparseBooleanArray mForcePictureLoadForUserId = new SparseBooleanArray(2);
private final UiEventLogger mUiEventLogger;
public final DetailAdapter mUserDetailAdapter;
- private final Executor mUiBgExecutor;
+ private final Executor mBgExecutor;
private final boolean mGuestUserAutoCreated;
+ private final AtomicBoolean mGuestIsResetting;
private final AtomicBoolean mGuestCreationScheduled;
private FalsingManager mFalsingManager;
@Inject
public UserSwitcherController(Context context,
+ UserManager userManager,
+ UserTracker userTracker,
KeyguardStateController keyguardStateController,
@Main Handler handler,
ActivityStarter activityStarter,
@@ -145,26 +157,30 @@ public class UserSwitcherController implements Dumpable {
TelephonyListenerManager telephonyListenerManager,
IActivityTaskManager activityTaskManager,
UserDetailAdapter userDetailAdapter,
- @UiBackground Executor uiBgExecutor) {
+ SecureSettings secureSettings,
+ @Background Executor bgExecutor) {
mContext = context;
+ mUserTracker = userTracker;
mBroadcastDispatcher = broadcastDispatcher;
mTelephonyListenerManager = telephonyListenerManager;
mActivityTaskManager = activityTaskManager;
mUiEventLogger = uiEventLogger;
mFalsingManager = falsingManager;
- mGuestResumeSessionReceiver = new GuestResumeSessionReceiver(this, mUiEventLogger);
+ mGuestResumeSessionReceiver = new GuestResumeSessionReceiver(
+ this, mUserTracker, mUiEventLogger, secureSettings);
mUserDetailAdapter = userDetailAdapter;
- mUiBgExecutor = uiBgExecutor;
+ mBgExecutor = bgExecutor;
if (!UserManager.isGuestUserEphemeral()) {
mGuestResumeSessionReceiver.register(mBroadcastDispatcher);
}
mGuestUserAutoCreated = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_guestUserAutoCreated);
+ mGuestIsResetting = new AtomicBoolean();
mGuestCreationScheduled = new AtomicBoolean();
mKeyguardStateController = keyguardStateController;
mHandler = handler;
mActivityStarter = activityStarter;
- mUserManager = UserManager.get(context);
+ mUserManager = userManager;
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_USER_ADDED);
filter.addAction(Intent.ACTION_USER_REMOVED);
@@ -183,6 +199,15 @@ public class UserSwitcherController implements Dumpable {
mContext.registerReceiverAsUser(mReceiver, UserHandle.SYSTEM, filter,
PERMISSION_SELF, null /* scheduler */);
+ mSettingsObserver = new ContentObserver(mHandler) {
+ @Override
+ public void onChange(boolean selfChange) {
+ mSimpleUserSwitcher = shouldUseSimpleUserSwitcher();
+ mAddUsersFromLockScreen = Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.ADD_USERS_WHEN_LOCKED, 0) != 0;
+ refreshUsers(UserHandle.USER_NULL);
+ };
+ };
mContext.getContentResolver().registerContentObserver(
Settings.Global.getUriFor(SIMPLE_USER_SWITCHER_GLOBAL_SETTING), true,
mSettingsObserver);
@@ -244,11 +269,11 @@ public class UserSwitcherController implements Dumpable {
return null;
}
ArrayList<UserRecord> records = new ArrayList<>(infos.size());
- int currentId = ActivityManager.getCurrentUser();
+ int currentId = mUserTracker.getUserId();
// Check user switchability of the foreground user since SystemUI is running in
// User 0
boolean canSwitchUsers = mUserManager.getUserSwitchability(
- UserHandle.of(ActivityManager.getCurrentUser())) == SWITCHABILITY_STATUS_OK;
+ UserHandle.of(mUserTracker.getUserId())) == SWITCHABILITY_STATUS_OK;
UserInfo currentUserInfo = null;
UserRecord guestRecord = null;
@@ -301,7 +326,20 @@ public class UserSwitcherController implements Dumpable {
boolean createIsRestricted = !addUsersWhenLocked;
if (guestRecord == null) {
- if (canCreateGuest) {
+ if (mGuestUserAutoCreated) {
+ // If mGuestIsResetting=true, the switch should be disabled since
+ // we will just use it as an indicator for "Resetting guest...".
+ // Otherwise, default to canSwitchUsers.
+ boolean isSwitchToGuestEnabled =
+ !mGuestIsResetting.get() && canSwitchUsers;
+ guestRecord = new UserRecord(null /* info */, null /* picture */,
+ true /* isGuest */, false /* isCurrent */,
+ false /* isAddUser */, false /* isRestricted */,
+ isSwitchToGuestEnabled);
+ // Don't call checkIfAddUserDisallowedByAdminOnly if
+ // config_guestUserAutoCreated=true.
+ records.add(guestRecord);
+ } else if (canCreateGuest) {
guestRecord = new UserRecord(null /* info */, null /* picture */,
true /* isGuest */, false /* isCurrent */,
false /* isAddUser */, createIsRestricted, canSwitchUsers);
@@ -376,7 +414,7 @@ public class UserSwitcherController implements Dumpable {
}
public void logoutCurrentUser() {
- int currentUser = ActivityManager.getCurrentUser();
+ int currentUser = mUserTracker.getUserId();
if (currentUser != UserHandle.USER_SYSTEM) {
pauseRefreshUsers();
ActivityManager.logoutCurrentUser();
@@ -388,7 +426,7 @@ public class UserSwitcherController implements Dumpable {
Log.w(TAG, "User " + userId + " could not removed.");
return;
}
- if (ActivityManager.getCurrentUser() == userId) {
+ if (mUserTracker.getUserId() == userId) {
switchToUserId(UserHandle.USER_SYSTEM);
}
if (mUserManager.removeUser(userId)) {
@@ -396,7 +434,8 @@ public class UserSwitcherController implements Dumpable {
}
}
- private void onUserListItemClicked(UserRecord record) {
+ @VisibleForTesting
+ void onUserListItemClicked(UserRecord record) {
int id;
if (record.isGuest && record.info == null) {
// No guest user. Create one.
@@ -414,7 +453,7 @@ public class UserSwitcherController implements Dumpable {
id = record.info.id;
}
- int currUserId = ActivityManager.getCurrentUser();
+ int currUserId = mUserTracker.getUserId();
if (currUserId == id) {
if (record.isGuest) {
showExitGuestDialog(id);
@@ -572,15 +611,6 @@ public class UserSwitcherController implements Dumpable {
}
};
- private final ContentObserver mSettingsObserver = new ContentObserver(new Handler()) {
- public void onChange(boolean selfChange) {
- mSimpleUserSwitcher = shouldUseSimpleUserSwitcher();
- mAddUsersFromLockScreen = Settings.Global.getInt(mContext.getContentResolver(),
- Settings.Global.ADD_USERS_WHEN_LOCKED, 0) != 0;
- refreshUsers(UserHandle.USER_NULL);
- };
- };
-
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println("UserSwitcherController state:");
@@ -639,13 +669,7 @@ public class UserSwitcherController implements Dumpable {
* UserHandle.USER_NULL}, then switch immediately to the newly created guest user.
*/
public void removeGuestUser(@UserIdInt int guestUserId, @UserIdInt int targetUserId) {
- UserInfo currentUser;
- try {
- currentUser = ActivityManager.getService().getCurrentUser();
- } catch (RemoteException e) {
- Log.e(TAG, "Couldn't remove guest because ActivityManager is dead");
- return;
- }
+ UserInfo currentUser = mUserTracker.getUserInfo();
if (currentUser.id != guestUserId) {
Log.w(TAG, "User requesting to start a new session (" + guestUserId + ")"
+ " is not current user (" + currentUser.id + ")");
@@ -677,6 +701,9 @@ public class UserSwitcherController implements Dumpable {
switchToUserId(newGuestId);
mUserManager.removeUser(currentUser.id);
} else {
+ if (mGuestUserAutoCreated) {
+ mGuestIsResetting.set(true);
+ }
switchToUserId(targetUserId);
mUserManager.removeUser(currentUser.id);
}
@@ -691,12 +718,16 @@ public class UserSwitcherController implements Dumpable {
return;
}
- mUiBgExecutor.execute(() -> {
+ mBgExecutor.execute(() -> {
int newGuestId = createGuest();
+ mGuestCreationScheduled.set(false);
+ mGuestIsResetting.set(false);
if (newGuestId == UserHandle.USER_NULL) {
Log.w(TAG, "Could not create new guest while exiting existing guest");
+ // Refresh users so that we still display "Guest" if
+ // config_guestUserAutoCreated=true
+ refreshUsers(UserHandle.USER_NULL);
}
- mGuestCreationScheduled.set(false);
});
}
@@ -799,12 +830,25 @@ public class UserSwitcherController implements Dumpable {
? com.android.settingslib.R.string.guest_reset_guest
: com.android.settingslib.R.string.guest_exit_guest);
} else {
- // If config_guestUserAutoCreated, always show guest nickname instead of "Add
- // guest" to make it seem as though the device always has a guest ready for use
- return context.getString(
- item.info == null && !mController.mGuestUserAutoCreated
- ? com.android.settingslib.R.string.guest_new_guest
- : com.android.settingslib.R.string.guest_nickname);
+ if (item.info != null) {
+ return context.getString(com.android.settingslib.R.string.guest_nickname);
+ } else {
+ if (mController.mGuestUserAutoCreated) {
+ // If mGuestIsResetting=true, we expect the guest user to be created
+ // shortly, so display a "Resetting guest..." as an indicator that we
+ // are busy. Otherwise, if mGuestIsResetting=false, we probably failed
+ // to create a guest at some point. In this case, always show guest
+ // nickname instead of "Add guest" to make it seem as though the device
+ // always has a guest ready for use.
+ return context.getString(
+ mController.mGuestIsResetting.get()
+ ? com.android.settingslib.R.string.guest_resetting
+ : com.android.settingslib.R.string.guest_nickname);
+ } else {
+ return context.getString(
+ com.android.settingslib.R.string.guest_new_guest);
+ }
+ }
}
} else if (item.isAddUser) {
return context.getString(R.string.user_add_user);
@@ -839,9 +883,9 @@ public class UserSwitcherController implements Dumpable {
private void checkIfAddUserDisallowedByAdminOnly(UserRecord record) {
EnforcedAdmin admin = RestrictedLockUtilsInternal.checkIfRestrictionEnforced(mContext,
- UserManager.DISALLOW_ADD_USER, ActivityManager.getCurrentUser());
+ UserManager.DISALLOW_ADD_USER, mUserTracker.getUserId());
if (admin != null && !RestrictedLockUtilsInternal.hasBaseUserRestriction(mContext,
- UserManager.DISALLOW_ADD_USER, ActivityManager.getCurrentUser())) {
+ UserManager.DISALLOW_ADD_USER, mUserTracker.getUserId())) {
record.isDisabledByAdmin = true;
record.enforcedAdmin = admin;
} else {
@@ -1053,7 +1097,8 @@ public class UserSwitcherController implements Dumpable {
}
}
- private final class AddUserDialog extends SystemUIDialog implements
+ @VisibleForTesting
+ final class AddUserDialog extends SystemUIDialog implements
DialogInterface.OnClickListener {
public AddUserDialog(Context context) {
diff --git a/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java b/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java
index df889f2c2ca6..35251002fb7b 100644
--- a/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java
@@ -39,6 +39,7 @@ import com.android.systemui.plugins.qs.QSFactory;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.power.EnhancedEstimates;
import com.android.systemui.power.EnhancedEstimatesImpl;
+import com.android.systemui.power.dagger.PowerModule;
import com.android.systemui.qs.dagger.QSModule;
import com.android.systemui.qs.tileimpl.QSFactoryImpl;
import com.android.systemui.recents.Recents;
@@ -81,6 +82,7 @@ import dagger.Provides;
* overridden by the System UI implementation.
*/
@Module(includes = {
+ PowerModule.class,
QSModule.class
},
subcomponents = {
diff --git a/packages/SystemUI/src/com/android/systemui/util/sensors/ProximitySensor.java b/packages/SystemUI/src/com/android/systemui/util/sensors/ProximitySensor.java
index 19ed2848ca6f..b38fc77fd131 100644
--- a/packages/SystemUI/src/com/android/systemui/util/sensors/ProximitySensor.java
+++ b/packages/SystemUI/src/com/android/systemui/util/sensors/ProximitySensor.java
@@ -281,18 +281,24 @@ public class ProximitySensor implements ThresholdSensor {
mLastPrimaryEvent = event;
- if (event.getBelow() && mSecondaryThresholdSensor.isLoaded()) {
- logDebug("Primary sensor is near. Checking secondary.");
+ if (mSecondarySafe && mSecondaryThresholdSensor.isLoaded()) {
+ logDebug("Primary sensor reported " + (event.getBelow() ? "near" : "far")
+ + ". Checking secondary.");
if (mCancelSecondaryRunnable == null) {
mSecondaryThresholdSensor.resume();
}
- } else {
- if (!mSecondaryThresholdSensor.isLoaded()) {
- logDebug("Primary sensor event: " + event.getBelow() + ". No secondary.");
- } else {
- logDebug("Primary sensor event: " + event.getBelow() + ".");
- }
+ return;
+ }
+
+ if (!mSecondaryThresholdSensor.isLoaded()) {
+ logDebug("Primary sensor event: " + event.getBelow() + ". No secondary.");
onSensorEvent(event);
+ } else if (event.getBelow()) {
+ logDebug("Primary sensor event: " + event.getBelow() + ". Checking secondary.");
+ if (mCancelSecondaryRunnable != null) {
+ mCancelSecondaryRunnable.run();
+ }
+ mSecondaryThresholdSensor.resume();
}
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index e9061afb647d..ec4dfba87af0 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -513,7 +513,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
public void testTriesToAuthenticate_whenBouncer() {
setKeyguardBouncerVisibility(true);
- verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt());
+ verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt(), anyBoolean());
verify(mFaceManager).isHardwareDetected();
verify(mFaceManager).hasEnrolledTemplates(anyInt());
}
@@ -523,7 +523,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
mKeyguardUpdateMonitor.dispatchStartedWakingUp();
mTestableLooper.processAllMessages();
mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(true);
- verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt());
+ verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt(), anyBoolean());
}
@Test
@@ -533,7 +533,8 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
mTestableLooper.processAllMessages();
mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(true);
- verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt());
+ verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt(),
+ anyBoolean());
}
@Test
@@ -545,7 +546,8 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
mKeyguardUpdateMonitor.dispatchStartedWakingUp();
mTestableLooper.processAllMessages();
mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(true);
- verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt());
+ verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt(),
+ anyBoolean());
}
@Test
@@ -568,13 +570,14 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
mKeyguardUpdateMonitor.dispatchStartedWakingUp();
mTestableLooper.processAllMessages();
mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(true);
- verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt());
+ verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt(), anyBoolean());
// Stop scanning when bouncer becomes visible
setKeyguardBouncerVisibility(true);
clearInvocations(mFaceManager);
mKeyguardUpdateMonitor.requestFaceAuth(true);
- verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt());
+ verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt(),
+ anyBoolean());
}
@Test
@@ -582,7 +585,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
mKeyguardUpdateMonitor.setKeyguardOccluded(true);
mKeyguardUpdateMonitor.setAssistantVisible(true);
- verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt());
+ verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt(), anyBoolean());
}
@Test
@@ -594,7 +597,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
mKeyguardUpdateMonitor.onTrustChanged(true /* enabled */,
KeyguardUpdateMonitor.getCurrentUser(), 0 /* flags */);
mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(true);
- verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt());
+ verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt(), anyBoolean());
}
@Test
@@ -604,7 +607,8 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
mKeyguardUpdateMonitor.onTrustChanged(true /* enabled */,
KeyguardUpdateMonitor.getCurrentUser(), 0 /* flags */);
mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(true);
- verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt());
+ verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt(),
+ anyBoolean());
}
@Test
@@ -615,7 +619,8 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
KeyguardUpdateMonitor.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN);
mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(true);
- verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt());
+ verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt(),
+ anyBoolean());
}
@Test
@@ -626,7 +631,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
KeyguardUpdateMonitor.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT);
mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(true);
- verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt());
+ verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt(), anyBoolean());
}
@Test
@@ -638,7 +643,8 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
mKeyguardUpdateMonitor.sendKeyguardBouncerChanged(true);
mTestableLooper.processAllMessages();
- verify(mFaceManager, never()).authenticate(any(), any(), any(), any());
+ verify(mFaceManager, never()).authenticate(any(), any(), any(), any(), anyInt(),
+ anyBoolean());
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFaceToFingerprintViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFaceToFingerprintViewTest.java
index 5cd781085b15..090cf9f63eaf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFaceToFingerprintViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFaceToFingerprintViewTest.java
@@ -23,7 +23,6 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
@@ -50,7 +49,6 @@ import com.android.systemui.SysuiTestCase;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -78,14 +76,16 @@ public class AuthBiometricFaceToFingerprintViewTest extends SysuiTestCase {
@Mock private TextView mIndicatorView;
@Mock private ImageView mIconView;
@Mock private View mIconHolderView;
- @Mock private AuthBiometricFaceView.IconController mIconController;
+ @Mock private AuthBiometricFaceView.IconController mFaceIconController;
+ @Mock private AuthBiometricFaceToFingerprintView.UdfpsIconController mUdfpsIconController;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
mFaceToFpView = new TestableView(mContext);
- mFaceToFpView.mIconController = mIconController;
+ mFaceToFpView.mFaceIconController = mFaceIconController;
+ mFaceToFpView.mUdfpsIconController = mUdfpsIconController;
mFaceToFpView.setCallback(mCallback);
mFaceToFpView.mNegativeButton = mNegativeButton;
@@ -99,20 +99,23 @@ public class AuthBiometricFaceToFingerprintViewTest extends SysuiTestCase {
@Test
public void testStateUpdated_whenDialogAnimatedIn() {
mFaceToFpView.onDialogAnimatedIn();
- verify(mFaceToFpView.mIconController)
+ verify(mFaceToFpView.mFaceIconController)
.updateState(anyInt(), eq(AuthBiometricFaceToFingerprintView.STATE_AUTHENTICATING));
+ verify(mFaceToFpView.mUdfpsIconController, never()).updateState(anyInt(), anyInt());
}
@Test
public void testIconUpdatesState_whenDialogStateUpdated() {
mFaceToFpView.onDialogAnimatedIn();
- verify(mFaceToFpView.mIconController)
+ verify(mFaceToFpView.mFaceIconController)
.updateState(anyInt(), eq(AuthBiometricFaceToFingerprintView.STATE_AUTHENTICATING));
+ verify(mFaceToFpView.mUdfpsIconController, never()).updateState(anyInt(), anyInt());
mFaceToFpView.updateState(AuthBiometricFaceView.STATE_AUTHENTICATED);
- verify(mFaceToFpView.mIconController).updateState(
+ verify(mFaceToFpView.mFaceIconController).updateState(
eq(AuthBiometricFaceToFingerprintView.STATE_AUTHENTICATING),
eq(AuthBiometricFaceToFingerprintView.STATE_AUTHENTICATED));
+ verify(mFaceToFpView.mUdfpsIconController, never()).updateState(anyInt(), anyInt());
assertEquals(AuthBiometricFaceToFingerprintView.STATE_AUTHENTICATED, mFaceToFpView.mState);
}
@@ -120,21 +123,22 @@ public class AuthBiometricFaceToFingerprintViewTest extends SysuiTestCase {
@Test
public void testStateUpdated_whenSwitchToFingerprint() {
mFaceToFpView.onDialogAnimatedIn();
- verify(mFaceToFpView.mIconController)
+ verify(mFaceToFpView.mFaceIconController)
.updateState(anyInt(), eq(AuthBiometricFaceToFingerprintView.STATE_AUTHENTICATING));
mFaceToFpView.updateState(AuthBiometricFaceToFingerprintView.STATE_ERROR);
- mFaceToFpView.updateState(AuthBiometricFaceToFingerprintView.STATE_AUTHENTICATING);
- InOrder order = inOrder(mFaceToFpView.mIconController);
- order.verify(mFaceToFpView.mIconController).updateState(
+ verify(mFaceToFpView.mFaceIconController).deactivate();
+ verify(mFaceToFpView.mUdfpsIconController).updateState(
eq(AuthBiometricFaceToFingerprintView.STATE_AUTHENTICATING),
eq(AuthBiometricFaceToFingerprintView.STATE_ERROR));
- order.verify(mFaceToFpView.mIconController).updateState(
+ verify(mConfirmButton).setVisibility(eq(View.GONE));
+
+ mFaceToFpView.updateState(AuthBiometricFaceToFingerprintView.STATE_AUTHENTICATING);
+
+ verify(mFaceToFpView.mUdfpsIconController).updateState(
eq(AuthBiometricFaceToFingerprintView.STATE_ERROR),
eq(AuthBiometricFaceToFingerprintView.STATE_AUTHENTICATING));
-
- verify(mConfirmButton).setVisibility(eq(View.GONE));
}
@Test
@@ -172,7 +176,10 @@ public class AuthBiometricFaceToFingerprintViewTest extends SysuiTestCase {
eq(mContext.getString(R.string.fingerprint_dialog_use_fingerprint_instead)));
verify(mCallback).onAction(
eq(AuthBiometricView.Callback.ACTION_START_DELAYED_FINGERPRINT_SENSOR));
- assertEquals(AuthBiometricFaceToFingerprintView.STATE_AUTHENTICATING, mFaceToFpView.mState);
+
+ // First we enter the error state, since we need to show the error animation/text. The
+ // error state is later cleared based on a timer, and we enter STATE_AUTHENTICATING.
+ assertEquals(AuthBiometricFaceToFingerprintView.STATE_ERROR, mFaceToFpView.mState);
}
@Test
@@ -185,13 +192,16 @@ public class AuthBiometricFaceToFingerprintViewTest extends SysuiTestCase {
eq(mContext.getString(R.string.fingerprint_dialog_use_fingerprint_instead)));
verify(mCallback).onAction(
eq(AuthBiometricView.Callback.ACTION_START_DELAYED_FINGERPRINT_SENSOR));
- assertEquals(AuthBiometricFaceToFingerprintView.STATE_AUTHENTICATING, mFaceToFpView.mState);
+
+ // First we enter the error state, since we need to show the error animation/text. The
+ // error state is later cleared based on a timer, and we enter STATE_AUTHENTICATING.
+ assertEquals(AuthBiometricFaceToFingerprintView.STATE_ERROR, mFaceToFpView.mState);
}
@Test
public void testFingerprintOnlyStartsOnFirstError() {
mFaceToFpView.onDialogAnimatedIn();
- verify(mFaceToFpView.mIconController)
+ verify(mFaceToFpView.mFaceIconController)
.updateState(anyInt(), eq(AuthBiometricFaceToFingerprintView.STATE_AUTHENTICATING));
mFaceToFpView.onDialogAnimatedIn();
@@ -260,11 +270,6 @@ public class AuthBiometricFaceToFingerprintViewTest extends SysuiTestCase {
protected int getDelayAfterAuthenticatedDurationMs() {
return 0;
}
-
- @Override
- protected IconController createUdfpsIconController() {
- return AuthBiometricFaceToFingerprintViewTest.this.mIconController;
- }
}
private class MockInjector extends AuthBiometricView.Injector {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFaceViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFaceViewTest.java
index 043bd5cd6ba5..b93381d2b5c9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFaceViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFaceViewTest.java
@@ -62,7 +62,7 @@ public class AuthBiometricFaceViewTest extends SysuiTestCase {
public void setup() {
MockitoAnnotations.initMocks(this);
mFaceView = new TestableFaceView(mContext);
- mFaceView.mIconController = mock(TestableFaceView.TestableIconController.class);
+ mFaceView.mFaceIconController = mock(TestableFaceView.TestableIconController.class);
mFaceView.setCallback(mCallback);
mFaceView.mNegativeButton = mNegativeButton;
@@ -78,18 +78,18 @@ public class AuthBiometricFaceViewTest extends SysuiTestCase {
@Test
public void testStateUpdated_whenDialogAnimatedIn() {
mFaceView.onDialogAnimatedIn();
- verify(mFaceView.mIconController)
+ verify(mFaceView.mFaceIconController)
.updateState(anyInt(), eq(AuthBiometricFaceView.STATE_AUTHENTICATING));
}
@Test
public void testIconUpdatesState_whenDialogStateUpdated() {
mFaceView.updateState(AuthBiometricFaceView.STATE_AUTHENTICATING);
- verify(mFaceView.mIconController)
+ verify(mFaceView.mFaceIconController)
.updateState(anyInt(), eq(AuthBiometricFaceView.STATE_AUTHENTICATING));
mFaceView.updateState(AuthBiometricFaceView.STATE_AUTHENTICATED);
- verify(mFaceView.mIconController).updateState(
+ verify(mFaceView.mFaceIconController).updateState(
eq(AuthBiometricFaceView.STATE_AUTHENTICATING),
eq(AuthBiometricFaceView.STATE_AUTHENTICATED));
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
index ca114516ef8d..2120b0ee4790 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
@@ -24,6 +24,7 @@ import static org.mockito.ArgumentMatchers.anyFloat;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -62,6 +63,7 @@ import com.android.systemui.statusbar.LockscreenShadeTransitionController;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
+import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.concurrency.Execution;
import com.android.systemui.util.concurrency.FakeExecution;
@@ -143,6 +145,8 @@ public class UdfpsControllerTest extends SysuiTestCase {
private DisplayManager mDisplayManager;
@Mock
private Handler mHandler;
+ @Mock
+ private ConfigurationController mConfigurationController;
private FakeExecutor mFgExecutor;
@@ -150,6 +154,10 @@ public class UdfpsControllerTest extends SysuiTestCase {
@Mock
private UdfpsView mUdfpsView;
@Mock
+ private UdfpsEnrollView mEnrollView;
+ @Mock
+ private UdfpsKeyguardView mKeyguardView;
+ @Mock
private UdfpsKeyguardViewController mUdfpsKeyguardViewController;
@Mock
private TypedArray mBrightnessValues;
@@ -171,7 +179,13 @@ public class UdfpsControllerTest extends SysuiTestCase {
setUpResources();
mExecution = new FakeExecution();
- when(mLayoutInflater.inflate(R.layout.udfps_view, null, false)).thenReturn(mUdfpsView);
+ when(mLayoutInflater.inflate(R.layout.udfps_view, null, false))
+ .thenReturn(mUdfpsView);
+ when(mLayoutInflater.inflate(R.layout.udfps_enroll_view, null))
+ .thenReturn(mEnrollView); // for showOverlay REASON_ENROLL_ENROLLING
+ when(mLayoutInflater.inflate(R.layout.udfps_keyguard_view, null))
+ .thenReturn(mKeyguardView); // for showOverlay REASON_AUTH_FPM_KEYGUARD
+ when(mEnrollView.getContext()).thenReturn(mContext);
final List<FingerprintSensorPropertiesInternal> props = new ArrayList<>();
final List<ComponentInfoInternal> componentInfo = new ArrayList<>();
@@ -214,7 +228,8 @@ public class UdfpsControllerTest extends SysuiTestCase {
mKeyguardStateController,
mKeyguardBypassController,
mDisplayManager,
- mHandler);
+ mHandler,
+ mConfigurationController);
verify(mFingerprintManager).setUdfpsOverlayController(mOverlayCaptor.capture());
mOverlayController = mOverlayCaptor.getValue();
verify(mScreenLifecycle).addObserver(mScreenObserverCaptor.capture());
@@ -264,6 +279,75 @@ public class UdfpsControllerTest extends SysuiTestCase {
}
@Test
+ public void onActionMove_dozing_setDeviceEntryIntent() throws RemoteException {
+ // GIVEN the current animation is UdfpsKeyguardViewController and device IS dozing
+ when(mKeyguardStateController.canDismissLockScreen()).thenReturn(false);
+ when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(true);
+ when(mUdfpsView.getAnimationViewController()).thenReturn(mUdfpsKeyguardViewController);
+ when(mStatusBarStateController.isDozing()).thenReturn(true);
+
+ // GIVEN that the overlay is showing
+ mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID,
+ IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback);
+ mFgExecutor.runAllReady();
+
+ // WHEN ACTION_DOWN is received
+ verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture());
+ MotionEvent moveEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0, 0, 0);
+ mTouchListenerCaptor.getValue().onTouch(mUdfpsView, moveEvent);
+ moveEvent.recycle();
+
+ // THEN device entry intent is never to true b/c device was dozing on touch
+ verify(mKeyguardBypassController, never()).setUserHasDeviceEntryIntent(true);
+ }
+
+ @Test
+ public void onActionMove_onKeyguard_setDeviceEntryIntent() throws RemoteException {
+ // GIVEN the current animation is UdfpsKeyguardViewController and device isn't dozing
+ when(mKeyguardStateController.canDismissLockScreen()).thenReturn(false);
+ when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(true);
+ when(mUdfpsView.getAnimationViewController()).thenReturn(mUdfpsKeyguardViewController);
+ when(mStatusBarStateController.isDozing()).thenReturn(false);
+
+ // GIVEN that the overlay is showing
+ mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID,
+ IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback);
+ mFgExecutor.runAllReady();
+
+ // WHEN ACTION_DOWN is received
+ verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture());
+ MotionEvent moveEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0, 0, 0);
+ mTouchListenerCaptor.getValue().onTouch(mUdfpsView, moveEvent);
+ moveEvent.recycle();
+
+ // THEN device entry intent is set to true
+ verify(mKeyguardBypassController).setUserHasDeviceEntryIntent(true);
+ }
+
+ @Test
+ public void onActionMove_onEnrollment_neverSetDeviceEntryIntent() throws RemoteException {
+ // GIVEN the current animation is UdfpsEnrollViewController
+ when(mKeyguardStateController.canDismissLockScreen()).thenReturn(false);
+ when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(true);
+ when(mUdfpsView.getAnimationViewController()).thenReturn(
+ mock(UdfpsEnrollViewController.class));
+
+ // GIVEN that the overlay is showing
+ mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID,
+ IUdfpsOverlayController.REASON_ENROLL_ENROLLING, mUdfpsOverlayControllerCallback);
+ mFgExecutor.runAllReady();
+
+ // WHEN ACTION_DOWN is received
+ verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture());
+ MotionEvent moveEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0, 0, 0);
+ mTouchListenerCaptor.getValue().onTouch(mUdfpsView, moveEvent);
+ moveEvent.recycle();
+
+ // THEN device entry intent is never set
+ verify(mKeyguardBypassController, never()).setUserHasDeviceEntryIntent(anyBoolean());
+ }
+
+ @Test
public void onActionMoveTouch_whenCanDismissLockScreen_entersDevice() throws RemoteException {
// GIVEN can dismiss lock screen and the current animation is an UdfpsKeyguardViewController
when(mKeyguardStateController.canDismissLockScreen()).thenReturn(true);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java
index f62587c6e87c..0c03a51f816e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java
@@ -39,6 +39,7 @@ import com.android.systemui.statusbar.LockscreenShadeTransitionController;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
+import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.util.concurrency.DelayableExecutor;
import org.junit.Before;
@@ -76,6 +77,8 @@ public class UdfpsKeyguardViewControllerTest extends SysuiTestCase {
@Mock
private KeyguardViewMediator mKeyguardViewMediator;
@Mock
+ private ConfigurationController mConfigurationController;
+ @Mock
private UdfpsController mUdfpsController;
private UdfpsKeyguardViewController mController;
@@ -110,6 +113,7 @@ public class UdfpsKeyguardViewControllerTest extends SysuiTestCase {
mDumpManager,
mKeyguardViewMediator,
mLockscreenShadeTransitionController,
+ mConfigurationController,
mUdfpsController);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
index 1dacc6245d84..ad0878031679 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
@@ -23,6 +23,7 @@ import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
@@ -33,8 +34,9 @@ import android.app.admin.DevicePolicyManager;
import android.app.trust.TrustManager;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
+import android.telephony.TelephonyManager;
import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper.RunWithLooper;
+import android.testing.TestableLooper;
import androidx.test.filters.SmallTest;
@@ -65,7 +67,7 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@RunWith(AndroidTestingRunner.class)
-@RunWithLooper
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
@SmallTest
public class KeyguardViewMediatorTest extends SysuiTestCase {
private KeyguardViewMediator mViewMediator;
@@ -124,6 +126,7 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
mUnlockedScreenOffAnimationController,
() -> mNotificationShadeDepthController);
mViewMediator.start();
+ mViewMediator.onSystemReady();
}
@Test
@@ -160,4 +163,27 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
mViewMediator.onDozeAmountChanged(1f, 1f);
assertFalse(mViewMediator.isAnimatingScreenOff());
}
+
+ @Test
+ public void restoreBouncerWhenSimLockedAndKeyguardIsGoingAway() {
+ // When showing and provisioned
+ when(mUpdateMonitor.isDeviceProvisioned()).thenReturn(true);
+ mViewMediator.setShowingLocked(true);
+
+ // and a SIM becomes locked and requires a PIN
+ mViewMediator.mUpdateCallback.onSimStateChanged(
+ 1 /* subId */,
+ 0 /* slotId */,
+ TelephonyManager.SIM_STATE_PIN_REQUIRED);
+
+ // and the keyguard goes away
+ mViewMediator.setShowingLocked(false);
+ when(mStatusBarKeyguardViewManager.isShowing()).thenReturn(false);
+ mViewMediator.mUpdateCallback.onKeyguardVisibilityChanged(false);
+
+ TestableLooper.get(this).processAllMessages();
+
+ // then make sure it comes back
+ verify(mStatusBarKeyguardViewManager, atLeast(1)).show(null);
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
index c40977b31e73..3ee3e55c749a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
@@ -55,6 +55,7 @@ import com.android.systemui.shared.plugins.PluginManager;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.statusbar.phone.AutoTileManager;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.StatusBarIconController;
import com.android.systemui.statusbar.policy.Clock;
@@ -92,6 +93,8 @@ public class QSFragmentTest extends SysuiBaseFragmentTest {
@Mock
private MediaHost mQQSMediaHost;
@Mock
+ private KeyguardBypassController mBypassController;
+ @Mock
private FeatureFlags mFeatureFlags;
@Mock
private FalsingManager mFalsingManager;
@@ -184,8 +187,10 @@ public class QSFragmentTest extends SysuiBaseFragmentTest {
new QSDetailDisplayer(),
mQSMediaHost,
mQQSMediaHost,
+ mBypassController,
mQsComponentFactory,
mFeatureFlags,
- mFalsingManager);
+ mFalsingManager,
+ mock(DumpManager.class));
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelSwitchToParentTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelSwitchToParentTest.kt
new file mode 100644
index 000000000000..56f2905e834f
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelSwitchToParentTest.kt
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2021 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.qs
+
+import com.google.common.truth.Truth.assertThat
+
+import androidx.test.filters.SmallTest
+
+import android.testing.AndroidTestingRunner
+import android.view.View
+import android.view.ViewGroup
+import android.widget.FrameLayout
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.util.children
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class QSPanelSwitchToParentTest : SysuiTestCase() {
+
+ private lateinit var parent1: FrameLayout
+ private lateinit var parent2: FrameLayout
+
+ private lateinit var movingView: View
+
+ private lateinit var view1A: View
+ private lateinit var view1B: View
+ private lateinit var view1C: View
+
+ private lateinit var view2A: View
+ private lateinit var view2B: View
+ private lateinit var view2C: View
+
+ @Before
+ fun setUp() {
+ parent1 = FrameLayout(mContext)
+ parent2 = FrameLayout(mContext)
+
+ movingView = View(mContext)
+
+ view1A = View(mContext)
+ parent1.addView(view1A)
+ view1B = View(mContext)
+ parent1.addView(view1B)
+ view1C = View(mContext)
+ parent1.addView(view1C)
+
+ view2A = View(mContext)
+ parent2.addView(view2A)
+ view2B = View(mContext)
+ parent2.addView(view2B)
+ view2C = View(mContext)
+ parent2.addView(view2C)
+ }
+
+ @Test
+ fun testNullTargetNoInteractions() {
+ QSPanel.switchToParent(movingView, null, -1, "")
+
+ assertThat(movingView.parent).isNull()
+ }
+
+ @Test
+ fun testMoveToEndNoParent() {
+ QSPanel.switchToParent(movingView, parent2, -1, "")
+
+ assertThat(parent1.childrenList).containsExactly(
+ view1A, view1B, view1C
+ )
+
+ assertThat(parent2.childrenList).containsExactly(
+ view2A, view2B, view2C, movingView
+ )
+ }
+
+ @Test
+ fun testMoveToEndDifferentParent() {
+ parent1.addView(movingView, 0)
+
+ QSPanel.switchToParent(movingView, parent2, -1, "")
+
+ assertThat(parent1.childrenList).containsExactly(
+ view1A, view1B, view1C
+ )
+ assertThat(parent2.childrenList).containsExactly(
+ view2A, view2B, view2C, movingView
+ )
+ }
+
+ @Test
+ fun testMoveToEndSameParent() {
+ parent2.addView(movingView, 0)
+
+ QSPanel.switchToParent(movingView, parent2, -1, "")
+
+ assertThat(parent1.childrenList).containsExactly(
+ view1A, view1B, view1C
+ )
+ assertThat(parent2.childrenList).containsExactly(
+ view2A, view2B, view2C, movingView
+ )
+ }
+
+ @Test
+ fun testMoveToMiddleFromNoParent() {
+ QSPanel.switchToParent(movingView, parent2, 1, "")
+
+ assertThat(parent1.childrenList).containsExactly(
+ view1A, view1B, view1C
+ )
+ assertThat(parent2.childrenList).containsExactly(
+ view2A, movingView, view2B, view2C
+ )
+ }
+
+ @Test
+ fun testMoveToMiddleDifferentParent() {
+ parent1.addView(movingView, 1)
+
+ QSPanel.switchToParent(movingView, parent2, 2, "")
+
+ assertThat(parent1.childrenList).containsExactly(
+ view1A, view1B, view1C
+ )
+ assertThat(parent2.childrenList).containsExactly(
+ view2A, view2B, movingView, view2C
+ )
+ }
+
+ @Test
+ fun testMoveToMiddleSameParent() {
+ parent2.addView(movingView, 0)
+
+ QSPanel.switchToParent(movingView, parent2, 1, "")
+
+ assertThat(parent1.childrenList).containsExactly(
+ view1A, view1B, view1C
+ )
+ assertThat(parent2.childrenList).containsExactly(
+ view2A, movingView, view2B, view2C
+ )
+ }
+
+ private val ViewGroup.childrenList: List<View>
+ get() = children.toList()
+} \ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java
index 4f8859927d06..16d4dddd67aa 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java
@@ -14,6 +14,8 @@
package com.android.systemui.qs;
+import static junit.framework.Assert.assertEquals;
+
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
@@ -21,19 +23,20 @@ import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.content.res.Configuration;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
+import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
-import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.qs.QSTileView;
-import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.qs.tileimpl.QSTileImpl;
+import com.android.systemui.util.animation.UniqueObjectHostView;
import org.junit.Before;
import org.junit.Test;
@@ -56,29 +59,28 @@ public class QSPanelTest extends SysuiTestCase {
private QSTileImpl dndTile;
@Mock
private QSPanelControllerBase.TileRecord mDndTileRecord;
- @Mock
- private QSLogger mQSLogger;
private ViewGroup mParentView;
@Mock
private QSDetail.Callback mCallback;
@Mock
private QSTileView mQSTileView;
+
+ private UniqueObjectHostView mMediaView;
+ private View mSecurityFooter;
@Mock
- private ActivityStarter mActivityStarter;
+ private FrameLayout mHeaderContainer;
@Before
public void setup() throws Exception {
MockitoAnnotations.initMocks(this);
mTestableLooper = TestableLooper.get(this);
-// // Dependencies for QSSecurityFooter
-// mDependency.injectTestDependency(ActivityStarter.class, mActivityStarter);
-// mDependency.injectMockDependency(SecurityController.class);
-// mDependency.injectTestDependency(Dependency.BG_LOOPER, mTestableLooper.getLooper());
-// mContext.addMockSystemService(Context.USER_SERVICE, mock(UserManager.class));
mDndTileRecord.tile = dndTile;
mDndTileRecord.tileView = mQSTileView;
+ mMediaView = new UniqueObjectHostView(mContext);
+ mSecurityFooter = new View(mContext);
+
mTestableLooper.runWithLooper(() -> {
mQsPanel = new QSPanel(mContext, null);
mQsPanel.initialize();
@@ -92,6 +94,7 @@ public class QSPanelTest extends SysuiTestCase {
when(mHost.createTileView(any(), any(), anyBoolean())).thenReturn(mQSTileView);
mQsPanel.addTile(mDndTileRecord);
mQsPanel.setCallback(mCallback);
+ mQsPanel.setHeaderContainer(mHeaderContainer);
});
}
@@ -112,4 +115,62 @@ public class QSPanelTest extends SysuiTestCase {
verify(mCallback, never()).onShowingDetail(any(), anyInt(), anyInt());
}
+
+ @Test
+ public void testSecurityFooterAtEndNoMedia_portrait() {
+ mTestableLooper.processAllMessages();
+
+ mContext.getResources().getConfiguration().orientation = Configuration.ORIENTATION_PORTRAIT;
+
+ mQsPanel.setSecurityFooter(mSecurityFooter);
+
+ int children = mQsPanel.getChildCount();
+ assertEquals(children - 1, mQsPanel.indexOfChild(mSecurityFooter));
+ }
+
+ @Test
+ public void testSecurityFooterRightBeforeMedia_portrait() {
+ mTestableLooper.processAllMessages();
+
+ mContext.getResources().getConfiguration().orientation = Configuration.ORIENTATION_PORTRAIT;
+
+ mQsPanel.addView(mMediaView);
+
+ mQsPanel.setSecurityFooter(mSecurityFooter);
+
+ int securityFooterIndex = mQsPanel.indexOfChild(mSecurityFooter);
+ int mediaIndex = mQsPanel.indexOfChild(mMediaView);
+
+ assertEquals(mediaIndex - 1, securityFooterIndex);
+ }
+
+ @Test
+ public void testSecurityFooterRightBeforeMedia_portrait_configChange() {
+ mTestableLooper.processAllMessages();
+
+ mContext.getResources().getConfiguration().orientation = Configuration.ORIENTATION_PORTRAIT;
+
+ mQsPanel.addView(mMediaView);
+
+ mQsPanel.setSecurityFooter(mSecurityFooter);
+
+ mQsPanel.onConfigurationChanged(mContext.getResources().getConfiguration());
+
+ int securityFooterIndex = mQsPanel.indexOfChild(mSecurityFooter);
+ int mediaIndex = mQsPanel.indexOfChild(mMediaView);
+
+ assertEquals(mediaIndex - 1, securityFooterIndex);
+ }
+
+ @Test
+ public void testSecurityFooterInHeader_landscape() {
+ mTestableLooper.processAllMessages();
+
+ mContext.getResources().getConfiguration().orientation =
+ Configuration.ORIENTATION_LANDSCAPE;
+
+ mQsPanel.setSecurityFooter(mSecurityFooter);
+
+ verify(mHeaderContainer).addView(mSecurityFooter, 0);
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScrollCaptureClientTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScrollCaptureClientTest.java
index 3a4bc699b967..670a130d610a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScrollCaptureClientTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScrollCaptureClientTest.java
@@ -26,7 +26,6 @@ import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
-import android.content.Context;
import android.graphics.Rect;
import android.os.RemoteException;
import android.testing.AndroidTestingRunner;
@@ -36,7 +35,6 @@ import android.view.IWindowManager;
import android.view.ScrollCaptureResponse;
import androidx.test.filters.SmallTest;
-import androidx.test.platform.app.InstrumentationRegistry;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.screenshot.ScrollCaptureClient.CaptureResult;
@@ -83,7 +81,7 @@ public class ScrollCaptureClientTest extends SysuiTestCase {
/* taskId */ anyInt(), any(IScrollCaptureResponseListener.class));
// Create client
- ScrollCaptureClient client = new ScrollCaptureClient(mContext, mWm);
+ ScrollCaptureClient client = new ScrollCaptureClient(mWm, Runnable::run, mContext);
// Request scroll capture
ListenableFuture<ScrollCaptureResponse> requestFuture =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
index 298bd9a3082d..f5ce673c249e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
@@ -81,6 +81,7 @@ import com.android.systemui.keyguard.KeyguardIndication;
import com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.KeyguardIndicationTextView;
import com.android.systemui.statusbar.phone.LockIcon;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
@@ -146,6 +147,8 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
private LockPatternUtils mLockPatternUtils;
@Mock
private IActivityManager mIActivityManager;
+ @Mock
+ private KeyguardBypassController mKeyguardBypassController;
@Captor
private ArgumentCaptor<DockManager.AlignmentStateListener> mAlignmentListener;
@Captor
@@ -216,7 +219,8 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
mController = new KeyguardIndicationController(mContext, mWakeLockBuilder,
mKeyguardStateController, mStatusBarStateController, mKeyguardUpdateMonitor,
mDockManager, mBroadcastDispatcher, mDevicePolicyManager, mIBatteryStats,
- mUserManager, mExecutor, mFalsingManager, mLockPatternUtils, mIActivityManager);
+ mUserManager, mExecutor, mFalsingManager, mLockPatternUtils, mIActivityManager,
+ mKeyguardBypassController);
mController.init();
mController.setIndicationArea(mIndicationArea);
verify(mStatusBarStateController).addCallback(mStatusBarStateListenerCaptor.capture());
@@ -507,6 +511,7 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
createController();
String message = mContext.getString(R.string.keyguard_retry);
when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(true);
+ when(mKeyguardUpdateMonitor.isFaceEnrolled()).thenReturn(true);
mController.setVisible(true);
mController.getKeyguardCallback().onBiometricError(FaceManager.FACE_ERROR_TIMEOUT,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
index 4da7ddce8083..525bb1c641fd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
@@ -86,6 +86,7 @@ import com.android.systemui.SysuiTestCase;
import com.android.systemui.biometrics.AuthController;
import com.android.systemui.classifier.FalsingCollectorFake;
import com.android.systemui.classifier.FalsingManagerFake;
+import com.android.systemui.controls.dagger.ControlsComponent;
import com.android.systemui.doze.DozeLog;
import com.android.systemui.fragments.FragmentHostManager;
import com.android.systemui.fragments.FragmentService;
@@ -301,6 +302,8 @@ public class NotificationPanelViewTest extends SysuiTestCase {
private RemoteInputController mRemoteInputController;
@Mock
private RecordingController mRecordingController;
+ @Mock
+ private ControlsComponent mControlsComponent;
private SysuiStatusBarStateController mStatusBarStateController;
private NotificationPanelViewController mNotificationPanelViewController;
@@ -372,16 +375,17 @@ public class NotificationPanelViewTest extends SysuiTestCase {
mKeyguardBypassController,
mDozeParameters,
mUnlockedScreenOffAnimationController);
+ mConfigurationController = new ConfigurationControllerImpl(mContext);
PulseExpansionHandler expansionHandler = new PulseExpansionHandler(
mContext,
coordinator,
mKeyguardBypassController, mHeadsUpManager,
mock(NotificationRoundnessManager.class),
+ mConfigurationController,
mStatusBarStateController,
mFalsingManager,
mLockscreenShadeTransitionController,
new FalsingCollectorFake());
- mConfigurationController = new ConfigurationControllerImpl(mContext);
when(mKeyguardStatusViewComponentFactory.build(any()))
.thenReturn(mKeyguardStatusViewComponent);
when(mKeyguardStatusViewComponent.getKeyguardClockSwitchController())
@@ -443,8 +447,9 @@ public class NotificationPanelViewTest extends SysuiTestCase {
new FakeExecutor(new FakeSystemClock()),
mSecureSettings,
mUnlockedScreenOffAnimationController,
- mEmergencyButtonControllerFactory,
- mNotificationRemoteInputManager);
+ mNotificationRemoteInputManager,
+ mControlsComponent,
+ mEmergencyButtonControllerFactory);
mNotificationPanelViewController.initDependencies(
mStatusBar,
mNotificationShelfController);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerTest.kt
new file mode 100644
index 000000000000..ace2c71d9c63
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerTest.kt
@@ -0,0 +1,257 @@
+/*
+ * Copyright (C) 2021 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 android.app.IActivityTaskManager
+import android.content.Context
+import android.content.DialogInterface
+import android.content.Intent
+import android.content.pm.UserInfo
+import android.graphics.Bitmap
+import android.hardware.face.FaceManager
+import android.hardware.fingerprint.FingerprintManager
+import android.os.Handler
+import android.os.UserHandle
+import android.os.UserManager
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import androidx.test.filters.SmallTest
+import com.android.internal.logging.testing.UiEventLoggerFake
+import com.android.internal.util.UserIcons
+import com.android.systemui.GuestResumeSessionReceiver
+import com.android.systemui.R
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.broadcast.BroadcastDispatcher
+import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.plugins.FalsingManager
+import com.android.systemui.qs.QSUserSwitcherEvent
+import com.android.systemui.settings.UserTracker
+import com.android.systemui.telephony.TelephonyListenerManager
+import com.android.systemui.util.concurrency.FakeExecutor
+import com.android.systemui.util.settings.SecureSettings
+import com.android.systemui.util.time.FakeSystemClock
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertNotNull
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.ArgumentMatchers.eq
+import org.mockito.Mock
+import org.mockito.Mockito.any
+import org.mockito.Mockito.anyString
+import org.mockito.Mockito.mock
+import org.mockito.Mockito.`when`
+import org.mockito.MockitoAnnotations
+
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+@SmallTest
+class UserSwitcherControllerTest : SysuiTestCase() {
+ @Mock private lateinit var keyguardStateController: KeyguardStateController
+ @Mock private lateinit var handler: Handler
+ @Mock private lateinit var userTracker: UserTracker
+ @Mock private lateinit var userManager: UserManager
+ @Mock private lateinit var activityStarter: ActivityStarter
+ @Mock private lateinit var broadcastDispatcher: BroadcastDispatcher
+ @Mock private lateinit var activityTaskManager: IActivityTaskManager
+ @Mock private lateinit var userDetailAdapter: UserSwitcherController.UserDetailAdapter
+ @Mock private lateinit var telephonyListenerManager: TelephonyListenerManager
+ @Mock private lateinit var secureSettings: SecureSettings
+ @Mock private lateinit var falsingManager: FalsingManager
+ private lateinit var testableLooper: TestableLooper
+ private lateinit var uiBgExecutor: FakeExecutor
+ private lateinit var uiEventLogger: UiEventLoggerFake
+ private lateinit var userSwitcherController: UserSwitcherController
+ private lateinit var picture: Bitmap
+ private val ownerId = UserHandle.USER_SYSTEM
+ private val ownerInfo = UserInfo(ownerId, "Owner", null,
+ UserInfo.FLAG_ADMIN or UserInfo.FLAG_FULL or UserInfo.FLAG_INITIALIZED or
+ UserInfo.FLAG_PRIMARY or UserInfo.FLAG_SYSTEM,
+ UserManager.USER_TYPE_FULL_SYSTEM)
+ private val guestId = 1234
+ private val guestInfo = UserInfo(guestId, "Guest", null,
+ UserInfo.FLAG_FULL or UserInfo.FLAG_GUEST, UserManager.USER_TYPE_FULL_GUEST)
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+ testableLooper = TestableLooper.get(this)
+ uiBgExecutor = FakeExecutor(FakeSystemClock())
+ uiEventLogger = UiEventLoggerFake()
+
+ context.orCreateTestableResources.addOverride(
+ com.android.internal.R.bool.config_guestUserAutoCreated, false)
+
+ context.addMockSystemService(Context.FACE_SERVICE, mock(FaceManager::class.java))
+ context.addMockSystemService(Context.FINGERPRINT_SERVICE,
+ mock(FingerprintManager::class.java))
+
+ `when`(userManager.canAddMoreUsers()).thenReturn(true)
+
+ userSwitcherController = UserSwitcherController(context,
+ userManager,
+ userTracker,
+ keyguardStateController,
+ handler,
+ activityStarter,
+ broadcastDispatcher,
+ uiEventLogger,
+ falsingManager,
+ telephonyListenerManager,
+ activityTaskManager,
+ userDetailAdapter,
+ secureSettings,
+ uiBgExecutor)
+ userSwitcherController.mPauseRefreshUsers = true
+
+ picture = UserIcons.convertToBitmap(context.getDrawable(R.drawable.ic_avatar_user))
+ }
+
+ @Test
+ fun testAddGuest_okButtonPressed_isLogged() {
+ val emptyGuestUserRecord = UserSwitcherController.UserRecord(
+ null,
+ null,
+ true /* guest */,
+ false /* current */,
+ false /* isAddUser */,
+ false /* isRestricted */,
+ true /* isSwitchToEnabled */)
+ `when`(userTracker.userId).thenReturn(ownerId)
+ `when`(userTracker.userInfo).thenReturn(ownerInfo)
+
+ `when`(userManager.createGuest(any(), anyString())).thenReturn(guestInfo)
+
+ userSwitcherController.onUserListItemClicked(emptyGuestUserRecord)
+ testableLooper.processAllMessages()
+ assertEquals(1, uiEventLogger.numLogs())
+ assertEquals(QSUserSwitcherEvent.QS_USER_GUEST_ADD.id, uiEventLogger.eventId(0))
+ }
+
+ @Test
+ fun testRemoveGuest_removeButtonPressed_isLogged() {
+ val currentGuestUserRecord = UserSwitcherController.UserRecord(
+ guestInfo,
+ picture,
+ true /* guest */,
+ true /* current */,
+ false /* isAddUser */,
+ false /* isRestricted */,
+ true /* isSwitchToEnabled */)
+ `when`(userTracker.userId).thenReturn(guestInfo.id)
+ `when`(userTracker.userInfo).thenReturn(guestInfo)
+
+ userSwitcherController.onUserListItemClicked(currentGuestUserRecord)
+ assertNotNull(userSwitcherController.mExitGuestDialog)
+ userSwitcherController.mExitGuestDialog
+ .getButton(DialogInterface.BUTTON_POSITIVE).performClick()
+ testableLooper.processAllMessages()
+ assertEquals(1, uiEventLogger.numLogs())
+ assertEquals(QSUserSwitcherEvent.QS_USER_GUEST_REMOVE.id, uiEventLogger.eventId(0))
+ }
+
+ @Test
+ fun testRemoveGuest_cancelButtonPressed_isNotLogged() {
+ val currentGuestUserRecord = UserSwitcherController.UserRecord(
+ guestInfo,
+ picture,
+ true /* guest */,
+ true /* current */,
+ false /* isAddUser */,
+ false /* isRestricted */,
+ true /* isSwitchToEnabled */)
+ `when`(userTracker.userId).thenReturn(guestId)
+ `when`(userTracker.userInfo).thenReturn(guestInfo)
+
+ userSwitcherController.onUserListItemClicked(currentGuestUserRecord)
+ assertNotNull(userSwitcherController.mExitGuestDialog)
+ userSwitcherController.mExitGuestDialog
+ .getButton(DialogInterface.BUTTON_NEGATIVE).performClick()
+ testableLooper.processAllMessages()
+ assertEquals(0, uiEventLogger.numLogs())
+ }
+
+ @Test
+ fun testWipeGuest_startOverButtonPressed_isLogged() {
+ val currentGuestUserRecord = UserSwitcherController.UserRecord(
+ guestInfo,
+ picture,
+ true /* guest */,
+ false /* current */,
+ false /* isAddUser */,
+ false /* isRestricted */,
+ true /* isSwitchToEnabled */)
+ `when`(userTracker.userId).thenReturn(guestId)
+ `when`(userTracker.userInfo).thenReturn(guestInfo)
+
+ // Simulate that guest user has already logged in
+ `when`(secureSettings.getIntForUser(
+ eq(GuestResumeSessionReceiver.SETTING_GUEST_HAS_LOGGED_IN), anyInt(), anyInt()))
+ .thenReturn(1)
+
+ userSwitcherController.onUserListItemClicked(currentGuestUserRecord)
+
+ // Simulate a user switch event
+ val intent = Intent(Intent.ACTION_USER_SWITCHED).putExtra(Intent.EXTRA_USER_HANDLE, guestId)
+
+ assertNotNull(userSwitcherController.mGuestResumeSessionReceiver)
+ userSwitcherController.mGuestResumeSessionReceiver.onReceive(context, intent)
+
+ assertNotNull(userSwitcherController.mGuestResumeSessionReceiver.mNewSessionDialog)
+ userSwitcherController.mGuestResumeSessionReceiver.mNewSessionDialog
+ .getButton(GuestResumeSessionReceiver.ResetSessionDialog.BUTTON_WIPE).performClick()
+ testableLooper.processAllMessages()
+ assertEquals(1, uiEventLogger.numLogs())
+ assertEquals(QSUserSwitcherEvent.QS_USER_GUEST_WIPE.id, uiEventLogger.eventId(0))
+ }
+
+ @Test
+ fun testWipeGuest_continueButtonPressed_isLogged() {
+ val currentGuestUserRecord = UserSwitcherController.UserRecord(
+ guestInfo,
+ picture,
+ true /* guest */,
+ false /* current */,
+ false /* isAddUser */,
+ false /* isRestricted */,
+ true /* isSwitchToEnabled */)
+ `when`(userTracker.userId).thenReturn(guestId)
+ `when`(userTracker.userInfo).thenReturn(guestInfo)
+
+ // Simulate that guest user has already logged in
+ `when`(secureSettings.getIntForUser(
+ eq(GuestResumeSessionReceiver.SETTING_GUEST_HAS_LOGGED_IN), anyInt(), anyInt()))
+ .thenReturn(1)
+
+ userSwitcherController.onUserListItemClicked(currentGuestUserRecord)
+
+ // Simulate a user switch event
+ val intent = Intent(Intent.ACTION_USER_SWITCHED).putExtra(Intent.EXTRA_USER_HANDLE, guestId)
+
+ assertNotNull(userSwitcherController.mGuestResumeSessionReceiver)
+ userSwitcherController.mGuestResumeSessionReceiver.onReceive(context, intent)
+
+ assertNotNull(userSwitcherController.mGuestResumeSessionReceiver.mNewSessionDialog)
+ userSwitcherController.mGuestResumeSessionReceiver.mNewSessionDialog
+ .getButton(GuestResumeSessionReceiver.ResetSessionDialog.BUTTON_DONTWIPE)
+ .performClick()
+ testableLooper.processAllMessages()
+ assertEquals(1, uiEventLogger.numLogs())
+ assertEquals(QSUserSwitcherEvent.QS_USER_GUEST_CONTINUE.id, uiEventLogger.eventId(0))
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/sensors/ProximitySensorDualTest.java b/packages/SystemUI/tests/src/com/android/systemui/util/sensors/ProximitySensorDualTest.java
index 8f0754592b83..cc2afe2f7b8a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/util/sensors/ProximitySensorDualTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/sensors/ProximitySensorDualTest.java
@@ -60,6 +60,25 @@ public class ProximitySensorDualTest extends SysuiTestCase {
}
@Test
+ public void testPrimaryBelowDoesNotInvokeSecondary() {
+ TestableListener listener = new TestableListener();
+
+ mProximitySensor.register(listener);
+ assertTrue(mProximitySensor.isRegistered());
+ assertFalse(mThresholdSensorPrimary.isPaused());
+ assertTrue(mThresholdSensorSecondary.isPaused());
+ assertNull(listener.mLastEvent);
+ assertEquals(0, listener.mCallCount);
+
+ // Trigger primary sensor. Our secondary sensor is not registered.
+ mThresholdSensorPrimary.triggerEvent(false, 0);
+ assertFalse(mThresholdSensorPrimary.isPaused());
+ assertTrue(mThresholdSensorSecondary.isPaused());
+ assertNull(listener.mLastEvent);
+ assertEquals(0, listener.mCallCount);
+ }
+
+ @Test
public void testSingleListener() {
TestableListener listener = new TestableListener();
@@ -256,40 +275,6 @@ public class ProximitySensorDualTest extends SysuiTestCase {
}
@Test
- public void testPrimaryCancelsSecondary() {
- TestableListener listener = new TestableListener();
-
- mProximitySensor.register(listener);
- assertFalse(mThresholdSensorPrimary.isPaused());
- assertTrue(mThresholdSensorSecondary.isPaused());
- assertNull(listener.mLastEvent);
- assertEquals(0, listener.mCallCount);
-
- mThresholdSensorPrimary.triggerEvent(true, 0);
- assertNull(listener.mLastEvent);
- assertEquals(0, listener.mCallCount);
- mThresholdSensorSecondary.triggerEvent(true, 0);
- assertTrue(listener.mLastEvent.getBelow());
- assertEquals(1, listener.mCallCount);
-
- // When the primary reports false, the secondary is no longer needed. We get an immediate
- // report.
- mThresholdSensorPrimary.triggerEvent(false, 1);
- assertFalse(listener.mLastEvent.getBelow());
- assertEquals(2, listener.mCallCount);
-
- // The secondary is now ignored. No more work is scheduled.
- mFakeExecutor.advanceClockToNext();
- mFakeExecutor.runNextReady();
- mThresholdSensorSecondary.triggerEvent(true, 0);
- assertFalse(listener.mLastEvent.getBelow());
- assertEquals(2, listener.mCallCount);
- assertEquals(0, mFakeExecutor.numPending());
-
- mProximitySensor.unregister(listener);
- }
-
- @Test
public void testSecondaryCancelsSecondary() {
TestableListener listener = new TestableListener();
ThresholdSensor.Listener cancelingListener = new ThresholdSensor.Listener() {
@@ -342,7 +327,7 @@ public class ProximitySensorDualTest extends SysuiTestCase {
// The secondary sensor should now remain resumed indefinitely.
assertFalse(mThresholdSensorSecondary.isPaused());
- mThresholdSensorPrimary.triggerEvent(false, 1);
+ mThresholdSensorSecondary.triggerEvent(false, 1);
assertFalse(listener.mLastEvent.getBelow());
assertEquals(2, listener.mCallCount);
diff --git a/packages/VpnDialogs/res/values-gu/strings.xml b/packages/VpnDialogs/res/values-gu/strings.xml
index b5a88310fb43..5ffdcb1d8079 100644
--- a/packages/VpnDialogs/res/values-gu/strings.xml
+++ b/packages/VpnDialogs/res/values-gu/strings.xml
@@ -29,7 +29,7 @@
<string name="always_on_disconnected_message" msgid="555634519845992917">"<xliff:g id="VPN_APP_0">%1$s</xliff:g>ને હંમેશાં જોડાયેલ રહેવા માટે સેટ કરેલ છે, પરંતુ તે હાલમાં કનેક્ટ કરી શકાતું નથી. તમારો ફોન જ્યાં સુધી <xliff:g id="VPN_APP_1">%1$s</xliff:g> સાથે ફરીથી કનેક્ટ ન થાય ત્યાં સુધી તે સાર્વજનિક નેટવર્કનો ઉપયોગ કરશે."</string>
<string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"<xliff:g id="VPN_APP">%1$s</xliff:g>ને હંમેશાં જોડાયેલ રહેવા માટે સેટ કરેલ છે, પરંતુ તે હાલમાં કનેક્ટ કરી શકાતું નથી. VPN ફરીથી કનેક્ટ ન થઈ શકે ત્યાં સુધી તમારી પાસે કોઈ કનેક્શન હશે નહીં."</string>
<string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
- <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"VPN સેટિંગ્સ બદલો"</string>
+ <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"VPN સેટિંગ બદલો"</string>
<string name="configure" msgid="4905518375574791375">"ગોઠવો"</string>
<string name="disconnect" msgid="971412338304200056">"ડિસ્કનેક્ટ કરો"</string>
<string name="open_app" msgid="3717639178595958667">"ઍપ ખોલો"</string>
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index 5aec6aa99c12..a56b1db1494c 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -3285,6 +3285,57 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
}
}
+ private void applyResourceOverlaysToWidgetsLocked(Set<String> packageNames, int userId,
+ boolean updateFrameworkRes) {
+ for (int i = 0, N = mProviders.size(); i < N; i++) {
+ Provider provider = mProviders.get(i);
+ if (provider.getUserId() != userId) {
+ continue;
+ }
+
+ final String packageName = provider.id.componentName.getPackageName();
+ if (!updateFrameworkRes && !packageNames.contains(packageName)) {
+ continue;
+ }
+
+ ApplicationInfo newAppInfo = null;
+ try {
+ newAppInfo = mPackageManager.getApplicationInfo(packageName,
+ PackageManager.GET_SHARED_LIBRARY_FILES, userId);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Failed to retrieve app info for " + packageName
+ + " userId=" + userId, e);
+ }
+ if (newAppInfo == null) {
+ continue;
+ }
+ ApplicationInfo oldAppInfo = provider.info.providerInfo.applicationInfo;
+ if (!newAppInfo.sourceDir.equals(oldAppInfo.sourceDir)) {
+ // Overlay paths are generated against a particular version of an application.
+ // The overlays paths of a newly upgraded application are incompatible with the
+ // old version of the application.
+ continue;
+ }
+
+ // Isolate the changes relating to RROs. The app info must be copied to prevent
+ // affecting other parts of system server that may have cached this app info.
+ oldAppInfo = new ApplicationInfo(oldAppInfo);
+ oldAppInfo.overlayPaths = newAppInfo.overlayPaths.clone();
+ oldAppInfo.resourceDirs = newAppInfo.resourceDirs.clone();
+ provider.info.providerInfo.applicationInfo = oldAppInfo;
+
+ for (int j = 0, M = provider.widgets.size(); j < M; j++) {
+ Widget widget = provider.widgets.get(j);
+ if (widget.views != null) {
+ widget.views.updateAppInfo(oldAppInfo);
+ }
+ if (widget.maskedViews != null) {
+ widget.maskedViews.updateAppInfo(oldAppInfo);
+ }
+ }
+ }
+ }
+
/**
* Updates all providers with the specified package names, and records any providers that were
* pruned.
@@ -4875,5 +4926,14 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
public void unlockUser(int userId) {
handleUserUnlocked(userId);
}
+
+ @Override
+ public void applyResourceOverlaysToWidgets(Set<String> packageNames, int userId,
+ boolean updateFrameworkRes) {
+ synchronized (mLock) {
+ applyResourceOverlaysToWidgetsLocked(new HashSet<>(packageNames), userId,
+ updateFrameworkRes);
+ }
+ }
}
}
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 078d908684bc..df269d71f915 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -96,6 +96,7 @@ import android.util.Slog;
import android.util.SparseArray;
import android.util.TimeUtils;
import android.view.KeyEvent;
+import android.view.accessibility.AccessibilityManager;
import android.view.autofill.AutofillId;
import android.view.autofill.AutofillManager;
import android.view.autofill.AutofillManager.SmartSuggestionMode;
@@ -346,6 +347,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
*/
private final AssistDataReceiverImpl mAssistReceiver = new AssistDataReceiverImpl();
+ private final AccessibilityManager mAccessibilityManager;
+
void onSwitchInputMethodLocked() {
// One caveat is that for the case where the focus is on a field for which regular autofill
// returns null, and augmented autofill is triggered, and then the user switches the input
@@ -440,6 +443,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
if (!mWaitForInlineRequest || mPendingInlineSuggestionsRequest != null) {
return;
}
+ mWaitForInlineRequest = inlineSuggestionsRequest != null;
mPendingInlineSuggestionsRequest = inlineSuggestionsRequest;
maybeRequestFillLocked();
viewState.resetState(ViewState.STATE_PENDING_CREATE_INLINE_REQUEST);
@@ -457,9 +461,14 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
return;
}
- mPendingFillRequest = new FillRequest(mPendingFillRequest.getId(),
- mPendingFillRequest.getFillContexts(), mPendingFillRequest.getClientState(),
- mPendingFillRequest.getFlags(), mPendingInlineSuggestionsRequest);
+ // If a11y touch exploration is enabled, then we do not send an inline fill request
+ // to the regular af service, because dropdown UI is easier to use.
+ if (!mAccessibilityManager.isTouchExplorationEnabled()) {
+ mPendingFillRequest = new FillRequest(mPendingFillRequest.getId(),
+ mPendingFillRequest.getFillContexts(),
+ mPendingFillRequest.getClientState(),
+ mPendingFillRequest.getFlags(), mPendingInlineSuggestionsRequest);
+ }
}
mRemoteFillService.onFillRequest(mPendingFillRequest);
@@ -888,6 +897,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
mRemoteFillService = serviceComponentName == null ? null
: new RemoteFillService(context, serviceComponentName, userId, this,
bindInstantServiceAllowed);
+ mAccessibilityManager = AccessibilityManager.getInstance(context);
mActivityToken = activityToken;
mHasCallback = hasCallback;
mUiLatencyHistory = uiLatencyHistory;
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
index b7feb6306c99..30de4b416410 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
@@ -17,6 +17,7 @@
package com.android.server.companion;
+import static android.Manifest.permission.BIND_COMPANION_DEVICE_SERVICE;
import static android.bluetooth.le.ScanSettings.CALLBACK_TYPE_ALL_MATCHES;
import static android.bluetooth.le.ScanSettings.SCAN_MODE_BALANCED;
import static android.content.Context.BIND_IMPORTANT;
@@ -1197,6 +1198,12 @@ public class CompanionDeviceManagerService extends SystemService implements Bind
+ " has " + packageResolveInfos.size());
return new ServiceConnector.NoOp<>();
}
+ String servicePermission = packageResolveInfos.get(0).serviceInfo.permission;
+ if (!BIND_COMPANION_DEVICE_SERVICE.equals(servicePermission)) {
+ Slog.w(LOG_TAG, "Binding CompanionDeviceService must have "
+ + BIND_COMPANION_DEVICE_SERVICE + " permission.");
+ return new ServiceConnector.NoOp<>();
+ }
ComponentName componentName = packageResolveInfos.get(0).serviceInfo.getComponentName();
Slog.i(LOG_TAG, "Initializing CompanionDeviceService binding for " + componentName);
return new ServiceConnector.Impl<ICompanionDeviceService>(getContext(),
diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
index 25ea12b1c341..8a42ddfdc19d 100644
--- a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
+++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
@@ -70,6 +70,7 @@ import android.provider.Settings;
import android.service.contentcapture.ActivityEvent.ActivityEventType;
import android.service.contentcapture.IDataShareCallback;
import android.service.contentcapture.IDataShareReadAdapter;
+import android.service.voice.VoiceInteractionManagerInternal;
import android.util.ArraySet;
import android.util.LocalLog;
import android.util.Pair;
@@ -302,6 +303,37 @@ public final class ContentCaptureManagerService extends
|| super.isDisabledLocked(userId);
}
+ @Override
+ protected void assertCalledByPackageOwner(@NonNull String packageName) {
+ try {
+ super.assertCalledByPackageOwner(packageName);
+ } catch (SecurityException e) {
+ final int callingUid = Binder.getCallingUid();
+
+ VoiceInteractionManagerInternal.HotwordDetectionServiceIdentity
+ hotwordDetectionServiceIdentity =
+ LocalServices.getService(VoiceInteractionManagerInternal.class)
+ .getHotwordDetectionServiceIdentity();
+
+ if (callingUid != hotwordDetectionServiceIdentity.getIsolatedUid()) {
+ super.assertCalledByPackageOwner(packageName);
+ return;
+ }
+
+ final String[] packages =
+ getContext()
+ .getPackageManager()
+ .getPackagesForUid(hotwordDetectionServiceIdentity.getOwnerUid());
+ if (packages != null) {
+ for (String candidate : packages) {
+ if (packageName.equals(candidate)) return; // Found it
+ }
+ }
+
+ throw e;
+ }
+ }
+
private boolean isDisabledBySettingsLocked(@UserIdInt int userId) {
return mDisabledBySettings != null && mDisabledBySettings.get(userId);
}
diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java
index 225a8d48114b..904def0af2cf 100644
--- a/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java
+++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java
@@ -57,6 +57,7 @@ import android.service.contentcapture.FlushMetrics;
import android.service.contentcapture.IContentCaptureServiceCallback;
import android.service.contentcapture.IDataShareCallback;
import android.service.contentcapture.SnapshotData;
+import android.service.voice.VoiceInteractionManagerInternal;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Slog;
@@ -415,12 +416,25 @@ final class ContentCapturePerUserService
}
if (callingUid != packageUid && !LocalServices.getService(ActivityManagerInternal.class)
.hasRunningActivity(callingUid, packageName)) {
- final String[] packages = pm.getPackagesForUid(callingUid);
- final String callingPackage = packages != null ? packages[0] : "uid-" + callingUid;
- Slog.w(TAG, "App (package=" + callingPackage + ", UID=" + callingUid
- + ") passed package (" + packageName + ") owned by UID " + packageUid);
- throw new SecurityException("Invalid package: " + packageName);
+ VoiceInteractionManagerInternal.HotwordDetectionServiceIdentity
+ hotwordDetectionServiceIdentity =
+ LocalServices.getService(VoiceInteractionManagerInternal.class)
+ .getHotwordDetectionServiceIdentity();
+
+ boolean isHotwordDetectionServiceCall =
+ hotwordDetectionServiceIdentity != null
+ && callingUid == hotwordDetectionServiceIdentity.getIsolatedUid()
+ && packageUid == hotwordDetectionServiceIdentity.getOwnerUid();
+
+ if (!isHotwordDetectionServiceCall) {
+ final String[] packages = pm.getPackagesForUid(callingUid);
+ final String callingPackage = packages != null ? packages[0] : "uid-" + callingUid;
+ Slog.w(TAG, "App (package=" + callingPackage + ", UID=" + callingUid
+ + ") passed package (" + packageName + ") owned by UID " + packageUid);
+
+ throw new SecurityException("Invalid package: " + packageName);
+ }
}
}
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index 4da682e1ec49..0aeda9d1c65f 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -2877,6 +2877,16 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
mContext.sendBroadcastAsUser(intent, UserHandle.ALL, null, getTempAllowlistBroadcastOptions());
}
+ private boolean isBleState(int state) {
+ switch (state) {
+ case BluetoothAdapter.STATE_BLE_ON:
+ case BluetoothAdapter.STATE_BLE_TURNING_ON:
+ case BluetoothAdapter.STATE_BLE_TURNING_OFF:
+ return true;
+ }
+ return false;
+ }
+
@RequiresPermission(allOf = {
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.BLUETOOTH_PRIVILEGED,
@@ -2900,10 +2910,15 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
sendBluetoothStateCallback(false);
unbindAndFinish();
sendBleStateChanged(prevState, newState);
- if (prevState != BluetoothAdapter.STATE_TURNING_ON) {
- // Don't broadcast as it has already been broadcast before
- isStandardBroadcast = false;
- }
+
+ /* Currently, the OFF intent is broadcasted externally only when we transition
+ * from TURNING_OFF to BLE_ON state. So if the previous state is a BLE state,
+ * we are guaranteed that the OFF intent has been broadcasted earlier and we
+ * can safely skip it.
+ * Conversely, if the previous state is not a BLE state, it indicates that some
+ * sort of crash has occurred, moving us directly to STATE_OFF without ever
+ * passing through BLE_ON. We should broadcast the OFF intent in this case. */
+ isStandardBroadcast = !isBleState(prevState);
} else if (!intermediate_off) {
// connect to GattService
@@ -2956,6 +2971,11 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
// Show prevState of BLE_ON as OFF to standard users
prevState = BluetoothAdapter.STATE_OFF;
}
+ if (DBG) {
+ Slog.d(TAG,
+ "Sending State Change: " + BluetoothAdapter.nameForState(prevState) + " > "
+ + BluetoothAdapter.nameForState(newState));
+ }
Intent intent = new Intent(BluetoothAdapter.ACTION_STATE_CHANGED);
intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, prevState);
intent.putExtra(BluetoothAdapter.EXTRA_STATE, newState);
diff --git a/services/core/java/com/android/server/PersistentDataBlockService.java b/services/core/java/com/android/server/PersistentDataBlockService.java
index e336b6bafac4..16645dfd386d 100644
--- a/services/core/java/com/android/server/PersistentDataBlockService.java
+++ b/services/core/java/com/android/server/PersistentDataBlockService.java
@@ -375,15 +375,38 @@ public class PersistentDataBlockService extends SystemService {
try {
FileChannel channel = getBlockOutputChannel();
+ // Format the data selectively.
+ //
+ // 1. write header, set length = 0
int header_size = DIGEST_SIZE_BYTES + HEADER_SIZE;
ByteBuffer buf = ByteBuffer.allocate(header_size);
buf.put(new byte[DIGEST_SIZE_BYTES]);
buf.putInt(PARTITION_TYPE_MARKER);
buf.putInt(0);
+ buf.flip();
channel.write(buf);
- // corrupt the payload explicitly
+ channel.force(true);
+
+ // 2. corrupt the legacy FRP data explicitly
int payload_size = (int) getBlockDeviceSize() - header_size;
- buf = ByteBuffer.allocate(payload_size);
+ buf = ByteBuffer.allocate(payload_size
+ - TEST_MODE_RESERVED_SIZE - FRP_CREDENTIAL_RESERVED_SIZE - 1);
+ channel.write(buf);
+ channel.force(true);
+
+ // 3. skip the test mode data and leave it unformat
+ // This is for a feature that enables testing.
+ channel.position(channel.position() + TEST_MODE_RESERVED_SIZE);
+
+ // 4. wipe the FRP_CREDENTIAL explicitly
+ buf = ByteBuffer.allocate(FRP_CREDENTIAL_RESERVED_SIZE);
+ channel.write(buf);
+ channel.force(true);
+
+ // 5. set unlock = 0 because it's a formatPartitionLocked
+ buf = ByteBuffer.allocate(FRP_CREDENTIAL_RESERVED_SIZE);
+ buf.put((byte)0);
+ buf.flip();
channel.write(buf);
channel.force(true);
} catch (IOException e) {
diff --git a/services/core/java/com/android/server/SensorPrivacyService.java b/services/core/java/com/android/server/SensorPrivacyService.java
index ac43fbd4f976..40e63dac72ea 100644
--- a/services/core/java/com/android/server/SensorPrivacyService.java
+++ b/services/core/java/com/android/server/SensorPrivacyService.java
@@ -21,8 +21,6 @@ import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_CAMERA;
import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_MICROPHONE;
import static android.app.ActivityManager.RunningServiceInfo;
import static android.app.ActivityManager.RunningTaskInfo;
-import static android.app.ActivityManager.getCurrentUser;
-import static android.app.AppOpsManager.MODE_ALLOWED;
import static android.app.AppOpsManager.MODE_IGNORED;
import static android.app.AppOpsManager.OP_CAMERA;
import static android.app.AppOpsManager.OP_PHONE_CALL_CAMERA;
@@ -232,14 +230,14 @@ public final class SensorPrivacyService extends SystemService {
public void onUserStarting(TargetUser user) {
if (mCurrentUser == -1) {
mCurrentUser = user.getUserIdentifier();
- setGlobalRestriction();
+ mSensorPrivacyServiceImpl.userSwitching(-1, user.getUserIdentifier());
}
}
@Override
public void onUserSwitching(TargetUser from, TargetUser to) {
mCurrentUser = to.getUserIdentifier();
- setGlobalRestriction();
+ mSensorPrivacyServiceImpl.userSwitching(from.getUserIdentifier(), to.getUserIdentifier());
}
class SensorPrivacyServiceImpl extends ISensorPrivacyManager.Stub implements
@@ -383,17 +381,9 @@ public final class SensorPrivacyService extends SystemService {
int sensor;
if (result == MODE_IGNORED) {
- if (code == OP_RECORD_AUDIO) {
+ if (code == OP_RECORD_AUDIO || code == OP_PHONE_CALL_MICROPHONE) {
sensor = MICROPHONE;
- } else if (code == OP_CAMERA) {
- sensor = CAMERA;
- } else {
- return;
- }
- } else if (result == MODE_ALLOWED) {
- if (code == OP_PHONE_CALL_MICROPHONE) {
- sensor = MICROPHONE;
- } else if (code == OP_PHONE_CALL_CAMERA) {
+ } else if (code == OP_CAMERA || code == OP_PHONE_CALL_CAMERA) {
sensor = CAMERA;
} else {
return;
@@ -718,6 +708,9 @@ public final class SensorPrivacyService extends SystemService {
public void setIndividualSensorPrivacy(@UserIdInt int userId,
@SensorPrivacyManager.Sources.Source int source, int sensor, boolean enable) {
enforceManageSensorPrivacyPermission();
+ if (userId == UserHandle.USER_CURRENT) {
+ userId = mCurrentUser;
+ }
if (!canChangeIndividualSensorPrivacy(userId, sensor)) {
return;
}
@@ -843,6 +836,9 @@ public final class SensorPrivacyService extends SystemService {
public void setIndividualSensorPrivacyForProfileGroup(@UserIdInt int userId,
@SensorPrivacyManager.Sources.Source int source, int sensor, boolean enable) {
enforceManageSensorPrivacyPermission();
+ if (userId == UserHandle.USER_CURRENT) {
+ userId = mCurrentUser;
+ }
int parentId = mUserManagerInternal.getProfileParentId(userId);
forAllUsers(userId2 -> {
if (parentId == mUserManagerInternal.getProfileParentId(userId2)) {
@@ -896,17 +892,24 @@ public final class SensorPrivacyService extends SystemService {
@Override
public boolean isIndividualSensorPrivacyEnabled(@UserIdInt int userId, int sensor) {
enforceObserveSensorPrivacyPermission();
+ if (userId == UserHandle.USER_CURRENT) {
+ userId = mCurrentUser;
+ }
synchronized (mLock) {
- SparseArray<SensorState> states = mIndividualEnabled.get(userId);
- if (states == null) {
- return false;
- }
- SensorState state = states.get(sensor);
- if (state == null) {
- return false;
- }
- return state.mEnabled;
+ return isIndividualSensorPrivacyEnabledLocked(userId, sensor);
+ }
+ }
+
+ private boolean isIndividualSensorPrivacyEnabledLocked(int userId, int sensor) {
+ SparseArray<SensorState> states = mIndividualEnabled.get(userId);
+ if (states == null) {
+ return false;
}
+ SensorState state = states.get(sensor);
+ if (state == null) {
+ return false;
+ }
+ return state.mEnabled;
}
/**
@@ -1149,11 +1152,27 @@ public final class SensorPrivacyService extends SystemService {
ISensorPrivacyListener listener) {
enforceObserveSensorPrivacyPermission();
if (listener == null) {
- throw new NullPointerException("listener cannot be null");
+ throw new IllegalArgumentException("listener cannot be null");
}
mHandler.addListener(userId, sensor, listener);
}
+
+ /**
+ * Registers a listener to be notified when the sensor privacy state changes. The callback
+ * can be called if the user changes and the setting is different between the transitioning
+ * users.
+ */
+ @Override
+ public void addUserGlobalIndividualSensorPrivacyListener(int sensor,
+ ISensorPrivacyListener listener) {
+ enforceObserveSensorPrivacyPermission();
+ if (listener == null) {
+ throw new IllegalArgumentException("listener cannot be null");
+ }
+ mHandler.addUserGlobalListener(sensor, listener);
+ }
+
/**
* Unregisters a listener from sensor privacy state change notifications.
*/
@@ -1174,15 +1193,28 @@ public final class SensorPrivacyService extends SystemService {
ISensorPrivacyListener listener) {
enforceObserveSensorPrivacyPermission();
if (listener == null) {
- throw new NullPointerException("listener cannot be null");
+ throw new IllegalArgumentException("listener cannot be null");
}
mHandler.removeListener(sensor, listener);
}
@Override
+ public void removeUserGlobalIndividualSensorPrivacyListener(int sensor,
+ ISensorPrivacyListener listener) {
+ enforceObserveSensorPrivacyPermission();
+ if (listener == null) {
+ throw new IllegalArgumentException("listener cannot be null");
+ }
+ mHandler.removeUserGlobalListener(sensor, listener);
+ }
+
+ @Override
public void suppressIndividualSensorPrivacyReminders(int userId, int sensor,
IBinder token, boolean suppress) {
enforceManageSensorPrivacyPermission();
+ if (userId == UserHandle.USER_CURRENT) {
+ userId = mCurrentUser;
+ }
Objects.requireNonNull(token);
Pair<Integer, UserHandle> key = new Pair<>(sensor, UserHandle.of(userId));
@@ -1209,6 +1241,44 @@ public final class SensorPrivacyService extends SystemService {
}
}
+ private void userSwitching(int from, int to) {
+ boolean micState;
+ boolean camState;
+ boolean prevMicState;
+ boolean prevCamState;
+ synchronized (mLock) {
+ prevMicState = isIndividualSensorPrivacyEnabledLocked(from, MICROPHONE);
+ prevCamState = isIndividualSensorPrivacyEnabledLocked(from, CAMERA);
+ micState = isIndividualSensorPrivacyEnabledLocked(to, MICROPHONE);
+ camState = isIndividualSensorPrivacyEnabledLocked(to, CAMERA);
+ }
+ if (prevMicState != micState) {
+ mHandler.onUserGlobalSensorPrivacyChanged(MICROPHONE, micState);
+ setGlobalRestriction(MICROPHONE, micState);
+ }
+ if (prevCamState != camState) {
+ mHandler.onUserGlobalSensorPrivacyChanged(CAMERA, camState);
+ setGlobalRestriction(CAMERA, micState);
+ }
+ }
+
+ private void setGlobalRestriction(int sensor, boolean enabled) {
+ switch(sensor) {
+ case MICROPHONE:
+ mAppOpsManagerInternal.setGlobalRestriction(OP_RECORD_AUDIO, enabled,
+ mAppOpsRestrictionToken);
+ mAppOpsManagerInternal.setGlobalRestriction(OP_PHONE_CALL_MICROPHONE, enabled,
+ mAppOpsRestrictionToken);
+ break;
+ case CAMERA:
+ mAppOpsManagerInternal.setGlobalRestriction(OP_CAMERA, enabled,
+ mAppOpsRestrictionToken);
+ mAppOpsManagerInternal.setGlobalRestriction(OP_PHONE_CALL_CAMERA, enabled,
+ mAppOpsRestrictionToken);
+ break;
+ }
+ }
+
/**
* Remove a sensor use reminder suppression token.
*
@@ -1454,7 +1524,12 @@ public final class SensorPrivacyService extends SystemService {
@GuardedBy("mListenerLock")
private final SparseArray<SparseArray<RemoteCallbackList<ISensorPrivacyListener>>>
mIndividualSensorListeners = new SparseArray<>();
- private final ArrayMap<ISensorPrivacyListener, DeathRecipient> mDeathRecipients;
+ @GuardedBy("mListenerLock")
+ private final SparseArray<RemoteCallbackList<ISensorPrivacyListener>>
+ mUserGlobalIndividualSensorListeners = new SparseArray<>();
+ @GuardedBy("mListenerLock")
+ private final ArrayMap<ISensorPrivacyListener, Pair<DeathRecipient, Integer>>
+ mDeathRecipients;
private final Context mContext;
SensorPrivacyHandler(Looper looper, Context context) {
@@ -1479,18 +1554,22 @@ public final class SensorPrivacyService extends SystemService {
mSensorPrivacyServiceImpl));
}
+ public void onUserGlobalSensorPrivacyChanged(int sensor, boolean enabled) {
+ sendMessage(PooledLambda.obtainMessage(
+ SensorPrivacyHandler::handleUserGlobalSensorPrivacyChanged,
+ this, sensor, enabled));
+ }
+
public void addListener(ISensorPrivacyListener listener) {
synchronized (mListenerLock) {
- DeathRecipient deathRecipient = new DeathRecipient(listener);
- mDeathRecipients.put(listener, deathRecipient);
- mListeners.register(listener);
+ if (mListeners.register(listener)) {
+ addDeathRecipient(listener);
+ }
}
}
public void addListener(int userId, int sensor, ISensorPrivacyListener listener) {
synchronized (mListenerLock) {
- DeathRecipient deathRecipient = new DeathRecipient(listener);
- mDeathRecipients.put(listener, deathRecipient);
SparseArray<RemoteCallbackList<ISensorPrivacyListener>> listenersForUser =
mIndividualSensorListeners.get(userId);
if (listenersForUser == null) {
@@ -1502,32 +1581,55 @@ public final class SensorPrivacyService extends SystemService {
listeners = new RemoteCallbackList<>();
listenersForUser.put(sensor, listeners);
}
- listeners.register(listener);
+ if (listeners.register(listener)) {
+ addDeathRecipient(listener);
+ }
}
}
- public void removeListener(ISensorPrivacyListener listener) {
+ public void addUserGlobalListener(int sensor, ISensorPrivacyListener listener) {
synchronized (mListenerLock) {
- DeathRecipient deathRecipient = mDeathRecipients.remove(listener);
- if (deathRecipient != null) {
- deathRecipient.destroy();
+ RemoteCallbackList<ISensorPrivacyListener> listeners =
+ mUserGlobalIndividualSensorListeners.get(sensor);
+ if (listeners == null) {
+ listeners = new RemoteCallbackList<>();
+ mUserGlobalIndividualSensorListeners.put(sensor, listeners);
+ }
+ if (listeners.register(listener)) {
+ addDeathRecipient(listener);
}
- mListeners.unregister(listener);
}
}
- public void removeListener(int sensor, ISensorPrivacyListener listener) {
+ public void removeListener(ISensorPrivacyListener listener) {
synchronized (mListenerLock) {
- DeathRecipient deathRecipient = mDeathRecipients.remove(listener);
- if (deathRecipient != null) {
- deathRecipient.destroy();
+ if (mListeners.unregister(listener)) {
+ removeDeathRecipient(listener);
}
+ }
+ }
+ public void removeListener(int sensor, ISensorPrivacyListener listener) {
+ synchronized (mListenerLock) {
for (int i = 0, numUsers = mIndividualSensorListeners.size(); i < numUsers; i++) {
RemoteCallbackList callbacks =
mIndividualSensorListeners.valueAt(i).get(sensor);
if (callbacks != null) {
- callbacks.unregister(listener);
+ if (callbacks.unregister(listener)) {
+ removeDeathRecipient(listener);
+ }
+ }
+ }
+ }
+ }
+
+ public void removeUserGlobalListener(int sensor, ISensorPrivacyListener listener) {
+ synchronized (mListenerLock) {
+ RemoteCallbackList callbacks =
+ mUserGlobalIndividualSensorListeners.get(sensor);
+ if (callbacks != null) {
+ if (callbacks.unregister(listener)) {
+ removeDeathRecipient(listener);
}
}
}
@@ -1551,9 +1653,12 @@ public final class SensorPrivacyService extends SystemService {
SparseArray<RemoteCallbackList<ISensorPrivacyListener>> listenersForUser =
mIndividualSensorListeners.get(userId);
- setGlobalRestriction();
if (userId == mCurrentUser) {
- setGlobalRestriction();
+ mSensorPrivacyServiceImpl.setGlobalRestriction(sensor, enabled);
+ }
+
+ if (userId == mCurrentUser) {
+ onUserGlobalSensorPrivacyChanged(sensor, enabled);
}
if (listenersForUser == null) {
@@ -1563,16 +1668,42 @@ public final class SensorPrivacyService extends SystemService {
if (listeners == null) {
return;
}
- final int count = listeners.beginBroadcast();
- for (int i = 0; i < count; i++) {
- ISensorPrivacyListener listener = listeners.getBroadcastItem(i);
- try {
- listener.onSensorPrivacyChanged(enabled);
- } catch (RemoteException e) {
- Log.e(TAG, "Caught an exception notifying listener " + listener + ": ", e);
+ try {
+ final int count = listeners.beginBroadcast();
+ for (int i = 0; i < count; i++) {
+ ISensorPrivacyListener listener = listeners.getBroadcastItem(i);
+ try {
+ listener.onSensorPrivacyChanged(enabled);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Caught an exception notifying listener " + listener + ": ", e);
+ }
+ }
+ } finally {
+ listeners.finishBroadcast();
+ }
+ }
+
+ public void handleUserGlobalSensorPrivacyChanged(int sensor, boolean enabled) {
+ RemoteCallbackList<ISensorPrivacyListener> listeners =
+ mUserGlobalIndividualSensorListeners.get(sensor);
+
+ if (listeners == null) {
+ return;
+ }
+
+ try {
+ final int count = listeners.beginBroadcast();
+ for (int i = 0; i < count; i++) {
+ ISensorPrivacyListener listener = listeners.getBroadcastItem(i);
+ try {
+ listener.onSensorPrivacyChanged(enabled);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Caught an exception notifying listener " + listener + ": ", e);
+ }
}
+ } finally {
+ listeners.finishBroadcast();
}
- listeners.finishBroadcast();
}
public void removeSuppressPackageReminderToken(Pair<Integer, UserHandle> key,
@@ -1581,20 +1712,33 @@ public final class SensorPrivacyService extends SystemService {
SensorPrivacyServiceImpl::removeSuppressPackageReminderToken,
mSensorPrivacyServiceImpl, key, token));
}
- }
- private void setGlobalRestriction() {
- boolean camState =
- mSensorPrivacyServiceImpl
- .isIndividualSensorPrivacyEnabled(mCurrentUser, CAMERA);
- boolean micState =
- mSensorPrivacyServiceImpl
- .isIndividualSensorPrivacyEnabled(mCurrentUser, MICROPHONE);
-
- mAppOpsManagerInternal
- .setGlobalRestriction(OP_CAMERA, camState, mAppOpsRestrictionToken);
- mAppOpsManagerInternal
- .setGlobalRestriction(OP_RECORD_AUDIO, micState, mAppOpsRestrictionToken);
+ private void addDeathRecipient(ISensorPrivacyListener listener) {
+ Pair<DeathRecipient, Integer> deathRecipient = mDeathRecipients.get(listener);
+ if (deathRecipient == null) {
+ deathRecipient = new Pair<>(new DeathRecipient(listener), 1);
+ } else {
+ int newRefCount = deathRecipient.second + 1;
+ deathRecipient = new Pair<>(deathRecipient.first, newRefCount);
+ }
+ mDeathRecipients.put(listener, deathRecipient);
+ }
+
+ private void removeDeathRecipient(ISensorPrivacyListener listener) {
+ Pair<DeathRecipient, Integer> deathRecipient = mDeathRecipients.get(listener);
+ if (deathRecipient == null) {
+ return;
+ } else {
+ int newRefCount = deathRecipient.second - 1;
+ if (newRefCount == 0) {
+ mDeathRecipients.remove(listener);
+ deathRecipient.first.destroy();
+ return;
+ }
+ deathRecipient = new Pair<>(deathRecipient.first, newRefCount);
+ }
+ mDeathRecipients.put(listener, deathRecipient);
+ }
}
private final class DeathRecipient implements IBinder.DeathRecipient {
@@ -1760,9 +1904,9 @@ public final class SensorPrivacyService extends SystemService {
if (!mIsInEmergencyCall) {
mIsInEmergencyCall = true;
if (mSensorPrivacyServiceImpl
- .isIndividualSensorPrivacyEnabled(getCurrentUser(), MICROPHONE)) {
+ .isIndividualSensorPrivacyEnabled(mCurrentUser, MICROPHONE)) {
mSensorPrivacyServiceImpl.setIndividualSensorPrivacyUnchecked(
- getCurrentUser(), OTHER, MICROPHONE, false);
+ mCurrentUser, OTHER, MICROPHONE, false);
mMicUnmutedForEmergencyCall = true;
} else {
mMicUnmutedForEmergencyCall = false;
@@ -1777,7 +1921,7 @@ public final class SensorPrivacyService extends SystemService {
mIsInEmergencyCall = false;
if (mMicUnmutedForEmergencyCall) {
mSensorPrivacyServiceImpl.setIndividualSensorPrivacyUnchecked(
- getCurrentUser(), OTHER, MICROPHONE, true);
+ mCurrentUser, OTHER, MICROPHONE, true);
mMicUnmutedForEmergencyCall = false;
}
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 20dcb0559447..e485d38c24c6 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -193,6 +193,7 @@ import android.app.usage.UsageEvents.Event;
import android.app.usage.UsageStatsManager;
import android.app.usage.UsageStatsManagerInternal;
import android.appwidget.AppWidgetManager;
+import android.appwidget.AppWidgetManagerInternal;
import android.content.AttributionSource;
import android.content.AutofillOptions;
import android.content.BroadcastReceiver;
@@ -16700,6 +16701,13 @@ public class ActivityManagerService extends IActivityManager.Stub
if (updateFrameworkRes) {
ParsingPackageUtils.readConfigUseRoundIcon(null);
}
+
+ AppWidgetManagerInternal widgets = LocalServices.getService(AppWidgetManagerInternal.class);
+ if (widgets != null) {
+ widgets.applyResourceOverlaysToWidgets(new HashSet<>(packagesToUpdate), userId,
+ updateFrameworkRes);
+ }
+
mProcessList.updateApplicationInfoLOSP(packagesToUpdate, userId, updateFrameworkRes);
if (updateFrameworkRes) {
diff --git a/services/core/java/com/android/server/am/AppExitInfoTracker.java b/services/core/java/com/android/server/am/AppExitInfoTracker.java
index abb824395578..979a9eed14aa 100644
--- a/services/core/java/com/android/server/am/AppExitInfoTracker.java
+++ b/services/core/java/com/android/server/am/AppExitInfoTracker.java
@@ -430,7 +430,13 @@ public final class AppExitInfoTracker {
final ApplicationExitInfo info = new ApplicationExitInfo(raw);
final String[] packages = raw.getPackageList();
- final int uid = raw.getPackageUid();
+ int uid = raw.getRealUid();
+ if (UserHandle.isIsolated(uid)) {
+ Integer k = mIsolatedUidRecords.getUidByIsolatedUid(uid);
+ if (k != null) {
+ uid = k;
+ }
+ }
for (int i = 0; i < packages.length; i++) {
addExitInfoInnerLocked(packages[i], uid, info);
}
@@ -833,14 +839,14 @@ public final class AppExitInfoTracker {
pw.println(prefix + "package: " + packageName);
int size = array.size();
for (int i = 0; i < size; i++) {
- pw.println(prefix + " Historical Process Exit for userId=" + array.keyAt(i));
+ pw.println(prefix + " Historical Process Exit for uid=" + array.keyAt(i));
array.valueAt(i).dumpLocked(pw, prefix + " ", sdf);
}
}
@GuardedBy("mLock")
- private void addExitInfoInnerLocked(String packageName, int userId, ApplicationExitInfo info) {
- AppExitInfoContainer container = mData.get(packageName, userId);
+ private void addExitInfoInnerLocked(String packageName, int uid, ApplicationExitInfo info) {
+ AppExitInfoContainer container = mData.get(packageName, uid);
if (container == null) {
container = new AppExitInfoContainer(mAppExitInfoHistoryListSize);
if (UserHandle.isIsolated(info.getRealUid())) {
@@ -851,7 +857,7 @@ public final class AppExitInfoTracker {
} else {
container.mUid = info.getRealUid();
}
- mData.put(packageName, userId, container);
+ mData.put(packageName, uid, container);
}
container.addExitInfoLocked(info);
}
@@ -997,7 +1003,7 @@ public final class AppExitInfoTracker {
info.setPackageList(app.getPackageList());
info.setReason(ApplicationExitInfo.REASON_UNKNOWN);
info.setStatus(0);
- info.setImportance(procStateToImportance(app.mState.getSetProcState()));
+ info.setImportance(procStateToImportance(app.mState.getReportedProcState()));
info.setPss(app.mProfile.getLastPss());
info.setRss(app.mProfile.getLastRss());
info.setTimestamp(timestamp);
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 9f41c8ba9626..ae14ca7b66bd 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -841,6 +841,12 @@ public final class BatteryStatsService extends IBatteryStats.Stub
public void noteEvent(final int code, final String name, final int uid) {
enforceCallingPermission();
+ if (name == null) {
+ // TODO(b/194733136): Replace with an IllegalArgumentException throw.
+ Slog.wtfStack(TAG, "noteEvent called with null name. code = " + code);
+ return;
+ }
+
synchronized (mLock) {
final long elapsedRealtime = SystemClock.elapsedRealtime();
final long uptime = SystemClock.uptimeMillis();
diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java
index ee4551de00df..a947a24bc6bf 100644
--- a/services/core/java/com/android/server/am/CachedAppOptimizer.java
+++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java
@@ -43,6 +43,7 @@ import android.util.BoostFramework;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.os.ProcLocksReader;
import com.android.internal.util.FrameworkStatsLog;
import com.android.server.ServiceThread;
@@ -324,6 +325,7 @@ public final class CachedAppOptimizer {
private int mPersistentCompactionCount;
private int mBfgsCompactionCount;
private final ProcessDependencies mProcessDependencies;
+ private final ProcLocksReader mProcLocksReader;
public static BoostFramework mPerf = new BoostFramework();
public CachedAppOptimizer(ActivityManagerService am) {
@@ -341,6 +343,7 @@ public final class CachedAppOptimizer {
mProcessDependencies = processDependencies;
mTestCallback = callback;
mSettingsObserver = new SettingsContentObserver();
+ mProcLocksReader = new ProcLocksReader();
}
/**
@@ -1411,7 +1414,7 @@ public final class CachedAppOptimizer {
try {
// pre-check for locks to avoid unnecessary freeze/unfreeze operations
- if (Process.hasFileLocks(pid)) {
+ if (mProcLocksReader.hasFileLocks(pid)) {
if (DEBUG_FREEZER) {
Slog.d(TAG_AM, name + " (" + pid + ") holds file locks, not freezing");
}
@@ -1498,7 +1501,7 @@ public final class CachedAppOptimizer {
try {
// post-check to prevent races
- if (Process.hasFileLocks(pid)) {
+ if (mProcLocksReader.hasFileLocks(pid)) {
if (DEBUG_FREEZER) {
Slog.d(TAG_AM, name + " (" + pid + ") holds file locks, reverting freeze");
}
diff --git a/services/core/java/com/android/server/am/LmkdConnection.java b/services/core/java/com/android/server/am/LmkdConnection.java
index 1ecb9eb81709..598f086db94d 100644
--- a/services/core/java/com/android/server/am/LmkdConnection.java
+++ b/services/core/java/com/android/server/am/LmkdConnection.java
@@ -50,7 +50,7 @@ public class LmkdConnection {
* Used to hold the data for the statsd atoms logging
* Must be in sync with statslog.h
*/
- private static final int LMKD_REPLY_MAX_SIZE = 214;
+ private static final int LMKD_REPLY_MAX_SIZE = 222;
// connection listener interface
interface LmkdConnectionListener {
diff --git a/services/core/java/com/android/server/am/LmkdStatsReporter.java b/services/core/java/com/android/server/am/LmkdStatsReporter.java
index a8d058229a4b..91588913c33c 100644
--- a/services/core/java/com/android/server/am/LmkdStatsReporter.java
+++ b/services/core/java/com/android/server/am/LmkdStatsReporter.java
@@ -64,11 +64,14 @@ public final class LmkdStatsReporter {
final int freeMemKb = inputData.readInt();
final int freeSwapKb = inputData.readInt();
final int killReason = inputData.readInt();
+ final int thrashing = inputData.readInt();
+ final int maxThrashing = inputData.readInt();
final String procName = inputData.readUTF();
FrameworkStatsLog.write(FrameworkStatsLog.LMK_KILL_OCCURRED, uid, procName, oomScore,
pgFault, pgMajFault, rssInBytes, cacheInBytes, swapInBytes, processStartTimeNS,
- minOomScore, freeMemKb, freeSwapKb, mapKillReason(killReason));
+ minOomScore, freeMemKb, freeSwapKb, mapKillReason(killReason), thrashing,
+ maxThrashing);
} catch (IOException e) {
Slog.e(TAG, "Invalid buffer data. Failed to log LMK_KILL_OCCURRED");
return;
diff --git a/services/core/java/com/android/server/am/PhantomProcessList.java b/services/core/java/com/android/server/am/PhantomProcessList.java
index 4f3438fe8706..b07684c9a004 100644
--- a/services/core/java/com/android/server/am/PhantomProcessList.java
+++ b/services/core/java/com/android/server/am/PhantomProcessList.java
@@ -305,7 +305,7 @@ public final class PhantomProcessList {
}
// Somehow our record doesn't match, remove it anyway
Slog.w(TAG, "Stale " + proc + ", removing");
- mPhantomProcesses.removeAt(index);
+ onPhantomProcessKilledLocked(proc);
} else {
// Is this one of the zombie processes we've known?
final int idx = mZombiePhantomProcesses.indexOfKey(pid);
@@ -365,6 +365,9 @@ public final class PhantomProcessList {
private int onPhantomProcessFdEvent(FileDescriptor fd, int events) {
synchronized (mLock) {
final PhantomProcessRecord proc = mPhantomProcessesPidFds.get(fd.getInt$());
+ if (proc == null) {
+ return 0;
+ }
if ((events & EVENT_INPUT) != 0) {
proc.onProcDied(true);
} else {
diff --git a/services/core/java/com/android/server/am/ProcessStateRecord.java b/services/core/java/com/android/server/am/ProcessStateRecord.java
index 7520d88fcd16..dc6bcd8ab9de 100644
--- a/services/core/java/com/android/server/am/ProcessStateRecord.java
+++ b/services/core/java/com/android/server/am/ProcessStateRecord.java
@@ -1086,7 +1086,7 @@ final class ProcessStateRecord {
mCurRawAdj = mSetRawAdj = mCurAdj = mSetAdj = mVerifiedAdj = ProcessList.INVALID_ADJ;
mCurCapability = mSetCapability = PROCESS_CAPABILITY_NONE;
mCurSchedGroup = mSetSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
- mCurProcState = mRepProcState = mCurRawProcState = mSetProcState = mAllowStartFgsState =
+ mCurProcState = mCurRawProcState = mSetProcState = mAllowStartFgsState =
PROCESS_STATE_NONEXISTENT;
}
diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java
index 6b7787aad17e..b1d300cd838e 100644
--- a/services/core/java/com/android/server/biometrics/BiometricService.java
+++ b/services/core/java/com/android/server/biometrics/BiometricService.java
@@ -1103,9 +1103,13 @@ public class BiometricService extends SystemService {
}
public boolean isAdvancedCoexLogicEnabled(Context context) {
- return (Build.IS_USERDEBUG || Build.IS_ENG)
- && Settings.Secure.getInt(context.getContentResolver(),
- CoexCoordinator.SETTING_ENABLE_NAME, 0) != 0;
+ return Settings.Secure.getInt(context.getContentResolver(),
+ CoexCoordinator.SETTING_ENABLE_NAME, 1) != 0;
+ }
+
+ public boolean isCoexFaceNonBypassHapticsDisabled(Context context) {
+ return Settings.Secure.getInt(context.getContentResolver(),
+ CoexCoordinator.FACE_HAPTIC_DISABLE, 1) != 0;
}
}
@@ -1138,6 +1142,8 @@ public class BiometricService extends SystemService {
// by default.
CoexCoordinator coexCoordinator = CoexCoordinator.getInstance();
coexCoordinator.setAdvancedLogicEnabled(injector.isAdvancedCoexLogicEnabled(context));
+ coexCoordinator.setFaceHapticDisabledWhenNonBypass(
+ injector.isCoexFaceNonBypassHapticsDisabled(context));
try {
injector.getActivityManagerService().registerUserSwitchObserver(
diff --git a/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
index 6463e04a4ff6..f4327e8a104d 100644
--- a/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
@@ -54,12 +54,18 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T>
public static final int STATE_NEW = 0;
// Framework/HAL have started this operation
public static final int STATE_STARTED = 1;
- // Operation is started, but requires some user action (such as finger lift & re-touch)
+ // Operation is started, but requires some user action to start (such as finger lift & re-touch)
public static final int STATE_STARTED_PAUSED = 2;
+ // Same as above, except auth was attempted (rejected, timed out, etc).
+ public static final int STATE_STARTED_PAUSED_ATTEMPTED = 3;
// Done, errored, canceled, etc. HAL/framework are not running this sensor anymore.
- public static final int STATE_STOPPED = 3;
+ public static final int STATE_STOPPED = 4;
- @IntDef({STATE_NEW, STATE_STARTED, STATE_STARTED_PAUSED, STATE_STOPPED})
+ @IntDef({STATE_NEW,
+ STATE_STARTED,
+ STATE_STARTED_PAUSED,
+ STATE_STARTED_PAUSED_ATTEMPTED,
+ STATE_STOPPED})
@interface State {}
private final boolean mIsStrongBiometric;
@@ -70,6 +76,7 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T>
private final LockoutTracker mLockoutTracker;
private final boolean mIsRestricted;
private final boolean mAllowBackgroundAuthentication;
+ private final boolean mIsKeyguardBypassEnabled;
protected final long mOperationId;
@@ -97,7 +104,7 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T>
int cookie, boolean requireConfirmation, int sensorId, boolean isStrongBiometric,
int statsModality, int statsClient, @Nullable TaskStackListener taskStackListener,
@NonNull LockoutTracker lockoutTracker, boolean allowBackgroundAuthentication,
- boolean shouldVibrate) {
+ boolean shouldVibrate, boolean isKeyguardBypassEnabled) {
super(context, lazyDaemon, token, listener, targetUserId, owner, cookie, sensorId,
shouldVibrate, statsModality, BiometricsProtoEnums.ACTION_AUTHENTICATE,
statsClient);
@@ -110,6 +117,7 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T>
mLockoutTracker = lockoutTracker;
mIsRestricted = restricted;
mAllowBackgroundAuthentication = allowBackgroundAuthentication;
+ mIsKeyguardBypassEnabled = isKeyguardBypassEnabled;
}
public @LockoutTracker.LockoutMode int handleFailedAttempt(int userId) {
@@ -394,6 +402,14 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T>
return mState;
}
+ /**
+ * @return true if the client supports bypass (e.g. passive auth such as face), and if it's
+ * enabled by the user.
+ */
+ public boolean isKeyguardBypassEnabled() {
+ return mIsKeyguardBypassEnabled;
+ }
+
@Override
public int getProtoEnum() {
return BiometricsProto.CM_AUTHENTICATE;
diff --git a/services/core/java/com/android/server/biometrics/sensors/CoexCoordinator.java b/services/core/java/com/android/server/biometrics/sensors/CoexCoordinator.java
index f732a147e4b7..a15ecada3cae 100644
--- a/services/core/java/com/android/server/biometrics/sensors/CoexCoordinator.java
+++ b/services/core/java/com/android/server/biometrics/sensors/CoexCoordinator.java
@@ -26,7 +26,6 @@ import android.os.Handler;
import android.os.Looper;
import android.util.Slog;
-import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.biometrics.sensors.BiometricScheduler.SensorType;
import com.android.server.biometrics.sensors.fingerprint.Udfps;
@@ -46,6 +45,8 @@ public class CoexCoordinator {
private static final String TAG = "BiometricCoexCoordinator";
public static final String SETTING_ENABLE_NAME =
"com.android.server.biometrics.sensors.CoexCoordinator.enable";
+ public static final String FACE_HAPTIC_DISABLE =
+ "com.android.server.biometrics.sensors.CoexCoordinator.disable_face_haptics";
private static final boolean DEBUG = true;
// Successful authentications should be used within this amount of time.
@@ -145,6 +146,10 @@ public class CoexCoordinator {
mAdvancedLogicEnabled = enabled;
}
+ public void setFaceHapticDisabledWhenNonBypass(boolean disabled) {
+ mFaceHapticDisabledWhenNonBypass = disabled;
+ }
+
@VisibleForTesting
void reset() {
mClientMap.clear();
@@ -154,6 +159,7 @@ public class CoexCoordinator {
private final Map<Integer, AuthenticationClient<?>> mClientMap;
@VisibleForTesting final LinkedList<SuccessfulAuth> mSuccessfulAuths;
private boolean mAdvancedLogicEnabled;
+ private boolean mFaceHapticDisabledWhenNonBypass;
private final Handler mHandler;
private CoexCoordinator() {
@@ -226,7 +232,11 @@ public class CoexCoordinator {
mSuccessfulAuths.add(new SuccessfulAuth(mHandler, mSuccessfulAuths,
currentTimeMillis, SENSOR_TYPE_FACE, client, callback));
} else {
- callback.sendHapticFeedback();
+ if (mFaceHapticDisabledWhenNonBypass && !face.isKeyguardBypassEnabled()) {
+ Slog.w(TAG, "Skipping face success haptic");
+ } else {
+ callback.sendHapticFeedback();
+ }
callback.sendAuthenticationResult(true /* addAuthTokenIfStrong */);
callback.handleLifecycleAfterAuth();
}
@@ -242,6 +252,11 @@ public class CoexCoordinator {
callback.sendHapticFeedback();
callback.sendAuthenticationResult(true /* addAuthTokenIfStrong */);
callback.handleLifecycleAfterAuth();
+ } else {
+ // Capacitive fingerprint sensor (or other)
+ callback.sendHapticFeedback();
+ callback.sendAuthenticationResult(true /* addAuthTokenIfStrong */);
+ callback.handleLifecycleAfterAuth();
}
}
} else {
@@ -274,12 +289,23 @@ public class CoexCoordinator {
// BiometricScheduler do not get stuck.
Slog.d(TAG, "Face rejected in multi-sensor auth, udfps: " + udfps);
callback.handleLifecycleAfterAuth();
- } else {
- // UDFPS is not actively authenticating (finger not touching, already
- // rejected, etc).
+ } else if (isUdfpsAuthAttempted(udfps)) {
+ // If UDFPS is STATE_STARTED_PAUSED (e.g. finger rejected but can still
+ // auth after pointer goes down, it means UDFPS encountered a rejection. In
+ // this case, we need to play the final reject haptic since face auth is
+ // also done now.
callback.sendHapticFeedback();
callback.handleLifecycleAfterAuth();
}
+ else {
+ // UDFPS auth has never been attempted.
+ if (mFaceHapticDisabledWhenNonBypass && !face.isKeyguardBypassEnabled()) {
+ Slog.w(TAG, "Skipping face reject haptic");
+ } else {
+ callback.sendHapticFeedback();
+ }
+ callback.handleLifecycleAfterAuth();
+ }
} else if (isCurrentUdfps(client)) {
// Face should either be running, or have already finished
SuccessfulAuth auth = popSuccessfulFaceAuthIfExists(currentTimeMillis);
@@ -370,6 +396,13 @@ public class CoexCoordinator {
return false;
}
+ private static boolean isUdfpsAuthAttempted(@Nullable AuthenticationClient<?> client) {
+ if (client instanceof Udfps) {
+ return client.getState() == AuthenticationClient.STATE_STARTED_PAUSED_ATTEMPTED;
+ }
+ return false;
+ }
+
private boolean isUnknownClient(@NonNull AuthenticationClient<?> client) {
for (AuthenticationClient<?> c : mClientMap.values()) {
if (c == client) {
@@ -396,6 +429,7 @@ public class CoexCoordinator {
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("Enabled: ").append(mAdvancedLogicEnabled);
+ sb.append(", Face Haptic Disabled: ").append(mFaceHapticDisabledWhenNonBypass);
sb.append(", Queue size: " ).append(mSuccessfulAuths.size());
for (SuccessfulAuth auth : mSuccessfulAuths) {
sb.append(", Auth: ").append(auth.toString());
diff --git a/services/core/java/com/android/server/biometrics/sensors/LoggableMonitor.java b/services/core/java/com/android/server/biometrics/sensors/LoggableMonitor.java
index c8867ea2df1c..b4c82f2ed799 100644
--- a/services/core/java/com/android/server/biometrics/sensors/LoggableMonitor.java
+++ b/services/core/java/com/android/server/biometrics/sensors/LoggableMonitor.java
@@ -48,6 +48,64 @@ public abstract class LoggableMonitor {
private boolean mLightSensorEnabled = false;
private boolean mShouldLogMetrics = true;
+ /**
+ * Probe for loggable attributes that can be continuously monitored, such as ambient light.
+ *
+ * Disable probes when the sensors are in states that are not interesting for monitoring
+ * purposes to save power.
+ */
+ protected interface Probe {
+ /** Ensure the probe is actively sampling for new data. */
+ void enable();
+ /** Stop sampling data. */
+ void disable();
+ }
+
+ /**
+ * Client monitor callback that exposes a probe.
+ *
+ * Disables the probe when the operation completes.
+ */
+ protected static class CallbackWithProbe<T extends Probe>
+ implements BaseClientMonitor.Callback {
+ private final boolean mStartWithClient;
+ private final T mProbe;
+
+ public CallbackWithProbe(@NonNull T probe, boolean startWithClient) {
+ mProbe = probe;
+ mStartWithClient = startWithClient;
+ }
+
+ @Override
+ public void onClientStarted(@NonNull BaseClientMonitor clientMonitor) {
+ if (mStartWithClient) {
+ mProbe.enable();
+ }
+ }
+
+ @Override
+ public void onClientFinished(@NonNull BaseClientMonitor clientMonitor, boolean success) {
+ mProbe.disable();
+ }
+
+ @NonNull
+ public T getProbe() {
+ return mProbe;
+ }
+ }
+
+ private class ALSProbe implements Probe {
+ @Override
+ public void enable() {
+ setLightSensorLoggingEnabled(getAmbientLightSensor(mSensorManager));
+ }
+
+ @Override
+ public void disable() {
+ setLightSensorLoggingEnabled(null);
+ }
+ }
+
// report only the most recent value
// consider com.android.server.display.utils.AmbientFilter or similar if need arises
private volatile float mLastAmbientLux = 0;
@@ -285,21 +343,17 @@ public abstract class LoggableMonitor {
return latency;
}
- /** Get a callback to start/stop ALS capture when client runs. */
+ /**
+ * Get a callback to start/stop ALS capture when client runs.
+ *
+ * If the probe should not run for the entire operation, do not set startWithClient and
+ * start/stop the problem when needed.
+ *
+ * @param startWithClient if probe should start automatically when the operation starts.
+ */
@NonNull
- protected BaseClientMonitor.Callback createALSCallback() {
- return new BaseClientMonitor.Callback() {
- @Override
- public void onClientStarted(@NonNull BaseClientMonitor clientMonitor) {
- setLightSensorLoggingEnabled(getAmbientLightSensor(mSensorManager));
- }
-
- @Override
- public void onClientFinished(@NonNull BaseClientMonitor clientMonitor,
- boolean success) {
- setLightSensorLoggingEnabled(null);
- }
- };
+ protected CallbackWithProbe<Probe> createALSCallback(boolean startWithClient) {
+ return new CallbackWithProbe<>(new ALSProbe(), startWithClient);
}
/** The sensor to use for ALS logging. */
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
index 219e06358afb..12d6b08b8bcf 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
@@ -251,7 +251,8 @@ public class FaceService extends SystemService {
@Override // Binder call
public void authenticate(final IBinder token, final long operationId, int userId,
- final IFaceServiceReceiver receiver, final String opPackageName) {
+ final IFaceServiceReceiver receiver, final String opPackageName,
+ boolean isKeyguardBypassEnabled) {
Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
// TODO(b/152413782): If the sensor supports face detect and the device is encrypted or
@@ -275,7 +276,7 @@ public class FaceService extends SystemService {
provider.second.scheduleAuthenticate(provider.first, token, operationId, userId,
0 /* cookie */,
new ClientMonitorCallbackConverter(receiver), opPackageName, restricted,
- statsClient, isKeyguard);
+ statsClient, isKeyguard, isKeyguardBypassEnabled);
}
@Override // Binder call
@@ -318,10 +319,12 @@ public class FaceService extends SystemService {
return;
}
+ final boolean isKeyguardBypassEnabled = false; // only valid for keyguard clients
final boolean restricted = true; // BiometricPrompt is always restricted
provider.scheduleAuthenticate(sensorId, token, operationId, userId, cookie,
new ClientMonitorCallbackConverter(sensorReceiver), opPackageName, restricted,
- BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT, allowBackgroundAuthentication);
+ BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT, allowBackgroundAuthentication,
+ isKeyguardBypassEnabled);
}
@Override // Binder call
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/ServiceProvider.java b/services/core/java/com/android/server/biometrics/sensors/face/ServiceProvider.java
index 1d2ac3b3bfdc..93ab1b65edff 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/ServiceProvider.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/ServiceProvider.java
@@ -110,7 +110,7 @@ public interface ServiceProvider {
void scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId, int userId,
int cookie, @NonNull ClientMonitorCallbackConverter callback,
@NonNull String opPackageName, boolean restricted, int statsClient,
- boolean allowBackgroundAuthentication);
+ boolean allowBackgroundAuthentication, boolean isKeyguardBypassEnabled);
void cancelAuthentication(int sensorId, @NonNull IBinder token);
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java
index 35c17459804d..f7fd8d0972f6 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java
@@ -69,11 +69,13 @@ class FaceAuthenticationClient extends AuthenticationClient<ISession> implements
@NonNull ClientMonitorCallbackConverter listener, int targetUserId, long operationId,
boolean restricted, String owner, int cookie, boolean requireConfirmation, int sensorId,
boolean isStrongBiometric, int statsClient, @NonNull UsageStats usageStats,
- @NonNull LockoutCache lockoutCache, boolean allowBackgroundAuthentication) {
+ @NonNull LockoutCache lockoutCache, boolean allowBackgroundAuthentication,
+ boolean isKeyguardBypassEnabled) {
super(context, lazyDaemon, token, listener, targetUserId, operationId, restricted,
owner, cookie, requireConfirmation, sensorId, isStrongBiometric,
BiometricsProtoEnums.MODALITY_FACE, statsClient, null /* taskStackListener */,
- lockoutCache, allowBackgroundAuthentication, true /* shouldVibrate */);
+ lockoutCache, allowBackgroundAuthentication, true /* shouldVibrate */,
+ isKeyguardBypassEnabled);
mUsageStats = usageStats;
mLockoutCache = lockoutCache;
mNotificationManager = context.getSystemService(NotificationManager.class);
@@ -98,7 +100,7 @@ class FaceAuthenticationClient extends AuthenticationClient<ISession> implements
@NonNull
@Override
protected Callback wrapCallbackForStart(@NonNull Callback callback) {
- return new CompositeCallback(createALSCallback(), callback);
+ return new CompositeCallback(createALSCallback(true /* startWithClient */), callback);
}
@Override
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceEnrollClient.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceEnrollClient.java
index 55c987a19e45..a806277ed45e 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceEnrollClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceEnrollClient.java
@@ -109,7 +109,8 @@ public class FaceEnrollClient extends EnrollClient<ISession> {
@NonNull
@Override
protected Callback wrapCallbackForStart(@NonNull Callback callback) {
- return new CompositeCallback(mPreviewHandleDeleterCallback, createALSCallback(), callback);
+ return new CompositeCallback(mPreviewHandleDeleterCallback,
+ createALSCallback(true /* startWithClient */), callback);
}
@Override
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java
index 5c24108dcded..718b9da968f5 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java
@@ -378,7 +378,7 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
public void scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId,
int userId, int cookie, @NonNull ClientMonitorCallbackConverter callback,
@NonNull String opPackageName, boolean restricted, int statsClient,
- boolean allowBackgroundAuthentication) {
+ boolean allowBackgroundAuthentication, boolean isKeyguardBypassEnabled) {
mHandler.post(() -> {
final boolean isStrongBiometric = Utils.isStrongBiometric(sensorId);
final FaceAuthenticationClient client = new FaceAuthenticationClient(
@@ -386,7 +386,7 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
operationId, restricted, opPackageName, cookie,
false /* requireConfirmation */, sensorId, isStrongBiometric, statsClient,
mUsageStats, mSensors.get(sensorId).getLockoutCache(),
- allowBackgroundAuthentication);
+ allowBackgroundAuthentication, isKeyguardBypassEnabled);
scheduleForSensor(sensorId, client);
});
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java
index da4ad863fdba..d05333db7532 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java
@@ -622,7 +622,7 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
public void scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId,
int userId, int cookie, @NonNull ClientMonitorCallbackConverter receiver,
@NonNull String opPackageName, boolean restricted, int statsClient,
- boolean allowBackgroundAuthentication) {
+ boolean allowBackgroundAuthentication, boolean isKeyguardBypassEnabled) {
mHandler.post(() -> {
scheduleUpdateActiveUserWithoutHandler(userId);
@@ -630,7 +630,8 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
final FaceAuthenticationClient client = new FaceAuthenticationClient(mContext,
mLazyDaemon, token, receiver, userId, operationId, restricted, opPackageName,
cookie, false /* requireConfirmation */, mSensorId, isStrongBiometric,
- statsClient, mLockoutTracker, mUsageStats, allowBackgroundAuthentication);
+ statsClient, mLockoutTracker, mUsageStats, allowBackgroundAuthentication,
+ isKeyguardBypassEnabled);
mScheduler.scheduleClientMonitor(client);
});
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceAuthenticationClient.java
index e65245b98829..c33b957223a4 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceAuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceAuthenticationClient.java
@@ -61,11 +61,13 @@ class FaceAuthenticationClient extends AuthenticationClient<IBiometricsFace> {
@NonNull ClientMonitorCallbackConverter listener, int targetUserId, long operationId,
boolean restricted, String owner, int cookie, boolean requireConfirmation, int sensorId,
boolean isStrongBiometric, int statsClient, @NonNull LockoutTracker lockoutTracker,
- @NonNull UsageStats usageStats, boolean allowBackgroundAuthentication) {
+ @NonNull UsageStats usageStats, boolean allowBackgroundAuthentication,
+ boolean isKeyguardBypassEnabled) {
super(context, lazyDaemon, token, listener, targetUserId, operationId, restricted,
owner, cookie, requireConfirmation, sensorId, isStrongBiometric,
BiometricsProtoEnums.MODALITY_FACE, statsClient, null /* taskStackListener */,
- lockoutTracker, allowBackgroundAuthentication, true /* shouldVibrate */);
+ lockoutTracker, allowBackgroundAuthentication, true /* shouldVibrate */,
+ isKeyguardBypassEnabled);
mUsageStats = usageStats;
final Resources resources = getContext().getResources();
@@ -88,7 +90,7 @@ class FaceAuthenticationClient extends AuthenticationClient<IBiometricsFace> {
@NonNull
@Override
protected Callback wrapCallbackForStart(@NonNull Callback callback) {
- return new CompositeCallback(createALSCallback(), callback);
+ return new CompositeCallback(createALSCallback(true /* startWithClient */), callback);
}
@Override
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceEnrollClient.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceEnrollClient.java
index 455d6f868e65..80828cced4e8 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceEnrollClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceEnrollClient.java
@@ -69,7 +69,7 @@ public class FaceEnrollClient extends EnrollClient<IBiometricsFace> {
@NonNull
@Override
protected Callback wrapCallbackForStart(@NonNull Callback callback) {
- return new CompositeCallback(createALSCallback(), callback);
+ return new CompositeCallback(createALSCallback(true /* startWithClient */), callback);
}
@Override
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java
index 14d18225d674..8835c1e02610 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java
@@ -55,6 +55,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<ISession> imp
@NonNull private final LockoutCache mLockoutCache;
@Nullable private final IUdfpsOverlayController mUdfpsOverlayController;
@NonNull private final FingerprintSensorPropertiesInternal mSensorProps;
+ @NonNull private final CallbackWithProbe<Probe> mALSProbeCallback;
@Nullable private ICancellationSignal mCancellationSignal;
private boolean mIsPointerDown;
@@ -71,10 +72,12 @@ class FingerprintAuthenticationClient extends AuthenticationClient<ISession> imp
super(context, lazyDaemon, token, listener, targetUserId, operationId, restricted, owner,
cookie, requireConfirmation, sensorId, isStrongBiometric,
BiometricsProtoEnums.MODALITY_FINGERPRINT, statsClient, taskStackListener,
- lockoutCache, allowBackgroundAuthentication, true /* shouldVibrate */);
+ lockoutCache, allowBackgroundAuthentication, true /* shouldVibrate */,
+ false /* isKeyguardBypassEnabled */);
mLockoutCache = lockoutCache;
mUdfpsOverlayController = udfpsOverlayController;
mSensorProps = sensorProps;
+ mALSProbeCallback = createALSCallback(false /* startWithClient */);
}
@Override
@@ -92,7 +95,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<ISession> imp
@NonNull
@Override
protected Callback wrapCallbackForStart(@NonNull Callback callback) {
- return new CompositeCallback(createALSCallback(), callback);
+ return new CompositeCallback(mALSProbeCallback, callback);
}
@Override
@@ -111,7 +114,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<ISession> imp
mState = STATE_STOPPED;
UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController);
} else {
- mState = STATE_STARTED_PAUSED;
+ mState = STATE_STARTED_PAUSED_ATTEMPTED;
}
}
@@ -170,7 +173,9 @@ class FingerprintAuthenticationClient extends AuthenticationClient<ISession> imp
try {
mIsPointerDown = true;
mState = STATE_STARTED;
+ mALSProbeCallback.getProbe().enable();
getFreshDaemon().onPointerDown(0 /* pointerId */, x, y, minor, major);
+
if (getListener() != null) {
getListener().onUdfpsPointerDown(getSensorId());
}
@@ -183,8 +188,10 @@ class FingerprintAuthenticationClient extends AuthenticationClient<ISession> imp
public void onPointerUp() {
try {
mIsPointerDown = false;
- mState = STATE_STARTED_PAUSED;
+ mState = STATE_STARTED_PAUSED_ATTEMPTED;
+ mALSProbeCallback.getProbe().disable();
getFreshDaemon().onPointerUp(0 /* pointerId */);
+
if (getListener() != null) {
getListener().onUdfpsPointerUp(getSensorId());
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java
index e8200af68db5..c420c5c57241 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java
@@ -84,7 +84,7 @@ class FingerprintEnrollClient extends EnrollClient<ISession> implements Udfps {
@NonNull
@Override
protected Callback wrapCallbackForStart(@NonNull Callback callback) {
- return new CompositeCallback(createALSCallback(), callback);
+ return new CompositeCallback(createALSCallback(true /* startWithClient */), callback);
}
@Override
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintAuthenticationClient.java
index 9347244d7c77..83f1480f4611 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintAuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintAuthenticationClient.java
@@ -54,6 +54,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi
private final LockoutFrameworkImpl mLockoutFrameworkImpl;
@Nullable private final IUdfpsOverlayController mUdfpsOverlayController;
@NonNull private final FingerprintSensorPropertiesInternal mSensorProps;
+ @NonNull private final CallbackWithProbe<Probe> mALSProbeCallback;
private boolean mIsPointerDown;
@@ -70,10 +71,12 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi
super(context, lazyDaemon, token, listener, targetUserId, operationId, restricted,
owner, cookie, requireConfirmation, sensorId, isStrongBiometric,
BiometricsProtoEnums.MODALITY_FINGERPRINT, statsClient, taskStackListener,
- lockoutTracker, allowBackgroundAuthentication, true /* shouldVibrate */);
+ lockoutTracker, allowBackgroundAuthentication, true /* shouldVibrate */,
+ false /* isKeyguardBypassEnabled */);
mLockoutFrameworkImpl = lockoutTracker;
mUdfpsOverlayController = udfpsOverlayController;
mSensorProps = sensorProps;
+ mALSProbeCallback = createALSCallback(false /* startWithClient */);
}
@Override
@@ -91,7 +94,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi
@NonNull
@Override
protected Callback wrapCallbackForStart(@NonNull Callback callback) {
- return new CompositeCallback(createALSCallback(), callback);
+ return new CompositeCallback(mALSProbeCallback, callback);
}
@Override
@@ -109,7 +112,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi
resetFailedAttempts(getTargetUserId());
UdfpsHelper.hideUdfpsOverlay(getSensorId(), mUdfpsOverlayController);
} else {
- mState = STATE_STARTED_PAUSED;
+ mState = STATE_STARTED_PAUSED_ATTEMPTED;
final @LockoutTracker.LockoutMode int lockoutMode =
mLockoutFrameworkImpl.getLockoutModeForUser(getTargetUserId());
if (lockoutMode != LockoutTracker.LOCKOUT_NONE) {
@@ -188,7 +191,9 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi
public void onPointerDown(int x, int y, float minor, float major) {
mIsPointerDown = true;
mState = STATE_STARTED;
+ mALSProbeCallback.getProbe().enable();
UdfpsHelper.onFingerDown(getFreshDaemon(), x, y, minor, major);
+
if (getListener() != null) {
try {
getListener().onUdfpsPointerDown(getSensorId());
@@ -201,8 +206,10 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi
@Override
public void onPointerUp() {
mIsPointerDown = false;
- mState = STATE_STARTED_PAUSED;
+ mState = STATE_STARTED_PAUSED_ATTEMPTED;
+ mALSProbeCallback.getProbe().disable();
UdfpsHelper.onFingerUp(getFreshDaemon());
+
if (getListener() != null) {
try {
getListener().onUdfpsPointerUp(getSensorId());
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintEnrollClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintEnrollClient.java
index 250e1328104b..dc705346f534 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintEnrollClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintEnrollClient.java
@@ -77,7 +77,7 @@ public class FingerprintEnrollClient extends EnrollClient<IBiometricsFingerprint
@NonNull
@Override
protected Callback wrapCallbackForStart(@NonNull Callback callback) {
- return new CompositeCallback(createALSCallback(), callback);
+ return new CompositeCallback(createALSCallback(true /* startWithClient */), callback);
}
@Override
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index ce481550e010..7a14df1831c5 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -3305,6 +3305,9 @@ public final class DisplayManagerService extends SystemService {
synchronized (mSyncRoot) {
final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(displayId);
+ if (display == null) {
+ return null;
+ }
final DisplayDevice device = display.getPrimaryDisplayDeviceLocked();
if (device == null) {
return null;
diff --git a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
index 016c5ed36f5f..14616754e160 100644
--- a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
+++ b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
@@ -744,7 +744,7 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
*
* @throws SecurityException when it's not...
*/
- protected final void assertCalledByPackageOwner(@NonNull String packageName) {
+ protected void assertCalledByPackageOwner(@NonNull String packageName) {
Objects.requireNonNull(packageName);
final int uid = Binder.getCallingUid();
final String[] packages = getContext().getPackageManager().getPackagesForUid(uid);
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 9fcc9a1b7994..6fb9e58a49d1 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -3230,7 +3230,7 @@ public class InputManagerService extends IInputManager.Stub
* Interface for the system to handle request from InputMonitors.
*/
private final class InputMonitorHost extends IInputMonitorHost.Stub {
- private final IBinder mToken;
+ private IBinder mToken;
InputMonitorHost(IBinder token) {
mToken = token;
@@ -3238,12 +3238,23 @@ public class InputManagerService extends IInputManager.Stub
@Override
public void pilferPointers() {
+ if (mToken == null) {
+ throw new IllegalStateException(
+ "Illegal call to pilferPointers after InputMonitorHost is disposed.");
+ }
nativePilferPointers(mPtr, mToken);
}
@Override
public void dispose() {
- nativeRemoveInputChannel(mPtr, mToken);
+ // We do not remove the input monitor here by calling nativeRemoveInputChannel because
+ // it causes a race in InputDispatcher between the removal of the InputChannel through
+ // that call and the InputChannel#dispose call (which causes an FD hangup) from the
+ // client (b/189135695).
+ //
+ // NOTE: This means the client is responsible for properly closing the InputMonitor by
+ // disposing the InputChannel and all its duplicates.
+ mToken = null;
}
}
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java
index 9d80b9c8b93e..2328dfc8b781 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java
@@ -116,8 +116,10 @@ public abstract class InputMethodManagerInternal {
*
* @param windowToken the window token that is now in control, or {@code null} if no client
* window is in control of the IME.
+ * @param imeParentChanged {@code true} when the window manager thoughts the IME surface parent
+ * will end up to change later, or {@code false} otherwise.
*/
- public abstract void reportImeControl(@Nullable IBinder windowToken);
+ public abstract void reportImeControl(@Nullable IBinder windowToken, boolean imeParentChanged);
/**
* Destroys the IME surface.
@@ -176,7 +178,8 @@ public abstract class InputMethodManagerInternal {
}
@Override
- public void reportImeControl(@Nullable IBinder windowToken) {
+ public void reportImeControl(@Nullable IBinder windowToken,
+ boolean imeParentChanged) {
}
@Override
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index fd0f1c38938f..dc955337fdbc 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -4937,13 +4937,19 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
return mInputManagerInternal.transferTouchFocus(sourceInputToken, curHostInputToken);
}
- private void reportImeControl(@Nullable IBinder windowToken) {
+ private void reportImeControl(@Nullable IBinder windowToken, boolean imeParentChanged) {
synchronized (mMethodMap) {
if (mCurFocusedWindow != windowToken) {
// mCurPerceptible was set by the focused window, but it is no longer in control,
// so we reset mCurPerceptible.
mCurPerceptible = true;
}
+ if (imeParentChanged) {
+ // Hide the IME method menu earlier when the IME surface parent will change in
+ // case seeing the dialog dismiss flickering during the next focused window
+ // starting the input connection.
+ mMenuController.hideInputMethodMenu();
+ }
}
}
@@ -5001,8 +5007,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
@Override
- public void reportImeControl(@Nullable IBinder windowToken) {
- mService.reportImeControl(windowToken);
+ public void reportImeControl(@Nullable IBinder windowToken, boolean imeParentChanged) {
+ mService.reportImeControl(windowToken, imeParentChanged);
}
@Override
diff --git a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
index ce195e6ddd64..aa4fa7c6f470 100644
--- a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
@@ -225,7 +225,8 @@ public final class MultiClientInputMethodManagerService {
}
@Override
- public void reportImeControl(@Nullable IBinder windowToken) {
+ public void reportImeControl(@Nullable IBinder windowToken,
+ boolean imeParentChanged) {
}
@Override
diff --git a/services/core/java/com/android/server/media/MediaServerUtils.java b/services/core/java/com/android/server/media/MediaServerUtils.java
index a4f11b2470f1..5fa2b1ceaae9 100644
--- a/services/core/java/com/android/server/media/MediaServerUtils.java
+++ b/services/core/java/com/android/server/media/MediaServerUtils.java
@@ -18,9 +18,6 @@ package com.android.server.media;
import android.content.Context;
import android.content.pm.PackageManager;
-import android.media.AudioAttributes;
-import android.media.AudioManager;
-import android.media.AudioPlaybackConfiguration;
import android.os.Binder;
import java.io.PrintWriter;
@@ -32,7 +29,7 @@ class MediaServerUtils {
/**
* Verify that caller holds {@link android.Manifest.permission#DUMP}.
*/
- static boolean checkDumpPermission(Context context, String tag, PrintWriter pw) {
+ public static boolean checkDumpPermission(Context context, String tag, PrintWriter pw) {
if (context.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
!= PackageManager.PERMISSION_GRANTED) {
pw.println("Permission Denial: can't dump " + tag + " from from pid="
@@ -43,18 +40,4 @@ class MediaServerUtils {
return true;
}
}
-
- /**
- * Whether the given stream is currently active or not.
- */
- static boolean isStreamActive(AudioManager audioManager, int stream) {
- for (AudioPlaybackConfiguration configuration
- : audioManager.getActivePlaybackConfigurations()) {
- AudioAttributes attributes = configuration.getAudioAttributes();
- if (attributes != null && attributes.getVolumeControlStream() == stream) {
- return configuration.isActive();
- }
- }
- return false;
- }
}
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index abcf4fb939e1..1525cd4da669 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -24,6 +24,7 @@ import android.content.Intent;
import android.content.pm.ParceledListSlice;
import android.media.AudioAttributes;
import android.media.AudioManager;
+import android.media.AudioSystem;
import android.media.MediaMetadata;
import android.media.Rating;
import android.media.VolumeProvider;
@@ -515,7 +516,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR
public void run() {
try {
if (useSuggested) {
- if (MediaServerUtils.isStreamActive(mAudioManager, stream)) {
+ if (AudioSystem.isStreamActive(stream, 0)) {
mAudioManager.adjustSuggestedStreamVolumeForUid(stream,
direction, flags, opPackageName, uid, pid,
mContext.getApplicationInfo().targetSdkVersion);
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index 491cd181b6f9..b477ea353c25 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -42,6 +42,7 @@ import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.media.AudioManager;
import android.media.AudioPlaybackConfiguration;
+import android.media.AudioSystem;
import android.media.IRemoteSessionCallback;
import android.media.MediaCommunicationManager;
import android.media.Session2Token;
@@ -2147,7 +2148,7 @@ public class MediaSessionService extends SystemService implements Monitor {
boolean preferSuggestedStream = false;
if (isValidLocalStreamType(suggestedStream)
- && MediaServerUtils.isStreamActive(mAudioManager, suggestedStream)) {
+ && AudioSystem.isStreamActive(suggestedStream, 0)) {
preferSuggestedStream = true;
}
if (session == null || preferSuggestedStream) {
@@ -2156,8 +2157,7 @@ public class MediaSessionService extends SystemService implements Monitor {
+ ". flags=" + flags + ", preferSuggestedStream="
+ preferSuggestedStream + ", session=" + session);
}
- if (musicOnly && !MediaServerUtils.isStreamActive(mAudioManager,
- AudioManager.STREAM_MUSIC)) {
+ if (musicOnly && !AudioSystem.isStreamActive(AudioManager.STREAM_MUSIC, 0)) {
if (DEBUG_KEY_EVENT) {
Log.d(TAG, "Nothing is playing on the music stream. Skipping volume event,"
+ " flags=" + flags);
diff --git a/services/core/java/com/android/server/media/MediaSessionStack.java b/services/core/java/com/android/server/media/MediaSessionStack.java
index 50eed19389dc..c4c21df746b3 100644
--- a/services/core/java/com/android/server/media/MediaSessionStack.java
+++ b/services/core/java/com/android/server/media/MediaSessionStack.java
@@ -325,7 +325,8 @@ class MediaSessionStack {
int size = records.size();
for (int i = 0; i < size; i++) {
MediaSessionRecord record = records.get(i);
- if (record.checkPlaybackActiveState(true)) {
+ // Do not send the volume key events to remote sessions.
+ if (record.checkPlaybackActiveState(true) && record.isPlaybackTypeLocal()) {
mCachedVolumeDefault = record;
return record;
}
diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java
index 954e65c1c254..097b0711eff7 100644
--- a/services/core/java/com/android/server/net/NetworkStatsService.java
+++ b/services/core/java/com/android/server/net/NetworkStatsService.java
@@ -289,8 +289,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
private String mActiveIface;
/** Set of any ifaces associated with mobile networks since boot. */
- @GuardedBy("mStatsLock")
- private String[] mMobileIfaces = new String[0];
+ private volatile String[] mMobileIfaces = new String[0];
/** Set of all ifaces currently used by traffic that does not explicitly specify a Network. */
@GuardedBy("mStatsLock")
@@ -935,7 +934,12 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
@Override
public String[] getMobileIfaces() {
- return mMobileIfaces;
+ // TODO (b/192758557): Remove debug log.
+ if (ArrayUtils.contains(mMobileIfaces, null)) {
+ throw new NullPointerException(
+ "null element in mMobileIfaces: " + Arrays.toString(mMobileIfaces));
+ }
+ return mMobileIfaces.clone();
}
@Override
@@ -1084,11 +1088,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
}
@Override
- public long getIfaceStats(String iface, int type) {
- if (iface == null) {
- Log.e(TAG, "getIfaceStats called with null iface, returning -1");
- return -1;
- }
+ public long getIfaceStats(@NonNull String iface, int type) {
+ Objects.requireNonNull(iface);
long nativeIfaceStats = nativeGetIfaceStat(iface, type, checkBpfStatsEnable());
if (nativeIfaceStats == -1) {
return nativeIfaceStats;
@@ -1386,7 +1387,12 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
}
}
- mMobileIfaces = mobileIfaces.toArray(new String[mobileIfaces.size()]);
+ mMobileIfaces = mobileIfaces.toArray(new String[0]);
+ // TODO (b/192758557): Remove debug log.
+ if (ArrayUtils.contains(mMobileIfaces, null)) {
+ throw new NullPointerException(
+ "null element in mMobileIfaces: " + Arrays.toString(mMobileIfaces));
+ }
}
private static int getSubIdForMobile(@NonNull NetworkStateSnapshot state) {
diff --git a/services/core/java/com/android/server/pm/IncrementalStates.java b/services/core/java/com/android/server/pm/IncrementalStates.java
index 7627281d2188..3101ca7f9f6b 100644
--- a/services/core/java/com/android/server/pm/IncrementalStates.java
+++ b/services/core/java/com/android/server/pm/IncrementalStates.java
@@ -118,12 +118,19 @@ public final class IncrementalStates {
* @param progress Value between [0, 1].
*/
public void setProgress(float progress) {
+ final boolean oldLoadingState;
final boolean newLoadingState;
synchronized (mLock) {
- updateProgressLocked(progress);
+ oldLoadingState = mLoadingState.isLoading();
+ if (oldLoadingState) {
+ // Due to asynchronous progress reporting, incomplete progress might be received
+ // after the app is migrated off incremental. Ignore such progress updates.
+ updateProgressLocked(progress);
+ }
newLoadingState = mLoadingState.isLoading();
}
- if (!newLoadingState) {
+ if (oldLoadingState && !newLoadingState) {
+ // Only report the state change when loading state changes from true to false
onLoadingStateChanged();
}
}
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index 2a5a7210635b..08a67d7f4bb5 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -3347,13 +3347,15 @@ public class PermissionManagerService extends IPermissionManager.Stub {
}
@Override
- public void registerAttributionSource(@NonNull AttributionSource source) {
- mAttributionSourceRegistry.registerAttributionSource(source);
+ public void registerAttributionSource(@NonNull AttributionSourceState source) {
+ mAttributionSourceRegistry
+ .registerAttributionSource(new AttributionSource(source));
}
@Override
- public boolean isRegisteredAttributionSource(@NonNull AttributionSource source) {
- return mAttributionSourceRegistry.isRegisteredAttributionSource(source);
+ public boolean isRegisteredAttributionSource(@NonNull AttributionSourceState source) {
+ return mAttributionSourceRegistry
+ .isRegisteredAttributionSource(new AttributionSource(source));
}
@Override
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 0accc2bfb10b..3bdf9da5bd4d 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -3862,9 +3862,13 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
mCameraGestureTriggered = false;
final MutableBoolean outLaunched = new MutableBoolean(false);
- mGestureLauncherService.interceptPowerKeyDown(event, interactive, outLaunched);
+ final boolean intercept =
+ mGestureLauncherService.interceptPowerKeyDown(event, interactive, outLaunched);
if (!outLaunched.value) {
- return false;
+ // If GestureLauncherService intercepted the power key, but didn't launch camera app,
+ // we should still return the intercept result. This prevents the single key gesture
+ // detector from processing the power key later on.
+ return intercept;
}
mCameraGestureTriggered = true;
if (mRequestedOrSleepingDefaultDisplay) {
diff --git a/services/core/java/com/android/server/vcn/Vcn.java b/services/core/java/com/android/server/vcn/Vcn.java
index 9c3721b15f32..382398a210bb 100644
--- a/services/core/java/com/android/server/vcn/Vcn.java
+++ b/services/core/java/com/android/server/vcn/Vcn.java
@@ -596,7 +596,12 @@ public class Vcn extends Handler {
/** Retrieves the network score for a VCN Network */
// Package visibility for use in VcnGatewayConnection and VcnNetworkProvider
static NetworkScore getNetworkScore() {
- return new NetworkScore.Builder().setLegacyInt(VCN_LEGACY_SCORE_INT).build();
+ // TODO(b/193687515): Stop setting TRANSPORT_PRIMARY, define a TRANSPORT_VCN, and set in
+ // NetworkOffer/NetworkAgent.
+ return new NetworkScore.Builder()
+ .setLegacyInt(VCN_LEGACY_SCORE_INT)
+ .setTransportPrimary(true)
+ .build();
}
/** Callback used for passing status signals from a VcnGatewayConnection to its managing Vcn. */
diff --git a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
index 3c0a05b6edf7..450257fcdecb 100644
--- a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
+++ b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
@@ -195,6 +195,7 @@ public class VcnGatewayConnection extends StateMachine {
@VisibleForTesting(visibility = Visibility.PRIVATE)
static final int SAFEMODE_TIMEOUT_SECONDS = 30;
+ private static final int SAFEMODE_TIMEOUT_SECONDS_TEST_MODE = 10;
private interface EventInfo {}
@@ -1082,7 +1083,9 @@ public class VcnGatewayConnection extends StateMachine {
createScheduledAlarm(
SAFEMODE_TIMEOUT_ALARM,
delayedMessage,
- TimeUnit.SECONDS.toMillis(SAFEMODE_TIMEOUT_SECONDS));
+ mVcnContext.isInTestMode()
+ ? TimeUnit.SECONDS.toMillis(SAFEMODE_TIMEOUT_SECONDS_TEST_MODE)
+ : TimeUnit.SECONDS.toMillis(SAFEMODE_TIMEOUT_SECONDS));
}
private void cancelSafeModeAlarm() {
diff --git a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
index a7228a36872d..afe6345f096f 100644
--- a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
@@ -941,9 +941,11 @@ class ActivityMetricsLogger {
// This will avoid any races with other operations that modify the ActivityRecord.
final TransitionInfoSnapshot infoSnapshot = new TransitionInfoSnapshot(info);
if (info.isInterestingToLoggerAndObserver()) {
+ final long timestamp = info.mTransitionStartTimeNs;
+ final long uptime = info.mTransitionDeviceUptimeMs;
+ final int transitionDelay = info.mCurrentTransitionDelayMs;
mLoggerHandler.post(() -> logAppTransition(
- info.mTransitionDeviceUptimeMs, info.mCurrentTransitionDelayMs,
- infoSnapshot, isHibernating));
+ timestamp, uptime, transitionDelay, infoSnapshot, isHibernating));
}
mLoggerHandler.post(() -> logAppDisplayed(infoSnapshot));
if (info.mPendingFullyDrawn != null) {
@@ -954,8 +956,8 @@ class ActivityMetricsLogger {
}
// This gets called on another thread without holding the activity manager lock.
- private void logAppTransition(long transitionDeviceUptimeMs, int currentTransitionDelayMs,
- TransitionInfoSnapshot info, boolean isHibernating) {
+ private void logAppTransition(long transitionStartTimeNs, long transitionDeviceUptimeMs,
+ int currentTransitionDelayMs, TransitionInfoSnapshot info, boolean isHibernating) {
final LogMaker builder = new LogMaker(APP_TRANSITION);
builder.setPackageName(info.packageName);
builder.setType(info.type);
@@ -1006,7 +1008,7 @@ class ActivityMetricsLogger {
info.launchedActivityName,
info.launchedActivityLaunchedFromPackage,
isInstantApp,
- transitionDeviceUptimeMs,
+ 0 /* deprecated transitionDeviceUptimeMs */,
info.reason,
currentTransitionDelayMs,
info.startingWindowDelayMs,
@@ -1020,7 +1022,8 @@ class ActivityMetricsLogger {
isHibernating,
isIncremental,
isLoading,
- info.launchedActivityName.hashCode());
+ info.launchedActivityName.hashCode(),
+ TimeUnit.NANOSECONDS.toMillis(transitionStartTimeNs));
if (DEBUG_METRICS) {
Slog.i(TAG, String.format("APP_START_OCCURRED(%s, %s, %s, %s, %s)",
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 825d480cd941..03085af144e6 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -5133,6 +5133,12 @@ public final class ActivityRecord extends WindowToken implements WindowManagerSe
void notifyAppStopped() {
ProtoLog.v(WM_DEBUG_ADD_REMOVE, "notifyAppStopped: %s", this);
mAppStopped = true;
+ // This is to fix the edge case that auto-enter-pip is finished in Launcher but app calls
+ // setAutoEnterEnabled(false) and transitions to STOPPED state, see b/191930787.
+ // Clear any surface transactions and content overlay in this case.
+ if (task != null && task.mLastRecentsAnimationTransaction != null) {
+ task.clearLastRecentsAnimationTransaction(true /* forceRemoveOverlay */);
+ }
// Reset the last saved PiP snap fraction on app stop.
mDisplayContent.mPinnedTaskController.onActivityHidden(mActivityComponent);
mDisplayContent.mUnknownAppVisibilityController.appRemovedOrHidden(this);
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 3144c87e8314..4c1142257218 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -61,6 +61,7 @@ import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
+import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
import static android.view.WindowManager.LayoutParams.FLAG_SPLIT_TOUCH;
import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN;
@@ -728,12 +729,19 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
// When switching the app task, we keep the IME window visibility for better
// transitioning experiences.
- // However, in case IME created a child window without dismissing during the task
- // switching to keep the window focus because IME window has higher window hierarchy,
- // we don't give it focus if the next IME layering target doesn't request IME visible.
- if (w.mIsImWindow && w.isChildWindow() && (mImeLayeringTarget == null
+ // However, in case IME created a child window or the IME selection dialog without
+ // dismissing during the task switching to keep the window focus because IME window has
+ // higher window hierarchy, we don't give it focus if the next IME layering target
+ // doesn't request IME visible.
+ if (w.mIsImWindow && (mImeLayeringTarget == null
|| !mImeLayeringTarget.getRequestedVisibility(ITYPE_IME))) {
- return false;
+ if (w.mAttrs.type == TYPE_INPUT_METHOD_DIALOG) {
+ return false;
+ }
+
+ if (w.isChildWindow()) {
+ return false;
+ }
}
final ActivityRecord activity = w.mActivityRecord;
@@ -3977,7 +3985,9 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
// Update Ime parent when IME insets leash created or the new IME layering target might
// updated from setImeLayeringTarget, which is the best time that default IME visibility
// has been settled down after IME control target changed.
- if (prevImeControlTarget != mImeControlTarget || forceUpdateImeParent) {
+ final boolean imeParentChanged =
+ prevImeControlTarget != mImeControlTarget || forceUpdateImeParent;
+ if (imeParentChanged) {
updateImeParent();
}
@@ -3985,7 +3995,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
final IBinder token = win != null ? win.mClient.asBinder() : null;
// Note: not allowed to call into IMMS with the WM lock held, hence the post.
mWmService.mH.post(() ->
- InputMethodManagerInternal.get().reportImeControl(token)
+ InputMethodManagerInternal.get().reportImeControl(token, imeParentChanged)
);
}
@@ -5829,7 +5839,9 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
return false; /* continue */
}
}
-
+ if (nextWindow.isSecureLocked()) {
+ return false; /* continue */
+ }
return true; /* stop, match found */
}
});
diff --git a/services/core/java/com/android/server/wm/FadeRotationAnimationController.java b/services/core/java/com/android/server/wm/FadeRotationAnimationController.java
index 53b6b41db2ba..eab3f108d17a 100644
--- a/services/core/java/com/android/server/wm/FadeRotationAnimationController.java
+++ b/services/core/java/com/android/server/wm/FadeRotationAnimationController.java
@@ -66,10 +66,8 @@ public class FadeRotationAnimationController extends FadeAnimationController {
} else {
mNavBarToken = null;
}
- // Do not fade notification shade when running fixed rotation (not frozen) because it may
- // need to animate with the launching app.
- final WindowState notificationShade = mFrozenTimeoutRunnable == null
- ? displayPolicy.getNotificationShade() : null;
+ // Collect the target windows to fade out. The display won't wait for them to unfreeze.
+ final WindowState notificationShade = displayPolicy.getNotificationShade();
displayContent.forAllWindows(w -> {
if (w.mActivityRecord == null && w.mHasSurface && !w.mForceSeamlesslyRotate
&& !w.mIsWallpaper && !w.mIsImWindow && w != navigationBar
diff --git a/services/core/java/com/android/server/wm/InsetsPolicy.java b/services/core/java/com/android/server/wm/InsetsPolicy.java
index f2f192686ad5..11a0fba4b015 100644
--- a/services/core/java/com/android/server/wm/InsetsPolicy.java
+++ b/services/core/java/com/android/server/wm/InsetsPolicy.java
@@ -32,6 +32,10 @@ import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_B
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION;
+import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_RECENTS;
+import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
+import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.StatusBarManager;
@@ -211,7 +215,7 @@ class InsetsPolicy {
InsetsState getInsetsForWindow(WindowState target) {
final InsetsState originalState = mStateController.getInsetsForWindow(target);
final InsetsState state = adjustVisibilityForTransientTypes(originalState);
- return target.mIsImWindow ? adjustVisibilityForIme(state, state == originalState) : state;
+ return adjustVisibilityForIme(target, state, state == originalState);
}
/**
@@ -241,16 +245,38 @@ class InsetsPolicy {
return state;
}
- // Navigation bar insets is always visible to IME.
- private static InsetsState adjustVisibilityForIme(InsetsState originalState,
+ private InsetsState adjustVisibilityForIme(WindowState w, InsetsState originalState,
boolean copyState) {
- final InsetsSource originalNavSource = originalState.peekSource(ITYPE_NAVIGATION_BAR);
- if (originalNavSource != null && !originalNavSource.isVisible()) {
- final InsetsState state = copyState ? new InsetsState(originalState) : originalState;
- final InsetsSource navSource = new InsetsSource(originalNavSource);
- navSource.setVisible(true);
- state.addSource(navSource);
- return state;
+ if (w.mIsImWindow) {
+ // Navigation bar insets is always visible to IME.
+ final InsetsSource originalNavSource = originalState.peekSource(ITYPE_NAVIGATION_BAR);
+ if (originalNavSource != null && !originalNavSource.isVisible()) {
+ final InsetsState state = copyState ? new InsetsState(originalState)
+ : originalState;
+ final InsetsSource navSource = new InsetsSource(originalNavSource);
+ navSource.setVisible(true);
+ state.addSource(navSource);
+ return state;
+ }
+ } else if (w.mActivityRecord != null && !w.mActivityRecord.mLastImeShown) {
+ // During switching tasks with gestural navigation, if the IME is attached to
+ // one app window on that time, even the next app window is behind the IME window,
+ // conceptually the window should not receive the IME insets if the next window is
+ // not eligible IME requester and ready to show IME on top of it.
+ final boolean shouldImeAttachedToApp = mDisplayContent.shouldImeAttachedToApp();
+ final InsetsSource originalImeSource = originalState.peekSource(ITYPE_IME);
+
+ if (originalImeSource != null && shouldImeAttachedToApp
+ && (w.isAnimating(PARENTS | TRANSITION, ANIMATION_TYPE_RECENTS)
+ || !w.getRequestedVisibility(ITYPE_IME))) {
+ final InsetsState state = copyState ? new InsetsState(originalState)
+ : originalState;
+
+ final InsetsSource imeSource = new InsetsSource(originalImeSource);
+ imeSource.setVisible(false);
+ state.addSource(imeSource);
+ return state;
+ }
}
return originalState;
}
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index b50014203cb1..5215de12af1c 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -2159,7 +2159,7 @@ public class RootWindowContainer extends WindowContainer<DisplayContent>
rootTask.setLastRecentsAnimationTransaction(
task.mLastRecentsAnimationTransaction,
task.mLastRecentsAnimationOverlay);
- task.clearLastRecentsAnimationTransaction();
+ task.clearLastRecentsAnimationTransaction(false /* forceRemoveOverlay */);
}
// There are multiple activities in the task and moving the top activity should
@@ -2214,16 +2214,17 @@ public class RootWindowContainer extends WindowContainer<DisplayContent>
ensureActivitiesVisible(null, 0, false /* preserveWindows */);
resumeFocusedTasksTopActivities();
- notifyActivityPipModeChanged(r);
+ notifyActivityPipModeChanged(r.getTask(), r);
}
/**
* Notifies when an activity enters or leaves PIP mode.
*
+ * @param task the task of {@param r}
* @param r indicates the activity currently in PIP, can be null to indicate no activity is
* currently in PIP mode.
*/
- void notifyActivityPipModeChanged(@Nullable ActivityRecord r) {
+ void notifyActivityPipModeChanged(@NonNull Task task, @Nullable ActivityRecord r) {
final boolean inPip = r != null;
if (inPip) {
mService.getTaskChangeNotificationController().notifyActivityPinned(r);
@@ -2231,6 +2232,9 @@ public class RootWindowContainer extends WindowContainer<DisplayContent>
mService.getTaskChangeNotificationController().notifyActivityUnpinned();
}
mWindowManager.mPolicy.setPipVisibilityLw(inPip);
+ mWmService.mTransactionFactory.get()
+ .setTrustedOverlay(task.getSurfaceControl(), inPip)
+ .apply();
}
void executeAppTransitionForAllDisplay() {
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 57efd0ffe5ee..251eeb1af268 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -1447,7 +1447,7 @@ class Task extends WindowContainer<WindowContainer> {
&& (newParent == null || !newParent.inPinnedWindowingMode())) {
// Notify if a task from the root pinned task is being removed
// (or moved depending on the mode).
- mRootWindowContainer.notifyActivityPipModeChanged(null);
+ mRootWindowContainer.notifyActivityPipModeChanged(this, null);
}
}
@@ -4177,7 +4177,9 @@ class Task extends WindowContainer<WindowContainer> {
StartingWindowInfo getStartingWindowInfo(ActivityRecord activity) {
final StartingWindowInfo info = new StartingWindowInfo();
info.taskInfo = getTaskInfo();
-
+ info.targetActivityInfo = info.taskInfo.topActivityInfo != null
+ && activity.info != info.taskInfo.topActivityInfo
+ ? activity.info : null;
info.isKeyguardOccluded =
mAtmService.mKeyguardController.isDisplayOccluded(DEFAULT_DISPLAY);
@@ -5404,7 +5406,7 @@ class Task extends WindowContainer<WindowContainer> {
: WINDOWING_MODE_FULLSCREEN;
}
if (currentMode == WINDOWING_MODE_PINNED) {
- mRootWindowContainer.notifyActivityPipModeChanged(null);
+ mRootWindowContainer.notifyActivityPipModeChanged(this, null);
}
if (likelyResolvedMode == WINDOWING_MODE_PINNED) {
// In the case that we've disabled affecting the SysUI flags as a part of seamlessly
@@ -7676,7 +7678,10 @@ class Task extends WindowContainer<WindowContainer> {
mLastRecentsAnimationOverlay = overlay;
}
- void clearLastRecentsAnimationTransaction() {
+ void clearLastRecentsAnimationTransaction(boolean forceRemoveOverlay) {
+ if (forceRemoveOverlay && mLastRecentsAnimationOverlay != null) {
+ getPendingTransaction().remove(mLastRecentsAnimationOverlay);
+ }
mLastRecentsAnimationTransaction = null;
mLastRecentsAnimationOverlay = null;
// reset also the crop and transform introduced by mLastRecentsAnimationTransaction
diff --git a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
index a254f68e8bed..16afef57d31e 100644
--- a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
@@ -3002,7 +3002,8 @@ public class AlarmManagerServiceTest {
final PendingIntent pi = getNewMockPendingIntent();
setTestAlarm(ELAPSED_REALTIME, mNowElapsedTest + i, pi);
- verify(() -> MetricsHelper.pushAlarmScheduled(argThat(a -> a.matches(pi, null))));
+ verify(() -> MetricsHelper.pushAlarmScheduled(argThat(a -> a.matches(pi, null)),
+ anyInt()));
}
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/ApplicationExitInfoTest.java b/services/tests/mockingservicestests/src/com/android/server/am/ApplicationExitInfoTest.java
index 803a0c10fe1c..26b5218d2ab4 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/ApplicationExitInfoTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/ApplicationExitInfoTest.java
@@ -1003,7 +1003,7 @@ public class ApplicationExitInfoTest {
dummyPackageName, dummyClassName), "", definingUid));
}
app.mServices.setConnectionGroup(connectionGroup);
- app.mState.setSetProcState(procState);
+ app.mState.setReportedProcState(procState);
app.mProfile.setLastMemInfo(spy(new Debug.MemoryInfo()));
app.mProfile.setLastPss(pss);
app.mProfile.setLastRss(rss);
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java
index b2471fac8b45..56bcb834dbfd 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java
@@ -885,6 +885,7 @@ public class JobSchedulerServiceTest {
// * E jobs test that expedited jobs don't skip the line when the app has no regular jobs
// * F jobs test correct expedited/regular ordering doesn't push jobs too high in list
// * G jobs test correct ordering for regular jobs
+ // * H job tests correct behavior when enqueue times are the same
JobStatus rA1 = createJobStatus("testPendingJobSorting", createJobInfo(1), 1);
JobStatus rB2 = createJobStatus("testPendingJobSorting", createJobInfo(2), 2);
JobStatus eC3 = createJobStatus("testPendingJobSorting",
@@ -896,6 +897,7 @@ public class JobSchedulerServiceTest {
createJobInfo(6).setExpedited(true), 2);
JobStatus eA7 = createJobStatus("testPendingJobSorting",
createJobInfo(7).setExpedited(true), 1);
+ JobStatus rH8 = createJobStatus("testPendingJobSorting", createJobInfo(8), 14);
JobStatus rF8 = createJobStatus("testPendingJobSorting", createJobInfo(8), 6);
JobStatus eF9 = createJobStatus("testPendingJobSorting",
createJobInfo(9).setExpedited(true), 6);
@@ -915,6 +917,7 @@ public class JobSchedulerServiceTest {
eB6.enqueueTime = 6;
eA7.enqueueTime = 7;
rF8.enqueueTime = 8;
+ rH8.enqueueTime = 8;
eF9.enqueueTime = 9;
rC10.enqueueTime = 10;
eC11.enqueueTime = 11;
@@ -931,6 +934,7 @@ public class JobSchedulerServiceTest {
mService.mPendingJobs.add(rD4);
mService.mPendingJobs.add(eA7);
mService.mPendingJobs.add(rG12);
+ mService.mPendingJobs.add(rH8);
mService.mPendingJobs.add(rF8);
mService.mPendingJobs.add(eB6);
mService.mPendingJobs.add(eE14);
@@ -943,7 +947,7 @@ public class JobSchedulerServiceTest {
mService.mPendingJobs.sort(mService.mPendingJobComparator);
final JobStatus[] expectedOrder = new JobStatus[]{
- eA7, rA1, eB6, rB2, eC3, rD4, eE5, eF9, rF8, eC11, rC10, rG12, rG13, eE14};
+ eA7, rA1, eB6, rB2, eC3, rD4, eE5, eF9, rH8, rF8, eC11, rC10, rG12, rG13, eE14};
for (int i = 0; i < expectedOrder.length; ++i) {
assertEquals("List wasn't correctly sorted @ index " + i,
expectedOrder[i].getJobId(), mService.mPendingJobs.get(i).getJobId());
@@ -995,7 +999,7 @@ public class JobSchedulerServiceTest {
for (int i = 0; i < 2500; ++i) {
JobStatus job = createJobStatus("testPendingJobSorting_Random",
createJobInfo(i).setExpedited(random.nextBoolean()), random.nextInt(250));
- job.enqueueTime = Math.abs(random.nextInt(1_000_000));
+ job.enqueueTime = random.nextInt(1_000_000);
mService.mPendingJobs.add(job);
mService.mPendingJobComparator.refreshLocked();
@@ -1023,18 +1027,48 @@ public class JobSchedulerServiceTest {
@Test
public void testPendingJobSortingTransitivity() {
- Random random = new Random(1); // Always use the same series of pseudo random values.
+ // Always use the same series of pseudo random values.
+ for (int seed : new int[]{1337, 7357, 606, 6357, 41106010, 3, 2, 1}) {
+ Random random = new Random(seed);
+
+ mService.mPendingJobs.clear();
+
+ for (int i = 0; i < 300; ++i) {
+ JobStatus job = createJobStatus("testPendingJobSortingTransitivity",
+ createJobInfo(i).setExpedited(random.nextBoolean()), random.nextInt(50));
+ job.enqueueTime = random.nextInt(1_000_000);
+ job.overrideState = random.nextInt(4);
+ mService.mPendingJobs.add(job);
+ }
- mService.mPendingJobs.clear();
+ verifyPendingJobComparatorTransitivity();
+ }
+ }
- for (int i = 0; i < 250; ++i) {
- JobStatus job = createJobStatus("testPendingJobSortingTransitivity",
- createJobInfo(i).setExpedited(random.nextBoolean()), random.nextInt(50));
- job.enqueueTime = Math.abs(random.nextInt(1_000_000));
- job.overrideState = random.nextInt(4);
- mService.mPendingJobs.add(job);
+ @Test
+ public void testPendingJobSortingTransitivity_Concentrated() {
+ // Always use the same series of pseudo random values.
+ for (int seed : new int[]{1337, 6000, 637739, 6357, 1, 7, 13}) {
+ Random random = new Random(seed);
+
+ mService.mPendingJobs.clear();
+
+ for (int i = 0; i < 300; ++i) {
+ JobStatus job = createJobStatus("testPendingJobSortingTransitivity_Concentrated",
+ createJobInfo(i).setExpedited(random.nextFloat() < .03),
+ random.nextInt(20));
+ job.enqueueTime = random.nextInt(250);
+ job.overrideState = random.nextFloat() < .01
+ ? JobStatus.OVERRIDE_SORTING : JobStatus.OVERRIDE_NONE;
+ mService.mPendingJobs.add(job);
+ Log.d(TAG, sortedJobToString(job));
+ }
+
+ verifyPendingJobComparatorTransitivity();
}
+ }
+ private void verifyPendingJobComparatorTransitivity() {
mService.mPendingJobComparator.refreshLocked();
for (int i = 0; i < mService.mPendingJobs.size(); ++i) {
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/gestures/TouchExplorerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/gestures/TouchExplorerTest.java
index 7bf0bb873fc3..57ee7aa522c2 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/gestures/TouchExplorerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/gestures/TouchExplorerTest.java
@@ -145,7 +145,6 @@ public class TouchExplorerTest {
}
mContext = InstrumentationRegistry.getContext();
mTouchSlop = ViewConfiguration.get(mContext).getScaledTouchSlop();
- AccessibilityManagerService ams = new AccessibilityManagerService(mContext);
mCaptor = new EventCaptor();
mHandler = new TestHandler();
mTouchExplorer = new TouchExplorer(mContext, mMockAms, null, mHandler);
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java
index 1fe41234849f..8592166aae15 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java
@@ -360,7 +360,8 @@ public class BiometricSchedulerTest {
false /* restricted */, TAG, 1 /* cookie */, false /* requireConfirmation */,
TEST_SENSOR_ID, true /* isStrongBiometric */, 0 /* statsModality */,
0 /* statsClient */, null /* taskStackListener */, mock(LockoutTracker.class),
- false /* isKeyguard */, true /* shouldVibrate */);
+ false /* isKeyguard */, true /* shouldVibrate */,
+ false /* isKeyguardBypassEnabled */);
}
@Override
@@ -388,7 +389,8 @@ public class BiometricSchedulerTest {
false /* restricted */, TAG, 1 /* cookie */, false /* requireConfirmation */,
TEST_SENSOR_ID, true /* isStrongBiometric */, 0 /* statsModality */,
0 /* statsClient */, null /* taskStackListener */, mock(LockoutTracker.class),
- false /* isKeyguard */, true /* shouldVibrate */);
+ false /* isKeyguard */, true /* shouldVibrate */,
+ false /* isKeyguardBypassEnabled */);
}
@Override
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/CoexCoordinatorTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/CoexCoordinatorTest.java
index a169ebd0320f..7f5f3c2df077 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/CoexCoordinatorTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/CoexCoordinatorTest.java
@@ -17,6 +17,7 @@
package com.android.server.biometrics.sensors;
import static com.android.server.biometrics.sensors.BiometricScheduler.SENSOR_TYPE_FACE;
+import static com.android.server.biometrics.sensors.BiometricScheduler.SENSOR_TYPE_FP_OTHER;
import static com.android.server.biometrics.sensors.BiometricScheduler.SENSOR_TYPE_UDFPS;
import static junit.framework.Assert.assertEquals;
@@ -69,6 +70,7 @@ public class CoexCoordinatorTest {
mCoexCoordinator = CoexCoordinator.getInstance();
mCoexCoordinator.setAdvancedLogicEnabled(true);
+ mCoexCoordinator.setFaceHapticDisabledWhenNonBypass(true);
}
@Test
@@ -150,12 +152,76 @@ public class CoexCoordinatorTest {
mCoexCoordinator.onAuthenticationSucceeded(0 /* currentTimeMillis */, faceClient,
mCallback);
- verify(mCallback).sendHapticFeedback();
+ // Haptics tested in #testKeyguard_bypass_haptics. Let's leave this commented out (instead
+ // of removed) to keep this context.
+ // verify(mCallback).sendHapticFeedback();
verify(mCallback).sendAuthenticationResult(eq(true) /* addAuthTokenIfStrong */);
verify(mCallback).handleLifecycleAfterAuth();
}
@Test
+ public void testKeyguard_faceAuthSuccess_nonBypass_udfpsRunning_noHaptics() {
+ testKeyguard_bypass_haptics(false /* bypassEnabled */,
+ true /* faceAccepted */,
+ false /* shouldReceiveHaptics */);
+ }
+
+ @Test
+ public void testKeyguard_faceAuthReject_nonBypass_udfpsRunning_noHaptics() {
+ testKeyguard_bypass_haptics(false /* bypassEnabled */,
+ false /* faceAccepted */,
+ false /* shouldReceiveHaptics */);
+ }
+
+ @Test
+ public void testKeyguard_faceAuthSuccess_bypass_udfpsRunning_haptics() {
+ testKeyguard_bypass_haptics(true /* bypassEnabled */,
+ true /* faceAccepted */,
+ true /* shouldReceiveHaptics */);
+ }
+
+ @Test
+ public void testKeyguard_faceAuthReject_bypass_udfpsRunning_haptics() {
+ testKeyguard_bypass_haptics(true /* bypassEnabled */,
+ false /* faceAccepted */,
+ true /* shouldReceiveHaptics */);
+ }
+
+ private void testKeyguard_bypass_haptics(boolean bypassEnabled, boolean faceAccepted,
+ boolean shouldReceiveHaptics) {
+ mCoexCoordinator.reset();
+
+ AuthenticationClient<?> faceClient = mock(AuthenticationClient.class);
+ when(faceClient.isKeyguard()).thenReturn(true);
+ when(faceClient.isKeyguardBypassEnabled()).thenReturn(bypassEnabled);
+
+ AuthenticationClient<?> udfpsClient = mock(AuthenticationClient.class,
+ withSettings().extraInterfaces(Udfps.class));
+ when(udfpsClient.isKeyguard()).thenReturn(true);
+ when(((Udfps) udfpsClient).isPointerDown()).thenReturn(false);
+
+ mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, faceClient);
+ mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_UDFPS, udfpsClient);
+
+ if (faceAccepted) {
+ mCoexCoordinator.onAuthenticationSucceeded(0 /* currentTimeMillis */, faceClient,
+ mCallback);
+ } else {
+ mCoexCoordinator.onAuthenticationRejected(0 /* currentTimeMillis */, faceClient,
+ LockoutTracker.LOCKOUT_NONE, mCallback);
+ }
+
+ if (shouldReceiveHaptics) {
+ verify(mCallback).sendHapticFeedback();
+ } else {
+ verify(mCallback, never()).sendHapticFeedback();
+ }
+
+ verify(mCallback).sendAuthenticationResult(eq(faceAccepted) /* addAuthTokenIfStrong */);
+ verify(mCallback).handleLifecycleAfterAuth();
+ }
+
+ @Test
public void testKeyguard_faceAuth_udfpsTouching_faceSuccess_thenUdfpsRejectedWithinBounds() {
testKeyguard_faceAuth_udfpsTouching_faceSuccess(false /* thenUdfpsAccepted */,
0 /* udfpsRejectedAfterMs */);
@@ -293,12 +359,13 @@ public class CoexCoordinatorTest {
}
@Test
- public void testKeyguard_udfpsRejected_thenFaceRejected() {
+ public void testKeyguard_udfpsRejected_thenFaceRejected_noKeyguardBypass() {
mCoexCoordinator.reset();
AuthenticationClient<?> faceClient = mock(AuthenticationClient.class);
when(faceClient.isKeyguard()).thenReturn(true);
when(faceClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED);
+ when(faceClient.isKeyguardBypassEnabled()).thenReturn(false); // TODO: also test "true" case
AuthenticationClient<?> udfpsClient = mock(AuthenticationClient.class,
withSettings().extraInterfaces(Udfps.class));
@@ -311,8 +378,9 @@ public class CoexCoordinatorTest {
mCoexCoordinator.onAuthenticationRejected(0 /* currentTimeMillis */, udfpsClient,
LockoutTracker.LOCKOUT_NONE, mCallback);
- // Client becomes paused, but finger does not necessarily lift, since we suppress the haptic
- when(udfpsClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED_PAUSED);
+ // Auth was attempted
+ when(udfpsClient.getState())
+ .thenReturn(AuthenticationClient.STATE_STARTED_PAUSED_ATTEMPTED);
verify(mCallback, never()).sendHapticFeedback();
verify(mCallback).handleLifecycleAfterAuth();
@@ -327,6 +395,49 @@ public class CoexCoordinatorTest {
}
@Test
+ public void testKeyguard_capacitiveAccepted_whenFaceScanning() {
+ mCoexCoordinator.reset();
+
+ AuthenticationClient<?> faceClient = mock(AuthenticationClient.class);
+ when(faceClient.isKeyguard()).thenReturn(true);
+ when(faceClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED);
+
+ AuthenticationClient<?> fpClient = mock(AuthenticationClient.class);
+ when(fpClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED);
+ when(fpClient.isKeyguard()).thenReturn(true);
+
+ mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, faceClient);
+ mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FP_OTHER, fpClient);
+
+ mCoexCoordinator.onAuthenticationSucceeded(0 /* currentTimeMillis */, fpClient, mCallback);
+ verify(mCallback).sendHapticFeedback();
+ verify(mCallback).sendAuthenticationResult(eq(true) /* addAuthTokenIfStrong */);
+ verify(mCallback).handleLifecycleAfterAuth();
+ }
+
+ @Test
+ public void testKeyguard_capacitiveRejected_whenFaceScanning() {
+ mCoexCoordinator.reset();
+
+ AuthenticationClient<?> faceClient = mock(AuthenticationClient.class);
+ when(faceClient.isKeyguard()).thenReturn(true);
+ when(faceClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED);
+
+ AuthenticationClient<?> fpClient = mock(AuthenticationClient.class);
+ when(fpClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED);
+ when(fpClient.isKeyguard()).thenReturn(true);
+
+ mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, faceClient);
+ mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FP_OTHER, fpClient);
+
+ mCoexCoordinator.onAuthenticationRejected(0 /* currentTimeMillis */, fpClient,
+ LockoutTracker.LOCKOUT_NONE, mCallback);
+ verify(mCallback).sendHapticFeedback();
+ verify(mCallback).sendAuthenticationResult(eq(false) /* addAuthTokenIfStrong */);
+ verify(mCallback).handleLifecycleAfterAuth();
+ }
+
+ @Test
public void testNonKeyguard_rejectAndNotLockedOut() {
mCoexCoordinator.reset();
diff --git a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
index 645fa630f0db..9e46e1f2be92 100644
--- a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
@@ -93,6 +93,7 @@ import android.util.Pair;
import android.view.Display;
import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.FlakyTest;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
@@ -103,7 +104,6 @@ import com.android.server.usage.AppStandbyInternal.AppIdleStateChangeListener;
import org.junit.After;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -502,6 +502,7 @@ public class AppStandbyControllerTests {
}
@Test
+ @FlakyTest(bugId = 185169504)
public void testBoundWidgetPackageExempt() throws Exception {
assumeTrue(mInjector.getContext().getSystemService(AppWidgetManager.class) != null);
assertEquals(STANDBY_BUCKET_ACTIVE,
@@ -584,6 +585,7 @@ public class AppStandbyControllerTests {
}
@Test
+ @FlakyTest(bugId = 185169504)
public void testIsAppIdle_Charging() throws Exception {
TestParoleListener paroleListener = new TestParoleListener();
mController.addListener(paroleListener);
@@ -616,6 +618,7 @@ public class AppStandbyControllerTests {
}
@Test
+ @FlakyTest(bugId = 185169504)
public void testIsAppIdle_Enabled() throws Exception {
setChargingState(mController, false);
TestParoleListener paroleListener = new TestParoleListener();
@@ -715,6 +718,7 @@ public class AppStandbyControllerTests {
}
@Test
+ @FlakyTest(bugId = 185169504)
public void testBuckets() throws Exception {
assertTimeout(mController, 0, STANDBY_BUCKET_NEVER);
@@ -747,6 +751,7 @@ public class AppStandbyControllerTests {
}
@Test
+ @FlakyTest(bugId = 185169504)
public void testSetAppStandbyBucket() throws Exception {
// For a known package, standby bucket should be set properly
reportEvent(mController, USER_INTERACTION, 0, PACKAGE_1);
@@ -766,6 +771,7 @@ public class AppStandbyControllerTests {
}
@Test
+ @FlakyTest(bugId = 185169504)
public void testAppStandbyBucketOnInstallAndUninstall() throws Exception {
// On package install, standby bucket should be ACTIVE
reportEvent(mController, USER_INTERACTION, 0, PACKAGE_UNKNOWN);
@@ -784,6 +790,7 @@ public class AppStandbyControllerTests {
}
@Test
+ @FlakyTest(bugId = 185169504)
public void testScreenTimeAndBuckets() throws Exception {
mInjector.setDisplayOn(false);
@@ -807,6 +814,7 @@ public class AppStandbyControllerTests {
}
@Test
+ @FlakyTest(bugId = 185169504)
public void testForcedIdle() throws Exception {
mController.forceIdleState(PACKAGE_1, USER_ID, true);
assertEquals(STANDBY_BUCKET_RARE, getStandbyBucket(mController, PACKAGE_1));
@@ -819,6 +827,7 @@ public class AppStandbyControllerTests {
}
@Test
+ @FlakyTest(bugId = 185169504)
public void testNotificationEvent() throws Exception {
reportEvent(mController, USER_INTERACTION, 0, PACKAGE_1);
assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController, PACKAGE_1));
@@ -832,6 +841,7 @@ public class AppStandbyControllerTests {
}
@Test
+ @FlakyTest(bugId = 185169504)
public void testSlicePinnedEvent() throws Exception {
reportEvent(mController, USER_INTERACTION, 0, PACKAGE_1);
assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController, PACKAGE_1));
@@ -845,6 +855,7 @@ public class AppStandbyControllerTests {
}
@Test
+ @FlakyTest(bugId = 185169504)
public void testSlicePinnedPrivEvent() throws Exception {
mController.forceIdleState(PACKAGE_1, USER_ID, true);
reportEvent(mController, SLICE_PINNED_PRIV, mInjector.mElapsedRealtime, PACKAGE_1);
@@ -852,6 +863,7 @@ public class AppStandbyControllerTests {
}
@Test
+ @FlakyTest(bugId = 185169504)
public void testPredictionTimedOut() throws Exception {
// Set it to timeout or usage, so that prediction can override it
mInjector.mElapsedRealtime = HOUR_MS;
@@ -882,6 +894,7 @@ public class AppStandbyControllerTests {
}
@Test
+ @FlakyTest(bugId = 185169504)
public void testOverrides() throws Exception {
// Can force to NEVER
mInjector.mElapsedRealtime = HOUR_MS;
@@ -992,6 +1005,7 @@ public class AppStandbyControllerTests {
}
@Test
+ @FlakyTest(bugId = 185169504)
public void testTimeout() throws Exception {
reportEvent(mController, USER_INTERACTION, 0, PACKAGE_1);
assertBucket(STANDBY_BUCKET_ACTIVE);
@@ -1015,6 +1029,7 @@ public class AppStandbyControllerTests {
/** Test that timeouts still work properly even if invalid configuration values are set. */
@Test
+ @FlakyTest(bugId = 185169504)
public void testTimeout_InvalidThresholds() throws Exception {
mInjector.mSettingsBuilder
.setLong("screen_threshold_active", -1)
@@ -1052,6 +1067,7 @@ public class AppStandbyControllerTests {
* timeout has passed.
*/
@Test
+ @FlakyTest(bugId = 185169504)
public void testTimeoutBeforeRestricted() throws Exception {
reportEvent(mController, USER_INTERACTION, 0, PACKAGE_1);
assertBucket(STANDBY_BUCKET_ACTIVE);
@@ -1078,6 +1094,7 @@ public class AppStandbyControllerTests {
* Test that an app is put into the RESTRICTED bucket after enough time has passed.
*/
@Test
+ @FlakyTest(bugId = 185169504)
public void testRestrictedDelay() throws Exception {
reportEvent(mController, USER_INTERACTION, 0, PACKAGE_1);
assertBucket(STANDBY_BUCKET_ACTIVE);
@@ -1100,6 +1117,7 @@ public class AppStandbyControllerTests {
* Test that an app is put into the RESTRICTED bucket after enough time has passed.
*/
@Test
+ @FlakyTest(bugId = 185169504)
public void testRestrictedDelay_DelayChange() throws Exception {
reportEvent(mController, USER_INTERACTION, 0, PACKAGE_1);
assertBucket(STANDBY_BUCKET_ACTIVE);
@@ -1124,6 +1142,7 @@ public class AppStandbyControllerTests {
* a low bucket after the RESTRICTED timeout.
*/
@Test
+ @FlakyTest(bugId = 185169504)
public void testRestrictedTimeoutOverridesRestoredLowBucketPrediction() throws Exception {
reportEvent(mController, USER_INTERACTION, mInjector.mElapsedRealtime, PACKAGE_1);
assertBucket(STANDBY_BUCKET_ACTIVE);
@@ -1160,6 +1179,7 @@ public class AppStandbyControllerTests {
* a low bucket after the RESTRICTED timeout.
*/
@Test
+ @FlakyTest(bugId = 185169504)
public void testRestrictedTimeoutOverridesPredictionLowBucket() throws Exception {
reportEvent(mController, USER_INTERACTION, mInjector.mElapsedRealtime, PACKAGE_1);
@@ -1187,6 +1207,7 @@ public class AppStandbyControllerTests {
* interaction.
*/
@Test
+ @FlakyTest(bugId = 185169504)
public void testSystemInteractionOverridesRestrictedTimeout() throws Exception {
reportEvent(mController, USER_INTERACTION, mInjector.mElapsedRealtime, PACKAGE_1);
assertBucket(STANDBY_BUCKET_ACTIVE);
@@ -1213,6 +1234,7 @@ public class AppStandbyControllerTests {
}
@Test
+ @FlakyTest(bugId = 185169504)
public void testRestrictedBucketDisabled() throws Exception {
mInjector.mIsRestrictedBucketEnabled = false;
// Get the controller to read the new value. Capturing the ContentObserver isn't possible
@@ -1238,6 +1260,7 @@ public class AppStandbyControllerTests {
}
@Test
+ @FlakyTest(bugId = 185169504)
public void testRestrictedBucket_EnabledToDisabled() throws Exception {
reportEvent(mController, USER_INTERACTION, mInjector.mElapsedRealtime, PACKAGE_1);
mInjector.mElapsedRealtime += RESTRICTED_THRESHOLD;
@@ -1255,6 +1278,7 @@ public class AppStandbyControllerTests {
}
@Test
+ @FlakyTest(bugId = 185169504)
public void testPredictionRaiseFromRestrictedTimeout_highBucket() throws Exception {
reportEvent(mController, USER_INTERACTION, mInjector.mElapsedRealtime, PACKAGE_1);
@@ -1272,6 +1296,7 @@ public class AppStandbyControllerTests {
}
@Test
+ @FlakyTest(bugId = 185169504)
public void testPredictionRaiseFromRestrictedTimeout_lowBucket() throws Exception {
reportEvent(mController, USER_INTERACTION, mInjector.mElapsedRealtime, PACKAGE_1);
@@ -1289,6 +1314,7 @@ public class AppStandbyControllerTests {
}
@Test
+ @FlakyTest(bugId = 185169504)
public void testCascadingTimeouts() throws Exception {
reportEvent(mController, USER_INTERACTION, 0, PACKAGE_1);
assertBucket(STANDBY_BUCKET_ACTIVE);
@@ -1312,6 +1338,7 @@ public class AppStandbyControllerTests {
}
@Test
+ @FlakyTest(bugId = 185169504)
public void testOverlappingTimeouts() throws Exception {
reportEvent(mController, USER_INTERACTION, 0, PACKAGE_1);
assertBucket(STANDBY_BUCKET_ACTIVE);
@@ -1343,6 +1370,7 @@ public class AppStandbyControllerTests {
}
@Test
+ @FlakyTest(bugId = 185169504)
public void testSystemInteractionTimeout() throws Exception {
reportEvent(mController, USER_INTERACTION, 0, PACKAGE_1);
// Fast forward to RARE
@@ -1366,6 +1394,7 @@ public class AppStandbyControllerTests {
}
@Test
+ @FlakyTest(bugId = 185169504)
public void testInitialForegroundServiceTimeout() throws Exception {
mInjector.mElapsedRealtime = 1 * RARE_THRESHOLD + 100;
// Make sure app is in NEVER bucket
@@ -1399,6 +1428,7 @@ public class AppStandbyControllerTests {
}
@Test
+ @FlakyTest(bugId = 185169504)
public void testPredictionNotOverridden() throws Exception {
reportEvent(mController, USER_INTERACTION, 0, PACKAGE_1);
assertBucket(STANDBY_BUCKET_ACTIVE);
@@ -1424,8 +1454,8 @@ public class AppStandbyControllerTests {
assertBucket(STANDBY_BUCKET_ACTIVE);
}
- @Ignore
@Test
+ @FlakyTest(bugId = 185169504)
public void testPredictionStrikesBack() throws Exception {
reportEvent(mController, USER_INTERACTION, 0, PACKAGE_1);
assertBucket(STANDBY_BUCKET_ACTIVE);
@@ -1451,6 +1481,7 @@ public class AppStandbyControllerTests {
}
@Test
+ @FlakyTest(bugId = 185169504)
public void testSystemForcedFlags_NotAddedForUserForce() throws Exception {
final int expectedReason = REASON_MAIN_FORCED_BY_USER;
mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_RESTRICTED,
@@ -1465,6 +1496,7 @@ public class AppStandbyControllerTests {
}
@Test
+ @FlakyTest(bugId = 185169504)
public void testSystemForcedFlags_AddedForSystemForce() throws Exception {
mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_ACTIVE,
REASON_MAIN_DEFAULT);
@@ -1487,6 +1519,7 @@ public class AppStandbyControllerTests {
}
@Test
+ @FlakyTest(bugId = 185169504)
public void testSystemForcedFlags_SystemForceChangesBuckets() throws Exception {
mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_ACTIVE,
REASON_MAIN_DEFAULT);
@@ -1524,6 +1557,7 @@ public class AppStandbyControllerTests {
}
@Test
+ @FlakyTest(bugId = 185169504)
public void testRestrictApp_MainReason() throws Exception {
mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_ACTIVE,
REASON_MAIN_DEFAULT);
@@ -1598,6 +1632,7 @@ public class AppStandbyControllerTests {
}
@Test
+ @FlakyTest(bugId = 185169504)
public void testUserInteraction_CrossProfile() throws Exception {
mInjector.mRunningUsers = new int[] {USER_ID, USER_ID2, USER_ID3};
mInjector.mCrossProfileTargets = Arrays.asList(USER_HANDLE_USER2);
@@ -1621,6 +1656,7 @@ public class AppStandbyControllerTests {
}
@Test
+ @FlakyTest(bugId = 185169504)
public void testUnexemptedSyncScheduled() throws Exception {
rearmLatch(PACKAGE_1);
mController.addListener(mListener);
@@ -1642,6 +1678,7 @@ public class AppStandbyControllerTests {
}
@Test
+ @FlakyTest(bugId = 185169504)
public void testExemptedSyncScheduled() throws Exception {
setAndAssertBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_RARE, REASON_MAIN_FORCED_BY_SYSTEM);
mInjector.mDeviceIdleMode = true;
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index d498d4663d78..c60b8dcf67cf 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -42,6 +42,7 @@ import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_B
import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
+import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
@@ -49,6 +50,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE;
import static android.view.WindowManager.LayoutParams.TYPE_SCREENSHOT;
@@ -1746,6 +1748,31 @@ public class DisplayContentTests extends WindowTestsBase {
}
@Test
+ public void testFindScrollCaptureTargetWindow_secure() {
+ DisplayContent display = createNewDisplay();
+ Task rootTask = createTask(display);
+ Task task = createTaskInRootTask(rootTask, 0 /* userId */);
+ WindowState secureWindow = createWindow(null, TYPE_APPLICATION, "Secure Window");
+ secureWindow.mAttrs.flags |= FLAG_SECURE;
+
+ WindowState result = display.findScrollCaptureTargetWindow(null,
+ ActivityTaskManager.INVALID_TASK_ID);
+ assertNull(result);
+ }
+
+ @Test
+ public void testFindScrollCaptureTargetWindow_secureTaskId() {
+ DisplayContent display = createNewDisplay();
+ Task rootTask = createTask(display);
+ Task task = createTaskInRootTask(rootTask, 0 /* userId */);
+ WindowState secureWindow = createWindow(null, TYPE_APPLICATION, "Secure Window");
+ secureWindow.mAttrs.flags |= FLAG_SECURE;
+
+ WindowState result = display.findScrollCaptureTargetWindow(null, task.mTaskId);
+ assertNull(result);
+ }
+
+ @Test
public void testFindScrollCaptureTargetWindow_taskId() {
DisplayContent display = createNewDisplay();
Task rootTask = createTask(display);
@@ -2175,6 +2202,31 @@ public class DisplayContentTests extends WindowTestsBase {
assertNotEquals(imeChildWindow, mDisplayContent.findFocusedWindow());
}
+ @UseTestDisplay(addWindows = W_INPUT_METHOD)
+ @Test
+ public void testImeMenuDialogFocusWhenImeLayeringTargetChanges() {
+ final WindowState imeMenuDialog =
+ createWindow(mImeWindow, TYPE_INPUT_METHOD_DIALOG, "imeMenuDialog");
+ makeWindowVisibleAndDrawn(imeMenuDialog, mImeWindow);
+ assertTrue(imeMenuDialog.canReceiveKeys());
+ mDisplayContent.setInputMethodWindowLocked(mImeWindow);
+
+ // Verify imeMenuDialog can be focused window if the next IME target requests IME visible.
+ final WindowState imeAppTarget =
+ createWindow(null, TYPE_BASE_APPLICATION, mDisplayContent, "imeAppTarget");
+ mDisplayContent.setImeLayeringTarget(imeAppTarget);
+ spyOn(imeAppTarget);
+ doReturn(true).when(imeAppTarget).getRequestedVisibility(ITYPE_IME);
+ assertEquals(imeMenuDialog, mDisplayContent.findFocusedWindow());
+
+ // Verify imeMenuDialog doesn't be focused window if the next IME target does not
+ // request IME visible.
+ final WindowState nextImeAppTarget =
+ createWindow(null, TYPE_BASE_APPLICATION, mDisplayContent, "nextImeAppTarget");
+ mDisplayContent.setImeLayeringTarget(nextImeAppTarget);
+ assertNotEquals(imeMenuDialog, mDisplayContent.findFocusedWindow());
+ }
+
private void removeRootTaskTests(Runnable runnable) {
final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
final Task rootTask1 = taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN,
diff --git a/services/tests/wmtests/src/com/android/server/wm/StubTransaction.java b/services/tests/wmtests/src/com/android/server/wm/StubTransaction.java
index b89539cabbfe..3a2190d13354 100644
--- a/services/tests/wmtests/src/com/android/server/wm/StubTransaction.java
+++ b/services/tests/wmtests/src/com/android/server/wm/StubTransaction.java
@@ -265,4 +265,10 @@ public class StubTransaction extends SurfaceControl.Transaction {
public SurfaceControl.Transaction setColorSpace(SurfaceControl sc, ColorSpace colorSpace) {
return this;
}
+
+ @Override
+ public SurfaceControl.Transaction setTrustedOverlay(SurfaceControl sc,
+ boolean isTrustedOverlay) {
+ return this;
+ }
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
index 92b670ed9699..3a50bb0f06bc 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
@@ -53,6 +53,9 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
import static com.android.server.wm.DisplayContent.IME_TARGET_CONTROL;
import static com.android.server.wm.DisplayContent.IME_TARGET_LAYERING;
+import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_RECENTS;
+import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
+import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
import static com.android.server.wm.WindowContainer.SYNC_STATE_WAITING_FOR_DRAW;
import static com.google.common.truth.Truth.assertThat;
@@ -891,6 +894,36 @@ public class WindowStateTests extends WindowTestsBase {
assertTrue(mAppWindow.getInsetsState().getSourceOrDefaultVisibility(ITYPE_NAVIGATION_BAR));
}
+ @UseTestDisplay(addWindows = W_INPUT_METHOD)
+ @Test
+ public void testAdjustImeInsetsVisibilityWhenTaskSwitchIsAnimating() {
+ final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
+ final WindowState app2 = createWindow(null, TYPE_APPLICATION, "app2");
+ final InsetsStateController controller = mDisplayContent.getInsetsStateController();
+ controller.getImeSourceProvider().setWindow(mImeWindow, null, null);
+
+ // Simulate app requests IME with updating all windows Insets State when IME is above app.
+ mDisplayContent.setImeLayeringTarget(app);
+ mDisplayContent.setImeInputTarget(app);
+ assertTrue(mDisplayContent.shouldImeAttachedToApp());
+ controller.getImeSourceProvider().scheduleShowImePostLayout(app);
+ controller.getImeSourceProvider().getSource().setVisible(true);
+ controller.updateAboveInsetsState(mImeWindow, false);
+
+ // Simulate task switching animation happens when switching app to app2.
+ spyOn(app);
+ spyOn(app2);
+ doReturn(true).when(app).isAnimating(PARENTS | TRANSITION, ANIMATION_TYPE_RECENTS);
+ doReturn(true).when(app2).isAnimating(PARENTS | TRANSITION, ANIMATION_TYPE_RECENTS);
+ app.mActivityRecord.mLastImeShown = true;
+
+ // Verify the IME insets is visible on app, but not for app2 during task animating.
+ InsetsState stateApp = app.getInsetsState();
+ InsetsState stateApp2 = app2.getInsetsState();
+ assertTrue(stateApp.getSource(ITYPE_IME).isVisible());
+ assertFalse(stateApp2.getSource(ITYPE_IME).isVisible());
+ }
+
@UseTestDisplay(addWindows = { W_ACTIVITY })
@Test
public void testUpdateImeControlTargetWhenLeavingMultiWindow() {
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
index e408cfc77ad0..965f126000fd 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
@@ -87,14 +87,14 @@ import java.util.function.Function;
*/
final class HotwordDetectionConnection {
private static final String TAG = "HotwordDetectionConnection";
- // TODO (b/177502877): Set the Debug flag to false before shipping.
- static final boolean DEBUG = true;
+ static final boolean DEBUG = false;
// TODO: These constants need to be refined.
private static final long VALIDATION_TIMEOUT_MILLIS = 3000;
private static final long MAX_UPDATE_TIMEOUT_MILLIS = 6000;
private static final Duration MAX_UPDATE_TIMEOUT_DURATION =
Duration.ofMillis(MAX_UPDATE_TIMEOUT_MILLIS);
+ private static final long RESET_DEBUG_HOTWORD_LOGGING_TIMEOUT_MILLIS = 60 * 60 * 1000; // 1 hour
private final Executor mAudioCopyExecutor = Executors.newCachedThreadPool();
// TODO: This may need to be a Handler(looper)
@@ -103,6 +103,7 @@ final class HotwordDetectionConnection {
private final AtomicBoolean mUpdateStateAfterStartFinished = new AtomicBoolean(false);
private final IBinder.DeathRecipient mAudioServerDeathRecipient = this::audioServerDied;
private final @NonNull ServiceConnectionFactory mServiceConnectionFactory;
+ private final IHotwordRecognitionStatusCallback mCallback;
final Object mLock;
final int mVoiceInteractionServiceUid;
@@ -110,11 +111,11 @@ final class HotwordDetectionConnection {
final int mUser;
final Context mContext;
volatile HotwordDetectionServiceIdentity mIdentity;
- private IHotwordRecognitionStatusCallback mCallback;
private IMicrophoneHotwordDetectionVoiceInteractionCallback mSoftwareCallback;
private Instant mLastRestartInstant;
private ScheduledFuture<?> mCancellationTaskFuture;
+ private ScheduledFuture<?> mDebugHotwordLoggingTimeoutFuture = null;
/** Identity used for attributing app ops when delivering data to the Interactor. */
@GuardedBy("mLock")
@@ -128,17 +129,24 @@ final class HotwordDetectionConnection {
private boolean mPerformingSoftwareHotwordDetection;
private @NonNull ServiceConnection mRemoteHotwordDetectionService;
private IBinder mAudioFlinger;
+ private boolean mDebugHotwordLogging = false;
HotwordDetectionConnection(Object lock, Context context, int voiceInteractionServiceUid,
Identity voiceInteractorIdentity, ComponentName serviceName, int userId,
boolean bindInstantServiceAllowed, @Nullable PersistableBundle options,
- @Nullable SharedMemory sharedMemory, IHotwordRecognitionStatusCallback callback) {
+ @Nullable SharedMemory sharedMemory,
+ @NonNull IHotwordRecognitionStatusCallback callback) {
+ if (callback == null) {
+ Slog.w(TAG, "Callback is null while creating connection");
+ throw new IllegalArgumentException("Callback is null while creating connection");
+ }
mLock = lock;
mContext = context;
mVoiceInteractionServiceUid = voiceInteractionServiceUid;
mVoiceInteractorIdentity = voiceInteractorIdentity;
mDetectionComponentName = serviceName;
mUser = userId;
+ mCallback = callback;
final Intent intent = new Intent(HotwordDetectionService.SERVICE_INTERFACE);
intent.setComponent(mDetectionComponentName);
initAudioFlingerLocked();
@@ -147,22 +155,13 @@ final class HotwordDetectionConnection {
mRemoteHotwordDetectionService = mServiceConnectionFactory.createLocked();
- if (callback == null) {
- updateStateLocked(options, sharedMemory);
- return;
- }
- mCallback = callback;
-
mLastRestartInstant = Instant.now();
updateStateAfterProcessStart(options, sharedMemory);
// TODO(volnov): we need to be smarter here, e.g. schedule it a bit more often, but wait
// until the current session is closed.
mCancellationTaskFuture = mScheduledExecutorService.scheduleAtFixedRate(() -> {
- if (DEBUG) {
- Slog.i(TAG, "Time to restart the process, TTL has passed");
- }
-
+ Slog.v(TAG, "Time to restart the process, TTL has passed");
synchronized (mLock) {
restartProcessLocked();
}
@@ -268,9 +267,9 @@ final class HotwordDetectionConnection {
}
void cancelLocked() {
- if (DEBUG) {
- Slog.d(TAG, "cancelLocked");
- }
+ Slog.v(TAG, "cancelLocked");
+ clearDebugHotwordLoggingTimeoutLocked();
+ mDebugHotwordLogging = false;
if (mRemoteHotwordDetectionService.isBound()) {
mRemoteHotwordDetectionService.unbind();
LocalServices.getService(PermissionManagerServiceInternal.class)
@@ -288,6 +287,7 @@ final class HotwordDetectionConnection {
// TODO(b/191742511): this logic needs a test
if (!mUpdateStateAfterStartFinished.get()
&& Instant.now().minus(MAX_UPDATE_TIMEOUT_DURATION).isBefore(mLastRestartInstant)) {
+ Slog.v(TAG, "call updateStateAfterProcessStart");
updateStateAfterProcessStart(options, sharedMemory);
} else {
mRemoteHotwordDetectionService.run(
@@ -330,6 +330,9 @@ final class HotwordDetectionConnection {
if (result != null) {
Slog.i(TAG, "Egressed " + HotwordDetectedResult.getUsageSize(result)
+ " bits from hotword trusted process");
+ if (mDebugHotwordLogging) {
+ Slog.i(TAG, "Egressed detected result: " + result);
+ }
}
} else {
Slog.i(TAG, "Hotword detection has already completed");
@@ -407,15 +410,11 @@ final class HotwordDetectionConnection {
private void detectFromDspSourceForTest(SoundTrigger.KeyphraseRecognitionEvent recognitionEvent,
IHotwordRecognitionStatusCallback externalCallback) {
- if (DEBUG) {
- Slog.d(TAG, "detectFromDspSourceForTest");
- }
+ Slog.v(TAG, "detectFromDspSourceForTest");
IDspHotwordDetectionCallback internalCallback = new IDspHotwordDetectionCallback.Stub() {
@Override
public void onDetected(HotwordDetectedResult result) throws RemoteException {
- if (DEBUG) {
- Slog.d(TAG, "onDetected");
- }
+ Slog.v(TAG, "onDetected");
synchronized (mLock) {
if (mValidatingDspTrigger) {
mValidatingDspTrigger = false;
@@ -424,6 +423,9 @@ final class HotwordDetectionConnection {
if (result != null) {
Slog.i(TAG, "Egressed " + HotwordDetectedResult.getUsageSize(result)
+ " bits from hotword trusted process");
+ if (mDebugHotwordLogging) {
+ Slog.i(TAG, "Egressed detected result: " + result);
+ }
}
} else {
Slog.i(TAG, "Ignored hotword detected since trigger has been handled");
@@ -433,13 +435,14 @@ final class HotwordDetectionConnection {
@Override
public void onRejected(HotwordRejectedResult result) throws RemoteException {
- if (DEBUG) {
- Slog.d(TAG, "onRejected");
- }
+ Slog.v(TAG, "onRejected");
synchronized (mLock) {
if (mValidatingDspTrigger) {
mValidatingDspTrigger = false;
externalCallback.onRejected(result);
+ if (mDebugHotwordLogging && result != null) {
+ Slog.i(TAG, "Egressed rejected result: " + result);
+ }
} else {
Slog.i(TAG, "Ignored hotword rejected since trigger has been handled");
}
@@ -482,6 +485,9 @@ final class HotwordDetectionConnection {
if (result != null) {
Slog.i(TAG, "Egressed " + HotwordDetectedResult.getUsageSize(result)
+ " bits from hotword trusted process");
+ if (mDebugHotwordLogging) {
+ Slog.i(TAG, "Egressed detected result: " + result);
+ }
}
}
}
@@ -498,6 +504,9 @@ final class HotwordDetectionConnection {
}
mValidatingDspTrigger = false;
externalCallback.onRejected(result);
+ if (mDebugHotwordLogging && result != null) {
+ Slog.i(TAG, "Egressed rejected result: " + result);
+ }
}
}
};
@@ -514,19 +523,37 @@ final class HotwordDetectionConnection {
}
void forceRestart() {
- if (DEBUG) {
- Slog.i(TAG, "Requested to restart the service internally. Performing the restart");
- }
+ Slog.v(TAG, "Requested to restart the service internally. Performing the restart");
synchronized (mLock) {
restartProcessLocked();
}
}
- private void restartProcessLocked() {
- if (DEBUG) {
- Slog.i(TAG, "Restarting hotword detection process");
+ void setDebugHotwordLoggingLocked(boolean logging) {
+ Slog.v(TAG, "setDebugHotwordLoggingLocked: " + logging);
+ clearDebugHotwordLoggingTimeoutLocked();
+ mDebugHotwordLogging = logging;
+
+ if (logging) {
+ // Reset mDebugHotwordLogging to false after one hour
+ mDebugHotwordLoggingTimeoutFuture = mScheduledExecutorService.schedule(() -> {
+ Slog.v(TAG, "Timeout to reset mDebugHotwordLogging to false");
+ synchronized (mLock) {
+ mDebugHotwordLogging = false;
+ }
+ }, RESET_DEBUG_HOTWORD_LOGGING_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
+ }
+ }
+
+ private void clearDebugHotwordLoggingTimeoutLocked() {
+ if (mDebugHotwordLoggingTimeoutFuture != null) {
+ mDebugHotwordLoggingTimeoutFuture.cancel(/* mayInterruptIfRunning= */true);
+ mDebugHotwordLoggingTimeoutFuture = null;
}
+ }
+ private void restartProcessLocked() {
+ Slog.v(TAG, "Restarting hotword detection process");
ServiceConnection oldConnection = mRemoteHotwordDetectionService;
// TODO(volnov): this can be done after connect() has been successful.
@@ -547,9 +574,7 @@ final class HotwordDetectionConnection {
// Recreate connection to reset the cache.
mRemoteHotwordDetectionService = mServiceConnectionFactory.createLocked();
- if (DEBUG) {
- Slog.i(TAG, "Started the new process, issuing #onProcessRestarted");
- }
+ Slog.v(TAG, "Started the new process, issuing #onProcessRestarted");
try {
mCallback.onProcessRestarted();
} catch (RemoteException e) {
@@ -700,6 +725,9 @@ final class HotwordDetectionConnection {
bestEffortClose(serviceAudioSource);
bestEffortClose(audioSource);
+ if (mDebugHotwordLogging && result != null) {
+ Slog.i(TAG, "Egressed rejected result: " + result);
+ }
// TODO: Propagate the HotwordRejectedResult.
}
@@ -714,6 +742,9 @@ final class HotwordDetectionConnection {
if (triggerResult != null) {
Slog.i(TAG, "Egressed " + HotwordDetectedResult.getUsageSize(
triggerResult) + " bits from hotword trusted process");
+ if (mDebugHotwordLogging) {
+ Slog.i(TAG, "Egressed detected result: " + triggerResult);
+ }
}
// TODO: Add a delay before closing.
bestEffortClose(audioSource);
@@ -773,9 +804,7 @@ final class HotwordDetectionConnection {
}
synchronized (mLock) {
if (!mRespectServiceConnectionStatusChanged) {
- if (DEBUG) {
- Slog.d(TAG, "Ignored onServiceConnectionStatusChanged event");
- }
+ Slog.v(TAG, "Ignored onServiceConnectionStatusChanged event");
return;
}
mIsBound = connected;
@@ -792,9 +821,7 @@ final class HotwordDetectionConnection {
super.binderDied();
synchronized (mLock) {
if (!mRespectServiceConnectionStatusChanged) {
- if (DEBUG) {
- Slog.d(TAG, "Ignored #binderDied event");
- }
+ Slog.v(TAG, "Ignored #binderDied event");
return;
}
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerSessionPermissionsDecorator.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerSessionPermissionsDecorator.java
index b9e1fcd7ffd3..68b2e6168b5c 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerSessionPermissionsDecorator.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerSessionPermissionsDecorator.java
@@ -29,7 +29,6 @@ import android.media.permission.Identity;
import android.media.permission.PermissionUtil;
import android.os.IBinder;
import android.os.RemoteException;
-import android.os.ServiceSpecificException;
import android.text.TextUtils;
import android.util.Slog;
@@ -117,8 +116,8 @@ final class SoundTriggerSessionPermissionsDecorator implements
/**
* Throws a {@link SecurityException} if originator permanently doesn't have the given
- * permission, or a {@link ServiceSpecificException} with a {@link
- * #TEMPORARY_PERMISSION_DENIED} if caller originator doesn't have the given permission.
+ * permission.
+ * Soft (temporary) denials are considered OK for preflight purposes.
*
* @param context A {@link Context}, used for permission checks.
* @param identity The identity to check.
@@ -130,15 +129,12 @@ final class SoundTriggerSessionPermissionsDecorator implements
permission);
switch (status) {
case PermissionChecker.PERMISSION_GRANTED:
+ case PermissionChecker.PERMISSION_SOFT_DENIED:
return;
case PermissionChecker.PERMISSION_HARD_DENIED:
throw new SecurityException(
TextUtils.formatSimple("Failed to obtain permission %s for identity %s",
permission, toString(identity)));
- case PermissionChecker.PERMISSION_SOFT_DENIED:
- throw new ServiceSpecificException(TEMPORARY_PERMISSION_DENIED,
- TextUtils.formatSimple("Failed to obtain permission %s for identity %s",
- permission, toString(identity)));
default:
throw new RuntimeException("Unexpected permission check result.");
}
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index ccf4267a0fbc..71541ad729d5 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -832,6 +832,17 @@ public class VoiceInteractionManagerService extends SystemService {
mImpl.forceRestartHotwordDetector();
}
+ // Called by Shell command
+ void setDebugHotwordLogging(boolean logging) {
+ synchronized (this) {
+ if (mImpl == null) {
+ Slog.w(TAG, "setTemporaryLogging without running voice interaction service");
+ return;
+ }
+ mImpl.setDebugHotwordLoggingLocked(logging);
+ }
+ }
+
@Override
public void showSession(Bundle args, int flags) {
synchronized (this) {
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
index cbcbf52c2c9c..558a9ac9298e 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
@@ -79,8 +79,7 @@ import java.util.List;
class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConnection.Callback {
final static String TAG = "VoiceInteractionServiceManager";
- // TODO (b/177502877): Set the Debug flag to false before shipping.
- static final boolean DEBUG = true;
+ static final boolean DEBUG = false;
final static String CLOSE_REASON_VOICE_INTERACTION = "voiceinteraction";
@@ -420,9 +419,7 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne
@Nullable PersistableBundle options,
@Nullable SharedMemory sharedMemory,
IHotwordRecognitionStatusCallback callback) {
- if (DEBUG) {
- Slog.d(TAG, "updateStateLocked");
- }
+ Slog.v(TAG, "updateStateLocked");
if (mHotwordDetectionComponentName == null) {
Slog.w(TAG, "Hotword detection service name not found");
throw new IllegalStateException("Hotword detection service name not found");
@@ -584,6 +581,14 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne
mHotwordDetectionConnection.forceRestart();
}
+ void setDebugHotwordLoggingLocked(boolean logging) {
+ if (mHotwordDetectionConnection == null) {
+ Slog.w(TAG, "Failed to set temporary debug logging: no hotword detection active");
+ return;
+ }
+ mHotwordDetectionConnection.setDebugHotwordLoggingLocked(logging);
+ }
+
void resetHotwordDetectionConnectionLocked() {
if (DEBUG) {
Slog.d(TAG, "resetHotwordDetectionConnectionLocked");
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceShellCommand.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceShellCommand.java
index cdd8f7b91d9d..9bdf4e418a52 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceShellCommand.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceShellCommand.java
@@ -56,6 +56,8 @@ final class VoiceInteractionManagerServiceShellCommand extends ShellCommand {
return requestDisable(pw);
case "restart-detection":
return requestRestartDetection(pw);
+ case "set-debug-hotword-logging":
+ return setDebugHotwordLogging(pw);
default:
return handleDefaultCommands(cmd);
}
@@ -76,9 +78,14 @@ final class VoiceInteractionManagerServiceShellCommand extends ShellCommand {
pw.println("");
pw.println(" disable [true|false]");
pw.println(" Temporarily disable (when true) service");
+ pw.println("");
pw.println(" restart-detection");
pw.println(" Force a restart of a hotword detection service");
pw.println("");
+ pw.println(" set-debug-hotword-logging [true|false]");
+ pw.println(" Temporarily enable or disable debug logging for hotword result.");
+ pw.println(" The debug logging will be reset after one hour from last enable.");
+ pw.println("");
}
}
@@ -157,6 +164,17 @@ final class VoiceInteractionManagerServiceShellCommand extends ShellCommand {
return 0;
}
+ private int setDebugHotwordLogging(PrintWriter pw) {
+ boolean logging = Boolean.parseBoolean(getNextArgRequired());
+ Slog.i(TAG, "setDebugHotwordLogging(): " + logging);
+ try {
+ mService.setDebugHotwordLogging(logging);
+ } catch (Exception e) {
+ return handleError(pw, "setDebugHotwordLogging()", e);
+ }
+ return 0;
+ }
+
private static int handleError(PrintWriter pw, String message, Exception e) {
Slog.e(TAG, "error calling " + message, e);
pw.printf("Error calling %s: %s\n", message, e);
diff --git a/telephony/java/android/telephony/AccessNetworkUtils.java b/telephony/java/android/telephony/AccessNetworkUtils.java
index 6b820459be98..b5d97abdd3eb 100644
--- a/telephony/java/android/telephony/AccessNetworkUtils.java
+++ b/telephony/java/android/telephony/AccessNetworkUtils.java
@@ -567,6 +567,10 @@ public class AccessNetworkUtils {
*/
public static int getFrequencyFromNrArfcn(int nrArfcn) {
+ if (nrArfcn == PhysicalChannelConfig.CHANNEL_NUMBER_UNKNOWN) {
+ return PhysicalChannelConfig.FREQUENCY_UNKNOWN;
+ }
+
int globalKhz = 0;
int rangeOffset = 0;
int arfcnOffset = 0;
@@ -632,6 +636,10 @@ public class AccessNetworkUtils {
*/
public static int getFrequencyFromUarfcn(int band, int uarfcn, boolean isUplink) {
+ if (uarfcn == PhysicalChannelConfig.CHANNEL_NUMBER_UNKNOWN) {
+ return PhysicalChannelConfig.FREQUENCY_UNKNOWN;
+ }
+
int offsetKhz = 0;
for (UtranBandArfcnFrequency uarfcnFrequency : AccessNetworkConstants.
UtranBandArfcnFrequency.values()) {
@@ -702,6 +710,10 @@ public class AccessNetworkUtils {
*/
public static int getFrequencyFromArfcn(int band, int arfcn, boolean isUplink) {
+ if (arfcn == PhysicalChannelConfig.CHANNEL_NUMBER_UNKNOWN) {
+ return PhysicalChannelConfig.FREQUENCY_UNKNOWN;
+ }
+
int uplinkFrequencyFirst = 0;
int arfcnOffset = 0;
int downlinkOffset = 0;
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 10f8463029fa..aa61229ecc24 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -3581,7 +3581,7 @@ public class CarrierConfigManager {
"nr_advanced_capable_pco_id_int";
/**
- * This configuration allows the framework to use user data communication to detect RRC state,
+ * This configuration allows the framework to use user data communication to detect Idle state,
* and this is used on the 5G icon.
*
* There is a new way for for RRC state detection at Android 12. If
@@ -3589,16 +3589,23 @@ public class CarrierConfigManager {
* {@link TelephonyManager#CAPABILITY_PHYSICAL_CHANNEL_CONFIG_1_6_SUPPORTED}) returns true,
* then framework can use PHYSICAL_CHANNEL_CONFIG for RRC state detection. Based on this
* condition, some carriers want to use the legacy behavior that way is using user data
- * communication to detect the RRC state. Therefore, this configuration allows the framework
- * to use user data communication to detect RRC state.
+ * communication to detect the Idle state. Therefore, this configuration allows the framework
+ * to use user data communication to detect Idle state.
*
- * The precondition is
+ * There are 3 situations reflects the carrier define Idle state.
+ * 1. using PHYSICAL_CHANNEL_CONFIG to detect RRC Idle
+ * 2. using all of data connections to detect RRC Idle.
+ * 3. using data communication(consider internet data connection only) to detect data Idle.
+ *
+ * How to setup for above 3 cases?
+ * For below part, we call the condition#1 is device support
* {@link android.telephony.TelephonyManager#isRadioInterfaceCapabilitySupported}(
- * {@link TelephonyManager#CAPABILITY_PHYSICAL_CHANNEL_CONFIG_1_6_SUPPORTED}) returns true,
- * otherwise this config is not working.
- * If this is true, framework uses the user data communication for RRC state detection.
- * If this is false, framework uses the PHYSICAL_CHANNEL_CONFIG for RRC state detection.
+ * {@link TelephonyManager#CAPABILITY_PHYSICAL_CHANNEL_CONFIG_1_6_SUPPORTED}).
+ * The condition#2 is carrier enable the KEY_LTE_ENDC_USING_USER_DATA_FOR_RRC_DETECTION_BOOL.
*
+ * For case#1, the condition#1 is true and the condition#2 is false.
+ * For case#2, the condition#1 is false and the condition#2 is false.
+ * For case#3, the condition#2 is true.
* @hide
*/
public static final String KEY_LTE_ENDC_USING_USER_DATA_FOR_RRC_DETECTION_BOOL =
diff --git a/telephony/java/android/telephony/CellSignalStrengthNr.java b/telephony/java/android/telephony/CellSignalStrengthNr.java
index 72150ddf8597..6ada32e1a86d 100644
--- a/telephony/java/android/telephony/CellSignalStrengthNr.java
+++ b/telephony/java/android/telephony/CellSignalStrengthNr.java
@@ -178,7 +178,7 @@ public final class CellSignalStrengthNr extends CellSignalStrength implements Pa
mCsiSinr = inRangeOrUnavailable(csiSinr, -23, 23);
mCsiCqiTableIndex = inRangeOrUnavailable(csiCqiTableIndex, 1, 3);
mCsiCqiReport = csiCqiReport.stream()
- .map(cqi -> new Integer(inRangeOrUnavailable(Byte.toUnsignedInt(cqi), 1, 3)))
+ .map(cqi -> new Integer(inRangeOrUnavailable(Byte.toUnsignedInt(cqi), 0, 15)))
.collect(Collectors.toList());
mSsRsrp = inRangeOrUnavailable(ssRsrp, -140, -44);
mSsRsrq = inRangeOrUnavailable(ssRsrq, -43, 20);
diff --git a/telephony/java/android/telephony/PhysicalChannelConfig.java b/telephony/java/android/telephony/PhysicalChannelConfig.java
index 8df41fb6b288..d250088c2f10 100644
--- a/telephony/java/android/telephony/PhysicalChannelConfig.java
+++ b/telephony/java/android/telephony/PhysicalChannelConfig.java
@@ -338,7 +338,8 @@ public final class PhysicalChannelConfig implements Parcelable {
private void setUplinkFrequency() {
switch (mNetworkType){
case TelephonyManager.NETWORK_TYPE_NR:
- mUplinkFrequency = mDownlinkFrequency;
+ mUplinkFrequency = AccessNetworkUtils.getFrequencyFromNrArfcn(
+ mUplinkChannelNumber);
break;
case TelephonyManager.NETWORK_TYPE_LTE:
mUplinkFrequency = AccessNetworkUtils.getFrequencyFromEarfcn(
diff --git a/tests/vcn/java/com/android/server/vcn/VcnNetworkProviderTest.java b/tests/vcn/java/com/android/server/vcn/VcnNetworkProviderTest.java
index 72db55b3f4c5..e9026e22b6b2 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnNetworkProviderTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnNetworkProviderTest.java
@@ -87,8 +87,8 @@ public class VcnNetworkProviderTest {
eq(mVcnNetworkProvider),
argThat(
score ->
- score.getLegacyInt()
- == Vcn.getNetworkScore().getLegacyInt()),
+ score.getLegacyInt() == Vcn.getNetworkScore().getLegacyInt()
+ && score.isTransportPrimary()),
any(),
any(),
cbCaptor.capture());