summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AconfigFlags.bp14
-rw-r--r--Android.bp3
-rw-r--r--api/Android.bp3
-rw-r--r--cmds/screencap/screencap.cpp286
-rw-r--r--core/api/current.txt51
-rw-r--r--core/api/system-current.txt46
-rw-r--r--core/api/test-current.txt1
-rw-r--r--core/java/Android.bp26
-rw-r--r--core/java/android/app/ContextImpl.java49
-rw-r--r--core/java/android/app/ForegroundServiceDelegationOptions.java40
-rw-r--r--core/java/android/app/SystemServiceRegistry.java11
-rw-r--r--core/java/android/app/contextualsearch/ContextualSearchManager.java230
-rw-r--r--core/java/android/app/contextualsearch/ContextualSearchState.aidl (renamed from core/java/android/os/WorkDuration.aidl)10
-rw-r--r--core/java/android/app/contextualsearch/ContextualSearchState.java104
-rw-r--r--core/java/android/app/contextualsearch/IContextualSearchCallback.aidl (renamed from packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/shared/SceneContainerFlagsExtension.kt)18
-rw-r--r--core/java/android/app/contextualsearch/IContextualSearchManager.aidl11
-rw-r--r--core/java/android/app/contextualsearch/flags.aconfig8
-rw-r--r--core/java/android/content/Context.java13
-rw-r--r--core/java/android/hardware/biometrics/BiometricPrompt.java83
-rw-r--r--core/java/android/hardware/biometrics/CryptoObject.java6
-rw-r--r--core/java/android/hardware/biometrics/PromptContentViewParcelable.java2
-rw-r--r--core/java/android/hardware/biometrics/PromptContentViewWithMoreOptionsButton.java198
-rw-r--r--core/java/android/hardware/biometrics/PromptInfo.java11
-rw-r--r--core/java/android/hardware/camera2/CameraDevice.java60
-rw-r--r--core/java/android/hardware/camera2/MultiResolutionImageReader.java57
-rw-r--r--core/java/android/hardware/camera2/impl/CameraDeviceSetupImpl.java1
-rw-r--r--core/java/android/hardware/camera2/params/OutputConfiguration.java462
-rw-r--r--core/java/android/hardware/camera2/params/SessionConfiguration.java49
-rw-r--r--core/java/android/hardware/camera2/params/StreamConfigurationMap.java6
-rw-r--r--core/java/android/os/IHintSession.aidl2
-rw-r--r--core/java/android/os/UserManager.java9
-rw-r--r--core/java/android/os/WorkDuration.java90
-rw-r--r--core/java/android/service/dreams/DreamService.java55
-rw-r--r--core/java/android/service/ondeviceintelligence/OnDeviceSandboxedInferenceService.java40
-rw-r--r--core/java/android/service/persistentdata/PersistentDataBlockManager.java5
-rw-r--r--core/java/android/view/ImeInsetsSourceConsumer.java45
-rw-r--r--core/java/android/view/View.java67
-rw-r--r--core/java/android/view/ViewRootImpl.java15
-rw-r--r--core/java/android/view/WindowManager.java5
-rw-r--r--core/res/Android.bp1
-rw-r--r--core/res/AndroidManifest.xml13
-rw-r--r--core/res/res/values/attrs.xml23
-rw-r--r--core/res/res/values/colors.xml566
-rw-r--r--core/res/res/values/config.xml4
-rw-r--r--core/res/res/values/public-staging.xml2
-rw-r--r--core/res/res/values/strings.xml3
-rw-r--r--core/res/res/values/symbols.xml4
-rw-r--r--core/tests/coretests/src/android/os/PerformanceHintManagerTest.java14
-rw-r--r--core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java45
-rw-r--r--data/etc/privapp-permissions-platform.xml2
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/DividerPresenter.java159
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java40
-rw-r--r--libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/DividerPresenterTest.java159
-rw-r--r--libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java5
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleFlyoutView.java62
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java1
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedAnimationController.java8
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/PhysicsAnimationLayout.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/GlobalDragListener.kt10
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java22
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java13
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java43
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java16
-rw-r--r--libs/hwui/Android.bp2
-rw-r--r--libs/hwui/WebViewFunctorManager.cpp19
-rw-r--r--libs/hwui/WebViewFunctorManager.h3
-rw-r--r--libs/hwui/platform/android/thread/CommonPoolBase.h57
-rw-r--r--libs/hwui/platform/host/thread/CommonPoolBase.h56
-rw-r--r--libs/hwui/private/hwui/WebViewFunctor.h5
-rw-r--r--libs/hwui/thread/CommonPool.cpp27
-rw-r--r--libs/hwui/thread/CommonPool.h13
-rw-r--r--media/java/android/media/MediaCodec.java4
-rw-r--r--media/java/android/media/MediaCodecInfo.java9
-rw-r--r--media/java/android/media/MediaFormat.java65
-rw-r--r--native/android/Android.bp2
-rw-r--r--native/android/performance_hint.cpp181
-rw-r--r--native/android/tests/performance_hint/Android.bp1
-rw-r--r--native/android/tests/performance_hint/PerformanceHintNativeTest.cpp299
-rw-r--r--native/webview/plat_support/draw_fn.h9
-rw-r--r--native/webview/plat_support/draw_functor.cpp21
-rw-r--r--nfc/api/current.txt3
-rw-r--r--nfc/java/android/nfc/INfcCardEmulation.aidl3
-rw-r--r--nfc/java/android/nfc/cardemulation/ApduServiceInfo.java81
-rw-r--r--nfc/java/android/nfc/cardemulation/CardEmulation.java147
-rw-r--r--packages/CompanionDeviceManager/res/values-af/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-am/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-ar/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-as/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-az/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-be/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-bg/strings.xml5
-rw-r--r--packages/CompanionDeviceManager/res/values-bn/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-bs/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-ca/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-cs/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-da/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-de/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-el/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-en-rAU/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-en-rCA/strings.xml5
-rw-r--r--packages/CompanionDeviceManager/res/values-en-rGB/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-en-rIN/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-en-rXC/strings.xml5
-rw-r--r--packages/CompanionDeviceManager/res/values-es-rUS/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-es/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-et/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-eu/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-fa/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-fi/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-fr/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-gl/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-gu/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-hi/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-hr/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-hu/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-hy/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-in/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-is/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-it/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-iw/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-ja/strings.xml5
-rw-r--r--packages/CompanionDeviceManager/res/values-ka/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-kk/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-km/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-kn/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-ko/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-ky/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-lo/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-lt/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-lv/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-mk/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-ml/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-mn/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-mr/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-ms/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-my/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-nb/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-ne/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-nl/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-or/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-pa/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-pl/strings.xml5
-rw-r--r--packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-pt/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-ro/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-ru/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-si/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-sk/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-sl/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-sq/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-sr/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-sv/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-sw/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-ta/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-te/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-th/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-tl/strings.xml5
-rw-r--r--packages/CompanionDeviceManager/res/values-tr/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-uk/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-ur/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-uz/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-vi/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml10
-rw-r--r--packages/CompanionDeviceManager/res/values-zu/strings.xml10
-rw-r--r--packages/CrashRecovery/services/java/com/android/server/RescueParty.java4
-rw-r--r--packages/CredentialManager/res/values-uz/strings.xml2
-rw-r--r--packages/SettingsLib/SearchWidget/res/values-fr-rCA/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-af/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-am/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-ar/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-as/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-az/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-b+sr+Latn/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-be/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-bg/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-bn/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-bs/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-ca/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-cs/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-da/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-de/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-el/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-en-rAU/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-en-rCA/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-en-rGB/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-en-rIN/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-en-rXC/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-es-rUS/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-es/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-et/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-eu/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-fa/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-fi/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-fr-rCA/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-fr/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-gl/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-gu/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-hi/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-hr/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-hu/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-hy/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-in/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-is/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-it/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-iw/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-ja/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-ka/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-kk/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-km/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-kn/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-ko/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-ky/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-lo/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-lt/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-lv/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-mk/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-ml/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-mn/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-mr/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-ms/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-my/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-nb/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-ne/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-nl/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-or/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-pa/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-pl/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-pt-rBR/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-pt-rPT/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-pt/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-ro/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-ru/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-si/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-sk/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-sl/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-sq/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-sr/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-sv/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-sw/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-ta/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-te/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-th/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-tl/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-tr/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-uk/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-ur/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-uz/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-vi/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-zh-rCN/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-zh-rHK/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-zh-rTW/strings.xml3
-rw-r--r--packages/SettingsLib/res/values-zu/strings.xml3
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java2
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java2
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/volume/data/repository/AudioRepository.kt2
-rw-r--r--packages/SettingsProvider/res/values-af/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-am/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-ar/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-as/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-az/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-b+sr+Latn/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-be/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-bg/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-bn/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-bs/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-ca/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-cs/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-da/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-de/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-el/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-en-rAU/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-en-rCA/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-en-rGB/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-en-rIN/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-en-rXC/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-es-rUS/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-es/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-et/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-eu/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-fa/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-fi/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-fr-rCA/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-fr/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-gl/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-gu/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-hi/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-hr/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-hu/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-hy/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-in/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-is/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-it/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-iw/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-ja/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-ka/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-kk/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-km/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-kn/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-ko/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-ky/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-lo/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-lt/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-lv/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-mk/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-ml/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-mn/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-mr/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-ms/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-my/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-nb/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-ne/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-nl/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-or/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-pa/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-pl/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-pt-rBR/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-pt-rPT/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-pt/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-ro/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-ru/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-si/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-sk/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-sl/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-sq/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-sr/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-sv/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-sw/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-ta/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-te/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-th/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-tl/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-tr/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-uk/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-ur/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-uz/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-vi/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-zh-rCN/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-zh-rHK/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-zh-rTW/strings.xml2
-rw-r--r--packages/SettingsProvider/res/values-zu/strings.xml2
-rw-r--r--packages/Shell/AndroidManifest.xml2
-rw-r--r--packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/AccessibilityMenuService.java33
-rw-r--r--packages/SystemUI/aconfig/systemui.aconfig31
-rw-r--r--packages/SystemUI/animation/Android.bp1
-rw-r--r--packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt31
-rw-r--r--packages/SystemUI/compose/core/src/com/android/compose/PlatformSlider.kt4
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenSceneBlueprintModule.kt2
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/ClockTransition.kt5
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/DefaultBlueprint.kt22
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/ShortcutsBesideUdfpsBlueprint.kt21
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/SplitShadeBlueprint.kt222
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/WeatherClockBlueprint.kt2
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/DefaultClockSection.kt187
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/NotificationSection.kt3
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/SmartSpaceSection.kt101
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/TopAreaSection.kt195
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/Notifications.kt14
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSlider.kt14
-rw-r--r--packages/SystemUI/customization/src/com/android/systemui/util/Assert.java33
-rw-r--r--packages/SystemUI/monet/Android.bp1
-rw-r--r--packages/SystemUI/monet/src/com/android/systemui/monet/ColorScheme.kt510
-rw-r--r--packages/SystemUI/monet/src/com/android/systemui/monet/SchemeClock.java55
-rw-r--r--packages/SystemUI/monet/src/com/android/systemui/monet/SchemeClockVibrant.java53
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/communal/ui/viewmodel/CommunalTransitionViewModelTest.kt89
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToLockscreenTransitionViewModelTest.kt4
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt42
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModelTest.kt40
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGlanceableHubTransitionViewModelTest.kt4
-rw-r--r--packages/SystemUI/res/layout/super_notification_shade.xml5
-rw-r--r--packages/SystemUI/res/values/dimens.xml3
-rw-r--r--packages/SystemUI/res/xml/home_controls_dream_metadata.xml1
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java8
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/SystemUIApplication.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationAnimationController.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuView.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/RadiiAnimator.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalTransitionViewModel.kt54
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractor.kt23
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractor.kt31
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardBlueprintInteractor.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractor.kt12
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/NotificationStackScrollLayoutSection.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToGlanceableHubTransitionViewModel.kt12
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToDreamingTransitionViewModel.kt12
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToLockscreenTransitionViewModel.kt22
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt35
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt41
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModel.kt15
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGlanceableHubTransitionViewModel.kt20
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaHierarchyManager.kt14
-rw-r--r--packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java49
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlags.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootViewBinder.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java24
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/domain/interactor/StatusBarKeyguardViewManagerInteractor.kt18
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotifBindPipeline.java38
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationEntryProcessorFactory.kt25
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationEntryProcessorFactoryExecutorImpl.kt56
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationEntryProcessorFactoryLooperImpl.kt60
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/Processor.kt25
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationStackAppearanceViewBinder.kt10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModel.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt21
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyConstants.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java82
-rw-r--r--packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java8
-rw-r--r--packages/SystemUI/tests/AndroidTest.xml7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationAnimationControllerTest.java35
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerWindowlessMagnifierTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractorTest.kt69
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardBlueprintInteractorTest.kt24
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelTest.kt9
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelWithKosmosTest.kt101
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaHierarchyManagerTest.kt53
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/monet/ColorSchemeTest.kt249
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java44
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotifBindPipelineTest.java15
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java38
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyConstantsTest.java10
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java2
-rw-r--r--packages/SystemUI/tests/utils/src/android/animation/AnimatorTestRule.java6
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/communal/ui/viewmodel/CommunalTransitionViewModelKosmos.kt35
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/flags/EnableSceneContainer.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorKosmos.kt1
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelKosmos.kt4
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModelKosmos.kt4
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/domain/interactor/StatusBarKeyguardViewManagerInteractorKosmos.kt (renamed from packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/domain/interactor/KeyguardViewOcclusionInteractorKosmos.kt)4
-rw-r--r--services/Android.bp2
-rw-r--r--services/accessibility/java/com/android/server/accessibility/ProxyAccessibilityServiceConnection.java6
-rw-r--r--services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java109
-rw-r--r--services/companion/java/com/android/server/companion/association/AssociationStore.java29
-rw-r--r--services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java59
-rw-r--r--services/contextualsearch/Android.bp22
-rw-r--r--services/contextualsearch/java/com/android/server/contextualsearch/ContextualSearchManagerService.java315
-rw-r--r--services/contextualsearch/java/com/android/server/contextualsearch/ContextualSearchManagerShellCommand.java78
-rw-r--r--services/core/java/com/android/server/am/ActiveServices.java8
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerConstants.java115
-rw-r--r--services/core/java/com/android/server/am/BroadcastQueueModernImpl.java76
-rw-r--r--services/core/java/com/android/server/am/EventLogTags.logtags6
-rw-r--r--services/core/java/com/android/server/am/OomAdjuster.java64
-rw-r--r--services/core/java/com/android/server/am/OomAdjusterDebugLogger.java110
-rw-r--r--services/core/java/com/android/server/am/OomAdjusterModernImpl.java2
-rw-r--r--services/core/java/com/android/server/am/PendingIntentController.java15
-rw-r--r--services/core/java/com/android/server/am/flags.aconfig15
-rw-r--r--services/core/java/com/android/server/biometrics/AuthService.java6
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodManagerService.java3
-rw-r--r--services/core/java/com/android/server/net/NetworkPolicyManagerService.java5
-rw-r--r--services/core/java/com/android/server/pm/UserRestrictionsUtils.java6
-rw-r--r--services/core/java/com/android/server/power/PowerManagerService.java2
-rw-r--r--services/core/java/com/android/server/power/ShutdownThread.java2
-rw-r--r--services/core/java/com/android/server/power/hint/HintManagerService.java46
-rw-r--r--services/core/java/com/android/server/vcn/TelephonySubscriptionTracker.java13
-rw-r--r--services/core/java/com/android/server/wallpaper/WallpaperDataParser.java3
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java12
-rw-r--r--services/core/java/com/android/server/wm/BackgroundActivityStartController.java110
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java3
-rw-r--r--services/core/java/com/android/server/wm/DisplayPolicy.java34
-rw-r--r--services/core/java/com/android/server/wm/DragDropController.java8
-rw-r--r--services/core/java/com/android/server/wm/DragState.java20
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java5
-rw-r--r--services/core/java/com/android/server/wm/utils/OptPropFactory.java233
-rw-r--r--services/core/jni/com_android_server_hint_HintManagerService.cpp76
-rw-r--r--services/java/com/android/server/SystemServer.java12
-rw-r--r--services/tests/dreamservicetests/res/xml/test_dream_metadata.xml4
-rw-r--r--services/tests/dreamservicetests/src/com/android/server/dreams/DreamServiceTest.java2
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java16
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerServiceTest.java213
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/am/BaseBroadcastQueueTest.java2
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java5
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/backup/PackageManagerBackupAgentTest.java63
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/ProxyAccessibilityServiceConnectionTest.java21
-rw-r--r--services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java9
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/UserRestrictionsUtilsTest.java6
-rw-r--r--services/tests/servicestests/src/com/android/server/power/hint/HintManagerServiceTest.java32
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/utils/OptPropFactoryTest.java286
-rw-r--r--services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java14
-rw-r--r--telephony/common/com/android/internal/telephony/CarrierAppUtils.java35
-rw-r--r--telephony/java/android/telephony/euicc/EuiccManager.java10
-rw-r--r--tools/aapt2/optimize/VersionCollapser.cpp23
494 files changed, 8245 insertions, 3077 deletions
diff --git a/AconfigFlags.bp b/AconfigFlags.bp
index 8591a9c4a195..6ecd38f054aa 100644
--- a/AconfigFlags.bp
+++ b/AconfigFlags.bp
@@ -21,6 +21,7 @@ aconfig_declarations_group {
// !!! KEEP THIS LIST ALPHABETICAL !!!
"aconfig_mediacodec_flags_java_lib",
"android.adaptiveauth.flags-aconfig-java",
+ "android.app.contextualsearch.flags-aconfig-java",
"android.app.flags-aconfig-java",
"android.app.ondeviceintelligence-aconfig-java",
"android.app.smartspace.flags-aconfig-java",
@@ -974,6 +975,19 @@ java_aconfig_library {
],
}
+// Contextual Search
+aconfig_declarations {
+ name: "android.app.contextualsearch.flags-aconfig",
+ package: "android.app.contextualsearch.flags",
+ srcs: ["core/java/android/app/contextualsearch/flags.aconfig"],
+}
+
+java_aconfig_library {
+ name: "android.app.contextualsearch.flags-aconfig-java",
+ aconfig_declarations: "android.app.contextualsearch.flags-aconfig",
+ defaults: ["framework-minus-apex-aconfig-java-defaults"],
+}
+
// Smartspace
aconfig_declarations {
name: "android.app.smartspace.flags-aconfig",
diff --git a/Android.bp b/Android.bp
index 8d7ab983593d..057b1d62ea5a 100644
--- a/Android.bp
+++ b/Android.bp
@@ -355,8 +355,11 @@ java_defaults {
"packages/modules/Media/apex/aidl/stable",
"hardware/interfaces/biometrics/common/aidl",
"hardware/interfaces/biometrics/fingerprint/aidl",
+ "hardware/interfaces/common/aidl",
+ "hardware/interfaces/common/fmq/aidl",
"hardware/interfaces/graphics/common/aidl",
"hardware/interfaces/keymaster/aidl",
+ "hardware/interfaces/power/aidl",
"system/hardware/interfaces/media/aidl",
],
},
diff --git a/api/Android.bp b/api/Android.bp
index 093ee4beab50..010a2a587057 100644
--- a/api/Android.bp
+++ b/api/Android.bp
@@ -342,8 +342,11 @@ stubs_defaults {
"packages/modules/Media/apex/aidl/stable",
"hardware/interfaces/biometrics/common/aidl",
"hardware/interfaces/biometrics/fingerprint/aidl",
+ "hardware/interfaces/common/aidl",
+ "hardware/interfaces/common/fmq/aidl",
"hardware/interfaces/graphics/common/aidl",
"hardware/interfaces/keymaster/aidl",
+ "hardware/interfaces/power/aidl",
"system/hardware/interfaces/media/aidl",
],
},
diff --git a/cmds/screencap/screencap.cpp b/cmds/screencap/screencap.cpp
index 917529ec1dcf..7e4f95bc9274 100644
--- a/cmds/screencap/screencap.cpp
+++ b/cmds/screencap/screencap.cpp
@@ -51,11 +51,13 @@ using namespace android;
void usage(const char* pname, ftl::Optional<DisplayId> displayIdOpt) {
fprintf(stderr, R"(
-usage: %s [-hp] [-d display-id] [FILENAME]
+usage: %s [-ahp] [-d display-id] [FILENAME]
-h: this message
- -p: save the file as a png.
+ -a: captures all the active displays. This appends an integer postfix to the FILENAME.
+ e.g., FILENAME_0.png, FILENAME_1.png. If both -a and -d are given, it ignores -d.
-d: specify the display ID to capture%s
see "dumpsys SurfaceFlinger --display-id" for valid display IDs.
+ -p: outputs in png format.
--hint-for-seamless If set will use the hintForSeamless path in SF
If FILENAME ends with .png it will be saved as a png.
@@ -63,11 +65,13 @@ If FILENAME is not given, the results will be printed to stdout.
)",
pname,
displayIdOpt
- .transform([](DisplayId id) {
- return std::string(ftl::Concat(" (default: ", id.value, ')').str());
- })
- .value_or(std::string())
- .c_str());
+ .transform([](DisplayId id) {
+ return std::string(ftl::Concat(
+ " (If the id is not given, it defaults to ", id.value,')'
+ ).str());
+ })
+ .value_or(std::string())
+ .c_str());
}
// For options that only exist in long-form. Anything in the
@@ -123,8 +127,8 @@ static status_t notifyMediaScanner(const char* fileName) {
int status;
int pid = fork();
if (pid < 0){
- fprintf(stderr, "Unable to fork in order to send intent for media scanner.\n");
- return UNKNOWN_ERROR;
+ fprintf(stderr, "Unable to fork in order to send intent for media scanner.\n");
+ return UNKNOWN_ERROR;
}
if (pid == 0){
int fd = open("/dev/null", O_WRONLY);
@@ -146,19 +150,119 @@ static status_t notifyMediaScanner(const char* fileName) {
return NO_ERROR;
}
+status_t capture(const DisplayId displayId,
+ const gui::CaptureArgs& captureArgs,
+ ScreenCaptureResults& outResult) {
+ sp<SyncScreenCaptureListener> captureListener = new SyncScreenCaptureListener();
+ ScreenshotClient::captureDisplay(displayId, captureArgs, captureListener);
+
+ ScreenCaptureResults captureResults = captureListener->waitForResults();
+ if (!captureResults.fenceResult.ok()) {
+ fprintf(stderr, "Failed to take screenshot. Status: %d\n",
+ fenceStatus(captureResults.fenceResult));
+ return 1;
+ }
+
+ outResult = captureResults;
+
+ return 0;
+}
+
+status_t saveImage(const char* fn, bool png, const ScreenCaptureResults& captureResults) {
+ void* base = nullptr;
+ ui::Dataspace dataspace = captureResults.capturedDataspace;
+ sp<GraphicBuffer> buffer = captureResults.buffer;
+
+ status_t result = buffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, &base);
+
+ if (base == nullptr || result != NO_ERROR) {
+ String8 reason;
+ if (result != NO_ERROR) {
+ reason.appendFormat(" Error Code: %d", result);
+ } else {
+ reason = "Failed to write to buffer";
+ }
+ fprintf(stderr, "Failed to take screenshot (%s)\n", reason.c_str());
+ return 1;
+ }
+
+ int fd = -1;
+ if (fn == nullptr) {
+ fd = dup(STDOUT_FILENO);
+ if (fd == -1) {
+ fprintf(stderr, "Error writing to stdout. (%s)\n", strerror(errno));
+ return 1;
+ }
+ } else {
+ fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0664);
+ if (fd == -1) {
+ fprintf(stderr, "Error opening file: %s (%s)\n", fn, strerror(errno));
+ return 1;
+ }
+ }
+
+ if (png) {
+ AndroidBitmapInfo info;
+ info.format = flinger2bitmapFormat(buffer->getPixelFormat());
+ info.flags = ANDROID_BITMAP_FLAGS_ALPHA_PREMUL;
+ info.width = buffer->getWidth();
+ info.height = buffer->getHeight();
+ info.stride = buffer->getStride() * bytesPerPixel(buffer->getPixelFormat());
+
+ int result = AndroidBitmap_compress(&info, static_cast<int32_t>(dataspace), base,
+ ANDROID_BITMAP_COMPRESS_FORMAT_PNG, 100, &fd,
+ [](void* fdPtr, const void* data, size_t size) -> bool {
+ int bytesWritten = write(*static_cast<int*>(fdPtr),
+ data, size);
+ return bytesWritten == size;
+ });
+
+ if (result != ANDROID_BITMAP_RESULT_SUCCESS) {
+ fprintf(stderr, "Failed to compress PNG (error code: %d)\n", result);
+ }
+
+ if (fn != NULL) {
+ notifyMediaScanner(fn);
+ }
+ } else {
+ uint32_t w = buffer->getWidth();
+ uint32_t h = buffer->getHeight();
+ uint32_t s = buffer->getStride();
+ uint32_t f = buffer->getPixelFormat();
+ uint32_t c = dataSpaceToInt(dataspace);
+
+ write(fd, &w, 4);
+ write(fd, &h, 4);
+ write(fd, &f, 4);
+ write(fd, &c, 4);
+ size_t Bpp = bytesPerPixel(f);
+ for (size_t y=0 ; y<h ; y++) {
+ write(fd, base, w*Bpp);
+ base = (void *)((char *)base + s*Bpp);
+ }
+ }
+ close(fd);
+
+ return 0;
+}
+
int main(int argc, char** argv)
{
- const std::vector<PhysicalDisplayId> ids = SurfaceComposerClient::getPhysicalDisplayIds();
- if (ids.empty()) {
+ const std::vector<PhysicalDisplayId> physicalDisplays =
+ SurfaceComposerClient::getPhysicalDisplayIds();
+
+ if (physicalDisplays.empty()) {
fprintf(stderr, "Failed to get ID for any displays.\n");
return 1;
}
std::optional<DisplayId> displayIdOpt;
+ std::vector<DisplayId> displaysToCapture;
gui::CaptureArgs captureArgs;
const char* pname = argv[0];
bool png = false;
+ bool all = false;
int c;
- while ((c = getopt_long(argc, argv, "phd:", LONG_OPTIONS, nullptr)) != -1) {
+ while ((c = getopt_long(argc, argv, "aphd:", LONG_OPTIONS, nullptr)) != -1) {
switch (c) {
case 'p':
png = true;
@@ -177,12 +281,17 @@ int main(int argc, char** argv)
fprintf(stderr, "Invalid display ID: Incorrect encoding.\n");
return 1;
}
+ displaysToCapture.push_back(displayIdOpt.value());
+ break;
+ }
+ case 'a': {
+ all = true;
break;
}
case '?':
case 'h':
- if (ids.size() == 1) {
- displayIdOpt = ids.front();
+ if (physicalDisplays.size() >= 1) {
+ displayIdOpt = physicalDisplays.front();
}
usage(pname, displayIdOpt);
return 1;
@@ -192,44 +301,52 @@ int main(int argc, char** argv)
}
}
- if (!displayIdOpt) {
- displayIdOpt = ids.front();
- if (ids.size() > 1) {
- fprintf(stderr,
- "[Warning] Multiple displays were found, but no display id was specified! "
- "Defaulting to the first display found, however this default is not guaranteed "
- "to be consistent across captures. A display id should be specified.\n");
- fprintf(stderr, "A display ID can be specified with the [-d display-id] option.\n");
- fprintf(stderr, "See \"dumpsys SurfaceFlinger --display-id\" for valid display IDs.\n");
- }
- }
-
argc -= optind;
argv += optind;
- int fd = -1;
- const char* fn = NULL;
- if (argc == 0) {
- fd = dup(STDOUT_FILENO);
- } else if (argc == 1) {
- fn = argv[0];
- fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0664);
- if (fd == -1) {
- fprintf(stderr, "Error opening file: %s (%s)\n", fn, strerror(errno));
- return 1;
+ // We don't expect more than 2 arguments.
+ if (argc >= 2) {
+ if (physicalDisplays.size() >= 1) {
+ usage(pname, physicalDisplays.front());
+ } else {
+ usage(pname, std::nullopt);
}
- const int len = strlen(fn);
- if (len >= 4 && 0 == strcmp(fn+len-4, ".png")) {
+ return 1;
+ }
+
+ std::string baseName;
+ std::string suffix;
+
+ if (argc == 1) {
+ std::string_view filename = { argv[0] };
+ if (filename.ends_with(".png")) {
+ baseName = filename.substr(0, filename.size()-4);
+ suffix = ".png";
png = true;
+ } else {
+ baseName = filename;
}
}
- if (fd == -1) {
- usage(pname, displayIdOpt);
- return 1;
+ if (all) {
+ // Ignores -d if -a is given.
+ displaysToCapture.clear();
+ for (int i = 0; i < physicalDisplays.size(); i++) {
+ displaysToCapture.push_back(physicalDisplays[i]);
+ }
}
- void* base = NULL;
+ if (displaysToCapture.empty()) {
+ displaysToCapture.push_back(physicalDisplays.front());
+ if (physicalDisplays.size() > 1) {
+ fprintf(stderr,
+ "[Warning] Multiple displays were found, but no display id was specified! "
+ "Defaulting to the first display found, however this default is not guaranteed "
+ "to be consistent across captures. A display id should be specified.\n");
+ fprintf(stderr, "A display ID can be specified with the [-d display-id] option.\n");
+ fprintf(stderr, "See \"dumpsys SurfaceFlinger --display-id\" for valid display IDs.\n");
+ }
+ }
// setThreadPoolMaxThreadCount(0) actually tells the kernel it's
// not allowed to spawn any additional threads, but we still spawn
@@ -238,74 +355,39 @@ int main(int argc, char** argv)
ProcessState::self()->setThreadPoolMaxThreadCount(0);
ProcessState::self()->startThreadPool();
- sp<SyncScreenCaptureListener> captureListener = new SyncScreenCaptureListener();
- ScreenshotClient::captureDisplay(*displayIdOpt, captureArgs, captureListener);
-
- ScreenCaptureResults captureResults = captureListener->waitForResults();
- if (!captureResults.fenceResult.ok()) {
- close(fd);
- fprintf(stderr, "Failed to take screenshot. Status: %d\n",
- fenceStatus(captureResults.fenceResult));
- return 1;
- }
- ui::Dataspace dataspace = captureResults.capturedDataspace;
- sp<GraphicBuffer> buffer = captureResults.buffer;
+ std::vector<ScreenCaptureResults> results;
+ const size_t numDisplays = displaysToCapture.size();
+ for (int i=0; i<numDisplays; i++) {
+ ScreenCaptureResults result;
- status_t result = buffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, &base);
+ // 1. Capture the screen
+ if (const status_t captureStatus =
+ capture(displaysToCapture[i], captureArgs, result) != 0) {
- if (base == nullptr || result != NO_ERROR) {
- String8 reason;
- if (result != NO_ERROR) {
- reason.appendFormat(" Error Code: %d", result);
- } else {
- reason = "Failed to write to buffer";
+ fprintf(stderr, "Capturing failed.\n");
+ return captureStatus;
}
- fprintf(stderr, "Failed to take screenshot (%s)\n", reason.c_str());
- close(fd);
- return 1;
- }
-
- if (png) {
- AndroidBitmapInfo info;
- info.format = flinger2bitmapFormat(buffer->getPixelFormat());
- info.flags = ANDROID_BITMAP_FLAGS_ALPHA_PREMUL;
- info.width = buffer->getWidth();
- info.height = buffer->getHeight();
- info.stride = buffer->getStride() * bytesPerPixel(buffer->getPixelFormat());
-
- int result = AndroidBitmap_compress(&info, static_cast<int32_t>(dataspace), base,
- ANDROID_BITMAP_COMPRESS_FORMAT_PNG, 100, &fd,
- [](void* fdPtr, const void* data, size_t size) -> bool {
- int bytesWritten = write(*static_cast<int*>(fdPtr),
- data, size);
- return bytesWritten == size;
- });
- if (result != ANDROID_BITMAP_RESULT_SUCCESS) {
- fprintf(stderr, "Failed to compress PNG (error code: %d)\n", result);
+ // 2. Save the capture result as an image.
+ // When there's more than one file to capture, add the index as postfix.
+ std::string filename;
+ if (!baseName.empty()) {
+ filename = baseName;
+ if (numDisplays > 1) {
+ filename += "_";
+ filename += std::to_string(i);
+ }
+ filename += suffix;
}
-
- if (fn != NULL) {
- notifyMediaScanner(fn);
+ const char* fn = nullptr;
+ if (!filename.empty()) {
+ fn = filename.c_str();
}
- } else {
- uint32_t w = buffer->getWidth();
- uint32_t h = buffer->getHeight();
- uint32_t s = buffer->getStride();
- uint32_t f = buffer->getPixelFormat();
- uint32_t c = dataSpaceToInt(dataspace);
-
- write(fd, &w, 4);
- write(fd, &h, 4);
- write(fd, &f, 4);
- write(fd, &c, 4);
- size_t Bpp = bytesPerPixel(f);
- for (size_t y=0 ; y<h ; y++) {
- write(fd, base, w*Bpp);
- base = (void *)((char *)base + s*Bpp);
+ if (const status_t saveImageStatus = saveImage(fn, png, result) != 0) {
+ fprintf(stderr, "Saving image failed.\n");
+ return saveImageStatus;
}
}
- close(fd);
return 0;
}
diff --git a/core/api/current.txt b/core/api/current.txt
index 2c2a75924684..bb5c091915d6 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -293,7 +293,7 @@ package android {
field public static final String SET_ALARM = "com.android.alarm.permission.SET_ALARM";
field public static final String SET_ALWAYS_FINISH = "android.permission.SET_ALWAYS_FINISH";
field public static final String SET_ANIMATION_SCALE = "android.permission.SET_ANIMATION_SCALE";
- field @FlaggedApi("android.hardware.biometrics.custom_biometric_prompt") public static final String SET_BIOMETRIC_DIALOG_LOGO = "android.permission.SET_BIOMETRIC_DIALOG_LOGO";
+ field @FlaggedApi("android.hardware.biometrics.custom_biometric_prompt") public static final String SET_BIOMETRIC_DIALOG_ADVANCED = "android.permission.SET_BIOMETRIC_DIALOG_ADVANCED";
field public static final String SET_DEBUG_APP = "android.permission.SET_DEBUG_APP";
field @Deprecated public static final String SET_PREFERRED_APPLICATIONS = "android.permission.SET_PREFERRED_APPLICATIONS";
field public static final String SET_PROCESS_LIMIT = "android.permission.SET_PROCESS_LIMIT";
@@ -18904,9 +18904,9 @@ package android.hardware.biometrics {
method @Nullable public int getAllowedAuthenticators();
method @FlaggedApi("android.hardware.biometrics.custom_biometric_prompt") @Nullable public android.hardware.biometrics.PromptContentView getContentView();
method @Nullable public CharSequence getDescription();
- method @FlaggedApi("android.hardware.biometrics.custom_biometric_prompt") @Nullable @RequiresPermission(android.Manifest.permission.SET_BIOMETRIC_DIALOG_LOGO) public android.graphics.Bitmap getLogoBitmap();
- method @FlaggedApi("android.hardware.biometrics.custom_biometric_prompt") @Nullable @RequiresPermission(android.Manifest.permission.SET_BIOMETRIC_DIALOG_LOGO) public String getLogoDescription();
- method @FlaggedApi("android.hardware.biometrics.custom_biometric_prompt") @DrawableRes @RequiresPermission(android.Manifest.permission.SET_BIOMETRIC_DIALOG_LOGO) public int getLogoRes();
+ method @FlaggedApi("android.hardware.biometrics.custom_biometric_prompt") @Nullable @RequiresPermission(android.Manifest.permission.SET_BIOMETRIC_DIALOG_ADVANCED) public android.graphics.Bitmap getLogoBitmap();
+ method @FlaggedApi("android.hardware.biometrics.custom_biometric_prompt") @Nullable @RequiresPermission(android.Manifest.permission.SET_BIOMETRIC_DIALOG_ADVANCED) public String getLogoDescription();
+ method @FlaggedApi("android.hardware.biometrics.custom_biometric_prompt") @DrawableRes @RequiresPermission(android.Manifest.permission.SET_BIOMETRIC_DIALOG_ADVANCED) public int getLogoRes();
method @Nullable public CharSequence getNegativeButtonText();
method @Nullable public CharSequence getSubtitle();
method @NonNull public CharSequence getTitle();
@@ -18956,9 +18956,9 @@ package android.hardware.biometrics {
method @FlaggedApi("android.hardware.biometrics.custom_biometric_prompt") @NonNull public android.hardware.biometrics.BiometricPrompt.Builder setContentView(@NonNull android.hardware.biometrics.PromptContentView);
method @NonNull public android.hardware.biometrics.BiometricPrompt.Builder setDescription(@NonNull CharSequence);
method @Deprecated @NonNull public android.hardware.biometrics.BiometricPrompt.Builder setDeviceCredentialAllowed(boolean);
- method @FlaggedApi("android.hardware.biometrics.custom_biometric_prompt") @NonNull @RequiresPermission(android.Manifest.permission.SET_BIOMETRIC_DIALOG_LOGO) public android.hardware.biometrics.BiometricPrompt.Builder setLogoBitmap(@NonNull android.graphics.Bitmap);
- method @FlaggedApi("android.hardware.biometrics.custom_biometric_prompt") @NonNull @RequiresPermission(android.Manifest.permission.SET_BIOMETRIC_DIALOG_LOGO) public android.hardware.biometrics.BiometricPrompt.Builder setLogoDescription(@NonNull String);
- method @FlaggedApi("android.hardware.biometrics.custom_biometric_prompt") @NonNull @RequiresPermission(android.Manifest.permission.SET_BIOMETRIC_DIALOG_LOGO) public android.hardware.biometrics.BiometricPrompt.Builder setLogoRes(@DrawableRes int);
+ method @FlaggedApi("android.hardware.biometrics.custom_biometric_prompt") @NonNull @RequiresPermission(android.Manifest.permission.SET_BIOMETRIC_DIALOG_ADVANCED) public android.hardware.biometrics.BiometricPrompt.Builder setLogoBitmap(@NonNull android.graphics.Bitmap);
+ method @FlaggedApi("android.hardware.biometrics.custom_biometric_prompt") @NonNull @RequiresPermission(android.Manifest.permission.SET_BIOMETRIC_DIALOG_ADVANCED) public android.hardware.biometrics.BiometricPrompt.Builder setLogoDescription(@NonNull String);
+ method @FlaggedApi("android.hardware.biometrics.custom_biometric_prompt") @NonNull @RequiresPermission(android.Manifest.permission.SET_BIOMETRIC_DIALOG_ADVANCED) public android.hardware.biometrics.BiometricPrompt.Builder setLogoRes(@DrawableRes int);
method @NonNull public android.hardware.biometrics.BiometricPrompt.Builder setNegativeButton(@NonNull CharSequence, @NonNull java.util.concurrent.Executor, @NonNull android.content.DialogInterface.OnClickListener);
method @NonNull public android.hardware.biometrics.BiometricPrompt.Builder setSubtitle(@NonNull CharSequence);
method @NonNull public android.hardware.biometrics.BiometricPrompt.Builder setTitle(@NonNull CharSequence);
@@ -18971,6 +18971,7 @@ package android.hardware.biometrics {
ctor @Deprecated public BiometricPrompt.CryptoObject(@NonNull android.security.identity.IdentityCredential);
ctor public BiometricPrompt.CryptoObject(@NonNull android.security.identity.PresentationSession);
ctor @FlaggedApi("android.hardware.biometrics.add_key_agreement_crypto_object") public BiometricPrompt.CryptoObject(@NonNull javax.crypto.KeyAgreement);
+ ctor @FlaggedApi("android.hardware.biometrics.get_op_id_crypto_object") public BiometricPrompt.CryptoObject(long);
method @Nullable public javax.crypto.Cipher getCipher();
method @Deprecated @Nullable public android.security.identity.IdentityCredential getIdentityCredential();
method @FlaggedApi("android.hardware.biometrics.add_key_agreement_crypto_object") @Nullable public javax.crypto.KeyAgreement getKeyAgreement();
@@ -19000,6 +19001,21 @@ package android.hardware.biometrics {
@FlaggedApi("android.hardware.biometrics.custom_biometric_prompt") public interface PromptContentView {
}
+ @FlaggedApi("android.hardware.biometrics.custom_biometric_prompt") public final class PromptContentViewWithMoreOptionsButton implements android.os.Parcelable android.hardware.biometrics.PromptContentView {
+ method public int describeContents();
+ method @Nullable @RequiresPermission(android.Manifest.permission.SET_BIOMETRIC_DIALOG_ADVANCED) public String getDescription();
+ method @NonNull @RequiresPermission(android.Manifest.permission.SET_BIOMETRIC_DIALOG_ADVANCED) public android.content.DialogInterface.OnClickListener getMoreOptionsButtonListener();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.hardware.biometrics.PromptContentViewWithMoreOptionsButton> CREATOR;
+ }
+
+ public static final class PromptContentViewWithMoreOptionsButton.Builder {
+ ctor public PromptContentViewWithMoreOptionsButton.Builder();
+ method @NonNull @RequiresPermission(android.Manifest.permission.SET_BIOMETRIC_DIALOG_ADVANCED) public android.hardware.biometrics.PromptContentViewWithMoreOptionsButton build();
+ method @NonNull @RequiresPermission(android.Manifest.permission.SET_BIOMETRIC_DIALOG_ADVANCED) public android.hardware.biometrics.PromptContentViewWithMoreOptionsButton.Builder setDescription(@NonNull String);
+ method @NonNull @RequiresPermission(android.Manifest.permission.SET_BIOMETRIC_DIALOG_ADVANCED) public android.hardware.biometrics.PromptContentViewWithMoreOptionsButton.Builder setMoreOptionsButtonListener(@NonNull java.util.concurrent.Executor, @NonNull android.content.DialogInterface.OnClickListener);
+ }
+
@FlaggedApi("android.hardware.biometrics.custom_biometric_prompt") public final class PromptVerticalListContentView implements android.os.Parcelable android.hardware.biometrics.PromptContentView {
method public int describeContents();
method @Nullable public String getDescription();
@@ -20121,9 +20137,14 @@ package android.hardware.camera2.params {
ctor public OutputConfiguration(@NonNull android.view.Surface);
ctor public OutputConfiguration(int, @NonNull android.view.Surface);
ctor public <T> OutputConfiguration(@NonNull android.util.Size, @NonNull Class<T>);
+ ctor @FlaggedApi("com.android.internal.camera.flags.camera_device_setup") public OutputConfiguration(int, @NonNull android.util.Size);
+ ctor @FlaggedApi("com.android.internal.camera.flags.camera_device_setup") public OutputConfiguration(int, int, @NonNull android.util.Size);
+ ctor @FlaggedApi("com.android.internal.camera.flags.camera_device_setup") public OutputConfiguration(int, @NonNull android.util.Size, long);
+ ctor @FlaggedApi("com.android.internal.camera.flags.camera_device_setup") public OutputConfiguration(int, int, @NonNull android.util.Size, long);
method public void addSensorPixelModeUsed(int);
method public void addSurface(@NonNull android.view.Surface);
method @NonNull public static java.util.Collection<android.hardware.camera2.params.OutputConfiguration> createInstancesForMultiResolutionOutput(@NonNull android.hardware.camera2.MultiResolutionImageReader);
+ method @FlaggedApi("com.android.internal.camera.flags.camera_device_setup") @NonNull public static java.util.List<android.hardware.camera2.params.OutputConfiguration> createInstancesForMultiResolutionOutput(@NonNull java.util.Collection<android.hardware.camera2.params.MultiResolutionStreamInfo>, int);
method public int describeContents();
method public void enableSurfaceSharing();
method public long getDynamicRangeProfile();
@@ -20142,6 +20163,7 @@ package android.hardware.camera2.params {
method public void setPhysicalCameraId(@Nullable String);
method public void setReadoutTimestampEnabled(boolean);
method public void setStreamUseCase(long);
+ method @FlaggedApi("com.android.internal.camera.flags.camera_device_setup") public static void setSurfacesForMultiResolutionOutput(@NonNull java.util.Collection<android.hardware.camera2.params.OutputConfiguration>, @NonNull android.hardware.camera2.MultiResolutionImageReader);
method public void setTimestampBase(int);
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.hardware.camera2.params.OutputConfiguration> CREATOR;
@@ -20203,6 +20225,7 @@ package android.hardware.camera2.params {
public final class SessionConfiguration implements android.os.Parcelable {
ctor public SessionConfiguration(int, @NonNull java.util.List<android.hardware.camera2.params.OutputConfiguration>, @NonNull java.util.concurrent.Executor, @NonNull android.hardware.camera2.CameraCaptureSession.StateCallback);
+ ctor @FlaggedApi("com.android.internal.camera.flags.camera_device_setup") public SessionConfiguration(int, @NonNull java.util.List<android.hardware.camera2.params.OutputConfiguration>);
method public void clearColorSpace();
method public int describeContents();
method @Nullable public android.graphics.ColorSpace getColorSpace();
@@ -20212,6 +20235,7 @@ package android.hardware.camera2.params {
method public android.hardware.camera2.CaptureRequest getSessionParameters();
method public int getSessionType();
method public android.hardware.camera2.CameraCaptureSession.StateCallback getStateCallback();
+ method @FlaggedApi("com.android.internal.camera.flags.camera_device_setup") public void setCallback(@NonNull java.util.concurrent.Executor, @NonNull android.hardware.camera2.CameraCaptureSession.StateCallback);
method public void setColorSpace(@NonNull android.graphics.ColorSpace.Named);
method public void setInputConfiguration(@NonNull android.hardware.camera2.params.InputConfiguration);
method public void setSessionParameters(android.hardware.camera2.CaptureRequest);
@@ -23711,6 +23735,13 @@ package android.media {
field public static final int VIDEO_ENCODING_STATISTICS_LEVEL_NONE = 0; // 0x0
}
+ @FlaggedApi("android.media.codec.region_of_interest") public static final class MediaFormat.QpOffsetRect {
+ ctor public MediaFormat.QpOffsetRect(@NonNull android.graphics.Rect, int);
+ method @NonNull public String flattenToString();
+ method @NonNull public static String flattenToString(@NonNull java.util.List<android.media.MediaFormat.QpOffsetRect>);
+ method public void set(@NonNull android.graphics.Rect, int);
+ }
+
public final class MediaMetadata implements android.os.Parcelable {
method public boolean containsKey(String);
method public int describeContents();
@@ -33960,6 +33991,7 @@ package android.os {
method public static boolean supportsMultipleUsers();
field public static final String ALLOW_PARENT_PROFILE_APP_LINKING = "allow_parent_profile_app_linking";
field @Deprecated public static final String DISALLOW_ADD_MANAGED_PROFILE = "no_add_managed_profile";
+ field @FlaggedApi("android.os.allow_private_profile") public static final String DISALLOW_ADD_PRIVATE_PROFILE = "no_add_private_profile";
field public static final String DISALLOW_ADD_USER = "no_add_user";
field public static final String DISALLOW_ADD_WIFI_CONFIG = "no_add_wifi_config";
field public static final String DISALLOW_ADJUST_VOLUME = "no_adjust_volume";
@@ -34147,9 +34179,8 @@ package android.os {
method @RequiresPermission(android.Manifest.permission.VIBRATE) public final void vibrate(@NonNull android.os.CombinedVibration, @Nullable android.os.VibrationAttributes);
}
- @FlaggedApi("android.os.adpf_gpu_report_actual_work_duration") public final class WorkDuration implements android.os.Parcelable {
+ @FlaggedApi("android.os.adpf_gpu_report_actual_work_duration") public final class WorkDuration {
ctor public WorkDuration();
- method public int describeContents();
method public long getActualCpuDurationNanos();
method public long getActualGpuDurationNanos();
method public long getActualTotalDurationNanos();
@@ -34158,8 +34189,6 @@ package android.os {
method public void setActualGpuDurationNanos(long);
method public void setActualTotalDurationNanos(long);
method public void setWorkPeriodStartTimestampNanos(long);
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.os.WorkDuration> CREATOR;
}
public class WorkSource implements android.os.Parcelable {
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 7aeecbfeb3ad..161904976743 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -7,6 +7,7 @@ package android {
field public static final String ACCESS_BROADCAST_RADIO = "android.permission.ACCESS_BROADCAST_RADIO";
field public static final String ACCESS_BROADCAST_RESPONSE_STATS = "android.permission.ACCESS_BROADCAST_RESPONSE_STATS";
field public static final String ACCESS_CACHE_FILESYSTEM = "android.permission.ACCESS_CACHE_FILESYSTEM";
+ field @FlaggedApi("android.app.contextualsearch.flags.enable_service") public static final String ACCESS_CONTEXTUAL_SEARCH = "android.permission.ACCESS_CONTEXTUAL_SEARCH";
field public static final String ACCESS_CONTEXT_HUB = "android.permission.ACCESS_CONTEXT_HUB";
field public static final String ACCESS_DRM_CERTIFICATES = "android.permission.ACCESS_DRM_CERTIFICATES";
field @Deprecated public static final String ACCESS_FM_RADIO = "android.permission.ACCESS_FM_RADIO";
@@ -2176,6 +2177,39 @@ package android.app.contentsuggestions {
}
+package android.app.contextualsearch {
+
+ @FlaggedApi("android.app.contextualsearch.flags.enable_service") public class ContextualSearchManager {
+ method public void getContextualSearchState(@NonNull android.os.IBinder, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<android.app.contextualsearch.ContextualSearchState,java.lang.Throwable>);
+ method @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXTUAL_SEARCH) public void startContextualSearch(int);
+ field public static final String ACTION_LAUNCH_CONTEXTUAL_SEARCH = "android.app.contextualsearch.action.LAUNCH_CONTEXTUAL_SEARCH";
+ field public static final int ENTRYPOINT_LONG_PRESS_HOME = 2; // 0x2
+ field public static final int ENTRYPOINT_LONG_PRESS_META = 10; // 0xa
+ field public static final int ENTRYPOINT_LONG_PRESS_NAV_HANDLE = 1; // 0x1
+ field public static final int ENTRYPOINT_LONG_PRESS_OVERVIEW = 3; // 0x3
+ field public static final int ENTRYPOINT_OVERVIEW_ACTION = 4; // 0x4
+ field public static final int ENTRYPOINT_OVERVIEW_MENU = 5; // 0x5
+ field public static final int ENTRYPOINT_SYSTEM_ACTION = 9; // 0x9
+ field public static final String EXTRA_ENTRYPOINT = "android.app.contextualsearch.extra.ENTRYPOINT";
+ field public static final String EXTRA_FLAG_SECURE_FOUND = "android.app.contextualsearch.extra.FLAG_SECURE_FOUND";
+ field public static final String EXTRA_IS_MANAGED_PROFILE_VISIBLE = "android.app.contextualsearch.extra.IS_MANAGED_PROFILE_VISIBLE";
+ field public static final String EXTRA_SCREENSHOT = "android.app.contextualsearch.extra.SCREENSHOT";
+ field public static final String EXTRA_TOKEN = "android.app.contextualsearch.extra.TOKEN";
+ field public static final String EXTRA_VISIBLE_PACKAGE_NAMES = "android.app.contextualsearch.extra.VISIBLE_PACKAGE_NAMES";
+ }
+
+ @FlaggedApi("android.app.contextualsearch.flags.enable_service") public final class ContextualSearchState implements android.os.Parcelable {
+ ctor public ContextualSearchState(@Nullable android.app.assist.AssistStructure, @Nullable android.app.assist.AssistContent, @NonNull android.os.Bundle);
+ method public int describeContents();
+ method @Nullable public android.app.assist.AssistContent getContent();
+ method @NonNull public android.os.Bundle getExtras();
+ method @Nullable public android.app.assist.AssistStructure getStructure();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.app.contextualsearch.ContextualSearchState> CREATOR;
+ }
+
+}
+
package android.app.job {
public abstract class JobScheduler {
@@ -3747,6 +3781,7 @@ package android.content {
field public static final String CLOUDSEARCH_SERVICE = "cloudsearch";
field public static final String CONTENT_SUGGESTIONS_SERVICE = "content_suggestions";
field public static final String CONTEXTHUB_SERVICE = "contexthub";
+ field @FlaggedApi("android.app.contextualsearch.flags.enable_service") public static final String CONTEXTUAL_SEARCH_SERVICE = "contextual_search";
field @FlaggedApi("android.permission.flags.enhanced_confirmation_mode_apis_enabled") public static final String ECM_ENHANCED_CONFIRMATION_SERVICE = "ecm_enhanced_confirmation";
field public static final String ETHERNET_SERVICE = "ethernet";
field public static final String EUICC_CARD_SERVICE = "euicc_card";
@@ -10403,6 +10438,7 @@ package android.nfc.cardemulation {
@FlaggedApi("android.nfc.enable_nfc_mainline") public final class ApduServiceInfo implements android.os.Parcelable {
ctor @FlaggedApi("android.nfc.enable_nfc_mainline") public ApduServiceInfo(@NonNull android.content.pm.PackageManager, @NonNull android.content.pm.ResolveInfo, boolean) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
method @FlaggedApi("android.nfc.nfc_read_polling_loop") public void addPollingLoopFilter(@NonNull String, boolean);
+ method @FlaggedApi("android.nfc.nfc_read_polling_loop") public void addPollingLoopPatternFilter(@NonNull String, boolean);
method @FlaggedApi("android.nfc.enable_nfc_mainline") public int describeContents();
method @FlaggedApi("android.nfc.enable_nfc_mainline") public void dump(@NonNull android.os.ParcelFileDescriptor, @NonNull java.io.PrintWriter, @NonNull String[]);
method @FlaggedApi("android.nfc.enable_nfc_mainline") public void dumpDebug(@NonNull android.util.proto.ProtoOutputStream);
@@ -10414,6 +10450,7 @@ package android.nfc.cardemulation {
method @FlaggedApi("android.nfc.enable_nfc_mainline") @NonNull public android.nfc.cardemulation.AidGroup getDynamicAidGroupForCategory(@NonNull String);
method @FlaggedApi("android.nfc.enable_nfc_mainline") @Nullable public String getOffHostSecureElement();
method @FlaggedApi("android.nfc.nfc_read_polling_loop") @NonNull public java.util.List<java.lang.String> getPollingLoopFilters();
+ method @FlaggedApi("android.nfc.nfc_read_polling_loop") @NonNull public java.util.List<java.util.regex.Pattern> getPollingLoopPatternFilters();
method @FlaggedApi("android.nfc.enable_nfc_mainline") @NonNull public java.util.List<java.lang.String> getPrefixAids();
method @FlaggedApi("android.nfc.enable_nfc_mainline") @NonNull public String getSettingsActivityName();
method @FlaggedApi("android.nfc.nfc_read_polling_loop") public boolean getShouldAutoTransact(@NonNull String);
@@ -10428,6 +10465,7 @@ package android.nfc.cardemulation {
method @FlaggedApi("android.nfc.enable_nfc_mainline") @NonNull public CharSequence loadLabel(@NonNull android.content.pm.PackageManager);
method @FlaggedApi("android.nfc.enable_nfc_mainline") @NonNull public boolean removeDynamicAidGroupForCategory(@NonNull String);
method @FlaggedApi("android.nfc.nfc_read_polling_loop") public void removePollingLoopFilter(@NonNull String);
+ method @FlaggedApi("android.nfc.nfc_read_polling_loop") public void removePollingLoopPatternFilter(@NonNull String);
method @FlaggedApi("android.nfc.enable_nfc_mainline") public boolean requiresScreenOn();
method @FlaggedApi("android.nfc.enable_nfc_mainline") public boolean requiresUnlock();
method @FlaggedApi("android.nfc.enable_nfc_mainline") public void resetOffHostSecureElement();
@@ -12956,15 +12994,15 @@ package android.service.ondeviceintelligence {
@FlaggedApi("android.app.ondeviceintelligence.flags.enable_on_device_intelligence") public abstract class OnDeviceSandboxedInferenceService extends android.app.Service {
ctor public OnDeviceSandboxedInferenceService();
- method public final void fetchFeatureFileInputStreamMap(@NonNull android.app.ondeviceintelligence.Feature, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.util.Map<java.lang.String,java.io.FileInputStream>>);
+ method public final void fetchFeatureFileDescriptorMap(@NonNull android.app.ondeviceintelligence.Feature, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.util.Map<java.lang.String,android.os.ParcelFileDescriptor>>);
method @NonNull public java.util.concurrent.Executor getCallbackExecutor();
+ method public final void getReadOnlyFileDescriptor(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.os.ParcelFileDescriptor>) throws java.io.FileNotFoundException;
method @Nullable public final android.os.IBinder onBind(@NonNull android.content.Intent);
method @NonNull public abstract void onProcessRequest(int, @NonNull android.app.ondeviceintelligence.Feature, @NonNull android.os.Bundle, int, @Nullable android.os.CancellationSignal, @Nullable android.app.ondeviceintelligence.ProcessingSignal, @NonNull android.app.ondeviceintelligence.ProcessingCallback);
method @NonNull public abstract void onProcessRequestStreaming(int, @NonNull android.app.ondeviceintelligence.Feature, @NonNull android.os.Bundle, int, @Nullable android.os.CancellationSignal, @Nullable android.app.ondeviceintelligence.ProcessingSignal, @NonNull android.app.ondeviceintelligence.StreamingProcessingCallback);
method @NonNull public abstract void onTokenInfoRequest(int, @NonNull android.app.ondeviceintelligence.Feature, @NonNull android.os.Bundle, @Nullable android.os.CancellationSignal, @NonNull android.os.OutcomeReceiver<android.app.ondeviceintelligence.TokenInfo,android.app.ondeviceintelligence.OnDeviceIntelligenceException>);
method public abstract void onUpdateProcessingState(@NonNull android.os.Bundle, @NonNull android.os.OutcomeReceiver<android.os.PersistableBundle,android.app.ondeviceintelligence.OnDeviceIntelligenceException>);
method public final java.io.FileInputStream openFileInput(@NonNull String) throws java.io.FileNotFoundException;
- method public final void openFileInputAsync(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.io.FileInputStream>) throws java.io.FileNotFoundException;
field public static final String SERVICE_INTERFACE = "android.service.ondeviceintelligence.OnDeviceSandboxedInferenceService";
}
@@ -12979,11 +13017,11 @@ package android.service.persistentdata {
method public long getMaximumDataBlockSize();
method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_OEM_UNLOCK_STATE, "android.permission.OEM_UNLOCK_STATE"}) public boolean getOemUnlockEnabled();
method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_PDB_STATE) public String getPersistentDataPackageName();
- method public byte[] read();
+ method @Nullable public byte[] read();
method @FlaggedApi("android.security.frp_enforcement") public boolean setFactoryResetProtectionSecret(@NonNull byte[]);
method @Deprecated @RequiresPermission("android.permission.OEM_UNLOCK_STATE") public void setOemUnlockEnabled(boolean);
method @RequiresPermission("android.permission.OEM_UNLOCK_STATE") public void wipe();
- method public int write(byte[]);
+ method public int write(@Nullable byte[]);
field public static final int FLASH_LOCK_LOCKED = 1; // 0x1
field public static final int FLASH_LOCK_UNKNOWN = -1; // 0xffffffff
field public static final int FLASH_LOCK_UNLOCKED = 0; // 0x0
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index c1af719e91c9..0a26490b772f 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -3065,6 +3065,7 @@ package android.service.dreams {
}
public static final class DreamService.DreamMetadata {
+ field @FlaggedApi("android.service.controls.flags.home_panel_dream") @NonNull public final int dreamCategory;
field @Nullable public final android.graphics.drawable.Drawable previewImage;
field @Nullable public final android.content.ComponentName settingsActivity;
field @NonNull public final boolean showComplications;
diff --git a/core/java/Android.bp b/core/java/Android.bp
index 4f96206bfd08..db5888ec64b4 100644
--- a/core/java/Android.bp
+++ b/core/java/Android.bp
@@ -135,8 +135,6 @@ filegroup {
srcs: [
"android/os/Temperature.aidl",
"android/os/CoolingDevice.aidl",
- "android/os/IHintManager.aidl",
- "android/os/IHintSession.aidl",
"android/os/IThermalEventListener.aidl",
"android/os/IThermalStatusListener.aidl",
"android/os/IThermalService.aidl",
@@ -145,6 +143,30 @@ filegroup {
],
}
+aidl_interface {
+ name: "android.os.hintmanager_aidl",
+ srcs: [
+ "android/os/IHintManager.aidl",
+ "android/os/IHintSession.aidl",
+ ],
+ unstable: true,
+ backend: {
+ java: {
+ sdk_version: "module_current",
+ enabled: true,
+ },
+ cpp: {
+ enabled: false,
+ },
+ ndk: {
+ enabled: true,
+ },
+ },
+ imports: [
+ "android.hardware.power-V5",
+ ],
+}
+
aidl_library {
name: "ILogcatManagerService_aidl",
srcs: ["android/os/logcat/ILogcatManagerService.aidl"],
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index df566db5ba97..6f6e0911fa4b 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -272,10 +272,15 @@ class ContextImpl extends Context {
@UnsupportedAppUsage
private Context mOuterContext;
+
+ private final Object mThemeLock = new Object();
@UnsupportedAppUsage
+ @GuardedBy("mThemeLock")
private int mThemeResource = 0;
@UnsupportedAppUsage
+ @GuardedBy("mThemeLock")
private Resources.Theme mTheme = null;
+
@UnsupportedAppUsage
private PackageManager mPackageManager;
private Context mReceiverRestrictedContext = null;
@@ -288,7 +293,6 @@ class ContextImpl extends Context {
private ContentCaptureOptions mContentCaptureOptions = null;
- private final Object mSync = new Object();
/**
* Indicates this {@link Context} can not handle UI components properly and is not associated
* with a {@link Display} instance.
@@ -340,20 +344,21 @@ class ContextImpl extends Context {
*/
private boolean mOwnsToken = false;
- @GuardedBy("mSync")
+ private final Object mDirsLock = new Object();
+ @GuardedBy("mDirsLock")
private File mDatabasesDir;
- @GuardedBy("mSync")
+ @GuardedBy("mDirsLock")
@UnsupportedAppUsage
private File mPreferencesDir;
- @GuardedBy("mSync")
+ @GuardedBy("mDirsLock")
private File mFilesDir;
- @GuardedBy("mSync")
+ @GuardedBy("mDirsLock")
private File mCratesDir;
- @GuardedBy("mSync")
+ @GuardedBy("mDirsLock")
private File mNoBackupFilesDir;
- @GuardedBy("mSync")
+ @GuardedBy("mDirsLock")
private File mCacheDir;
- @GuardedBy("mSync")
+ @GuardedBy("mDirsLock")
private File mCodeCacheDir;
// The system service cache for the system services that are cached per-ContextImpl.
@@ -458,7 +463,7 @@ class ContextImpl extends Context {
@Override
public void setTheme(int resId) {
- synchronized (mSync) {
+ synchronized (mThemeLock) {
if (mThemeResource != resId) {
mThemeResource = resId;
initializeTheme();
@@ -468,14 +473,14 @@ class ContextImpl extends Context {
@Override
public int getThemeResId() {
- synchronized (mSync) {
+ synchronized (mThemeLock) {
return mThemeResource;
}
}
@Override
public Resources.Theme getTheme() {
- synchronized (mSync) {
+ synchronized (mThemeLock) {
if (mTheme != null) {
return mTheme;
}
@@ -737,7 +742,7 @@ class ContextImpl extends Context {
@UnsupportedAppUsage
private File getPreferencesDir() {
- synchronized (mSync) {
+ synchronized (mDirsLock) {
if (mPreferencesDir == null) {
mPreferencesDir = new File(getDataDir(), "shared_prefs");
}
@@ -826,7 +831,7 @@ class ContextImpl extends Context {
@Override
public File getFilesDir() {
- synchronized (mSync) {
+ synchronized (mDirsLock) {
if (mFilesDir == null) {
mFilesDir = new File(getDataDir(), "files");
}
@@ -841,7 +846,7 @@ class ContextImpl extends Context {
final Path absoluteNormalizedCratePath = cratesRootPath.resolve(crateId)
.toAbsolutePath().normalize();
- synchronized (mSync) {
+ synchronized (mDirsLock) {
if (mCratesDir == null) {
mCratesDir = cratesRootPath.toFile();
}
@@ -854,7 +859,7 @@ class ContextImpl extends Context {
@Override
public File getNoBackupFilesDir() {
- synchronized (mSync) {
+ synchronized (mDirsLock) {
if (mNoBackupFilesDir == null) {
mNoBackupFilesDir = new File(getDataDir(), "no_backup");
}
@@ -871,7 +876,7 @@ class ContextImpl extends Context {
@Override
public File[] getExternalFilesDirs(String type) {
- synchronized (mSync) {
+ synchronized (mDirsLock) {
File[] dirs = Environment.buildExternalStorageAppFilesDirs(getPackageName());
if (type != null) {
dirs = Environment.buildPaths(dirs, type);
@@ -889,7 +894,7 @@ class ContextImpl extends Context {
@Override
public File[] getObbDirs() {
- synchronized (mSync) {
+ synchronized (mDirsLock) {
File[] dirs = Environment.buildExternalStorageAppObbDirs(getPackageName());
return ensureExternalDirsExistOrFilter(dirs, true /* tryCreateInProcess */);
}
@@ -897,7 +902,7 @@ class ContextImpl extends Context {
@Override
public File getCacheDir() {
- synchronized (mSync) {
+ synchronized (mDirsLock) {
if (mCacheDir == null) {
mCacheDir = new File(getDataDir(), "cache");
}
@@ -907,7 +912,7 @@ class ContextImpl extends Context {
@Override
public File getCodeCacheDir() {
- synchronized (mSync) {
+ synchronized (mDirsLock) {
if (mCodeCacheDir == null) {
mCodeCacheDir = getCodeCacheDirBeforeBind(getDataDir());
}
@@ -933,7 +938,7 @@ class ContextImpl extends Context {
@Override
public File[] getExternalCacheDirs() {
- synchronized (mSync) {
+ synchronized (mDirsLock) {
File[] dirs = Environment.buildExternalStorageAppCacheDirs(getPackageName());
// We don't try to create cache directories in-process, because they need special
// setup for accurate quota tracking. This ensures the cache dirs are always
@@ -944,7 +949,7 @@ class ContextImpl extends Context {
@Override
public File[] getExternalMediaDirs() {
- synchronized (mSync) {
+ synchronized (mDirsLock) {
File[] dirs = Environment.buildExternalStorageAppMediaDirs(getPackageName());
return ensureExternalDirsExistOrFilter(dirs, true /* tryCreateInProcess */);
}
@@ -1046,7 +1051,7 @@ class ContextImpl extends Context {
}
private File getDatabasesDir() {
- synchronized (mSync) {
+ synchronized (mDirsLock) {
if (mDatabasesDir == null) {
if ("android".equals(getPackageName())) {
mDatabasesDir = new File("/data/system");
diff --git a/core/java/android/app/ForegroundServiceDelegationOptions.java b/core/java/android/app/ForegroundServiceDelegationOptions.java
index 875e01f32f54..d6b6a5844ff1 100644
--- a/core/java/android/app/ForegroundServiceDelegationOptions.java
+++ b/core/java/android/app/ForegroundServiceDelegationOptions.java
@@ -92,6 +92,16 @@ public class ForegroundServiceDelegationOptions {
*/
public final @DelegationService int mDelegationService;
+ /**
+ * The optional notification Id of the foreground service delegation.
+ */
+ public final int mClientNotificationId;
+
+ /**
+ * The optional notification of the foreground service delegation.
+ */
+ public final @Nullable Notification mClientNotification;
+
public ForegroundServiceDelegationOptions(int clientPid,
int clientUid,
@NonNull String clientPackageName,
@@ -100,6 +110,21 @@ public class ForegroundServiceDelegationOptions {
@NonNull String clientInstanceName,
int foregroundServiceTypes,
@DelegationService int delegationService) {
+ this(clientPid, clientUid, clientPackageName, clientAppThread, isSticky,
+ clientInstanceName, foregroundServiceTypes, delegationService,
+ 0 /* notificationId */, null /* notification */);
+ }
+
+ public ForegroundServiceDelegationOptions(int clientPid,
+ int clientUid,
+ @NonNull String clientPackageName,
+ @NonNull IApplicationThread clientAppThread,
+ boolean isSticky,
+ @NonNull String clientInstanceName,
+ int foregroundServiceTypes,
+ @DelegationService int delegationService,
+ int clientNotificationId,
+ @Nullable Notification clientNotification) {
mClientPid = clientPid;
mClientUid = clientUid;
mClientPackageName = clientPackageName;
@@ -108,6 +133,8 @@ public class ForegroundServiceDelegationOptions {
mClientInstanceName = clientInstanceName;
mForegroundServiceTypes = foregroundServiceTypes;
mDelegationService = delegationService;
+ mClientNotificationId = clientNotificationId;
+ mClientNotification = clientNotification;
}
/**
@@ -201,7 +228,8 @@ public class ForegroundServiceDelegationOptions {
int mClientPid; // The actual app PID
int mClientUid; // The actual app UID
String mClientPackageName; // The actual app's package name
- int mClientNotificationId; // The actual app's notification
+ int mClientNotificationId; // The actual app's notification id
+ Notification mClientNotification; // The actual app's notification
IApplicationThread mClientAppThread; // The actual app's app thread
boolean mSticky; // Is it a sticky service
String mClientInstanceName; // The delegation service instance name
@@ -233,10 +261,12 @@ public class ForegroundServiceDelegationOptions {
}
/**
- * Set the notification ID from the client app.
+ * Set the notification from the client app.
*/
- public Builder setClientNotificationId(int clientNotificationId) {
+ public Builder setClientNotification(int clientNotificationId,
+ @Nullable Notification clientNotification) {
mClientNotificationId = clientNotificationId;
+ mClientNotification = clientNotification;
return this;
}
@@ -291,7 +321,9 @@ public class ForegroundServiceDelegationOptions {
mSticky,
mClientInstanceName,
mForegroundServiceTypes,
- mDelegationService
+ mDelegationService,
+ mClientNotificationId,
+ mClientNotification
);
}
}
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index fa4a4009ebc9..66269a52f0c7 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -32,6 +32,7 @@ import android.app.appsearch.AppSearchManagerFrameworkInitializer;
import android.app.blob.BlobStoreManagerFrameworkInitializer;
import android.app.contentsuggestions.ContentSuggestionsManager;
import android.app.contentsuggestions.IContentSuggestionsManager;
+import android.app.contextualsearch.ContextualSearchManager;
import android.app.ecm.EnhancedConfirmationFrameworkInitializer;
import android.app.job.JobSchedulerFrameworkInitializer;
import android.app.ondeviceintelligence.IOnDeviceIntelligenceManager;
@@ -1282,6 +1283,16 @@ public final class SystemServiceRegistry {
}
});
+ registerService(Context.CONTEXTUAL_SEARCH_SERVICE, ContextualSearchManager.class,
+ new CachedServiceFetcher<>() {
+ @Override
+ public ContextualSearchManager createService(ContextImpl ctx)
+ throws ServiceNotFoundException {
+ IBinder b = ServiceManager.getService(Context.CONTEXTUAL_SEARCH_SERVICE);
+ return b == null ? null : new ContextualSearchManager();
+ }
+ });
+
registerService(Context.APP_PREDICTION_SERVICE, AppPredictionManager.class,
new CachedServiceFetcher<AppPredictionManager>() {
@Override
diff --git a/core/java/android/app/contextualsearch/ContextualSearchManager.java b/core/java/android/app/contextualsearch/ContextualSearchManager.java
new file mode 100644
index 000000000000..693de219e7d7
--- /dev/null
+++ b/core/java/android/app/contextualsearch/ContextualSearchManager.java
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.contextualsearch;
+
+import static android.Manifest.permission.ACCESS_CONTEXTUAL_SEARCH;
+
+import android.annotation.CallbackExecutor;
+import android.annotation.FlaggedApi;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
+import android.app.contextualsearch.flags.Flags;
+import android.content.Context;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.OutcomeReceiver;
+import android.os.ParcelableException;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.util.Log;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.concurrent.Executor;
+
+/**
+ * {@link ContextualSearchManager} is a system service to facilitate contextual search experience on
+ * configured Android devices.
+ * <p>
+ * This class lets
+ * <ul>
+ * <li> a caller start contextual search by calling {@link #startContextualSearch} method.
+ * <li> a handler request {@link ContextualSearchState} by calling the
+ * {@link #getContextualSearchState} method.
+ * </ul>
+ *
+ * @hide
+ */
+@SystemApi
+@FlaggedApi(Flags.FLAG_ENABLE_SERVICE)
+public class ContextualSearchManager {
+
+ /**
+ * Key to get the entrypoint from the extras of the activity launched by contextual search.
+ * Only supposed to be used with ACTON_LAUNCH_CONTEXTUAL_SEARCH.
+ */
+ public static final String EXTRA_ENTRYPOINT =
+ "android.app.contextualsearch.extra.ENTRYPOINT";
+ /**
+ * Key to get the flag_secure value from the extras of the activity launched by contextual
+ * search. The value will be true if flag_secure is found in any of the visible activities.
+ * Only supposed to be used with ACTON_LAUNCH_CONTEXTUAL_SEARCH.
+ */
+ public static final String EXTRA_FLAG_SECURE_FOUND =
+ "android.app.contextualsearch.extra.FLAG_SECURE_FOUND";
+ /**
+ * Key to get the screenshot from the extras of the activity launched by contextual search.
+ * Only supposed to be used with ACTON_LAUNCH_CONTEXTUAL_SEARCH.
+ */
+ public static final String EXTRA_SCREENSHOT =
+ "android.app.contextualsearch.extra.SCREENSHOT";
+ /**
+ * Key to check whether managed profile is visible from the extras of the activity launched by
+ * contextual search. The value will be true if any one of the visible apps is managed.
+ * Only supposed to be used with ACTON_LAUNCH_CONTEXTUAL_SEARCH.
+ */
+ public static final String EXTRA_IS_MANAGED_PROFILE_VISIBLE =
+ "android.app.contextualsearch.extra.IS_MANAGED_PROFILE_VISIBLE";
+ /**
+ * Key to get the list of visible packages from the extras of the activity launched by
+ * contextual search.
+ * Only supposed to be used with ACTON_LAUNCH_CONTEXTUAL_SEARCH.
+ */
+ public static final String EXTRA_VISIBLE_PACKAGE_NAMES =
+ "android.app.contextualsearch.extra.VISIBLE_PACKAGE_NAMES";
+
+ /**
+ * Key to get the binder token from the extras of the activity launched by contextual search.
+ * This token is needed to invoke {@link #getContextualSearchState} method.
+ * Only supposed to be used with ACTON_LAUNCH_CONTEXTUAL_SEARCH.
+ */
+ public static final String EXTRA_TOKEN = "android.app.contextualsearch.extra.TOKEN";
+ /**
+ * Intent action for contextual search invocation. The app providing the contextual search
+ * experience must add this intent filter action to the activity it wants to be launched.
+ * <br>
+ * <b>Note</b> This activity must not be exported.
+ */
+ public static final String ACTION_LAUNCH_CONTEXTUAL_SEARCH =
+ "android.app.contextualsearch.action.LAUNCH_CONTEXTUAL_SEARCH";
+
+ /** Entrypoint to be used when a user long presses on the nav handle. */
+ public static final int ENTRYPOINT_LONG_PRESS_NAV_HANDLE = 1;
+ /** Entrypoint to be used when a user long presses on the home button. */
+ public static final int ENTRYPOINT_LONG_PRESS_HOME = 2;
+ /** Entrypoint to be used when a user long presses on the overview button. */
+ public static final int ENTRYPOINT_LONG_PRESS_OVERVIEW = 3;
+ /** Entrypoint to be used when a user presses the action button in overview. */
+ public static final int ENTRYPOINT_OVERVIEW_ACTION = 4;
+ /** Entrypoint to be used when a user presses the context menu button in overview. */
+ public static final int ENTRYPOINT_OVERVIEW_MENU = 5;
+ /** Entrypoint to be used by system actions like TalkBack, Accessibility etc. */
+ public static final int ENTRYPOINT_SYSTEM_ACTION = 9;
+ /** Entrypoint to be used when a user long presses on the meta key. */
+ public static final int ENTRYPOINT_LONG_PRESS_META = 10;
+ /**
+ * The {@link Entrypoint} annotation is used to standardize the entrypoints supported by
+ * {@link #startContextualSearch} method.
+ *
+ * @hide
+ */
+ @IntDef(prefix = {"ENTRYPOINT_"}, value = {
+ ENTRYPOINT_LONG_PRESS_NAV_HANDLE,
+ ENTRYPOINT_LONG_PRESS_HOME,
+ ENTRYPOINT_LONG_PRESS_OVERVIEW,
+ ENTRYPOINT_OVERVIEW_ACTION,
+ ENTRYPOINT_OVERVIEW_MENU,
+ ENTRYPOINT_SYSTEM_ACTION,
+ ENTRYPOINT_LONG_PRESS_META
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Entrypoint {
+ }
+ private static final String TAG = ContextualSearchManager.class.getSimpleName();
+ private static final boolean DEBUG = false;
+
+ private final IContextualSearchManager mService;
+
+ /** @hide */
+ public ContextualSearchManager() {
+ if (DEBUG) Log.d(TAG, "ContextualSearchManager created");
+ IBinder b = ServiceManager.getService(Context.CONTEXTUAL_SEARCH_SERVICE);
+ mService = IContextualSearchManager.Stub.asInterface(b);
+ }
+
+ /**
+ * Used to start contextual search.
+ * <p>
+ * When {@link #startContextualSearch} is called, the system server does the following:
+ * <ul>
+ * <li>Resolves the activity using the package name and intent filter. The package name
+ * is fetched from the config specified in ContextualSearchManagerService.
+ * The activity must have ACTION_LAUNCH_CONTEXTUAL_SEARCH specified in its manifest.
+ * <li>Puts the required extras in the launch intent.
+ * <li>Launches the activity.
+ * </ul>
+ * </p>
+ *
+ * @param entrypoint the invocation entrypoint
+ */
+ @RequiresPermission(ACCESS_CONTEXTUAL_SEARCH)
+ public void startContextualSearch(@Entrypoint int entrypoint) {
+ if (DEBUG) Log.d(TAG, "startContextualSearch for entrypoint: " + entrypoint);
+ try {
+ mService.startContextualSearch(entrypoint);
+ } catch (RemoteException e) {
+ if (DEBUG) Log.d(TAG, "Failed to startContextualSearch", e);
+ e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Returns the {@link ContextualSearchState} to the handler via the provided callback.
+ *
+ * @param token The caller is expected to get the token from the launch extras of the handling
+ * activity using {@link Bundle#getIBinder} with {@link #EXTRA_TOKEN} key.
+ * <br>
+ * <b>Note</b> This token is for one time use only. Subsequent uses will invoke
+ * callback's {@link OutcomeReceiver#onError}.
+ * @param executor The executor which will be used to invoke the callback.
+ * @param callback The callback which will be used to return {@link ContextualSearchState}
+ * if/when it is available via {@link OutcomeReceiver#onResult}. It will also be
+ * used to return errors via {@link OutcomeReceiver#onError}.
+ */
+ public void getContextualSearchState(@NonNull IBinder token,
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull OutcomeReceiver<ContextualSearchState, Throwable> callback) {
+ if (DEBUG) Log.d(TAG, "getContextualSearchState for token:" + token);
+ try {
+ final CallbackWrapper wrapper = new CallbackWrapper(executor, callback);
+ mService.getContextualSearchState(token, wrapper);
+ } catch (RemoteException e) {
+ if (DEBUG) Log.d(TAG, "Failed to getContextualSearchState", e);
+ e.rethrowFromSystemServer();
+ }
+ }
+
+ private static class CallbackWrapper extends IContextualSearchCallback.Stub {
+ private final OutcomeReceiver<ContextualSearchState, Throwable> mCallback;
+ private final Executor mExecutor;
+
+ CallbackWrapper(@NonNull Executor callbackExecutor,
+ @NonNull OutcomeReceiver<ContextualSearchState, Throwable> callback) {
+ mCallback = callback;
+ mExecutor = callbackExecutor;
+ }
+
+ @Override
+ public void onResult(ContextualSearchState state) {
+ Binder.withCleanCallingIdentity(() -> {
+ if (DEBUG) Log.d(TAG, "onResult state:" + state);
+ mExecutor.execute(() -> mCallback.onResult(state));
+ });
+ }
+
+ @Override
+ public void onError(ParcelableException error) {
+ Binder.withCleanCallingIdentity(() -> {
+ if (DEBUG) Log.w(TAG, "onError", error);
+ mExecutor.execute(() -> mCallback.onError(error));
+ });
+ }
+ }
+}
diff --git a/core/java/android/os/WorkDuration.aidl b/core/java/android/app/contextualsearch/ContextualSearchState.aidl
index 0f61204d72c4..7f64484b0f38 100644
--- a/core/java/android/os/WorkDuration.aidl
+++ b/core/java/android/app/contextualsearch/ContextualSearchState.aidl
@@ -1,11 +1,11 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
+/**
+ * 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
+ * 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,
@@ -14,6 +14,6 @@
* limitations under the License.
*/
-package android.os;
+package android.app.contextualsearch;
-parcelable WorkDuration cpp_header "android/WorkDuration.h"; \ No newline at end of file
+parcelable ContextualSearchState; \ No newline at end of file
diff --git a/core/java/android/app/contextualsearch/ContextualSearchState.java b/core/java/android/app/contextualsearch/ContextualSearchState.java
new file mode 100644
index 000000000000..5c04bc8933c0
--- /dev/null
+++ b/core/java/android/app/contextualsearch/ContextualSearchState.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.contextualsearch;
+
+import android.annotation.FlaggedApi;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.app.assist.AssistContent;
+import android.app.assist.AssistStructure;
+import android.app.contextualsearch.flags.Flags;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import androidx.annotation.NonNull;
+
+/**
+ * {@link ContextualSearchState} contains additional data a contextual search handler can request
+ * via {@link ContextualSearchManager#getContextualSearchState} method.
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_ENABLE_SERVICE)
+@SystemApi
+public final class ContextualSearchState implements Parcelable {
+ private final @NonNull Bundle mExtras;
+ private final @Nullable AssistStructure mStructure;
+ private final @Nullable AssistContent mContent;
+
+ public ContextualSearchState(@Nullable AssistStructure structure,
+ @Nullable AssistContent content, @NonNull Bundle extras) {
+ mStructure = structure;
+ mContent = content;
+ mExtras = extras;
+ }
+
+ private ContextualSearchState(Parcel source) {
+ this.mStructure = source.readTypedObject(AssistStructure.CREATOR);
+ this.mContent = source.readTypedObject(AssistContent.CREATOR);
+ Bundle extras = source.readBundle(getClass().getClassLoader());
+ this.mExtras = extras != null ? extras : Bundle.EMPTY;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeTypedObject(this.mStructure, flags);
+ dest.writeTypedObject(this.mContent, flags);
+ dest.writeBundle(this.mExtras);
+ }
+
+ /** Gets an instance of {@link AssistContent}. */
+ @Nullable
+ public AssistContent getContent() {
+ return mContent;
+ }
+
+ /** Gets an instance of {@link AssistStructure}. */
+ @Nullable
+ public AssistStructure getStructure() {
+ return mStructure;
+ }
+
+ /**
+ * Gets an instance of {@link Bundle} containing the extras added by the system server.
+ * The contents of this bundle vary by usecase. When Contextual is invoked via Launcher, this
+ * bundle is empty.
+ */
+ @NonNull
+ public Bundle getExtras() {
+ return mExtras;
+ }
+
+ @NonNull
+ public static final Creator<ContextualSearchState> CREATOR = new Creator<>() {
+ @Override
+ public ContextualSearchState createFromParcel(Parcel source) {
+ return new ContextualSearchState(source);
+ }
+
+ @Override
+ public ContextualSearchState[] newArray(int size) {
+ return new ContextualSearchState[size];
+ }
+ };
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/shared/SceneContainerFlagsExtension.kt b/core/java/android/app/contextualsearch/IContextualSearchCallback.aidl
index 7dfd53e544c0..5fe5fd23c501 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/shared/SceneContainerFlagsExtension.kt
+++ b/core/java/android/app/contextualsearch/IContextualSearchCallback.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2023 The Android Open Source Project
+ * 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.
@@ -14,14 +14,14 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar.notification.stack.shared
-
-import com.android.systemui.scene.shared.flag.SceneContainerFlags
-
-private const val FLEXI_NOTIFS = true
+package android.app.contextualsearch;
+import android.os.ParcelableException;
+import android.app.contextualsearch.ContextualSearchState;
/**
- * Returns whether flexiglass is displaying notifications, which is currently an optional piece of
- * flexiglass
+ * @hide
*/
-fun SceneContainerFlags.flexiNotifsEnabled() = FLEXI_NOTIFS && isEnabled()
+oneway interface IContextualSearchCallback {
+ void onResult(in ContextualSearchState state);
+ void onError(in ParcelableException error);
+}
diff --git a/core/java/android/app/contextualsearch/IContextualSearchManager.aidl b/core/java/android/app/contextualsearch/IContextualSearchManager.aidl
new file mode 100644
index 000000000000..1735a7139e6f
--- /dev/null
+++ b/core/java/android/app/contextualsearch/IContextualSearchManager.aidl
@@ -0,0 +1,11 @@
+package android.app.contextualsearch;
+
+
+import android.app.contextualsearch.IContextualSearchCallback;
+/**
+ * @hide
+ */
+oneway interface IContextualSearchManager {
+ void startContextualSearch(int entrypoint);
+ void getContextualSearchState(in IBinder token, in IContextualSearchCallback callback);
+}
diff --git a/core/java/android/app/contextualsearch/flags.aconfig b/core/java/android/app/contextualsearch/flags.aconfig
new file mode 100644
index 000000000000..5ab07620bc81
--- /dev/null
+++ b/core/java/android/app/contextualsearch/flags.aconfig
@@ -0,0 +1,8 @@
+package: "android.app.contextualsearch.flags"
+
+flag {
+ name: "enable_service"
+ namespace: "machine_learning"
+ description: "Flag to enable the service"
+ bug: "309689654"
+}
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 7f2ec53ea41a..1653bf538435 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -5396,6 +5396,19 @@ public abstract class Context {
public static final String SMARTSPACE_SERVICE = "smartspace";
/**
+ * Used for getting the contextual search service.
+ *
+ * <p><b>NOTE: </b> this service is optional; callers of
+ * {@code Context.getSystemServiceName(CONTEXTUAL_SEARCH_SERVICE)} must check for {@code null}.
+ *
+ * @hide
+ * @see #getSystemService(String)
+ */
+ @FlaggedApi(android.app.contextualsearch.flags.Flags.FLAG_ENABLE_SERVICE)
+ @SystemApi
+ public static final String CONTEXTUAL_SEARCH_SERVICE = "contextual_search";
+
+ /**
* Used for getting the cloudsearch service.
*
* <p><b>NOTE: </b> this service is optional; callers of
diff --git a/core/java/android/hardware/biometrics/BiometricPrompt.java b/core/java/android/hardware/biometrics/BiometricPrompt.java
index be9f0a0c8d13..a8d54ed970b7 100644
--- a/core/java/android/hardware/biometrics/BiometricPrompt.java
+++ b/core/java/android/hardware/biometrics/BiometricPrompt.java
@@ -16,7 +16,7 @@
package android.hardware.biometrics;
-import static android.Manifest.permission.SET_BIOMETRIC_DIALOG_LOGO;
+import static android.Manifest.permission.SET_BIOMETRIC_DIALOG_ADVANCED;
import static android.Manifest.permission.TEST_BIOMETRIC;
import static android.Manifest.permission.USE_BIOMETRIC;
import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL;
@@ -135,7 +135,7 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
@Retention(RetentionPolicy.SOURCE)
public @interface DismissedReason {}
- private static class ButtonInfo {
+ static class ButtonInfo {
Executor executor;
DialogInterface.OnClickListener listener;
ButtonInfo(Executor ex, DialogInterface.OnClickListener l) {
@@ -150,6 +150,7 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
public static class Builder {
private PromptInfo mPromptInfo;
private ButtonInfo mNegativeButtonInfo;
+ private ButtonInfo mContentViewMoreOptionsButtonInfo;
private Context mContext;
private IAuthService mService;
@@ -175,7 +176,7 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
* @return This builder.
*/
@FlaggedApi(FLAG_CUSTOM_BIOMETRIC_PROMPT)
- @RequiresPermission(SET_BIOMETRIC_DIALOG_LOGO)
+ @RequiresPermission(SET_BIOMETRIC_DIALOG_ADVANCED)
@NonNull
public BiometricPrompt.Builder setLogoRes(@DrawableRes int logoRes) {
mPromptInfo.setLogoRes(logoRes);
@@ -194,7 +195,7 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
* @return This builder.
*/
@FlaggedApi(FLAG_CUSTOM_BIOMETRIC_PROMPT)
- @RequiresPermission(SET_BIOMETRIC_DIALOG_LOGO)
+ @RequiresPermission(SET_BIOMETRIC_DIALOG_ADVANCED)
@NonNull
public BiometricPrompt.Builder setLogoBitmap(@NonNull Bitmap logoBitmap) {
mPromptInfo.setLogoBitmap(logoBitmap);
@@ -213,7 +214,7 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
* @return This builder.
*/
@FlaggedApi(FLAG_CUSTOM_BIOMETRIC_PROMPT)
- @RequiresPermission(SET_BIOMETRIC_DIALOG_LOGO)
+ @RequiresPermission(SET_BIOMETRIC_DIALOG_ADVANCED)
@NonNull
public BiometricPrompt.Builder setLogoDescription(@NonNull String logoDescription) {
mPromptInfo.setLogoDescription(logoDescription);
@@ -301,6 +302,12 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
@NonNull
public BiometricPrompt.Builder setContentView(@NonNull PromptContentView view) {
mPromptInfo.setContentView(view);
+
+ if (mPromptInfo.isContentViewMoreOptionsButtonUsed()) {
+ mContentViewMoreOptionsButtonInfo =
+ ((PromptContentViewWithMoreOptionsButton) view).getButtonInfo();
+ }
+
return this;
}
@@ -619,7 +626,8 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
}
mService = (mService == null) ? IAuthService.Stub.asInterface(
ServiceManager.getService(Context.AUTH_SERVICE)) : mService;
- return new BiometricPrompt(mContext, mPromptInfo, mNegativeButtonInfo, mService);
+ return new BiometricPrompt(mContext, mPromptInfo, mNegativeButtonInfo,
+ mContentViewMoreOptionsButtonInfo, mService);
}
}
@@ -646,6 +654,9 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
private final IAuthService mService;
private final PromptInfo mPromptInfo;
private final ButtonInfo mNegativeButtonInfo;
+ // TODO(b/328843028): add callback onContentViewMoreOptionsButtonClicked() in
+ // IBiometricServiceReceiver.
+ private final ButtonInfo mContentViewMoreOptionsButtonInfo;
private CryptoObject mCryptoObject;
private Executor mExecutor;
@@ -751,10 +762,11 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
private boolean mIsPromptShowing;
private BiometricPrompt(Context context, PromptInfo promptInfo, ButtonInfo negativeButtonInfo,
- IAuthService service) {
+ ButtonInfo contentViewMoreOptionsButtonInfo, IAuthService service) {
mContext = context;
mPromptInfo = promptInfo;
mNegativeButtonInfo = negativeButtonInfo;
+ mContentViewMoreOptionsButtonInfo = contentViewMoreOptionsButtonInfo;
mService = service;
mIsPromptShowing = false;
}
@@ -766,7 +778,7 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
* @return The drawable resource of the logo, or -1 if the prompt has no logo resource set.
*/
@FlaggedApi(FLAG_CUSTOM_BIOMETRIC_PROMPT)
- @RequiresPermission(SET_BIOMETRIC_DIALOG_LOGO)
+ @RequiresPermission(SET_BIOMETRIC_DIALOG_ADVANCED)
@DrawableRes
public int getLogoRes() {
return mPromptInfo.getLogoRes();
@@ -779,7 +791,7 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
* @return The logo bitmap of the prompt, or null if the prompt has no logo bitmap set.
*/
@FlaggedApi(FLAG_CUSTOM_BIOMETRIC_PROMPT)
- @RequiresPermission(SET_BIOMETRIC_DIALOG_LOGO)
+ @RequiresPermission(SET_BIOMETRIC_DIALOG_ADVANCED)
@Nullable
public Bitmap getLogoBitmap() {
return mPromptInfo.getLogoBitmap();
@@ -794,7 +806,7 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
* set.
*/
@FlaggedApi(FLAG_CUSTOM_BIOMETRIC_PROMPT)
- @RequiresPermission(SET_BIOMETRIC_DIALOG_LOGO)
+ @RequiresPermission(SET_BIOMETRIC_DIALOG_ADVANCED)
@Nullable
public String getLogoDescription() {
return mPromptInfo.getLogoDescription();
@@ -932,14 +944,29 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
* @see Builder#setAllowedAuthenticators(int)
*/
public static final class CryptoObject extends android.hardware.biometrics.CryptoObject {
+ /**
+ * Create from a {@link Signature} object.
+ *
+ * @param signature a {@link Signature} object.
+ */
public CryptoObject(@NonNull Signature signature) {
super(signature);
}
+ /**
+ * Create from a {@link Cipher} object.
+ *
+ * @param cipher a {@link Cipher} object.
+ */
public CryptoObject(@NonNull Cipher cipher) {
super(cipher);
}
+ /**
+ * Create from a {@link Mac} object.
+ *
+ * @param mac a {@link Mac} object.
+ */
public CryptoObject(@NonNull Mac mac) {
super(mac);
}
@@ -955,16 +982,37 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
super(credential);
}
+ /**
+ * Create from a {@link PresentationSession} object.
+ *
+ * @param session a {@link PresentationSession} object.
+ */
public CryptoObject(@NonNull PresentationSession session) {
super(session);
}
+ /**
+ * Create from a {@link KeyAgreement} object.
+ *
+ * @param keyAgreement a {@link KeyAgreement} object.
+ */
@FlaggedApi(FLAG_ADD_KEY_AGREEMENT_CRYPTO_OBJECT)
public CryptoObject(@NonNull KeyAgreement keyAgreement) {
super(keyAgreement);
}
/**
+ * Create from an operation handle.
+ * @see CryptoObject#getOperationHandle()
+ *
+ * @param operationHandle the operation handle associated with this object.
+ */
+ @FlaggedApi(FLAG_GET_OP_ID_CRYPTO_OBJECT)
+ public CryptoObject(long operationHandle) {
+ super(operationHandle);
+ }
+
+ /**
* Get {@link Signature} object.
* @return {@link Signature} object or null if this doesn't contain one.
*/
@@ -1016,7 +1064,20 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
}
/**
- * Get the operation handle associated with this object or 0 if none.
+ * Returns the {@code operationHandle} associated with this object or 0 if none.
+ * The {@code operationHandle} is the underlying identifier associated with
+ * the {@code CryptoObject}.
+ *
+ * <p> The {@code operationHandle} can be used to reconstruct a {@code CryptoObject}
+ * instance. This is useful for any cross-process communication as the {@code CryptoObject}
+ * class is not {@link android.os.Parcelable}. Hence, if the {@code CryptoObject} is
+ * constructed in one process, and needs to be propagated to another process,
+ * before calling the
+ * {@link BiometricPrompt#authenticate(CryptoObject, CancellationSignal, Executor,
+ * AuthenticationCallback)} API in the second process, the recommendation is to retrieve the
+ * {@code operationHandle} using this API, and then reconstruct the
+ * {@code CryptoObject}using the constructor that takes in an {@code operationHandle}, and
+ * pass that in to the {@code authenticate} API mentioned above.
*/
@FlaggedApi(FLAG_GET_OP_ID_CRYPTO_OBJECT)
public long getOperationHandle() {
diff --git a/core/java/android/hardware/biometrics/CryptoObject.java b/core/java/android/hardware/biometrics/CryptoObject.java
index 8d3ea3f914ec..81b4c21f4b71 100644
--- a/core/java/android/hardware/biometrics/CryptoObject.java
+++ b/core/java/android/hardware/biometrics/CryptoObject.java
@@ -97,6 +97,10 @@ public class CryptoObject {
mCrypto = keyAgreement;
}
+ public CryptoObject(long operationHandle) {
+ mCrypto = operationHandle;
+ }
+
/**
* Get {@link Signature} object.
* @return {@link Signature} object or null if this doesn't contain one.
@@ -157,6 +161,8 @@ public class CryptoObject {
public long getOpId() {
if (mCrypto == null) {
return 0;
+ } else if (mCrypto instanceof Long) {
+ return (long) mCrypto;
} else if (mCrypto instanceof IdentityCredential) {
return ((IdentityCredential) mCrypto).getCredstoreOperationHandle();
} else if (mCrypto instanceof PresentationSession) {
diff --git a/core/java/android/hardware/biometrics/PromptContentViewParcelable.java b/core/java/android/hardware/biometrics/PromptContentViewParcelable.java
index 43b965bb696d..b5982d4f7251 100644
--- a/core/java/android/hardware/biometrics/PromptContentViewParcelable.java
+++ b/core/java/android/hardware/biometrics/PromptContentViewParcelable.java
@@ -26,5 +26,5 @@ import android.os.Parcelable;
*/
@FlaggedApi(FLAG_CUSTOM_BIOMETRIC_PROMPT)
sealed interface PromptContentViewParcelable extends PromptContentView, Parcelable
- permits PromptVerticalListContentView {
+ permits PromptVerticalListContentView, PromptContentViewWithMoreOptionsButton {
}
diff --git a/core/java/android/hardware/biometrics/PromptContentViewWithMoreOptionsButton.java b/core/java/android/hardware/biometrics/PromptContentViewWithMoreOptionsButton.java
new file mode 100644
index 000000000000..9ebfa8f4301d
--- /dev/null
+++ b/core/java/android/hardware/biometrics/PromptContentViewWithMoreOptionsButton.java
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.biometrics;
+
+import static android.Manifest.permission.SET_BIOMETRIC_DIALOG_ADVANCED;
+import static android.hardware.biometrics.Flags.FLAG_CUSTOM_BIOMETRIC_PROMPT;
+
+import android.annotation.CallbackExecutor;
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.content.DialogInterface;
+import android.hardware.biometrics.BiometricPrompt.ButtonInfo;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.concurrent.Executor;
+
+/**
+ * Contains the information of the template of content view with a more options button for Biometric
+ * Prompt.
+ * This button should be used to provide more options for sign in or other purposes, such as when a
+ * user needs to select between multiple app-specific accounts or profiles that are available for
+ * sign in. This is not common and apps should avoid using it if there is only one choice available
+ * or if the user has already selected the appropriate account to use before invoking
+ * BiometricPrompt because it will create additional steps that the user must navigate through.
+ * Clicking the more options button will dismiss the prompt, provide the app an opportunity to ask
+ * the user for the correct account, &finally allow the app to decide how to proceed once selected.
+ * <p>
+ * Here's how you'd set a <code>PromptContentViewWithMoreOptionsButton</code> on a Biometric Prompt:
+ * <pre class="prettyprint">
+ * BiometricPrompt biometricPrompt = new BiometricPrompt.Builder(...)
+ * .setTitle(...)
+ * .setSubTitle(...)
+ * .setContentView(new PromptContentViewWithMoreOptionsButton.Builder()
+ * .setDescription("test description")
+ * .setMoreOptionsButtonListener(executor, listener)
+ * .build())
+ * .build();
+ * </pre>
+ */
+@FlaggedApi(FLAG_CUSTOM_BIOMETRIC_PROMPT)
+public final class PromptContentViewWithMoreOptionsButton implements PromptContentViewParcelable {
+
+ private final String mDescription;
+ private DialogInterface.OnClickListener mListener;
+ private ButtonInfo mButtonInfo;
+
+ private PromptContentViewWithMoreOptionsButton(
+ @NonNull String description, @NonNull @CallbackExecutor Executor executor,
+ @NonNull DialogInterface.OnClickListener listener) {
+ mDescription = description;
+ mListener = listener;
+ mButtonInfo = new ButtonInfo(executor, listener);
+ }
+
+ private PromptContentViewWithMoreOptionsButton(Parcel in) {
+ mDescription = in.readString();
+ }
+
+ /**
+ * Gets the description for the content view, as set by
+ * {@link PromptContentViewWithMoreOptionsButton.Builder#setDescription(String)}.
+ *
+ * @return The description for the content view, or null if the content view has no description.
+ */
+ @RequiresPermission(SET_BIOMETRIC_DIALOG_ADVANCED)
+ @Nullable
+ public String getDescription() {
+ return mDescription;
+ }
+
+ /**
+ * Gets the click listener for the more options button on the content view, as set by
+ * {@link PromptContentViewWithMoreOptionsButton.Builder#setMoreOptionsButtonListener(Executor,
+ * DialogInterface.OnClickListener)}.
+ *
+ * @return The click listener for the more options button on the content view.
+ */
+ @RequiresPermission(SET_BIOMETRIC_DIALOG_ADVANCED)
+ @NonNull
+ public DialogInterface.OnClickListener getMoreOptionsButtonListener() {
+ return mListener;
+ }
+
+ ButtonInfo getButtonInfo() {
+ return mButtonInfo;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeString(mDescription);
+ }
+
+ /**
+ * @see Parcelable.Creator
+ */
+ @NonNull
+ public static final Creator<PromptContentViewWithMoreOptionsButton> CREATOR = new Creator<>() {
+ @Override
+ public PromptContentViewWithMoreOptionsButton createFromParcel(Parcel in) {
+ return new PromptContentViewWithMoreOptionsButton(in);
+ }
+
+ @Override
+ public PromptContentViewWithMoreOptionsButton[] newArray(int size) {
+ return new PromptContentViewWithMoreOptionsButton[size];
+ }
+ };
+
+ public static final class Builder {
+ private String mDescription;
+ private Executor mExecutor;
+ private DialogInterface.OnClickListener mListener;
+
+ /**
+ * Optional: Sets a description that will be shown on the content view. Note that there are
+ * limits on the number of characters allowed for description.
+ *
+ * @param description The description to display.
+ * @return This builder.
+ */
+ @NonNull
+ @RequiresPermission(SET_BIOMETRIC_DIALOG_ADVANCED)
+ public Builder setDescription(@NonNull String description) {
+ mDescription = description;
+ return this;
+ }
+
+ /**
+ * Required: Sets the executor and click listener for the more options button on the
+ * prompt content.
+ * This button should be used to provide more options for sign in or other purposes, such
+ * as when a user needs to select between multiple app-specific accounts or profiles that
+ * are available for sign in. This is not common and apps should avoid using it if there
+ * is only one choice available or if the user has already selected the appropriate
+ * account to use before invoking BiometricPrompt because it will create additional steps
+ * that the user must navigate through. Clicking the more options button will dismiss the
+ * prompt, provide the app an opportunity to ask the user for the correct account, &finally
+ * allow the app to decide how to proceed once selected.
+ *
+ * @param executor Executor that will be used to run the on click callback.
+ * @param listener Listener containing a callback to be run when the button is pressed.
+ * @return This builder.
+ */
+ @NonNull
+ @RequiresPermission(SET_BIOMETRIC_DIALOG_ADVANCED)
+ public Builder setMoreOptionsButtonListener(@NonNull @CallbackExecutor Executor executor,
+ @NonNull DialogInterface.OnClickListener listener) {
+ if (executor == null) {
+ throw new IllegalArgumentException("Executor must not be null");
+ }
+ if (listener == null) {
+ throw new IllegalArgumentException("Listener must not be null");
+ }
+ mExecutor = executor;
+ mListener = listener;
+ return this;
+ }
+
+
+ /**
+ * Creates a {@link PromptContentViewWithMoreOptionsButton}.
+ *
+ * @return An instance of {@link PromptContentViewWithMoreOptionsButton}.
+ */
+ @NonNull
+ @RequiresPermission(SET_BIOMETRIC_DIALOG_ADVANCED)
+ public PromptContentViewWithMoreOptionsButton build() {
+ if (mListener == null) {
+ throw new IllegalArgumentException(
+ "The listener of more options button on prompt content must be set if "
+ + "PromptContentViewWithMoreOptionsButton is used.");
+ }
+ return new PromptContentViewWithMoreOptionsButton(mDescription, mExecutor, mListener);
+ }
+ }
+}
diff --git a/core/java/android/hardware/biometrics/PromptInfo.java b/core/java/android/hardware/biometrics/PromptInfo.java
index 8bb958553673..814321319e2f 100644
--- a/core/java/android/hardware/biometrics/PromptInfo.java
+++ b/core/java/android/hardware/biometrics/PromptInfo.java
@@ -172,7 +172,7 @@ public class PromptInfo implements Parcelable {
}
/**
- * Returns whether SET_BIOMETRIC_DIALOG_LOGO is contained.
+ * Returns whether SET_BIOMETRIC_DIALOG_ADVANCED is contained.
*/
public boolean containsSetLogoApiConfigurations() {
if (mLogoRes != -1) {
@@ -191,6 +191,15 @@ public class PromptInfo implements Parcelable {
public boolean shouldUseParentProfileForDeviceCredential() {
return mUseParentProfileForDeviceCredential;
}
+
+ /**
+ * Returns if the PromptContentViewWithMoreOptionsButton is set.
+ */
+ public boolean isContentViewMoreOptionsButtonUsed() {
+ return Flags.customBiometricPrompt() && mContentView != null
+ && mContentView instanceof PromptContentViewWithMoreOptionsButton;
+ }
+
// LINT.ThenChange(frameworks/base/core/java/android/hardware/biometrics/BiometricPrompt.java)
// Setters
diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java
index 991bade09a25..ec9b013c34cc 100644
--- a/core/java/android/hardware/camera2/CameraDevice.java
+++ b/core/java/android/hardware/camera2/CameraDevice.java
@@ -585,6 +585,11 @@ public abstract class CameraDevice implements AutoCloseable {
* <p>Configuring a session with an empty or null list will close the current session, if
* any. This can be used to release the current session's target surfaces for another use.</p>
*
+ * <p>This function throws an {@code IllegalArgumentException} if called with a
+ * SessionConfiguration lacking state callbacks or valid output surfaces. The only exceptions
+ * are deferred SurfaceView or SurfaceTexture outputs. See {@link
+ * OutputConfiguration#OutputConfiguration(Size, Class)} for details.</p>
+ *
* <h3>Regular capture</h3>
*
* <p>While any of the sizes from {@link StreamConfigurationMap#getOutputSizes} can be used when
@@ -1675,19 +1680,32 @@ public abstract class CameraDevice implements AutoCloseable {
*
* <p><b>IMPORTANT:</b></p>
* <ul>
- * <li>If a feature support can be queried via
+ * <li>If feature support can be queried via
* {@link CameraCharacteristics#SCALER_MANDATORY_STREAM_COMBINATIONS} or
* {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP}, applications should
- * directly use it rather than calling this function as: (1) using
- * {@code CameraCharacteristics} is more efficient, and (2) calling this function with on
- * non-supported devices will throw a {@link UnsupportedOperationException}.
+ * directly use that route rather than calling this function as: (1) using
+ * {@code CameraCharacteristics} is more efficient, and (2) calling this function with
+ * certain non-supported features will throw a {@link IllegalArgumentException}.</li>
*
- * <li>To minimize latency of {@link SessionConfiguration} creation, applications can
- * use deferred surfaces for SurfaceView and SurfaceTexture to avoid waiting for UI
- * creation before setting up the camera. For {@link android.media.MediaRecorder} and
- * {@link android.media.MediaCodec} uses, applications can use {@code ImageReader} with
- * {@link android.hardware.HardwareBuffer#USAGE_VIDEO_ENCODE}. The lightweight nature of
- * {@code ImageReader} helps minimize the latency cost.
+ * <li>To minimize {@link SessionConfiguration} creation latency due to its dependency on
+ * output surfaces, the application can call this method before acquiring valid
+ * {@link android.view.SurfaceView}, {@link android.graphics.SurfaceTexture},
+ * {@link android.media.MediaRecorder}, {@link android.media.MediaCodec}, or {@link
+ * android.media.ImageReader} surfaces. For {@link android.view.SurfaceView},
+ * {@link android.graphics.SurfaceTexture}, {@link android.media.MediaRecorder}, and
+ * {@link android.media.MediaCodec}, the application can call
+ * {@link OutputConfiguration#OutputConfiguration(Size, Class)}. For {@link
+ * android.media.ImageReader}, the application can call {@link
+ * OutputConfiguration#OutputConfiguration(int, Size)}, {@link
+ * OutputConfiguration#OutputConfiguration(int, int, Size)}, {@link
+ * OutputConfiguration#OutputConfiguration(int, Size, long)}, or {@link
+ * OutputConfiguration#OutputConfiguration(int, int, Size, long)}. The {@link
+ * SessionConfiguration} can then be created using the OutputConfiguration objects and
+ * be used to query whether it's supported by the camera device. To create the
+ * CameraCaptureSession, the application still needs to make sure all output surfaces
+ * are added via {@link OutputConfiguration#addSurfaces} with the exception of deferred
+ * surfaces for {@link android.view.SurfaceView} and
+ * {@link android.graphics.SurfaceTexture}.</li>
* </ul>
*
* @return {@code true} if the given session configuration is supported by the camera
@@ -1706,8 +1724,8 @@ public abstract class CameraDevice implements AutoCloseable {
@NonNull SessionConfiguration config) throws CameraAccessException;
/**
- * <p>Get camera characteristics for a particular session configuration for this camera
- * device</p>
+ * Get camera characteristics for a particular session configuration for this camera
+ * device.
*
* <p>The camera characteristics returned by this method are different from those returned
* from {@link CameraManager#getCameraCharacteristics}. The characteristics returned here
@@ -1718,6 +1736,24 @@ public abstract class CameraDevice implements AutoCloseable {
* <p>Other than that, the characteristics returned here can be used in the same way as
* those returned from {@link CameraManager#getCameraCharacteristics}.</p>
*
+ * <p>To optimize latency, the application can call this method before acquiring valid
+ * {@link android.view.SurfaceView}, {@link android.graphics.SurfaceTexture},
+ * {@link android.media.MediaRecorder}, {@link android.media.MediaCodec}, or {@link
+ * android.media.ImageReader} surfaces. For {@link android.view.SurfaceView},
+ * {@link android.graphics.SurfaceTexture}, {@link android.media.MediaRecorder}, and
+ * {@link android.media.MediaCodec}, the application can call
+ * {@link OutputConfiguration#OutputConfiguration(Size, Class)}. For {@link
+ * android.media.ImageReader}, the application can call {@link
+ * OutputConfiguration#OutputConfiguration(int, Size)}, {@link
+ * OutputConfiguration#OutputConfiguration(int, int, Size)}, {@link
+ * OutputConfiguration#OutputConfiguration(int, Size, long)}, or {@link
+ * OutputConfiguration#OutputConfiguration(int, int, Size, long)}. The {@link
+ * SessionConfiguration} can then be created using the OutputConfiguration objects and
+ * be used for this function. To create the CameraCaptureSession, the application still
+ * needs to make sure all output surfaces are added via {@link
+ * OutputConfiguration#addSurfaces} with the exception of deferred surfaces for {@link
+ * android.view.SurfaceView} and {@link android.graphics.SurfaceTexture}.</p>
+ *
* @param sessionConfig The session configuration for which characteristics are fetched.
* @return CameraCharacteristics specific to a given session configuration.
*
diff --git a/core/java/android/hardware/camera2/MultiResolutionImageReader.java b/core/java/android/hardware/camera2/MultiResolutionImageReader.java
index 8a18a0d2d367..116928b4283a 100644
--- a/core/java/android/hardware/camera2/MultiResolutionImageReader.java
+++ b/core/java/android/hardware/camera2/MultiResolutionImageReader.java
@@ -16,6 +16,8 @@
package android.hardware.camera2;
+import static com.android.internal.util.Preconditions.checkNotNull;
+
import android.annotation.CallbackExecutor;
import android.annotation.FlaggedApi;
import android.annotation.IntRange;
@@ -26,20 +28,15 @@ import android.graphics.ImageFormat;
import android.graphics.ImageFormat.Format;
import android.hardware.HardwareBuffer;
import android.hardware.HardwareBuffer.Usage;
+import android.hardware.camera2.params.MultiResolutionStreamInfo;
import android.media.Image;
import android.media.ImageReader;
-import android.hardware.camera2.params.MultiResolutionStreamInfo;
-import android.os.Looper;
-import android.os.Message;
-import android.util.Log;
+import android.util.Size;
import android.view.Surface;
import com.android.internal.camera.flags.Flags;
-import java.nio.NioUtils;
-import java.util.ArrayList;
import java.util.Collection;
-import java.util.List;
import java.util.concurrent.Executor;
/**
@@ -351,6 +348,52 @@ public class MultiResolutionImageReader implements AutoCloseable {
}
/**
+ * Get the internal ImageReader surface based on configured size and physical camera Id.
+ *
+ * <p>The {@code configuredSize} and {@code physicalCameraId} parameters must match one of the
+ * MultiResolutionStreamInfo used to create this {@link MultiResolutionImageReader}.</p>
+ *
+ * <p>The Surface returned from this function isn't meant to be used directly as part of a
+ * {@link CaptureRequest}. It should instead be used for creating an OutputConfiguration
+ * before session creation. See {@link OutputConfiguration#setSurfacesForMultiResolutionOutput}
+ * for details. For {@link CaptureRequest}, use {@link #getSurface()} instead.</p>
+ *
+ * <p>Please note that holding on to the Surface objects returned by this method is not enough
+ * to keep their parent MultiResolutionImageReaders from being reclaimed. In that sense, a
+ * Surface acts like a {@link java.lang.ref.WeakReference weak reference} to the
+ * MultiResolutionImageReader that provides it.</p>
+ *
+ * @param configuredSize The configured size corresponding to one of the internal ImageReader.
+ * @param physicalCameraId The physical camera Id the internal ImageReader targets for. If
+ * the ImageReader is not targeting a physical camera of a logical
+ * multi-camera, this parameter is set to "".
+ *
+ * @return The {@link Surface} of the internal ImageReader corresponding to the provided
+ * configured size and physical camera Id.
+ *
+ * @throws IllegalArgumentException If {@code configuredSize} is {@code null}, or the ({@code
+ * configuredSize} and {@code physicalCameraId}) combo is not
+ * part of this {@code MultiResolutionImageReader}.
+ * @hide
+ */
+ @FlaggedApi(Flags.FLAG_CAMERA_DEVICE_SETUP)
+ public @NonNull Surface getSurface(@NonNull Size configuredSize,
+ @NonNull String physicalCameraId) {
+ checkNotNull(configuredSize, "configuredSize must not be null");
+ checkNotNull(physicalCameraId, "physicalCameraId must not be null");
+
+ for (int i = 0; i < mStreamInfo.length; i++) {
+ if (mStreamInfo[i].getWidth() == configuredSize.getWidth()
+ && mStreamInfo[i].getHeight() == configuredSize.getHeight()
+ && physicalCameraId.equals(mStreamInfo[i].getPhysicalCameraId())) {
+ return mReaders[i].getSurface();
+ }
+ }
+ throw new IllegalArgumentException("configuredSize and physicalCameraId don't match with "
+ + "this MultiResolutionImageReader");
+ }
+
+ /**
* Get the surface that is used as a target for {@link CaptureRequest}
*
* <p>The application must use the surface returned by this function as a target for
diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceSetupImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceSetupImpl.java
index 0f199b15af6c..9e014386a6e5 100644
--- a/core/java/android/hardware/camera2/impl/CameraDeviceSetupImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraDeviceSetupImpl.java
@@ -90,7 +90,6 @@ public class CameraDeviceSetupImpl extends CameraDevice.CameraDeviceSetup {
@Override
public boolean isSessionConfigurationSupported(@NonNull SessionConfiguration config)
throws CameraAccessException {
- // TODO(b/298033056): restructure the OutputConfiguration API for better usability
synchronized (mInterfaceLock) {
if (mCameraManager.isCameraServiceDisabled()) {
throw new IllegalArgumentException("No cameras available on device");
diff --git a/core/java/android/hardware/camera2/params/OutputConfiguration.java b/core/java/android/hardware/camera2/params/OutputConfiguration.java
index 8aacd5e3908f..dda52dd5e8cc 100644
--- a/core/java/android/hardware/camera2/params/OutputConfiguration.java
+++ b/core/java/android/hardware/camera2/params/OutputConfiguration.java
@@ -19,6 +19,7 @@ package android.hardware.camera2.params;
import static com.android.internal.util.Preconditions.*;
+import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -27,6 +28,9 @@ import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.graphics.ColorSpace;
import android.graphics.ImageFormat;
+import android.graphics.ImageFormat.Format;
+import android.hardware.HardwareBuffer;
+import android.hardware.HardwareBuffer.Usage;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
@@ -43,6 +47,8 @@ import android.util.Log;
import android.util.Size;
import android.view.Surface;
+import com.android.internal.camera.flags.Flags;
+
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
@@ -50,6 +56,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
+import java.util.concurrent.atomic.AtomicInteger;
/**
* A class for describing camera output, which contains a {@link Surface} and its specific
@@ -361,6 +368,21 @@ public final class OutputConfiguration implements Parcelable {
private final int SURFACE_TYPE_SURFACE_TEXTURE = 1;
/**
+ * The surface is obtained from {@link android.media.MediaRecorder}.
+ */
+ private static final int SURFACE_TYPE_MEDIA_RECORDER = 2;
+
+ /**
+ * The surface is obtained from {@link android.media.MediaCodec}.
+ */
+ private static final int SURFACE_TYPE_MEDIA_CODEC = 3;
+
+ /**
+ * The surface is obtained from {@link android.media.ImageReader}.
+ */
+ private static final int SURFACE_TYPE_IMAGE_READER = 4;
+
+ /**
* Maximum number of surfaces supported by one {@link OutputConfiguration}.
*
* <p>The combined number of surfaces added by the constructor and
@@ -576,6 +598,7 @@ public final class OutputConfiguration implements Parcelable {
mMirrorMode = MIRROR_MODE_AUTO;
mReadoutTimestampEnabled = false;
mIsReadoutSensorTimestampBase = false;
+ mUsage = 0;
}
/**
@@ -592,13 +615,7 @@ public final class OutputConfiguration implements Parcelable {
@NonNull MultiResolutionImageReader multiResolutionImageReader) {
checkNotNull(multiResolutionImageReader, "Multi-resolution image reader must not be null");
- int groupId = MULTI_RESOLUTION_GROUP_ID_COUNTER;
- MULTI_RESOLUTION_GROUP_ID_COUNTER++;
- // Skip in case the group id counter overflows to -1, the invalid value.
- if (MULTI_RESOLUTION_GROUP_ID_COUNTER == -1) {
- MULTI_RESOLUTION_GROUP_ID_COUNTER++;
- }
-
+ int groupId = getAndIncreaseMultiResolutionGroupId();
ImageReader[] imageReaders = multiResolutionImageReader.getReaders();
ArrayList<OutputConfiguration> configs = new ArrayList<OutputConfiguration>();
for (int i = 0; i < imageReaders.length; i++) {
@@ -620,6 +637,115 @@ public final class OutputConfiguration implements Parcelable {
}
/**
+ * Create a list of {@link OutputConfiguration} instances for a
+ * {@link android.hardware.camera2.params.MultiResolutionImageReader}.
+ *
+ * <p>This method can be used to create query OutputConfigurations for a
+ * MultiResolutionImageReader that can be included in a SessionConfiguration passed into
+ * {@link CameraDeviceSetup#isSessionConfigurationSupported} before opening and setting up
+ * a camera device in full, at which point {@link #setSurfacesForMultiResolutionOutput}
+ * can be used to link to the actual MultiResolutionImageReader.</p>
+ *
+ * <p>This constructor takes same arguments used to create a {@link
+ * MultiResolutionImageReader}: a collection of {@link MultiResolutionStreamInfo}
+ * objects and the format.</p>
+ *
+ * @param streams The group of multi-resolution stream info objects, which are used to create a
+ * multi-resolution image reader containing a number of ImageReaders.
+ * @param format The format of the MultiResolutionImageReader. This must be one of the {@link
+ * android.graphics.ImageFormat} or {@link android.graphics.PixelFormat} constants
+ * supported by the camera device. Note that not all formats are supported, like
+ * {@link ImageFormat.NV21}. The supported multi-resolution reader format can be
+ * queried by {@link MultiResolutionStreamConfigurationMap#getOutputFormats}.
+ *
+ * @return The list of {@link OutputConfiguration} objects for a MultiResolutionImageReader.
+ *
+ * @throws IllegaArgumentException If the {@code streams} is null or doesn't contain
+ * at least 2 items, or if {@code format} isn't a valid camera
+ * format.
+ *
+ * @see MultiResolutionImageReader
+ * @see MultiResolutionStreamInfo
+ */
+ @FlaggedApi(Flags.FLAG_CAMERA_DEVICE_SETUP)
+ public static @NonNull List<OutputConfiguration> createInstancesForMultiResolutionOutput(
+ @NonNull Collection<MultiResolutionStreamInfo> streams,
+ @Format int format) {
+ if (streams == null || streams.size() <= 1) {
+ throw new IllegalArgumentException(
+ "The streams list must contain at least 2 entries");
+ }
+ if (format == ImageFormat.NV21) {
+ throw new IllegalArgumentException(
+ "NV21 format is not supported");
+ }
+
+ int groupId = getAndIncreaseMultiResolutionGroupId();
+ ArrayList<OutputConfiguration> configs = new ArrayList<OutputConfiguration>();
+ for (MultiResolutionStreamInfo stream : streams) {
+ Size surfaceSize = new Size(stream.getWidth(), stream.getHeight());
+ OutputConfiguration config = new OutputConfiguration(
+ groupId, format, surfaceSize);
+ config.setPhysicalCameraId(stream.getPhysicalCameraId());
+ config.setMultiResolutionOutput();
+ configs.add(config);
+
+ // No need to call addSensorPixelModeUsed for ultra high resolution sensor camera,
+ // because regular and max resolution output configurations are used for DEFAULT mode
+ // and MAX_RESOLUTION mode respectively by default.
+ }
+
+ return configs;
+ }
+
+ /**
+ * Set the OutputConfiguration surfaces corresponding to the {@link MultiResolutionImageReader}.
+ *
+ * <p>This function should be used together with {@link
+ * #createInstancesForMultiResolutionOutput}. The application calls {@link
+ * #createInstancesForMultiResolutionOutput} first to create a list of
+ * OutputConfiguration objects without the actual MultiResolutionImageReader.
+ * Once the MultiResolutionImageReader is created later during full camera setup, the
+ * application then calls this function to assign the surfaces to the OutputConfiguration
+ * instances.</p>
+ *
+ * @param outputConfigurations The OutputConfiguration objects created by {@link
+ * #createInstancesFromMultiResolutionOutput}
+ * @param multiResolutionImageReader The MultiResolutionImageReader object created from the same
+ * MultiResolutionStreamInfo parameters as
+ * {@code outputConfigurations}.
+ * @throws IllegalArgumentException If {@code outputConfigurations} or {@code
+ * multiResolutionImageReader} is {@code null}, the {@code
+ * outputConfigurations} and {@code multiResolutionImageReader}
+ * sizes don't match, or if the
+ * {@code multiResolutionImageReader}'s surfaces don't match
+ * with the {@code outputConfigurations}.
+ * @throws IllegalStateException If {@code outputConfigurations} already contains valid output
+ * surfaces.
+ */
+ @FlaggedApi(Flags.FLAG_CAMERA_DEVICE_SETUP)
+ public static void setSurfacesForMultiResolutionOutput(
+ @NonNull Collection<OutputConfiguration> outputConfigurations,
+ @NonNull MultiResolutionImageReader multiResolutionImageReader) {
+ checkNotNull(outputConfigurations, "outputConfigurations must not be null");
+ checkNotNull(multiResolutionImageReader, "multiResolutionImageReader must not be null");
+ if (outputConfigurations.size() != multiResolutionImageReader.getReaders().length) {
+ throw new IllegalArgumentException(
+ "outputConfigurations and multiResolutionImageReader sizes must match");
+ }
+
+ for (OutputConfiguration config : outputConfigurations) {
+ String physicalCameraId = config.getPhysicalCameraId();
+ if (physicalCameraId == null) {
+ physicalCameraId = "";
+ }
+ Surface surface = multiResolutionImageReader.getSurface(config.getConfiguredSize(),
+ physicalCameraId);
+ config.addSurface(surface);
+ }
+ }
+
+ /**
* Create a new {@link OutputConfiguration} instance, with desired Surface size and Surface
* source class.
* <p>
@@ -628,30 +754,64 @@ public final class OutputConfiguration implements Parcelable {
* with a deferred Surface. The application can use this output configuration to create a
* session.
* </p>
- * <p>
- * However, the actual output Surface must be set via {@link #addSurface} and the deferred
- * Surface configuration must be finalized via {@link
- * CameraCaptureSession#finalizeOutputConfigurations} before submitting a request with this
- * Surface target. The deferred Surface can only be obtained either from {@link
- * android.view.SurfaceView} by calling {@link android.view.SurfaceHolder#getSurface}, or from
+ *
+ * <p>Starting from {@link android.os.Build.VERSION_CODES#VANILLA_ICE_CREAM Android V},
+ * the deferred Surface can be obtained: (1) from {@link android.view.SurfaceView}
+ * by calling {@link android.view.SurfaceHolder#getSurface}, (2) from
* {@link android.graphics.SurfaceTexture} via
- * {@link android.view.Surface#Surface(android.graphics.SurfaceTexture)}).
- * </p>
+ * {@link android.view.Surface#Surface(android.graphics.SurfaceTexture)}, (3) from {@link
+ * android.media.MediaRecorder} via {@link android.media.MediaRecorder.getSurface} or {@link
+ * android.media.MediaCodec#createPersistentInputSurface}, or (4) from {@link
+ * android.media.MediaCodce} via {@link android.media.MediaCodec#createInputSurface} or {@link
+ * android.media.MediaCodec#createPersistentInputSource}.</p>
+ *
+ * <ul>
+ * <li>Surfaces for {@link android.view.SurfaceView} and {@link android.graphics.SurfaceTexture}
+ * can be deferred until after {@link CameraDevice#createCaptureSession}. In that case, the
+ * output Surface must be set via {@link #addSurface}, and the Surface configuration must be
+ * finalized via {@link CameraCaptureSession#finalizeOutputConfiguration} before submitting
+ * a request with the Surface target.</li>
+ * <li>For all other target types, the output Surface must be set by {@link #addSurface},
+ * and {@link CameraCaptureSession#finalizeOutputConfiguration} is not needed because the
+ * OutputConfiguration used to create the session will contain the actual Surface.</li>
+ * </ul>
+ *
+ * <p>Before {@link android.os.Build.VERSION_CODES#VANILLA_ICE_CREAM Android V}, only {@link
+ * android.view.SurfaceView} and {@link android.graphics.SurfaceTexture} are supported. Both
+ * kind of outputs can be deferred until after {@link
+ * CameraDevice#createCaptureSessionByOutputConfiguration}.</p>
+ *
+ * <p>An OutputConfiguration object created by this constructor can be used for {@link
+ * CameraDeviceSetup.isSessionConfigurationSupported} and {@link
+ * CameraDeviceSetup.getSessionCharacteristics} without having called {@link #addSurface}.</p>
*
* @param surfaceSize Size for the deferred surface.
* @param klass a non-{@code null} {@link Class} object reference that indicates the source of
- * this surface. Only {@link android.view.SurfaceHolder SurfaceHolder.class} and
- * {@link android.graphics.SurfaceTexture SurfaceTexture.class} are supported.
+ * this surface. Only {@link android.view.SurfaceHolder SurfaceHolder.class},
+ * {@link android.graphics.SurfaceTexture SurfaceTexture.class}, {@link
+ * android.media.MediaRecorder MediaRecorder.class}, and
+ * {@link android.media.MediaCodec MediaCodec.class} are supported.
+ * Before {@link android.os.Build.VERSION_CODES#VANILLA_ICE_CREAM Android V}, only
+ * {@link android.view.SurfaceHolder SurfaceHolder.class} and {@link
+ * android.graphics.SurfaceTexture SurfaceTexture.class} are supported.
* @throws IllegalArgumentException if the Surface source class is not supported, or Surface
* size is zero.
*/
public <T> OutputConfiguration(@NonNull Size surfaceSize, @NonNull Class<T> klass) {
- checkNotNull(klass, "surfaceSize must not be null");
+ checkNotNull(surfaceSize, "surfaceSize must not be null");
checkNotNull(klass, "klass must not be null");
if (klass == android.view.SurfaceHolder.class) {
mSurfaceType = SURFACE_TYPE_SURFACE_VIEW;
+ mIsDeferredConfig = true;
} else if (klass == android.graphics.SurfaceTexture.class) {
mSurfaceType = SURFACE_TYPE_SURFACE_TEXTURE;
+ mIsDeferredConfig = true;
+ } else if (klass == android.media.MediaRecorder.class) {
+ mSurfaceType = SURFACE_TYPE_MEDIA_RECORDER;
+ mIsDeferredConfig = false;
+ } else if (klass == android.media.MediaCodec.class) {
+ mSurfaceType = SURFACE_TYPE_MEDIA_CODEC;
+ mIsDeferredConfig = false;
} else {
mSurfaceType = SURFACE_TYPE_UNKNOWN;
throw new IllegalArgumentException("Unknown surface source class type");
@@ -668,7 +828,6 @@ public final class OutputConfiguration implements Parcelable {
mConfiguredFormat = StreamConfigurationMap.imageFormatToInternal(ImageFormat.PRIVATE);
mConfiguredDataspace = StreamConfigurationMap.imageFormatToDataspace(ImageFormat.PRIVATE);
mConfiguredGenerationId = 0;
- mIsDeferredConfig = true;
mIsShared = false;
mPhysicalCameraId = null;
mIsMultiResolution = false;
@@ -678,6 +837,131 @@ public final class OutputConfiguration implements Parcelable {
mStreamUseCase = CameraMetadata.SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT;
mReadoutTimestampEnabled = false;
mIsReadoutSensorTimestampBase = false;
+ mUsage = 0;
+ }
+
+ /**
+ * Create a new {@link OutputConfiguration} instance for an {@link ImageReader} for a given
+ * format and size.
+ *
+ * <p>This constructor creates an OutputConfiguration for an ImageReader without providing
+ * the actual output Surface. The actual output Surface must be set via {@link #addSurface}
+ * before creating the capture session.</p>
+ *
+ * <p>An OutputConfiguration object created by this constructor can be used for {@link
+ * CameraDeviceSetup.isSessionConfigurationSupported} and {@link
+ * CameraDeviceSetup.getSessionCharacteristics} without having called {@link #addSurface}.</p>
+ *
+ * @param format The format of the ImageReader output. This must be one of the
+ * {@link android.graphics.ImageFormat} or {@link android.graphics.PixelFormat}
+ * constants. Note that not all formats are supported by the camera device.
+ * @param surfaceSize Size for the ImageReader surface.
+ * @throws IllegalArgumentException if the Surface size is null or zero.
+ */
+ @FlaggedApi(Flags.FLAG_CAMERA_DEVICE_SETUP)
+ public OutputConfiguration(@Format int format, @NonNull Size surfaceSize) {
+ this(format, surfaceSize,
+ format == ImageFormat.PRIVATE ? 0 : HardwareBuffer.USAGE_CPU_READ_OFTEN);
+ }
+
+ /**
+ * Create a new {@link OutputConfiguration} instance for an {@link ImageReader} for a given
+ * surfaceGroupId, format, and size.
+ *
+ * <p>This constructor creates an OutputConfiguration for an ImageReader without providing
+ * the actual output Surface. The actual output Surface must be set via {@link #addSurface}
+ * before creating the capture session.</p>
+ *
+ * <p>An OutputConfiguration object created by this constructor can be used for {@link
+ * CameraDeviceSetup.isSessionConfigurationSupported} and {@link
+ * CameraDeviceSetup.getSessionCharacteristics} without having called {@link #addSurface}.</p>
+ *
+ * @param surfaceGroupId A group ID for this output, used for sharing memory between multiple
+ * outputs.
+ * @param format The format of the ImageReader output. This must be one of the
+ * {@link android.graphics.ImageFormat} or {@link android.graphics.PixelFormat}
+ * constants. Note that not all formats are supported by the camera device.
+ * @param surfaceSize Size for the ImageReader surface.
+ * @throws IllegalArgumentException if the Surface size is null or zero.
+ */
+ @FlaggedApi(Flags.FLAG_CAMERA_DEVICE_SETUP)
+ public OutputConfiguration(int surfaceGroupId, @Format int format, @NonNull Size surfaceSize) {
+ this(surfaceGroupId, format, surfaceSize,
+ format == ImageFormat.PRIVATE ? 0 : HardwareBuffer.USAGE_CPU_READ_OFTEN);
+ }
+
+ /**
+ * Create a new {@link OutputConfiguration} instance for an {@link ImageReader} for a given
+ * format, size, and usage flags.
+ *
+ * <p>This constructor creates an OutputConfiguration for an ImageReader without providing
+ * the actual output Surface. The actual output Surface must be set via {@link #addSurface}
+ * before creating the capture session.</p>
+ *
+ * <p>An OutputConfiguration object created by this constructor can be used for {@link
+ * CameraDeviceSetup.isSessionConfigurationSupported} and {@link
+ * CameraDeviceSetup.getSessionCharacteristics} without having called {@link #addSurface}.</p>
+ *
+ * @param format The format of the ImageReader output. This must be one of the
+ * {@link android.graphics.ImageFormat} or {@link android.graphics.PixelFormat}
+ * constants. Note that not all formats are supported by the camera device.
+ * @param surfaceSize Size for the ImageReader surface.
+ * @param usage The usage flags of the ImageReader output surface.
+ * @throws IllegalArgumentException if the Surface size is null or zero.
+ */
+ @FlaggedApi(Flags.FLAG_CAMERA_DEVICE_SETUP)
+ public OutputConfiguration(@Format int format, @NonNull Size surfaceSize, @Usage long usage) {
+ this(SURFACE_GROUP_ID_NONE, format, surfaceSize, usage);
+ }
+
+ /**
+ * Create a new {@link OutputConfiguration} instance for an {@link ImageReader} for a given
+ * surface group id, format, size, and usage flags.
+ *
+ * <p>This constructor creates an OutputConfiguration for an ImageReader without providing
+ * the actual output Surface. The actual output Surface must be set via {@link #addSurface}
+ * before creating the capture session.</p>
+ *
+ * <p>An OutputConfiguration object created by this constructor can be used for {@link
+ * CameraDeviceSetup.isSessionConfigurationSupported} and {@link
+ * CameraDeviceSetup.getSessionCharacteristics} without having called {@link #addSurface}.</p>
+ *
+ * @param surfaceGroupId A group ID for this output, used for sharing memory between multiple
+ * outputs.
+ * @param format The format of the ImageReader output. This must be one of the
+ * {@link android.graphics.ImageFormat} or {@link android.graphics.PixelFormat}
+ * constants. Note that not all formats are supported by the camera device.
+ * @param surfaceSize Size for the ImageReader surface.
+ * @param usage The usage flags of the ImageReader output surface.
+ * @throws IllegalArgumentException if the Surface size is null or zero.
+ */
+ @FlaggedApi(Flags.FLAG_CAMERA_DEVICE_SETUP)
+ public OutputConfiguration(int surfaceGroupId, @Format int format,
+ @NonNull Size surfaceSize, @Usage long usage) {
+ checkNotNull(surfaceSize, "surfaceSize must not be null");
+ if (surfaceSize.getWidth() == 0 || surfaceSize.getHeight() == 0) {
+ throw new IllegalArgumentException("Surface size needs to be non-zero");
+ }
+
+ mSurfaceType = SURFACE_TYPE_IMAGE_READER;
+ mSurfaceGroupId = surfaceGroupId;
+ mSurfaces = new ArrayList<Surface>();
+ mRotation = ROTATION_0;
+ mConfiguredSize = surfaceSize;
+ mConfiguredFormat = StreamConfigurationMap.imageFormatToInternal(format);
+ mConfiguredDataspace = StreamConfigurationMap.imageFormatToDataspace(format);
+ mConfiguredGenerationId = 0;
+ mIsDeferredConfig = false;
+ mIsShared = false;
+ mPhysicalCameraId = null;
+ mIsMultiResolution = false;
+ mSensorPixelModesUsed = new ArrayList<Integer>();
+ mDynamicRangeProfile = DynamicRangeProfiles.STANDARD;
+ mColorSpace = ColorSpaceProfiles.UNSPECIFIED;
+ mStreamUseCase = CameraMetadata.SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT;
+ mReadoutTimestampEnabled = false;
+ mIsReadoutSensorTimestampBase = false;
+ mUsage = usage;
}
/**
@@ -852,7 +1136,8 @@ public final class OutputConfiguration implements Parcelable {
/**
* Check if this configuration has deferred configuration.
*
- * <p>This will return true if the output configuration was constructed with surface deferred by
+ * <p>This will return true if the output configuration was constructed with {@link
+ * android.view.SurfaceView} or {@link android.graphics.SurfaceTexture} deferred by
* {@link OutputConfiguration#OutputConfiguration(Size, Class)}. It will return true even after
* the deferred surface is added later by {@link OutputConfiguration#addSurface}.</p>
*
@@ -872,13 +1157,28 @@ public final class OutputConfiguration implements Parcelable {
* {@link CameraCaptureSession#finalizeOutputConfigurations}. It is possible to call this method
* after the output configurations have been finalized only in cases of enabled surface sharing
* see {@link #enableSurfaceSharing}. The modified output configuration must be updated with
- * {@link CameraCaptureSession#updateOutputConfiguration}.</p>
- *
- * <p> If the OutputConfiguration was constructed with a deferred surface by {@link
- * OutputConfiguration#OutputConfiguration(Size, Class)}, the added surface must be obtained
- * from {@link android.view.SurfaceView} by calling {@link android.view.SurfaceHolder#getSurface},
- * or from {@link android.graphics.SurfaceTexture} via
- * {@link android.view.Surface#Surface(android.graphics.SurfaceTexture)}).</p>
+ * {@link CameraCaptureSession#updateOutputConfiguration}. If this function is called before
+ * session creation, {@link CameraCaptureSession#finalizeOutputConfigurations} doesn't need to
+ * be called.</p>
+ *
+ * <p> If the OutputConfiguration was constructed by {@link
+ * OutputConfiguration#OutputConfiguration(Size, Class)}, the added surface must be obtained:
+ * <ul>
+ * <li>from {@link android.view.SurfaceView} by calling
+ * {@link android.view.SurfaceHolder#getSurface}</li>
+ * <li>from {@link android.graphics.SurfaceTexture} by calling
+ * {@link android.view.Surface#Surface(android.graphics.SurfaceTexture)}</li>
+ * <li>from {@link android.media.MediaRecorder} by calling
+ * {@link android.media.MediaRecorder#getSurface} or {@link
+ * android.media.MediaCodec#createPersistentInputSurface}</li>
+ * <li>from {@link android.media.MediaCodce} by calling
+ * {@link android.media.MediaCodec#createInputSurface} or {@link
+ * android.media.MediaCodec#createPersistentInputSource}</li>
+ * </ul>
+ *
+ * <p> If the OutputConfiguration was constructed by {@link #OutputConfiguration(int, Size)}
+ * or its variants, the added surface must be obtained from {@link android.media.ImageReader}
+ * by calling {@link android.media.ImageReader#getSurface}.</p>
*
* <p> If the OutputConfiguration was constructed by other constructors, the added
* surface must be compatible with the existing surface. See {@link #enableSurfaceSharing} for
@@ -934,9 +1234,13 @@ public final class OutputConfiguration implements Parcelable {
*
* <p> Surfaces added via calls to {@link #addSurface} can also be removed from the
* OutputConfiguration. The only notable exception is the surface associated with
- * the OutputConfiguration see {@link #getSurface} which was passed as part of the constructor
- * or was added first in the deferred case
- * {@link OutputConfiguration#OutputConfiguration(Size, Class)}.</p>
+ * the OutputConfiguration (see {@link #getSurface}) which was passed as part of the
+ * constructor or was added first in the case of
+ * {@link OutputConfiguration#OutputConfiguration(Size, Class)}, {@link
+ * OutputConfiguration#OutputConfiguration(int, Size)}, {@link
+ * OutputConfiguration#OutputConfiguration(int, Size, long)}, {@link
+ * OutputConfiguration#OutputConfiguration(int, int, Size)}, {@link
+ * OutputConfiguration#OutputConfiguration(int, int, Size, long)}.</p>
*
* @param surface The surface to be removed.
*
@@ -945,6 +1249,7 @@ public final class OutputConfiguration implements Parcelable {
* with {@link #addSurface}.
*/
public void removeSurface(@NonNull Surface surface) {
+ checkNotNull(surface, "Surface must not be null");
if (getSurface() == surface) {
throw new IllegalArgumentException(
"Cannot remove surface associated with this output configuration");
@@ -1175,6 +1480,7 @@ public final class OutputConfiguration implements Parcelable {
this.mTimestampBase = other.mTimestampBase;
this.mMirrorMode = other.mMirrorMode;
this.mReadoutTimestampEnabled = other.mReadoutTimestampEnabled;
+ this.mUsage = other.mUsage;
}
/**
@@ -1203,6 +1509,9 @@ public final class OutputConfiguration implements Parcelable {
int timestampBase = source.readInt();
int mirrorMode = source.readInt();
boolean readoutTimestampEnabled = source.readInt() == 1;
+ int format = source.readInt();
+ int dataSpace = source.readInt();
+ long usage = source.readLong();
mSurfaceGroupId = surfaceSetId;
mRotation = rotation;
@@ -1211,6 +1520,7 @@ public final class OutputConfiguration implements Parcelable {
mIsDeferredConfig = isDeferred;
mIsShared = isShared;
mSurfaces = surfaces;
+ mUsage = 0;
if (mSurfaces.size() > 0) {
mSurfaceType = SURFACE_TYPE_UNKNOWN;
mConfiguredFormat = SurfaceUtils.getSurfaceFormat(mSurfaces.get(0));
@@ -1218,9 +1528,16 @@ public final class OutputConfiguration implements Parcelable {
mConfiguredGenerationId = mSurfaces.get(0).getGenerationId();
} else {
mSurfaceType = surfaceType;
- mConfiguredFormat = StreamConfigurationMap.imageFormatToInternal(ImageFormat.PRIVATE);
- mConfiguredDataspace =
- StreamConfigurationMap.imageFormatToDataspace(ImageFormat.PRIVATE);
+ if (mSurfaceType != SURFACE_TYPE_IMAGE_READER) {
+ mConfiguredFormat = StreamConfigurationMap.imageFormatToInternal(
+ ImageFormat.PRIVATE);
+ mConfiguredDataspace =
+ StreamConfigurationMap.imageFormatToDataspace(ImageFormat.PRIVATE);
+ } else {
+ mConfiguredFormat = format;
+ mConfiguredDataspace = dataSpace;
+ mUsage = usage;
+ }
mConfiguredGenerationId = 0;
}
mPhysicalCameraId = physicalCameraId;
@@ -1293,6 +1610,31 @@ public final class OutputConfiguration implements Parcelable {
return mSurfaceGroupId;
}
+ /**
+ * Get the configured size associated with this {@link OutputConfiguration}.
+ *
+ * @return The configured size associated with this {@link OutputConfiguration}.
+ *
+ * @hide
+ */
+ public Size getConfiguredSize() {
+ return mConfiguredSize;
+ }
+
+ /**
+ * Get the physical camera ID associated with this {@link OutputConfiguration}.
+ *
+ * <p>If this OutputConfiguration isn't targeting a physical camera of a logical
+ * multi-camera, this function returns {@code null}.</p>
+ *
+ * @return The physical camera Id associated with this {@link OutputConfiguration}.
+ *
+ * @hide
+ */
+ public @Nullable String getPhysicalCameraId() {
+ return mPhysicalCameraId;
+ }
+
public static final @android.annotation.NonNull Parcelable.Creator<OutputConfiguration> CREATOR =
new Parcelable.Creator<OutputConfiguration>() {
@Override
@@ -1353,6 +1695,9 @@ public final class OutputConfiguration implements Parcelable {
dest.writeInt(mTimestampBase);
dest.writeInt(mMirrorMode);
dest.writeInt(mReadoutTimestampEnabled ? 1 : 0);
+ dest.writeInt(mConfiguredFormat);
+ dest.writeInt(mConfiguredDataspace);
+ dest.writeLong(mUsage);
}
/**
@@ -1372,22 +1717,24 @@ public final class OutputConfiguration implements Parcelable {
return true;
} else if (obj instanceof OutputConfiguration) {
final OutputConfiguration other = (OutputConfiguration) obj;
- if (mRotation != other.mRotation ||
- !mConfiguredSize.equals(other.mConfiguredSize) ||
- mConfiguredFormat != other.mConfiguredFormat ||
- mSurfaceGroupId != other.mSurfaceGroupId ||
- mSurfaceType != other.mSurfaceType ||
- mIsDeferredConfig != other.mIsDeferredConfig ||
- mIsShared != other.mIsShared ||
- mConfiguredDataspace != other.mConfiguredDataspace ||
- mConfiguredGenerationId != other.mConfiguredGenerationId ||
- !Objects.equals(mPhysicalCameraId, other.mPhysicalCameraId) ||
- mIsMultiResolution != other.mIsMultiResolution ||
- mStreamUseCase != other.mStreamUseCase ||
- mTimestampBase != other.mTimestampBase ||
- mMirrorMode != other.mMirrorMode ||
- mReadoutTimestampEnabled != other.mReadoutTimestampEnabled)
+ if (mRotation != other.mRotation
+ || !mConfiguredSize.equals(other.mConfiguredSize)
+ || mConfiguredFormat != other.mConfiguredFormat
+ || mSurfaceGroupId != other.mSurfaceGroupId
+ || mSurfaceType != other.mSurfaceType
+ || mIsDeferredConfig != other.mIsDeferredConfig
+ || mIsShared != other.mIsShared
+ || mConfiguredDataspace != other.mConfiguredDataspace
+ || mConfiguredGenerationId != other.mConfiguredGenerationId
+ || !Objects.equals(mPhysicalCameraId, other.mPhysicalCameraId)
+ || mIsMultiResolution != other.mIsMultiResolution
+ || mStreamUseCase != other.mStreamUseCase
+ || mTimestampBase != other.mTimestampBase
+ || mMirrorMode != other.mMirrorMode
+ || mReadoutTimestampEnabled != other.mReadoutTimestampEnabled
+ || mUsage != other.mUsage) {
return false;
+ }
if (mSensorPixelModesUsed.size() != other.mSensorPixelModesUsed.size()) {
return false;
}
@@ -1416,6 +1763,16 @@ public final class OutputConfiguration implements Parcelable {
}
/**
+ * Get and increase the next MultiResolution group id.
+ *
+ * If the ID reaches -1, skip it.
+ */
+ private static int getAndIncreaseMultiResolutionGroupId() {
+ return sNextMultiResolutionGroupId.getAndUpdate(i ->
+ i + 1 == SURFACE_GROUP_ID_NONE ? i + 2 : i + 1);
+ }
+
+ /**
* {@inheritDoc}
*/
@Override
@@ -1430,7 +1787,8 @@ public final class OutputConfiguration implements Parcelable {
mPhysicalCameraId == null ? 0 : mPhysicalCameraId.hashCode(),
mIsMultiResolution ? 1 : 0, mSensorPixelModesUsed.hashCode(),
mDynamicRangeProfile, mColorSpace, mStreamUseCase,
- mTimestampBase, mMirrorMode, mReadoutTimestampEnabled ? 1 : 0);
+ mTimestampBase, mMirrorMode, mReadoutTimestampEnabled ? 1 : 0,
+ Long.hashCode(mUsage));
}
return HashCodeHelpers.hashCode(
@@ -1440,14 +1798,14 @@ public final class OutputConfiguration implements Parcelable {
mPhysicalCameraId == null ? 0 : mPhysicalCameraId.hashCode(),
mIsMultiResolution ? 1 : 0, mSensorPixelModesUsed.hashCode(),
mDynamicRangeProfile, mColorSpace, mStreamUseCase, mTimestampBase,
- mMirrorMode, mReadoutTimestampEnabled ? 1 : 0);
+ mMirrorMode, mReadoutTimestampEnabled ? 1 : 0, Long.hashCode(mUsage));
}
private static final String TAG = "OutputConfiguration";
// A surfaceGroupId counter used for MultiResolutionImageReader. Its value is
// incremented every time {@link createInstancesForMultiResolutionOutput} is called.
- private static int MULTI_RESOLUTION_GROUP_ID_COUNTER = 0;
+ private static AtomicInteger sNextMultiResolutionGroupId = new AtomicInteger(0);
private ArrayList<Surface> mSurfaces;
private final int mRotation;
@@ -1486,4 +1844,6 @@ public final class OutputConfiguration implements Parcelable {
private boolean mReadoutTimestampEnabled;
// Whether the timestamp base is set to READOUT_SENSOR
private boolean mIsReadoutSensorTimestampBase;
+ // The usage flags. Only set for instances created for ImageReader without specifying surface.
+ private long mUsage;
}
diff --git a/core/java/android/hardware/camera2/params/SessionConfiguration.java b/core/java/android/hardware/camera2/params/SessionConfiguration.java
index 991f545b5193..b0f354fac009 100644
--- a/core/java/android/hardware/camera2/params/SessionConfiguration.java
+++ b/core/java/android/hardware/camera2/params/SessionConfiguration.java
@@ -20,6 +20,7 @@ package android.hardware.camera2.params;
import static com.android.internal.util.Preconditions.*;
import android.annotation.CallbackExecutor;
+import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -28,6 +29,7 @@ import android.graphics.ColorSpace;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
+import android.hardware.camera2.CameraDevice.CameraDeviceSetup;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.impl.CameraMetadataNative;
import android.hardware.camera2.params.InputConfiguration;
@@ -125,6 +127,34 @@ public final class SessionConfiguration implements Parcelable {
}
/**
+ * Create a new {@link SessionConfiguration} with sessionType and output configurations.
+ *
+ * <p>The SessionConfiguration objects created by this constructor can be used by
+ * {@link CameraDeviceSetup.isSessionConfigurationSupported} and {@link
+ * CameraDeviceSetup.getSessionCharacteristics} to query a camera device's feature
+ * combination support and session specific characteristics. For the SessionConfiguration
+ * object to be used to create a capture session, {@link #setCallback} must be called to
+ * specify the state callback function, and any incomplete OutputConfigurations must be
+ * completed via {@link OutputConfiguration#addSurface} or
+ * {@link OutputConfiguration#setSurfacesForMultiResolutionOutput} as appropriate.</p>
+ *
+ * @param sessionType The session type.
+ * @param outputs A list of output configurations for the capture session.
+ *
+ * @see #SESSION_REGULAR
+ * @see #SESSION_HIGH_SPEED
+ * @see CameraDevice#createCaptureSession(SessionConfiguration)
+ * @see CameraDeviceSetup#isSessionConfigurationSupported
+ * @see CameraDeviceSetup#getSessionCharacteristics
+ */
+ @FlaggedApi(Flags.FLAG_CAMERA_DEVICE_SETUP)
+ public SessionConfiguration(@SessionMode int sessionType,
+ @NonNull List<OutputConfiguration> outputs) {
+ mSessionType = sessionType;
+ mOutputConfigurations = Collections.unmodifiableList(new ArrayList<>(outputs));
+ }
+
+ /**
* Create a SessionConfiguration from Parcel.
* No support for parcelable 'mStateCallback' and 'mExecutor' yet.
*/
@@ -376,4 +406,23 @@ public final class SessionConfiguration implements Parcelable {
return null;
}
}
+
+ /**
+ * Set the state callback and executor.
+ *
+ * <p>This function must be called for the SessionConfiguration object created via {@link
+ * #SessionConfiguration(int, List) SessionConfiguration(int, List&lt;OutputConfiguration&gt;)}
+ * before it's used to create a capture session.</p>
+ *
+ * @param executor The executor which should be used to invoke the callback. In general it is
+ * recommended that camera operations are not done on the main (UI) thread.
+ * @param cb A state callback interface implementation.
+ */
+ @FlaggedApi(Flags.FLAG_CAMERA_DEVICE_SETUP)
+ public void setCallback(
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull CameraCaptureSession.StateCallback cb) {
+ mStateCallback = cb;
+ mExecutor = executor;
+ }
}
diff --git a/core/java/android/hardware/camera2/params/StreamConfigurationMap.java b/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
index b85d6869a1ff..b067095668b2 100644
--- a/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
+++ b/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
@@ -1509,6 +1509,8 @@ public final class StreamConfigurationMap {
return HAL_DATASPACE_HEIF;
case ImageFormat.JPEG_R:
return HAL_DATASPACE_JPEG_R;
+ case ImageFormat.YUV_420_888:
+ return HAL_DATASPACE_JFIF;
default:
return HAL_DATASPACE_UNKNOWN;
}
@@ -2025,6 +2027,10 @@ public final class StreamConfigurationMap {
* @hide
*/
public static final int HAL_DATASPACE_JPEG_R = 0x1005;
+ /**
+ * @hide
+ */
+ public static final int HAL_DATASPACE_JFIF = 0x8C20000;
private static final long DURATION_20FPS_NS = 50000000L;
/**
* @see #getDurations(int, int)
diff --git a/core/java/android/os/IHintSession.aidl b/core/java/android/os/IHintSession.aidl
index fe85da26e610..6fd4f3c7c01a 100644
--- a/core/java/android/os/IHintSession.aidl
+++ b/core/java/android/os/IHintSession.aidl
@@ -17,7 +17,7 @@
package android.os;
-import android.os.WorkDuration;
+import android.hardware.power.WorkDuration;
/** {@hide} */
oneway interface IHintSession {
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 318c2911197c..84619a0eee2e 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -1024,7 +1024,11 @@ public class UserManager {
/**
* Specifies if a user is disallowed from creating a private profile.
* <p>The default value for an unmanaged user is <code>false</code>.
- * For users with a device owner set, the default is <code>true</code>.
+ * For users with a device owner set, the default value is <code>true</code> and the
+ * device owner currently cannot change it to <code>false</code>.
+ * On organization-owned managed profile devices, the default value is <code>false</code> but
+ * the profile owner can change it to <code>true</code> via the parent profile to block creating
+ * of private profiles on the personal user.
*
* <p>Holders of the permission
* {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_PROFILES}
@@ -1034,9 +1038,10 @@ public class UserManager {
* <p>Type: Boolean
* @see DevicePolicyManager#addUserRestriction(ComponentName, String)
* @see DevicePolicyManager#clearUserRestriction(ComponentName, String)
+ * @see DevicePolicyManager#getParentProfileInstance(ComponentName)
* @see #getUserRestrictions()
- * @hide
*/
+ @FlaggedApi(android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE)
public static final String DISALLOW_ADD_PRIVATE_PROFILE = "no_add_private_profile";
/**
diff --git a/core/java/android/os/WorkDuration.java b/core/java/android/os/WorkDuration.java
index 5a54e90372fc..3627502ed2d9 100644
--- a/core/java/android/os/WorkDuration.java
+++ b/core/java/android/os/WorkDuration.java
@@ -17,7 +17,6 @@
package android.os;
import android.annotation.FlaggedApi;
-import android.annotation.NonNull;
import java.util.Objects;
@@ -29,24 +28,11 @@ import java.util.Objects;
* All timings should be in {@link SystemClock#uptimeNanos()} and measured in wall time.
*/
@FlaggedApi(Flags.FLAG_ADPF_GPU_REPORT_ACTUAL_WORK_DURATION)
-public final class WorkDuration implements Parcelable {
- long mWorkPeriodStartTimestampNanos = 0;
+public final class WorkDuration {
long mActualTotalDurationNanos = 0;
+ long mWorkPeriodStartTimestampNanos = 0;
long mActualCpuDurationNanos = 0;
long mActualGpuDurationNanos = 0;
- long mTimestampNanos = 0;
-
- public static final @NonNull Creator<WorkDuration> CREATOR = new Creator<>() {
- @Override
- public WorkDuration createFromParcel(Parcel in) {
- return new WorkDuration(in);
- }
-
- @Override
- public WorkDuration[] newArray(int size) {
- return new WorkDuration[size];
- }
- };
public WorkDuration() {}
@@ -58,47 +44,37 @@ public final class WorkDuration implements Parcelable {
public WorkDuration(long workPeriodStartTimestampNanos,
long actualTotalDurationNanos,
long actualCpuDurationNanos,
- long actualGpuDurationNanos,
- long timestampNanos) {
- mWorkPeriodStartTimestampNanos = workPeriodStartTimestampNanos;
+ long actualGpuDurationNanos) {
mActualTotalDurationNanos = actualTotalDurationNanos;
+ mWorkPeriodStartTimestampNanos = workPeriodStartTimestampNanos;
mActualCpuDurationNanos = actualCpuDurationNanos;
mActualGpuDurationNanos = actualGpuDurationNanos;
- mTimestampNanos = timestampNanos;
- }
-
- WorkDuration(@NonNull Parcel in) {
- mWorkPeriodStartTimestampNanos = in.readLong();
- mActualTotalDurationNanos = in.readLong();
- mActualCpuDurationNanos = in.readLong();
- mActualGpuDurationNanos = in.readLong();
- mTimestampNanos = in.readLong();
}
/**
- * Sets the work period start timestamp in nanoseconds.
+ * Sets the actual total duration in nanoseconds.
*
* All timings should be in {@link SystemClock#uptimeNanos()}.
*/
- public void setWorkPeriodStartTimestampNanos(long workPeriodStartTimestampNanos) {
- if (workPeriodStartTimestampNanos <= 0) {
+ public void setActualTotalDurationNanos(long actualTotalDurationNanos) {
+ if (actualTotalDurationNanos <= 0) {
throw new IllegalArgumentException(
- "the work period start timestamp should be greater than zero.");
+ "the actual total duration should be greater than zero.");
}
- mWorkPeriodStartTimestampNanos = workPeriodStartTimestampNanos;
+ mActualTotalDurationNanos = actualTotalDurationNanos;
}
/**
- * Sets the actual total duration in nanoseconds.
+ * Sets the work period start timestamp in nanoseconds.
*
* All timings should be in {@link SystemClock#uptimeNanos()}.
*/
- public void setActualTotalDurationNanos(long actualTotalDurationNanos) {
- if (actualTotalDurationNanos <= 0) {
+ public void setWorkPeriodStartTimestampNanos(long workPeriodStartTimestampNanos) {
+ if (workPeriodStartTimestampNanos <= 0) {
throw new IllegalArgumentException(
- "the actual total duration should be greater than zero.");
+ "the work period start timestamp should be greater than zero.");
}
- mActualTotalDurationNanos = actualTotalDurationNanos;
+ mWorkPeriodStartTimestampNanos = workPeriodStartTimestampNanos;
}
/**
@@ -128,21 +104,21 @@ public final class WorkDuration implements Parcelable {
}
/**
- * Returns the work period start timestamp based in nanoseconds.
+ * Returns the actual total duration in nanoseconds.
*
* All timings should be in {@link SystemClock#uptimeNanos()}.
*/
- public long getWorkPeriodStartTimestampNanos() {
- return mWorkPeriodStartTimestampNanos;
+ public long getActualTotalDurationNanos() {
+ return mActualTotalDurationNanos;
}
/**
- * Returns the actual total duration in nanoseconds.
+ * Returns the work period start timestamp based in nanoseconds.
*
* All timings should be in {@link SystemClock#uptimeNanos()}.
*/
- public long getActualTotalDurationNanos() {
- return mActualTotalDurationNanos;
+ public long getWorkPeriodStartTimestampNanos() {
+ return mWorkPeriodStartTimestampNanos;
}
/**
@@ -163,27 +139,6 @@ public final class WorkDuration implements Parcelable {
return mActualGpuDurationNanos;
}
- /**
- * @hide
- */
- public long getTimestampNanos() {
- return mTimestampNanos;
- }
-
- @Override
- public void writeToParcel(@NonNull Parcel dest, int flags) {
- dest.writeLong(mWorkPeriodStartTimestampNanos);
- dest.writeLong(mActualTotalDurationNanos);
- dest.writeLong(mActualCpuDurationNanos);
- dest.writeLong(mActualGpuDurationNanos);
- dest.writeLong(mTimestampNanos);
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
@Override
public boolean equals(Object obj) {
if (obj == this) {
@@ -193,9 +148,8 @@ public final class WorkDuration implements Parcelable {
return false;
}
WorkDuration workDuration = (WorkDuration) obj;
- return workDuration.mTimestampNanos == this.mTimestampNanos
+ return workDuration.mActualTotalDurationNanos == this.mActualTotalDurationNanos
&& workDuration.mWorkPeriodStartTimestampNanos == this.mWorkPeriodStartTimestampNanos
- && workDuration.mActualTotalDurationNanos == this.mActualTotalDurationNanos
&& workDuration.mActualCpuDurationNanos == this.mActualCpuDurationNanos
&& workDuration.mActualGpuDurationNanos == this.mActualGpuDurationNanos;
}
@@ -203,6 +157,6 @@ public final class WorkDuration implements Parcelable {
@Override
public int hashCode() {
return Objects.hash(mWorkPeriodStartTimestampNanos, mActualTotalDurationNanos,
- mActualCpuDurationNanos, mActualGpuDurationNanos, mTimestampNanos);
+ mActualCpuDurationNanos, mActualGpuDurationNanos);
}
}
diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java
index 2d657c2813a5..4060b242292a 100644
--- a/core/java/android/service/dreams/DreamService.java
+++ b/core/java/android/service/dreams/DreamService.java
@@ -18,7 +18,9 @@ package android.service.dreams;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import android.annotation.FlaggedApi;
import android.annotation.IdRes;
+import android.annotation.IntDef;
import android.annotation.LayoutRes;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -47,6 +49,7 @@ import android.os.Looper;
import android.os.PowerManager;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.service.controls.flags.Flags;
import android.util.AttributeSet;
import android.util.Log;
import android.util.MathUtils;
@@ -76,6 +79,8 @@ import org.xmlpull.v1.XmlPullParserException;
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.function.Consumer;
/**
@@ -217,6 +222,33 @@ public class DreamService extends Service implements Window.Callback {
*/
public static final boolean DEFAULT_SHOW_COMPLICATIONS = false;
+ /**
+ * The default value for dream category
+ * @hide
+ */
+ public static final int DREAM_CATEGORY_DEFAULT = 0;
+
+ /**
+ * Dream category for Low Light Dream
+ * @hide
+ */
+ public static final int DREAM_CATEGORY_LOW_LIGHT = 1 << 0;
+
+ /**
+ * Dream category for Home Panel Dream
+ * @hide
+ */
+ public static final int DREAM_CATEGORY_HOME_PANEL = 1 << 1;
+
+ /** @hide */
+ @IntDef(flag = true, prefix = {"DREAM_CATEGORY"}, value = {
+ DREAM_CATEGORY_DEFAULT,
+ DREAM_CATEGORY_LOW_LIGHT,
+ DREAM_CATEGORY_HOME_PANEL
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ @interface DreamCategory {}
+
private final IDreamManager mDreamManager;
private final Handler mHandler = new Handler(Looper.getMainLooper());
private IBinder mDreamToken;
@@ -1122,12 +1154,15 @@ public class DreamService extends Service implements Window.Callback {
try (TypedArray rawMetadata = readMetadata(pm, serviceInfo)) {
if (rawMetadata == null) return null;
return new DreamMetadata(
- convertToComponentName(rawMetadata.getString(
+ convertToComponentName(
+ rawMetadata.getString(
com.android.internal.R.styleable.Dream_settingsActivity), serviceInfo),
rawMetadata.getDrawable(
com.android.internal.R.styleable.Dream_previewImage),
rawMetadata.getBoolean(R.styleable.Dream_showClockAndComplications,
- DEFAULT_SHOW_COMPLICATIONS));
+ DEFAULT_SHOW_COMPLICATIONS),
+ rawMetadata.getInt(R.styleable.Dream_dreamCategory, DREAM_CATEGORY_DEFAULT)
+ );
}
}
@@ -1543,11 +1578,23 @@ public class DreamService extends Service implements Window.Callback {
@NonNull
public final boolean showComplications;
- DreamMetadata(ComponentName settingsActivity, Drawable previewImage,
- boolean showComplications) {
+ @NonNull
+ @FlaggedApi(Flags.FLAG_HOME_PANEL_DREAM)
+ public final int dreamCategory;
+
+ DreamMetadata(
+ ComponentName settingsActivity,
+ Drawable previewImage,
+ boolean showComplications,
+ int dreamCategory) {
this.settingsActivity = settingsActivity;
this.previewImage = previewImage;
this.showComplications = showComplications;
+ if (Flags.homePanelDream()) {
+ this.dreamCategory = dreamCategory;
+ } else {
+ this.dreamCategory = DREAM_CATEGORY_DEFAULT;
+ }
}
}
}
diff --git a/core/java/android/service/ondeviceintelligence/OnDeviceSandboxedInferenceService.java b/core/java/android/service/ondeviceintelligence/OnDeviceSandboxedInferenceService.java
index d943c80e525b..fc7a4c83f82c 100644
--- a/core/java/android/service/ondeviceintelligence/OnDeviceSandboxedInferenceService.java
+++ b/core/java/android/service/ondeviceintelligence/OnDeviceSandboxedInferenceService.java
@@ -27,21 +27,21 @@ import android.annotation.SdkConstant;
import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.app.Service;
-import android.app.ondeviceintelligence.OnDeviceIntelligenceException;
-import android.os.Bundle;
import android.app.ondeviceintelligence.Feature;
import android.app.ondeviceintelligence.IProcessingSignal;
import android.app.ondeviceintelligence.IResponseCallback;
import android.app.ondeviceintelligence.IStreamingResponseCallback;
import android.app.ondeviceintelligence.ITokenInfoCallback;
+import android.app.ondeviceintelligence.OnDeviceIntelligenceException;
import android.app.ondeviceintelligence.OnDeviceIntelligenceManager;
import android.app.ondeviceintelligence.OnDeviceIntelligenceManager.InferenceParams;
-import android.app.ondeviceintelligence.ProcessingSignal;
import android.app.ondeviceintelligence.ProcessingCallback;
+import android.app.ondeviceintelligence.ProcessingSignal;
import android.app.ondeviceintelligence.StreamingProcessingCallback;
import android.app.ondeviceintelligence.TokenInfo;
import android.content.Context;
import android.content.Intent;
+import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.Handler;
import android.os.HandlerExecutor;
@@ -292,15 +292,15 @@ public abstract class OnDeviceSandboxedInferenceService extends Service {
/**
* Provides read-only access to the internal app storage via the
- * {@link OnDeviceIntelligenceService}. This is an asynchronous implementation for
+ * {@link OnDeviceIntelligenceService}. This is an asynchronous alternative for
* {@link #openFileInput(String)}.
*
* @param fileName File name relative to the {@link Context#getFilesDir()}.
- * @param resultConsumer Consumer to populate the corresponding file stream in.
+ * @param resultConsumer Consumer to populate the corresponding file descriptor in.
*/
- public final void openFileInputAsync(@NonNull String fileName,
+ public final void getReadOnlyFileDescriptor(@NonNull String fileName,
@NonNull @CallbackExecutor Executor executor,
- @NonNull Consumer<FileInputStream> resultConsumer) throws FileNotFoundException {
+ @NonNull Consumer<ParcelFileDescriptor> resultConsumer) throws FileNotFoundException {
AndroidFuture<ParcelFileDescriptor> future = new AndroidFuture<>();
try {
mRemoteStorageService.getReadOnlyFileDescriptor(fileName, future);
@@ -314,7 +314,7 @@ public abstract class OnDeviceSandboxedInferenceService extends Service {
executor.execute(() -> resultConsumer.accept(null));
} else {
executor.execute(
- () -> resultConsumer.accept(new FileInputStream(pfd.getFileDescriptor())));
+ () -> resultConsumer.accept(pfd));
}
}, executor);
}
@@ -328,12 +328,12 @@ public abstract class OnDeviceSandboxedInferenceService extends Service {
* @param resultConsumer Consumer to receive a map of filePath to the corresponding file input
* stream.
*/
- public final void fetchFeatureFileInputStreamMap(@NonNull Feature feature,
+ public final void fetchFeatureFileDescriptorMap(@NonNull Feature feature,
@NonNull @CallbackExecutor Executor executor,
- @NonNull Consumer<Map<String, FileInputStream>> resultConsumer) {
+ @NonNull Consumer<Map<String, ParcelFileDescriptor>> resultConsumer) {
try {
mRemoteStorageService.getReadOnlyFeatureFileDescriptorMap(feature,
- wrapResultReceiverAsReadOnly(resultConsumer, executor));
+ wrapAsRemoteCallback(resultConsumer, executor));
} catch (RemoteException e) {
throw new RuntimeException(e);
}
@@ -359,22 +359,18 @@ public abstract class OnDeviceSandboxedInferenceService extends Service {
}
- private RemoteCallback wrapResultReceiverAsReadOnly(
- @NonNull Consumer<Map<String, FileInputStream>> resultConsumer,
+ private RemoteCallback wrapAsRemoteCallback(
+ @NonNull Consumer<Map<String, ParcelFileDescriptor>> resultConsumer,
@NonNull Executor executor) {
return new RemoteCallback(result -> {
if (result == null) {
executor.execute(() -> resultConsumer.accept(new HashMap<>()));
} else {
- Map<String, FileInputStream> bundleMap = new HashMap<>();
- result.keySet().forEach(key -> {
- ParcelFileDescriptor pfd = result.getParcelable(key,
- ParcelFileDescriptor.class);
- if (pfd != null) {
- bundleMap.put(key, new FileInputStream(pfd.getFileDescriptor()));
- }
- });
- executor.execute(() -> resultConsumer.accept(bundleMap));
+ Map<String, ParcelFileDescriptor> pfdMap = new HashMap<>();
+ result.keySet().forEach(key ->
+ pfdMap.put(key, result.getParcelable(key,
+ ParcelFileDescriptor.class)));
+ executor.execute(() -> resultConsumer.accept(pfdMap));
}
});
}
diff --git a/core/java/android/service/persistentdata/PersistentDataBlockManager.java b/core/java/android/service/persistentdata/PersistentDataBlockManager.java
index 9b9cc1933b93..7a1c75a6034f 100644
--- a/core/java/android/service/persistentdata/PersistentDataBlockManager.java
+++ b/core/java/android/service/persistentdata/PersistentDataBlockManager.java
@@ -19,6 +19,7 @@ package android.service.persistentdata;
import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SuppressLint;
import android.annotation.SystemApi;
@@ -100,7 +101,7 @@ public class PersistentDataBlockManager {
*/
@SystemApi
@SuppressLint("RequiresPermission")
- public int write(byte[] data) {
+ public int write(@Nullable byte[] data) {
try {
return sService.write(data);
} catch (RemoteException e) {
@@ -115,7 +116,7 @@ public class PersistentDataBlockManager {
*/
@SystemApi
@SuppressLint("RequiresPermission")
- public byte[] read() {
+ public @Nullable byte[] read() {
try {
return sService.read();
} catch (RemoteException e) {
diff --git a/core/java/android/view/ImeInsetsSourceConsumer.java b/core/java/android/view/ImeInsetsSourceConsumer.java
index 821e13d85370..b30002228d54 100644
--- a/core/java/android/view/ImeInsetsSourceConsumer.java
+++ b/core/java/android/view/ImeInsetsSourceConsumer.java
@@ -49,9 +49,9 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {
/**
* Tracks whether we have an outstanding request from the IME to show, but weren't able to
- * execute it because we didn't have control yet.
+ * execute it because we didn't have control yet, or we didn't have a leash on the control yet.
*/
- private boolean mIsRequestedVisibleAwaitingControl;
+ private boolean mIsRequestedVisibleAwaitingLeash;
public ImeInsetsSourceConsumer(
int id, InsetsState state, Supplier<Transaction> transactionSupplier,
@@ -68,7 +68,7 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {
}
final boolean insetsChanged = super.onAnimationStateChanged(running);
if (!isShowRequested()) {
- mIsRequestedVisibleAwaitingControl = false;
+ mIsRequestedVisibleAwaitingLeash = false;
if (!running && !mHasPendingRequest) {
final var statsToken = ImeTracker.forLogging().onStart(ImeTracker.TYPE_HIDE,
ImeTracker.ORIGIN_CLIENT,
@@ -91,8 +91,8 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {
public void onWindowFocusGained(boolean hasViewFocus) {
super.onWindowFocusGained(hasViewFocus);
getImm().registerImeConsumer(this);
- if ((mController.getRequestedVisibleTypes() & getType()) != 0 && getControl() == null) {
- mIsRequestedVisibleAwaitingControl = true;
+ if ((mController.getRequestedVisibleTypes() & getType()) != 0 && !hasLeash()) {
+ mIsRequestedVisibleAwaitingLeash = true;
}
}
@@ -100,7 +100,7 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {
public void onWindowFocusLost() {
super.onWindowFocusLost();
getImm().unregisterImeConsumer(this);
- mIsRequestedVisibleAwaitingControl = false;
+ mIsRequestedVisibleAwaitingLeash = false;
}
@Override
@@ -130,15 +130,15 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {
ImeTracker.forLogging().onProgress(statsToken,
ImeTracker.PHASE_CLIENT_INSETS_CONSUMER_REQUEST_SHOW);
- if (getControl() == null) {
- // If control is null, schedule to show IME when control is available.
- mIsRequestedVisibleAwaitingControl = true;
+ if (!hasLeash()) {
+ // If control or leash is null, schedule to show IME when both available.
+ mIsRequestedVisibleAwaitingLeash = true;
}
// If we had a request before to show from IME (tracked with mImeRequestedShow), reaching
// this code here means that we now got control, so we can start the animation immediately.
// If client window is trying to control IME and IME is already visible, it is immediate.
if (fromIme
- || (mState.isSourceOrDefaultVisible(getId(), getType()) && getControl() != null)) {
+ || (mState.isSourceOrDefaultVisible(getId(), getType()) && hasLeash())) {
return ShowResult.SHOW_IMMEDIATELY;
}
@@ -148,9 +148,9 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {
void requestHide(boolean fromIme, @Nullable ImeTracker.Token statsToken) {
if (!fromIme) {
- // Create a new token to track the hide request when we have control,
+ // Create a new token to track the hide request when we have control and leash,
// as we use the passed in token for the insets animation already.
- final var notifyStatsToken = getControl() != null
+ final var notifyStatsToken = hasLeash()
? ImeTracker.forLogging().onStart(ImeTracker.TYPE_HIDE,
ImeTracker.ORIGIN_CLIENT,
SoftInputShowHideReason.HIDE_SOFT_INPUT_REQUEST_HIDE_WITH_CONTROL,
@@ -176,7 +176,7 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {
ImeTracker.PHASE_CLIENT_INSETS_CONSUMER_NOTIFY_HIDDEN);
getImm().notifyImeHidden(mController.getHost().getWindowToken(), statsToken);
- mIsRequestedVisibleAwaitingControl = false;
+ mIsRequestedVisibleAwaitingLeash = false;
Trace.asyncTraceEnd(TRACE_TAG_VIEW, "IC.hideRequestFromApi", 0);
}
@@ -196,19 +196,28 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {
if (!super.setControl(control, showTypes, hideTypes)) {
return false;
}
- if (control == null && !mIsRequestedVisibleAwaitingControl) {
+ final boolean hasLeash = control != null && control.getLeash() != null;
+ if (!hasLeash && !mIsRequestedVisibleAwaitingLeash) {
mController.setRequestedVisibleTypes(0 /* visibleTypes */, getType());
removeSurface();
}
- if (control != null) {
- mIsRequestedVisibleAwaitingControl = false;
+ if (hasLeash) {
+ mIsRequestedVisibleAwaitingLeash = false;
}
return true;
}
@Override
protected boolean isRequestedVisibleAwaitingControl() {
- return super.isRequestedVisibleAwaitingControl() || mIsRequestedVisibleAwaitingControl;
+ return super.isRequestedVisibleAwaitingControl() || mIsRequestedVisibleAwaitingLeash;
+ }
+
+ /**
+ * Checks whether the consumer has an insets source control with a leash.
+ */
+ private boolean hasLeash() {
+ final var control = getControl();
+ return control != null && control.getLeash() != null;
}
@Override
@@ -224,7 +233,7 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {
public void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
super.dumpDebug(proto, INSETS_SOURCE_CONSUMER);
- proto.write(IS_REQUESTED_VISIBLE_AWAITING_CONTROL, mIsRequestedVisibleAwaitingControl);
+ proto.write(IS_REQUESTED_VISIBLE_AWAITING_CONTROL, mIsRequestedVisibleAwaitingLeash);
proto.write(HAS_PENDING_REQUEST, mHasPendingRequest);
proto.end(token);
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 0ac893665241..0a75f4e6d731 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -18,6 +18,7 @@ package android.view;
import static android.content.res.Resources.ID_NULL;
import static android.os.Trace.TRACE_TAG_APP;
+import static android.os.Trace.TRACE_TAG_VIEW;
import static android.service.autofill.Flags.FLAG_AUTOFILL_CREDMAN_DEV_INTEGRATION;
import static android.view.ContentInfo.SOURCE_DRAG_AND_DROP;
import static android.view.Surface.FRAME_RATE_CATEGORY_HIGH;
@@ -16356,20 +16357,20 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
ListenerInfo li = mListenerInfo;
if (li != null && li.mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED) {
try {
- Trace.traceBegin(Trace.TRACE_TAG_VIEW, "View.onTouchListener#onTouch");
+ Trace.traceBegin(TRACE_TAG_VIEW, "View.onTouchListener#onTouch");
handled = li.mOnTouchListener.onTouch(this, event);
} finally {
- Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+ Trace.traceEnd(TRACE_TAG_VIEW);
}
}
if (handled) {
return true;
}
try {
- Trace.traceBegin(Trace.TRACE_TAG_VIEW, "View#onTouchEvent");
+ Trace.traceBegin(TRACE_TAG_VIEW, "View#onTouchEvent");
return onTouchEvent(event);
} finally {
- Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+ Trace.traceEnd(TRACE_TAG_VIEW);
}
}
@@ -23846,14 +23847,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
public void buildDrawingCache(boolean autoScale) {
if ((mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == 0 || (autoScale ?
mDrawingCache == null : mUnscaledDrawingCache == null)) {
- if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
- Trace.traceBegin(Trace.TRACE_TAG_VIEW,
+ if (Trace.isTagEnabled(TRACE_TAG_VIEW)) {
+ Trace.traceBegin(TRACE_TAG_VIEW,
"buildDrawingCache/SW Layer for " + getClass().getSimpleName());
}
try {
buildDrawingCacheImpl(autoScale);
} finally {
- Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+ Trace.traceEnd(TRACE_TAG_VIEW);
}
}
}
@@ -28980,6 +28981,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
surface.copyFrom(surfaceControl);
IBinder token = null;
try {
+ Trace.traceBegin(TRACE_TAG_VIEW, "startDragAndDrop#drawDragShadow");
final Canvas canvas = isHardwareAccelerated()
? surface.lockHardwareCanvas()
: surface.lockCanvas(null);
@@ -28988,33 +28990,40 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
shadowBuilder.onDrawShadow(canvas);
} finally {
surface.unlockCanvasAndPost(canvas);
+ Trace.traceEnd(TRACE_TAG_VIEW);
}
- token = mAttachInfo.mSession.performDrag(mAttachInfo.mWindow, flags, surfaceControl,
- root.getLastTouchSource(), root.getLastTouchDeviceId(),
- root.getLastTouchPointerId(), lastTouchPoint.x, lastTouchPoint.y,
- shadowTouchPoint.x, shadowTouchPoint.y, data);
- if (ViewDebug.DEBUG_DRAG) {
- Log.d(VIEW_LOG_TAG, "performDrag returned " + token);
- }
- if (token != null) {
- if (mAttachInfo.mDragSurface != null) {
- mAttachInfo.mDragSurface.release();
- }
- if (mAttachInfo.mDragData != null) {
- View.cleanUpPendingIntents(mAttachInfo.mDragData);
+ Trace.traceBegin(TRACE_TAG_VIEW, "startDragAndDrop#performDrag");
+ try {
+ token = mAttachInfo.mSession.performDrag(mAttachInfo.mWindow, flags, surfaceControl,
+ root.getLastTouchSource(), root.getLastTouchDeviceId(),
+ root.getLastTouchPointerId(), lastTouchPoint.x, lastTouchPoint.y,
+ shadowTouchPoint.x, shadowTouchPoint.y, data);
+ if (ViewDebug.DEBUG_DRAG) {
+ Log.d(VIEW_LOG_TAG, "performDrag returned " + token);
}
- mAttachInfo.mDragSurface = surface;
- mAttachInfo.mDragToken = token;
- mAttachInfo.mDragData = data;
- // Cache the local state object for delivery with DragEvents
- root.setLocalDragState(myLocalState);
- if (a11yEnabled) {
- // Set for AccessibilityEvents
- mAttachInfo.mViewRootImpl.setDragStartedViewForAccessibility(this);
+ if (token != null) {
+ if (mAttachInfo.mDragSurface != null) {
+ mAttachInfo.mDragSurface.release();
+ }
+ if (mAttachInfo.mDragData != null) {
+ // Clean up previous drag data intents
+ View.cleanUpPendingIntents(mAttachInfo.mDragData);
+ }
+ mAttachInfo.mDragSurface = surface;
+ mAttachInfo.mDragToken = token;
+ mAttachInfo.mDragData = data;
+ // Cache the local state object for delivery with DragEvents
+ root.setLocalDragState(myLocalState);
+ if (a11yEnabled) {
+ // Set for AccessibilityEvents
+ mAttachInfo.mViewRootImpl.setDragStartedViewForAccessibility(this);
+ }
}
+ return token != null;
+ } finally {
+ Trace.traceEnd(TRACE_TAG_VIEW);
}
- return token != null;
} catch (Exception e) {
Log.e(VIEW_LOG_TAG, "Unable to initiate drag", e);
return false;
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 8c3cf5f7fe71..cae66720e49e 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -21,8 +21,10 @@ import static android.content.pm.ActivityInfo.OVERRIDE_SANDBOX_VIEW_BOUNDS_APIS;
import static android.graphics.HardwareRenderer.SYNC_CONTEXT_IS_STOPPED;
import static android.graphics.HardwareRenderer.SYNC_LOST_SURFACE_REWARD_IF_FOUND;
import static android.os.IInputConstants.INVALID_INPUT_EVENT_ID;
+import static android.os.Trace.TRACE_TAG_VIEW;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
+import static android.view.DragEvent.ACTION_DRAG_LOCATION;
import static android.view.InputDevice.SOURCE_CLASS_NONE;
import static android.view.InsetsSource.ID_IME;
import static android.view.Surface.FRAME_RATE_CATEGORY_HIGH;
@@ -6473,7 +6475,18 @@ public final class ViewRootImpl implements ViewParent,
DragEvent event = (DragEvent) msg.obj;
// only present when this app called startDrag()
event.mLocalState = mLocalDragState;
- handleDragEvent(event);
+ final boolean traceDragEvent = event.mAction != ACTION_DRAG_LOCATION;
+ try {
+ if (traceDragEvent) {
+ Trace.traceBegin(TRACE_TAG_VIEW,
+ "c#" + DragEvent.actionToString(event.mAction));
+ }
+ handleDragEvent(event);
+ } finally {
+ if (traceDragEvent) {
+ Trace.traceEnd(TRACE_TAG_VIEW);
+ }
+ }
} break;
case MSG_DISPATCH_SYSTEM_UI_VISIBILITY: {
handleDispatchSystemUiVisibilityChanged();
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index c127a432f0bb..107c5f20acde 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -5871,7 +5871,10 @@ public interface WindowManager extends ViewManager {
&& height == WindowManager.LayoutParams.MATCH_PARENT;
}
- private static String layoutInDisplayCutoutModeToString(
+ /**
+ * @hide
+ */
+ public static String layoutInDisplayCutoutModeToString(
@LayoutInDisplayCutoutMode int mode) {
switch (mode) {
case LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT:
diff --git a/core/res/Android.bp b/core/res/Android.bp
index 79b13765dcc6..a44e92ca4019 100644
--- a/core/res/Android.bp
+++ b/core/res/Android.bp
@@ -156,6 +156,7 @@ android_app {
generate_product_characteristics_rro: true,
flags_packages: [
+ "android.app.contextualsearch.flags-aconfig",
"android.content.pm.flags-aconfig",
"android.provider.flags-aconfig",
"camera_platform_flags",
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 12320d708293..31f2d8b13794 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -154,6 +154,7 @@
<protected-broadcast android:name="android.app.backup.intent.INIT" />
<protected-broadcast android:name="android.bluetooth.intent.DISCOVERABLE_TIMEOUT" />
+ <protected-broadcast android:name="android.bluetooth.action.AUTO_ON_STATE_CHANGED" />
<protected-broadcast android:name="android.bluetooth.adapter.action.STATE_CHANGED" />
<protected-broadcast android:name="android.bluetooth.adapter.action.SCAN_MODE_CHANGED" />
<protected-broadcast android:name="android.bluetooth.adapter.action.DISCOVERY_STARTED" />
@@ -6776,11 +6777,12 @@
<permission android:name="android.permission.MANAGE_BIOMETRIC_DIALOG"
android:protectionLevel="signature" />
- <!-- Allows an application to set the BiometricDialog (SystemUI) logo .
+ <!-- Allows an application to set the advanced features on BiometricDialog (SystemUI), including
+ logo, logo description.
<p>Not for use by third-party applications.
@FlaggedApi("android.hardware.biometrics.custom_biometric_prompt")
-->
- <permission android:name="android.permission.SET_BIOMETRIC_DIALOG_LOGO"
+ <permission android:name="android.permission.SET_BIOMETRIC_DIALOG_ADVANCED"
android:protectionLevel="signature|privileged" />
<!-- Allows an application to control keyguard. Only allowed for system processes.
@@ -7208,6 +7210,13 @@
<permission android:name="android.permission.ACCESS_SMARTSPACE"
android:protectionLevel="signature|privileged|development" />
+ <!-- @SystemApi Allows an application to start a contextual search.
+ @FlaggedApi("android.app.contextualsearch.flags.enable_service")
+ @hide <p>Not for use by third-party applications.</p> -->
+ <permission android:name="android.permission.ACCESS_CONTEXTUAL_SEARCH"
+ android:protectionLevel="signature|privileged"
+ android:featureFlag="android.app.contextualsearch.flags.enable_service"/>
+
<!-- @SystemApi Allows an application to manage the wallpaper effects
generation service.
@hide <p>Not for use by third-party applications.</p> -->
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 48cf09a84e57..81c79f23af46 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -4484,6 +4484,21 @@
<attr name="autoTransact" format="boolean"/>
</declare-styleable>
+ <!-- Specify one or more <code>polling-loop-pattern-filter</code> elements inside a
+ <code>host-apdu-service</code> to indicate polling loop frames that
+ your service can handle. -->
+ <!-- @FlaggedApi("android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP") -->
+ <declare-styleable name="PollingLoopPatternFilter">
+ <!-- The patter to match polling loop frames to, must to be compatible with
+ {@link java.util.regex.Pattern#compile(String)} and only contain hexadecimal numbers and
+ `.`, `?` and `*` operators. This attribute is mandatory. -->
+ <attr name="name" />
+ <!-- Whether or not the system should automatically start a transaction when this polling
+ loop filter matches. If not set, default value is false. -->
+ <!-- @FlaggedApi("android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP") -->
+ <attr name="autoTransact" format="boolean"/>
+ </declare-styleable>
+
<!-- Use <code>host-nfcf-service</code> as the root tag of the XML resource that
describes an {@link android.nfc.cardemulation.HostNfcFService} service, which
is referenced from its {@link android.nfc.cardemulation.HostNfcFService#SERVICE_META_DATA}
@@ -8988,6 +9003,14 @@
<!-- Whether to show clock and other complications such as weather in the overlay. Default
to true. Note that the overlay on dreams is currently only supported on tablets. -->
<attr name="showClockAndComplications" format="boolean" />
+
+ <!-- Dream Category to determine the type of dream. Default to default.
+ @hide -->
+ <attr name="dreamCategory" format="integer">
+ <flag name="none" value="0x0" />
+ <flag name="low_light" value="0x1" />
+ <flag name="home_panel" value="0x2" />
+ </attr>
</declare-styleable>
<!-- Use <code>trust-agent</code> as the root tag of the XML resource that
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index b879c9794f39..417c6df1e30d 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -238,204 +238,204 @@
<color name="conversation_important_highlight">#F9AB00</color>
- <!-- Lightest shade of the accent color used by the system. White.
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent1_0">#ffffff</color>
- <!-- Shade of the accent system color at 99% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent1_10">#F9FCFF</color>
- <!-- Shade of the accent system color at 95% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent1_50">#E0F3FF</color>
- <!-- Shade of the accent system color at 90% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent1_100">#C1E8FF</color>
- <!-- Shade of the accent system color at 80% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent1_200">#76D1FF</color>
- <!-- Shade of the accent system color at 70% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent1_300">#4BB6E8</color>
- <!-- Shade of the accent system color at 60% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent1_400">#219BCC</color>
- <!-- Shade of the accent system color at 49.6% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent1_500">#007FAC</color>
- <!-- Shade of the accent system color at 40% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent1_600">#00668B</color>
- <!-- Shade of the accent system color at 30% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent1_700">#004C69</color>
- <!-- Shade of the accent system color at 20% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent1_800">#003549</color>
- <!-- Shade of the accent system color at 10% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent1_900">#001E2C</color>
- <!-- Darkest shade of the accent color used by the system. Black.
- This value can be overlaid at runtime by OverlayManager RROs. -->
+ <!--Lightest shade of the Primary color used by the system. White.
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent1_0">#FFFFFF</color>
+ <!--Shade of the Primary system color at 99% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent1_10">#FEFBFF</color>
+ <!--Shade of the Primary system color at 95% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent1_50">#EEF0FF</color>
+ <!--Shade of the Primary system color at 90% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent1_100">#D9E2FF</color>
+ <!--Shade of the Primary system color at 80% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent1_200">#B0C6FF</color>
+ <!--Shade of the Primary system color at 70% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent1_300">#94AAE4</color>
+ <!--Shade of the Primary system color at 60% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent1_400">#7A90C8</color>
+ <!--Shade of the Primary system color at 50% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent1_500">#6076AC</color>
+ <!--Shade of the Primary system color at 40% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent1_600">#475D92</color>
+ <!--Shade of the Primary system color at 30% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent1_700">#2F4578</color>
+ <!--Shade of the Primary system color at 20% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent1_800">#152E60</color>
+ <!--Shade of the Primary system color at 10% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent1_900">#001945</color>
+ <!--Darkest shade of the Primary color used by the system. Black.
+ This value can be overlaid at runtime by OverlayManager RROs.-->
<color name="system_accent1_1000">#000000</color>
- <!-- Lightest shade of the secondary accent color used by the system. White.
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent2_0">#ffffff</color>
- <!-- Shade of the secondary accent system color at 99% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent2_10">#F9FCFF</color>
- <!-- Shade of the secondary accent system color at 95% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent2_50">#E0F3FF</color>
- <!-- Shade of the secondary accent system color at 90% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent2_100">#D1E5F4</color>
- <!-- Shade of the secondary accent system color at 80% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent2_200">#B5CAD7</color>
- <!-- Shade of the secondary accent system color at 70% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent2_300">#9AAEBB</color>
- <!-- Shade of the secondary accent system color at 60% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent2_400">#8094A0</color>
- <!-- Shade of the secondary accent system color at 49.6% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent2_500">#657985</color>
- <!-- Shade of the secondary accent system color at 40% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent2_600">#4E616C</color>
- <!-- Shade of the secondary accent system color at 30% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent2_700">#374955</color>
- <!-- Shade of the secondary accent system color at 20% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent2_800">#20333D</color>
- <!-- Shade of the secondary accent system color at 10% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent2_900">#091E28</color>
- <!-- Darkest shade of the secondary accent color used by the system. Black.
- This value can be overlaid at runtime by OverlayManager RROs. -->
+ <!--Lightest shade of the Secondary color used by the system. White.
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent2_0">#FFFFFF</color>
+ <!--Shade of the Secondary system color at 99% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent2_10">#FEFBFF</color>
+ <!--Shade of the Secondary system color at 95% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent2_50">#EEF0FF</color>
+ <!--Shade of the Secondary system color at 90% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent2_100">#DCE2F9</color>
+ <!--Shade of the Secondary system color at 80% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent2_200">#C0C6DC</color>
+ <!--Shade of the Secondary system color at 70% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent2_300">#A4ABC1</color>
+ <!--Shade of the Secondary system color at 60% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent2_400">#8A90A5</color>
+ <!--Shade of the Secondary system color at 50% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent2_500">#70778B</color>
+ <!--Shade of the Secondary system color at 40% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent2_600">#575E71</color>
+ <!--Shade of the Secondary system color at 30% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent2_700">#404659</color>
+ <!--Shade of the Secondary system color at 20% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent2_800">#2A3042</color>
+ <!--Shade of the Secondary system color at 10% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent2_900">#151B2C</color>
+ <!--Darkest shade of the Secondary color used by the system. Black.
+ This value can be overlaid at runtime by OverlayManager RROs.-->
<color name="system_accent2_1000">#000000</color>
- <!-- Lightest shade of the tertiary accent color used by the system. White.
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent3_0">#ffffff</color>
- <!-- Shade of the tertiary accent system color at 99% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
+ <!--Lightest shade of the Tertiary color used by the system. White.
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent3_0">#FFFFFF</color>
+ <!--Shade of the Tertiary system color at 99% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
<color name="system_accent3_10">#FFFBFF</color>
- <!-- Shade of the tertiary accent system color at 95% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent3_50">#F5EEFF</color>
- <!-- Shade of the tertiary accent system color at 90% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent3_100">#E6DEFF</color>
- <!-- Shade of the tertiary accent system color at 80% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent3_200">#CAC1EA</color>
- <!-- Shade of the tertiary accent system color at 70% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent3_300">#AEA6CE</color>
- <!-- Shade of the tertiary accent system color at 60% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent3_400">#938CB1</color>
- <!-- Shade of the tertiary accent system color at 49% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent3_500">#787296</color>
- <!-- Shade of the tertiary accent system color at 40% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent3_600">#605A7C</color>
- <!-- Shade of the tertiary accent system color at 30% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent3_700">#484264</color>
- <!-- Shade of the tertiary accent system color at 20% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent3_800">#322C4C</color>
- <!-- Shade of the tertiary accent system color at 10% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_accent3_900">#1D1736</color>
- <!-- Darkest shade of the tertiary accent color used by the system. Black.
- This value can be overlaid at runtime by OverlayManager RROs. -->
+ <!--Shade of the Tertiary system color at 95% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent3_50">#FFEBFA</color>
+ <!--Shade of the Tertiary system color at 90% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent3_100">#FDD7FA</color>
+ <!--Shade of the Tertiary system color at 80% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent3_200">#E0BBDD</color>
+ <!--Shade of the Tertiary system color at 70% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent3_300">#C3A0C1</color>
+ <!--Shade of the Tertiary system color at 60% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent3_400">#A886A6</color>
+ <!--Shade of the Tertiary system color at 50% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent3_500">#8C6D8C</color>
+ <!--Shade of the Tertiary system color at 40% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent3_600">#725572</color>
+ <!--Shade of the Tertiary system color at 30% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent3_700">#593D59</color>
+ <!--Shade of the Tertiary system color at 20% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent3_800">#412742</color>
+ <!--Shade of the Tertiary system color at 10% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_accent3_900">#2A122C</color>
+ <!--Darkest shade of the Tertiary color used by the system. Black.
+ This value can be overlaid at runtime by OverlayManager RROs.-->
<color name="system_accent3_1000">#000000</color>
- <!-- Lightest shade of the neutral color used by the system. White.
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral1_0">#ffffff</color>
- <!-- Shade of the neutral system color at 99% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral1_10">#FCFCFF</color>
- <!-- Shade of the neutral system color at 95% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral1_50">#F0F0F3</color>
- <!-- Shade of the neutral system color at 90% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral1_100">#E1E3E5</color>
- <!-- Shade of the neutral system color at 80% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral1_200">#C5C7C9</color>
- <!-- Shade of the neutral system color at 70% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral1_300">#AAABAE</color>
- <!-- Shade of the neutral system color at 60% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral1_400">#8F9193</color>
- <!-- Shade of the neutral system color at 49% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral1_500">#747679</color>
- <!-- Shade of the neutral system color at 40% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral1_600">#5C5F61</color>
- <!-- Shade of the neutral system color at 30% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral1_700">#454749</color>
- <!-- Shade of the neutral system color at 20% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral1_800">#2E3133</color>
- <!-- Shade of the neutral system color at 10% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral1_900">#191C1E</color>
- <!-- Darkest shade of the neutral color used by the system. Black.
- This value can be overlaid at runtime by OverlayManager RROs. -->
+ <!--Lightest shade of the Neutral color used by the system. White.
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_neutral1_0">#FFFFFF</color>
+ <!--Shade of the Neutral system color at 99% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_neutral1_10">#FEFBFF</color>
+ <!--Shade of the Neutral system color at 95% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_neutral1_50">#F1F0F7</color>
+ <!--Shade of the Neutral system color at 90% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_neutral1_100">#E2E2E9</color>
+ <!--Shade of the Neutral system color at 80% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_neutral1_200">#C6C6CD</color>
+ <!--Shade of the Neutral system color at 70% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_neutral1_300">#ABABB1</color>
+ <!--Shade of the Neutral system color at 60% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_neutral1_400">#909097</color>
+ <!--Shade of the Neutral system color at 50% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_neutral1_500">#76777D</color>
+ <!--Shade of the Neutral system color at 40% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_neutral1_600">#5D5E64</color>
+ <!--Shade of the Neutral system color at 30% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_neutral1_700">#45464C</color>
+ <!--Shade of the Neutral system color at 20% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_neutral1_800">#2F3036</color>
+ <!--Shade of the Neutral system color at 10% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_neutral1_900">#1A1B20</color>
+ <!--Darkest shade of the Neutral color used by the system. Black.
+ This value can be overlaid at runtime by OverlayManager RROs.-->
<color name="system_neutral1_1000">#000000</color>
- <!-- Lightest shade of the secondary neutral color used by the system. White.
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral2_0">#ffffff</color>
- <!-- Shade of the secondary neutral system color at 99% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral2_10">#F9FCFF</color>
- <!-- Shade of the secondary neutral system color at 95% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral2_50">#EBF1F8</color>
- <!-- Shade of the secondary neutral system color at 90% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral2_100">#DCE3E9</color>
- <!-- Shade of the secondary neutral system color at 80% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral2_200">#C0C7CD</color>
- <!-- Shade of the secondary neutral system color at 70% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral2_300">#A5ACB2</color>
- <!-- Shade of the secondary neutral system color at 60% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral2_400">#8A9297</color>
- <!-- Shade of the secondary neutral system color at 49% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral2_500">#70777C</color>
- <!-- Shade of the secondary neutral system color at 40% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral2_600">#585F65</color>
- <!-- Shade of the secondary neutral system color at 30% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral2_700">#40484D</color>
- <!-- Shade of the secondary neutral system color at 20% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral2_800">#2A3136</color>
- <!-- Shade of the secondary neutral system color at 10% perceptual luminance (L* in L*a*b* color space).
- This value can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_neutral2_900">#161C20</color>
- <!-- Darkest shade of the secondary neutral color used by the system. Black.
- This value can be overlaid at runtime by OverlayManager RROs. -->
+ <!--Lightest shade of the Secondary Neutral color used by the system. White.
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_neutral2_0">#FFFFFF</color>
+ <!--Shade of the Secondary Neutral system color at 99% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_neutral2_10">#FEFBFF</color>
+ <!--Shade of the Secondary Neutral system color at 95% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_neutral2_50">#F0F0FA</color>
+ <!--Shade of the Secondary Neutral system color at 90% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_neutral2_100">#E1E2EC</color>
+ <!--Shade of the Secondary Neutral system color at 80% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_neutral2_200">#C5C6D0</color>
+ <!--Shade of the Secondary Neutral system color at 70% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_neutral2_300">#A9ABB4</color>
+ <!--Shade of the Secondary Neutral system color at 60% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_neutral2_400">#8F9099</color>
+ <!--Shade of the Secondary Neutral system color at 50% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_neutral2_500">#757780</color>
+ <!--Shade of the Secondary Neutral system color at 40% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_neutral2_600">#5C5E67</color>
+ <!--Shade of the Secondary Neutral system color at 30% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_neutral2_700">#44464F</color>
+ <!--Shade of the Secondary Neutral system color at 20% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_neutral2_800">#2E3038</color>
+ <!--Shade of the Secondary Neutral system color at 10% perceptual luminance (L* in L*a*b* color space).
+ This value can be overlaid at runtime by OverlayManager RROs.-->
+ <color name="system_neutral2_900">#191B23</color>
+ <!--Darkest shade of the Secondary Neutral color used by the system. Black.
+ This value can be overlaid at runtime by OverlayManager RROs.-->
<color name="system_neutral2_1000">#000000</color>
<!-- Lightest shade of the error color used by the system. White.
@@ -480,106 +480,106 @@
<!-- Colors used in Android system, from design system.
These values can be overlaid at runtime by OverlayManager RROs. -->
- <color name="system_primary_container_light">#D8E2FF</color>
- <color name="system_on_primary_container_light">#001A41</color>
- <color name="system_primary_light">#445E91</color>
+ <color name="system_primary_container_light">#5E73A9</color>
+ <color name="system_on_primary_container_light">#FFFFFF</color>
+ <color name="system_primary_light">#2A4174</color>
<color name="system_on_primary_light">#FFFFFF</color>
- <color name="system_secondary_container_light">#DBE2F9</color>
- <color name="system_on_secondary_container_light">#141B2C</color>
- <color name="system_secondary_light">#575E71</color>
+ <color name="system_secondary_container_light">#6E7488</color>
+ <color name="system_on_secondary_container_light">#FFFFFF</color>
+ <color name="system_secondary_light">#3C4255</color>
<color name="system_on_secondary_light">#FFFFFF</color>
- <color name="system_tertiary_container_light">#FBD7FC</color>
- <color name="system_on_tertiary_container_light">#29132D</color>
- <color name="system_tertiary_light">#715573</color>
+ <color name="system_tertiary_container_light">#8A6A89</color>
+ <color name="system_on_tertiary_container_light">#FFFFFF</color>
+ <color name="system_tertiary_light">#553A55</color>
<color name="system_on_tertiary_light">#FFFFFF</color>
- <color name="system_background_light">#FAF9FD</color>
- <color name="system_on_background_light">#1B1B1F</color>
- <color name="system_surface_light">#FAF9FD</color>
- <color name="system_on_surface_light">#1B1B1F</color>
- <color name="system_surface_container_low_light">#F5F3F7</color>
+ <color name="system_background_light">#FAF8FF</color>
+ <color name="system_on_background_light">#1A1B20</color>
+ <color name="system_surface_light">#FAF8FF</color>
+ <color name="system_on_surface_light">#1A1B20</color>
+ <color name="system_surface_container_low_light">#F4F3FA</color>
<color name="system_surface_container_lowest_light">#FFFFFF</color>
- <color name="system_surface_container_light">#EFEDF1</color>
- <color name="system_surface_container_high_light">#E9E7EC</color>
- <color name="system_surface_container_highest_light">#E3E2E6</color>
- <color name="system_surface_bright_light">#FAF9FD</color>
- <color name="system_surface_dim_light">#DBD9DD</color>
+ <color name="system_surface_container_light">#EEEDF4</color>
+ <color name="system_surface_container_high_light">#E8E7EF</color>
+ <color name="system_surface_container_highest_light">#E2E2E9</color>
+ <color name="system_surface_bright_light">#FAF8FF</color>
+ <color name="system_surface_dim_light">#DAD9E0</color>
<color name="system_surface_variant_light">#E1E2EC</color>
- <color name="system_on_surface_variant_light">#44474F</color>
- <color name="system_outline_light">#72747D</color>
- <color name="system_outline_variant_light">#C4C7C5</color>
- <color name="system_error_light">#C00003</color>
+ <color name="system_on_surface_variant_light">#40434B</color>
+ <color name="system_outline_light">#5D5F67</color>
+ <color name="system_outline_variant_light">#797A83</color>
+ <color name="system_error_light">#8C0009</color>
<color name="system_on_error_light">#FFFFFF</color>
- <color name="system_error_container_light">#FFDAD5</color>
- <color name="system_on_error_container_light">#410000</color>
- <color name="system_primary_fixed">#D8E2FF</color>
- <color name="system_primary_fixed_dim">#ADC6FF</color>
- <color name="system_on_primary_fixed">#001A41</color>
- <color name="system_on_primary_fixed_variant">#2B4678</color>
- <color name="system_secondary_fixed">#DBE2F9</color>
- <color name="system_secondary_fixed_dim">#BFC6DC</color>
- <color name="system_on_secondary_fixed">#141B2C</color>
- <color name="system_on_secondary_fixed_variant">#3F4759</color>
- <color name="system_tertiary_fixed">#FBD7FC</color>
- <color name="system_tertiary_fixed_dim">#DEBCDF</color>
- <color name="system_on_tertiary_fixed">#29132D</color>
- <color name="system_on_tertiary_fixed_variant">#583E5B</color>
- <color name="system_control_activated_light">#D8E2FF</color>
- <color name="system_control_normal_light">#44474F</color>
- <color name="system_control_highlight_light">#1F000000</color>
- <color name="system_text_primary_inverse_light">#E3E2E6</color>
- <color name="system_text_secondary_and_tertiary_inverse_light">#C4C6D0</color>
- <color name="system_text_primary_inverse_disable_only_light">#E3E2E6</color>
- <color name="system_text_secondary_and_tertiary_inverse_disabled_light">#E3E2E6</color>
- <color name="system_text_hint_inverse_light">#E3E2E6</color>
- <color name="system_palette_key_color_primary_light">#5D77AC</color>
- <color name="system_palette_key_color_secondary_light">#6C7488</color>
- <color name="system_palette_key_color_tertiary_light">#907292</color>
- <color name="system_palette_key_color_neutral_light">#838387</color>
- <color name="system_palette_key_color_neutral_variant_light">#777982</color>
- <color name="system_primary_container_dark">#2B4678</color>
- <color name="system_on_primary_container_dark">#D8E2FF</color>
- <color name="system_primary_dark">#ADC6FF</color>
- <color name="system_on_primary_dark">#102F60</color>
- <color name="system_secondary_container_dark">#3F4759</color>
- <color name="system_on_secondary_container_dark">#DBE2F9</color>
- <color name="system_secondary_dark">#BFC6DC</color>
- <color name="system_on_secondary_dark">#293041</color>
- <color name="system_tertiary_container_dark">#583E5B</color>
- <color name="system_on_tertiary_container_dark">#FBD7FC</color>
- <color name="system_tertiary_dark">#DEBCDF</color>
- <color name="system_on_tertiary_dark">#402843</color>
- <color name="system_background_dark">#121316</color>
- <color name="system_on_background_dark">#E3E2E6</color>
- <color name="system_surface_dark">#121316</color>
- <color name="system_on_surface_dark">#E3E2E6</color>
- <color name="system_surface_container_low_dark">#1B1B1F</color>
- <color name="system_surface_container_lowest_dark">#0D0E11</color>
- <color name="system_surface_container_dark">#1F1F23</color>
- <color name="system_surface_container_high_dark">#292A2D</color>
- <color name="system_surface_container_highest_dark">#343538</color>
- <color name="system_surface_bright_dark">#38393C</color>
- <color name="system_surface_dim_dark">#121316</color>
- <color name="system_surface_variant_dark">#44474F</color>
- <color name="system_on_surface_variant_dark">#C4C6D0</color>
- <color name="system_outline_dark">#8E9099</color>
- <color name="system_outline_variant_dark">#444746</color>
- <color name="system_error_dark">#FFB4A8</color>
- <color name="system_on_error_dark">#690001</color>
- <color name="system_error_container_dark">#930001</color>
- <color name="system_on_error_container_dark">#FFDAD5</color>
- <color name="system_control_activated_dark">#2B4678</color>
- <color name="system_control_normal_dark">#C4C6D0</color>
- <color name="system_control_highlight_dark">#33FFFFFF</color>
- <color name="system_text_primary_inverse_dark">#1B1B1F</color>
- <color name="system_text_secondary_and_tertiary_inverse_dark">#44474F</color>
- <color name="system_text_primary_inverse_disable_only_dark">#1B1B1F</color>
- <color name="system_text_secondary_and_tertiary_inverse_disabled_dark">#1B1B1F</color>
- <color name="system_text_hint_inverse_dark">#1B1B1F</color>
- <color name="system_palette_key_color_primary_dark">#5D77AC</color>
- <color name="system_palette_key_color_secondary_dark">#6C7488</color>
- <color name="system_palette_key_color_tertiary_dark">#907292</color>
- <color name="system_palette_key_color_neutral_dark">#838387</color>
- <color name="system_palette_key_color_neutral_variant_dark">#777982</color>
+ <color name="system_error_container_light">#DA342E</color>
+ <color name="system_on_error_container_light">#FFFFFF</color>
+ <color name="system_control_activated_light">#D9E2FF</color>
+ <color name="system_control_normal_light">#44464F</color>
+ <color name="system_control_highlight_light">#000000</color>
+ <color name="system_text_primary_inverse_light">#E2E2E9</color>
+ <color name="system_text_secondary_and_tertiary_inverse_light">#C5C6D0</color>
+ <color name="system_text_primary_inverse_disable_only_light">#E2E2E9</color>
+ <color name="system_text_secondary_and_tertiary_inverse_disabled_light">#E2E2E9</color>
+ <color name="system_text_hint_inverse_light">#E2E2E9</color>
+ <color name="system_palette_key_color_primary_light">#6076AC</color>
+ <color name="system_palette_key_color_secondary_light">#70778B</color>
+ <color name="system_palette_key_color_tertiary_light">#8C6D8C</color>
+ <color name="system_palette_key_color_neutral_light">#76777D</color>
+ <color name="system_palette_key_color_neutral_variant_light">#757780</color>
+ <color name="system_primary_container_dark">#7A90C8</color>
+ <color name="system_on_primary_container_dark">#000000</color>
+ <color name="system_primary_dark">#B7CAFF</color>
+ <color name="system_on_primary_dark">#00143B</color>
+ <color name="system_secondary_container_dark">#8A90A5</color>
+ <color name="system_on_secondary_container_dark">#000000</color>
+ <color name="system_secondary_dark">#C4CAE1</color>
+ <color name="system_on_secondary_dark">#0F1626</color>
+ <color name="system_tertiary_container_dark">#A886A6</color>
+ <color name="system_on_tertiary_container_dark">#000000</color>
+ <color name="system_tertiary_dark">#E4BFE2</color>
+ <color name="system_on_tertiary_dark">#240D26</color>
+ <color name="system_background_dark">#121318</color>
+ <color name="system_on_background_dark">#E2E2E9</color>
+ <color name="system_surface_dark">#121318</color>
+ <color name="system_on_surface_dark">#FCFAFF</color>
+ <color name="system_surface_container_low_dark">#1A1B20</color>
+ <color name="system_surface_container_lowest_dark">#0C0E13</color>
+ <color name="system_surface_container_dark">#1E1F25</color>
+ <color name="system_surface_container_high_dark">#282A2F</color>
+ <color name="system_surface_container_highest_dark">#33343A</color>
+ <color name="system_surface_bright_dark">#38393F</color>
+ <color name="system_surface_dim_dark">#121318</color>
+ <color name="system_surface_variant_dark">#44464F</color>
+ <color name="system_on_surface_variant_dark">#C9CAD4</color>
+ <color name="system_outline_dark">#A1A2AC</color>
+ <color name="system_outline_variant_dark">#81838C</color>
+ <color name="system_error_dark">#FFBAB1</color>
+ <color name="system_on_error_dark">#370001</color>
+ <color name="system_error_container_dark">#FF5449</color>
+ <color name="system_on_error_container_dark">#000000</color>
+ <color name="system_control_activated_dark">#2F4578</color>
+ <color name="system_control_normal_dark">#C5C6D0</color>
+ <color name="system_control_highlight_dark">#FFFFFF</color>
+ <color name="system_text_primary_inverse_dark">#1A1B20</color>
+ <color name="system_text_secondary_and_tertiary_inverse_dark">#44464F</color>
+ <color name="system_text_primary_inverse_disable_only_dark">#1A1B20</color>
+ <color name="system_text_secondary_and_tertiary_inverse_disabled_dark">#1A1B20</color>
+ <color name="system_text_hint_inverse_dark">#1A1B20</color>
+ <color name="system_palette_key_color_primary_dark">#6076AC</color>
+ <color name="system_palette_key_color_secondary_dark">#70778B</color>
+ <color name="system_palette_key_color_tertiary_dark">#8C6D8C</color>
+ <color name="system_palette_key_color_neutral_dark">#76777D</color>
+ <color name="system_palette_key_color_neutral_variant_dark">#757780</color>
+ <color name="system_primary_fixed">#5E73A9</color>
+ <color name="system_primary_fixed_dim">#455B8F</color>
+ <color name="system_on_primary_fixed">#FFFFFF</color>
+ <color name="system_on_primary_fixed_variant">#FFFFFF</color>
+ <color name="system_secondary_fixed">#6E7488</color>
+ <color name="system_secondary_fixed_dim">#555C6F</color>
+ <color name="system_on_secondary_fixed">#FFFFFF</color>
+ <color name="system_on_secondary_fixed_variant">#FFFFFF</color>
+ <color name="system_tertiary_fixed">#8A6A89</color>
+ <color name="system_tertiary_fixed_dim">#705270</color>
+ <color name="system_on_tertiary_fixed">#FFFFFF</color>
+ <color name="system_on_tertiary_fixed_variant">#FFFFFF</color>
<!-- Accessibility shortcut icon background color -->
<color name="accessibility_feature_background">#5F6368</color> <!-- Google grey 700 -->
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 511c6c93721a..e3f1cb619eb5 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -6977,4 +6977,8 @@
<!-- The key containing the branching boolean for legacy Search. -->
<string name="config_defaultContextualSearchLegacyEnabled" translatable="false" />
+
+ <!-- Whether WM DisplayContent supports high performance transitions
+ (lower-end devices may want to disable) -->
+ <bool name="config_deviceSupportsHighPerfTransitions">true</bool>
</resources>
diff --git a/core/res/res/values/public-staging.xml b/core/res/res/values/public-staging.xml
index 3303c076c090..4be8c1bb4627 100644
--- a/core/res/res/values/public-staging.xml
+++ b/core/res/res/values/public-staging.xml
@@ -167,6 +167,8 @@
<public name="shiftDrawingOffsetForStartOverhang" />
<!-- @FlaggedApi("android.view.flags.toolkit_set_frame_rate_read_only") -->
<public name="windowIsFrameRatePowerSavingsBalanced"/>
+ <!-- @FlaggedApi("android.service.controls.flags.Flags.FLAG_HOME_PANEL_DREAM") -->
+ <public name="dreamCategory"/>
</staging-public-group>
<staging-public-group type="id" first-id="0x01bc0000">
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index c7e08e2b5b92..f915f038dc0d 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -400,6 +400,9 @@
<string name="scCellularNetworkSecurityTitle">Cellular network security</string>
<!-- Summary of the cellular network security safety center source's status. -->
<string name="scCellularNetworkSecuritySummary">Review settings</string>
+ <!-- Link passed to safety center for the Learn More button on notifications -->
+ <!-- DO NOT TRANSLATE -->
+ <string name="scCellularNetworkSecurityLearnMore" translatable="false"></string>
<!-- Title of the safety center issue and notification when the phone's identifier is shared over the network. -->
<string name="scIdentifierDisclosureIssueTitle">Device identifier accessed</string>
<!-- Summary of the safety center issue and notification when the phone's identifier is shared over the network. -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index b11d26ee6501..f4b42f6b3fb2 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -954,6 +954,7 @@
<java-symbol type="string" name="roamingTextSearching" />
<java-symbol type="string" name="scCellularNetworkSecuritySummary" />
<java-symbol type="string" name="scCellularNetworkSecurityTitle" />
+ <java-symbol type="string" name="scCellularNetworkSecurityLearnMore" />
<java-symbol type="string" name="scIdentifierDisclosureIssueSummary" />
<java-symbol type="string" name="scIdentifierDisclosureIssueTitle" />
<java-symbol type="string" name="scNullCipherIssueActionLearnMore" />
@@ -5374,4 +5375,7 @@
<java-symbol type="string" name="config_defaultContextualSearchLegacyEnabled" />
<java-symbol type="string" name="unarchival_session_app_label" />
+
+ <!-- Whether WM DisplayContent supports high performance transitions -->
+ <java-symbol type="bool" name="config_deviceSupportsHighPerfTransitions" />
</resources>
diff --git a/core/tests/coretests/src/android/os/PerformanceHintManagerTest.java b/core/tests/coretests/src/android/os/PerformanceHintManagerTest.java
index 2bd563191134..93a564208522 100644
--- a/core/tests/coretests/src/android/os/PerformanceHintManagerTest.java
+++ b/core/tests/coretests/src/android/os/PerformanceHintManagerTest.java
@@ -243,25 +243,25 @@ public class PerformanceHintManagerTest {
assumeNotNull(s);
s.updateTargetWorkDuration(16);
assertThrows(IllegalArgumentException.class, () -> {
- s.reportActualWorkDuration(new WorkDuration(-1, 12, 8, 6, 1));
+ s.reportActualWorkDuration(new WorkDuration(-1, 12, 8, 6));
});
assertThrows(IllegalArgumentException.class, () -> {
- s.reportActualWorkDuration(new WorkDuration(0, 12, 8, 6, 1));
+ s.reportActualWorkDuration(new WorkDuration(0, 12, 8, 6));
});
assertThrows(IllegalArgumentException.class, () -> {
- s.reportActualWorkDuration(new WorkDuration(1, -1, 8, 6, 1));
+ s.reportActualWorkDuration(new WorkDuration(1, -1, 8, 6));
});
assertThrows(IllegalArgumentException.class, () -> {
- s.reportActualWorkDuration(new WorkDuration(1, 0, 8, 6, 1));
+ s.reportActualWorkDuration(new WorkDuration(1, 0, 8, 6));
});
assertThrows(IllegalArgumentException.class, () -> {
- s.reportActualWorkDuration(new WorkDuration(1, 12, -1, 6, 1));
+ s.reportActualWorkDuration(new WorkDuration(1, 12, -1, 6));
});
assertThrows(IllegalArgumentException.class, () -> {
- s.reportActualWorkDuration(new WorkDuration(1, 12, 0, 0, 1));
+ s.reportActualWorkDuration(new WorkDuration(1, 12, 0, 0));
});
assertThrows(IllegalArgumentException.class, () -> {
- s.reportActualWorkDuration(new WorkDuration(1, 12, 8, -1, 1));
+ s.reportActualWorkDuration(new WorkDuration(1, 12, 8, -1));
});
}
}
diff --git a/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java b/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java
index fc1fbb5368dc..47b288993d11 100644
--- a/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java
+++ b/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java
@@ -28,6 +28,7 @@ import static org.mockito.AdditionalMatchers.and;
import static org.mockito.AdditionalMatchers.not;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.notNull;
+import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
@@ -140,6 +141,50 @@ public class ImeInsetsSourceConsumerTest {
}
@Test
+ public void testImeRequestedVisibleAwaitingLeash() {
+ // Set null control, then request show.
+ mController.onControlsChanged(new InsetsSourceControl[] { null });
+
+ InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
+ // Request IME visible before control is available.
+ final var statsToken = ImeTracker.Token.empty();
+ mImeConsumer.onWindowFocusGained(true);
+ mController.show(WindowInsets.Type.ime(), true /* fromIme */, statsToken);
+ // Called once through the show flow.
+ verify(mController).applyAnimation(
+ eq(WindowInsets.Type.ime()), eq(true) /* show */, eq(true) /* fromIme */,
+ eq(statsToken));
+ // Clear previous invocations to verify this is never called with control without leash.
+ clearInvocations(mController);
+
+ // set control without leash and verify visibility is not applied.
+ InsetsSourceControl control = new InsetsSourceControl(ID_IME,
+ WindowInsets.Type.ime(), null /* leash */, false, new Point(), Insets.NONE);
+ mController.onControlsChanged(new InsetsSourceControl[] { control });
+ // IME show animation should not be triggered when control becomes available,
+ // as we have no leash.
+ verify(mController, never()).applyAnimation(
+ eq(WindowInsets.Type.ime()), eq(true) /* show */, eq(false) /* fromIme */,
+ and(not(eq(statsToken)), notNull()));
+ verify(mController, never()).applyAnimation(
+ eq(WindowInsets.Type.ime()), eq(false) /* show */, eq(false) /* fromIme */,
+ and(not(eq(statsToken)), notNull()));
+
+ // set control with leash and verify visibility is applied.
+ InsetsSourceControl controlWithLeash = new InsetsSourceControl(ID_IME,
+ WindowInsets.Type.ime(), mLeash, false, new Point(), Insets.NONE);
+ mController.onControlsChanged(new InsetsSourceControl[] { controlWithLeash });
+ // IME show animation should be triggered when control with leash becomes available.
+ verify(mController).applyAnimation(
+ eq(WindowInsets.Type.ime()), eq(true) /* show */, eq(false) /* fromIme */,
+ and(not(eq(statsToken)), notNull()));
+ verify(mController, never()).applyAnimation(
+ eq(WindowInsets.Type.ime()), eq(false) /* show */, eq(false) /* fromIme */,
+ and(not(eq(statsToken)), notNull()));
+ });
+ }
+
+ @Test
public void testImeGetAndClearSkipAnimationOnce_expectSkip() {
// Expect IME animation will skipped when the IME is visible at first place.
verifyImeGetAndClearSkipAnimationOnce(true /* hasWindowFocus */, true /* hasViewFocus */,
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 749f0e12aa03..9c1c700641f1 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -454,7 +454,7 @@ applications that come with the platform
<!-- Permissions required for CTS test - android.server.biometrics -->
<permission name="android.permission.USE_BIOMETRIC" />
<permission name="android.permission.TEST_BIOMETRIC" />
- <permission name="android.permission.SET_BIOMETRIC_DIALOG_LOGO" />
+ <permission name="android.permission.SET_BIOMETRIC_DIALOG_ADVANCED" />
<permission name="android.permission.MANAGE_BIOMETRIC_DIALOG" />
<!-- Permissions required for CTS test - CtsContactsProviderTestCases -->
<permission name="android.contacts.permission.MANAGE_SIM_ACCOUNTS" />
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/DividerPresenter.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/DividerPresenter.java
new file mode 100644
index 000000000000..100185b84b77
--- /dev/null
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/DividerPresenter.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2024 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 androidx.window.extensions.embedding;
+
+import static android.util.TypedValue.COMPLEX_UNIT_DIP;
+
+import static androidx.window.extensions.embedding.DividerAttributes.RATIO_UNSET;
+import static androidx.window.extensions.embedding.DividerAttributes.WIDTH_UNSET;
+import static androidx.window.extensions.embedding.SplitPresenter.CONTAINER_POSITION_BOTTOM;
+import static androidx.window.extensions.embedding.SplitPresenter.CONTAINER_POSITION_LEFT;
+import static androidx.window.extensions.embedding.SplitPresenter.CONTAINER_POSITION_RIGHT;
+import static androidx.window.extensions.embedding.SplitPresenter.CONTAINER_POSITION_TOP;
+
+import android.annotation.Nullable;
+import android.app.ActivityThread;
+import android.content.Context;
+import android.util.TypedValue;
+
+import androidx.annotation.NonNull;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.window.flags.Flags;
+
+/**
+ * Manages the rendering and interaction of the divider.
+ */
+class DividerPresenter {
+ // TODO(b/327067596) Update based on UX guidance.
+ @VisibleForTesting static final float DEFAULT_MIN_RATIO = 0.35f;
+ @VisibleForTesting static final float DEFAULT_MAX_RATIO = 0.65f;
+ @VisibleForTesting static final int DEFAULT_DIVIDER_WIDTH_DP = 24;
+
+ static int getDividerWidthPx(@NonNull DividerAttributes dividerAttributes) {
+ int dividerWidthDp = dividerAttributes.getWidthDp();
+
+ // TODO(b/329193115) support divider on secondary display
+ final Context applicationContext = ActivityThread.currentActivityThread().getApplication();
+
+ return (int) TypedValue.applyDimension(
+ COMPLEX_UNIT_DIP,
+ dividerWidthDp,
+ applicationContext.getResources().getDisplayMetrics());
+ }
+
+ /**
+ * Returns the container bound offset that is a result of the presence of a divider.
+ *
+ * The offset is the relative position change for the container edge that is next to the divider
+ * due to the presence of the divider. The value could be negative or positive depending on the
+ * container position. Positive values indicate that the edge is shifting towards the right
+ * (or bottom) and negative values indicate that the edge is shifting towards the left (or top).
+ *
+ * @param splitAttributes the {@link SplitAttributes} of the split container that we want to
+ * compute bounds offset.
+ * @param position the position of the container in the split that we want to compute
+ * bounds offset for.
+ * @return the bounds offset in pixels.
+ */
+ static int getBoundsOffsetForDivider(
+ @NonNull SplitAttributes splitAttributes,
+ @SplitPresenter.ContainerPosition int position) {
+ if (!Flags.activityEmbeddingInteractiveDividerFlag()) {
+ return 0;
+ }
+ final DividerAttributes dividerAttributes = splitAttributes.getDividerAttributes();
+ if (dividerAttributes == null) {
+ return 0;
+ }
+ final int dividerWidthPx = getDividerWidthPx(dividerAttributes);
+ return getBoundsOffsetForDivider(
+ dividerWidthPx,
+ splitAttributes.getSplitType(),
+ position);
+ }
+
+ @VisibleForTesting
+ static int getBoundsOffsetForDivider(
+ int dividerWidthPx,
+ @NonNull SplitAttributes.SplitType splitType,
+ @SplitPresenter.ContainerPosition int position) {
+ if (splitType instanceof SplitAttributes.SplitType.ExpandContainersSplitType) {
+ // No divider is needed for the ExpandContainersSplitType.
+ return 0;
+ }
+ int primaryOffset;
+ if (splitType instanceof final SplitAttributes.SplitType.RatioSplitType splitRatio) {
+ // When a divider is present, both containers shrink by an amount proportional to their
+ // split ratio and sum to the width of the divider, so that the ending sizing of the
+ // containers still maintain the same ratio.
+ primaryOffset = (int) (dividerWidthPx * splitRatio.getRatio());
+ } else {
+ // Hinge split type (and other future split types) will have the divider width equally
+ // distributed to both containers.
+ primaryOffset = dividerWidthPx / 2;
+ }
+ final int secondaryOffset = dividerWidthPx - primaryOffset;
+ switch (position) {
+ case CONTAINER_POSITION_LEFT:
+ case CONTAINER_POSITION_TOP:
+ return -primaryOffset;
+ case CONTAINER_POSITION_RIGHT:
+ case CONTAINER_POSITION_BOTTOM:
+ return secondaryOffset;
+ default:
+ throw new IllegalArgumentException("Unknown position:" + position);
+ }
+ }
+
+ /**
+ * Sanitizes and sets default values in the {@link DividerAttributes}.
+ *
+ * Unset values will be set with system default values. See
+ * {@link DividerAttributes#WIDTH_UNSET} and {@link DividerAttributes#RATIO_UNSET}.
+ *
+ * @param dividerAttributes input {@link DividerAttributes}
+ * @return a {@link DividerAttributes} that has all values properly set.
+ */
+ @Nullable
+ static DividerAttributes sanitizeDividerAttributes(
+ @Nullable DividerAttributes dividerAttributes) {
+ if (dividerAttributes == null) {
+ return null;
+ }
+ int widthDp = dividerAttributes.getWidthDp();
+ if (widthDp == WIDTH_UNSET) {
+ widthDp = DEFAULT_DIVIDER_WIDTH_DP;
+ }
+
+ float minRatio = dividerAttributes.getPrimaryMinRatio();
+ if (minRatio == RATIO_UNSET) {
+ minRatio = DEFAULT_MIN_RATIO;
+ }
+
+ float maxRatio = dividerAttributes.getPrimaryMaxRatio();
+ if (maxRatio == RATIO_UNSET) {
+ maxRatio = DEFAULT_MAX_RATIO;
+ }
+
+ return new DividerAttributes.Builder(dividerAttributes)
+ .setWidthDp(widthDp)
+ .setPrimaryMinRatio(minRatio)
+ .setPrimaryMaxRatio(maxRatio)
+ .build();
+ }
+}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
index b53b9c519cb6..f680694c3af9 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
@@ -18,6 +18,7 @@ package androidx.window.extensions.embedding;
import static android.content.pm.PackageManager.MATCH_ALL;
+import static androidx.window.extensions.embedding.DividerPresenter.getBoundsOffsetForDivider;
import static androidx.window.extensions.embedding.WindowAttributes.DIM_AREA_ON_TASK;
import android.app.Activity;
@@ -85,10 +86,10 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
})
private @interface Position {}
- private static final int CONTAINER_POSITION_LEFT = 0;
- private static final int CONTAINER_POSITION_TOP = 1;
- private static final int CONTAINER_POSITION_RIGHT = 2;
- private static final int CONTAINER_POSITION_BOTTOM = 3;
+ static final int CONTAINER_POSITION_LEFT = 0;
+ static final int CONTAINER_POSITION_TOP = 1;
+ static final int CONTAINER_POSITION_RIGHT = 2;
+ static final int CONTAINER_POSITION_BOTTOM = 3;
@IntDef(value = {
CONTAINER_POSITION_LEFT,
@@ -96,7 +97,7 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
CONTAINER_POSITION_RIGHT,
CONTAINER_POSITION_BOTTOM,
})
- private @interface ContainerPosition {}
+ @interface ContainerPosition {}
/**
* Result of {@link #expandSplitContainerIfNeeded(WindowContainerTransaction, SplitContainer,
@@ -738,6 +739,15 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
private SplitAttributes sanitizeSplitAttributes(@NonNull TaskProperties taskProperties,
@NonNull SplitAttributes splitAttributes,
@Nullable Pair<Size, Size> minDimensionsPair) {
+ // Sanitize the DividerAttributes and set default values.
+ if (splitAttributes.getDividerAttributes() != null) {
+ splitAttributes = new SplitAttributes.Builder(splitAttributes)
+ .setDividerAttributes(
+ DividerPresenter.sanitizeDividerAttributes(
+ splitAttributes.getDividerAttributes())
+ ).build();
+ }
+
if (minDimensionsPair == null) {
return splitAttributes;
}
@@ -930,18 +940,18 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
*/
private static SplitAttributes updateSplitAttributesType(
@NonNull SplitAttributes splitAttributes, @NonNull SplitType splitTypeToUpdate) {
- return new SplitAttributes.Builder()
+ return new SplitAttributes.Builder(splitAttributes)
.setSplitType(splitTypeToUpdate)
- .setLayoutDirection(splitAttributes.getLayoutDirection())
- .setAnimationBackground(splitAttributes.getAnimationBackground())
.build();
}
@NonNull
private Rect getLeftContainerBounds(@NonNull Configuration taskConfiguration,
@NonNull SplitAttributes splitAttributes, @Nullable FoldingFeature foldingFeature) {
+ final int dividerOffset = getBoundsOffsetForDivider(
+ splitAttributes, CONTAINER_POSITION_LEFT);
final int right = computeBoundaryBetweenContainers(taskConfiguration, splitAttributes,
- CONTAINER_POSITION_LEFT, foldingFeature);
+ CONTAINER_POSITION_LEFT, foldingFeature) + dividerOffset;
final Rect taskBounds = taskConfiguration.windowConfiguration.getBounds();
return new Rect(taskBounds.left, taskBounds.top, right, taskBounds.bottom);
}
@@ -949,8 +959,10 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
@NonNull
private Rect getRightContainerBounds(@NonNull Configuration taskConfiguration,
@NonNull SplitAttributes splitAttributes, @Nullable FoldingFeature foldingFeature) {
+ final int dividerOffset = getBoundsOffsetForDivider(
+ splitAttributes, CONTAINER_POSITION_RIGHT);
final int left = computeBoundaryBetweenContainers(taskConfiguration, splitAttributes,
- CONTAINER_POSITION_RIGHT, foldingFeature);
+ CONTAINER_POSITION_RIGHT, foldingFeature) + dividerOffset;
final Rect parentBounds = taskConfiguration.windowConfiguration.getBounds();
return new Rect(left, parentBounds.top, parentBounds.right, parentBounds.bottom);
}
@@ -958,8 +970,10 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
@NonNull
private Rect getTopContainerBounds(@NonNull Configuration taskConfiguration,
@NonNull SplitAttributes splitAttributes, @Nullable FoldingFeature foldingFeature) {
+ final int dividerOffset = getBoundsOffsetForDivider(
+ splitAttributes, CONTAINER_POSITION_TOP);
final int bottom = computeBoundaryBetweenContainers(taskConfiguration, splitAttributes,
- CONTAINER_POSITION_TOP, foldingFeature);
+ CONTAINER_POSITION_TOP, foldingFeature) + dividerOffset;
final Rect parentBounds = taskConfiguration.windowConfiguration.getBounds();
return new Rect(parentBounds.left, parentBounds.top, parentBounds.right, bottom);
}
@@ -967,8 +981,10 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
@NonNull
private Rect getBottomContainerBounds(@NonNull Configuration taskConfiguration,
@NonNull SplitAttributes splitAttributes, @Nullable FoldingFeature foldingFeature) {
+ final int dividerOffset = getBoundsOffsetForDivider(
+ splitAttributes, CONTAINER_POSITION_BOTTOM);
final int top = computeBoundaryBetweenContainers(taskConfiguration, splitAttributes,
- CONTAINER_POSITION_BOTTOM, foldingFeature);
+ CONTAINER_POSITION_BOTTOM, foldingFeature) + dividerOffset;
final Rect parentBounds = taskConfiguration.windowConfiguration.getBounds();
return new Rect(parentBounds.left, top, parentBounds.right, parentBounds.bottom);
}
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/DividerPresenterTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/DividerPresenterTest.java
new file mode 100644
index 000000000000..2a277f4c9619
--- /dev/null
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/DividerPresenterTest.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2024 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 androidx.window.extensions.embedding;
+
+import static androidx.window.extensions.embedding.DividerPresenter.getBoundsOffsetForDivider;
+import static androidx.window.extensions.embedding.SplitPresenter.CONTAINER_POSITION_BOTTOM;
+import static androidx.window.extensions.embedding.SplitPresenter.CONTAINER_POSITION_LEFT;
+import static androidx.window.extensions.embedding.SplitPresenter.CONTAINER_POSITION_RIGHT;
+import static androidx.window.extensions.embedding.SplitPresenter.CONTAINER_POSITION_TOP;
+
+import static org.junit.Assert.assertEquals;
+
+import android.platform.test.annotations.Presubmit;
+
+import androidx.annotation.NonNull;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test class for {@link DividerPresenter}.
+ *
+ * Build/Install/Run:
+ * atest WMJetpackUnitTests:DividerPresenterTest
+ */
+@Presubmit
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class DividerPresenterTest {
+ @Test
+ public void testSanitizeDividerAttributes_setDefaultValues() {
+ DividerAttributes attributes =
+ new DividerAttributes.Builder(DividerAttributes.DIVIDER_TYPE_DRAGGABLE).build();
+ DividerAttributes sanitized = DividerPresenter.sanitizeDividerAttributes(attributes);
+
+ assertEquals(DividerAttributes.DIVIDER_TYPE_DRAGGABLE, sanitized.getDividerType());
+ assertEquals(DividerPresenter.DEFAULT_DIVIDER_WIDTH_DP, sanitized.getWidthDp());
+ assertEquals(DividerPresenter.DEFAULT_MIN_RATIO, sanitized.getPrimaryMinRatio(),
+ 0.0f /* delta */);
+ assertEquals(DividerPresenter.DEFAULT_MAX_RATIO, sanitized.getPrimaryMaxRatio(),
+ 0.0f /* delta */);
+ }
+
+ @Test
+ public void testSanitizeDividerAttributes_notChangingValidValues() {
+ DividerAttributes attributes =
+ new DividerAttributes.Builder(DividerAttributes.DIVIDER_TYPE_DRAGGABLE)
+ .setWidthDp(10)
+ .setPrimaryMinRatio(0.3f)
+ .setPrimaryMaxRatio(0.7f)
+ .build();
+ DividerAttributes sanitized = DividerPresenter.sanitizeDividerAttributes(attributes);
+
+ assertEquals(attributes, sanitized);
+ }
+
+ @Test
+ public void testGetBoundsOffsetForDivider_ratioSplitType() {
+ final int dividerWidthPx = 100;
+ final float splitRatio = 0.25f;
+ final SplitAttributes.SplitType splitType =
+ new SplitAttributes.SplitType.RatioSplitType(splitRatio);
+ final int expectedTopLeftOffset = 25;
+ final int expectedBottomRightOffset = 75;
+
+ assertDividerOffsetEquals(
+ dividerWidthPx, splitType, expectedTopLeftOffset, expectedBottomRightOffset);
+ }
+
+ @Test
+ public void testGetBoundsOffsetForDivider_ratioSplitType_withRounding() {
+ final int dividerWidthPx = 101;
+ final float splitRatio = 0.25f;
+ final SplitAttributes.SplitType splitType =
+ new SplitAttributes.SplitType.RatioSplitType(splitRatio);
+ final int expectedTopLeftOffset = 25;
+ final int expectedBottomRightOffset = 76;
+
+ assertDividerOffsetEquals(
+ dividerWidthPx, splitType, expectedTopLeftOffset, expectedBottomRightOffset);
+ }
+
+ @Test
+ public void testGetBoundsOffsetForDivider_hingeSplitType() {
+ final int dividerWidthPx = 100;
+ final SplitAttributes.SplitType splitType =
+ new SplitAttributes.SplitType.HingeSplitType(
+ new SplitAttributes.SplitType.RatioSplitType(0.5f));
+
+ final int expectedTopLeftOffset = 50;
+ final int expectedBottomRightOffset = 50;
+
+ assertDividerOffsetEquals(
+ dividerWidthPx, splitType, expectedTopLeftOffset, expectedBottomRightOffset);
+ }
+
+ @Test
+ public void testGetBoundsOffsetForDivider_expandContainersSplitType() {
+ final int dividerWidthPx = 100;
+ final SplitAttributes.SplitType splitType =
+ new SplitAttributes.SplitType.ExpandContainersSplitType();
+ // Always return 0 for ExpandContainersSplitType as divider is not needed.
+ final int expectedTopLeftOffset = 0;
+ final int expectedBottomRightOffset = 0;
+
+ assertDividerOffsetEquals(
+ dividerWidthPx, splitType, expectedTopLeftOffset, expectedBottomRightOffset);
+ }
+
+ private void assertDividerOffsetEquals(
+ int dividerWidthPx,
+ @NonNull SplitAttributes.SplitType splitType,
+ int expectedTopLeftOffset,
+ int expectedBottomRightOffset) {
+ int offset = getBoundsOffsetForDivider(
+ dividerWidthPx,
+ splitType,
+ CONTAINER_POSITION_LEFT
+ );
+ assertEquals(-expectedTopLeftOffset, offset);
+
+ offset = getBoundsOffsetForDivider(
+ dividerWidthPx,
+ splitType,
+ CONTAINER_POSITION_RIGHT
+ );
+ assertEquals(expectedBottomRightOffset, offset);
+
+ offset = getBoundsOffsetForDivider(
+ dividerWidthPx,
+ splitType,
+ CONTAINER_POSITION_TOP
+ );
+ assertEquals(-expectedTopLeftOffset, offset);
+
+ offset = getBoundsOffsetForDivider(
+ dividerWidthPx,
+ splitType,
+ CONTAINER_POSITION_BOTTOM
+ );
+ assertEquals(expectedBottomRightOffset, offset);
+ }
+}
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java
index bdeeb7304b12..cdb37acfc0c2 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java
@@ -294,7 +294,10 @@ public class SplitControllerTest {
doReturn(tf).when(splitContainer).getPrimaryContainer();
doReturn(tf).when(splitContainer).getSecondaryContainer();
doReturn(createTestTaskContainer()).when(splitContainer).getTaskContainer();
- doReturn(createSplitRule(mActivity, mActivity)).when(splitContainer).getSplitRule();
+ final SplitRule splitRule = createSplitRule(mActivity, mActivity);
+ doReturn(splitRule).when(splitContainer).getSplitRule();
+ doReturn(splitRule.getDefaultSplitAttributes())
+ .when(splitContainer).getDefaultSplitAttributes();
taskContainer = mSplitController.getTaskContainer(TASK_ID);
taskContainer.addSplitContainer(splitContainer);
// Add a mock SplitContainer on top of splitContainer
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleFlyoutView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleFlyoutView.java
index 6a5f785504c0..42de401d9db9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleFlyoutView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleFlyoutView.java
@@ -24,6 +24,7 @@ import static com.android.wm.shell.animation.Interpolators.ALPHA_OUT;
import android.animation.ArgbEvaluator;
import android.content.Context;
+import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
@@ -74,7 +75,7 @@ public class BubbleFlyoutView extends FrameLayout {
private final int mFlyoutElevation;
private final int mBubbleElevation;
- private final int mFloatingBackgroundColor;
+ private int mFloatingBackgroundColor;
private final float mCornerRadius;
private final ViewGroup mFlyoutTextContainer;
@@ -107,6 +108,9 @@ public class BubbleFlyoutView extends FrameLayout {
/** Color of the 'new' dot that the flyout will transform into. */
private int mDotColor;
+ /** Keeps last used night mode flags **/
+ private int mNightModeFlags;
+
/** The outline of the triangle, used for elevation shadows. */
private final Outline mTriangleOutline = new Outline();
@@ -176,11 +180,8 @@ public class BubbleFlyoutView extends FrameLayout {
mFlyoutElevation = res.getDimensionPixelSize(R.dimen.bubble_flyout_elevation);
final TypedArray ta = mContext.obtainStyledAttributes(
- new int[] {
- com.android.internal.R.attr.materialColorSurfaceContainer,
- android.R.attr.dialogCornerRadius});
- mFloatingBackgroundColor = ta.getColor(0, Color.WHITE);
- mCornerRadius = ta.getDimensionPixelSize(1, 0);
+ new int[] {android.R.attr.dialogCornerRadius});
+ mCornerRadius = ta.getDimensionPixelSize(0, 0);
ta.recycle();
// Add padding for the pointer on either side, onDraw will draw it in this space.
@@ -198,19 +199,17 @@ public class BubbleFlyoutView extends FrameLayout {
// Use locale direction so the text is aligned correctly.
setLayoutDirection(LAYOUT_DIRECTION_LOCALE);
- mBgPaint.setColor(mFloatingBackgroundColor);
-
mLeftTriangleShape =
new ShapeDrawable(TriangleShape.createHorizontal(
mPointerSize, mPointerSize, true /* isPointingLeft */));
mLeftTriangleShape.setBounds(0, 0, mPointerSize, mPointerSize);
- mLeftTriangleShape.getPaint().setColor(mFloatingBackgroundColor);
mRightTriangleShape =
new ShapeDrawable(TriangleShape.createHorizontal(
mPointerSize, mPointerSize, false /* isPointingLeft */));
mRightTriangleShape.setBounds(0, 0, mPointerSize, mPointerSize);
- mRightTriangleShape.getPaint().setColor(mFloatingBackgroundColor);
+
+ applyConfigurationColors(getResources().getConfiguration());
}
@Override
@@ -244,6 +243,13 @@ public class BubbleFlyoutView extends FrameLayout {
fade(false /* in */, stackPos, hideDot, afterFadeOut);
}
+ @Override
+ protected void onConfigurationChanged(Configuration newConfig) {
+ if (applyColorsAccordingToConfiguration(newConfig)) {
+ invalidate();
+ }
+ }
+
/*
* Fade-out above or fade-in from below.
*/
@@ -424,6 +430,42 @@ public class BubbleFlyoutView extends FrameLayout {
}
/**
+ * Resolving and applying colors according to the ui mode, remembering most recent mode.
+ *
+ * @return {@code true} if night mode setting has changed since the last invocation,
+ * {@code false} otherwise
+ */
+ boolean applyColorsAccordingToConfiguration(Configuration configuration) {
+ int nightModeFlags = configuration.uiMode & Configuration.UI_MODE_NIGHT_MASK;
+ boolean flagsChanged = nightModeFlags != mNightModeFlags;
+ if (flagsChanged) {
+ mNightModeFlags = nightModeFlags;
+ applyConfigurationColors(configuration);
+ }
+ return flagsChanged;
+ }
+
+ private void applyConfigurationColors(Configuration configuration) {
+ int nightModeFlags = configuration.uiMode & Configuration.UI_MODE_NIGHT_MASK;
+ boolean isNightModeOn = nightModeFlags == Configuration.UI_MODE_NIGHT_YES;
+ try (TypedArray ta = mContext.obtainStyledAttributes(
+ new int[]{
+ com.android.internal.R.attr.materialColorSurfaceContainer,
+ com.android.internal.R.attr.materialColorOnSurface,
+ com.android.internal.R.attr.materialColorOnSurfaceVariant})) {
+ mFloatingBackgroundColor = ta.getColor(0,
+ isNightModeOn ? Color.BLACK : Color.WHITE);
+ mSenderText.setTextColor(ta.getColor(1,
+ isNightModeOn ? Color.WHITE : Color.BLACK));
+ mMessageText.setTextColor(ta.getColor(2,
+ isNightModeOn ? Color.WHITE : Color.BLACK));
+ mBgPaint.setColor(mFloatingBackgroundColor);
+ mLeftTriangleShape.getPaint().setColor(mFloatingBackgroundColor);
+ mRightTriangleShape.getPaint().setColor(mFloatingBackgroundColor);
+ }
+ }
+
+ /**
* Renders the background, which is either the rounded 'chat bubble' flyout, or some state
* between that and the 'new' dot over the bubbles.
*/
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
index 6524c96fb21a..690868208b91 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
@@ -1025,6 +1025,7 @@ public class BubbleStackView extends FrameLayout
WindowManager.class)));
onDisplaySizeChanged();
mExpandedAnimationController.updateResources();
+ mExpandedAnimationController.onOrientationChanged();
mStackAnimationController.updateResources();
mBubbleOverflow.updateResources();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedAnimationController.java
index 7798aa753aa2..512c9d133d08 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedAnimationController.java
@@ -614,6 +614,14 @@ public class ExpandedAnimationController
}
}
+ /**
+ * Call to update the bubble positions after an orientation change.
+ */
+ public void onOrientationChanged() {
+ if (mLayout == null) return;
+ updateBubblePositions();
+ }
+
private void updateBubblePositions() {
if (mAnimatingExpand || mAnimatingCollapse) {
return;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/PhysicsAnimationLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/PhysicsAnimationLayout.java
index ed00da848a14..bfddff0f72e3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/PhysicsAnimationLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/PhysicsAnimationLayout.java
@@ -378,6 +378,8 @@ public class PhysicsAnimationLayout extends FrameLayout {
}
final int oldIndex = indexOfChild(view);
+ if (oldIndex == index) return;
+
super.removeView(view);
if (view.getParent() != null) {
// View still has a parent. This could have been added as a transient view.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/GlobalDragListener.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/GlobalDragListener.kt
index 8826141fb406..31214eba8dd0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/GlobalDragListener.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/GlobalDragListener.kt
@@ -17,6 +17,8 @@ package com.android.wm.shell.draganddrop
import android.app.ActivityManager
import android.os.RemoteException
+import android.os.Trace
+import android.os.Trace.TRACE_TAG_WINDOW_MANAGER
import android.util.Log
import android.view.DragEvent
import android.view.IWindowManager
@@ -27,6 +29,7 @@ import com.android.internal.protolog.common.ProtoLog
import com.android.wm.shell.common.ShellExecutor
import com.android.wm.shell.protolog.ShellProtoLogGroup
import java.util.function.Consumer
+import kotlin.random.Random
/**
* Manages the listener and callbacks for unhandled global drags.
@@ -101,10 +104,15 @@ class GlobalDragListener(
@VisibleForTesting
fun onUnhandledDrop(dragEvent: DragEvent, wmCallback: IUnhandledDragCallback) {
+ val traceCookie = Random.nextInt()
+ Trace.asyncTraceBegin(TRACE_TAG_WINDOW_MANAGER, "GlobalDragListener.onUnhandledDrop",
+ traceCookie);
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP,
"onUnhandledDrop: %s", dragEvent)
if (callback == null) {
wmCallback.notifyUnhandledDropComplete(false)
+ Trace.asyncTraceEnd(TRACE_TAG_WINDOW_MANAGER, "GlobalDragListener.onUnhandledDrop",
+ traceCookie);
return
}
@@ -112,6 +120,8 @@ class GlobalDragListener(
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP,
"Notifying onUnhandledDrop complete: %b", it)
wmCallback.notifyUnhandledDropComplete(it)
+ Trace.asyncTraceEnd(TRACE_TAG_WINDOW_MANAGER, "GlobalDragListener.onUnhandledDrop",
+ traceCookie);
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java
index b99e94399046..2b433e9c4227 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreen.java
@@ -64,9 +64,7 @@ public interface SplitScreen {
default void onSplitVisibilityChanged(boolean visible) {}
}
- /**
- * Callback interface for listening to requests to enter split select. Used for desktop -> split
- */
+ /** Callback interface for listening to requests to enter split select */
interface SplitSelectListener {
default boolean onRequestEnterSplitSelect(ActivityManager.RunningTaskInfo taskInfo,
int splitPosition, Rect taskBounds) {
@@ -74,15 +72,6 @@ public interface SplitScreen {
}
}
- interface SplitInvocationListener {
- /**
- * Called whenever shell starts or stops the split screen animation
- * @param animationRunning if {@code true} the animation has begun, if {@code false} the
- * animation has finished
- */
- default void onSplitAnimationInvoked(boolean animationRunning) { }
- }
-
/** Registers listener that gets split screen callback. */
void registerSplitScreenListener(@NonNull SplitScreenListener listener,
@NonNull Executor executor);
@@ -90,15 +79,6 @@ public interface SplitScreen {
/** Unregisters listener that gets split screen callback. */
void unregisterSplitScreenListener(@NonNull SplitScreenListener listener);
- /**
- * Registers a {@link SplitInvocationListener} to notify when the animation to enter split
- * screen has started and stopped
- *
- * @param executor callbacks to the listener will be executed on this executor
- */
- void registerSplitAnimationListener(@NonNull SplitInvocationListener listener,
- @NonNull Executor executor);
-
/** Called when device waking up finished. */
void onFinishedWakingUp();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
index 5fbb15216eea..3e34c303e161 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
@@ -1144,12 +1144,6 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
}
@Override
- public void registerSplitAnimationListener(@NonNull SplitInvocationListener listener,
- @NonNull Executor executor) {
- mStageCoordinator.registerSplitAnimationListener(listener, executor);
- }
-
- @Override
public void onFinishedWakingUp() {
mMainExecutor.execute(SplitScreenController.this::onFinishedWakingUp);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java
index e69ff70e5273..1a53a1d10dd2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java
@@ -55,7 +55,6 @@ import com.android.wm.shell.transition.OneShotRemoteHandler;
import com.android.wm.shell.transition.Transitions;
import java.util.ArrayList;
-import java.util.concurrent.Executor;
/** Manages transition animations for split-screen. */
class SplitScreenTransitions {
@@ -80,8 +79,6 @@ class SplitScreenTransitions {
private Transitions.TransitionFinishCallback mFinishCallback = null;
private SurfaceControl.Transaction mFinishTransaction;
- private SplitScreen.SplitInvocationListener mSplitInvocationListener;
- private Executor mSplitInvocationListenerExecutor;
SplitScreenTransitions(@NonNull TransactionPool pool, @NonNull Transitions transitions,
@NonNull Runnable onFinishCallback, StageCoordinator stageCoordinator) {
@@ -356,10 +353,6 @@ class SplitScreenTransitions {
+ " skip to start enter split transition since it already exist. ");
return null;
}
- if (mSplitInvocationListenerExecutor != null && mSplitInvocationListener != null) {
- mSplitInvocationListenerExecutor.execute(() -> mSplitInvocationListener
- .onSplitAnimationInvoked(true /*animationRunning*/));
- }
final IBinder transition = mTransitions.startTransition(transitType, wct, handler);
setEnterTransition(transition, remoteTransition, extraTransitType, resizeAnim);
return transition;
@@ -536,12 +529,6 @@ class SplitScreenTransitions {
mTransitions.getAnimExecutor().execute(va::start);
}
- public void registerSplitAnimListener(@NonNull SplitScreen.SplitInvocationListener listener,
- @NonNull Executor executor) {
- mSplitInvocationListener = listener;
- mSplitInvocationListenerExecutor = executor;
- }
-
/** Calls when the transition got consumed. */
interface TransitionConsumedCallback {
void onConsumed(boolean aborted);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
index 661faf5b4f28..41890df9a4ee 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
@@ -156,7 +156,6 @@ import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
-import java.util.concurrent.Executor;
/**
* Coordinates the staging (visibility, sizing, ...) of the split-screen {@link MainStage} and
@@ -237,9 +236,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
private DefaultMixedHandler mMixedHandler;
private final Toast mSplitUnsupportedToast;
private SplitRequest mSplitRequest;
- /** Used to notify others of when shell is animating into split screen */
- private SplitScreen.SplitInvocationListener mSplitInvocationListener;
- private Executor mSplitInvocationListenerExecutor;
/**
* Since StageCoordinator only coordinates MainStage and SideStage, it shouldn't support
@@ -250,14 +246,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
return false;
}
- /** NOTE: Will overwrite any previously set {@link #mSplitInvocationListener} */
- public void registerSplitAnimationListener(
- @NonNull SplitScreen.SplitInvocationListener listener, @NonNull Executor executor) {
- mSplitInvocationListener = listener;
- mSplitInvocationListenerExecutor = executor;
- mSplitTransitions.registerSplitAnimListener(listener, executor);
- }
-
class SplitRequest {
@SplitPosition
int mActivatePosition;
@@ -541,7 +529,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
null /* childrenToTop */, EXIT_REASON_UNKNOWN));
Log.w(TAG, splitFailureMessage("startShortcut",
"side stage was not populated"));
- handleUnsupportedSplitStart();
+ mSplitUnsupportedToast.show();
}
if (finishedCallback != null) {
@@ -672,7 +660,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
null /* childrenToTop */, EXIT_REASON_UNKNOWN));
Log.w(TAG, splitFailureMessage("startIntentLegacy",
"side stage was not populated"));
- handleUnsupportedSplitStart();
+ mSplitUnsupportedToast.show();
}
if (apps != null) {
@@ -1225,7 +1213,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
? mSideStage : mMainStage, EXIT_REASON_UNKNOWN));
Log.w(TAG, splitFailureMessage("onRemoteAnimationFinishedOrCancelled",
"main or side stage was not populated."));
- handleUnsupportedSplitStart();
+ mSplitUnsupportedToast.show();
} else {
mSyncQueue.queue(evictWct);
mSyncQueue.runInSync(t -> {
@@ -1246,7 +1234,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
? mSideStage : mMainStage, EXIT_REASON_UNKNOWN));
Log.w(TAG, splitFailureMessage("onRemoteAnimationFinished",
"main or side stage was not populated"));
- handleUnsupportedSplitStart();
+ mSplitUnsupportedToast.show();
return;
}
@@ -2818,7 +2806,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
if (hasEnteringPip) {
mMixedHandler.animatePendingEnterPipFromSplit(transition, info,
startTransaction, finishTransaction, finishCallback);
- notifySplitAnimationFinished();
return true;
}
@@ -2853,7 +2840,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
// the transition, or synchronize task-org callbacks.
}
// Use normal animations.
- notifySplitAnimationFinished();
return false;
} else if (mMixedHandler != null && TransitionUtil.hasDisplayChange(info)) {
// A display-change has been un-expectedly inserted into the transition. Redirect
@@ -2867,7 +2853,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
mSplitLayout.update(startTransaction, true /* resetImePosition */);
startTransaction.apply();
}
- notifySplitAnimationFinished();
return true;
}
}
@@ -3041,7 +3026,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
pendingEnter.mRemoteHandler.onTransitionConsumed(transition,
false /*aborted*/, finishT);
}
- handleUnsupportedSplitStart();
+ mSplitUnsupportedToast.show();
return true;
}
}
@@ -3070,7 +3055,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
final TransitionInfo.Change finalMainChild = mainChild;
final TransitionInfo.Change finalSideChild = sideChild;
enterTransition.setFinishedCallback((callbackWct, callbackT) -> {
- notifySplitAnimationFinished();
if (finalMainChild != null) {
if (!mainNotContainOpenTask) {
mMainStage.evictOtherChildren(callbackWct, finalMainChild.getTaskInfo().taskId);
@@ -3487,19 +3471,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
mSplitLayout.isLeftRightSplit());
}
- private void handleUnsupportedSplitStart() {
- mSplitUnsupportedToast.show();
- notifySplitAnimationFinished();
- }
-
- private void notifySplitAnimationFinished() {
- if (mSplitInvocationListener == null || mSplitInvocationListenerExecutor == null) {
- return;
- }
- mSplitInvocationListenerExecutor.execute(() ->
- mSplitInvocationListener.onSplitAnimationInvoked(false /*animationRunning*/));
- }
-
/**
* Logs the exit of splitscreen to a specific stage. This must be called before the exit is
* executed.
@@ -3562,7 +3533,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
if (!ENABLE_SHELL_TRANSITIONS) {
StageCoordinator.this.exitSplitScreen(isMainStage ? mMainStage : mSideStage,
EXIT_REASON_APP_DOES_NOT_SUPPORT_MULTIWINDOW);
- handleUnsupportedSplitStart();
+ mSplitUnsupportedToast.show();
return;
}
@@ -3582,7 +3553,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
"app package " + taskInfo.baseActivity.getPackageName()
+ " does not support splitscreen, or is a controlled activity type"));
if (splitScreenVisible) {
- handleUnsupportedSplitStart();
+ mSplitUnsupportedToast.show();
}
}
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
index 34b2eebb15a1..befc702b01aa 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
@@ -39,13 +39,10 @@ import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
import android.annotation.NonNull;
import android.app.ActivityManager;
@@ -66,7 +63,6 @@ import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.ShellTestCase;
import com.android.wm.shell.TestRunningTaskInfoBuilder;
-import com.android.wm.shell.TestShellExecutor;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayImeController;
import com.android.wm.shell.common.DisplayInsetsController;
@@ -109,8 +105,6 @@ public class SplitTransitionTests extends ShellTestCase {
@Mock private ShellExecutor mMainExecutor;
@Mock private LaunchAdjacentController mLaunchAdjacentController;
@Mock private DefaultMixedHandler mMixedHandler;
- @Mock private SplitScreen.SplitInvocationListener mInvocationListener;
- private final TestShellExecutor mTestShellExecutor = new TestShellExecutor();
private SplitLayout mSplitLayout;
private MainStage mMainStage;
private SideStage mSideStage;
@@ -153,7 +147,6 @@ public class SplitTransitionTests extends ShellTestCase {
.setParentTaskId(mSideStage.mRootTaskInfo.taskId).build();
doReturn(mock(SplitDecorManager.class)).when(mMainStage).getSplitDecorManager();
doReturn(mock(SplitDecorManager.class)).when(mSideStage).getSplitDecorManager();
- mStageCoordinator.registerSplitAnimationListener(mInvocationListener, mTestShellExecutor);
}
@Test
@@ -459,15 +452,6 @@ public class SplitTransitionTests extends ShellTestCase {
mMainStage.activate(new WindowContainerTransaction(), true /* includingTopTask */);
}
- @Test
- @UiThreadTest
- public void testSplitInvocationCallback() {
- enterSplit();
- mTestShellExecutor.flushAll();
- verify(mInvocationListener, times(1))
- .onSplitAnimationInvoked(eq(true));
- }
-
private boolean containsSplitEnter(@NonNull WindowContainerTransaction wct) {
for (int i = 0; i < wct.getHierarchyOps().size(); ++i) {
WindowContainerTransaction.HierarchyOp op = wct.getHierarchyOps().get(i);
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index 33830f154835..014b8413bb10 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -547,6 +547,7 @@ cc_defaults {
"hwui/MinikinUtils.cpp",
"hwui/PaintImpl.cpp",
"hwui/Typeface.cpp",
+ "thread/CommonPool.cpp",
"utils/Blur.cpp",
"utils/Color.cpp",
"utils/LinearAllocator.cpp",
@@ -623,7 +624,6 @@ cc_defaults {
"renderthread/RenderThread.cpp",
"renderthread/HintSessionWrapper.cpp",
"service/GraphicsStatsService.cpp",
- "thread/CommonPool.cpp",
"utils/GLUtils.cpp",
"utils/NdkUtils.cpp",
"AutoBackendTextureRelease.cpp",
diff --git a/libs/hwui/WebViewFunctorManager.cpp b/libs/hwui/WebViewFunctorManager.cpp
index 6fc251dc815c..5b4ab5f2d3b1 100644
--- a/libs/hwui/WebViewFunctorManager.cpp
+++ b/libs/hwui/WebViewFunctorManager.cpp
@@ -86,6 +86,10 @@ void WebViewFunctor_release(int functor) {
WebViewFunctorManager::instance().releaseFunctor(functor);
}
+void WebViewFunctor_reportRenderingThreads(int functor, const int32_t* thread_ids, size_t size) {
+ WebViewFunctorManager::instance().reportRenderingThreads(functor, thread_ids, size);
+}
+
static std::atomic_int sNextId{1};
WebViewFunctor::WebViewFunctor(void* data, const WebViewFunctorCallbacks& callbacks,
@@ -260,6 +264,10 @@ void WebViewFunctor::reparentSurfaceControl(ASurfaceControl* parent) {
funcs.transactionDeleteFunc(transaction);
}
+void WebViewFunctor::reportRenderingThreads(const int32_t* thread_ids, size_t size) {
+ // TODO(b/329219352): Pass the threads to HWUI and update the ADPF session.
+}
+
WebViewFunctorManager& WebViewFunctorManager::instance() {
static WebViewFunctorManager sInstance;
return sInstance;
@@ -346,6 +354,17 @@ void WebViewFunctorManager::destroyFunctor(int functor) {
}
}
+void WebViewFunctorManager::reportRenderingThreads(int functor, const int32_t* thread_ids,
+ size_t size) {
+ std::lock_guard _lock{mLock};
+ for (auto& iter : mFunctors) {
+ if (iter->id() == functor) {
+ iter->reportRenderingThreads(thread_ids, size);
+ break;
+ }
+ }
+}
+
sp<WebViewFunctor::Handle> WebViewFunctorManager::handleFor(int functor) {
std::lock_guard _lock{mLock};
for (auto& iter : mActiveFunctors) {
diff --git a/libs/hwui/WebViewFunctorManager.h b/libs/hwui/WebViewFunctorManager.h
index 0a02f2d4b720..1bf2c1f9c4ef 100644
--- a/libs/hwui/WebViewFunctorManager.h
+++ b/libs/hwui/WebViewFunctorManager.h
@@ -81,6 +81,8 @@ public:
ASurfaceControl* getSurfaceControl();
void mergeTransaction(ASurfaceTransaction* transaction);
+ void reportRenderingThreads(const int32_t* thread_ids, size_t size);
+
sp<Handle> createHandle() {
LOG_ALWAYS_FATAL_IF(mCreatedHandle);
mCreatedHandle = true;
@@ -110,6 +112,7 @@ public:
void releaseFunctor(int functor);
void onContextDestroyed();
void destroyFunctor(int functor);
+ void reportRenderingThreads(int functor, const int32_t* thread_ids, size_t size);
sp<WebViewFunctor::Handle> handleFor(int functor);
diff --git a/libs/hwui/platform/android/thread/CommonPoolBase.h b/libs/hwui/platform/android/thread/CommonPoolBase.h
new file mode 100644
index 000000000000..8f836b612440
--- /dev/null
+++ b/libs/hwui/platform/android/thread/CommonPoolBase.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2024 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.
+ */
+
+#ifndef FRAMEWORKS_BASE_COMMONPOOLBASE_H
+#define FRAMEWORKS_BASE_COMMONPOOLBASE_H
+
+#include <sys/resource.h>
+
+#include "renderthread/RenderThread.h"
+
+namespace android {
+namespace uirenderer {
+
+class CommonPoolBase {
+ PREVENT_COPY_AND_ASSIGN(CommonPoolBase);
+
+protected:
+ CommonPoolBase() {}
+
+ void setupThread(int i, std::mutex& mLock, std::vector<int>& tids,
+ std::vector<std::condition_variable>& tidConditionVars) {
+ std::array<char, 20> name{"hwuiTask"};
+ snprintf(name.data(), name.size(), "hwuiTask%d", i);
+ auto self = pthread_self();
+ pthread_setname_np(self, name.data());
+ {
+ std::unique_lock lock(mLock);
+ tids[i] = pthread_gettid_np(self);
+ tidConditionVars[i].notify_one();
+ }
+ setpriority(PRIO_PROCESS, 0, PRIORITY_FOREGROUND);
+ auto startHook = renderthread::RenderThread::getOnStartHook();
+ if (startHook) {
+ startHook(name.data());
+ }
+ }
+
+ bool supportsTid() { return true; }
+};
+
+} // namespace uirenderer
+} // namespace android
+
+#endif // FRAMEWORKS_BASE_COMMONPOOLBASE_H
diff --git a/libs/hwui/platform/host/thread/CommonPoolBase.h b/libs/hwui/platform/host/thread/CommonPoolBase.h
new file mode 100644
index 000000000000..cd091013ce0c
--- /dev/null
+++ b/libs/hwui/platform/host/thread/CommonPoolBase.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2024 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.
+ */
+
+#ifndef FRAMEWORKS_BASE_COMMONPOOLBASE_H
+#define FRAMEWORKS_BASE_COMMONPOOLBASE_H
+
+#include <condition_variable>
+#include <mutex>
+#include <vector>
+
+#include "renderthread/RenderThread.h"
+
+namespace android {
+namespace uirenderer {
+
+class CommonPoolBase {
+ PREVENT_COPY_AND_ASSIGN(CommonPoolBase);
+
+protected:
+ CommonPoolBase() {}
+
+ void setupThread(int i, std::mutex& mLock, std::vector<int>& tids,
+ std::vector<std::condition_variable>& tidConditionVars) {
+ std::array<char, 20> name{"hwuiTask"};
+ snprintf(name.data(), name.size(), "hwuiTask%d", i);
+ {
+ std::unique_lock lock(mLock);
+ tids[i] = -1;
+ tidConditionVars[i].notify_one();
+ }
+ auto startHook = renderthread::RenderThread::getOnStartHook();
+ if (startHook) {
+ startHook(name.data());
+ }
+ }
+
+ bool supportsTid() { return false; }
+};
+
+} // namespace uirenderer
+} // namespace android
+
+#endif // FRAMEWORKS_BASE_COMMONPOOLBASE_H
diff --git a/libs/hwui/private/hwui/WebViewFunctor.h b/libs/hwui/private/hwui/WebViewFunctor.h
index 493c943079ab..dbd8a16dfcfc 100644
--- a/libs/hwui/private/hwui/WebViewFunctor.h
+++ b/libs/hwui/private/hwui/WebViewFunctor.h
@@ -106,6 +106,11 @@ ANDROID_API int WebViewFunctor_create(void* data, const WebViewFunctorCallbacks&
// and it should be considered alive & active until that point.
ANDROID_API void WebViewFunctor_release(int functor);
+// Reports the list of threads critical for frame production for the given
+// functor. Must be called on render thread.
+ANDROID_API void WebViewFunctor_reportRenderingThreads(int functor, const int32_t* thread_ids,
+ size_t size);
+
} // namespace android::uirenderer
#endif // FRAMEWORKS_BASE_WEBVIEWFUNCTOR_H
diff --git a/libs/hwui/thread/CommonPool.cpp b/libs/hwui/thread/CommonPool.cpp
index dc92f9f0d39a..6c0c30f95955 100644
--- a/libs/hwui/thread/CommonPool.cpp
+++ b/libs/hwui/thread/CommonPool.cpp
@@ -16,16 +16,14 @@
#include "CommonPool.h"
-#include <sys/resource.h>
#include <utils/Trace.h>
-#include "renderthread/RenderThread.h"
#include <array>
namespace android {
namespace uirenderer {
-CommonPool::CommonPool() {
+CommonPool::CommonPool() : CommonPoolBase() {
ATRACE_CALL();
CommonPool* pool = this;
@@ -36,22 +34,7 @@ CommonPool::CommonPool() {
// Create 2 workers
for (int i = 0; i < THREAD_COUNT; i++) {
std::thread worker([pool, i, &mLock, &tids, &tidConditionVars] {
- {
- std::array<char, 20> name{"hwuiTask"};
- snprintf(name.data(), name.size(), "hwuiTask%d", i);
- auto self = pthread_self();
- pthread_setname_np(self, name.data());
- {
- std::unique_lock lock(mLock);
- tids[i] = pthread_gettid_np(self);
- tidConditionVars[i].notify_one();
- }
- setpriority(PRIO_PROCESS, 0, PRIORITY_FOREGROUND);
- auto startHook = renderthread::RenderThread::getOnStartHook();
- if (startHook) {
- startHook(name.data());
- }
- }
+ pool->setupThread(i, mLock, tids, tidConditionVars);
pool->workerLoop();
});
worker.detach();
@@ -64,7 +47,9 @@ CommonPool::CommonPool() {
}
}
}
- mWorkerThreadIds = std::move(tids);
+ if (pool->supportsTid()) {
+ mWorkerThreadIds = std::move(tids);
+ }
}
CommonPool& CommonPool::instance() {
@@ -95,7 +80,7 @@ void CommonPool::enqueue(Task&& task) {
void CommonPool::workerLoop() {
std::unique_lock lock(mLock);
- while (true) {
+ while (!mIsStopping) {
if (!mWorkQueue.hasWork()) {
mWaitingThreads++;
mCondition.wait(lock);
diff --git a/libs/hwui/thread/CommonPool.h b/libs/hwui/thread/CommonPool.h
index 74f852bd1413..0c025b4f0ee7 100644
--- a/libs/hwui/thread/CommonPool.h
+++ b/libs/hwui/thread/CommonPool.h
@@ -17,8 +17,6 @@
#ifndef FRAMEWORKS_BASE_COMMONPOOL_H
#define FRAMEWORKS_BASE_COMMONPOOL_H
-#include "utils/Macros.h"
-
#include <log/log.h>
#include <condition_variable>
@@ -27,6 +25,9 @@
#include <mutex>
#include <vector>
+#include "thread/CommonPoolBase.h"
+#include "utils/Macros.h"
+
namespace android {
namespace uirenderer {
@@ -73,7 +74,7 @@ private:
int mTail = 0;
};
-class CommonPool {
+class CommonPool : private CommonPoolBase {
PREVENT_COPY_AND_ASSIGN(CommonPool);
public:
@@ -107,7 +108,10 @@ private:
static CommonPool& instance();
CommonPool();
- ~CommonPool() {}
+ ~CommonPool() {
+ mIsStopping = true;
+ mCondition.notify_all();
+ }
void enqueue(Task&&);
void doWaitForIdle();
@@ -120,6 +124,7 @@ private:
std::condition_variable mCondition;
int mWaitingThreads = 0;
ArrayQueue<Task, QUEUE_SIZE> mWorkQueue;
+ std::atomic_bool mIsStopping = false;
};
} // namespace uirenderer
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index f5dc6ead374a..1905fa8ce612 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -5101,7 +5101,7 @@ final public class MediaCodec {
* size is larger than 16x16, then the qpOffset information of all 16x16 blocks that
* encompass the coding unit is combined and used. The QP of target block will be calculated
* as 'frameQP + offsetQP'. If the result exceeds minQP or maxQP configured then the value
- * may be clamped. Negative offset results in blocks encoded at lower QP than frame QP and
+ * will be clamped. Negative offset results in blocks encoded at lower QP than frame QP and
* positive offsets will result in encoding blocks at higher QP than frame QP. If the areas
* of negative QP and positive QP are chosen wisely, the overall viewing experience can be
* improved.
@@ -5128,7 +5128,7 @@ final public class MediaCodec {
* quantization parameter (QP) offset of the blocks in the bounding box. The bounding box
* will get stretched outwards to align to LCU boundaries during encoding. The Qp Offset is
* integral and shall be in the range [-128, 127]. The QP of target block will be calculated
- * as frameQP + offsetQP. If the result exceeds minQP or maxQP configured then the value may
+ * as frameQP + offsetQP. If the result exceeds minQP or maxQP configured then the value will
* be clamped. Negative offset results in blocks encoded at lower QP than frame QP and
* positive offsets will result in blocks encoded at higher QP than frame QP. If the areas of
* negative QP and positive QP are chosen wisely, the overall viewing experience can be
diff --git a/media/java/android/media/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java
index 1e7bc4764dd7..abad46046890 100644
--- a/media/java/android/media/MediaCodecInfo.java
+++ b/media/java/android/media/MediaCodecInfo.java
@@ -2651,11 +2651,10 @@ public final class MediaCodecInfo {
mBlockAspectRatioRange = POSITIVE_RATIONALS;
mAspectRatioRange = POSITIVE_RATIONALS;
- // YUV 4:2:0 requires 2:2 alignment
- mWidthAlignment = 2;
- mHeightAlignment = 2;
- mBlockWidth = 2;
- mBlockHeight = 2;
+ mWidthAlignment = 1;
+ mHeightAlignment = 1;
+ mBlockWidth = 1;
+ mBlockHeight = 1;
mSmallerDimensionUpperLimit = getSizeRange().getUpper();
}
diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java
index 7b83842a9fb2..cd0654ceb348 100644
--- a/media/java/android/media/MediaFormat.java
+++ b/media/java/android/media/MediaFormat.java
@@ -17,6 +17,7 @@
package android.media;
import static android.media.codec.Flags.FLAG_IN_PROCESS_SW_AUDIO_CODEC;
+import static android.media.codec.Flags.FLAG_REGION_OF_INTEREST;
import static com.android.media.codec.flags.Flags.FLAG_CODEC_IMPORTANCE;
import static com.android.media.codec.flags.Flags.FLAG_LARGE_AUDIO_FRAME;
@@ -26,6 +27,8 @@ import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.compat.annotation.UnsupportedAppUsage;
+import android.graphics.Rect;
+import android.text.TextUtils;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -34,6 +37,7 @@ import java.nio.ByteOrder;
import java.util.AbstractSet;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
@@ -1769,6 +1773,67 @@ public final class MediaFormat {
@FlaggedApi(FLAG_IN_PROCESS_SW_AUDIO_CODEC)
public static final String KEY_SECURITY_MODEL = "security-model";
+ /**
+ * QpOffsetRect constitutes the metadata required for encoding a region of interest in an
+ * image or a video frame. The region of interest is represented by a rectangle. The four
+ * integer coordinates of the rectangle are stored in fields left, top, right, bottom.
+ * Note that the right and bottom coordinates are exclusive.
+ * This is paired with a suggestive qp offset information that is to be used during encoding
+ * of the blocks belonging to the to the box.
+ */
+ @FlaggedApi(FLAG_REGION_OF_INTEREST)
+ public static final class QpOffsetRect {
+ private Rect mContour;
+ private int mQpOffset;
+
+ /**
+ * Create a new region of interest with the specified coordinates and qpOffset. Note: no
+ * range checking is performed, so the caller must ensure that left >= 0, left <= right,
+ * top >= 0 and top <= bottom. Note that the right and bottom coordinates are exclusive.
+ *
+ * @param contour Rectangle specifying the region of interest
+ * @param qpOffset qpOffset to be used for the blocks in the specified rectangle
+ */
+ public QpOffsetRect(@NonNull Rect contour, int qpOffset) {
+ mContour = contour;
+ mQpOffset = qpOffset;
+ }
+
+ /**
+ * Update the region of interest information with the specified coordinates and qpOffset
+ *
+ * @param contour Rectangle specifying the region of interest
+ * @param qpOffset qpOffset to be used for the blocks in the specified rectangle
+ */
+ public void set(@NonNull Rect contour, int qpOffset) {
+ mContour = contour;
+ mQpOffset = qpOffset;
+ }
+
+ /**
+ * @return Return a string representation of qpOffsetRect in a compact form.
+ * Helper function to insert key {@link #PARAMETER_KEY_QP_OFFSET_RECTS} in MediaFormat
+ */
+ @NonNull
+ public String flattenToString() {
+ return TextUtils.formatSimple("%d,%d-%d,%d=%d;", mContour.top, mContour.left,
+ mContour.bottom, mContour.right, mQpOffset);
+ }
+
+ /**
+ * @return Return a string representation of qpOffsetRect in a compact form.
+ * Helper function to insert key {@link #PARAMETER_KEY_QP_OFFSET_RECTS} in MediaFormat
+ */
+ @NonNull
+ public static String flattenToString(@NonNull List<QpOffsetRect> qpOffsetRects) {
+ StringBuilder builder = new StringBuilder();
+ for (QpOffsetRect qpOffsetRect : qpOffsetRects) {
+ builder.append(qpOffsetRect.flattenToString());
+ }
+ return builder.toString();
+ }
+ }
+
/* package private */ MediaFormat(@NonNull Map<String, Object> map) {
mMap = map;
}
diff --git a/native/android/Android.bp b/native/android/Android.bp
index 481268516b51..001b8a573354 100644
--- a/native/android/Android.bp
+++ b/native/android/Android.bp
@@ -84,6 +84,7 @@ cc_library_shared {
"libinput",
"libutils",
"libbinder",
+ "libbinder_ndk",
"libui",
"libgui",
"libharfbuzz_ng", // Only for including hb.h via minikin
@@ -101,6 +102,7 @@ cc_library_shared {
"android.hardware.configstore-utils",
"android.os.flags-aconfig-cc",
"libnativedisplay",
+ "libfmq",
],
static_libs: [
diff --git a/native/android/performance_hint.cpp b/native/android/performance_hint.cpp
index 279f9d682b9f..8227bdbd14a7 100644
--- a/native/android/performance_hint.cpp
+++ b/native/android/performance_hint.cpp
@@ -18,15 +18,15 @@
#include <aidl/android/hardware/power/SessionHint.h>
#include <aidl/android/hardware/power/SessionMode.h>
+#include <aidl/android/hardware/power/SessionTag.h>
+#include <aidl/android/hardware/power/WorkDuration.h>
+#include <aidl/android/os/IHintManager.h>
+#include <aidl/android/os/IHintSession.h>
#include <android-base/stringprintf.h>
-#include <android/WorkDuration.h>
-#include <android/os/IHintManager.h>
-#include <android/os/IHintSession.h>
+#include <android/binder_manager.h>
+#include <android/binder_status.h>
#include <android/performance_hint.h>
#include <android/trace.h>
-#include <binder/Binder.h>
-#include <binder/IBinder.h>
-#include <binder/IServiceManager.h>
#include <inttypes.h>
#include <performance_hint_private.h>
#include <utils/SystemClock.h>
@@ -37,22 +37,25 @@
#include <vector>
using namespace android;
-using namespace android::os;
+using namespace aidl::android::os;
using namespace std::chrono_literals;
-using AidlSessionHint = aidl::android::hardware::power::SessionHint;
-using AidlSessionMode = aidl::android::hardware::power::SessionMode;
+using HalSessionHint = aidl::android::hardware::power::SessionHint;
+using HalSessionMode = aidl::android::hardware::power::SessionMode;
+using HalWorkDuration = aidl::android::hardware::power::WorkDuration;
+
using android::base::StringPrintf;
struct APerformanceHintSession;
constexpr int64_t SEND_HINT_TIMEOUT = std::chrono::nanoseconds(100ms).count();
+struct AWorkDuration : public HalWorkDuration {};
struct APerformanceHintManager {
public:
static APerformanceHintManager* getInstance();
- APerformanceHintManager(sp<IHintManager> service, int64_t preferredRateNanos);
+ APerformanceHintManager(std::shared_ptr<IHintManager> service, int64_t preferredRateNanos);
APerformanceHintManager() = delete;
~APerformanceHintManager() = default;
@@ -61,17 +64,28 @@ public:
int64_t getPreferredRateNanos() const;
private:
- static APerformanceHintManager* create(sp<IHintManager> iHintManager);
+ // Necessary to create an empty binder object
+ static void* tokenStubOnCreate(void*) {
+ return nullptr;
+ }
+ static void tokenStubOnDestroy(void*) {}
+ static binder_status_t tokenStubOnTransact(AIBinder*, transaction_code_t, const AParcel*,
+ AParcel*) {
+ return STATUS_OK;
+ }
+
+ static APerformanceHintManager* create(std::shared_ptr<IHintManager> iHintManager);
- sp<IHintManager> mHintManager;
- const sp<IBinder> mToken = sp<BBinder>::make();
+ std::shared_ptr<IHintManager> mHintManager;
+ ndk::SpAIBinder mToken;
const int64_t mPreferredRateNanos;
};
struct APerformanceHintSession {
public:
- APerformanceHintSession(sp<IHintManager> hintManager, sp<IHintSession> session,
- int64_t preferredRateNanos, int64_t targetDurationNanos);
+ APerformanceHintSession(std::shared_ptr<IHintManager> hintManager,
+ std::shared_ptr<IHintSession> session, int64_t preferredRateNanos,
+ int64_t targetDurationNanos);
APerformanceHintSession() = delete;
~APerformanceHintSession();
@@ -86,10 +100,10 @@ public:
private:
friend struct APerformanceHintManager;
- int reportActualWorkDurationInternal(WorkDuration* workDuration);
+ int reportActualWorkDurationInternal(AWorkDuration* workDuration);
- sp<IHintManager> mHintManager;
- sp<IHintSession> mHintSession;
+ std::shared_ptr<IHintManager> mHintManager;
+ std::shared_ptr<IHintSession> mHintSession;
// HAL preferred update rate
const int64_t mPreferredRateNanos;
// Target duration for choosing update rate
@@ -101,7 +115,7 @@ private:
// Last hint reported from sendHint indexed by hint value
std::vector<int64_t> mLastHintSentTimestamp;
// Cached samples
- std::vector<WorkDuration> mActualWorkDurations;
+ std::vector<HalWorkDuration> mActualWorkDurations;
std::string mSessionName;
static int32_t sIDCounter;
// The most recent set of thread IDs
@@ -114,19 +128,24 @@ private:
void traceTargetDuration(int64_t targetDuration);
};
-static IHintManager* gIHintManagerForTesting = nullptr;
+static std::shared_ptr<IHintManager>* gIHintManagerForTesting = nullptr;
static APerformanceHintManager* gHintManagerForTesting = nullptr;
int32_t APerformanceHintSession::sIDCounter = 0;
// ===================================== APerformanceHintManager implementation
-APerformanceHintManager::APerformanceHintManager(sp<IHintManager> manager,
+APerformanceHintManager::APerformanceHintManager(std::shared_ptr<IHintManager> manager,
int64_t preferredRateNanos)
- : mHintManager(std::move(manager)), mPreferredRateNanos(preferredRateNanos) {}
+ : mHintManager(std::move(manager)), mPreferredRateNanos(preferredRateNanos) {
+ static AIBinder_Class* tokenBinderClass =
+ AIBinder_Class_define("phm_token", tokenStubOnCreate, tokenStubOnDestroy,
+ tokenStubOnTransact);
+ mToken = ndk::SpAIBinder(AIBinder_new(tokenBinderClass, nullptr));
+}
APerformanceHintManager* APerformanceHintManager::getInstance() {
if (gHintManagerForTesting) return gHintManagerForTesting;
if (gIHintManagerForTesting) {
- APerformanceHintManager* manager = create(gIHintManagerForTesting);
+ APerformanceHintManager* manager = create(*gIHintManagerForTesting);
gIHintManagerForTesting = nullptr;
return manager;
}
@@ -134,20 +153,19 @@ APerformanceHintManager* APerformanceHintManager::getInstance() {
return instance;
}
-APerformanceHintManager* APerformanceHintManager::create(sp<IHintManager> manager) {
+APerformanceHintManager* APerformanceHintManager::create(std::shared_ptr<IHintManager> manager) {
if (!manager) {
- manager = interface_cast<IHintManager>(
- defaultServiceManager()->checkService(String16("performance_hint")));
+ manager = IHintManager::fromBinder(
+ ndk::SpAIBinder(AServiceManager_waitForService("performance_hint")));
}
if (manager == nullptr) {
ALOGE("%s: PerformanceHint service is not ready ", __FUNCTION__);
return nullptr;
}
int64_t preferredRateNanos = -1L;
- binder::Status ret = manager->getHintSessionPreferredRate(&preferredRateNanos);
+ ndk::ScopedAStatus ret = manager->getHintSessionPreferredRate(&preferredRateNanos);
if (!ret.isOk()) {
- ALOGE("%s: PerformanceHint cannot get preferred rate. %s", __FUNCTION__,
- ret.exceptionMessage().c_str());
+ ALOGE("%s: PerformanceHint cannot get preferred rate. %s", __FUNCTION__, ret.getMessage());
return nullptr;
}
if (preferredRateNanos <= 0) {
@@ -159,8 +177,8 @@ APerformanceHintManager* APerformanceHintManager::create(sp<IHintManager> manage
APerformanceHintSession* APerformanceHintManager::createSession(
const int32_t* threadIds, size_t size, int64_t initialTargetWorkDurationNanos) {
std::vector<int32_t> tids(threadIds, threadIds + size);
- sp<IHintSession> session;
- binder::Status ret =
+ std::shared_ptr<IHintSession> session;
+ ndk::ScopedAStatus ret =
mHintManager->createHintSession(mToken, tids, initialTargetWorkDurationNanos, &session);
if (!ret.isOk() || !session) {
return nullptr;
@@ -179,8 +197,8 @@ int64_t APerformanceHintManager::getPreferredRateNanos() const {
// ===================================== APerformanceHintSession implementation
-APerformanceHintSession::APerformanceHintSession(sp<IHintManager> hintManager,
- sp<IHintSession> session,
+APerformanceHintSession::APerformanceHintSession(std::shared_ptr<IHintManager> hintManager,
+ std::shared_ptr<IHintSession> session,
int64_t preferredRateNanos,
int64_t targetDurationNanos)
: mHintManager(hintManager),
@@ -189,17 +207,17 @@ APerformanceHintSession::APerformanceHintSession(sp<IHintManager> hintManager,
mTargetDurationNanos(targetDurationNanos),
mFirstTargetMetTimestamp(0),
mLastTargetMetTimestamp(0) {
- const std::vector<AidlSessionHint> sessionHintRange{ndk::enum_range<AidlSessionHint>().begin(),
- ndk::enum_range<AidlSessionHint>().end()};
+ const std::vector<HalSessionHint> sessionHintRange{ndk::enum_range<HalSessionHint>().begin(),
+ ndk::enum_range<HalSessionHint>().end()};
mLastHintSentTimestamp = std::vector<int64_t>(sessionHintRange.size(), 0);
mSessionName = android::base::StringPrintf("ADPF Session %" PRId32, ++sIDCounter);
}
APerformanceHintSession::~APerformanceHintSession() {
- binder::Status ret = mHintSession->close();
+ ndk::ScopedAStatus ret = mHintSession->close();
if (!ret.isOk()) {
- ALOGE("%s: HintSession close failed: %s", __FUNCTION__, ret.exceptionMessage().c_str());
+ ALOGE("%s: HintSession close failed: %s", __FUNCTION__, ret.getMessage());
}
}
@@ -208,10 +226,10 @@ int APerformanceHintSession::updateTargetWorkDuration(int64_t targetDurationNano
ALOGE("%s: targetDurationNanos must be positive", __FUNCTION__);
return EINVAL;
}
- binder::Status ret = mHintSession->updateTargetWorkDuration(targetDurationNanos);
+ ndk::ScopedAStatus ret = mHintSession->updateTargetWorkDuration(targetDurationNanos);
if (!ret.isOk()) {
ALOGE("%s: HintSession updateTargetWorkDuration failed: %s", __FUNCTION__,
- ret.exceptionMessage().c_str());
+ ret.getMessage());
return EPIPE;
}
mTargetDurationNanos = targetDurationNanos;
@@ -228,9 +246,12 @@ int APerformanceHintSession::updateTargetWorkDuration(int64_t targetDurationNano
}
int APerformanceHintSession::reportActualWorkDuration(int64_t actualDurationNanos) {
- WorkDuration workDuration(0, actualDurationNanos, actualDurationNanos, 0);
+ HalWorkDuration workDuration{.durationNanos = actualDurationNanos,
+ .workPeriodStartTimestampNanos = 0,
+ .cpuDurationNanos = actualDurationNanos,
+ .gpuDurationNanos = 0};
- return reportActualWorkDurationInternal(&workDuration);
+ return reportActualWorkDurationInternal(static_cast<AWorkDuration*>(&workDuration));
}
int APerformanceHintSession::sendHint(SessionHint hint) {
@@ -238,17 +259,17 @@ int APerformanceHintSession::sendHint(SessionHint hint) {
ALOGE("%s: invalid session hint %d", __FUNCTION__, hint);
return EINVAL;
}
- int64_t now = elapsedRealtimeNano();
+ int64_t now = uptimeNanos();
// Limit sendHint to a pre-detemined rate for safety
if (now < (mLastHintSentTimestamp[hint] + SEND_HINT_TIMEOUT)) {
return 0;
}
- binder::Status ret = mHintSession->sendHint(hint);
+ ndk::ScopedAStatus ret = mHintSession->sendHint(hint);
if (!ret.isOk()) {
- ALOGE("%s: HintSession sendHint failed: %s", __FUNCTION__, ret.exceptionMessage().c_str());
+ ALOGE("%s: HintSession sendHint failed: %s", __FUNCTION__, ret.getMessage());
return EPIPE;
}
mLastHintSentTimestamp[hint] = now;
@@ -261,12 +282,12 @@ int APerformanceHintSession::setThreads(const int32_t* threadIds, size_t size) {
return EINVAL;
}
std::vector<int32_t> tids(threadIds, threadIds + size);
- binder::Status ret = mHintManager->setHintSessionThreads(mHintSession, tids);
+ ndk::ScopedAStatus ret = mHintManager->setHintSessionThreads(mHintSession, tids);
if (!ret.isOk()) {
- ALOGE("%s: failed: %s", __FUNCTION__, ret.exceptionMessage().c_str());
- if (ret.exceptionCode() == binder::Status::Exception::EX_ILLEGAL_ARGUMENT) {
+ ALOGE("%s: failed: %s", __FUNCTION__, ret.getMessage());
+ if (ret.getExceptionCode() == EX_ILLEGAL_ARGUMENT) {
return EINVAL;
- } else if (ret.exceptionCode() == binder::Status::Exception::EX_SECURITY) {
+ } else if (ret.getExceptionCode() == EX_SECURITY) {
return EPERM;
}
return EPIPE;
@@ -279,9 +300,9 @@ int APerformanceHintSession::setThreads(const int32_t* threadIds, size_t size) {
int APerformanceHintSession::getThreadIds(int32_t* const threadIds, size_t* size) {
std::vector<int32_t> tids;
- binder::Status ret = mHintManager->getHintSessionThreadIds(mHintSession, &tids);
+ ndk::ScopedAStatus ret = mHintManager->getHintSessionThreadIds(mHintSession, &tids);
if (!ret.isOk()) {
- ALOGE("%s: failed: %s", __FUNCTION__, ret.exceptionMessage().c_str());
+ ALOGE("%s: failed: %s", __FUNCTION__, ret.getMessage());
return EPIPE;
}
@@ -301,28 +322,27 @@ int APerformanceHintSession::getThreadIds(int32_t* const threadIds, size_t* size
}
int APerformanceHintSession::setPreferPowerEfficiency(bool enabled) {
- binder::Status ret =
- mHintSession->setMode(static_cast<int32_t>(AidlSessionMode::POWER_EFFICIENCY), enabled);
+ ndk::ScopedAStatus ret =
+ mHintSession->setMode(static_cast<int32_t>(HalSessionMode::POWER_EFFICIENCY), enabled);
if (!ret.isOk()) {
ALOGE("%s: HintSession setPreferPowerEfficiency failed: %s", __FUNCTION__,
- ret.exceptionMessage().c_str());
+ ret.getMessage());
return EPIPE;
}
tracePowerEfficient(enabled);
return OK;
}
-int APerformanceHintSession::reportActualWorkDuration(AWorkDuration* aWorkDuration) {
- WorkDuration* workDuration = static_cast<WorkDuration*>(aWorkDuration);
+int APerformanceHintSession::reportActualWorkDuration(AWorkDuration* workDuration) {
return reportActualWorkDurationInternal(workDuration);
}
-int APerformanceHintSession::reportActualWorkDurationInternal(WorkDuration* workDuration) {
- int64_t actualTotalDurationNanos = workDuration->actualTotalDurationNanos;
+int APerformanceHintSession::reportActualWorkDurationInternal(AWorkDuration* workDuration) {
+ int64_t actualTotalDurationNanos = workDuration->durationNanos;
int64_t now = uptimeNanos();
- workDuration->timestampNanos = now;
- traceActualDuration(workDuration->actualTotalDurationNanos);
+ workDuration->timeStampNanos = now;
+ traceActualDuration(workDuration->durationNanos);
mActualWorkDurations.push_back(std::move(*workDuration));
if (actualTotalDurationNanos >= mTargetDurationNanos) {
@@ -346,14 +366,14 @@ int APerformanceHintSession::reportActualWorkDurationInternal(WorkDuration* work
mLastTargetMetTimestamp = now;
}
- binder::Status ret = mHintSession->reportActualWorkDuration2(mActualWorkDurations);
+ ndk::ScopedAStatus ret = mHintSession->reportActualWorkDuration2(mActualWorkDurations);
if (!ret.isOk()) {
ALOGE("%s: HintSession reportActualWorkDuration failed: %s", __FUNCTION__,
- ret.exceptionMessage().c_str());
+ ret.getMessage());
mFirstTargetMetTimestamp = 0;
mLastTargetMetTimestamp = 0;
traceBatchSize(mActualWorkDurations.size());
- return ret.exceptionCode() == binder::Status::EX_ILLEGAL_ARGUMENT ? EINVAL : EPIPE;
+ return ret.getExceptionCode() == EX_ILLEGAL_ARGUMENT ? EINVAL : EPIPE;
}
mActualWorkDurations.clear();
traceBatchSize(0);
@@ -481,18 +501,16 @@ int APerformanceHint_reportActualWorkDuration2(APerformanceHintSession* session,
AWorkDuration* workDurationPtr) {
VALIDATE_PTR(session)
VALIDATE_PTR(workDurationPtr)
- WorkDuration& workDuration = *static_cast<WorkDuration*>(workDurationPtr);
- VALIDATE_INT(workDuration.workPeriodStartTimestampNanos, > 0)
- VALIDATE_INT(workDuration.actualTotalDurationNanos, > 0)
- VALIDATE_INT(workDuration.actualCpuDurationNanos, >= 0)
- VALIDATE_INT(workDuration.actualGpuDurationNanos, >= 0)
- VALIDATE_INT(workDuration.actualGpuDurationNanos + workDuration.actualCpuDurationNanos, > 0)
+ VALIDATE_INT(workDurationPtr->durationNanos, > 0)
+ VALIDATE_INT(workDurationPtr->workPeriodStartTimestampNanos, > 0)
+ VALIDATE_INT(workDurationPtr->cpuDurationNanos, >= 0)
+ VALIDATE_INT(workDurationPtr->gpuDurationNanos, >= 0)
+ VALIDATE_INT(workDurationPtr->gpuDurationNanos + workDurationPtr->cpuDurationNanos, > 0)
return session->reportActualWorkDuration(workDurationPtr);
}
AWorkDuration* AWorkDuration_create() {
- WorkDuration* workDuration = new WorkDuration();
- return static_cast<AWorkDuration*>(workDuration);
+ return new AWorkDuration();
}
void AWorkDuration_release(AWorkDuration* aWorkDuration) {
@@ -500,37 +518,36 @@ void AWorkDuration_release(AWorkDuration* aWorkDuration) {
delete aWorkDuration;
}
-void AWorkDuration_setWorkPeriodStartTimestampNanos(AWorkDuration* aWorkDuration,
- int64_t workPeriodStartTimestampNanos) {
- VALIDATE_PTR(aWorkDuration)
- WARN_INT(workPeriodStartTimestampNanos, > 0)
- static_cast<WorkDuration*>(aWorkDuration)->workPeriodStartTimestampNanos =
- workPeriodStartTimestampNanos;
-}
-
void AWorkDuration_setActualTotalDurationNanos(AWorkDuration* aWorkDuration,
int64_t actualTotalDurationNanos) {
VALIDATE_PTR(aWorkDuration)
WARN_INT(actualTotalDurationNanos, > 0)
- static_cast<WorkDuration*>(aWorkDuration)->actualTotalDurationNanos = actualTotalDurationNanos;
+ aWorkDuration->durationNanos = actualTotalDurationNanos;
+}
+
+void AWorkDuration_setWorkPeriodStartTimestampNanos(AWorkDuration* aWorkDuration,
+ int64_t workPeriodStartTimestampNanos) {
+ VALIDATE_PTR(aWorkDuration)
+ WARN_INT(workPeriodStartTimestampNanos, > 0)
+ aWorkDuration->workPeriodStartTimestampNanos = workPeriodStartTimestampNanos;
}
void AWorkDuration_setActualCpuDurationNanos(AWorkDuration* aWorkDuration,
int64_t actualCpuDurationNanos) {
VALIDATE_PTR(aWorkDuration)
WARN_INT(actualCpuDurationNanos, >= 0)
- static_cast<WorkDuration*>(aWorkDuration)->actualCpuDurationNanos = actualCpuDurationNanos;
+ aWorkDuration->cpuDurationNanos = actualCpuDurationNanos;
}
void AWorkDuration_setActualGpuDurationNanos(AWorkDuration* aWorkDuration,
int64_t actualGpuDurationNanos) {
VALIDATE_PTR(aWorkDuration)
WARN_INT(actualGpuDurationNanos, >= 0)
- static_cast<WorkDuration*>(aWorkDuration)->actualGpuDurationNanos = actualGpuDurationNanos;
+ aWorkDuration->gpuDurationNanos = actualGpuDurationNanos;
}
void APerformanceHint_setIHintManagerForTesting(void* iManager) {
delete gHintManagerForTesting;
gHintManagerForTesting = nullptr;
- gIHintManagerForTesting = static_cast<IHintManager*>(iManager);
+ gIHintManagerForTesting = static_cast<std::shared_ptr<IHintManager>*>(iManager);
}
diff --git a/native/android/tests/performance_hint/Android.bp b/native/android/tests/performance_hint/Android.bp
index fdc1bc6a20d8..608d5d8a923a 100644
--- a/native/android/tests/performance_hint/Android.bp
+++ b/native/android/tests/performance_hint/Android.bp
@@ -39,6 +39,7 @@ cc_test {
"libandroid",
"liblog",
"libbinder",
+ "libbinder_ndk",
"libpowermanager",
"libutils",
],
diff --git a/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp b/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp
index 4553b4919d2d..bfbe34e7a8a1 100644
--- a/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp
+++ b/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp
@@ -16,11 +16,11 @@
#define LOG_TAG "PerformanceHintNativeTest"
-#include <android/WorkDuration.h>
-#include <android/os/IHintManager.h>
-#include <android/os/IHintSession.h>
+#include <aidl/android/hardware/power/WorkDuration.h>
+#include <aidl/android/os/IHintManager.h>
+#include <android/binder_manager.h>
+#include <android/binder_status.h>
#include <android/performance_hint.h>
-#include <binder/IBinder.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <performance_hint_private.h>
@@ -28,48 +28,54 @@
#include <memory>
#include <vector>
-using android::binder::Status;
-using android::os::IHintManager;
-using android::os::IHintSession;
+using aidl::android::hardware::power::WorkDuration;
+using aidl::android::os::IHintManager;
+using aidl::android::os::IHintSession;
+using ndk::ScopedAStatus;
+using ndk::SpAIBinder;
using namespace android;
using namespace testing;
class MockIHintManager : public IHintManager {
public:
- MOCK_METHOD(Status, createHintSession,
- (const sp<IBinder>& token, const ::std::vector<int32_t>& tids,
- int64_t durationNanos, ::android::sp<IHintSession>* _aidl_return),
+ MOCK_METHOD(ScopedAStatus, createHintSession,
+ (const SpAIBinder& token, const ::std::vector<int32_t>& tids, int64_t durationNanos,
+ std::shared_ptr<IHintSession>* _aidl_return),
(override));
- MOCK_METHOD(Status, getHintSessionPreferredRate, (int64_t * _aidl_return), (override));
- MOCK_METHOD(Status, setHintSessionThreads,
- (const sp<IHintSession>& hintSession, const ::std::vector<int32_t>& tids),
+ MOCK_METHOD(ScopedAStatus, getHintSessionPreferredRate, (int64_t * _aidl_return), (override));
+ MOCK_METHOD(ScopedAStatus, setHintSessionThreads,
+ (const std::shared_ptr<IHintSession>& hintSession,
+ const ::std::vector<int32_t>& tids),
(override));
- MOCK_METHOD(Status, getHintSessionThreadIds,
- (const sp<IHintSession>& hintSession, ::std::vector<int32_t>* tids), (override));
- MOCK_METHOD(IBinder*, onAsBinder, (), (override));
+ MOCK_METHOD(ScopedAStatus, getHintSessionThreadIds,
+ (const std::shared_ptr<IHintSession>& hintSession, ::std::vector<int32_t>* tids),
+ (override));
+ MOCK_METHOD(SpAIBinder, asBinder, (), (override));
+ MOCK_METHOD(bool, isRemote, (), (override));
};
class MockIHintSession : public IHintSession {
public:
- MOCK_METHOD(Status, updateTargetWorkDuration, (int64_t targetDurationNanos), (override));
- MOCK_METHOD(Status, reportActualWorkDuration,
+ MOCK_METHOD(ScopedAStatus, updateTargetWorkDuration, (int64_t targetDurationNanos), (override));
+ MOCK_METHOD(ScopedAStatus, reportActualWorkDuration,
(const ::std::vector<int64_t>& actualDurationNanos,
const ::std::vector<int64_t>& timeStampNanos),
(override));
- MOCK_METHOD(Status, sendHint, (int32_t hint), (override));
- MOCK_METHOD(Status, setMode, (int32_t mode, bool enabled), (override));
- MOCK_METHOD(Status, close, (), (override));
- MOCK_METHOD(IBinder*, onAsBinder, (), (override));
- MOCK_METHOD(Status, reportActualWorkDuration2,
- (const ::std::vector<android::os::WorkDuration>& workDurations), (override));
+ MOCK_METHOD(ScopedAStatus, sendHint, (int32_t hint), (override));
+ MOCK_METHOD(ScopedAStatus, setMode, (int32_t mode, bool enabled), (override));
+ MOCK_METHOD(ScopedAStatus, close, (), (override));
+ MOCK_METHOD(ScopedAStatus, reportActualWorkDuration2,
+ (const ::std::vector<WorkDuration>& workDurations), (override));
+ MOCK_METHOD(SpAIBinder, asBinder, (), (override));
+ MOCK_METHOD(bool, isRemote, (), (override));
};
class PerformanceHintTest : public Test {
public:
void SetUp() override {
- mMockIHintManager = new StrictMock<MockIHintManager>();
- APerformanceHint_setIHintManagerForTesting(mMockIHintManager);
+ mMockIHintManager = ndk::SharedRefBase::make<NiceMock<MockIHintManager>>();
+ APerformanceHint_setIHintManagerForTesting(&mMockIHintManager);
}
void TearDown() override {
@@ -79,15 +85,50 @@ public:
}
APerformanceHintManager* createManager() {
- EXPECT_CALL(*mMockIHintManager, getHintSessionPreferredRate(_))
- .Times(Exactly(1))
- .WillRepeatedly(DoAll(SetArgPointee<0>(123L), Return(Status())));
+ ON_CALL(*mMockIHintManager, getHintSessionPreferredRate(_))
+ .WillByDefault(DoAll(SetArgPointee<0>(123L), [] { return ScopedAStatus::ok(); }));
return APerformanceHint_getManager();
}
+ APerformanceHintSession* createSession(APerformanceHintManager* manager,
+ int64_t targetDuration = 56789L) {
+ mMockSession = ndk::SharedRefBase::make<NiceMock<MockIHintSession>>();
+
+ std::vector<int32_t> tids;
+ tids.push_back(1);
+ tids.push_back(2);
+
+ ON_CALL(*mMockIHintManager, createHintSession(_, Eq(tids), Eq(targetDuration), _))
+ .WillByDefault(DoAll(SetArgPointee<3>(std::shared_ptr<IHintSession>(mMockSession)),
+ [] { return ScopedAStatus::ok(); }));
+ ON_CALL(*mMockIHintManager, setHintSessionThreads(_, _)).WillByDefault([] {
+ return ScopedAStatus::ok();
+ });
+ ON_CALL(*mMockSession, sendHint(_)).WillByDefault([] { return ScopedAStatus::ok(); });
+ ON_CALL(*mMockSession, setMode(_, _)).WillByDefault([] { return ScopedAStatus::ok(); });
+ ON_CALL(*mMockSession, close()).WillByDefault([] { return ScopedAStatus::ok(); });
+ ON_CALL(*mMockSession, updateTargetWorkDuration(_)).WillByDefault([] {
+ return ScopedAStatus::ok();
+ });
+ ON_CALL(*mMockSession, reportActualWorkDuration(_, _)).WillByDefault([] {
+ return ScopedAStatus::ok();
+ });
+ ON_CALL(*mMockSession, reportActualWorkDuration2(_)).WillByDefault([] {
+ return ScopedAStatus::ok();
+ });
+
+ return APerformanceHint_createSession(manager, tids.data(), tids.size(), targetDuration);
+ }
- StrictMock<MockIHintManager>* mMockIHintManager = nullptr;
+ std::shared_ptr<NiceMock<MockIHintManager>> mMockIHintManager = nullptr;
+ std::shared_ptr<NiceMock<MockIHintSession>> mMockSession = nullptr;
};
+bool equalsWithoutTimestamp(WorkDuration lhs, WorkDuration rhs) {
+ return lhs.workPeriodStartTimestampNanos == rhs.workPeriodStartTimestampNanos &&
+ lhs.cpuDurationNanos == rhs.cpuDurationNanos &&
+ lhs.gpuDurationNanos == rhs.gpuDurationNanos && lhs.durationNanos == rhs.durationNanos;
+}
+
TEST_F(PerformanceHintTest, TestGetPreferredUpdateRateNanos) {
APerformanceHintManager* manager = createManager();
int64_t preferredUpdateRateNanos = APerformanceHint_getPreferredUpdateRateNanos(manager);
@@ -96,25 +137,11 @@ TEST_F(PerformanceHintTest, TestGetPreferredUpdateRateNanos) {
TEST_F(PerformanceHintTest, TestSession) {
APerformanceHintManager* manager = createManager();
-
- std::vector<int32_t> tids;
- tids.push_back(1);
- tids.push_back(2);
- int64_t targetDuration = 56789L;
-
- StrictMock<MockIHintSession>* iSession = new StrictMock<MockIHintSession>();
- sp<IHintSession> session_sp(iSession);
-
- EXPECT_CALL(*mMockIHintManager, createHintSession(_, Eq(tids), Eq(targetDuration), _))
- .Times(Exactly(1))
- .WillRepeatedly(DoAll(SetArgPointee<3>(std::move(session_sp)), Return(Status())));
-
- APerformanceHintSession* session =
- APerformanceHint_createSession(manager, tids.data(), tids.size(), targetDuration);
+ APerformanceHintSession* session = createSession(manager);
ASSERT_TRUE(session);
int64_t targetDurationNanos = 10;
- EXPECT_CALL(*iSession, updateTargetWorkDuration(Eq(targetDurationNanos))).Times(Exactly(1));
+ EXPECT_CALL(*mMockSession, updateTargetWorkDuration(Eq(targetDurationNanos))).Times(Exactly(1));
int result = APerformanceHint_updateTargetWorkDuration(session, targetDurationNanos);
EXPECT_EQ(0, result);
@@ -122,8 +149,7 @@ TEST_F(PerformanceHintTest, TestSession) {
int64_t actualDurationNanos = 20;
std::vector<int64_t> actualDurations;
actualDurations.push_back(20);
- EXPECT_CALL(*iSession, reportActualWorkDuration(Eq(actualDurations), _)).Times(Exactly(1));
- EXPECT_CALL(*iSession, reportActualWorkDuration2(_)).Times(Exactly(1));
+ EXPECT_CALL(*mMockSession, reportActualWorkDuration2(_)).Times(Exactly(1));
result = APerformanceHint_reportActualWorkDuration(session, actualDurationNanos);
EXPECT_EQ(0, result);
@@ -133,114 +159,70 @@ TEST_F(PerformanceHintTest, TestSession) {
EXPECT_EQ(EINVAL, result);
SessionHint hintId = SessionHint::CPU_LOAD_RESET;
- EXPECT_CALL(*iSession, sendHint(Eq(hintId))).Times(Exactly(1));
+ EXPECT_CALL(*mMockSession, sendHint(Eq(hintId))).Times(Exactly(1));
result = APerformanceHint_sendHint(session, hintId);
EXPECT_EQ(0, result);
usleep(110000); // Sleep for longer than the update timeout.
- EXPECT_CALL(*iSession, sendHint(Eq(hintId))).Times(Exactly(1));
+ EXPECT_CALL(*mMockSession, sendHint(Eq(hintId))).Times(Exactly(1));
result = APerformanceHint_sendHint(session, hintId);
EXPECT_EQ(0, result);
// Expect to get rate limited if we try to send faster than the limiter allows
- EXPECT_CALL(*iSession, sendHint(Eq(hintId))).Times(Exactly(0));
+ EXPECT_CALL(*mMockSession, sendHint(Eq(hintId))).Times(Exactly(0));
result = APerformanceHint_sendHint(session, hintId);
EXPECT_EQ(0, result);
result = APerformanceHint_sendHint(session, static_cast<SessionHint>(-1));
EXPECT_EQ(EINVAL, result);
- EXPECT_CALL(*iSession, close()).Times(Exactly(1));
+ EXPECT_CALL(*mMockSession, close()).Times(Exactly(1));
APerformanceHint_closeSession(session);
}
TEST_F(PerformanceHintTest, SetThreads) {
APerformanceHintManager* manager = createManager();
- std::vector<int32_t> tids;
- tids.push_back(1);
- tids.push_back(2);
- int64_t targetDuration = 56789L;
-
- StrictMock<MockIHintSession>* iSession = new StrictMock<MockIHintSession>();
- sp<IHintSession> session_sp(iSession);
-
- EXPECT_CALL(*mMockIHintManager, createHintSession(_, Eq(tids), Eq(targetDuration), _))
- .Times(Exactly(1))
- .WillRepeatedly(DoAll(SetArgPointee<3>(std::move(session_sp)), Return(Status())));
-
- APerformanceHintSession* session =
- APerformanceHint_createSession(manager, tids.data(), tids.size(), targetDuration);
+ APerformanceHintSession* session = createSession(manager);
ASSERT_TRUE(session);
- std::vector<int32_t> emptyTids;
- int result = APerformanceHint_setThreads(session, emptyTids.data(), emptyTids.size());
+ int32_t emptyTids[2];
+ int result = APerformanceHint_setThreads(session, emptyTids, 0);
EXPECT_EQ(EINVAL, result);
std::vector<int32_t> newTids;
newTids.push_back(1);
newTids.push_back(3);
- EXPECT_CALL(*mMockIHintManager, setHintSessionThreads(_, Eq(newTids)))
- .Times(Exactly(1))
- .WillOnce(Return(Status()));
+ EXPECT_CALL(*mMockIHintManager, setHintSessionThreads(_, Eq(newTids))).Times(Exactly(1));
result = APerformanceHint_setThreads(session, newTids.data(), newTids.size());
EXPECT_EQ(0, result);
- testing::Mock::VerifyAndClearExpectations(mMockIHintManager);
+ testing::Mock::VerifyAndClearExpectations(mMockIHintManager.get());
std::vector<int32_t> invalidTids;
- auto status = Status::fromExceptionCode(binder::Status::Exception::EX_SECURITY);
invalidTids.push_back(4);
invalidTids.push_back(6);
EXPECT_CALL(*mMockIHintManager, setHintSessionThreads(_, Eq(invalidTids)))
.Times(Exactly(1))
- .WillOnce(Return(status));
+ .WillOnce(Return(ByMove(ScopedAStatus::fromExceptionCode(EX_SECURITY))));
result = APerformanceHint_setThreads(session, invalidTids.data(), invalidTids.size());
EXPECT_EQ(EPERM, result);
}
TEST_F(PerformanceHintTest, SetPowerEfficient) {
APerformanceHintManager* manager = createManager();
-
- std::vector<int32_t> tids;
- tids.push_back(1);
- tids.push_back(2);
- int64_t targetDuration = 56789L;
-
- StrictMock<MockIHintSession>* iSession = new StrictMock<MockIHintSession>();
- sp<IHintSession> session_sp(iSession);
-
- EXPECT_CALL(*mMockIHintManager, createHintSession(_, Eq(tids), Eq(targetDuration), _))
- .Times(Exactly(1))
- .WillRepeatedly(DoAll(SetArgPointee<3>(std::move(session_sp)), Return(Status())));
-
- APerformanceHintSession* session =
- APerformanceHint_createSession(manager, tids.data(), tids.size(), targetDuration);
+ APerformanceHintSession* session = createSession(manager);
ASSERT_TRUE(session);
- EXPECT_CALL(*iSession, setMode(_, Eq(true))).Times(Exactly(1));
+ EXPECT_CALL(*mMockSession, setMode(_, Eq(true))).Times(Exactly(1));
int result = APerformanceHint_setPreferPowerEfficiency(session, true);
EXPECT_EQ(0, result);
- EXPECT_CALL(*iSession, setMode(_, Eq(false))).Times(Exactly(1));
+ EXPECT_CALL(*mMockSession, setMode(_, Eq(false))).Times(Exactly(1));
result = APerformanceHint_setPreferPowerEfficiency(session, false);
EXPECT_EQ(0, result);
}
TEST_F(PerformanceHintTest, CreateZeroTargetDurationSession) {
APerformanceHintManager* manager = createManager();
-
- std::vector<int32_t> tids;
- tids.push_back(1);
- tids.push_back(2);
- int64_t targetDuration = 0;
-
- StrictMock<MockIHintSession>* iSession = new StrictMock<MockIHintSession>();
- sp<IHintSession> session_sp(iSession);
-
- EXPECT_CALL(*mMockIHintManager, createHintSession(_, Eq(tids), Eq(targetDuration), _))
- .Times(Exactly(1))
- .WillRepeatedly(DoAll(SetArgPointee<3>(std::move(session_sp)), Return(Status())));
-
- APerformanceHintSession* session =
- APerformanceHint_createSession(manager, tids.data(), tids.size(), targetDuration);
+ APerformanceHintSession* session = createSession(manager, 0);
ASSERT_TRUE(session);
}
@@ -251,12 +233,12 @@ MATCHER_P(WorkDurationEq, expected, "") {
return false;
}
for (int i = 0; i < expected.size(); ++i) {
- android::os::WorkDuration expectedWorkDuration = expected[i];
- android::os::WorkDuration actualWorkDuration = arg[i];
- if (!expectedWorkDuration.equalsWithoutTimestamp(actualWorkDuration)) {
+ WorkDuration expectedWorkDuration = expected[i];
+ WorkDuration actualWorkDuration = arg[i];
+ if (!equalsWithoutTimestamp(expectedWorkDuration, actualWorkDuration)) {
*result_listener << "WorkDuration at [" << i << "] is different: "
- << "Expected: " << expectedWorkDuration
- << ", Actual: " << actualWorkDuration;
+ << "Expected: " << expectedWorkDuration.toString()
+ << ", Actual: " << actualWorkDuration.toString();
return false;
}
}
@@ -265,92 +247,37 @@ MATCHER_P(WorkDurationEq, expected, "") {
TEST_F(PerformanceHintTest, TestAPerformanceHint_reportActualWorkDuration2) {
APerformanceHintManager* manager = createManager();
-
- std::vector<int32_t> tids;
- tids.push_back(1);
- tids.push_back(2);
- int64_t targetDuration = 56789L;
-
- StrictMock<MockIHintSession>* iSession = new StrictMock<MockIHintSession>();
- sp<IHintSession> session_sp(iSession);
-
- EXPECT_CALL(*mMockIHintManager, createHintSession(_, Eq(tids), Eq(targetDuration), _))
- .Times(Exactly(1))
- .WillRepeatedly(DoAll(SetArgPointee<3>(std::move(session_sp)), Return(Status())));
-
- APerformanceHintSession* session =
- APerformanceHint_createSession(manager, tids.data(), tids.size(), targetDuration);
+ APerformanceHintSession* session = createSession(manager);
ASSERT_TRUE(session);
int64_t targetDurationNanos = 10;
- EXPECT_CALL(*iSession, updateTargetWorkDuration(Eq(targetDurationNanos))).Times(Exactly(1));
+ EXPECT_CALL(*mMockSession, updateTargetWorkDuration(Eq(targetDurationNanos))).Times(Exactly(1));
int result = APerformanceHint_updateTargetWorkDuration(session, targetDurationNanos);
EXPECT_EQ(0, result);
usleep(2); // Sleep for longer than preferredUpdateRateNanos.
- {
- std::vector<android::os::WorkDuration> actualWorkDurations;
- android::os::WorkDuration workDuration(1, 20, 13, 8);
- actualWorkDurations.push_back(workDuration);
-
- EXPECT_CALL(*iSession, reportActualWorkDuration2(WorkDurationEq(actualWorkDurations)))
- .Times(Exactly(1));
- result = APerformanceHint_reportActualWorkDuration2(session,
- static_cast<AWorkDuration*>(
- &workDuration));
- EXPECT_EQ(0, result);
- }
-
- {
- std::vector<android::os::WorkDuration> actualWorkDurations;
- android::os::WorkDuration workDuration(-1, 20, 13, 8);
- actualWorkDurations.push_back(workDuration);
-
- EXPECT_CALL(*iSession, reportActualWorkDuration2(WorkDurationEq(actualWorkDurations)))
- .Times(Exactly(1));
- result = APerformanceHint_reportActualWorkDuration2(session,
- static_cast<AWorkDuration*>(
- &workDuration));
- EXPECT_EQ(22, result);
- }
- {
- std::vector<android::os::WorkDuration> actualWorkDurations;
- android::os::WorkDuration workDuration(1, -20, 13, 8);
- actualWorkDurations.push_back(workDuration);
-
- EXPECT_CALL(*iSession, reportActualWorkDuration2(WorkDurationEq(actualWorkDurations)))
- .Times(Exactly(1));
- result = APerformanceHint_reportActualWorkDuration2(session,
- static_cast<AWorkDuration*>(
- &workDuration));
- EXPECT_EQ(22, result);
- }
- {
- std::vector<android::os::WorkDuration> actualWorkDurations;
- android::os::WorkDuration workDuration(1, 20, -13, 8);
- actualWorkDurations.push_back(workDuration);
-
- EXPECT_CALL(*iSession, reportActualWorkDuration2(WorkDurationEq(actualWorkDurations)))
- .Times(Exactly(1));
- result = APerformanceHint_reportActualWorkDuration2(session,
- static_cast<AWorkDuration*>(
- &workDuration));
- EXPECT_EQ(EINVAL, result);
- }
- {
- std::vector<android::os::WorkDuration> actualWorkDurations;
- android::os::WorkDuration workDuration(1, 20, 13, -8);
- actualWorkDurations.push_back(workDuration);
-
- EXPECT_CALL(*iSession, reportActualWorkDuration2(WorkDurationEq(actualWorkDurations)))
+ struct TestPair {
+ WorkDuration duration;
+ int expectedResult;
+ };
+ std::vector<TestPair> testPairs{
+ {{1, 20, 1, 13, 8}, OK}, {{1, -20, 1, 13, 8}, EINVAL},
+ {{1, 20, -1, 13, 8}, EINVAL}, {{1, -20, 1, -13, 8}, EINVAL},
+ {{1, -20, 1, 13, -8}, EINVAL},
+ };
+ for (auto&& pair : testPairs) {
+ std::vector<WorkDuration> actualWorkDurations;
+ actualWorkDurations.push_back(pair.duration);
+
+ EXPECT_CALL(*mMockSession, reportActualWorkDuration2(WorkDurationEq(actualWorkDurations)))
.Times(Exactly(1));
result = APerformanceHint_reportActualWorkDuration2(session,
- static_cast<AWorkDuration*>(
- &workDuration));
- EXPECT_EQ(EINVAL, result);
+ reinterpret_cast<AWorkDuration*>(
+ &pair.duration));
+ EXPECT_EQ(pair.expectedResult, result);
}
- EXPECT_CALL(*iSession, close()).Times(Exactly(1));
+ EXPECT_CALL(*mMockSession, close()).Times(Exactly(1));
APerformanceHint_closeSession(session);
}
diff --git a/native/webview/plat_support/draw_fn.h b/native/webview/plat_support/draw_fn.h
index 44fe56fcaf4b..b865d0ebeb1f 100644
--- a/native/webview/plat_support/draw_fn.h
+++ b/native/webview/plat_support/draw_fn.h
@@ -23,7 +23,8 @@ extern "C" {
// 1 is Android Q. This matches kAwDrawGLInfoVersion version 3.
// 2 Adds transfer_function_* and color_space_toXYZD50 to AwDrawFn_DrawGLParams.
// 3 Adds SurfaceControl related functions.
-static const int kAwDrawFnVersion = 3;
+// 4 Adds AwDrawFn_ReportRenderingThreads to AwDrawFnFunctionTable.
+static const int kAwDrawFnVersion = 4;
// Returns parent ASurfaceControl for WebView overlays. It will be have same
// geometry as the surface we draw into and positioned below it (underlay).
@@ -268,6 +269,10 @@ typedef int AwDrawFn_CreateFunctor_v3(
// released, and it should be considered alive & active until that point.
typedef void AwDrawFn_ReleaseFunctor(int functor);
+// Report the list of threads critical for frame production for the given
+// functor. Must be called on render thread.
+typedef void AwDrawFn_ReportRenderingThreads(int functor, const int32_t* thread_ids, size_t size);
+
struct AwDrawFnFunctionTable {
int version;
AwDrawFn_QueryRenderMode* query_render_mode;
@@ -276,6 +281,8 @@ struct AwDrawFnFunctionTable {
AwDrawFn_ReleaseFunctor* release_functor;
// Added in version 3.
AwDrawFn_CreateFunctor_v3* create_functor_v3;
+ // Added in version 4.
+ AwDrawFn_ReportRenderingThreads* report_rendering_threads;
};
#ifdef __cplusplus
diff --git a/native/webview/plat_support/draw_functor.cpp b/native/webview/plat_support/draw_functor.cpp
index 1584350bb6f1..5d3e24c382bf 100644
--- a/native/webview/plat_support/draw_functor.cpp
+++ b/native/webview/plat_support/draw_functor.cpp
@@ -290,15 +290,20 @@ AwDrawFnRenderMode QueryRenderMode(void) {
}
}
+void ReportRenderingThreads(int functor, const int32_t* thread_ids, size_t size) {
+ uirenderer::WebViewFunctor_reportRenderingThreads(functor, thread_ids, size);
+}
+
jlong GetDrawFnFunctionTable() {
- static AwDrawFnFunctionTable function_table = {
- .version = kAwDrawFnVersion,
- .query_render_mode = &QueryRenderMode,
- .create_functor = &CreateFunctor,
- .release_functor = &ReleaseFunctor,
- .create_functor_v3 = &CreateFunctor_v3,
- };
- return reinterpret_cast<intptr_t>(&function_table);
+ static AwDrawFnFunctionTable function_table = {
+ .version = kAwDrawFnVersion,
+ .query_render_mode = &QueryRenderMode,
+ .create_functor = &CreateFunctor,
+ .release_functor = &ReleaseFunctor,
+ .create_functor_v3 = &CreateFunctor_v3,
+ .report_rendering_threads = &ReportRenderingThreads,
+ };
+ return reinterpret_cast<intptr_t>(&function_table);
}
const char kClassName[] = "com/android/webview/chromium/DrawFunctor";
diff --git a/nfc/api/current.txt b/nfc/api/current.txt
index 9e0bb86f46a5..da292a818396 100644
--- a/nfc/api/current.txt
+++ b/nfc/api/current.txt
@@ -205,7 +205,10 @@ package android.nfc.cardemulation {
method public boolean isDefaultServiceForCategory(android.content.ComponentName, String);
method public boolean registerAidsForService(android.content.ComponentName, String, java.util.List<java.lang.String>);
method @FlaggedApi("android.nfc.nfc_read_polling_loop") public boolean registerPollingLoopFilterForService(@NonNull android.content.ComponentName, @NonNull String, boolean);
+ method @FlaggedApi("android.nfc.nfc_read_polling_loop") public boolean registerPollingLoopPatternFilterForService(@NonNull android.content.ComponentName, @NonNull String, boolean);
method public boolean removeAidsForService(android.content.ComponentName, String);
+ method @FlaggedApi("android.nfc.nfc_read_polling_loop") public boolean removePollingLoopFilterForService(@NonNull android.content.ComponentName, @NonNull String);
+ method @FlaggedApi("android.nfc.nfc_read_polling_loop") public boolean removePollingLoopPatternFilterForService(@NonNull android.content.ComponentName, @NonNull String);
method @NonNull @RequiresPermission(android.Manifest.permission.NFC) public boolean setOffHostForService(@NonNull android.content.ComponentName, @NonNull String);
method public boolean setPreferredService(android.app.Activity, android.content.ComponentName);
method @FlaggedApi("android.nfc.nfc_observe_mode") public boolean setShouldDefaultToObserveModeForService(@NonNull android.content.ComponentName, boolean);
diff --git a/nfc/java/android/nfc/INfcCardEmulation.aidl b/nfc/java/android/nfc/INfcCardEmulation.aidl
index 85a07b74871b..cb97f23e813c 100644
--- a/nfc/java/android/nfc/INfcCardEmulation.aidl
+++ b/nfc/java/android/nfc/INfcCardEmulation.aidl
@@ -33,10 +33,13 @@ interface INfcCardEmulation
boolean setShouldDefaultToObserveModeForService(int userId, in android.content.ComponentName service, boolean enable);
boolean registerAidGroupForService(int userHandle, in ComponentName service, in AidGroup aidGroup);
boolean registerPollingLoopFilterForService(int userHandle, in ComponentName service, in String pollingLoopFilter, boolean autoTransact);
+ boolean registerPollingLoopPatternFilterForService(int userHandle, in ComponentName service, in String pollingLoopPatternFilter, boolean autoTransact);
boolean setOffHostForService(int userHandle, in ComponentName service, in String offHostSecureElement);
boolean unsetOffHostForService(int userHandle, in ComponentName service);
AidGroup getAidGroupForService(int userHandle, in ComponentName service, String category);
boolean removeAidGroupForService(int userHandle, in ComponentName service, String category);
+ boolean removePollingLoopFilterForService(int userHandle, in ComponentName service, in String pollingLoopFilter);
+ boolean removePollingLoopPatternFilterForService(int userHandle, in ComponentName service, in String pollingLoopPatternFilter);
List<ApduServiceInfo> getServices(int userHandle, in String category);
boolean setPreferredService(in ComponentName service);
boolean unsetPreferredService();
diff --git a/nfc/java/android/nfc/cardemulation/ApduServiceInfo.java b/nfc/java/android/nfc/cardemulation/ApduServiceInfo.java
index 2c7d61eea777..be3c24806c5b 100644
--- a/nfc/java/android/nfc/cardemulation/ApduServiceInfo.java
+++ b/nfc/java/android/nfc/cardemulation/ApduServiceInfo.java
@@ -108,6 +108,8 @@ public final class ApduServiceInfo implements Parcelable {
private final Map<String, Boolean> mAutoTransact;
+ private final Map<Pattern, Boolean> mAutoTransactPatterns;
+
/**
* Whether this service should only be started when the device is unlocked.
*/
@@ -179,7 +181,7 @@ public final class ApduServiceInfo implements Parcelable {
this(info, onHost, description, staticAidGroups, dynamicAidGroups,
requiresUnlock, requiresScreenOn, bannerResource, uid,
settingsActivityName, offHost, staticOffHost, isEnabled,
- new HashMap<String, Boolean>());
+ new HashMap<String, Boolean>(), new HashMap<Pattern, Boolean>());
}
/**
@@ -189,12 +191,13 @@ public final class ApduServiceInfo implements Parcelable {
List<AidGroup> staticAidGroups, List<AidGroup> dynamicAidGroups,
boolean requiresUnlock, boolean requiresScreenOn, int bannerResource, int uid,
String settingsActivityName, String offHost, String staticOffHost, boolean isEnabled,
- HashMap<String, Boolean> autoTransact) {
+ Map<String, Boolean> autoTransact, Map<Pattern, Boolean> autoTransactPatterns) {
this.mService = info;
this.mDescription = description;
this.mStaticAidGroups = new HashMap<String, AidGroup>();
this.mDynamicAidGroups = new HashMap<String, AidGroup>();
this.mAutoTransact = autoTransact;
+ this.mAutoTransactPatterns = autoTransactPatterns;
this.mOffHostName = offHost;
this.mStaticOffHostName = staticOffHost;
this.mOnHost = onHost;
@@ -314,6 +317,7 @@ public final class ApduServiceInfo implements Parcelable {
mStaticAidGroups = new HashMap<String, AidGroup>();
mDynamicAidGroups = new HashMap<String, AidGroup>();
mAutoTransact = new HashMap<String, Boolean>();
+ mAutoTransactPatterns = new HashMap<Pattern, Boolean>();
mOnHost = onHost;
final int depth = parser.getDepth();
@@ -408,6 +412,18 @@ public final class ApduServiceInfo implements Parcelable {
false);
mAutoTransact.put(plf, autoTransact);
a.recycle();
+ } else if (eventType == XmlPullParser.START_TAG
+ && "polling-loop-pattern-filter".equals(tagName) && currentGroup == null) {
+ final TypedArray a = res.obtainAttributes(attrs,
+ com.android.internal.R.styleable.PollingLoopPatternFilter);
+ String plf = a.getString(
+ com.android.internal.R.styleable.PollingLoopPatternFilter_name)
+ .toUpperCase(Locale.ROOT);
+ boolean autoTransact = a.getBoolean(
+ com.android.internal.R.styleable.PollingLoopFilter_autoTransact,
+ false);
+ mAutoTransactPatterns.put(Pattern.compile(plf), autoTransact);
+ a.recycle();
}
}
} catch (NameNotFoundException e) {
@@ -481,7 +497,30 @@ public final class ApduServiceInfo implements Parcelable {
*/
@FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP)
public boolean getShouldAutoTransact(@NonNull String plf) {
- return mAutoTransact.getOrDefault(plf.toUpperCase(Locale.ROOT), false);
+ if (mAutoTransact.getOrDefault(plf.toUpperCase(Locale.ROOT), false)) {
+ return true;
+ }
+ List<Pattern> patternMatches = mAutoTransactPatterns.keySet().stream()
+ .filter(p -> p.matcher(plf).matches()).toList();
+ if (patternMatches == null || patternMatches.size() == 0) {
+ return false;
+ }
+ for (Pattern patternMatch : patternMatches) {
+ if (mAutoTransactPatterns.get(patternMatch)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns the current polling loop pattern filters for this service.
+ * @return List of polling loop pattern filters.
+ */
+ @FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP)
+ @NonNull
+ public List<Pattern> getPollingLoopPatternFilters() {
+ return new ArrayList<>(mAutoTransactPatterns.keySet());
}
/**
@@ -683,7 +722,7 @@ public final class ApduServiceInfo implements Parcelable {
* Add a Polling Loop Filter. Custom NFC polling frames that match this filter will be
* delivered to {@link HostApduService#processPollingFrames(List)}. Adding a key with this
* multiple times will cause the value to be overwritten each time.
- * @param pollingLoopFilter the polling loop filter to add, must be a valide hexadecimal string
+ * @param pollingLoopFilter the polling loop filter to add, must be a valid hexadecimal string
*/
@FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP)
public void addPollingLoopFilter(@NonNull String pollingLoopFilter,
@@ -703,6 +742,31 @@ public final class ApduServiceInfo implements Parcelable {
}
/**
+ * Add a Polling Loop Pattern Filter. Custom NFC polling frames that match this filter will be
+ * delivered to {@link HostApduService#processPollingFrames(List)}. Adding a key with this
+ * multiple times will cause the value to be overwritten each time.
+ * @param pollingLoopPatternFilter the polling loop pattern filter to add, must be a valid
+ * regex to match a hexadecimal string
+ */
+ @FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP)
+ public void addPollingLoopPatternFilter(@NonNull String pollingLoopPatternFilter,
+ boolean autoTransact) {
+ mAutoTransactPatterns.put(Pattern.compile(pollingLoopPatternFilter), autoTransact);
+
+ }
+
+ /**
+ * Remove a Polling Loop Pattern Filter. Custom NFC polling frames that match this filter will
+ * no longer be delivered to {@link HostApduService#processPollingFrames(List)}.
+ * @param pollingLoopPatternFilter this polling loop filter to add.
+ */
+ @FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP)
+ public void removePollingLoopPatternFilter(@NonNull String pollingLoopPatternFilter) {
+ mAutoTransactPatterns.remove(
+ Pattern.compile(pollingLoopPatternFilter.toUpperCase(Locale.ROOT)));
+ }
+
+ /**
* Sets the off host Secure Element.
* @param offHost Secure Element to set. Only accept strings with prefix SIM or prefix eSE.
* Ref: GSMA TS.26 - NFC Handset Requirements
@@ -856,6 +920,8 @@ public final class ApduServiceInfo implements Parcelable {
dest.writeInt(mCategoryOtherServiceEnabled ? 1 : 0);
dest.writeInt(mAutoTransact.size());
dest.writeMap(mAutoTransact);
+ dest.writeInt(mAutoTransactPatterns.size());
+ dest.writeMap(mAutoTransactPatterns);
};
@FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
@@ -889,10 +955,15 @@ public final class ApduServiceInfo implements Parcelable {
new HashMap<String, Boolean>(autoTransactSize);
source.readMap(autoTransact, getClass().getClassLoader(),
String.class, Boolean.class);
+ int autoTransactPatternSize = source.readInt();
+ HashMap<Pattern, Boolean> autoTransactPatterns =
+ new HashMap<Pattern, Boolean>(autoTransactSize);
+ source.readMap(autoTransactPatterns, getClass().getClassLoader(),
+ Pattern.class, Boolean.class);
return new ApduServiceInfo(info, onHost, description, staticAidGroups,
dynamicAidGroups, requiresUnlock, requiresScreenOn, bannerResource, uid,
settingsActivityName, offHostName, staticOffHostName,
- isEnabled, autoTransact);
+ isEnabled, autoTransact, autoTransactPatterns);
}
@Override
diff --git a/nfc/java/android/nfc/cardemulation/CardEmulation.java b/nfc/java/android/nfc/cardemulation/CardEmulation.java
index e55f5403ed83..67697a429a32 100644
--- a/nfc/java/android/nfc/cardemulation/CardEmulation.java
+++ b/nfc/java/android/nfc/cardemulation/CardEmulation.java
@@ -45,6 +45,7 @@ import android.util.Log;
import java.util.HashMap;
import java.util.HexFormat;
import java.util.List;
+import java.util.Locale;
import java.util.regex.Pattern;
/**
@@ -61,6 +62,7 @@ import java.util.regex.Pattern;
*/
public final class CardEmulation {
private static final Pattern AID_PATTERN = Pattern.compile("[0-9A-Fa-f]{10,32}\\*?\\#?");
+ private static final Pattern PLPF_PATTERN = Pattern.compile("[0-9A-Fa-f,\\?,\\*\\.]*");
static final String TAG = "CardEmulation";
@@ -379,9 +381,9 @@ public final class CardEmulation {
* auto-transact or not. The PLF can be sequence of an
* even number of at least 2 hexadecimal numbers (0-9, A-F or a-f), representing a series of
* bytes. When non-standard polling loop frame matches this sequence exactly, it may be
- * delivered to {@link HostApduService#processPollingFrames(List)}. If auto-transact is set to
- * true, then observe mode will also be disabled. if this service is currently preferred or
- * there are no other services registered for this filter.
+ * delivered to {@link HostApduService#processPollingFrames(List)}. If auto-transact
+ * is set to true and this service is currently preferred or there are no other services
+ * registered for this filter then observe mode will also be disabled.
* @param service The HostApduService to register the filter for
* @param pollingLoopFilter The filter to register
* @param autoTransact true to have the NFC stack automatically disable observe mode and allow
@@ -416,6 +418,128 @@ public final class CardEmulation {
}
/**
+ * Unregister a polling loop filter (PLF) for a HostApduService. If the PLF had previously been
+ * registered via {@link #registerPollingLoopFilterForService(ComponentName, String, boolean)}
+ * for this service it will be removed.
+ * @param service The HostApduService to unregister the filter for
+ * @param pollingLoopFilter The filter to unregister
+ * @return true if the filter was removed, false otherwise
+ * @throws IllegalArgumentException if the passed in string doesn't parse to at least one byte
+ */
+ @FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP)
+ public boolean removePollingLoopFilterForService(@NonNull ComponentName service,
+ @NonNull String pollingLoopFilter) {
+ pollingLoopFilter = validatePollingLoopFilter(pollingLoopFilter);
+
+ try {
+ return sService.removePollingLoopFilterForService(mContext.getUser().getIdentifier(),
+ service, pollingLoopFilter);
+ } catch (RemoteException e) {
+ // Try one more time
+ recoverService();
+ if (sService == null) {
+ Log.e(TAG, "Failed to recover CardEmulationService.");
+ return false;
+ }
+ try {
+ return sService.removePollingLoopFilterForService(
+ mContext.getUser().getIdentifier(), service,
+ pollingLoopFilter);
+ } catch (RemoteException ee) {
+ Log.e(TAG, "Failed to reach CardEmulationService.");
+ return false;
+ }
+ }
+ }
+
+
+ /**
+ * Register a polling loop pattern filter (PLPF) for a HostApduService and indicate whether it
+ * should auto-transact or not. The pattern may include the characters 0-9 and A-F as well as
+ * the regular expression operators `.`, `?` and `*`. When the beginning of anon-standard
+ * polling loop frame matches this sequence exactly, it may be delivered to
+ * {@link HostApduService#processPollingFrames(List)}. If auto-transact is set to true and this
+ * service is currently preferred or there are no other services registered for this filter
+ * then observe mode will also be disabled.
+ * @param service The HostApduService to register the filter for
+ * @param pollingLoopPatternFilter The pattern filter to register, must to be compatible with
+ * {@link java.util.regex.Pattern#compile(String)} and only contain hexadecimal numbers
+ * and `.`, `?` and `*` operators
+ * @param autoTransact true to have the NFC stack automatically disable observe mode and allow
+ * transactions to proceed when this filter matches, false otherwise
+ * @return true if the filter was registered, false otherwise
+ * @throws IllegalArgumentException if the filter containst elements other than hexadecimal
+ * numbers and `.`, `?` and `*` operators
+ * @throws java.util.regex.PatternSyntaxException if the regex syntax is invalid
+ */
+ @FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP)
+ public boolean registerPollingLoopPatternFilterForService(@NonNull ComponentName service,
+ @NonNull String pollingLoopPatternFilter, boolean autoTransact) {
+ pollingLoopPatternFilter = validatePollingLoopPatternFilter(pollingLoopPatternFilter);
+
+ try {
+ return sService.registerPollingLoopPatternFilterForService(
+ mContext.getUser().getIdentifier(),
+ service, pollingLoopPatternFilter, autoTransact);
+ } catch (RemoteException e) {
+ // Try one more time
+ recoverService();
+ if (sService == null) {
+ Log.e(TAG, "Failed to recover CardEmulationService.");
+ return false;
+ }
+ try {
+ return sService.registerPollingLoopPatternFilterForService(
+ mContext.getUser().getIdentifier(), service,
+ pollingLoopPatternFilter, autoTransact);
+ } catch (RemoteException ee) {
+ Log.e(TAG, "Failed to reach CardEmulationService.");
+ return false;
+ }
+ }
+ }
+
+ /**
+ * Unregister a polling loop pattern filter (PLPF) for a HostApduService. If the PLF had
+ * previously been registered via
+ * {@link #registerPollingLoopFilterForService(ComponentName, String, boolean)} for this
+ * service it will be removed.
+ * @param service The HostApduService to unregister the filter for
+ * @param pollingLoopPatternFilter The filter to unregister, must to be compatible with
+ * {@link java.util.regex.Pattern#compile(String)} and only contain hexadecimal numbers
+ * and`.`, `?` and `*` operators
+ * @return true if the filter was removed, false otherwise
+ * @throws IllegalArgumentException if the filter containst elements other than hexadecimal
+ * numbers and `.`, `?` and `*` operators
+ * @throws java.util.regex.PatternSyntaxException if the regex syntax is invalid
+ */
+ @FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP)
+ public boolean removePollingLoopPatternFilterForService(@NonNull ComponentName service,
+ @NonNull String pollingLoopPatternFilter) {
+ pollingLoopPatternFilter = validatePollingLoopPatternFilter(pollingLoopPatternFilter);
+
+ try {
+ return sService.removePollingLoopPatternFilterForService(
+ mContext.getUser().getIdentifier(), service, pollingLoopPatternFilter);
+ } catch (RemoteException e) {
+ // Try one more time
+ recoverService();
+ if (sService == null) {
+ Log.e(TAG, "Failed to recover CardEmulationService.");
+ return false;
+ }
+ try {
+ return sService.removePollingLoopPatternFilterForService(
+ mContext.getUser().getIdentifier(), service,
+ pollingLoopPatternFilter);
+ } catch (RemoteException ee) {
+ Log.e(TAG, "Failed to reach CardEmulationService.");
+ return false;
+ }
+ }
+ }
+
+ /**
* Registers a list of AIDs for a specific category for the
* specified service.
*
@@ -1027,6 +1151,23 @@ public final class CardEmulation {
}
/**
+ * Tests the validity of the polling loop pattern filter.
+ * @param pollingLoopPatternFilter The polling loop filter to test.
+ *
+ * @hide
+ */
+ @FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP)
+ public static @NonNull String validatePollingLoopPatternFilter(
+ @NonNull String pollingLoopPatternFilter) {
+ // Verify hex characters
+ if (!PLPF_PATTERN.matcher(pollingLoopPatternFilter).matches()) {
+ throw new IllegalArgumentException(
+ "Polling loop pattern filters may only contain hexadecimal numbers, ?s and *s");
+ }
+ return Pattern.compile(pollingLoopPatternFilter.toUpperCase(Locale.ROOT)).toString();
+ }
+
+ /**
* A valid AID according to ISO/IEC 7816-4:
* <ul>
* <li>Has >= 5 bytes and <=16 bytes (>=10 hex chars and <= 32 hex chars)
diff --git a/packages/CompanionDeviceManager/res/values-af/strings.xml b/packages/CompanionDeviceManager/res/values-af/strings.xml
index 1f39509d4aad..94d9aaa67f20 100644
--- a/packages/CompanionDeviceManager/res/values-af/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-af/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"toestel"</string>
<string name="summary_glasses" msgid="2872254734959842579">"Hierdie app sal toegang tot hierdie toestemmings op jou <xliff:g id="DEVICE_NAME">%1$s</xliff:g> hê"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Gee &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; toegang tot hierdie inligting op jou foon"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Oorkruistoestel-dienste"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> versoek tans namens jou <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> toestemming om apps tussen jou toestelle te stroom"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Gee &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; toegang tot hierdie inligting op jou foon"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play Dienste"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> versoek tans namens jou <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> toegang tot jou foon se foto’s, media en kennisgewings"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"Laat &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; toe om hierdie handeling uit te voer?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> versoek tans namens jou <xliff:g id="DEVICE_NAME">%2$s</xliff:g> toestemming om apps en ander stelselkenmerke na toestelle in die omtrek te stroom"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"toestel"</string>
<string name="summary_generic" msgid="1761976003668044801">"Hierdie app sal inligting kan sinkroniseer, soos die naam van iemand wat bel, tussen jou foon en die gekose toestel"</string>
diff --git a/packages/CompanionDeviceManager/res/values-am/strings.xml b/packages/CompanionDeviceManager/res/values-am/strings.xml
index 007173cb8fad..b53ac7467367 100644
--- a/packages/CompanionDeviceManager/res/values-am/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-am/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"መሣሪያ"</string>
<string name="summary_glasses" msgid="2872254734959842579">"ይህ መተግበሪያ በእርስዎ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ላይ እነዚህን ፈቃዶች እንዲደርስ ይፈቀድለታል"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ይህን መረጃ ከስልክዎ እንዲደርስበት ይፍቀዱለት"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"መሣሪያ ተሻጋሪ አገልግሎቶች"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> በእርስዎ መሣሪያዎች መካከል መተግበሪያዎችን በዥረት ለመልቀቅ የእርስዎን <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> ወክሎ ፈቃድ እየጠየቀ ነው"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ይህን መረጃ ከስልክዎ ላይ እንዲደርስ ይፍቀዱለት"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"የGoogle Play አገልግሎቶች"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> የስልክዎን ፎቶዎች፣ ሚዲያ እና ማሳወቂያዎች ለመድረስ የእርስዎን <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> ወክሎ ፈቃድ እየጠየቀ ነው"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; ይህን እርምጃ እንዲወስድ ፈቃድ ይሰጠው?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> የእርስዎን <xliff:g id="DEVICE_NAME">%2$s</xliff:g> በመወከል በአቅራቢያ ላሉ መሣሪያዎች መተግበሪያዎች እና ሌሎች የስርዓት ባህሪያትን በዥረት ለመልቀቅ ፈቃድ እየጠየቀ ነው"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"መሣሪያ"</string>
<string name="summary_generic" msgid="1761976003668044801">"ይህ መተግበሪያ እንደ የሚደውል ሰው ስም ያለ መረጃን በስልክዎ እና በተመረጠው መሣሪያ መካከል ማስመር ይችላል"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ar/strings.xml b/packages/CompanionDeviceManager/res/values-ar/strings.xml
index 961c63bd2b11..a1e09b26afd0 100644
--- a/packages/CompanionDeviceManager/res/values-ar/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ar/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"جهاز"</string>
<string name="summary_glasses" msgid="2872254734959842579">"سيتم السماح لهذا التطبيق بالوصول إلى هذه الأذونات على \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\"."</string>
<string name="title_app_streaming" msgid="2270331024626446950">"‏السماح لتطبيق &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; بالوصول إلى هذه المعلومات من هاتفك"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"الخدمات التي تعمل بين الأجهزة"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"يطلب تطبيق \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" الحصول على إذن نيابةً عن \"<xliff:g id="DISPLAY_NAME">%2$s</xliff:g>\" لبثّ محتوى التطبيقات بين أجهزتك."</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"‏السماح لتطبيق &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; بالوصول إلى هذه المعلومات من هاتفك"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"‏خدمات Google Play"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"يطلب تطبيق \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" الحصول على إذن نيابةً عن \"<xliff:g id="DISPLAY_NAME">%2$s</xliff:g>\" للوصول إلى الصور والوسائط والإشعارات في هاتفك."</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"‏هل تريد السماح للتطبيق &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; باتّخاذ هذا الإجراء؟"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"يطلب \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" الحصول على إذن نيابةً عن \"<xliff:g id="DEVICE_NAME">%2$s</xliff:g>\" لبثّ التطبيقات وميزات النظام الأخرى إلى أجهزتك المجاورة."</string>
<string name="profile_name_generic" msgid="6851028682723034988">"جهاز"</string>
<string name="summary_generic" msgid="1761976003668044801">"سيتمكّن هذا التطبيق من مزامنة المعلومات، مثل اسم المتصل، بين هاتفك والجهاز المحدّد."</string>
diff --git a/packages/CompanionDeviceManager/res/values-as/strings.xml b/packages/CompanionDeviceManager/res/values-as/strings.xml
index 623b2121e39a..481ce24879ca 100644
--- a/packages/CompanionDeviceManager/res/values-as/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-as/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"ডিভাইচ"</string>
<string name="summary_glasses" msgid="2872254734959842579">"এই এপ্‌টোক আপোনাৰ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>ত এই অনুমতিসমূহ এক্সেছ কৰিবলৈ অনুমতি দিয়া হ’ব"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;ক আপোনাৰ ফ’নৰ পৰা এই তথ্যখিনি এক্সেছ কৰাৰ অনুমতি দিয়ক"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"ক্ৰছ-ডিভাইচ সেৱাসমূহ"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g>এ আপোনাৰ <xliff:g id="DISPLAY_NAME">%2$s</xliff:g>ৰ হৈ আপোনাৰ ডিভাইচসমূহৰ মাজত এপ্‌ ষ্ট্ৰীম কৰাৰ বাবে অনুৰোধ জনাইছে"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;ক আপোনাৰ ফ’নৰ পৰা এই তথ্যখিনি এক্সেছ কৰাৰ অনুমতি দিয়ক"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play সেৱা"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g>এ আপোনাৰ <xliff:g id="DISPLAY_NAME">%2$s</xliff:g>ৰ হৈ আপোনাৰ ফ’নৰ ফট’, মিডিয়া আৰু জাননী এক্সেছ কৰাৰ বাবে অনুৰোধ জনাইছে"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt;ক এই কাৰ্যটো সম্পাদন কৰিবলৈ দিবনে?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g>এ আপোনাৰ <xliff:g id="DEVICE_NAME">%2$s</xliff:g>ৰ হৈ নিকটৱৰ্তী ডিভাইচত এপ্‌ আৰু ছিষ্টেমৰ অন্য সুবিধাসমূহ ষ্ট্ৰীম কৰাৰ অনুমতি দিবলৈ অনুৰোধ জনাইছে"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"ডিভাইচ"</string>
<string name="summary_generic" msgid="1761976003668044801">"এই এপ্‌টোৱে আপোনাৰ ফ’ন আৰু বাছনি কৰা ডিভাইচটোৰ মাজত কল কৰোঁতাৰ নামৰ দৰে তথ্য ছিংক কৰিব পাৰিব"</string>
diff --git a/packages/CompanionDeviceManager/res/values-az/strings.xml b/packages/CompanionDeviceManager/res/values-az/strings.xml
index 65f3a62cdb57..4e71b8c58f0c 100644
--- a/packages/CompanionDeviceManager/res/values-az/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-az/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"cihazda"</string>
<string name="summary_glasses" msgid="2872254734959842579">"Bu tətbiq <xliff:g id="DEVICE_NAME">%1$s</xliff:g> bu icazələrə daxil ola biləcək"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; tətbiqinə telefonunuzdan bu məlumata giriş icazəsi verin"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Cihazlararası xidmətlər"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> adından cihazlar arasında tətbiqləri yayımlamaq icazəsi istəyir"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; tətbiqinə telefonunuzdan bu məlumata giriş icazəsi verin"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play xidmətləri"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> adından telefonun foto, media və bildirişlərinə giriş icazəsi istəyir"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; cihazına bu əməliyyatı yerinə yetirmək icazəsi verilsin?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="DEVICE_NAME">%2$s</xliff:g> adından tətbiq və digər sistem funksiyalarını yaxınlıqdakı cihazlara yayımlamaq icazəsi sitəyir"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"cihaz"</string>
<string name="summary_generic" msgid="1761976003668044801">"Tətbiq zəng edənin adı kimi məlumatları telefon ilə seçilmiş cihaz arasında sinxronlaşdıracaq"</string>
diff --git a/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml b/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml
index 314d9ffe43b4..6504ab424e20 100644
--- a/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"uređaj"</string>
<string name="summary_glasses" msgid="2872254734959842579">"Ovoj aplikaciji će biti dozvoljeno da pristupa ovim dozvolama na vašem uređaju (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>)"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Dozvolite da &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; pristupa ovim informacijama sa telefona"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Usluge na više uređaja"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> zahteva dozvolu u ime uređaja <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> za strimovanje aplikacija između uređaja"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Dozvolite da &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; pristupa ovim informacijama sa telefona"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play usluge"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> zahteva dozvolu u ime uređaja <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> za pristup slikama, medijskom sadržaju i obaveštenjima sa telefona"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"Želite li da dozvolite da &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; obavi ovu radnju?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> zahteva dozvolu u ime uređaja <xliff:g id="DEVICE_NAME">%2$s</xliff:g> da strimuje aplikacije i druge sistemske funkcije na uređaje u blizini"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"uređaj"</string>
<string name="summary_generic" msgid="1761976003668044801">"Ova aplikacija će moći da sinhronizuje podatke, poput imena osobe koja upućuje poziv, između telefona i odabranog uređaja"</string>
diff --git a/packages/CompanionDeviceManager/res/values-be/strings.xml b/packages/CompanionDeviceManager/res/values-be/strings.xml
index fc17899768c9..fcc587a5787b 100644
--- a/packages/CompanionDeviceManager/res/values-be/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-be/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"прылада"</string>
<string name="summary_glasses" msgid="2872254734959842579">"Гэтая праграма будзе мець на вашай прыладзе \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\" наступныя дазволы"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Дазвольце праграме &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; мець доступ да гэтай інфармацыі з вашага тэлефона"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Сэрвісы для некалькіх прылад"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"Праграма \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" запытвае дазвол ад імя вашай прылады \"<xliff:g id="DISPLAY_NAME">%2$s</xliff:g>\" на трансляцыю праграм паміж вашымі прыладамі"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Дазвольце праграме &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; мець доступ да гэтай інфармацыі з вашага тэлефона"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Сэрвісы Google Play"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"Праграма \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" запытвае дазвол ад імя вашай прылады \"<xliff:g id="DISPLAY_NAME">%2$s</xliff:g>\" на доступ да фота, медыяфайлаў і апавяшчэнняў на вашым тэлефоне"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"Дазволіць прыладзе &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; выканаць гэта дзеянне?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"Праграма \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" запытвае дазвол ад імя вашай прылады \"<xliff:g id="DEVICE_NAME">%2$s</xliff:g>\" на перадачу плынню змесціва праграм і іншых функцый сістэмы на прылады паблізу"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"прылада"</string>
<string name="summary_generic" msgid="1761976003668044801">"Гэта праграма зможа сінхранізаваць інфармацыю (напрыклад, імя таго, хто звоніць) паміж тэлефонам і выбранай прыладай"</string>
diff --git a/packages/CompanionDeviceManager/res/values-bg/strings.xml b/packages/CompanionDeviceManager/res/values-bg/strings.xml
index c9f85dd2ec6b..4fb9ceed1c6c 100644
--- a/packages/CompanionDeviceManager/res/values-bg/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-bg/strings.xml
@@ -26,8 +26,11 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"устройство"</string>
<string name="summary_glasses" msgid="2872254734959842579">"Това приложение ще има достъп до следните разрешения за вашето <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Разрешете на &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; да осъществява достъп до тази информация от телефона ви"</string>
+ <string name="title_app_streaming_with_mirroring" msgid="3364582597581570658">"Да се разреши ли на &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; да предава поточно приложенията на телефона ви?"</string>
+ <string name="summary_app_streaming" msgid="295548145144086753">"%1$s ще има достъп до всичко, което се показва или възпроизвежда на телефона, включително аудиосъдържание, снимки, пароли и съобщения.&lt;br/&gt;&lt;br/&gt;%1$s ще може да предава поточно приложения, докато не премахнете това разрешение."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Услуги за различни устройства"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> иска разрешение от името на <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> да предава поточно приложения между устройствата ви"</string>
+ <string name="helper_summary_app_streaming_with_mirroring" msgid="6138581029144467467">"<xliff:g id="APP_NAME">%1$s</xliff:g> иска разрешение от името на <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> да показва и да предава поточно приложения между устройствата ви"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Разрешете на &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; да осъществява достъп до тази информация от телефона ви"</string>
@@ -35,6 +38,8 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Услуги за Google Play"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> иска разрешение от името на <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> за достъп до снимките, мултимедията и известията на телефона ви"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"Разрешавате ли на &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; да предприема това действие?"</string>
+ <string name="title_nearby_device_streaming_with_mirroring" msgid="242855799919611657">"Да се разреши ли на &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; да предава поточно приложенията и системните функции на телефона ви?"</string>
+ <string name="summary_nearby_device_streaming" msgid="4039565463149145573">"%1$s ще има достъп до всичко, което се показва или възпроизвежда на телефона, включително аудиосъдържание, снимки, данни за плащане, пароли и съобщения.&lt;br/&gt;&lt;br/&gt;%1$s ще може да предава поточно приложения и системни функции, докато не премахнете това разрешение."</string>
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> иска разрешение от името на <xliff:g id="DEVICE_NAME">%2$s</xliff:g> да предава поточно приложения и други системни функции към устройства в близост"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"устройство"</string>
<string name="summary_generic" msgid="1761976003668044801">"Това приложение ще може да синхронизира различна информация, като например името на обаждащия се, между телефона ви и избраното устройство"</string>
diff --git a/packages/CompanionDeviceManager/res/values-bn/strings.xml b/packages/CompanionDeviceManager/res/values-bn/strings.xml
index c3ceda07b211..30447cef4bdb 100644
--- a/packages/CompanionDeviceManager/res/values-bn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-bn/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"ডিভাইস"</string>
<string name="summary_glasses" msgid="2872254734959842579">"এই অ্যাপ আপনার <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-এ এইসব অনুমতি অ্যাক্সেস করতে পারবে"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"আপনার ফোন থেকে &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; অ্যাপকে এই তথ্য অ্যাক্সেস করার অনুমতি দিন"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"ক্রস-ডিভাইস পরিষেবা"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"আপনার ডিভাইসগুলির মধ্যে অ্যাপ স্ট্রিম করার জন্য <xliff:g id="APP_NAME">%1$s</xliff:g>, <xliff:g id="DISPLAY_NAME">%2$s</xliff:g>-এর হয়ে অনুমতি চাইছে"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"আপনার ফোন থেকে &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;-কে এই তথ্য অ্যাক্সেস করার অনুমতি দিন"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play পরিষেবা"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"আপনার ফোনের ফটো, মিডিয়া এবং তথ্য অ্যাক্সেস করার জন্য <xliff:g id="APP_NAME">%1$s</xliff:g>, <xliff:g id="DISPLAY_NAME">%2$s</xliff:g>-এর হয়ে অনুমতি চাইছে"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt;-কে এই কাজটি করতে দেবেন?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"আশেপাশের ডিভাইসে অ্যাপ ও অন্যান্য সিস্টেম ফিচার স্ট্রিম করার জন্য আপনার <xliff:g id="DEVICE_NAME">%2$s</xliff:g>-এর হয়ে <xliff:g id="APP_NAME">%1$s</xliff:g> অনুমতি চেয়ে অনুরোধ করছে"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"ডিভাইস"</string>
<string name="summary_generic" msgid="1761976003668044801">"এই অ্যাপ, আপনার ফোন এবং বেছে নেওয়া ডিভাইসের মধ্যে তথ্য সিঙ্ক করতে পারবে, যেমন কোনও কলারের নাম"</string>
diff --git a/packages/CompanionDeviceManager/res/values-bs/strings.xml b/packages/CompanionDeviceManager/res/values-bs/strings.xml
index 259a06a245d7..87c5349bb01c 100644
--- a/packages/CompanionDeviceManager/res/values-bs/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-bs/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"uređaj"</string>
<string name="summary_glasses" msgid="2872254734959842579">"Aplikaciji će biti dozvoljen pristup ovim odobrenjima na uređaju <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Dozvolite da aplikacija &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; pristupa ovim informacijama s telefona"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Usluga na više uređaja"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> u ime uređaja <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> zahtijeva odobrenje da prenosi aplikacije između vaših uređaja"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Dozvolite aplikaciji &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; da pristupa ovim informacijama s vašeg telefona"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play usluge"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> u ime uređaja <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> zahtijeva odobrenje da pristupi fotografijama, medijima i obavještenjima na telefonu"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"Dozvoliti uređaju &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; da poduzme ovu radnju?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> u ime uređaja <xliff:g id="DEVICE_NAME">%2$s</xliff:g> traži odobrenje da prenosi aplikacije i druge funkcije sistema na uređajima u blizini"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"uređaj"</string>
<string name="summary_generic" msgid="1761976003668044801">"Ova aplikacija će moći sinhronizirati informacije, kao što je ime osobe koja upućuje poziv, između vašeg telefona i odabranog uređaja"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ca/strings.xml b/packages/CompanionDeviceManager/res/values-ca/strings.xml
index 62fe858559b0..40c6aac7daf5 100644
--- a/packages/CompanionDeviceManager/res/values-ca/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ca/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"dispositiu"</string>
<string name="summary_glasses" msgid="2872254734959842579">"Aquesta aplicació podrà accedir a aquests permisos del dispositiu (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>)"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Permet que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; accedeixi a aquesta informació del telèfon"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Serveis multidispositiu"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> demana permís en nom del teu dispositiu (<xliff:g id="DISPLAY_NAME">%2$s</xliff:g>) per reproduir en continu aplicacions entre els dispositius"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Permet que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; accedeixi a aquesta informació del telèfon"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Serveis de Google Play"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> demana permís en nom del teu dispositiu (<xliff:g id="DISPLAY_NAME">%2$s</xliff:g>) per accedir a les fotos, el contingut multimèdia i les notificacions del telèfon"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"Vols permetre que &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; dugui a terme aquesta acció?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> sol·licita permís en nom del teu dispositiu (<xliff:g id="DEVICE_NAME">%2$s</xliff:g>) per reproduir en continu aplicacions i altres funcions del sistema en dispositius propers"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"dispositiu"</string>
<string name="summary_generic" msgid="1761976003668044801">"Aquesta aplicació podrà sincronitzar informació, com ara el nom d\'algú que truca, entre el teu telèfon i el dispositiu triat"</string>
diff --git a/packages/CompanionDeviceManager/res/values-cs/strings.xml b/packages/CompanionDeviceManager/res/values-cs/strings.xml
index 76c0a4a774e7..7d7d74f73eb5 100644
--- a/packages/CompanionDeviceManager/res/values-cs/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-cs/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"zařízení"</string>
<string name="summary_glasses" msgid="2872254734959842579">"Tato aplikace bude mít ve vašem <xliff:g id="DEVICE_NAME">%1$s</xliff:g> povolený přístup k těmto oprávněním"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Povolte aplikaci &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; přístup k těmto informacím z vašeho telefonu"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Služby pro více zařízení"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"Aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> požaduje za vaše zařízení <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> oprávnění ke streamování aplikací mezi zařízeními"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Povolte aplikaci &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; přístup k těmto informacím z vašeho telefonu"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Služby Google Play"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"Aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> požaduje za vaše zařízení <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> oprávnění k přístupu k fotkám, médiím a oznámením v telefonu"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"Povolit zařízení &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; podniknout tuto akci?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"Aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> žádá jménem vašeho zařízení <xliff:g id="DEVICE_NAME">%2$s</xliff:g> o oprávnění streamovat aplikace a další systémové funkce do zařízení v okolí"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"zařízení"</string>
<string name="summary_generic" msgid="1761976003668044801">"Tato aplikace bude moci synchronizovat údaje, jako je jméno volajícího, mezi vaším telefonem a vybraným zařízením"</string>
diff --git a/packages/CompanionDeviceManager/res/values-da/strings.xml b/packages/CompanionDeviceManager/res/values-da/strings.xml
index f765c83b28ff..c4fa73a9392d 100644
--- a/packages/CompanionDeviceManager/res/values-da/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-da/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"enhed"</string>
<string name="summary_glasses" msgid="2872254734959842579">"Denne app får adgang til disse tilladelser på din <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Giv &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; adgang til disse oplysninger fra din telefon"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Tjenester, som kan tilsluttes en anden enhed"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> anmoder om tilladelse på vegne af din <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> til at streame apps mellem dine enheder"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Tillad, at &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; får adgang til disse oplysninger fra din telefon"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play-tjenester"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> anmoder om tilladelse på vegne af din <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> til at få adgang til din telefons billeder, medier og notifikationer"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"Vil du tillade, at &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; foretager denne handling?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> anmoder om tilladelse på vegne af din <xliff:g id="DEVICE_NAME">%2$s</xliff:g> til at streame apps og andre systemfunktioner til enheder i nærheden"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"enhed"</string>
<string name="summary_generic" msgid="1761976003668044801">"Denne app vil kunne synkronisere oplysninger som f.eks. navnet på en person, der ringer, mellem din telefon og den valgte enhed"</string>
diff --git a/packages/CompanionDeviceManager/res/values-de/strings.xml b/packages/CompanionDeviceManager/res/values-de/strings.xml
index 61c9b64071e1..d435829d59bb 100644
--- a/packages/CompanionDeviceManager/res/values-de/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-de/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"Gerät"</string>
<string name="summary_glasses" msgid="2872254734959842579">"Diese App darf dann auf diese Berechtigungen auf deinem <xliff:g id="DEVICE_NAME">%1$s</xliff:g> zugreifen:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; Zugriff auf diese Informationen von deinem Smartphone gewähren"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Geräteübergreifende Dienste"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> bittet für dein <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> um die Berechtigung zum Streamen von Apps zwischen deinen Geräten"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; Zugriff auf diese Informationen von deinem Smartphone gewähren"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play-Dienste"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> bittet im Namen deines <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> um die Berechtigung zum Zugriff auf die Fotos, Medien und Benachrichtigungen deines Smartphones"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"Darf das Gerät &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; diese Aktion ausführen?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> bittet für dein Gerät (<xliff:g id="DEVICE_NAME">%2$s</xliff:g>) um die Berechtigung, Apps und andere Systemfunktionen auf Geräte in der Nähe zu streamen"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"Gerät"</string>
<string name="summary_generic" msgid="1761976003668044801">"Diese App kann dann Daten wie den Namen eines Anrufers zwischen deinem Smartphone und dem ausgewählten Gerät synchronisieren"</string>
diff --git a/packages/CompanionDeviceManager/res/values-el/strings.xml b/packages/CompanionDeviceManager/res/values-el/strings.xml
index a95d06351427..2fbe35376732 100644
--- a/packages/CompanionDeviceManager/res/values-el/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-el/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"συσκευή"</string>
<string name="summary_glasses" msgid="2872254734959842579">"Αυτή η εφαρμογή θα μπορεί να έχει πρόσβαση σε αυτές τις άδειες στη συσκευή <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Να επιτρέπεται στο &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; η πρόσβαση σε αυτές τις πληροφορίες από το τηλέφωνό σας."</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Υπηρεσίες πολλών συσκευών"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> ζητά εκ μέρους της συσκευής σας <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> άδεια για ροή εφαρμογών μεταξύ των συσκευών σας"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Επιτρέψτε στην εφαρμογή &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; να έχει πρόσβαση σε αυτές τις πληροφορίες από το τηλέφωνό σας"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Υπηρεσίες Google Play"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> ζητά εκ μέρους της συσκευής σας <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> άδεια για πρόσβαση στις φωτογραφίες, τα αρχεία μέσων και τις ειδοποιήσεις του τηλεφώνου σας"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"Να επιτρέπεται στη συσκευή &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; να εκτελεί αυτή την ενέργεια;"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> ζητά άδεια εκ μέρους της συσκευής σας <xliff:g id="DEVICE_NAME">%2$s</xliff:g> για ροή εφαρμογών και άλλων λειτουργιών του συστήματος σε συσκευές σε κοντινή απόσταση"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"συσκευή"</string>
<string name="summary_generic" msgid="1761976003668044801">"Αυτή η εφαρμογή θα μπορεί να συγχρονίζει πληροφορίες μεταξύ του τηλεφώνου και της επιλεγμένης συσκευής σας, όπως το όνομα ενός ατόμου που σας καλεί."</string>
diff --git a/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml b/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml
index 8b506ed20963..ee8eca0e24e3 100644
--- a/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"device"</string>
<string name="summary_glasses" msgid="2872254734959842579">"This app will be allowed to access these permissions on your <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Allow &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to access this information from your phone"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Cross-device services"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> to stream apps between your devices"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Allow &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to access this information from your phone"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play services"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> to access your phone’s photos, media and notifications"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"Allow &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; to take this action?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_NAME">%2$s</xliff:g> to stream apps and other system features to nearby devices"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"device"</string>
<string name="summary_generic" msgid="1761976003668044801">"This app will be able to sync info, like the name of someone calling, between your phone and the chosen device"</string>
diff --git a/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml b/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml
index 4f463f692c37..0160609b3b44 100644
--- a/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml
@@ -26,8 +26,11 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"device"</string>
<string name="summary_glasses" msgid="2872254734959842579">"This app will be allowed to access these permissions on your <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Allow &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to access this information from your phone"</string>
+ <string name="title_app_streaming_with_mirroring" msgid="3364582597581570658">"Allow &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to stream your phone’s apps?"</string>
+ <string name="summary_app_streaming" msgid="295548145144086753">"%1$s will have access to anything that’s visible or played on the phone, including audio, photos, passwords, and messages.&lt;br/&gt;&lt;br/&gt;%1$s will be able to stream apps until you remove access to this permission."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Cross-device services"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> to stream apps between your devices"</string>
+ <string name="helper_summary_app_streaming_with_mirroring" msgid="6138581029144467467">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> to display and stream apps between your devices"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Allow &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to access this information from your phone"</string>
@@ -35,6 +38,8 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play services"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> to access your phone’s photos, media, and notifications"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"Allow &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; to take this action?"</string>
+ <string name="title_nearby_device_streaming_with_mirroring" msgid="242855799919611657">"Allow &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; to stream your phone’s apps and system features?"</string>
+ <string name="summary_nearby_device_streaming" msgid="4039565463149145573">"%1$s will have access to anything that’s visible or played on your phone, including audio, photos, payment info, passwords, and messages.&lt;br/&gt;&lt;br/&gt;%1$s will be able to stream apps and system features until you remove access to this permission."</string>
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_NAME">%2$s</xliff:g> to stream apps and other system features to nearby devices"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"device"</string>
<string name="summary_generic" msgid="1761976003668044801">"This app will be able to sync info, like the name of someone calling, between your phone and the chosen device"</string>
diff --git a/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml b/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml
index 8b506ed20963..ee8eca0e24e3 100644
--- a/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"device"</string>
<string name="summary_glasses" msgid="2872254734959842579">"This app will be allowed to access these permissions on your <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Allow &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to access this information from your phone"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Cross-device services"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> to stream apps between your devices"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Allow &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to access this information from your phone"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play services"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> to access your phone’s photos, media and notifications"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"Allow &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; to take this action?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_NAME">%2$s</xliff:g> to stream apps and other system features to nearby devices"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"device"</string>
<string name="summary_generic" msgid="1761976003668044801">"This app will be able to sync info, like the name of someone calling, between your phone and the chosen device"</string>
diff --git a/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml b/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml
index 8b506ed20963..ee8eca0e24e3 100644
--- a/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"device"</string>
<string name="summary_glasses" msgid="2872254734959842579">"This app will be allowed to access these permissions on your <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Allow &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to access this information from your phone"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Cross-device services"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> to stream apps between your devices"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Allow &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; to access this information from your phone"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play services"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> to access your phone’s photos, media and notifications"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"Allow &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; to take this action?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_NAME">%2$s</xliff:g> to stream apps and other system features to nearby devices"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"device"</string>
<string name="summary_generic" msgid="1761976003668044801">"This app will be able to sync info, like the name of someone calling, between your phone and the chosen device"</string>
diff --git a/packages/CompanionDeviceManager/res/values-en-rXC/strings.xml b/packages/CompanionDeviceManager/res/values-en-rXC/strings.xml
index c3ae8a692361..a601926a381a 100644
--- a/packages/CompanionDeviceManager/res/values-en-rXC/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rXC/strings.xml
@@ -26,8 +26,11 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‏‎‏‎‏‎‎‏‏‎‎‏‏‎‏‏‏‎‏‏‎‎‎‎‎‏‏‏‏‏‏‎‎‎‎‏‎‏‏‎‏‎‎‏‏‎‎‎‏‎‏‏‏‏‎‏‎device‎‏‎‎‏‎"</string>
<string name="summary_glasses" msgid="2872254734959842579">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‏‏‏‎‏‏‏‎‎‎‏‎‎‏‏‎‎‎‏‏‏‎‏‏‎‏‎‏‎‏‏‎‏‏‎‏‏‎‏‏‏‎‎‎‏‎‏‎‏‎‎‎‏‎‎‏‏‎This app will be allowed to access these permissions on your ‎‏‎‎‏‏‎<xliff:g id="DEVICE_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‏‎‎‎‎‎‎‏‏‏‎‏‎‏‏‎‎‎‎‎‏‎‎‏‏‏‎‎‎‏‎‏‎‏‏‎‏‎‎‎‎‏‏‏‎‎‏‎‎‏‏‎‎‏‏‎‎Allow &lt;strong&gt;‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎&lt;/strong&gt; to access this information from your phone‎‏‎‎‏‎"</string>
+ <string name="title_app_streaming_with_mirroring" msgid="3364582597581570658">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‎‏‎‏‏‎‎‎‏‎‏‏‎‎‏‏‎‎‎‎‎‏‎‏‏‏‏‎‏‎‎‏‎‎‏‎‎‏‏‏‏‏‎‎‎‎‎‏‎‎‏‏‎‎‎‏‎‎Allow &lt;strong&gt;‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎&lt;/strong&gt; to stream your phone’s apps?‎‏‎‎‏‎"</string>
+ <string name="summary_app_streaming" msgid="295548145144086753">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‎‎‎‎‏‏‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‎‎‏‏‎‏‏‏‎‏‎‏‎‏‎‏‏‎‏‏‎‎‎‎‎‎‏‏‏‎‎‎‎‏‎%1$s will have access to anything that’s visible or played on the phone, including audio, photos, passwords, and messages.&lt;br/&gt;&lt;br/&gt;%1$s will be able to stream apps until you remove access to this permission.‎‏‎‎‏‎"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‏‎‎‏‏‏‎‏‏‏‎‎‎‎‎‏‎‏‎‏‎‏‎‏‎‏‎‎‎‎‏‎‏‎‏‎‎‏‎‏‎‎‏‏‎‏‎‏‏‏‏‎‎‏‎‏‎Cross-device services‎‏‎‎‏‎"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‏‎‏‎‎‎‎‏‏‎‎‎‎‏‏‎‎‏‎‎‎‎‏‏‎‎‎‏‎‎‎‏‏‎‏‎‏‏‎‏‏‎‏‏‎‎‎‏‎‏‎‏‏‏‎‎‏‎‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ is requesting permission on behalf of your ‎‏‎‎‏‏‎<xliff:g id="DISPLAY_NAME">%2$s</xliff:g>‎‏‎‎‏‏‏‎ to stream apps between your devices‎‏‎‎‏‎"</string>
+ <string name="helper_summary_app_streaming_with_mirroring" msgid="6138581029144467467">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‎‏‏‎‎‎‎‏‎‎‏‏‏‏‎‏‏‏‎‏‏‎‎‎‎‏‎‎‎‏‏‎‎‎‏‏‎‏‏‏‎‎‏‏‎‎‎‎‎‎‎‏‎‏‏‎‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ is requesting permission on behalf of your ‎‏‎‎‏‏‎<xliff:g id="DISPLAY_NAME">%2$s</xliff:g>‎‏‎‎‏‏‏‎ to display and stream apps between your devices‎‏‎‎‏‎"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‏‏‎‏‏‎‏‏‎‎‎‎‏‎‎‏‎‏‎‎‏‎‏‎‎‎‏‏‏‎‏‏‏‏‏‎‎‏‏‎‎‎‎‎‏‎‎‏‎‏‎Allow &lt;strong&gt;‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎&lt;/strong&gt; to access this information from your phone‎‏‎‎‏‎"</string>
@@ -35,6 +38,8 @@
<string name="helper_title_computer" msgid="4671071173916176037">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‏‎‏‎‎‏‎‏‏‏‏‏‎‏‎‎‏‏‏‏‎‏‏‏‏‏‏‏‎‎‏‏‏‎‏‎‏‏‏‎‎‏‎‏‏‏‎‏‎‏‎‎‏‎‏‎Google Play services‎‏‎‎‏‎"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‎‏‏‎‎‏‏‏‎‏‏‏‏‏‏‎‎‎‏‏‎‏‏‎‏‎‏‎‏‎‏‎‎‎‎‎‏‎‏‎‏‏‏‎‏‏‎‎‎‎‎‎‎‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ is requesting permission on behalf of your ‎‏‎‎‏‏‎<xliff:g id="DISPLAY_NAME">%2$s</xliff:g>‎‏‎‎‏‏‏‎ to access your phone’s photos, media, and notifications‎‏‎‎‏‎"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‏‎‎‏‎‎‎‎‎‏‎‎‏‏‎‎‏‏‏‏‎‎‎‎‎‏‏‏‎‎‎‏‏‎‏‏‏‎‏‎‎‏‏‏‎‎‏‎‏‏‎‎‏‎‎Allow &lt;strong&gt;‎‏‎‎‏‏‎<xliff:g id="DEVICE_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎&lt;/strong&gt; to take this action?‎‏‎‎‏‎"</string>
+ <string name="title_nearby_device_streaming_with_mirroring" msgid="242855799919611657">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‏‎‏‎‏‏‏‏‎‏‏‎‎‏‏‎‎‎‎‎‏‎‎‎‎‎‎‏‏‎‏‎‏‏‏‎‏‏‎‏‎‎‎‎‎‏‏‏‏‎‎‎‎‏‎‎‏‎Allow &lt;strong&gt;‎‏‎‎‏‏‎<xliff:g id="DEVICE_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎&lt;/strong&gt; to stream your phone’s apps and system features?‎‏‎‎‏‎"</string>
+ <string name="summary_nearby_device_streaming" msgid="4039565463149145573">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‎‎‎‎‎‏‏‏‏‎‏‏‎‏‎‏‏‎‏‏‎‎‎‏‎‏‏‎‏‏‏‎‏‏‏‏‏‎‎‎‎‏‏‏‎‏‏‎‏‏‏‏‎‎‏‎‏‎%1$s will have access to anything that’s visible or played on your phone, including audio, photos, payment info, passwords, and messages.&lt;br/&gt;&lt;br/&gt;%1$s will be able to stream apps and system features until you remove access to this permission.‎‏‎‎‏‎"</string>
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‏‎‏‎‎‏‎‎‏‎‏‎‏‏‎‏‎‏‎‎‏‎‏‏‏‏‏‏‎‎‏‎‎‎‎‎‎‎‎‏‎‎‏‎‏‎‏‎‎‏‎‎‏‏‎‎‎‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ is requesting permission on behalf of your ‎‏‎‎‏‏‎<xliff:g id="DEVICE_NAME">%2$s</xliff:g>‎‏‎‎‏‏‏‎ to stream apps and other system features to nearby devices‎‏‎‎‏‎"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‎‎‏‎‎‏‏‏‎‏‏‏‏‏‎‎‏‎‎‏‎‎‏‏‏‏‎‎‎‏‏‏‎‏‏‏‎‎‎‎‎‎‎‎‏‏‏‎‏‏‎‏‏‎‎‎device‎‏‎‎‏‎"</string>
<string name="summary_generic" msgid="1761976003668044801">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‎‎‏‏‏‎‎‏‏‏‏‎‎‏‎‏‏‏‏‎‏‎‏‏‏‎‎‎‎‏‎‎‏‎‏‏‎‎‏‎‏‎‏‏‎‏‏‎‎‎‎‎‎‎‎‎‏‎This app will be able to sync info, like the name of someone calling, between your phone and the chosen device‎‏‎‎‏‎"</string>
diff --git a/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml b/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml
index 75cd49ca1237..51f187480905 100644
--- a/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"dispositivo"</string>
<string name="summary_glasses" msgid="2872254734959842579">"Esta app podrá acceder a los siguientes permisos en tu <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Permite que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acceda a esta información de tu teléfono"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Servicios multidispositivo"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> solicita tu permiso en nombre de <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> para transmitir apps entre dispositivos"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Permite que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acceda a esta información de tu teléfono"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Servicios de Google Play"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> solicita tu permiso en nombre de <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> para acceder a las fotos, el contenido multimedia y las notificaciones de tu teléfono"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"¿Permites que &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; realice esta acción?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> está solicitando permiso en nombre de tu <xliff:g id="DEVICE_NAME">%2$s</xliff:g> para transmitir apps y otras funciones del sistema a dispositivos cercanos"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
<string name="summary_generic" msgid="1761976003668044801">"Esta app podrá sincronizar información, como el nombre de la persona que llama, entre el teléfono y el dispositivo elegido"</string>
diff --git a/packages/CompanionDeviceManager/res/values-es/strings.xml b/packages/CompanionDeviceManager/res/values-es/strings.xml
index ba6045bdba67..3e157f039df7 100644
--- a/packages/CompanionDeviceManager/res/values-es/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-es/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"dispositivo"</string>
<string name="summary_glasses" msgid="2872254734959842579">"Esta aplicación podrá acceder a estos permisos de tu <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Permitir que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acceda a esta información de tu teléfono"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Servicios multidispositivo"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> está pidiendo permiso en nombre de tu <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> para emitir aplicaciones en otros dispositivos tuyos"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Permitir que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acceda a esta información de tu teléfono"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Servicios de Google Play"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> está pidiendo permiso en nombre de tu <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> para acceder a las fotos, los archivos multimedia y las notificaciones de tu teléfono"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"¿Permitir que &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; realice esta acción?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> está pidiendo permiso en nombre de tu <xliff:g id="DEVICE_NAME">%2$s</xliff:g> para emitir aplicaciones y otras funciones del sistema en dispositivos cercanos"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
<string name="summary_generic" msgid="1761976003668044801">"Esta aplicación podrá sincronizar información (por ejemplo, el nombre de la persona que te llama) entre tu teléfono y el dispositivo que elijas"</string>
diff --git a/packages/CompanionDeviceManager/res/values-et/strings.xml b/packages/CompanionDeviceManager/res/values-et/strings.xml
index dc8d9920030b..28e8b0d194a6 100644
--- a/packages/CompanionDeviceManager/res/values-et/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-et/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"seade"</string>
<string name="summary_glasses" msgid="2872254734959842579">"Sellele rakendusele antakse need load teie seadmes <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Lubage rakendusel &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; pääseda teie telefonis juurde sellele teabele"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Seadmeülesed teenused"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> taotleb teie seadme <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> nimel luba teie seadmete vahel rakendusi voogesitada"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Lubage rakendusel &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; pääseda teie telefonis juurde sellele teabele"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play teenused"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> taotleb teie seadme <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> nimel luba pääseda juurde telefoni fotodele, meediale ja märguannetele"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"Kas lubada seadmel &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; teha seda toimingut?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> taotleb teie seadme <xliff:g id="DEVICE_NAME">%2$s</xliff:g> nimel luba voogesitada rakendusi ja muid süsteemi funktsioone läheduses olevatesse seadmetesse"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"seade"</string>
<string name="summary_generic" msgid="1761976003668044801">"See rakendus saab sünkroonida teavet, näiteks helistaja nime, teie telefoni ja valitud seadme vahel"</string>
diff --git a/packages/CompanionDeviceManager/res/values-eu/strings.xml b/packages/CompanionDeviceManager/res/values-eu/strings.xml
index 8cd4fdefad97..1884e04bdb1a 100644
--- a/packages/CompanionDeviceManager/res/values-eu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-eu/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"gailua"</string>
<string name="summary_glasses" msgid="2872254734959842579">"Baimen hauek erabili ahalko ditu <xliff:g id="DEVICE_NAME">%1$s</xliff:g>n aplikazioak:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Eman informazioa telefonotik hartzeko baimena &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; aplikazioari"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Gailuarteko zerbitzuak"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"Gailu batetik bestera aplikazioak igortzeko baimena eskatzen ari da <xliff:g id="APP_NAME">%1$s</xliff:g>, <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> gailuaren izenean"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Eman telefonoko informazio hau erabiltzeko baimena &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; aplikazioari"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play Services"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"Telefonoko argazkiak, multimedia-edukia eta jakinarazpenak erabiltzeko baimena eskatzen ari da <xliff:g id="APP_NAME">%1$s</xliff:g>, <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> gailuaren izenean"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"Ekintza hau gauzatzeko baimena eman nahi diozu &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; aplikazioari?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"Aplikazioak eta sistemaren beste eginbide batzuk inguruko gailuetara igortzeko baimena eskatzen ari da <xliff:g id="APP_NAME">%1$s</xliff:g>, <xliff:g id="DEVICE_NAME">%2$s</xliff:g> gailuaren izenean"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"gailua"</string>
<string name="summary_generic" msgid="1761976003668044801">"Telefonoaren eta hautatutako gailuaren artean informazioa sinkronizatzeko gai izango da aplikazioa (esate baterako, deitzaileen izenak)"</string>
diff --git a/packages/CompanionDeviceManager/res/values-fa/strings.xml b/packages/CompanionDeviceManager/res/values-fa/strings.xml
index 83628cb4a360..9c5807bc5008 100644
--- a/packages/CompanionDeviceManager/res/values-fa/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fa/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"دستگاه"</string>
<string name="summary_glasses" msgid="2872254734959842579">"این برنامه مجاز می‌شود به این اجازه‌ها در <xliff:g id="DEVICE_NAME">%1$s</xliff:g> شما دسترسی پیدا کند"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"‏اجازه دادن به &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; برای دسترسی به اطلاعات تلفن"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"سرویس‌های بین‌دستگاهی"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> ازطرف <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> اجازه می‌خواهد برنامه‌ها را بین دستگاه‌های شما جاری‌سازی کند"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"‏به &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; اجازه دسترسی به این اطلاعات در دستگاهتان داده شود"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"‏خدمات Google Play"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> ازطرف <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> اجازه می‌خواهد به عکس‌ها، رسانه‌ها، و اعلان‌های تلفن شما دسترسی پیدا کند"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"‏به &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; اجازه داده شود این اقدام را انجام دهد؟"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> ازطرف <xliff:g id="DEVICE_NAME">%2$s</xliff:g> اجازه می‌خواهد تا برنامه‌ها و دیگر ویژگی‌های سیستم را در دستگاه‌های اطراف جاری‌سازی کند."</string>
<string name="profile_name_generic" msgid="6851028682723034988">"دستگاه"</string>
<string name="summary_generic" msgid="1761976003668044801">"این برنامه مجاز می‌شود اطلاعتی مثل نام شخصی را که تماس می‌گیرد بین تلفن شما و دستگاه انتخاب‌شده همگام‌سازی کند"</string>
diff --git a/packages/CompanionDeviceManager/res/values-fi/strings.xml b/packages/CompanionDeviceManager/res/values-fi/strings.xml
index 86e79041357b..ecde94926658 100644
--- a/packages/CompanionDeviceManager/res/values-fi/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fi/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"laite"</string>
<string name="summary_glasses" msgid="2872254734959842579">"Tämä sovellus saa käyttää näitä lupia laitteella (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>)"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Salli, että &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; saa pääsyn näihin puhelimesi tietoihin"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Laitteidenväliset palvelut"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> pyytää laitteesi (<xliff:g id="DISPLAY_NAME">%2$s</xliff:g>) puolesta lupaa striimata sovelluksia laitteidesi välillä"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Salli pääsy tähän tietoon puhelimellasi: &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play Palvelut"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> pyytää laitteesi (<xliff:g id="DISPLAY_NAME">%2$s</xliff:g>) puolesta lupaa päästä puhelimesi kuviin, mediaan ja ilmoituksiin"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"Sallitko, että &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; voi suorittaa tämän toiminnon?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> pyytää laitteesi (<xliff:g id="DEVICE_NAME">%2$s</xliff:g>) puolesta lupaa striimata sovelluksia ja muita järjestelmän ominaisuuksia lähellä oleviin laitteisiin."</string>
<string name="profile_name_generic" msgid="6851028682723034988">"laite"</string>
<string name="summary_generic" msgid="1761976003668044801">"Sovellus voi synkronoida tietoja (esimerkiksi soittajan nimen) puhelimesi ja valitun laitteen välillä"</string>
diff --git a/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml b/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
index b74c8ee5d68a..5debbf3bf6e1 100644
--- a/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"appareil"</string>
<string name="summary_glasses" msgid="2872254734959842579">"Cette application pourra accéder à ces autorisations sur votre <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Autorisez &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; à accéder à ces informations à partir de votre téléphone"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Services multiappareils"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> demande l\'autorisation au nom de votre <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> pour diffuser des applications entre vos appareils"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Autorisez &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; à accéder à ces informations à partir de votre téléphone"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Services Google Play"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> demande l\'autorisation au nom de votre <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> pour accéder aux photos, aux fichiers multimédias et aux notifications de votre téléphone"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"Autoriser &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; à effectuer cette action?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> demande l\'autorisation, au nom de votre <xliff:g id="DEVICE_NAME">%2$s</xliff:g>, de diffuser des applications et d\'autres fonctionnalités du système sur des appareils à proximité"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"appareil"</string>
<string name="summary_generic" msgid="1761976003668044801">"Cette application pourra synchroniser des informations, comme le nom de l\'appelant, entre votre téléphone et l\'appareil sélectionné"</string>
diff --git a/packages/CompanionDeviceManager/res/values-fr/strings.xml b/packages/CompanionDeviceManager/res/values-fr/strings.xml
index 30b0c9af5f0b..0403a4d69f72 100644
--- a/packages/CompanionDeviceManager/res/values-fr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fr/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"appareil"</string>
<string name="summary_glasses" msgid="2872254734959842579">"Cette appli sera autorisée à accéder à ces autorisations sur votre <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Autoriser &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; à accéder à ces informations depuis votre téléphone"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Services inter-appareils"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> demande l\'autorisation au nom de votre <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> pour caster des applis d\'un appareil à l\'autre"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Autoriser &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; à accéder à ces informations depuis votre téléphone"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Services Google Play"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> demande l\'autorisation au nom de votre <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> pour accéder aux photos, contenus multimédias et notifications de votre téléphone"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"Autoriser &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; à effectuer cette action ?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> demande l\'autorisation au nom de votre <xliff:g id="DEVICE_NAME">%2$s</xliff:g> de diffuser des applis et d\'autres fonctionnalités système en streaming sur des appareils à proximité"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"appareil"</string>
<string name="summary_generic" msgid="1761976003668044801">"Cette appli pourra synchroniser des infos, comme le nom de l\'appelant, entre votre téléphone et l\'appareil choisi"</string>
diff --git a/packages/CompanionDeviceManager/res/values-gl/strings.xml b/packages/CompanionDeviceManager/res/values-gl/strings.xml
index 1b8b8d4d9078..5d9d7ee915d5 100644
--- a/packages/CompanionDeviceManager/res/values-gl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-gl/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"dispositivo"</string>
<string name="summary_glasses" msgid="2872254734959842579">"Esta aplicación poderá acceder a estes permisos do dispositivo (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>)"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Permitir que a aplicación &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acceda a esta información desde o teu teléfono"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Servizos multidispositivo"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> está solicitando permiso en nome do teu dispositivo (<xliff:g id="DISPLAY_NAME">%2$s</xliff:g>) para emitir contido de aplicacións entre os teus aparellos"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Permitir que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acceda a esta información do teu teléfono"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Servizos de Google Play"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> está solicitando permiso en nome do teu dispositivo (<xliff:g id="DISPLAY_NAME">%2$s</xliff:g>) para acceder ás fotos, ao contido multimedia e ás notificacións do teléfono"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"Queres permitir que &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; leve a cabo esta acción?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> está solicitando permiso en nome do teu dispositivo (<xliff:g id="DEVICE_NAME">%2$s</xliff:g>) para emitir o contido das aplicacións e doutras funcións do sistema en dispositivos próximos"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
<string name="summary_generic" msgid="1761976003668044801">"Esta aplicación poderá sincronizar información (por exemplo, o nome de quen chama) entre o teléfono e o dispositivo escollido"</string>
diff --git a/packages/CompanionDeviceManager/res/values-gu/strings.xml b/packages/CompanionDeviceManager/res/values-gu/strings.xml
index 474960cd7394..e645f187b3f1 100644
--- a/packages/CompanionDeviceManager/res/values-gu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-gu/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"ડિવાઇસ"</string>
<string name="summary_glasses" msgid="2872254734959842579">"આ ઍપને તમારા <xliff:g id="DEVICE_NAME">%1$s</xliff:g> પર આ પરવાનગીઓ ઍક્સેસ કરવાની મંજૂરી મળશે"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"તમારા ફોનમાંથી આ માહિતી ઍક્સેસ કરવા માટે, &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;ને મંજૂરી આપો"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"ક્રોસ-ડિવાઇસ સેવાઓ"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> તમારા <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> વતી તમારા ડિવાઇસ વચ્ચે ઍપ સ્ટ્રીમ કરવાની પરવાનગીની વિનંતી કરી રહી છે"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"તમારા ફોનમાંથી આ માહિતી ઍક્સેસ કરવા માટે, &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;ને મંજૂરી આપો"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play સેવાઓ"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> તમારા <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> વતી તમારા ફોનના ફોટા, મીડિયા અને નોટિફિકેશન ઍક્સેસ કરવાની પરવાનગીની વિનંતી કરી રહી છે"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt;ને આ પગલું ભરવાની મંજૂરી આપીએ?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> નજીકના ડિવાઇસ પર ઍપ અને સિસ્ટમની અન્ય સુવિધાઓ સ્ટ્રીમ કરવા તમારા <xliff:g id="DEVICE_NAME">%2$s</xliff:g> વતી પરવાનગીની વિનંતી કરી રહી છે"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"ડિવાઇસ"</string>
<string name="summary_generic" msgid="1761976003668044801">"આ ઍપ તમારા ફોન અને પસંદ કરેલા ડિવાઇસ વચ્ચે, કૉલ કરનાર કોઈ વ્યક્તિનું નામ જેવી માહિતી સિંક કરી શકશે"</string>
diff --git a/packages/CompanionDeviceManager/res/values-hi/strings.xml b/packages/CompanionDeviceManager/res/values-hi/strings.xml
index 8a0e2d7f3017..f524b97f1222 100644
--- a/packages/CompanionDeviceManager/res/values-hi/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hi/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"डिवाइस"</string>
<string name="summary_glasses" msgid="2872254734959842579">"यह ऐप्लिकेशन, आपके <xliff:g id="DEVICE_NAME">%1$s</xliff:g> पर इन अनुमतियों को ऐक्सेस कर पाएगा"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; को अपने फ़ोन से यह जानकारी ऐक्सेस करने की अनुमति दें"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"क्रॉस-डिवाइस से जुड़ी सेवाएं"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> आपके <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> की ओर से, आपके डिवाइसों के बीच ऐप्लिकेशन स्ट्रीम करने की अनुमति मांग रहा है"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; को अपने फ़ोन से यह जानकारी ऐक्सेस करने की अनुमति दें"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play services"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> आपके <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> की ओर से, आपने फ़ोन में मौजूद फ़ोटो, मीडिया, और सूचनाओं को ऐक्सेस करने की अनुमति मांग रहा है"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"क्या &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; को यह कार्रवाई करने की अनुमति देनी है?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> आपके <xliff:g id="DEVICE_NAME">%2$s</xliff:g> की ओर से, ऐप्लिकेशन और दूसरे सिस्टम की सुविधाओं को आस-पास मौजूद डिवाइसों पर स्ट्रीम करने की अनुमति मांग रहा है"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"डिवाइस"</string>
<string name="summary_generic" msgid="1761976003668044801">"यह ऐप्लिकेशन, आपके फ़ोन और चुने हुए डिवाइस के बीच जानकारी सिंक करेगा. जैसे, कॉल करने वाले व्यक्ति का नाम"</string>
diff --git a/packages/CompanionDeviceManager/res/values-hr/strings.xml b/packages/CompanionDeviceManager/res/values-hr/strings.xml
index 6dc59ea0ceb0..5ed3eb278a50 100644
--- a/packages/CompanionDeviceManager/res/values-hr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hr/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"uređaj"</string>
<string name="summary_glasses" msgid="2872254734959842579">"Aplikacija će moći pristupati ovim dopuštenjima na vašem uređaju <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Omogućite aplikaciji &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; da pristupa informacijama s vašeg telefona"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Usluge na različitim uređajima"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> zahtijeva dopuštenje u ime vašeg uređaja <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> za stream aplikacija s jednog uređaja na drugi"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Omogućite aplikaciji &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; da pristupa informacijama s vašeg telefona"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Usluge za Google Play"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> zahtijeva dopuštenje u ime vašeg uređaja <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> za pristup fotografijama, medijskim sadržajima i obavijestima na telefonu"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"Želite li uređaju &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; dopustiti da izvrši tu radnju?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> zahtijeva dopuštenje u ime vašeg uređaja <xliff:g id="DEVICE_NAME">%2$s</xliff:g> za emitiranje aplikacija i drugih značajki sustava na uređajima u blizini"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"uređaj"</string>
<string name="summary_generic" msgid="1761976003668044801">"Ta će aplikacija moći sinkronizirati podatke između vašeg telefona i odabranog uređaja, primjerice ime pozivatelja"</string>
diff --git a/packages/CompanionDeviceManager/res/values-hu/strings.xml b/packages/CompanionDeviceManager/res/values-hu/strings.xml
index 4b1a6f7b98a7..8082bb5f4a71 100644
--- a/packages/CompanionDeviceManager/res/values-hu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hu/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"eszköz"</string>
<string name="summary_glasses" msgid="2872254734959842579">"Az alkalmazás hozzáférhet majd ezekhez az engedélyekhez az Ön <xliff:g id="DEVICE_NAME">%1$s</xliff:g> eszközén"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Engedélyezi a(z) „<xliff:g id="APP_NAME">%1$s</xliff:g>” alkalmazás számára az információhoz való hozzáférést a telefonról"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Többeszközös szolgáltatások"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> engedélyt kér a(z) <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> nevében az alkalmazások eszközök közötti streameléséhez"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Engedélyezi a(z) „<xliff:g id="APP_NAME">%1$s</xliff:g>” alkalmazás számára az információhoz való hozzáférést a telefonról"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play-szolgáltatások"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> engedélyt kér a(z) <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> nevében a telefonon tárolt fotókhoz, médiatartalmakhoz és értesítésekhez való hozzáféréshez"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"Engedélyezi a(z) &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; számára ennek a műveletnek a végrehajtását?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> engedélyt kér a(z) <xliff:g id="DEVICE_NAME">%2$s</xliff:g> nevében az alkalmazások és más rendszerfunkciók közeli eszközökre történő streamelésére"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"eszköz"</string>
<string name="summary_generic" msgid="1761976003668044801">"Ez az alkalmazás képes lesz szinkronizálni az olyan információkat a telefon és a kiválasztott eszköz között, mint például a hívó fél neve."</string>
diff --git a/packages/CompanionDeviceManager/res/values-hy/strings.xml b/packages/CompanionDeviceManager/res/values-hy/strings.xml
index 405a98387e33..fc8adee138ab 100644
--- a/packages/CompanionDeviceManager/res/values-hy/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hy/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"սարք"</string>
<string name="summary_glasses" msgid="2872254734959842579">"Այս հավելվածը կստանա հետևյալ թույլտվությունները ձեր <xliff:g id="DEVICE_NAME">%1$s</xliff:g>ում"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Թույլատրեք &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; հավելվածին օգտագործել այս տեղեկությունները ձեր հեռախոսից"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Միջսարքային ծառայություններ"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածը ձեր <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> սարքի անունից թույլտվություն է խնդրում՝ ձեր սարքերի միջև հավելվածներ հեռարձակելու համար"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Թույլատրեք &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; հավելվածին օգտագործել այս տեղեկությունները ձեր հեռախոսից"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play ծառայություններ"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածը ձեր <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> սարքի անունից թույլտվություն է խնդրում՝ ձեր հեռախոսի լուսանկարները, մեդիաֆայլերն ու ծանուցումները տեսնելու համար"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"Թույլատրե՞լ &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; հավելվածին կատարել այս գործողությունը"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածը ձեր <xliff:g id="DEVICE_NAME">%2$s</xliff:g> սարքի անունից թույլտվություն է խնդրում՝ մոտակա սարքերին հավելվածներ և համակարգի այլ գործառույթներ հեռարձակելու համար"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"սարք"</string>
<string name="summary_generic" msgid="1761976003668044801">"Այս հավելվածը կկարողանա համաժամացնել ձեր հեռախոսի և ընտրված սարքի տվյալները, օր․՝ զանգողի անունը"</string>
diff --git a/packages/CompanionDeviceManager/res/values-in/strings.xml b/packages/CompanionDeviceManager/res/values-in/strings.xml
index 02cc573315cc..c2814552b919 100644
--- a/packages/CompanionDeviceManager/res/values-in/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-in/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"perangkat"</string>
<string name="summary_glasses" msgid="2872254734959842579">"Aplikasi ini akan diizinkan mengakses izin ini di <xliff:g id="DEVICE_NAME">%1$s</xliff:g> Anda"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Izinkan &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; untuk mengakses informasi ini dari ponsel Anda"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Layanan lintas perangkat"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> meminta izin atas nama <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> untuk menstreaming aplikasi di antara perangkat Anda"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Izinkan &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; mengakses informasi ini dari ponsel Anda"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Layanan Google Play"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> meminta izin atas nama <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> untuk mengakses foto, media, dan notifikasi ponsel Anda"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"Izinkan &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; melakukan tindakan ini?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> meminta izin atas nama <xliff:g id="DEVICE_NAME">%2$s</xliff:g> untuk menstreaming aplikasi dan fitur sistem lainnya ke perangkat di sekitar"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"perangkat"</string>
<string name="summary_generic" msgid="1761976003668044801">"Aplikasi ini akan dapat menyinkronkan info, seperti nama penelepon, antara ponsel dan perangkat yang dipilih"</string>
diff --git a/packages/CompanionDeviceManager/res/values-is/strings.xml b/packages/CompanionDeviceManager/res/values-is/strings.xml
index baad2cf4676e..42ca7da70b94 100644
--- a/packages/CompanionDeviceManager/res/values-is/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-is/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"tæki"</string>
<string name="summary_glasses" msgid="2872254734959842579">"Þetta forrit fær aðgang að eftirfarandi heimildum í <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Veita &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; aðgang að þessum upplýsingum úr símanum þínum"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Þjónustur á milli tækja"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> biður um heimild fyrir <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> til að streyma forritum á milli tækjanna þinna"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Veita &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; aðgang að þessum upplýsingum úr símanum þínum"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Þjónusta Google Play"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> sendir beiðni um aðgang að myndum, margmiðlunarefni og tilkynningum símans þíns fyrir hönd <xliff:g id="DISPLAY_NAME">%2$s</xliff:g>"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"Leyfa &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; að framkvæma þessa aðgerð?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> biður um heimild fyrir <xliff:g id="DEVICE_NAME">%2$s</xliff:g> til að streyma forritum og öðrum kerfiseiginleikum í nálægum tækjum"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"tæki"</string>
<string name="summary_generic" msgid="1761976003668044801">"Þetta forrit mun geta samstillt upplýsingar, t.d. nafn þess sem hringir, á milli símans og valins tækis"</string>
diff --git a/packages/CompanionDeviceManager/res/values-it/strings.xml b/packages/CompanionDeviceManager/res/values-it/strings.xml
index 81f5d62cb7fb..06d58b694695 100644
--- a/packages/CompanionDeviceManager/res/values-it/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-it/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"dispositivo"</string>
<string name="summary_glasses" msgid="2872254734959842579">"Questa app potrà accedere alle seguenti autorizzazioni su <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Consenti a &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; di accedere a queste informazioni dal tuo telefono"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Servizi cross-device"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> richiede per conto del tuo <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> l\'autorizzazione a trasmettere app in streaming tra i dispositivi"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Consenti a &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; di accedere a questa informazione dal tuo telefono"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play Services"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> richiede per conto del tuo <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> l\'autorizzazione ad accedere a foto, contenuti multimediali e notifiche del telefono"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"Vuoi consentire a &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; di compiere questa azione?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> richiede per conto di <xliff:g id="DEVICE_NAME">%2$s</xliff:g> l\'autorizzazione a trasmettere in streaming app e altre funzionalità di sistema ai dispositivi nelle vicinanze"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
<string name="summary_generic" msgid="1761976003668044801">"Questa app potrà sincronizzare informazioni, ad esempio il nome di un chiamante, tra il telefono e il dispositivo scelto"</string>
diff --git a/packages/CompanionDeviceManager/res/values-iw/strings.xml b/packages/CompanionDeviceManager/res/values-iw/strings.xml
index f4367c0acea5..49d1f9e3b7e7 100644
--- a/packages/CompanionDeviceManager/res/values-iw/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-iw/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"מכשיר"</string>
<string name="summary_glasses" msgid="2872254734959842579">"האפליקציה הזו תוכל לגשת להרשאות האלה ב<xliff:g id="DEVICE_NAME">%1$s</xliff:g> שלך"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"‏מתן אישור לאפליקציה &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; לגשת למידע הזה מהטלפון שלך"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"שירותים למספר מכשירים"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> מבקשת הרשאה עבור המכשיר <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> כדי לשדר אפליקציות בין המכשירים שלך"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"‏מתן אישור לאפליקציה &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; לגשת למידע הזה מהטלפון שלך"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play Services"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> מבקשת הרשאה עבור המכשיר <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> כדי לגשת לתמונות, למדיה ולהתראות בטלפון שלך"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"‏לתת הרשאה למכשיר &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; לבצע את הפעולה הזו?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> מבקשת הרשאה עבור <xliff:g id="DEVICE_NAME">%2$s</xliff:g> כדי להעביר אפליקציות ותכונות מערכת אחרות בסטרימינג למכשירים בקרבת מקום"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"מכשיר"</string>
<string name="summary_generic" msgid="1761976003668044801">"האפליקציה הזו תוכל לסנכרן מידע, כמו השם של מישהו שמתקשר, מהטלפון שלך למכשיר שבחרת"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ja/strings.xml b/packages/CompanionDeviceManager/res/values-ja/strings.xml
index 2dfb4d1f6354..0f163947774f 100644
--- a/packages/CompanionDeviceManager/res/values-ja/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ja/strings.xml
@@ -26,8 +26,11 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"デバイス"</string>
<string name="summary_glasses" msgid="2872254734959842579">"このアプリは、<xliff:g id="DEVICE_NAME">%1$s</xliff:g>の以下の権限にアクセスできるようになります"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"スマートフォンのこの情報へのアクセスを &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; に許可"</string>
+ <string name="title_app_streaming_with_mirroring" msgid="3364582597581570658">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; にスマートフォンのアプリをストリーミングすることを許可しますか?"</string>
+ <string name="summary_app_streaming" msgid="295548145144086753">"%1$s は、音声、写真、パスワード、メッセージを含め、スマートフォンで表示、再生されるすべてのコンテンツにアクセスできるようになります。&lt;br/&gt;&lt;br/&gt;この権限へのアクセス権を削除するまで、%1$s はアプリをストリーミングできます。"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"クロスデバイス サービス"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> が <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> に代わってデバイス間でアプリをストリーミングする権限をリクエストしています"</string>
+ <string name="helper_summary_app_streaming_with_mirroring" msgid="6138581029144467467">"<xliff:g id="APP_NAME">%1$s</xliff:g> が <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> に代わってデバイス間でアプリを表示およびストリーミングする権限をリクエストしています"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"スマートフォンのこの情報へのアクセスを &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; に許可"</string>
@@ -35,6 +38,8 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play 開発者サービス"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> が <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> に代わってスマートフォンの写真、メディア、通知にアクセスする権限をリクエストしています"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; にこの操作の実行を許可しますか?"</string>
+ <string name="title_nearby_device_streaming_with_mirroring" msgid="242855799919611657">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; にスマートフォンのアプリとシステム機能をストリーミングすることを許可しますか?"</string>
+ <string name="summary_nearby_device_streaming" msgid="4039565463149145573">"%1$s は、音声、写真、お支払い情報、パスワード、メッセージを含め、スマートフォンで表示、再生されるすべてのコンテンツにアクセスできるようになります。&lt;br/&gt;&lt;br/&gt;この権限へのアクセス権を削除するまで、%1$s はアプリとシステム機能をストリーミングできます。"</string>
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> が <xliff:g id="DEVICE_NAME">%2$s</xliff:g> に代わって、アプリやその他のシステム機能を付近のデバイスにストリーミングする権限をリクエストしています"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"デバイス"</string>
<string name="summary_generic" msgid="1761976003668044801">"このアプリは、あなたのスマートフォンと選択したデバイスとの間で、通話相手の名前などの情報を同期できるようになります"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ka/strings.xml b/packages/CompanionDeviceManager/res/values-ka/strings.xml
index f4dcaea08230..3ad80badfa91 100644
--- a/packages/CompanionDeviceManager/res/values-ka/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ka/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"მოწყობილობა"</string>
<string name="summary_glasses" msgid="2872254734959842579">"ეს აპი შეძლებს ამ ნებართვებზე წვდომას თქვენს <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-ში"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"ნება დართეთ, რომ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; აპს ჰქონდეს ამ ინფორმაციაზე წვდომა თქვენი ტელეფონიდან"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"მოწყობილობათშორისი სერვისები"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> ითხოვს უფლებას თქვენი <xliff:g id="DISPLAY_NAME">%2$s</xliff:g>-ის სახელით, რომ მოწყობილობებს შორის სტრიმინგი შეძლოს"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"ნება დართეთ, რომ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; აპს ჰქონდეს ამ ინფორმაციაზე წვდომა თქვენი ტელეფონიდან"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play services"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> ითხოვს უფლებას თქვენი <xliff:g id="DISPLAY_NAME">%2$s</xliff:g>-ის სახელით, რომ წვდომა ჰქონდეს თქვენი ტელეფონის ფოტოებზე, მედიასა და შეტყობინებებზე"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"გსურთ ნება მისცეთ &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>-ს&lt;/strong&gt; ამ მოქმედების შესასრულებლად?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> ითხოვს თქვენი <xliff:g id="DEVICE_NAME">%2$s</xliff:g>-ის სახელით აპების და სისტემის სხვა ფუნქციების ახლომახლო მოწყობილობებზე სტრიმინგის ნებართვას"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"მოწყობილობა"</string>
<string name="summary_generic" msgid="1761976003668044801">"ეს აპი შეძლებს ინფორმაციის სინქრონიზებას თქვენს ტელეფონსა და თქვენ მიერ არჩეულ მოწყობილობას შორის, მაგალითად, იმ ადამიანის სახელის, რომელიც გირეკავთ"</string>
diff --git a/packages/CompanionDeviceManager/res/values-kk/strings.xml b/packages/CompanionDeviceManager/res/values-kk/strings.xml
index 122e2e60f7ba..4e4986ecf2ff 100644
--- a/packages/CompanionDeviceManager/res/values-kk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-kk/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"құрылғы"</string>
<string name="summary_glasses" msgid="2872254734959842579">"Бұл қолданба <xliff:g id="DEVICE_NAME">%1$s</xliff:g> құрылғысында осы рұқсаттарды пайдалана алады."</string>
<string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; қолданбасына телефоныңыздағы осы ақпаратты пайдалануға рұқсат беріңіз."</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Аралық құрылғы қызметтері"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасы <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> атынан құрылғылар арасында қолданбалар трансляциялау үшін рұқсат сұрайды."</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; қолданбасына телефоныңыздағы осы ақпаратты пайдалануға рұқсат беріңіз."</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play қызметтері"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасы <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> атынан телефондағы фотосуреттерді, медиафайлдар мен хабарландыруларды пайдалану үшін рұқсат сұрайды."</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; құрылғысына бұл әрекетті орындауға рұқсат беру керек пе?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасы <xliff:g id="DEVICE_NAME">%2$s</xliff:g> атынан қолданбалар мен басқа да жүйе функцияларын маңайдағы құрылғыларға трансляциялау рұқсатын сұрап тұр."</string>
<string name="profile_name_generic" msgid="6851028682723034988">"құрылғы"</string>
<string name="summary_generic" msgid="1761976003668044801">"Бұл қолданба телефон мен таңдалған құрылғы арасында деректі (мысалы, қоңырау шалушының атын) синхрондай алады."</string>
diff --git a/packages/CompanionDeviceManager/res/values-km/strings.xml b/packages/CompanionDeviceManager/res/values-km/strings.xml
index d6f303737ef3..4646e11887e2 100644
--- a/packages/CompanionDeviceManager/res/values-km/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-km/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"ឧបករណ៍"</string>
<string name="summary_glasses" msgid="2872254734959842579">"កម្មវិធីនេះ​នឹងត្រូវបានអនុញ្ញាតឱ្យ​ចូលប្រើប្រាស់ការអនុញ្ញាតទាំងនេះ​នៅលើ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> របស់អ្នក"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"អនុញ្ញាតឱ្យ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ចូលប្រើព័ត៌មាននេះពីទូរសព្ទរបស់អ្នក"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"សេវាកម្មឆ្លងកាត់ឧបករណ៍"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> កំពុងស្នើសុំការអនុញ្ញាតជំនួសឱ្យ <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> របស់អ្នក ដើម្បីបញ្ចាំងកម្មវិធីរវាងឧបករណ៍របស់អ្នក"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"អនុញ្ញាតឱ្យ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ចូលមើលព័ត៌មាននេះពីទូរសព្ទរបស់អ្នក"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"សេវាកម្ម Google Play"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> កំពុងស្នើសុំការអនុញ្ញាតជំនួសឱ្យ <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> របស់អ្នក ដើម្បីចូលប្រើរូបថត មេឌៀ និងការជូនដំណឹងរបស់ទូរសព្ទអ្នក"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"អនុញ្ញាតឱ្យ &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; ធ្វើសកម្មភាពនេះឬ?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> កំពុងស្នើសុំ​ការអនុញ្ញាតជំនួសឱ្យ <xliff:g id="DEVICE_NAME">%2$s</xliff:g> របស់អ្នក ដើម្បីចាក់ផ្សាយកម្មវិធី និងមុខងារប្រព័ន្ធផ្សេងទៀត​ទៅកាន់​ឧបករណ៍នៅជិត"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"ឧបករណ៍"</string>
<string name="summary_generic" msgid="1761976003668044801">"កម្មវិធីនេះនឹងអាច​ធ្វើសមកាលកម្មព័ត៌មាន ដូចជាឈ្មោះមនុស្សដែលហៅទូរសព្ទជាដើម​ រវាងឧបករណ៍ដែលបានជ្រើសរើស និងទូរសព្ទរបស់អ្នក"</string>
diff --git a/packages/CompanionDeviceManager/res/values-kn/strings.xml b/packages/CompanionDeviceManager/res/values-kn/strings.xml
index 661d344e2e6a..4f2bdd2d0732 100644
--- a/packages/CompanionDeviceManager/res/values-kn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-kn/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"ಸಾಧನ"</string>
<string name="summary_glasses" msgid="2872254734959842579">"ನಿಮ್ಮ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ನಲ್ಲಿ ಈ ಅನುಮತಿಗಳನ್ನು ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಲು ಈ ಆ್ಯಪ್‌ಗೆ ಅನುಮತಿಸಲಾಗುತ್ತದೆ"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"ನಿಮ್ಮ ಫೋನ್ ಮೂಲಕ ಈ ಮಾಹಿತಿಯನ್ನು ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಲು &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ಗೆ ಅನುಮತಿಸಿ"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"ಕ್ರಾಸ್-ಡಿವೈಸ್ ಸೇವೆಗಳು"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"ನಿಮ್ಮ ಸಾಧನಗಳ ನಡುವೆ ಆ್ಯಪ್‌ಗಳನ್ನು ಸ್ಟ್ರೀಮ್ ಮಾಡಲು ನಿಮ್ಮ <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> ನ ಪರವಾಗಿ <xliff:g id="APP_NAME">%1$s</xliff:g> ಅನುಮತಿಯನ್ನು ವಿನಂತಿಸಿಕೊಳ್ಳುತ್ತಿದೆ"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"ನಿಮ್ಮ ಫೋನ್ ಮೂಲಕ ಈ ಮಾಹಿತಿಯನ್ನು ಪ್ರವೇಶಿಸಲು &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ಗೆ ಅನುಮತಿಸಿ"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play ಸೇವೆಗಳು"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"ನಿಮ್ಮ ಫೋನ್‌ನ ಫೋಟೋಗಳು, ಮೀಡಿಯಾ ಮತ್ತು ಅಧಿಸೂಚನೆಗಳನ್ನು ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಲು ನಿಮ್ಮ <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> ನ ಪರವಾಗಿ <xliff:g id="APP_NAME">%1$s</xliff:g> ಅನುಮತಿಯನ್ನು ವಿನಂತಿಸಿಕೊಳ್ಳುತ್ತಿದೆ"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"ಈ ಆ್ಯಕ್ಷನ್ ಅನ್ನು ತೆಗೆದುಕೊಳ್ಳಲು &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; ಅನುಮತಿಸಬೇಕೇ?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"ಸಮೀಪದಲ್ಲಿರುವ ಸಾಧನಗಳಿಗೆ ಆ್ಯಪ್‌ಗಳು ಮತ್ತು ಇತರ ಸಿಸ್ಟಂ ಫೀಚರ್‌ಗಳನ್ನು ಸ್ಟ್ರೀಮ್ ಮಾಡಲು ನಿಮ್ಮ <xliff:g id="DEVICE_NAME">%2$s</xliff:g> ರ ಪರವಾಗಿ <xliff:g id="APP_NAME">%1$s</xliff:g> ಅನುಮತಿಯನ್ನು ವಿನಂತಿಸುತ್ತಿದೆ"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"ಸಾಧನ"</string>
<string name="summary_generic" msgid="1761976003668044801">"ಮೊಬೈಲ್ ಫೋನ್ ಮತ್ತು ಆಯ್ಕೆಮಾಡಿದ ಸಾಧನದ ನಡುವೆ, ಕರೆ ಮಾಡುವವರ ಹೆಸರಿನಂತಹ ಮಾಹಿತಿಯನ್ನು ಸಿಂಕ್ ಮಾಡಲು ಈ ಆ್ಯಪ್‌ಗೆ ಸಾಧ್ಯವಾಗುತ್ತದೆ"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ko/strings.xml b/packages/CompanionDeviceManager/res/values-ko/strings.xml
index 4ae5abdb4933..9aa49d57b89a 100644
--- a/packages/CompanionDeviceManager/res/values-ko/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ko/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"기기"</string>
<string name="summary_glasses" msgid="2872254734959842579">"앱이 <xliff:g id="DEVICE_NAME">%1$s</xliff:g>에서 이러한 권한에 액세스할 수 있게 됩니다."</string>
<string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;이 휴대전화의 이 정보에 액세스하도록 허용합니다."</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"교차 기기 서비스"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g>에서 <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> 대신 기기 간에 앱을 스트리밍할 수 있는 권한을 요청하고 있습니다."</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;이 휴대전화에서 이 정보에 액세스하도록 허용"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play 서비스"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g>에서 <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> 대신 휴대전화의 사진, 미디어, 알림에 액세스할 수 있는 권한을 요청하고 있습니다."</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; 기기가 이 작업을 수행하도록 허용하시겠습니까?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g>에서 <xliff:g id="DEVICE_NAME">%2$s</xliff:g> 대신 근처 기기로 앱 및 기타 시스템 기능을 스트리밍할 권한을 요청하고 있습니다."</string>
<string name="profile_name_generic" msgid="6851028682723034988">"기기"</string>
<string name="summary_generic" msgid="1761976003668044801">"이 앱에서 휴대전화와 선택한 기기 간에 정보(예: 발신자 이름)를 동기화할 수 있게 됩니다."</string>
diff --git a/packages/CompanionDeviceManager/res/values-ky/strings.xml b/packages/CompanionDeviceManager/res/values-ky/strings.xml
index 099b5c5b74e1..bb1e1aa76958 100644
--- a/packages/CompanionDeviceManager/res/values-ky/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ky/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"түзмөк"</string>
<string name="summary_glasses" msgid="2872254734959842579">"Бул колдонмого <xliff:g id="DEVICE_NAME">%1$s</xliff:g> түзмөгүңүздө төмөнкүлөрдү аткарууга уруксат берилет"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; колдонмосуна телефонуңуздагы ушул маалыматты көрүүгө уруксат бериңиз"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Түзмөктөр аралык кызматтар"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> түзмөгүңүздүн атынан түзмөктөрүңүздүн ортосунда колдонмолорду алып ойнотууга уруксат сурап жатат"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; колдонмосуна телефонуңуздагы ушул маалыматты көрүүгө уруксат бериңиз"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play кызматтары"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосу <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> түзмөгүңүздүн атынан телефондогу сүрөттөрдү, медиа файлдарды жана билдирмелерди колдонууга уруксат сурап жатат"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; түзмөгүнө бул аракетти аткарууга уруксат бересизби?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="DEVICE_NAME">%2$s</xliff:g> түзмөгүңүздүн атынан жакын жердеги түзмөктөрдө колдонмолорду жана системанын башка функцияларын алып ойнотууга уруксат сурап жатат"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"түзмөк"</string>
<string name="summary_generic" msgid="1761976003668044801">"Бул колдонмо маалыматты шайкештире алат, мисалы, чалып жаткан кишинин атын телефон жана тандалган түзмөк менен шайкештирет"</string>
diff --git a/packages/CompanionDeviceManager/res/values-lo/strings.xml b/packages/CompanionDeviceManager/res/values-lo/strings.xml
index fa378ca0640f..9a45460f3c5f 100644
--- a/packages/CompanionDeviceManager/res/values-lo/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-lo/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"ອຸປະກອນ"</string>
<string name="summary_glasses" msgid="2872254734959842579">"ແອັບນີ້ຈະໄດ້ຮັບສິດເຂົ້າເຖິງການອະນຸຍາດເຫຼົ່ານີ້ຢູ່ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ຂອງທ່ານ"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"ອະນຸຍາດ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ໃຫ້ເຂົ້າເຖິງຂໍ້ມູນນີ້ຈາກໂທລະສັບຂອງທ່ານໄດ້"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"ບໍລິການຂ້າມອຸປະກອນ"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> ກຳລັງຮ້ອງຂໍການອະນຸຍາດໃນນາມຂອງ <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> ເພື່ອສະຕຣີມແອັບລະຫວ່າງອຸປະກອນຕ່າງໆຂອງທ່ານ"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"ອະນຸຍາດ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ໃຫ້ເຂົ້າເຖິງຂໍ້ມູນນີ້ຈາກໂທລະສັບຂອງທ່ານໄດ້"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"ບໍລິການ Google Play"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> ກຳລັງຮ້ອງຂໍການອະນຸຍາດໃນນາມຂອງ <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> ເພື່ອເຂົ້າເຖິງຮູບພາບ, ສື່ ແລະ ການແຈ້ງເຕືອນໃນໂທລະສັບຂອງທ່ານ"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"ອະນຸຍາດ &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; ເພື່ອດຳເນີນຄຳສັ່ງນີ້ບໍ?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> ກໍາລັງຮ້ອງຂໍການອະນຸຍາດໃນນາມ <xliff:g id="DEVICE_NAME">%2$s</xliff:g> ຂອງທ່ານເພື່ອສະຕຣີມແອັບ ແລະ ຄຸນສົມບັດລະບົບອື່ນໆໄປຫາອຸປະກອນທີ່ຢູ່ໃກ້ຄຽງ"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"ອຸປະກອນ"</string>
<string name="summary_generic" msgid="1761976003668044801">"ແອັບນີ້ຈະສາມາດຊິ້ງຂໍ້ມູນ ເຊັ່ນ: ຊື່ຂອງຄົນທີ່ໂທເຂົ້າ, ລະຫວ່າງໂທລະສັບຂອງທ່ານ ແລະ ອຸປະກອນທີ່ເລືອກໄວ້ໄດ້"</string>
diff --git a/packages/CompanionDeviceManager/res/values-lt/strings.xml b/packages/CompanionDeviceManager/res/values-lt/strings.xml
index 54f840863f22..58a9db91bf3e 100644
--- a/packages/CompanionDeviceManager/res/values-lt/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-lt/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"įrenginio"</string>
<string name="summary_glasses" msgid="2872254734959842579">"Šiai programai bus leidžiama pasiekti toliau nurodytus <xliff:g id="DEVICE_NAME">%1$s</xliff:g> leidimus."</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Leisti &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; pasiekti šią informaciją iš jūsų telefono"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Pasl. keliuose įrenginiuose"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"Programa „<xliff:g id="APP_NAME">%1$s</xliff:g>“ prašo leidimo jūsų „<xliff:g id="DISPLAY_NAME">%2$s</xliff:g>“ vardu, kad galėtų srautu perduoti programas iš vieno įrenginio į kitą"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Leisti &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; pasiekti šią informaciją iš jūsų telefono"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"„Google Play“ paslaugos"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"Programa „<xliff:g id="APP_NAME">%1$s</xliff:g>“ prašo leidimo jūsų „<xliff:g id="DISPLAY_NAME">%2$s</xliff:g>“ vardu, kad galėtų pasiekti telefono nuotraukas, mediją ir pranešimus"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"Leisti &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; atlikti šį veiksmą?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"„<xliff:g id="APP_NAME">%1$s</xliff:g>“ prašo leidimo jūsų „<xliff:g id="DEVICE_NAME">%2$s</xliff:g>“ vardu, kad galėtų srautu perduoti programas ir kitas sistemos funkcijas įrenginiams netoliese"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"įrenginys"</string>
<string name="summary_generic" msgid="1761976003668044801">"Ši programa galės sinchronizuoti tam tikrą informaciją, pvz., skambinančio asmens vardą, su jūsų telefonu ir pasirinktu įrenginiu"</string>
diff --git a/packages/CompanionDeviceManager/res/values-lv/strings.xml b/packages/CompanionDeviceManager/res/values-lv/strings.xml
index 390d54428de2..36908e418e35 100644
--- a/packages/CompanionDeviceManager/res/values-lv/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-lv/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"ierīce"</string>
<string name="summary_glasses" msgid="2872254734959842579">"Šai lietotnei tiks sniegta piekļuve norādītajām atļaujām jūsu ierīcē (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>)."</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Atļaut lietotnei &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; piekļūt šai informācijai no jūsu tālruņa"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Vairāku ierīču pakalpojumi"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"Lietotne <xliff:g id="APP_NAME">%1$s</xliff:g> pieprasa atļauju straumēt lietotnes starp jūsu ierīcēm šīs ierīces vārdā: <xliff:g id="DISPLAY_NAME">%2$s</xliff:g>."</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Atļaut lietotnei &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; piekļūt šai informācijai no jūsu tālruņa"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play pakalpojumi"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"Lietotne <xliff:g id="APP_NAME">%1$s</xliff:g> pieprasa atļauju piekļūt jūsu tālruņa fotoattēliem, multivides saturam un paziņojumiem šīs ierīces vārdā: <xliff:g id="DISPLAY_NAME">%2$s</xliff:g>."</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"Vai atļaut ierīcei &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; veikt šo darbību?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> pieprasa atļauju tuvumā esošās ierīcēs straumēt lietotnes un citas sistēmas funkcijas šīs ierīces vārdā: <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"ierīce"</string>
<string name="summary_generic" msgid="1761976003668044801">"Šī lietotne varēs sinhronizēt informāciju (piemēram, zvanītāja vārdu) starp jūsu tālruni un izvēlēto ierīci"</string>
diff --git a/packages/CompanionDeviceManager/res/values-mk/strings.xml b/packages/CompanionDeviceManager/res/values-mk/strings.xml
index dc15899c328c..b361ae2eaed0 100644
--- a/packages/CompanionDeviceManager/res/values-mk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-mk/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"уред"</string>
<string name="summary_glasses" msgid="2872254734959842579">"Апликацијава ќе може да пристапува до овие дозволи на <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Овозможете &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; да пристапува до овие податоци на телефонот"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Повеќенаменски услуги"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> бара дозвола во име на вашиот <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> за да стримува апликации помеѓу вашите уреди"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Дозволете &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; да пристапува до овие податоци на телефонот"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Услуги на Google Play"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> бара дозвола во име на вашиот <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> за да пристапува до фотографиите, аудиовизуелните содржини и известувањата на телефонот"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"Ќе дозволите &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; да го преземе ова дејство?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> бара дозвола во име на вашиот <xliff:g id="DEVICE_NAME">%2$s</xliff:g> за да стримува апликации и други системски функции на уредите во близина"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"уред"</string>
<string name="summary_generic" msgid="1761976003668044801">"Оваа апликација ќе може да ги синхронизира податоците како што се имињата на јавувачите помеѓу вашиот телефон и избраниот уред"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ml/strings.xml b/packages/CompanionDeviceManager/res/values-ml/strings.xml
index 6c09e6383e44..485dc98626e8 100644
--- a/packages/CompanionDeviceManager/res/values-ml/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ml/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"ഉപകരണം"</string>
<string name="summary_glasses" msgid="2872254734959842579">"നിങ്ങളുടെ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> എന്നതിൽ ഇനിപ്പറയുന്ന അനുമതികൾ ആക്സസ് ചെയ്യാൻ ഈ ആപ്പിനെ അനുവദിക്കും"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"നിങ്ങളുടെ ഫോണിൽ നിന്ന് ഈ വിവരങ്ങൾ ആക്‌സസ് ചെയ്യാൻ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ആപ്പിനെ അനുവദിക്കുക"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"ക്രോസ്-ഉപകരണ സേവനങ്ങൾ"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"നിങ്ങളുടെ ഉപകരണങ്ങളിൽ ഒന്നിൽ നിന്ന് അടുത്തതിലേക്ക് ആപ്പുകൾ സ്ട്രീം ചെയ്യാൻ <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> എന്ന ഉപകരണത്തിന് വേണ്ടി <xliff:g id="APP_NAME">%1$s</xliff:g> എന്നത് അനുമതി അഭ്യർത്ഥിക്കുന്നു"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"നിങ്ങളുടെ ഫോണിൽ നിന്ന് ഈ വിവരങ്ങൾ ആക്‌സസ് ചെയ്യാൻ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ആപ്പിനെ അനുവദിക്കുക"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play സേവനങ്ങൾ"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"നിങ്ങളുടെ ഫോണിലെ ഫോട്ടോകൾ, മീഡിയ, അറിയിപ്പുകൾ എന്നിവ ആക്സസ് ചെയ്യാൻ <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> എന്ന ഉപകരണത്തിന് വേണ്ടി <xliff:g id="APP_NAME">%1$s</xliff:g> അനുമതി അഭ്യർത്ഥിക്കുന്നു"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"ഈ പ്രവർത്തനം നടത്താൻ &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; എന്നതിനെ അനുവദിക്കണോ?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"സമീപമുള്ള ഉപകരണങ്ങളിൽ ആപ്പുകളും മറ്റ് സിസ്റ്റം ഫീച്ചറുകളും സ്ട്രീം ചെയ്യാൻ നിങ്ങളുടെ <xliff:g id="DEVICE_NAME">%2$s</xliff:g> എന്നതിന് വേണ്ടി <xliff:g id="APP_NAME">%1$s</xliff:g> അനുമതി അഭ്യർത്ഥിക്കുന്നു"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"ഉപകരണം"</string>
<string name="summary_generic" msgid="1761976003668044801">"വിളിക്കുന്നയാളുടെ പേര് പോലുള്ള വിവരങ്ങൾ നിങ്ങളുടെ ഫോണിനും തിരഞ്ഞെടുത്ത ഉപകരണത്തിനും ഇടയിൽ സമന്വയിപ്പിക്കുന്നതിന് ഈ ആപ്പിന് കഴിയും"</string>
diff --git a/packages/CompanionDeviceManager/res/values-mn/strings.xml b/packages/CompanionDeviceManager/res/values-mn/strings.xml
index 4cbccb48cae4..13d52d6b222e 100644
--- a/packages/CompanionDeviceManager/res/values-mn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-mn/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"төхөөрөмж"</string>
<string name="summary_glasses" msgid="2872254734959842579">"Энэ апп таны <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-н эдгээр зөвшөөрөлд хандах эрхтэй байх болно"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;-д таны утаснаас энэ мэдээлэлд хандахыг зөвшөөрнө үү"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Төхөөрөмж хоорондын үйлчилгээ"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"Таны төхөөрөмжүүд хооронд апп дамжуулахын тулд <xliff:g id="APP_NAME">%1$s</xliff:g> таны <xliff:g id="DISPLAY_NAME">%2$s</xliff:g>-н өмнөөс зөвшөөрөл хүсэж байна"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;-д таны утаснаас энэ мэдээлэлд хандахыг зөвшөөрнө үү"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play үйлчилгээ"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"Таны утасны зураг, медиа болон мэдэгдэлд хандахын тулд <xliff:g id="APP_NAME">%1$s</xliff:g> таны <xliff:g id="DISPLAY_NAME">%2$s</xliff:g>-н өмнөөс зөвшөөрөл хүсэж байна"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt;-д энэ үйлдлийг хийхийг зөвшөөрөх үү?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> таны <xliff:g id="DEVICE_NAME">%2$s</xliff:g>-н өмнөөс аппууд болон системийн бусад онцлогийг ойролцоох төхөөрөмжүүд рүү дамжуулах зөвшөөрөл хүсэж байна"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"төхөөрөмж"</string>
<string name="summary_generic" msgid="1761976003668044801">"Энэ апп залгаж буй хүний нэр зэрэг мэдээллийг таны утас болон сонгосон төхөөрөмжийн хооронд синк хийх боломжтой болно"</string>
diff --git a/packages/CompanionDeviceManager/res/values-mr/strings.xml b/packages/CompanionDeviceManager/res/values-mr/strings.xml
index a01759b4511d..7f77303846de 100644
--- a/packages/CompanionDeviceManager/res/values-mr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-mr/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"डिव्हाइस"</string>
<string name="summary_glasses" msgid="2872254734959842579">"या अ‍ॅपला तुमच्या <xliff:g id="DEVICE_NAME">%1$s</xliff:g> वर या परवानग्या अ‍ॅक्सेस करण्याची अनुमती असेल"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ला ही माहिती तुमच्या फोनवरून अ‍ॅक्सेस करण्यासाठी अनुमती द्या"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"क्रॉस-डिव्हाइस सेवा"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"तुमच्या डिव्हाइसदरम्यान ॲप्स स्ट्रीम करण्यासाठी <xliff:g id="APP_NAME">%1$s</xliff:g> हे तुमच्या <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> च्या वतीने परवानगीची विनंती करत आहे"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ला ही माहिती तुमच्या फोनवरून अ‍ॅक्सेस करण्यासाठी अनुमती द्या"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play सेवा"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"तुमच्या फोनमधील फोटो, मीडिया आणि सूचना ॲक्सेस करण्यासाठी <xliff:g id="APP_NAME">%1$s</xliff:g> हे तुमच्या <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> च्या वतीने परवानगीची विनंती करत आहे"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; ला ही कृती करण्याची अनुमती द्यायची आहे का?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> हे जवळपासच्या डिव्हाइसवर अ‍ॅप्स आणि इतर सिस्टीम वैशिष्‍ट्ये स्ट्रीम करण्यासाठी तुमच्या <xliff:g id="DEVICE_NAME">%2$s</xliff:g> च्या वतीने परवानगीची विनंती करा"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"डिव्हाइस"</string>
<string name="summary_generic" msgid="1761976003668044801">"हे ॲप तुमचा फोन आणि निवडलेल्या डिव्‍हाइसदरम्यान कॉल करत असलेल्‍या एखाद्या व्यक्तीचे नाव यासारखी माहिती सिंक करू शकेल"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ms/strings.xml b/packages/CompanionDeviceManager/res/values-ms/strings.xml
index 008535b7711d..66f8caf42882 100644
--- a/packages/CompanionDeviceManager/res/values-ms/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ms/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"peranti"</string>
<string name="summary_glasses" msgid="2872254734959842579">"Apl ini akan dibenarkan untuk mengakses kebenaran yang berikut pada <xliff:g id="DEVICE_NAME">%1$s</xliff:g> anda"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Benarkan &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; mengakses maklumat ini daripada telefon anda"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Perkhidmatan silang peranti"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> sedang meminta kebenaran bagi pihak <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> anda untuk menstrim apl antara peranti anda"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Benarkan &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; untuk mengakses maklumat ini daripada telefon anda"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Perkhidmatan Google Play"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> sedang meminta kebenaran bagi pihak <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> anda untuk mengakses foto, media dan pemberitahuan telefon anda"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"Benarkan &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; mengambil tindakan ini?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> sedang meminta kebenaran bagi pihak <xliff:g id="DEVICE_NAME">%2$s</xliff:g> anda untuk menstrim apl dan ciri sistem yang lain pada peranti berdekatan"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"peranti"</string>
<string name="summary_generic" msgid="1761976003668044801">"Apl ini akan dapat menyegerakkan maklumat seperti nama individu yang memanggil, antara telefon anda dengan peranti yang dipilih"</string>
diff --git a/packages/CompanionDeviceManager/res/values-my/strings.xml b/packages/CompanionDeviceManager/res/values-my/strings.xml
index 05a3e88fcf98..2192efab84ec 100644
--- a/packages/CompanionDeviceManager/res/values-my/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-my/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"စက်"</string>
<string name="summary_glasses" msgid="2872254734959842579">"သင့် <xliff:g id="DEVICE_NAME">%1$s</xliff:g> တွင် ၎င်းခွင့်ပြုချက်များရယူရန် ဤအက်ပ်ကိုခွင့်ပြုမည်"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ကို သင့်ဖုန်းမှ ဤအချက်အလက် သုံးခွင့်ပြုမည်"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"စက်များကြားသုံး ဝန်ဆောင်မှုများ"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> သည် သင်၏စက်များအကြား အက်ပ်များတိုက်ရိုက်လွှင့်ရန် <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> ကိုယ်စား ခွင့်ပြုချက်တောင်းနေသည်"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; အား သင့်ဖုန်းမှ ဤအချက်အလက် သုံးခွင့်ပြုခြင်း"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play ဝန်ဆောင်မှုများ"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> သည် သင့်ဖုန်း၏ ဓာတ်ပုံ၊ မီဒီယာနှင့် အကြောင်းကြားချက်များသုံးရန် <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> ကိုယ်စား ခွင့်ပြုချက်တောင်းနေသည်"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; ကို ဤသို့လုပ်ဆောင်ခွင့်ပြုမလား။"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> သည် အနီးတစ်ဝိုက်ရှိ အက်ပ်များနှင့် အခြားစနစ်အင်္ဂါရပ်များကို တိုက်ရိုက်ဖွင့်ရန် သင့် <xliff:g id="DEVICE_NAME">%2$s</xliff:g> ကိုယ်စား ခွင့်ပြုချက်တောင်းနေသည်"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"စက်"</string>
<string name="summary_generic" msgid="1761976003668044801">"ဤအက်ပ်သည် သင့်ဖုန်းနှင့် ရွေးထားသောစက်အကြား ခေါ်ဆိုသူ၏အမည်ကဲ့သို့ အချက်အလက်ကို စင့်ခ်လုပ်နိုင်ပါမည်"</string>
diff --git a/packages/CompanionDeviceManager/res/values-nb/strings.xml b/packages/CompanionDeviceManager/res/values-nb/strings.xml
index d910f2fc9904..2ad0f32cd225 100644
--- a/packages/CompanionDeviceManager/res/values-nb/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-nb/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"enheten"</string>
<string name="summary_glasses" msgid="2872254734959842579">"Denne appen får disse tillatelsene på <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Gi &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; tilgang til denne informasjonen fra telefonen din"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Tjenester på flere enheter"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> ber om tillatelse til å strømme apper mellom enhetene dine, på vegne av <xliff:g id="DISPLAY_NAME">%2$s</xliff:g>"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Gi &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; tilgang til denne informasjonen fra telefonen din"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play-tjenester"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> ber om tillatelse til å få tilgang til bilder, medier og varsler på telefonen din, på vegne av <xliff:g id="DISPLAY_NAME">%2$s</xliff:g>"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"Vil du la &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; gjøre dette?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> ber om tillatelse på vegne av <xliff:g id="DEVICE_NAME">%2$s</xliff:g> til å strømme apper og andre systemfunksjoner til enheter i nærheten"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"enhet"</string>
<string name="summary_generic" msgid="1761976003668044801">"Denne appen kan synkronisere informasjon som navnet til noen som ringer, mellom telefonen og den valgte enheten"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ne/strings.xml b/packages/CompanionDeviceManager/res/values-ne/strings.xml
index 2001af20dd6d..0d5cad878f8c 100644
--- a/packages/CompanionDeviceManager/res/values-ne/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ne/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"डिभाइस"</string>
<string name="summary_glasses" msgid="2872254734959842579">"तपाईंको <xliff:g id="DEVICE_NAME">%1$s</xliff:g> मा यो एपलाई निम्न अनुमति दिइने छ:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; लाई तपाईंको फोनमा भएको यो जानकारी हेर्ने तथा प्रयोग गर्ने अनुमति दिनुहोस्"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"क्रस-डिभाइस सेवाहरू"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> तपाईंको डिभाइस <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> को तर्फबाट तपाईंका कुनै एउटा डिभाइसबाट अर्को डिभाइसमा एप स्ट्रिम गर्ने अनुमति माग्दै छ"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; लाई तपाईंको फोनमा भएको यो जानकारी हेर्ने तथा प्रयोग गर्ने अनुमति दिनुहोस्"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play services"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> तपाईंको डिभाइस <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> को तर्फबाट तपाईंको फोनमा भएका फोटो, मिडिया र सूचनाहरू हेर्ने तथा प्रयोग गर्ने अनुमति माग्दै छ"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; लाई यो कार्य गर्ने अनुमति दिने हो?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> तपाईंको डिभाइस <xliff:g id="DEVICE_NAME">%2$s</xliff:g> को तर्फबाट नजिकैका डिभाइसहरूमा एप र सिस्टमका अन्य सुविधाहरू स्ट्रिम गर्ने अनुमति माग्दै छ"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"यन्त्र"</string>
<string name="summary_generic" msgid="1761976003668044801">"यो एपले तपाईंको फोन र तपाईंले छनौट गर्ने डिभाइसका बिचमा कल गर्ने व्यक्तिको नाम जस्ता जानकारी सिंक गर्न सक्ने छ।"</string>
diff --git a/packages/CompanionDeviceManager/res/values-nl/strings.xml b/packages/CompanionDeviceManager/res/values-nl/strings.xml
index e8ccb58e0361..b2c2818592a8 100644
--- a/packages/CompanionDeviceManager/res/values-nl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-nl/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"apparaat"</string>
<string name="summary_glasses" msgid="2872254734959842579">"Deze app krijgt toegang tot deze rechten op je <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; toegang geven tot deze informatie op je telefoon"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Cross-device-services"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> vraagt namens jouw <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> toestemming om apps te streamen tussen je apparaten"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; toegang geven tot deze informatie op je telefoon"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play-services"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> vraagt namens jouw <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> toegang tot de foto\'s, media en meldingen van je telefoon"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"Toestaan dat &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; deze actie uitvoert?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> vraagt namens je <xliff:g id="DEVICE_NAME">%2$s</xliff:g> toestemming om apps en andere systeemfuncties naar apparaten in de buurt te streamen"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"apparaat"</string>
<string name="summary_generic" msgid="1761976003668044801">"Deze app kan informatie, zoals de naam van iemand die belt, synchroniseren tussen je telefoon en het gekozen apparaat"</string>
diff --git a/packages/CompanionDeviceManager/res/values-or/strings.xml b/packages/CompanionDeviceManager/res/values-or/strings.xml
index 0bb47b8b249d..d5e9d85a609f 100644
--- a/packages/CompanionDeviceManager/res/values-or/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-or/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"ଡିଭାଇସ"</string>
<string name="summary_glasses" msgid="2872254734959842579">"ଆପଣଙ୍କ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>ରେ ଏହି ଅନୁମତିଗୁଡ଼ିକୁ ଆକ୍ସେସ କରିବା ପାଇଁ ଏହି ଆପକୁ ଅନୁମତି ଦିଆଯିବ"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"ଆପଣଙ୍କ ଫୋନରୁ ଏହି ସୂଚନାକୁ ଆକ୍ସେସ କରିବା ପାଇଁ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;କୁ ଅନୁମତି ଦିଅନ୍ତୁ"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"କ୍ରସ-ଡିଭାଇସ ସେବାଗୁଡ଼ିକ"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"ଆପଣଙ୍କ ଡିଭାଇସଗୁଡ଼ିକ ମଧ୍ୟରେ ଆପ୍ସକୁ ଷ୍ଟ୍ରିମ କରିବା ପାଇଁ <xliff:g id="APP_NAME">%1$s</xliff:g> ଆପଣଙ୍କର <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> ତରଫରୁ ଅନୁମତି ପାଇଁ ଅନୁରୋଧ କରୁଛି"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"ଆପଣଙ୍କ ଫୋନରୁ ଏହି ସୂଚନାକୁ ଆକ୍ସେସ କରିବା ପାଇଁ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;କୁ ଅନୁମତି ଦିଅନ୍ତୁ"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play ସେବାଗୁଡ଼ିକ"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"ଆପଣଙ୍କ ଫୋନର ଫଟୋ, ମିଡିଆ ଏବଂ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକୁ ଆକ୍ସେସ କରିବା ପାଇଁ <xliff:g id="APP_NAME">%1$s</xliff:g> ଆପଣଙ୍କର <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> ତରଫରୁ ଅନୁମତି ପାଇଁ ଅନୁରୋଧ କରୁଛି"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"ଏହି ପଦକ୍ଷେପ ନେବା ପାଇଁ &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt;କୁ ଅନୁମତି ଦେବେ?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"ଆଖପାଖର ଡିଭାଇସଗୁଡ଼ିକରେ ଆପ୍ସ ଏବଂ ଅନ୍ୟ ସିଷ୍ଟମ ଫିଚରଗୁଡ଼ିକୁ ଷ୍ଟ୍ରିମ କରିବା ପାଇଁ <xliff:g id="APP_NAME">%1$s</xliff:g> ଆପଣଙ୍କ <xliff:g id="DEVICE_NAME">%2$s</xliff:g> ତରଫରୁ ଅନୁମତି ପାଇଁ ଅନୁରୋଧ କରୁଛି"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"ଡିଭାଇସ୍"</string>
<string name="summary_generic" msgid="1761976003668044801">"ଆପଣଙ୍କ ଫୋନ ଏବଂ ବଛାଯାଇଥିବା ଡିଭାଇସ ମଧ୍ୟରେ, କଲ କରୁଥିବା ଯେ କୌଣସି ବ୍ୟକ୍ତିଙ୍କ ନାମ ପରି ସୂଚନା ସିଙ୍କ କରିବାକୁ ଏହି ଆପ ସକ୍ଷମ ହେବ"</string>
diff --git a/packages/CompanionDeviceManager/res/values-pa/strings.xml b/packages/CompanionDeviceManager/res/values-pa/strings.xml
index 445afa363e5d..8a89f06ebc2a 100644
--- a/packages/CompanionDeviceManager/res/values-pa/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pa/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"ਡੀਵਾਈਸ"</string>
<string name="summary_glasses" msgid="2872254734959842579">"ਇਸ ਐਪ ਨੂੰ ਤੁਹਾਡੇ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> \'ਤੇ ਇਨ੍ਹਾਂ ਇਜਾਜ਼ਤਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਹੋਵੇਗੀ"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ਨੂੰ ਤੁਹਾਡੇ ਫ਼ੋਨ ਤੋਂ ਇਸ ਜਾਣਕਾਰੀ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿਓ"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"ਕ੍ਰਾਸ-ਡੀਵਾਈਸ ਸੇਵਾਵਾਂ"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਤੁਹਾਡੇ <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> ਦੀ ਤਰਫ਼ੋਂ ਤੁਹਾਡੇ ਡੀਵਾਈਸਾਂ ਵਿਚਕਾਰ ਐਪਾਂ ਨੂੰ ਸਟ੍ਰੀਮ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਮੰਗ ਰਹੀ ਹੈ"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ਨੂੰ ਤੁਹਾਡੇ ਫ਼ੋਨ ਤੋਂ ਇਸ ਜਾਣਕਾਰੀ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿਓ"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play ਸੇਵਾਵਾਂ"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਤੁਹਾਡੇ <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> ਦੀ ਤਰਫ਼ੋਂ ਤੁਹਾਡੇ ਫ਼ੋਨ ਦੀਆਂ ਫ਼ੋਟੋਆਂ, ਮੀਡੀਆ ਅਤੇ ਸੂਚਨਾਵਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਮੰਗ ਰਹੀ ਹੈ"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"ਕੀ &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; ਨੂੰ ਇਹ ਕਾਰਵਾਈ ਕਰਨ ਦੀ ਆਗਿਆ ਦੇਣੀ ਹੈ?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਤੁਹਾਡੇ <xliff:g id="DEVICE_NAME">%2$s</xliff:g> ਦੀ ਤਰਫ਼ੋਂ ਨਜ਼ਦੀਕੀ ਡੀਵਾਈਸਾਂ \'ਤੇ ਐਪਾਂ ਅਤੇ ਹੋਰ ਸਿਸਟਮ ਸੰਬੰਧੀ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਨੂੰ ਸਟ੍ਰੀਮ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਮੰਗ ਰਹੀ ਹੈ"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"ਡੀਵਾਈਸ"</string>
<string name="summary_generic" msgid="1761976003668044801">"ਇਹ ਐਪ ਤੁਹਾਡੇ ਫ਼ੋਨ ਅਤੇ ਚੁਣੇ ਗਏ ਡੀਵਾਈਸ ਵਿਚਕਾਰ ਕਾਲਰ ਦੇ ਨਾਮ ਵਰਗੀ ਜਾਣਕਾਰੀ ਨੂੰ ਸਿੰਕ ਕਰ ਸਕੇਗੀ"</string>
diff --git a/packages/CompanionDeviceManager/res/values-pl/strings.xml b/packages/CompanionDeviceManager/res/values-pl/strings.xml
index aec7b68504ff..945f8491597f 100644
--- a/packages/CompanionDeviceManager/res/values-pl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pl/strings.xml
@@ -26,8 +26,11 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"urządzenie"</string>
<string name="summary_glasses" msgid="2872254734959842579">"Aplikacja będzie miała dostęp do tych uprawnień na Twoim urządzeniu (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>)"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Zezwól urządzeniu &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; na dostęp do tych informacji na Twoim telefonie"</string>
+ <string name="title_app_streaming_with_mirroring" msgid="3364582597581570658">"Zezwolić aplikacji &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; na strumieniowanie aplikacji z telefonu?"</string>
+ <string name="summary_app_streaming" msgid="295548145144086753">"%1$s będzie mieć dostęp do wszystkiego, co jest widoczne i odtwarzane na telefonie, w tym do dźwięku, zdjęć, haseł i wiadomości.&lt;br/&gt;&lt;br/&gt;%1$s będzie w stanie strumieniować aplikacje, dopóki nie usuniesz dostępu do tego uprawnienia."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Usługi na innym urządzeniu"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> prosi w imieniu urządzenia <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> o uprawnienia dotyczące strumieniowego odtwarzania treści z aplikacji na innym urządzeniu"</string>
+ <string name="helper_summary_app_streaming_with_mirroring" msgid="6138581029144467467">"<xliff:g id="APP_NAME">%1$s</xliff:g> prosi w imieniu urządzenia <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> o pozwolenie na wyświetlanie i strumieniowanie aplikacji między Twoimi urządzeniami"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Zezwól aplikacji &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; na dostęp do tych informacji na Twoim telefonie"</string>
@@ -35,6 +38,8 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Usługi Google Play"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> prosi w imieniu urządzenia <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> o uprawnienia dotyczące dostępu do zdjęć, multimediów i powiadomień na telefonie"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"Zezwolić urządzeniu &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; na wykonanie tego działania?"</string>
+ <string name="title_nearby_device_streaming_with_mirroring" msgid="242855799919611657">"Zezwolić urządzeniu &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; na strumieniowanie aplikacji i funkcji systemowych z telefonu?"</string>
+ <string name="summary_nearby_device_streaming" msgid="4039565463149145573">"%1$s będzie mieć dostęp do wszystkiego, co jest widoczne i odtwarzane na telefonie, w tym do dźwięku, zdjęć, danych do płatności, haseł i wiadomości.&lt;br/&gt;&lt;br/&gt;%1$s będzie w stanie strumieniować aplikacje i funkcje systemowe, dopóki nie usuniesz dostępu do tego uprawnienia."</string>
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> prosi w imieniu urządzenia <xliff:g id="DEVICE_NAME">%2$s</xliff:g> o uprawnienia do strumieniowego odtwarzania treści i innych funkcji systemowych na urządzeniach w pobliżu"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"urządzenie"</string>
<string name="summary_generic" msgid="1761976003668044801">"Ta aplikacja może synchronizować informacje takie jak imię i nazwisko osoby dzwoniącej między Twoim telefonem i wybranym urządzeniem"</string>
diff --git a/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml b/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml
index ef1d6cdd2bb5..41029b120b8f 100644
--- a/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"dispositivo"</string>
<string name="summary_glasses" msgid="2872254734959842579">"O app poderá acessar estas permissões no seu <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Permitir que o app &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acesse estas informações do smartphone"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Serviços entre dispositivos"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu dispositivo <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> para fazer streaming de apps entre seus dispositivos"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Autorizar que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acesse estas informações do smartphone"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play Services"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu dispositivo <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> para acessar fotos, mídia e notificações do smartphone"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"Permitir que o dispositivo &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; realize esta ação?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu dispositivo <xliff:g id="DEVICE_NAME">%2$s</xliff:g> para fazer streaming de apps e de outros recursos do sistema para dispositivos por perto"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
<string name="summary_generic" msgid="1761976003668044801">"O app poderá sincronizar informações, como o nome de quem está ligando, entre seu smartphone e o dispositivo escolhido"</string>
diff --git a/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml b/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml
index 1d96c0d45fd9..60a625ce13f5 100644
--- a/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"dispositivo"</string>
<string name="summary_glasses" msgid="2872254734959842579">"Esta app vai poder aceder a estas autorizações no seu <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Permita que a app &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; aceda a estas informações do seu telemóvel"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Serviços entre dispositivos"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"A app <xliff:g id="APP_NAME">%1$s</xliff:g> está a pedir autorização em nome do seu dispositivo <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> para fazer stream de apps entre os seus dispositivos"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Permita que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; aceda a estas informações do seu telemóvel"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Serviços do Google Play"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"A app <xliff:g id="APP_NAME">%1$s</xliff:g> está a pedir autorização em nome do seu dispositivo <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> para aceder às fotos, ao conteúdo multimédia e às notificações do seu telemóvel"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"Permitir que o dispositivo &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; faça esta ação?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"A app <xliff:g id="APP_NAME">%1$s</xliff:g> está a pedir autorização em nome do dispositivo <xliff:g id="DEVICE_NAME">%2$s</xliff:g> para fazer stream de apps e outras funcionalidades do sistema para dispositivos próximos"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
<string name="summary_generic" msgid="1761976003668044801">"Esta app vai poder sincronizar informações, como o nome do autor de uma chamada, entre o telemóvel e o dispositivo escolhido"</string>
diff --git a/packages/CompanionDeviceManager/res/values-pt/strings.xml b/packages/CompanionDeviceManager/res/values-pt/strings.xml
index ef1d6cdd2bb5..41029b120b8f 100644
--- a/packages/CompanionDeviceManager/res/values-pt/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pt/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"dispositivo"</string>
<string name="summary_glasses" msgid="2872254734959842579">"O app poderá acessar estas permissões no seu <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Permitir que o app &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acesse estas informações do smartphone"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Serviços entre dispositivos"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu dispositivo <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> para fazer streaming de apps entre seus dispositivos"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Autorizar que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; acesse estas informações do smartphone"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play Services"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu dispositivo <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> para acessar fotos, mídia e notificações do smartphone"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"Permitir que o dispositivo &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; realize esta ação?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu dispositivo <xliff:g id="DEVICE_NAME">%2$s</xliff:g> para fazer streaming de apps e de outros recursos do sistema para dispositivos por perto"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
<string name="summary_generic" msgid="1761976003668044801">"O app poderá sincronizar informações, como o nome de quem está ligando, entre seu smartphone e o dispositivo escolhido"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ro/strings.xml b/packages/CompanionDeviceManager/res/values-ro/strings.xml
index d2c3099ee2b7..70fc09082b9c 100644
--- a/packages/CompanionDeviceManager/res/values-ro/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ro/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"dispozitiv"</string>
<string name="summary_glasses" msgid="2872254734959842579">"Aplicația va putea să acceseze următoarele permisiuni pe <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Permite ca &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; să acceseze aceste informații de pe telefon"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Servicii pe mai multe dispozitive"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> solicită permisiunea pentru <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> de a reda în stream aplicații între dispozitivele tale"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Permite ca &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; să acceseze aceste informații de pe telefon"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Servicii Google Play"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> solicită permisiunea pentru <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> de a accesa fotografiile, conținutul media și notificările de pe telefon"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"Permiți ca &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; să realizeze această acțiune?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> solicită permisiunea pentru <xliff:g id="DEVICE_NAME">%2$s</xliff:g> de a reda în stream conținut din aplicații și alte funcții de sistem pe dispozitivele din apropiere"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"dispozitiv"</string>
<string name="summary_generic" msgid="1761976003668044801">"Aplicația va putea să sincronizeze informații, cum ar fi numele unui apelant, între telefonul tău și dispozitivul ales"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ru/strings.xml b/packages/CompanionDeviceManager/res/values-ru/strings.xml
index 77a2c46503d0..2072f90fa152 100644
--- a/packages/CompanionDeviceManager/res/values-ru/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ru/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"устройстве"</string>
<string name="summary_glasses" msgid="2872254734959842579">"Это приложение получит указанные разрешения на <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Разрешите приложению &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; получать эту информацию с вашего телефона"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Сервисы стриминга приложений"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"Приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" запрашивает разрешение от имени вашего устройства <xliff:g id="DISPLAY_NAME">%2$s</xliff:g>, чтобы транслировать приложения между устройствами."</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Разрешите приложению &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; получать эту информацию с вашего телефона"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Сервисы Google Play"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"Приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" запрашивает разрешение от имени вашего устройства <xliff:g id="DISPLAY_NAME">%2$s</xliff:g>, чтобы получить доступ к фотографиям, медиаконтенту и уведомлениям на телефоне."</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"Разрешить приложению &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; выполнять это действие?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"Приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" от имени вашего устройства \"<xliff:g id="DEVICE_NAME">%2$s</xliff:g>\" запрашивает разрешение транслировать приложения и системные функции на устройства поблизости."</string>
<string name="profile_name_generic" msgid="6851028682723034988">"устройство"</string>
<string name="summary_generic" msgid="1761976003668044801">"Приложение сможет синхронизировать информацию между телефоном и выбранным устройством, например данные из журнала звонков."</string>
diff --git a/packages/CompanionDeviceManager/res/values-si/strings.xml b/packages/CompanionDeviceManager/res/values-si/strings.xml
index 1ba83fdff6ba..6d252603010e 100644
--- a/packages/CompanionDeviceManager/res/values-si/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-si/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"උපාංගය"</string>
<string name="summary_glasses" msgid="2872254734959842579">"මෙම යෙදුමට ඔබේ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> මත මෙම අවසර වෙත ප්‍රවේශ වීමට ඉඩ දෙනු ලැබේ"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; හට ඔබගේ දුරකථනයෙන් මෙම තොරතුරුවලට ප්‍රවේශ වීමට ඉඩ දෙන්න"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"හරස්-උපාංග සේවා"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> ඔබේ <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> වෙනුවෙන් ඔබේ උපාංග අතර යෙදුම් ප්‍රවාහ කිරීමට අවසරය ඉල්ලමින් සිටියි"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; හට ඔබගේ දුරකථනයෙන් මෙම තොරතුරුවලට ප්‍රවේශ වීමට ඉඩ දෙන්න"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play සේවා"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> ඔබේ <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> වෙනුවෙන් ඔබේ දුරකථනයේ ඡායාරූප, මාධ්‍ය, සහ දැනුම්දීම් වෙත ප්‍රවේශ වීමට අවසරය ඉල්ලමින් සිටියි"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"මෙම ක්‍රියාව කිරීමට &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; හට ඉඩ දෙන්න ද?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> ඔබේ <xliff:g id="DEVICE_NAME">%2$s</xliff:g> වෙනුවෙන් යෙදුම් සහ අනෙකුත් පද්ධති විශේෂාංග අවට උපාංග වෙත ප්‍රවාහ කිරීමට අවසර ඉල්ලයි"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"උපාංගය"</string>
<string name="summary_generic" msgid="1761976003668044801">"මෙම යෙදුමට ඔබේ දුරකථනය සහ තෝරා ගත් උපාංගය අතර, අමතන කෙනෙකුගේ නම වැනි, තතු සමමුහුර්ත කිරීමට හැකි වනු ඇත"</string>
diff --git a/packages/CompanionDeviceManager/res/values-sk/strings.xml b/packages/CompanionDeviceManager/res/values-sk/strings.xml
index 637a24018759..b1653310141d 100644
--- a/packages/CompanionDeviceManager/res/values-sk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sk/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"zariadenie"</string>
<string name="summary_glasses" msgid="2872254734959842579">"Táto aplikácia bude mať prístup k týmto povoleniam v zariadení <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Povoľte aplikácii &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; prístup k týmto informáciám z vášho telefónu"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Služby pre viacero zariadení"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> vyžaduje pre zariadenie <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> povolenie streamovať aplikácie medzi vašimi zariadeniami."</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Povoľte aplikácii &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; prístup k týmto informáciám z vášho telefónu"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Služby Google Play"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> vyžaduje pre zariadenie <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> povolenie na prístup k fotkám, médiám a upozorneniam vášho telefónu"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"Chcete povoliť zariadeniu &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; vykonať túto akciu?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> vyžaduje pre zariadenie <xliff:g id="DEVICE_NAME">%2$s</xliff:g> povolenie streamovať aplikácie a ďalšie systémové funkcie do zariadení v okolí"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"zariadenie"</string>
<string name="summary_generic" msgid="1761976003668044801">"Táto aplikácia bude môcť synchronizovať informácie, napríklad meno volajúceho, medzi telefónom a vybraným zariadením"</string>
diff --git a/packages/CompanionDeviceManager/res/values-sl/strings.xml b/packages/CompanionDeviceManager/res/values-sl/strings.xml
index b03c27a9849f..6972fb405500 100644
--- a/packages/CompanionDeviceManager/res/values-sl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sl/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"naprava"</string>
<string name="summary_glasses" msgid="2872254734959842579">"Ta aplikacija bo lahko dostopala do teh dovoljenj v napravi »<xliff:g id="DEVICE_NAME">%1$s</xliff:g>«."</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Dovolite, da &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; dostopa do teh podatkov v vašem telefonu"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Storitve za zunanje naprave"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> v imenu naprave »<xliff:g id="DISPLAY_NAME">%2$s</xliff:g>« zahteva dovoljenje za pretočno predvajanje aplikacij v vaših napravah."</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Dovolite, da &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; dostopa do teh podatkov v vašem telefonu"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Storitve Google Play"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> v imenu naprave »<xliff:g id="DISPLAY_NAME">%2$s</xliff:g>« zahteva dovoljenje za dostop do fotografij, predstavnosti in obvestil v telefonu."</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"Ali napravi &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; dovolite izvedbo tega dejanja?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> v imenu naprave »<xliff:g id="DEVICE_NAME">%2$s</xliff:g>« zahteva dovoljenje za pretočno predvajanje aplikacij in drugih sistemskih funkcij v napravah v bližini."</string>
<string name="profile_name_generic" msgid="6851028682723034988">"naprava"</string>
<string name="summary_generic" msgid="1761976003668044801">"Ta aplikacija bo lahko sinhronizirala podatke, na primer ime klicatelja, v telefonu in izbrani napravi."</string>
diff --git a/packages/CompanionDeviceManager/res/values-sq/strings.xml b/packages/CompanionDeviceManager/res/values-sq/strings.xml
index 5eeeeb81ddf5..635e5c870842 100644
--- a/packages/CompanionDeviceManager/res/values-sq/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sq/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"pajisje"</string>
<string name="summary_glasses" msgid="2872254734959842579">"Këtij aplikacioni do t\'i lejohet qasja te këto leje në <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Lejo që &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; të ketë qasje në këtë informacion nga telefoni yt"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Shërbimet mes pajisjeve"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> po kërkon leje në emër të <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> për të transmetuar aplikacione ndërmjet pajisjeve të tua"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Lejo që &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; të ketë qasje në këtë informacion nga telefoni yt"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Shërbimet e Google Play"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> po kërkon leje në emër të <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> për të marrë qasje te fotografitë, media dhe njoftimet e telefonit tënd"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"Të lejohet që &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; të ndërmarrë këtë veprim?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> po kërkon leje në emër të (<xliff:g id="DEVICE_NAME">%2$s</xliff:g>) tënde për të transmetuar aplikacione dhe veçori të tjera të sistemit te pajisjet në afërsi"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"pajisja"</string>
<string name="summary_generic" msgid="1761976003668044801">"Ky aplikacion do të mund të sinkronizojë informacione, si p.sh emrin e dikujt që po telefonon, mes telefonit tënd dhe pajisjes së zgjedhur."</string>
diff --git a/packages/CompanionDeviceManager/res/values-sr/strings.xml b/packages/CompanionDeviceManager/res/values-sr/strings.xml
index 2271092fc804..af9e1945aa4c 100644
--- a/packages/CompanionDeviceManager/res/values-sr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sr/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"уређај"</string>
<string name="summary_glasses" msgid="2872254734959842579">"Овој апликацији ће бити дозвољено да приступа овим дозволама на вашем уређају (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>)"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Дозволите да &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; приступа овим информацијама са телефона"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Услуге на више уређаја"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> захтева дозволу у име уређаја <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> за стримовање апликација између уређаја"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Дозволите да &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; приступа овим информацијама са телефона"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play услуге"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> захтева дозволу у име уређаја <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> за приступ сликама, медијском садржају и обавештењима са телефона"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"Желите ли да дозволите да &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; обави ову радњу?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"Апликација <xliff:g id="APP_NAME">%1$s</xliff:g> захтева дозволу у име уређаја <xliff:g id="DEVICE_NAME">%2$s</xliff:g> да стримује апликације и друге системске функције на уређаје у близини"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"уређај"</string>
<string name="summary_generic" msgid="1761976003668044801">"Ова апликација ће моћи да синхронизује податке, попут имена особе која упућује позив, између телефона и одабраног уређаја"</string>
diff --git a/packages/CompanionDeviceManager/res/values-sv/strings.xml b/packages/CompanionDeviceManager/res/values-sv/strings.xml
index a8934768d1fb..fdde926e961c 100644
--- a/packages/CompanionDeviceManager/res/values-sv/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sv/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"enhet"</string>
<string name="summary_glasses" msgid="2872254734959842579">"Appen får tillåtelse att använda dessa behörigheter på din <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Ge &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; åtkomstbehörighet till denna information på telefonen"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Tjänster för flera enheter"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> begär behörighet att låta <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> streama appar mellan enheter"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Ge &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; åtkomstbehörighet till denna information på telefonen"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play-tjänster"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> begär behörighet att ge <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> åtkomst till foton, mediefiler och aviseringar på telefonen"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"Vill du tillåta att &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; utför denna åtgärd?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> begär behörighet att streama appar och andra systemfunktioner till enheter i närheten för din <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"enhet"</string>
<string name="summary_generic" msgid="1761976003668044801">"Den här appen kommer att kunna synkronisera information mellan telefonen och den valda enheten, till exempel namnet på någon som ringer"</string>
diff --git a/packages/CompanionDeviceManager/res/values-sw/strings.xml b/packages/CompanionDeviceManager/res/values-sw/strings.xml
index c35c407fcbd2..2fb4677564b0 100644
--- a/packages/CompanionDeviceManager/res/values-sw/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sw/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"kifaa"</string>
<string name="summary_glasses" msgid="2872254734959842579">"Programu hii itaruhusiwa kufikia ruhusa hizi kwenye <xliff:g id="DEVICE_NAME">%1$s</xliff:g> yako"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Ruhusu &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ifikie maelezo haya kutoka kwenye simu yako"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Huduma za kifaa kilichounganishwa kwingine"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"Programu ya <xliff:g id="APP_NAME">%1$s</xliff:g> inaomba ruhusa kwa niaba ya <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> yako ili itiririshe programu kati ya vifaa vyako"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Ruhusu &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ifikie maelezo haya kutoka kwenye simu yako"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Huduma za Google Play"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"Programu ya <xliff:g id="APP_NAME">%1$s</xliff:g> inaomba ruhusa kwa niaba ya <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> yako ili ifikie picha, maudhui na arifa za simu yako"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"Ungependa kuruhusu &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; itekeleze kitendo hiki?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> inaomba ruhusa kwa niaba ya <xliff:g id="DEVICE_NAME">%2$s</xliff:g> chako ili itiririshe programu na vipengele vingine vya mfumo kwenye vifaa vilivyo karibu"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"kifaa"</string>
<string name="summary_generic" msgid="1761976003668044801">"Programu hii itaweza kusawazisha maelezo, kama vile jina la mtu anayepiga simu, kati ya simu yako na kifaa ulichochagua"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ta/strings.xml b/packages/CompanionDeviceManager/res/values-ta/strings.xml
index 1efdca48be81..62a9c332124b 100644
--- a/packages/CompanionDeviceManager/res/values-ta/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ta/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"சாதனம்"</string>
<string name="summary_glasses" msgid="2872254734959842579">"உங்கள் <xliff:g id="DEVICE_NAME">%1$s</xliff:g> சாதனத்தில் இந்த அனுமதிகளை அணுக இந்த ஆப்ஸ் அனுமதிக்கப்படும்"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"மொபைலில் உள்ள இந்தத் தகவல்களை அணுக, &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ஆப்ஸை அனுமதிக்கவும்"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"பன்முக சாதன சேவைகள்"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"உங்கள் சாதனங்களுக்கு இடையே ஆப்ஸை ஸ்ட்ரீம் செய்ய உங்கள் <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> சார்பாக <xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸ் அனுமதியைக் கோருகிறது"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"உங்கள் மொபைலிலிருந்து இந்தத் தகவலை அணுக &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ஆப்ஸை அனுமதியுங்கள்"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play சேவைகள்"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"உங்கள் மொபைலில் உள்ள படங்கள், மீடியா, அறிவிப்புகள் ஆகியவற்றை அணுக உங்கள் <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> சார்பாக <xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸ் அனுமதியைக் கோருகிறது"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"இந்தச் செயலைச் செய்ய &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; ஐ அனுமதிக்கவா?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"அருகிலுள்ள சாதனங்களுக்கு ஆப்ஸையும் பிற சிஸ்டம் அம்சங்களையும் ஸ்ட்ரீம் செய்ய உங்கள் <xliff:g id="DEVICE_NAME">%2$s</xliff:g> சார்பாக <xliff:g id="APP_NAME">%1$s</xliff:g> அனுமதி கோருகிறது"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"சாதனம்"</string>
<string name="summary_generic" msgid="1761976003668044801">"அழைப்பவரின் பெயர் போன்ற தகவலை உங்கள் மொபைல் மற்றும் தேர்வுசெய்த சாதனத்திற்கு இடையில் இந்த ஆப்ஸால் ஒத்திசைக்க முடியும்"</string>
diff --git a/packages/CompanionDeviceManager/res/values-te/strings.xml b/packages/CompanionDeviceManager/res/values-te/strings.xml
index 3dd183e6acfc..4e26141922de 100644
--- a/packages/CompanionDeviceManager/res/values-te/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-te/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"పరికరం"</string>
<string name="summary_glasses" msgid="2872254734959842579">"మీ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>లో ఈ అనుమతులను యాక్సెస్ చేయడానికి ఈ యాప్ అనుమతించబడుతుంది"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"మీ ఫోన్ నుండి ఈ సమాచారాన్ని యాక్సెస్ చేయడానికి &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; యాప్‌ను అనుమతించండి"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Cross-device services"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"మీ పరికరాల మధ్య యాప్‌లను స్ట్రీమ్ చేయడానికి <xliff:g id="APP_NAME">%1$s</xliff:g> మీ <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> తరఫున అనుమతిని రిక్వెస్ట్ చేస్తోంది"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"మీ ఫోన్ నుండి ఈ సమాచారాన్ని యాక్సెస్ చేయడానికి &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; యాప్‌ను అనుమతించండి"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play సర్వీసులు"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> మీ ఫోన్‌లోని ఫోటోలను, మీడియాను, ఇంకా నోటిఫికేషన్‌లను యాక్సెస్ చేయడానికి మీ <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> తరఫున అనుమతిని రిక్వెస్ట్ చేస్తోంది"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"ఈ చర్యను అమలు చేయడానికి &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt;‌ను అనుమతించాలా?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"సమీపంలోని పరికరాలకు యాప్‌లను, ఇతర సిస్టమ్ ఫీచర్‌లను స్ట్రీమ్ చేయడానికి <xliff:g id="APP_NAME">%1$s</xliff:g> మీ <xliff:g id="DEVICE_NAME">%2$s</xliff:g> తరఫున అనుమతిని రిక్వెస్ట్ చేస్తోంది"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"పరికరం"</string>
<string name="summary_generic" msgid="1761976003668044801">"కాల్ చేస్తున్న వారి పేరు వంటి సమాచారాన్ని ఈ యాప్ మీ ఫోన్ కు, ఎంచుకున్న పరికరానికీ మధ్య సింక్ చేయగలుగుతుంది"</string>
diff --git a/packages/CompanionDeviceManager/res/values-th/strings.xml b/packages/CompanionDeviceManager/res/values-th/strings.xml
index 1ed5abf60da5..8be8b3437b34 100644
--- a/packages/CompanionDeviceManager/res/values-th/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-th/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"อุปกรณ์"</string>
<string name="summary_glasses" msgid="2872254734959842579">"แอปนี้จะได้รับสิทธิ์ดังต่อไปนี้ใน<xliff:g id="DEVICE_NAME">%1$s</xliff:g>ของคุณ"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"อนุญาตให้ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; เข้าถึงข้อมูลนี้จากโทรศัพท์ของคุณ"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"บริการข้ามอุปกรณ์"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> กำลังขอสิทธิ์ในนามของ <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> เพื่อสตรีมแอประหว่างอุปกรณ์ต่างๆ ของคุณ"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"อนุญาตให้ &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; เข้าถึงข้อมูลนี้จากโทรศัพท์ของคุณ"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"บริการ Google Play"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> กำลังขอสิทธิ์ในนามของ <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> เพื่อเข้าถึงรูปภาพ สื่อ และการแจ้งเตือนในโทรศัพท์ของคุณ"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"อนุญาตให้ &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; ทำงานนี้ไหม"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> กำลังขอสิทธิ์ในนามของ <xliff:g id="DEVICE_NAME">%2$s</xliff:g> เพื่อสตรีมแอปและฟีเจอร์อื่นๆ ของระบบไปยังอุปกรณ์ที่อยู่ใกล้เคียง"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"อุปกรณ์"</string>
<string name="summary_generic" msgid="1761976003668044801">"แอปนี้จะสามารถซิงค์ข้อมูล เช่น ชื่อของบุคคลที่โทรเข้ามา ระหว่างโทรศัพท์ของคุณและอุปกรณ์ที่เลือกไว้ได้"</string>
diff --git a/packages/CompanionDeviceManager/res/values-tl/strings.xml b/packages/CompanionDeviceManager/res/values-tl/strings.xml
index 1b82d91836ea..45bc01d98d76 100644
--- a/packages/CompanionDeviceManager/res/values-tl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-tl/strings.xml
@@ -26,8 +26,11 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"device"</string>
<string name="summary_glasses" msgid="2872254734959842579">"Papayagan ang app na ito na i-access ang mga pahintulot na ito sa iyong <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Payagan ang &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; na i-access ang impormasyong ito sa iyong telepono"</string>
+ <string name="title_app_streaming_with_mirroring" msgid="3364582597581570658">"Payagan ang &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; na i-stream ang mga app ng iyong telepono?"</string>
+ <string name="summary_app_streaming" msgid="295548145144086753">"Magkakaroon ng access ang %1$s sa kahit anong nakikita o nape-play sa telepono, kasama ang audio, mga larawan, mga password, at mga mensahe.&lt;br/&gt;&lt;br/&gt;Makakapag-stream ng mga app ang %1$s hanggang sa alisin mo ang access sa pahintulot na ito."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Mga cross-device na serbisyo"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"Ang <xliff:g id="APP_NAME">%1$s</xliff:g> ay humihiling ng pahintulot sa ngalan ng iyong <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> para mag-stream ng mga app sa pagitan ng mga device mo"</string>
+ <string name="helper_summary_app_streaming_with_mirroring" msgid="6138581029144467467">"Humihiling ng pahintulot ang <xliff:g id="APP_NAME">%1$s</xliff:g> para sa iyong <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> na makapagpakita at makapag-stream ng mga app sa mga device mo"</string>
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Payagan ang &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; na i-access ang impormasyon sa iyong telepono"</string>
@@ -35,6 +38,8 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Mga serbisyo ng Google Play"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"Ang <xliff:g id="APP_NAME">%1$s</xliff:g> ay humihiling ng pahintulot sa ngalan ng iyong <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> para i-access ang mga larawan, media, at notification ng telepono mo"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"Payagan ang &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; na gawin ang pagkilos na ito?"</string>
+ <string name="title_nearby_device_streaming_with_mirroring" msgid="242855799919611657">"Payagan ang &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; na i-stream ang mga app at feature ng system ng iyong telepono?"</string>
+ <string name="summary_nearby_device_streaming" msgid="4039565463149145573">"Magkakaroon ng access ang %1$s sa kahit anong nakikita o nape-play sa iyong telepono, kasama ang audio, mga larawan, impormasyon sa pagbabayad, mga password, at mga mensahe.&lt;br/&gt;&lt;br/&gt;Makakapag-stream ng mga app at feature ng system ang %1$s hanggang sa alisin mo ang access sa pahintulot na ito."</string>
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"Humihiling ang <xliff:g id="APP_NAME">%1$s</xliff:g> ng pahintulot sa ngalan ng iyong <xliff:g id="DEVICE_NAME">%2$s</xliff:g> para mag-stream ng mga app at iba pang feature ng system sa mga kalapit na device"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"device"</string>
<string name="summary_generic" msgid="1761976003668044801">"Magagawa ng app na ito na mag-sync ng impormasyon, tulad ng pangalan ng isang taong tumatawag, sa pagitan ng iyong telepono at ng napiling device"</string>
diff --git a/packages/CompanionDeviceManager/res/values-tr/strings.xml b/packages/CompanionDeviceManager/res/values-tr/strings.xml
index 392e1585a6ac..d5c51e8b7446 100644
--- a/packages/CompanionDeviceManager/res/values-tr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-tr/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"Cihaz"</string>
<string name="summary_glasses" msgid="2872254734959842579">"Bu uygulamanın <xliff:g id="DEVICE_NAME">%1$s</xliff:g> cihazınızda şu izinlere erişmesine izin verilecek:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; uygulamasının, telefonunuzdaki bu bilgilere erişmesine izin verin"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Cihazlar arası hizmetler"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g>, cihazlarınız arasında uygulama akışı gerçekleştirmek için <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> cihazınız adına izin istiyor"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; uygulamasının, telefonunuzdaki bu bilgilere erişmesine izin verin"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play Hizmetleri"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g>, telefonunuzdaki fotoğraf, medya ve bildirimlere erişmek için <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> cihazınız adına izin istiyor"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; cihazının bu işlemi yapmasına izin verilsin mi?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> uygulaması <xliff:g id="DEVICE_NAME">%2$s</xliff:g> cihazınız adına uygulamaları ve diğer sistem özelliklerini yakındaki cihazlara aktarmak için izin istiyor"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"cihaz"</string>
<string name="summary_generic" msgid="1761976003668044801">"Bu uygulama, arayan kişinin adı gibi bilgileri telefonunuz ve seçili cihaz arasında senkronize edebilir"</string>
diff --git a/packages/CompanionDeviceManager/res/values-uk/strings.xml b/packages/CompanionDeviceManager/res/values-uk/strings.xml
index 9f88d9f3f852..97a3dbc17993 100644
--- a/packages/CompanionDeviceManager/res/values-uk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-uk/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"пристрій"</string>
<string name="summary_glasses" msgid="2872254734959842579">"Цей додаток матиме доступ до перелічених нижче дозволів на вашому <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Надайте додатку &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; доступ до цієї інформації з телефона"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Сервіси для кількох пристроїв"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"Додаток <xliff:g id="APP_NAME">%1$s</xliff:g> від імені вашого пристрою \"<xliff:g id="DISPLAY_NAME">%2$s</xliff:g>\" запитує дозвіл на трансляцію додатків між вашими пристроями"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Надайте пристрою &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; доступ до цієї інформації з телефона"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Сервіси Google Play"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"Додаток <xliff:g id="APP_NAME">%1$s</xliff:g> від імені вашого пристрою \"<xliff:g id="DISPLAY_NAME">%2$s</xliff:g>\" запитує дозвіл на доступ до фотографій, медіафайлів і сповіщень вашого телефона"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"Дозволити додатку &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; виконувати цю дію?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"Додаток <xliff:g id="APP_NAME">%1$s</xliff:g> від імені вашого пристрою (<xliff:g id="DEVICE_NAME">%2$s</xliff:g>) запитує дозвіл на трансляцію додатків та інших системних функцій на пристрої поблизу"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"пристрій"</string>
<string name="summary_generic" msgid="1761976003668044801">"Цей додаток зможе синхронізувати інформацію (наприклад, ім’я абонента, який викликає) між телефоном і вибраним пристроєм"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ur/strings.xml b/packages/CompanionDeviceManager/res/values-ur/strings.xml
index 36f8b4f8b5f1..52826b30e7b7 100644
--- a/packages/CompanionDeviceManager/res/values-ur/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ur/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"آلہ"</string>
<string name="summary_glasses" msgid="2872254734959842579">"اس ایپ کو آپ کے <xliff:g id="DEVICE_NAME">%1$s</xliff:g> پر ان اجازتوں تک رسائی کی اجازت ہوگی"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"‏اپنے فون سے ان معلومات تک رسائی حاصل کرنے کی &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; کو اجازت دیں"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"کراس ڈیوائس سروسز"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> ایپ آپ کے <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> کی جانب سے آپ کے آلات کے درمیان ایپس کی سلسلہ بندی کرنے کی اجازت کی درخواست کر رہی ہے"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"‏اپنے فون سے اس معلومات تک رسائی حاصل کرنے کی &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; کو اجازت دیں"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"‏Google Play سروسز"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> ایپ آپ کے <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> کی جانب سے آپ کے فون کی تصاویر، میڈیا اور اطلاعات تک رسائی کی اجازت کی درخواست کر رہی ہے"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"‏&lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; کو یہ کارروائی انجام دینے کی اجازت دیں؟"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> آپ کے <xliff:g id="DEVICE_NAME">%2$s</xliff:g> کی جانب سے ایپس اور سسٹم کی دیگر خصوصیات کی سلسلہ بندی قریبی آلات پر کرنے کی اجازت طلب کر رہی ہے"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"آلہ"</string>
<string name="summary_generic" msgid="1761976003668044801">"یہ ایپ آپ کے فون اور منتخب کردہ آلے کے درمیان معلومات، جیسے کسی کال کرنے والے کے نام، کی مطابقت پذیری کر سکے گی"</string>
diff --git a/packages/CompanionDeviceManager/res/values-uz/strings.xml b/packages/CompanionDeviceManager/res/values-uz/strings.xml
index 8defcbc82e53..b2c81e185ea4 100644
--- a/packages/CompanionDeviceManager/res/values-uz/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-uz/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"qurilma"</string>
<string name="summary_glasses" msgid="2872254734959842579">"Bu ilova <xliff:g id="DEVICE_NAME">%1$s</xliff:g> qurilmasida quyidagi ruxsatlarni oladi"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ilovasiga telefondagi ushbu maʼlumot uchun ruxsat bering"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Qurilmalararo xizmatlar"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"Qurilamalararo ilovalar strimingi uchun <xliff:g id="APP_NAME">%1$s</xliff:g> ilovasi <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> nomidan ruxsat soʻramoqda"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ilovasiga telefondagi ushbu maʼlumot uchun ruxsat bering"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play xizmatlari"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"Telefoningizdagi rasm, media va bildirishnomalarga kirish uchun <xliff:g id="APP_NAME">%1$s</xliff:g> ilovasi <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> nomidan ruxsat soʻramoqda"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; ilovasiga bu amalni bajarish uchun ruxsat berilsinmi?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> ilovasi <xliff:g id="DEVICE_NAME">%2$s</xliff:g> qurilmangizdan nomidan atrofdagi qurilmalarga ilova va boshqa tizim funksiyalarini uzatish uchun ruxsat olmoqchi"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"qurilma"</string>
<string name="summary_generic" msgid="1761976003668044801">"Bu ilova telefoningiz va tanlangan qurilmada chaqiruvchining ismi kabi maʼlumotlarni sinxronlay oladi"</string>
diff --git a/packages/CompanionDeviceManager/res/values-vi/strings.xml b/packages/CompanionDeviceManager/res/values-vi/strings.xml
index 779700824fbf..ae6fc7fefa9b 100644
--- a/packages/CompanionDeviceManager/res/values-vi/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-vi/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"thiết bị"</string>
<string name="summary_glasses" msgid="2872254734959842579">"Ứng dụng này sẽ được phép dùng những quyền sau trên <xliff:g id="DEVICE_NAME">%1$s</xliff:g> của bạn"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Cho phép &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; truy cập vào thông tin này trên điện thoại của bạn"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Dịch vụ trên nhiều thiết bị"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> đang yêu cầu quyền thay cho <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> để truyền trực tuyến ứng dụng giữa các thiết bị của bạn"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Cho phép &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; truy cập vào thông tin này trên điện thoại của bạn"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Dịch vụ Google Play"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> đang yêu cầu quyền thay cho <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> để truy cập vào ảnh, nội dung nghe nhìn và thông báo trên điện thoại của bạn"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"Cho phép &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; thực hiện hành động này?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> đang thay <xliff:g id="DEVICE_NAME">%2$s</xliff:g> yêu cầu quyền truyền trực tuyến ứng dụng và các tính năng khác của hệ thống đến các thiết bị ở gần"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"thiết bị"</string>
<string name="summary_generic" msgid="1761976003668044801">"Ứng dụng này sẽ đồng bộ hoá thông tin (ví dụ: tên người gọi) giữa điện thoại của bạn và thiết bị bạn chọn"</string>
diff --git a/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml
index 11e3332f2758..8bc828738590 100644
--- a/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"设备"</string>
<string name="summary_glasses" msgid="2872254734959842579">"该应用将可以获得您<xliff:g id="DEVICE_NAME">%1$s</xliff:g>上的以下权限"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"允许“<xliff:g id="APP_NAME">%1$s</xliff:g>”&lt;strong&gt;&lt;/strong&gt;访问您手机中的这项信息"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"跨设备服务"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"“<xliff:g id="APP_NAME">%1$s</xliff:g>”正代表您的<xliff:g id="DISPLAY_NAME">%2$s</xliff:g>请求在您的设备之间流式传输应用内容"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"允许 &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; 访问您手机中的这项信息"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play 服务"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"“<xliff:g id="APP_NAME">%1$s</xliff:g>”正代表您的<xliff:g id="DISPLAY_NAME">%2$s</xliff:g>请求访问您手机上的照片、媒体内容和通知"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"允许&lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt;进行此操作?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"“<xliff:g id="APP_NAME">%1$s</xliff:g>”正代表您的<xliff:g id="DEVICE_NAME">%2$s</xliff:g>请求将应用和其他系统功能流式传输到附近的设备"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"设备"</string>
<string name="summary_generic" msgid="1761976003668044801">"此应用将能在您的手机和所选设备之间同步信息,例如来电者的姓名"</string>
diff --git a/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml
index e340d5a91c13..a085893e8b28 100644
--- a/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"裝置"</string>
<string name="summary_glasses" msgid="2872254734959842579">"此應用程式將可在<xliff:g id="DEVICE_NAME">%1$s</xliff:g>上取得以下權限"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」&lt;strong&gt;&lt;/strong&gt;存取你手機中的這項資料"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"跨裝置服務"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在代表 <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> 要求權限,以便在裝置間串流應用程式的內容"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」&lt;strong&gt;&lt;/strong&gt;存取你手機中的這項資料"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play 服務"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在代表 <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> 要求權限,以便存取手機上的相片、媒體和通知"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"要允許「<xliff:g id="DEVICE_NAME">%1$s</xliff:g>」&lt;strong&gt;&lt;/strong&gt;執行此操作嗎?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在代表「<xliff:g id="DEVICE_NAME">%2$s</xliff:g>」要求權限,才能在附近的裝置上串流播放應用程式和其他系統功能"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"裝置"</string>
<string name="summary_generic" msgid="1761976003668044801">"此應用程式將可同步手機和所選裝置的資訊,例如來電者的名稱"</string>
diff --git a/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml
index 82ad021a082b..a93034ff96a0 100644
--- a/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"裝置"</string>
<string name="summary_glasses" msgid="2872254734959842579">"這個應用程式將可取得<xliff:g id="DEVICE_NAME">%1$s</xliff:g>上的這些權限"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」&lt;strong&gt;&lt;/strong&gt;存取手機中的這項資訊"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"跨裝置服務"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"為了在裝置間串流傳輸應用程式內容,「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在代表 <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> 要求相關權限"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」&lt;strong&gt;&lt;/strong&gt;存取你手機中的這項資訊"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play 服務"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"為了存取手機上的相片、媒體和通知,「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在代表 <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> 要求相關權限"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"要允許「<xliff:g id="DEVICE_NAME">%1$s</xliff:g>」&lt;strong&gt;&lt;/strong&gt;執行這項操作嗎?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在代表「<xliff:g id="DEVICE_NAME">%2$s</xliff:g>」要求必要權限,才能在鄰近裝置上串流播放應用程式和其他系統功能"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"裝置"</string>
<string name="summary_generic" msgid="1761976003668044801">"這個應用程式將可在手機和指定裝置間同步資訊,例如來電者名稱"</string>
diff --git a/packages/CompanionDeviceManager/res/values-zu/strings.xml b/packages/CompanionDeviceManager/res/values-zu/strings.xml
index c35ff6aaa3bf..ddda3e35d29e 100644
--- a/packages/CompanionDeviceManager/res/values-zu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zu/strings.xml
@@ -26,8 +26,14 @@
<string name="profile_name_glasses" msgid="3506504967216601277">"idivayisi"</string>
<string name="summary_glasses" msgid="2872254734959842579">"Le-app izovunyelwa ukufinyelela lezi zimvume ku-<xliff:g id="DEVICE_NAME">%1$s</xliff:g> yakho"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Vumela i-&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ifinyelele lolu lwazi kusukela efonini yakho"</string>
+ <!-- no translation found for title_app_streaming_with_mirroring (3364582597581570658) -->
+ <skip />
+ <!-- no translation found for summary_app_streaming (295548145144086753) -->
+ <skip />
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Amasevisi amadivayisi amaningi"</string>
<string name="helper_summary_app_streaming" msgid="2396773196949578425">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> icela imvume esikhundleni se-<xliff:g id="DISPLAY_NAME">%2$s</xliff:g> yakho ukuze isakaze-bukhoma ama-app phakathi kwamadivayisi akho"</string>
+ <!-- no translation found for helper_summary_app_streaming_with_mirroring (6138581029144467467) -->
+ <skip />
<string name="title_automotive_projection" msgid="3296005598978412847"></string>
<string name="summary_automotive_projection" msgid="8683801274662496164"></string>
<string name="title_computer" msgid="4693714143506569253">"Vumela &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ukufinyelela lolu lwazi kusuka efonini yakho"</string>
@@ -35,6 +41,10 @@
<string name="helper_title_computer" msgid="4671071173916176037">"Amasevisi we-Google Play"</string>
<string name="helper_summary_computer" msgid="8774832742608187072">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> icela imvume esikhundleni se-<xliff:g id="DISPLAY_NAME">%2$s</xliff:g> yakho ukuze ifinyelele izithombe zefoni yakho, imidiya nezaziso"</string>
<string name="title_nearby_device_streaming" msgid="7269956847378799794">"Vumela i-<xliff:g id="DEVICE_NAME">%1$s</xliff:g> ukwenza lesi senzo?"</string>
+ <!-- no translation found for title_nearby_device_streaming_with_mirroring (242855799919611657) -->
+ <skip />
+ <!-- no translation found for summary_nearby_device_streaming (4039565463149145573) -->
+ <skip />
<string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> icela imvume esikhundleni se-<xliff:g id="DEVICE_NAME">%2$s</xliff:g> ukusakaza ama-app nezinye izakhi zesistimu kumadivayisi aseduze"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"idivayisi"</string>
<string name="summary_generic" msgid="1761976003668044801">"Le app izokwazi ukuvumelanisa ulwazi, njengegama lomuntu othile ofonayo, phakathi kwefoni yakho nedivayisi ekhethiwe"</string>
diff --git a/packages/CrashRecovery/services/java/com/android/server/RescueParty.java b/packages/CrashRecovery/services/java/com/android/server/RescueParty.java
index d0fee44f791f..7bdc1a0e3ac7 100644
--- a/packages/CrashRecovery/services/java/com/android/server/RescueParty.java
+++ b/packages/CrashRecovery/services/java/com/android/server/RescueParty.java
@@ -163,10 +163,8 @@ public class RescueParty {
* Check if we're currently attempting to reboot for a factory reset. This method must
* return true if RescueParty tries to reboot early during a boot loop, since the device
* will not be fully booted at this time.
- *
- * TODO(gavincorkery): Rename method since its scope has expanded.
*/
- public static boolean isAttemptingFactoryReset() {
+ public static boolean isRecoveryTriggeredReboot() {
return isFactoryResetPropertySet() || isRebootPropertySet();
}
diff --git a/packages/CredentialManager/res/values-uz/strings.xml b/packages/CredentialManager/res/values-uz/strings.xml
index 4e27d3e71fd9..8b9cecd6f6f6 100644
--- a/packages/CredentialManager/res/values-uz/strings.xml
+++ b/packages/CredentialManager/res/values-uz/strings.xml
@@ -61,7 +61,7 @@
<string name="more_options_usage_passwords" msgid="1632047277723187813">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> ta parol"</string>
<string name="more_options_usage_passkeys" msgid="5390320437243042237">"<xliff:g id="PASSKEYSNUMBER">%1$s</xliff:g> ta kalit"</string>
<string name="more_options_usage_credentials" msgid="1785697001787193984">"<xliff:g id="TOTALCREDENTIALSNUMBER">%1$s</xliff:g> hisobi maʼlumotlari"</string>
- <string name="passkey_before_subtitle" msgid="2448119456208647444">"Kod"</string>
+ <string name="passkey_before_subtitle" msgid="2448119456208647444">"Kirish kaliti"</string>
<string name="another_device" msgid="5147276802037801217">"Boshqa qurilma"</string>
<string name="other_password_manager" msgid="565790221427004141">"Boshqa parol menejerlari"</string>
<string name="close_sheet" msgid="1393792015338908262">"Varaqni yopish"</string>
diff --git a/packages/SettingsLib/SearchWidget/res/values-fr-rCA/strings.xml b/packages/SettingsLib/SearchWidget/res/values-fr-rCA/strings.xml
index 9977138f2079..1b22e9e3af8a 100644
--- a/packages/SettingsLib/SearchWidget/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/SearchWidget/res/values-fr-rCA/strings.xml
@@ -17,5 +17,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="search_menu" msgid="1914043873178389845">"Rechercher dans les paramètres"</string>
+ <string name="search_menu" msgid="1914043873178389845">"Recherchez dans les paramètres"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index cc23f6eedf9a..530198522c98 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"Kon nie \'n nuwe gebruiker skep nie"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Kon nie ’n nuwe gas skep nie"</string>
<string name="user_nickname" msgid="262624187455825083">"Bynaam"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"Jou naam en prent sal sigbaar wees vir enigiemand wat hierdie toestel gebruik."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"Voeg gebruiker by"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Voeg gas by"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Verwyder gas"</string>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index 0ecd376626c4..c5c5cdd0b899 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"አዲስ ተጠቃሚን መፍጠር አልተሳካም"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"አዲስ እንግዳ መፍጠር አልተሳካም"</string>
<string name="user_nickname" msgid="262624187455825083">"ቅጽል ስም"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"ይህን መሳሪያ ለሚጠቀም ማንኛውም ሰው ስምዎ እና ምስልዎ ይታያል።"</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"ተጠቃሚን አክል"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"እንግዳን አክል"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"እንግዳን አስወግድ"</string>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index 1f313aef239c..4fda845defb2 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"تعذّر إنشاء مستخدم جديد."</string>
<string name="add_guest_failed" msgid="8074548434469843443">"تعذّر إنشاء جلسة ضيف جديدة."</string>
<string name="user_nickname" msgid="262624187455825083">"اللقب"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"سيكون اسمك وصورتك مرئيَين لأي شخص يستخدم هذا الجهاز."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"إضافة مستخدم"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"إضافة ضيف"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"إزالة جلسة الضيف"</string>
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index a4be8e997311..2d14a8265c89 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"নতুন ব্যৱহাৰকাৰী সৃষ্টি কৰিব পৰা নগ’ল"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"নতুন অতিথি সৃষ্টি কৰিব পৰা নগ’ল"</string>
<string name="user_nickname" msgid="262624187455825083">"উপনাম"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"এই ডিভাইচটো ব্যৱহাৰ কৰা যিকোনো লোকে আপোনাৰ নাম আৰু চিত্ৰ দেখা পাব।"</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"ব্যৱহাৰকাৰী যোগ দিয়ক"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"অতিথি যোগ দিয়ক"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"অতিথি আঁতৰাওক"</string>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index df6dad208bd8..0e3e99aa8b24 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"Yeni istifadəçi yaratmaq alınmadı"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Yeni qonaq yaratmaq alınmadı"</string>
<string name="user_nickname" msgid="262624187455825083">"Ləqəb"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"Ad və şəklinizi bu cihazdan istifadə edən hər kəs görəcək."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"İstifadəçi əlavə edin"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Qonaq əlavə edin"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Qonağı silin"</string>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index 8bb8c838ed39..c674a445e171 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"Pravljenje novog korisnika nije uspelo"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Pravljenje novog gosta nije uspelo"</string>
<string name="user_nickname" msgid="262624187455825083">"Nadimak"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"Ime i slika će biti vidljivi svakom ko koristi ovaj uređaj."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"Dodaj korisnika"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Dodaj gosta"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Ukloni gosta"</string>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index 433c2430a40d..9fe0680fbc74 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"Не ўдалося стварыць новага карыстальніка"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Не ўдалося стварыць новага госця"</string>
<string name="user_nickname" msgid="262624187455825083">"Псеўданім"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"Ваша імя і відарыс профілю будуць бачныя ўсім, хто выкарыстоўвае гэту прыладу."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"Дадаць карыстальніка"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Дадаць госця"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Выдаліць госця"</string>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index 27e27bef4f3a..b79c0e946a29 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"Неуспешно създаване на нов потребител"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Създаването на нов гост не бе успешно"</string>
<string name="user_nickname" msgid="262624187455825083">"Псевдоним"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"Вашето име и снимка няма да бъдат видими за нито един потребител, който използва това устройство."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"Добавяне на потреби­тел"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Добавяне на гост"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Премахване на госта"</string>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index 2cf055654f3b..31f693b813fa 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"নতুন ব্যবহারকারী যোগ করা যায়নি"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"নতুন অতিথি তৈরি করা যায়নি"</string>
<string name="user_nickname" msgid="262624187455825083">"বিশেষ নাম"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"এই ডিভাইস ব্যবহার করেন এমন যেকেউ আপনার নাম ও ছবি দেখতে পাবেন।"</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"ব্যবহারকারীর অ্যাকাউন্ট যোগ করুন"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"অতিথি যোগ করুন"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"অতিথি সরান"</string>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index 64ccf98c3aa8..db203d6e8ef9 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"Kreiranje novog korisnika nije uspjelo"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Kreiranje novog gosta nije uspjelo"</string>
<string name="user_nickname" msgid="262624187455825083">"Nadimak"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"Vaše ime i slika će biti vidljivi svakom ko koristi ovaj uređaj."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"Dodavanje korisnika"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Dodavanje gosta"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Ukloni gosta"</string>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 81f9e97a2203..262adba02e1b 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"No s\'ha pogut crear l\'usuari"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"No s\'ha pogut crear un convidat"</string>
<string name="user_nickname" msgid="262624187455825083">"Àlies"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"El teu nom i la teva foto seran visibles per a qualsevol persona que utilitzi aquest dispositiu."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"Afegeix un usuari"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Afegeix un convidat"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Suprimeix el convidat"</string>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index cb8c36b55580..3845e98b9a62 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"Nového uživatele se nepodařilo vytvořit"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Vytvoření nového hosta se nezdařilo"</string>
<string name="user_nickname" msgid="262624187455825083">"Přezdívka"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"Vaše jméno a fotku uvidí kdokoli, kdo toto zařízení použije."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"Přidat uživatele"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Přidat hosta"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Odstranit hosta"</string>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index 625f05b57ac8..97676ad26757 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"Der kunne ikke oprettes en ny bruger"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Der kunne ikke oprettes en ny gæst"</string>
<string name="user_nickname" msgid="262624187455825083">"Kaldenavn"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"Dit navn og profilbillede vil være synligt for alle, der bruger denne enhed."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"Tilføj bruger"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Tilføj gæst"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Fjern gæsten"</string>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index f622f61505f5..02fd0e0f786e 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"Nutzer konnte nicht erstellt werden"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Fehler beim Erstellen eines neuen Gasts"</string>
<string name="user_nickname" msgid="262624187455825083">"Alias"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"Dein Name und Bild sind für alle Nutzer dieses Geräts sichtbar."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"Nutzer hinzufügen"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Gast hinzufügen"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Gast entfernen"</string>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index 861f4722edfb..ce81fb74645d 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"Η δημιουργία νέου χρήστη απέτυχε"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Αποτυχία δημιουργίας νέου επισκέπτη"</string>
<string name="user_nickname" msgid="262624187455825083">"Ψευδώνυμο"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"Το όνομα και η εικόνα σας θα είναι ορατά σε όλους τους χρήστες που χρησιμοποιούν αυτή τη συσκευή."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"Προσθήκη χρήστη"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Προσθήκη επισκέπτη"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Κατάργηση επισκέπτη"</string>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index e6923de1af8c..78e5b616e683 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"Failed to create a new user"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Failed to create a new guest"</string>
<string name="user_nickname" msgid="262624187455825083">"Nickname"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"Your name and picture will be visible to anyone that uses this device."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"Add user"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Add guest"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Remove guest"</string>
diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml
index 36dfd2fb0c28..920f7b1a4efa 100644
--- a/packages/SettingsLib/res/values-en-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-en-rCA/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"Failed to create a new user"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Failed to create a new guest"</string>
<string name="user_nickname" msgid="262624187455825083">"Nickname"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"Your name and picture will be visible to anyone that uses this device."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"Add user"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Add guest"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Remove guest"</string>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index e6923de1af8c..78e5b616e683 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"Failed to create a new user"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Failed to create a new guest"</string>
<string name="user_nickname" msgid="262624187455825083">"Nickname"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"Your name and picture will be visible to anyone that uses this device."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"Add user"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Add guest"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Remove guest"</string>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index e6923de1af8c..78e5b616e683 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"Failed to create a new user"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Failed to create a new guest"</string>
<string name="user_nickname" msgid="262624187455825083">"Nickname"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"Your name and picture will be visible to anyone that uses this device."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"Add user"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Add guest"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Remove guest"</string>
diff --git a/packages/SettingsLib/res/values-en-rXC/strings.xml b/packages/SettingsLib/res/values-en-rXC/strings.xml
index 8b05e12f2ee4..dd83259d1733 100644
--- a/packages/SettingsLib/res/values-en-rXC/strings.xml
+++ b/packages/SettingsLib/res/values-en-rXC/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‎‎‏‎‏‏‎‎‎‎‎‎‎‎‏‎‎‏‏‏‎‏‏‏‎‏‏‏‎‎‎‎‏‏‎‏‏‎‎‏‎‎‎‏‏‏‎‏‏‏‏‏‎‎‏‎‏‎‎‎‎Failed to create a new user‎‏‎‎‏‎"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‎‎‏‏‏‎‏‎‎‎‏‏‏‏‎‎‎‎‎‏‎‏‎‎‏‏‎‏‏‎‎‏‎‎‎‎‏‎‏‏‏‏‎‎‎‏‏‏‏‏‎‎‏‏‎Failed to create a new guest‎‏‎‎‏‎"</string>
<string name="user_nickname" msgid="262624187455825083">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‎‏‎‏‏‏‎‏‎‎‏‎‏‎‎‎‎‎‏‏‏‎‏‎‎‏‏‏‎‏‎‎‏‏‎‏‎‏‎‏‏‏‎‏‎‏‏‏‎‎‏‎‎‏‎‏‏‏‎‏‏‎Nickname‎‏‎‎‏‎"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‏‎‎‎‎‎‏‎‏‎‎‎‎‎‏‏‏‎‎‏‎‎‏‎‎‎‎‏‎‏‎‏‎‎‎‏‎‏‎‎‎‎‏‎‏‎‎‏‎‏‏‎‏‎‎‏‎‏‎‏‎Your name and picture will be visible to anyone that uses this device.‎‏‎‎‏‎"</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‎‎‏‏‏‎‏‏‎‎‎‏‎‎‏‏‏‎‎‏‏‎‎‎‏‏‏‏‏‏‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‎‏‏‏‏‎‏‎‎‎Add user‎‏‎‎‏‎"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‎‎‎‎‎‏‎‏‎‎‏‎‏‎‏‎‎‏‎‎‎‏‎‎‏‏‏‏‎‏‏‎‏‏‎‎‎‎‎‎‎‏‏‏‏‏‏‎‎‏‏‎‏‏‏‎‎‏‎‏‎Add guest‎‏‎‎‏‎"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‎‎‏‎‎‏‎‏‎‏‏‏‎‏‎‏‎‎‏‎‎‏‏‎‎‎‎‎‎‏‏‎‎‏‎‎‏‏‏‎‎‎‎Remove guest‎‏‎‎‏‎"</string>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index a6fdf569954c..a221d114968a 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"No se pudo crear el usuario nuevo"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"No se pudo crear un nuevo invitado"</string>
<string name="user_nickname" msgid="262624187455825083">"Sobrenombre"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"Todas las personas que usen este dispositivo podrán ver tu nombre y foto."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"Agregar usuario"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Agregar invitado"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Quitar invitado"</string>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index d57a33a305c6..f6beab9b3980 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"No se ha podido crear el usuario"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"No se ha podido crear un nuevo invitado"</string>
<string name="user_nickname" msgid="262624187455825083">"Apodo"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"Cualquiera que use este dispositivo podrá ver tu nombre y tu imagen"</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"Añadir usuario"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Añadir invitado"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Quitar invitado"</string>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index dfe78d8f3557..b6b9132f8002 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"Uue kasutaja loomine ebaõnnestus"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Uue külalise loomine ei õnnestunud"</string>
<string name="user_nickname" msgid="262624187455825083">"Hüüdnimi"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"Teie nimi ja pilt on nähtav kõigile selle seadme kasutajatele."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"Lisa kasutaja"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Lisa külaline"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Eemalda külaline"</string>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index 3c6309dad77f..b61388da515f 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"Ezin izan da sortu erabiltzailea"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Ezin izan da sortu beste gonbidatu bat"</string>
<string name="user_nickname" msgid="262624187455825083">"Goitizena"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"Gailu hau darabilen edonork ikusi ahal izango ditu zure izena eta argazkia."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"Gehitu erabiltzaile bat"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Gehitu gonbidatu bat"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Kendu gonbidatua"</string>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index 2cb1873e5fbe..7938bc64c4ee 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"کاربر جدید ایجاد نشد"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"مهمان جدید ایجاد نشد"</string>
<string name="user_nickname" msgid="262624187455825083">"نام مستعار"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"افرادی که از این دستگاه استفاده می‌کنند می‌توانند نام و عکس شما را ببینند."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"افزودن کاربر"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"افزودن مهمان"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"حذف مهمان"</string>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index 29459ca5ee1f..3ee7dc1b017d 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"Uuden käyttäjän luominen epäonnistui"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Uutta vierasta ei voitu luoda"</string>
<string name="user_nickname" msgid="262624187455825083">"Lempinimi"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"Nimesi ja kuvasi ovat näkyvillä kaikille tätä laitetta käyttäville henkilöille."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"Lisää käyttäjä"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Lisää vieras"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Poista vieras"</string>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index f97b36ea895d..95a4e62486ba 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"Impossible de créer un utilisateur"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Impossible de créer un nouvel invité"</string>
<string name="user_nickname" msgid="262624187455825083">"Pseudo"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"Votre nom et votre photo seront visibles à toute personne utilisant cet appareil."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"Ajouter un utilisateur"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Ajouter un invité"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Supprimer l\'invité"</string>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index 7f7ba637b47d..e26e8b045d17 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"Échec de la création d\'un utilisateur"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Impossible de créer un profil invité"</string>
<string name="user_nickname" msgid="262624187455825083">"Pseudo"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"Votre nom et votre photo seront visibles par quiconque utilise cet appareil."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"Ajouter un utilisateur"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Ajouter un invité"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Supprimer l\'invité"</string>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index 179d946c23da..53332bf4c825 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"Non se puido crear un novo usuario"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Produciuse un erro ao crear o convidado"</string>
<string name="user_nickname" msgid="262624187455825083">"Alcume"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"Calquera que use este dispositivo poderá ver o teu nome e imaxe."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"Engadir usuario"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Engadir convidado"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Quitar convidado"</string>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index cafe86c26b77..e792e9fb79c3 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"નવો વપરાશકર્તા બનાવવામાં નિષ્ફળ"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"નવી અતિથિ બનાવવામાં નિષ્ફળ રહ્યાં"</string>
<string name="user_nickname" msgid="262624187455825083">"ઉપનામ"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"તમારું નામ અને ફોટો આ ડિવાઇસનો ઉપયોગ કરનાર કોઈપણ વ્યક્તિને દેખાશે."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"વપરાશકર્તા ઉમેરો"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"અતિથિ ઉમેરો"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"અતિથિને કાઢી નાખો"</string>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index 53cf7247b996..ae9e29a4a2a5 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"नया उपयोगकर्ता जोड़ा नहीं जा सका"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"नया मेहमान खाता नहीं बनाया जा सका"</string>
<string name="user_nickname" msgid="262624187455825083">"प्रचलित नाम"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"इस डिवाइस का इस्तेमाल करने वाले लोगों को आपका नाम और तस्वीर दिखेगी."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"उपयोगकर्ता जोड़ें"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"मेहमान जोड़ें"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"मेहमान को हटाएं"</string>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index f06baad6ea6c..1e12d969558a 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"Izrada novog korisnika nije uspjela"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Izrada novog gosta nije uspjela"</string>
<string name="user_nickname" msgid="262624187455825083">"Nadimak"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"Vaše ime i slika bit će vidljivi svima koji upotrebljavaju taj uređaj."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"Dodajte korisnika"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Dodajte gosta"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Ukloni gosta"</string>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index 39d905f0bf46..0e5b1deb56ba 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"Az új felhasználó létrehozása sikertelen"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Az új vendég létrehozása nem sikerült"</string>
<string name="user_nickname" msgid="262624187455825083">"Becenév"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"Neve és képe mindenki számára látható lesz, aki ezt az eszközt használja."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"Felhasználó hozzáadása"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Vendég hozzáadása"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Vendég munkamenet eltávolítása"</string>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index 55f09e297f2a..6e0dd495fb4d 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"Չհաջողվեց ստեղծել նոր օգտատեր"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Չհաջողվեց նոր հյուր ստեղծել"</string>
<string name="user_nickname" msgid="262624187455825083">"Կեղծանուն"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"Ձեր անունն ու նկարը տեսանելի կլինեն այս սարքն օգտագործող բոլոր մարդկանց։"</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"Ավելացնել օգտատեր"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Ավելացնել հյուր"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Հեռացնել հյուրին"</string>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 885729da1b66..8afffaab0cd7 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"Gagal membuat pengguna baru"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Gagal membuat tamu baru"</string>
<string name="user_nickname" msgid="262624187455825083">"Nama panggilan"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"Nama dan foto Anda akan dapat dilihat oleh siapa saja yang menggunakan perangkat ini."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"Tambahkan pengguna"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Tambahkan tamu"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Hapus tamu"</string>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index 020191b55e7c..b32266573638 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"Ekki tókst að stofna nýjan notanda"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Ekki tókst að búa til nýjan gest"</string>
<string name="user_nickname" msgid="262624187455825083">"Gælunafn"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"Allir sem nota þetta tæki geta séð nafnið þitt og myndina."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"Bæta notanda við"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Bæta gesti við"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Fjarlægja gest"</string>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index 37a20675abe7..43aded08ad3a 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"Creazione nuovo utente non riuscita"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Impossibile creare un nuovo ospite"</string>
<string name="user_nickname" msgid="262624187455825083">"Nickname"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"Il tuo nome e la tua foto saranno visibili a chiunque usi questo dispositivo."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"Aggiungi utente"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Aggiungi ospite"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Rimuovi ospite"</string>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index 3353374f7b40..990d9ac88ec0 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"לא ניתן היה ליצור משתמש חדש"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"יצירת אורח חדש נכשלה"</string>
<string name="user_nickname" msgid="262624187455825083">"כינוי"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"השם והתמונה שלך יהיו גלויים לכל מי שמשתמש במכשיר הזה."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"הוספת משתמש"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"הוספת אורח"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"הסרת אורח"</string>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index d87d0f8dafbc..7029f8c27112 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"新しいユーザーを作成できませんでした"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"新しいゲストを作成できませんでした"</string>
<string name="user_nickname" msgid="262624187455825083">"ニックネーム"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"このデバイスを使用するすべてのユーザーに、あなたの名前と写真が表示されます。"</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"ユーザーを追加"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"ゲストを追加"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"ゲストを削除"</string>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index 7812f0b21601..461f211c46f4 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"ახალი მომხმარებლის შექმნა ვერ მოხერხდა"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"ახალი სტუმრის შექმნა ვერ მოხერხდა"</string>
<string name="user_nickname" msgid="262624187455825083">"მეტსახელი"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"თქვენი სახელი და სურათი ხილვადი იქნება ყველასთვის, ვინც ამ მოწყობილობას იყენებს."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"მომხმარებლის დამატება"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"სტუმრის დამატება"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"სტუმრის ამოშლა"</string>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index 300d4e517013..77d9f8b39448 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"Жаңа пайдаланушы жасалмады."</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Жаңа қонақ профилі жасалмады."</string>
<string name="user_nickname" msgid="262624187455825083">"Лақап ат"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"Атыңыз бен суретіңіз осы құрылғыны пайдаланатын барлық адамға көрінеді."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"Пайда­ланушы қосу"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Қонақ қосу"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Қонақты жою"</string>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index 373cfc656789..7e57b15b3177 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"មិន​អាច​បង្កើត​អ្នកប្រើប្រាស់ថ្មី​បានទេ"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"មិនអាចបង្កើតភ្ញៀវថ្មីបានទេ"</string>
<string name="user_nickname" msgid="262624187455825083">"ឈ្មោះ​ហៅក្រៅ"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"គ្រប់គ្នាដែលប្រើឧបករណ៍នេះនឹងអាចមើលឃើញឈ្មោះ និងរូបភាពរបស់អ្នក។"</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"បញ្ចូល​អ្នក​ប្រើប្រាស់"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"បញ្ចូល​ភ្ញៀវ"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"ដកភ្ញៀវចេញ"</string>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index bf84cc48aa39..6737cdc403c5 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"ಹೊಸ ಬಳಕೆದಾರರನ್ನು ರಚಿಸಲು ವಿಫಲವಾಗಿದೆ"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"ಹೊಸ ಅತಿಥಿಯನ್ನು ರಚಿಸಲು ವಿಫಲವಾಗಿದೆ"</string>
<string name="user_nickname" msgid="262624187455825083">"ಅಡ್ಡ ಹೆಸರು"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"ಈ ಸಾಧನವನ್ನು ಬಳಸುವ ಯಾರಿಗಾದರೂ ನಿಮ್ಮ ಹೆಸರು ಮತ್ತು ಚಿತ್ರವು ಗೋಚರಿಸುತ್ತದೆ."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"ಬಳಕೆದಾರರನ್ನು ಸೇರಿಸಿ"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"ಅತಿಥಿಯನ್ನು ಸೇರಿಸಿ"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"ಅತಿಥಿಯನ್ನು ತೆಗೆದುಹಾಕಿ"</string>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index b184ef43e5b7..be472a1474f8 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"새 사용자를 만들지 못함"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"새 게스트 생성 실패"</string>
<string name="user_nickname" msgid="262624187455825083">"닉네임"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"이 기기를 사용하는 모든 사람에게 내 이름과 사진이 공개됩니다."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"사용자 추가"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"게스트 추가"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"게스트 삭제"</string>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index e565e444536c..94c0fd1113f8 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"Жаңы колдонуучу түзүлбөй калды"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Жаңы конок түзүлгөн жок"</string>
<string name="user_nickname" msgid="262624187455825083">"Ылакап аты"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"Аты-жөнүңүз менен сүрөтүңүз ушул түзмөктү колдонгондордун баарына көрүнөт."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"Колдонуучу кошуу"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Конок кошуу"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Конокту өчүрүү"</string>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index 6caaf952b364..036889899f25 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"ສ້າງຜູ້ໃຊ້ໃໝ່ບໍ່ສຳເລັດ"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"ສ້າງແຂກໃໝ່ບໍ່ສຳເລັດ"</string>
<string name="user_nickname" msgid="262624187455825083">"ຊື່ຫຼິ້ນ"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"ຊື່ ແລະ ຮູບຂອງທ່ານຈະເຫັນໄດ້ໂດຍທຸກຄົນທີ່ໃຊ້ອຸປະກອນນີ້."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"ເພີ່ມຜູ້ໃຊ້"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"ເພີ່ມແຂກ"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"ລຶບແຂກອອກ"</string>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index bc66a806375f..de0add8e3511 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"Nepavyko sukurti naujo naudotojo"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Nepavyko sukurti naujo gesto"</string>
<string name="user_nickname" msgid="262624187455825083">"Slapyvardis"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"Jūsų vardas ir nuotrauka bus rodomi visiems šio įrenginio naudotojams."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"Pridėti naudotoją"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Pridėti svečią"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Pašalinti svečią"</string>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index c5409454d384..1d627f372663 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"Neizdevās izveidot jaunu lietotāju"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Neizdevās izveidot jaunu viesa profilu"</string>
<string name="user_nickname" msgid="262624187455825083">"Segvārds"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"Jūsu vārds un attēls būs redzams jebkuram šīs ierīces lietotājam."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"Pievienot lietotāju"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Pievienot viesi"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Noņemt viesi"</string>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index 70bcc2100ddd..3bcabd68ea2a 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"Не успеа да создаде нов корисник"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Не успеа создавањето нов гостин"</string>
<string name="user_nickname" msgid="262624187455825083">"Прекар"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"Вашите име и слика ќе бидат видливи за секој што го користи уредов."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"Додајте корисник"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Додајте гостин"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Отстрани гостин"</string>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index 9a297e5fb4d8..b21d3cf8e0f1 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"പുതിയ ഉപയോക്താവിനെ സൃഷ്‌ടിക്കാനായില്ല"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"പുതിയ അതിഥിയെ സൃഷ്‌ടിക്കാനായില്ല"</string>
<string name="user_nickname" msgid="262624187455825083">"വിളിപ്പേര്"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"നിങ്ങളുടെ പേരും ചിത്രവും ഈ ഉപകരണം ഉപയോഗിക്കുന്ന എല്ലാവർക്കും ദൃശ്യമാകും."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"ഉപയോക്താവിനെ ചേർക്കുക"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"അതിഥിയെ ചേർക്കുക"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"അതിഥിയെ നീക്കം ചെയ്യുക"</string>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index 000e306afef3..dbdb694f71d5 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"Шинэ хэрэглэгч үүсгэж чадсангүй"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Шинэ зочин үүсгэж чадсангүй"</string>
<string name="user_nickname" msgid="262624187455825083">"Хоч"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"Таны нэр болон зураг энэ төхөөрөмжийг ашигладаг дурын хүнд харагдана."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"Хэрэглэгч нэмэх"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Зочин нэмэх"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Зочин хасах"</string>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index 6af0fbdc0ac8..b270f417adbe 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"नवीन वापरकर्ता तयार करता आला नाही"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"नवीन अतिथी तयार करता आला नाही"</string>
<string name="user_nickname" msgid="262624187455825083">"टोपणनाव"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"हे डिव्हाइस वापरणाऱ्या कोणत्याही व्यक्तीला तुमचे नाव आणि फोटो दिसेल."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"वापरकर्ता जोडा"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"अतिथी जोडा"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"अतिथी काढून टाका"</string>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index 621b4694026b..1bc0f20ba2ef 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"Gagal membuat pengguna baharu"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Gagal membuat tetamu baharu"</string>
<string name="user_nickname" msgid="262624187455825083">"Nama panggilan"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"Nama dan gambar anda akan kelihatan kepada sesiapa yang menggunakan peranti ini."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"Tambah pengguna"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Tambah tetamu"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Alih keluar tetamu"</string>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index 60161c344ebb..2b9ae6daa784 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"အသုံးပြုသူအသစ် ပြုလုပ်၍မရပါ"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"ဧည့်သည်သစ် ပြုလုပ်၍မရပါ"</string>
<string name="user_nickname" msgid="262624187455825083">"နာမည်ပြောင်"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"သင့်အမည်နှင့် ဓာတ်ပုံကို ဤစက်သုံးသူတိုင်း မြင်ရပါမည်။"</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"အသုံးပြုသူ ထည့်ရန်"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"ဧည့်သည် ထည့်ရန်"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"ဧည့်သည်ကို ဖယ်ရှားရန်"</string>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index 22162bbc79a3..4a3363fcd918 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"Kunne ikke opprette noen ny bruker"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Kunne ikke opprette en ny gjest"</string>
<string name="user_nickname" msgid="262624187455825083">"Kallenavn"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"Navnet og bildet ditt blir synlige for alle som bruker denne enheten."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"Legg til bruker"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Legg til gjest"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Fjern gjesten"</string>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index fdd965a6e52a..7ba6ca0d1e43 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"नयाँ प्रयोगकर्ता सिर्जना गर्न सकिएन"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"नयाँ अतिथि बनाउन सकिएन"</string>
<string name="user_nickname" msgid="262624187455825083">"उपनाम"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"यो डिभाइस प्रयोग गर्ने सबै जना मान्छे तपाईंको नाम र फोटो देख्ने छन्।"</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"प्रयोगकर्ता कनेक्ट गर्नुहोस्"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"अतिथि कनेक्ट गर्नुहोस्"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"गेस्ट मोडबाट बाहिर निस्कियोस्"</string>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 72e57af602e8..79d918a21e10 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"Kan geen nieuwe gebruiker maken"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Kan geen nieuwe gast maken"</string>
<string name="user_nickname" msgid="262624187455825083">"Bijnaam"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"Je naam en foto zijn zichtbaar voor iedereen die dit apparaat gebruikt."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"Gebruiker toevoegen"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Gast toevoegen"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Gast verwijderen"</string>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index 723af105f8ea..9ab80d0e4003 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"ନୂଆ ଉପଯୋଗକର୍ତ୍ତା ତିଆରି କରିବାକୁ ବିଫଳ ହେଲା"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"ଜଣେ ନୂଆ ଅତିଥି ତିଆରି କରିବାରେ ବିଫଳ ହୋଇଛି"</string>
<string name="user_nickname" msgid="262624187455825083">"ଡାକନାମ"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"ଏହି ଡିଭାଇସ ବ୍ୟବହାର କରୁଥିବା ଯେ କୌଣସି ବ୍ୟକ୍ତିଙ୍କୁ ଆପଣଙ୍କ ନାମ ଏବଂ ଛବି ଦେଖାଯିବ।"</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"ୟୁଜର ଯୋଗ କରନ୍ତୁ"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"ଅତିଥି ଯୋଗ କରନ୍ତୁ"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"ଅତିଥିଙ୍କୁ କାଢ଼ି ଦିଅନ୍ତୁ"</string>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index 8a77c12f6c0c..293233822cd1 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"ਨਵਾਂ ਵਰਤੋਂਕਾਰ ਬਣਾਉਣਾ ਅਸਫਲ ਰਿਹਾ"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"ਨਵਾਂ ਮਹਿਮਾਨ ਪ੍ਰੋਫਾਈਲ ਬਣਾਉਣਾ ਅਸਫਲ ਰਿਹਾ"</string>
<string name="user_nickname" msgid="262624187455825083">"ਉਪਨਾਮ"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"ਤੁਹਾਡਾ ਨਾਮ ਅਤੇ ਤਸਵੀਰ ਇਸ ਡੀਵਾਈਸ ਦੀ ਵਰਤੋਂ ਕਰਨ ਵਾਲੇ ਕਿਸੇ ਵੀ ਵਿਅਕਤੀ ਦਿਖਾਈ ਦੇਵੇਗੀ।"</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"ਵਰਤੋਂਕਾਰ ਨੂੰ ਸ਼ਾਮਲ ਕਰੋ"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"ਮਹਿਮਾਨ ਸ਼ਾਮਲ ਕਰੋ"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"ਮਹਿਮਾਨ ਹਟਾਓ"</string>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index 375a35f6edef..a7d59cfef236 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"Nie udało się utworzyć nowego użytkownika"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Nie udało się utworzyć nowego gościa"</string>
<string name="user_nickname" msgid="262624187455825083">"Pseudonim"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"Twoja nazwa użytkownika oraz zdjęcie będą widoczne dla każdego, kto korzysta z tego urządzenia."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"Dodaj użytkownika"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Dodaj gościa"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Usuń gościa"</string>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index 55b9db509200..bb83c2bcc631 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"Falha ao criar um novo usuário"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Falha ao criar um novo convidado"</string>
<string name="user_nickname" msgid="262624187455825083">"Apelido"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"Seu nome e foto vão ficar visíveis para qualquer pessoa que use este dispositivo."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"Adicionar usuário"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Adicionar visitante"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Remover visitante"</string>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index ca704e7bbb87..4554f85f7ec8 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"Falha ao criar um novo utilizador"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Falha ao criar um novo convidado"</string>
<string name="user_nickname" msgid="262624187455825083">"Alcunha"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"O seu nome e imagem vão ser visíveis para qualquer pessoa que use este dispositivo."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"Adicionar utilizador"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Adicionar convidado"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Remover convidado"</string>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index 55b9db509200..bb83c2bcc631 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"Falha ao criar um novo usuário"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Falha ao criar um novo convidado"</string>
<string name="user_nickname" msgid="262624187455825083">"Apelido"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"Seu nome e foto vão ficar visíveis para qualquer pessoa que use este dispositivo."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"Adicionar usuário"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Adicionar visitante"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Remover visitante"</string>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index fa89c1a4c3d8..1482ee541d16 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"Nu s-a creat noul utilizator"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Nu s-a putut crea un invitat nou"</string>
<string name="user_nickname" msgid="262624187455825083">"Pseudonim"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"Numele și fotografia ta vor fi vizibile pentru orice persoană care folosește acest dispozitiv."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"Adaugă un utilizator"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Adaugă un invitat"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Șterge invitatul"</string>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index d85307098a35..7fa3f1823022 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"Не удалось создать пользователя"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Не удалось создать гостя."</string>
<string name="user_nickname" msgid="262624187455825083">"Псевдоним"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"Ваше имя и фото профиля будут видны всем пользователям этого устройства."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"Добавить пользователя"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Добавить гостя"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Удалить аккаунт гостя"</string>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index 093f216afccc..ec4092637bec 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"නව පරිශීලකයෙකු තැනීමට අසමත් විය"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"නව අමුත්තකු තැනීම අසාර්ථක විය"</string>
<string name="user_nickname" msgid="262624187455825083">"අපනාමය"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"මෙම උපාංගය භාවිත කරන ඕනෑම කෙනෙකුට ඔබේ නම සහ පින්තූරය දැකිය හැකි වෙයි."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"පරිශීලකයා එක් කරන්න"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"අමුත්තා එක් කරන්න"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"අමුත්තා ඉවත් කරන්න"</string>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index 1c8293312871..4b90a9193273 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"Nového použív. sa nepodarilo vytvoriť"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Nového hosťa sa nepodarilo vytvoriť"</string>
<string name="user_nickname" msgid="262624187455825083">"Prezývka"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"Vaše meno a fotku uvidia všetci používatelia tohto zariadenia."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"Pridať používateľa"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Pridať hosťa"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Odobrať hosťa"</string>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index f97dd78f8179..f04e83942836 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"Ustvarjanje novega uporabnika ni uspelo."</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Ustvarjanje novega gosta ni uspelo."</string>
<string name="user_nickname" msgid="262624187455825083">"Vzdevek"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"Vaša ime in fotografija bosta vidna vsem uporabnikom te naprave."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"Dodaj uporabnika"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Dodaj gosta"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Odstrani gosta"</string>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index a802f115da4a..6721987e86c5 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"Krijimi i një përdoruesi të ri dështoi"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Profili i vizitorit të ri nuk u krijua"</string>
<string name="user_nickname" msgid="262624187455825083">"Pseudonimi"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"Emri dhe fotografia jote do të jenë të dukshme për çdo person që e përdor këtë pajisje."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"Shto përdorues"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Shto vizitor"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Hiq vizitorin"</string>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index df2215911673..5497c6e15b43 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"Прављење новог корисника није успело"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Прављење новог госта није успело"</string>
<string name="user_nickname" msgid="262624187455825083">"Надимак"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"Име и слика ће бити видљиви сваком ко користи овај уређај."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"Додај корисника"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Додај госта"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Уклони госта"</string>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index 79b8399527a0..a331bc601f60 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"Det gick inte att skapa en ny användare"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Det gick inte att skapa en ny gäst"</string>
<string name="user_nickname" msgid="262624187455825083">"Smeknamn"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"Ditt namn och din bild visas för alla som använder den här enheten."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"Lägg till användare"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Lägg till gäst"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Ta bort gäst"</string>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index c0ace5805e63..53481a2297a6 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"Imeshindwa kuweka mtumiaji mpya"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Imeshindwa kuunda wasifu mpya wa mgeni"</string>
<string name="user_nickname" msgid="262624187455825083">"Jina wakilishi"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"Mtu yeyote anayetumia kifaa hiki ataona jina na picha yako."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"Ongeza mtumiaji"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Ongeza mgeni"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Ondoa mgeni"</string>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index ebca26dc3063..204da0cb5344 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"புதிய பயனரை உருவாக்க முடியவில்லை"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"புதிய விருந்தினரை உருவாக்க முடியவில்லை"</string>
<string name="user_nickname" msgid="262624187455825083">"புனைப்பெயர்"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"இந்தச் சாதனத்தைப் பயன்படுத்தும் அனைவருக்கும் உங்கள் பெயரும் படமும் காட்டப்படும்."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"பயனரைச் சேர்"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"கெஸ்ட்டைச் சேர்"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"கெஸ்ட்டை அகற்று"</string>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index cf3c08acc54c..f576c8d2eee9 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"కొత్త యూజర్‌ను క్రియేట్ చేయడం విఫలమైంది"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"కొత్త అతిథిని క్రియేట్ చేయడం విఫలమైంది"</string>
<string name="user_nickname" msgid="262624187455825083">"మారుపేరు"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"ఈ పరికరాన్ని ఉపయోగించే ప్రతి ఒక్కరికి మీ పేరు, ఫోటో కనిపిస్తుంది."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"యూజర్‌ను జోడించండి"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"గెస్ట్‌ను జోడించండి"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"గెస్ట్‌ను తీసివేయండి"</string>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index a74265ee3e9a..42e6c0567800 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"สร้างผู้ใช้ใหม่ไม่ได้"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"สร้างผู้เข้าร่วมใหม่ไม่สำเร็จ"</string>
<string name="user_nickname" msgid="262624187455825083">"ชื่อเล่น"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"ชื่อและภาพของคุณจะปรากฏแก่ทุกคนที่ใช้อุปกรณ์นี้"</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"เพิ่มผู้ใช้"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"เพิ่มผู้ใช้ชั่วคราว"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"นำผู้ใช้ชั่วคราวออก"</string>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index 18d3d3b626fa..73db0c567024 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"Hindi nakagawa ng bagong user"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Hindi nakagawa ng bagong guest"</string>
<string name="user_nickname" msgid="262624187455825083">"Nickname"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"Makikita ng sinumang gumagamit ng device na ito ang iyong pangalan at larawan."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"Magdagdag ng user"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Magdagdag ng bisita"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Alisin ang bisita"</string>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index c4241150ad12..98cfe35635f8 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"Yeni kullanıcı oluşturulamadı"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Yeni misafir oluşturulamadı"</string>
<string name="user_nickname" msgid="262624187455825083">"Takma ad"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"Adınızı ve resminizi, bu cihazı kullanan herkes görebilir."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"Kullanıcı ekle"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Misafir ekle"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Misafir oturumunu kaldır"</string>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index 97592f970b67..3321c780ab6e 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"Не вдалося створити користувача"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Не вдалося створити гостя"</string>
<string name="user_nickname" msgid="262624187455825083">"Псевдонім"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"Ваше ім’я і зображення бачитимуть усі користувачі цього пристрою."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"Додати ​користувача"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Додати гостя"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Видалити гостя"</string>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index 9d3405234e5b..dadb9bc45f93 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"نیا صارف بنانے میں ناکام"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"نیا مہمان بنانے میں ناکام"</string>
<string name="user_nickname" msgid="262624187455825083">"عرفی نام"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"آپ کا نام اور تصویر ہر اس شخص کو نظر آئے گی جو اس آلہ کو استعمال کرتا ہے۔"</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"صارف کو شامل کریں"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"مہمان کو شامل کریں"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"مہمان کو ہٹائیں"</string>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index bd38bb44df6e..2254132195e3 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"Yangi foydalanuvchi yaratilmadi"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Yangi mehmon yaratilmadi"</string>
<string name="user_nickname" msgid="262624187455825083">"Nik"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"Ismingiz va rasmingiz ushbu qurilmadan foydalanadigan har bir kishiga koʻrinadi."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"Foydalanuvchi kiritish"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Mehmon kiritish"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Mehmonni olib tashlash"</string>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index 5b91df3e44a2..c98dcecbad9c 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"Không tạo được người dùng mới"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Không tạo được khách mới"</string>
<string name="user_nickname" msgid="262624187455825083">"Biệt hiệu"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"Bất kỳ ai dùng thiết bị này đều có thể thấy tên và hình ảnh của bạn."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"Thêm người dùng"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Thêm khách"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Xóa khách"</string>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index 594922a4050d..136586dce68d 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"无法创建新用户"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"未能创建新的访客"</string>
<string name="user_nickname" msgid="262624187455825083">"昵称"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"所有使用此设备的用户都将可以看到您的姓名和照片。"</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"添加用户"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"添加访客"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"移除访客"</string>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index b3aafae4a3c6..a32e51edb9a1 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"無法建立新使用者"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"無法建立新訪客"</string>
<string name="user_nickname" msgid="262624187455825083">"暱稱"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"此裝置的使用者都會看到你的名稱和相片。"</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"新增使用者"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"新增訪客"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"移除訪客"</string>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index c3be21a93d8c..b5f5e2edf993 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"無法建立新的使用者"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"無法建立新訪客"</string>
<string name="user_nickname" msgid="262624187455825083">"暱稱"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"這部裝置的使用者都會看到你的名稱和相片。"</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"新增使用者"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"新增訪客"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"移除訪客"</string>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index f6aaf813af84..19dbebfa3806 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -619,7 +619,8 @@
<string name="add_user_failed" msgid="4809887794313944872">"Yehlulekile ukudala umsebenzisi omusha"</string>
<string name="add_guest_failed" msgid="8074548434469843443">"Yehlulekile ukusungula isimenywa esisha"</string>
<string name="user_nickname" msgid="262624187455825083">"Isiteketiso"</string>
- <string name="edit_user_info_message" msgid="5199468585059260053">"Igama nesithombe sakho kuzobonakala kunoma ubani osebenzisa le divayisi."</string>
+ <!-- no translation found for edit_user_info_message (6677556031419002895) -->
+ <skip />
<string name="user_add_user" msgid="7876449291500212468">"Engeza umsebenzisi"</string>
<string name="guest_new_guest" msgid="3482026122932643557">"Engeza isivakashi"</string>
<string name="guest_exit_guest" msgid="5908239569510734136">"Susa isihambeli"</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java
index 1118efc3e953..64cf5c640143 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java
@@ -172,6 +172,7 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile {
if ((profile == BluetoothProfile.LE_AUDIO_BROADCAST)
&& mIsBroadcastProfileReady) {
mIsBroadcastProfileReady = false;
+ notifyBroadcastStateChange(BROADCAST_STATE_OFF);
unregisterServiceCallBack(mBroadcastCallback);
mCachedBroadcastCallbackExecutorMap.clear();
}
@@ -1118,6 +1119,7 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile {
Intent intent = new Intent(ACTION_LE_AUDIO_SHARING_STATE_CHANGE);
intent.putExtra(EXTRA_LE_AUDIO_SHARING_STATE, state);
intent.setPackage(mContext.getPackageName());
+ Log.e(TAG, "notifyBroadcastStateChange for state = " + state);
mContext.sendBroadcast(intent);
}
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java b/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java
index a617bf3278d6..fa27db9a427a 100644
--- a/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java
+++ b/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java
@@ -60,6 +60,7 @@ public class DreamBackend {
public CharSequence description;
public Drawable previewImage;
public boolean supportsComplications = false;
+ public int dreamCategory;
@Override
public String toString() {
@@ -207,6 +208,7 @@ public class DreamBackend {
dreamInfo.settingsComponentName = dreamMetadata.settingsActivity;
dreamInfo.previewImage = dreamMetadata.previewImage;
dreamInfo.supportsComplications = dreamMetadata.showComplications;
+ dreamInfo.dreamCategory = dreamMetadata.dreamCategory;
}
dreamInfos.add(dreamInfo);
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/volume/data/repository/AudioRepository.kt b/packages/SettingsLib/src/com/android/settingslib/volume/data/repository/AudioRepository.kt
index 21cc9a85edbc..6730aadbdeb3 100644
--- a/packages/SettingsLib/src/com/android/settingslib/volume/data/repository/AudioRepository.kt
+++ b/packages/SettingsLib/src/com/android/settingslib/volume/data/repository/AudioRepository.kt
@@ -34,6 +34,7 @@ import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.callbackFlow
+import kotlinx.coroutines.flow.conflate
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.filterIsInstance
import kotlinx.coroutines.flow.filterNotNull
@@ -134,6 +135,7 @@ class AudioRepositoryImpl(
}
.map { getCurrentAudioStream(audioStream) }
.onStart { emit(getCurrentAudioStream(audioStream)) }
+ .conflate()
.flowOn(backgroundCoroutineContext)
}
diff --git a/packages/SettingsProvider/res/values-af/strings.xml b/packages/SettingsProvider/res/values-af/strings.xml
index 24efbb61e0fc..79a7f2d86b74 100644
--- a/packages/SettingsProvider/res/values-af/strings.xml
+++ b/packages/SettingsProvider/res/values-af/strings.xml
@@ -20,6 +20,4 @@
<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">"Instellingsberging"</string>
- <string name="wifi_softap_config_change" msgid="5688373762357941645">"Warmkolinstellings het verander"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Tik om besonderhede te sien"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-am/strings.xml b/packages/SettingsProvider/res/values-am/strings.xml
index 48fb705cdf87..6380b999e9f3 100644
--- a/packages/SettingsProvider/res/values-am/strings.xml
+++ b/packages/SettingsProvider/res/values-am/strings.xml
@@ -20,6 +20,4 @@
<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="wifi_softap_config_change" msgid="5688373762357941645">"የመገናኛ ነጥብ ቅንብሮች ተለውጠዋል"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"ዝርዝሮችን ለማየት መታ ያድርጉ"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-ar/strings.xml b/packages/SettingsProvider/res/values-ar/strings.xml
index 6371f2c30abc..ab1b808d312a 100644
--- a/packages/SettingsProvider/res/values-ar/strings.xml
+++ b/packages/SettingsProvider/res/values-ar/strings.xml
@@ -20,6 +20,4 @@
<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="wifi_softap_config_change" msgid="5688373762357941645">"تم تغيير إعدادات نقطة الاتصال."</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"انقر للاطّلاع على التفاصيل."</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-as/strings.xml b/packages/SettingsProvider/res/values-as/strings.xml
index ead9f4da21ef..d90599e699e6 100644
--- a/packages/SettingsProvider/res/values-as/strings.xml
+++ b/packages/SettingsProvider/res/values-as/strings.xml
@@ -20,6 +20,4 @@
<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="wifi_softap_config_change" msgid="5688373762357941645">"হটস্পটৰ ছেটিং সলনি হৈছে"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"সবিশেষ চাবলৈ টিপক"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-az/strings.xml b/packages/SettingsProvider/res/values-az/strings.xml
index b0e864248e10..e99e99bc82ef 100644
--- a/packages/SettingsProvider/res/values-az/strings.xml
+++ b/packages/SettingsProvider/res/values-az/strings.xml
@@ -20,6 +20,4 @@
<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">"Ayarlar Deposu"</string>
- <string name="wifi_softap_config_change" msgid="5688373762357941645">"Hotspot ayarları dəyişib"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Detalları görmək üçün toxunun"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-b+sr+Latn/strings.xml b/packages/SettingsProvider/res/values-b+sr+Latn/strings.xml
index def4b6839143..337b18ef2f4a 100644
--- a/packages/SettingsProvider/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsProvider/res/values-b+sr+Latn/strings.xml
@@ -20,6 +20,4 @@
<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">"Podešavanja skladišta"</string>
- <string name="wifi_softap_config_change" msgid="5688373762357941645">"Podešavanja hotspota su promenjena"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Dodirnite da biste videli detalje"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-be/strings.xml b/packages/SettingsProvider/res/values-be/strings.xml
index 709178e9116b..3a8557ce9a32 100644
--- a/packages/SettingsProvider/res/values-be/strings.xml
+++ b/packages/SettingsProvider/res/values-be/strings.xml
@@ -20,6 +20,4 @@
<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="wifi_softap_config_change" msgid="5688373762357941645">"Налады хот-спота змяніліся"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Дакраніцеся, каб убачыць падрабязныя звесткі"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-bg/strings.xml b/packages/SettingsProvider/res/values-bg/strings.xml
index b2eae736acac..f3d21d82c700 100644
--- a/packages/SettingsProvider/res/values-bg/strings.xml
+++ b/packages/SettingsProvider/res/values-bg/strings.xml
@@ -20,6 +20,4 @@
<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="wifi_softap_config_change" msgid="5688373762357941645">"Настройките за точката за достъп са променени"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Докоснете, за да видите подробности"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-bn/strings.xml b/packages/SettingsProvider/res/values-bn/strings.xml
index b2eaa2f9ec5c..7e72dfb9a968 100644
--- a/packages/SettingsProvider/res/values-bn/strings.xml
+++ b/packages/SettingsProvider/res/values-bn/strings.xml
@@ -20,6 +20,4 @@
<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="wifi_softap_config_change" msgid="5688373762357941645">"হটস্পট সেটিংসে পরিবর্তন করা হয়েছে"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"বিশদে জানতে ট্যাপ করুন"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-bs/strings.xml b/packages/SettingsProvider/res/values-bs/strings.xml
index 506fea2b8fb5..464a29f17ad2 100644
--- a/packages/SettingsProvider/res/values-bs/strings.xml
+++ b/packages/SettingsProvider/res/values-bs/strings.xml
@@ -20,6 +20,4 @@
<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">"Postavke za pohranu podataka"</string>
- <string name="wifi_softap_config_change" msgid="5688373762357941645">"Postavke pristupne tačke su promijenjene"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Dodirnite da vidite detalje"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-ca/strings.xml b/packages/SettingsProvider/res/values-ca/strings.xml
index 58d3572e5efe..9d6ac7ae4e6d 100644
--- a/packages/SettingsProvider/res/values-ca/strings.xml
+++ b/packages/SettingsProvider/res/values-ca/strings.xml
@@ -20,6 +20,4 @@
<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">"Configuració de l\'emmagatzematge"</string>
- <string name="wifi_softap_config_change" msgid="5688373762357941645">"La configuració del punt d\'accés Wi‑Fi ha canviat"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Toca per veure\'n els detalls"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-cs/strings.xml b/packages/SettingsProvider/res/values-cs/strings.xml
index 449c63205432..a28ffa1e27a3 100644
--- a/packages/SettingsProvider/res/values-cs/strings.xml
+++ b/packages/SettingsProvider/res/values-cs/strings.xml
@@ -20,6 +20,4 @@
<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">"Paměť pro nastavení"</string>
- <string name="wifi_softap_config_change" msgid="5688373762357941645">"Nastavení hotspotu se změnilo"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Klepnutím zobrazíte podrobnosti"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-da/strings.xml b/packages/SettingsProvider/res/values-da/strings.xml
index 278d97840566..ed450d57e4e8 100644
--- a/packages/SettingsProvider/res/values-da/strings.xml
+++ b/packages/SettingsProvider/res/values-da/strings.xml
@@ -20,6 +20,4 @@
<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">"Lagring af indstillinger"</string>
- <string name="wifi_softap_config_change" msgid="5688373762357941645">"Indstillingerne for hotspots har ændret sig"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Tryk for at se flere oplysninger"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-de/strings.xml b/packages/SettingsProvider/res/values-de/strings.xml
index b006ac936755..6effbaee2196 100644
--- a/packages/SettingsProvider/res/values-de/strings.xml
+++ b/packages/SettingsProvider/res/values-de/strings.xml
@@ -20,6 +20,4 @@
<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">"Einstellungsspeicher"</string>
- <string name="wifi_softap_config_change" msgid="5688373762357941645">"Hotspot-Einstellungen wurden geändert"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Für Details tippen"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-el/strings.xml b/packages/SettingsProvider/res/values-el/strings.xml
index 1bfbf27513d9..5bd1fa6af8e6 100644
--- a/packages/SettingsProvider/res/values-el/strings.xml
+++ b/packages/SettingsProvider/res/values-el/strings.xml
@@ -20,6 +20,4 @@
<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="wifi_softap_config_change" msgid="5688373762357941645">"Οι ρυθμίσεις σημείου πρόσβασης Wi-Fi έχουν αλλάξει"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Πατήστε για προβολή λεπτομερειών."</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-en-rAU/strings.xml b/packages/SettingsProvider/res/values-en-rAU/strings.xml
index 4e90cade7323..c19fdd7aed7f 100644
--- a/packages/SettingsProvider/res/values-en-rAU/strings.xml
+++ b/packages/SettingsProvider/res/values-en-rAU/strings.xml
@@ -20,6 +20,4 @@
<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">"Settings Storage"</string>
- <string name="wifi_softap_config_change" msgid="5688373762357941645">"Hotspot settings have changed"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Tap to see details"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-en-rCA/strings.xml b/packages/SettingsProvider/res/values-en-rCA/strings.xml
index 4e90cade7323..c19fdd7aed7f 100644
--- a/packages/SettingsProvider/res/values-en-rCA/strings.xml
+++ b/packages/SettingsProvider/res/values-en-rCA/strings.xml
@@ -20,6 +20,4 @@
<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">"Settings Storage"</string>
- <string name="wifi_softap_config_change" msgid="5688373762357941645">"Hotspot settings have changed"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Tap to see details"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-en-rGB/strings.xml b/packages/SettingsProvider/res/values-en-rGB/strings.xml
index 4e90cade7323..c19fdd7aed7f 100644
--- a/packages/SettingsProvider/res/values-en-rGB/strings.xml
+++ b/packages/SettingsProvider/res/values-en-rGB/strings.xml
@@ -20,6 +20,4 @@
<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">"Settings Storage"</string>
- <string name="wifi_softap_config_change" msgid="5688373762357941645">"Hotspot settings have changed"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Tap to see details"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-en-rIN/strings.xml b/packages/SettingsProvider/res/values-en-rIN/strings.xml
index 4e90cade7323..c19fdd7aed7f 100644
--- a/packages/SettingsProvider/res/values-en-rIN/strings.xml
+++ b/packages/SettingsProvider/res/values-en-rIN/strings.xml
@@ -20,6 +20,4 @@
<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">"Settings Storage"</string>
- <string name="wifi_softap_config_change" msgid="5688373762357941645">"Hotspot settings have changed"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Tap to see details"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-en-rXC/strings.xml b/packages/SettingsProvider/res/values-en-rXC/strings.xml
index 4ea5c577070b..9b18e2b4028a 100644
--- a/packages/SettingsProvider/res/values-en-rXC/strings.xml
+++ b/packages/SettingsProvider/res/values-en-rXC/strings.xml
@@ -20,6 +20,4 @@
<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">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‎‎‎‏‏‎‏‎‎‎‎‎‏‎‎‏‎‏‎‏‎‏‎‏‎‎‏‏‎‏‏‏‎‏‎‎‏‏‏‎‏‎‏‎‎‎‎‏‏‏‏‏‏‎Settings Storage‎‏‎‎‏‎"</string>
- <string name="wifi_softap_config_change" msgid="5688373762357941645">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‏‏‏‎‏‏‏‏‎‎‎‏‎‎‏‎‏‎‎‏‏‏‎‎‏‏‎‎‎‏‏‎‏‏‏‎‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‏‏‎‎‎‏‏‎‏‎Hotspot settings have changed‎‏‎‎‏‎"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‏‏‏‎‏‎‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‎‏‏‏‏‎‎‏‏‏‏‎Tap to see details‎‏‎‎‏‎"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-es-rUS/strings.xml b/packages/SettingsProvider/res/values-es-rUS/strings.xml
index 4345b7a70792..7a15d8bda8e1 100644
--- a/packages/SettingsProvider/res/values-es-rUS/strings.xml
+++ b/packages/SettingsProvider/res/values-es-rUS/strings.xml
@@ -20,6 +20,4 @@
<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">"Almacenamiento de configuración"</string>
- <string name="wifi_softap_config_change" msgid="5688373762357941645">"Se modificó la configuración de hotspot"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Presiona para obtener más información"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-es/strings.xml b/packages/SettingsProvider/res/values-es/strings.xml
index c79968978686..7a15d8bda8e1 100644
--- a/packages/SettingsProvider/res/values-es/strings.xml
+++ b/packages/SettingsProvider/res/values-es/strings.xml
@@ -20,6 +20,4 @@
<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">"Almacenamiento de configuración"</string>
- <string name="wifi_softap_config_change" msgid="5688373762357941645">"Se han cambiado los ajustes de Compartir Internet"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Toca para ver información detallada"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-et/strings.xml b/packages/SettingsProvider/res/values-et/strings.xml
index 856ccf1c96f0..30b729365f15 100644
--- a/packages/SettingsProvider/res/values-et/strings.xml
+++ b/packages/SettingsProvider/res/values-et/strings.xml
@@ -20,6 +20,4 @@
<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">"Seadete talletusruum"</string>
- <string name="wifi_softap_config_change" msgid="5688373762357941645">"Kuumkoha seaded on muutunud"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Puudutage üksikasjade vaatamiseks"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-eu/strings.xml b/packages/SettingsProvider/res/values-eu/strings.xml
index e7d2c67ab736..6780ae0f663c 100644
--- a/packages/SettingsProvider/res/values-eu/strings.xml
+++ b/packages/SettingsProvider/res/values-eu/strings.xml
@@ -20,6 +20,4 @@
<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">"Ezarpenen biltegia"</string>
- <string name="wifi_softap_config_change" msgid="5688373762357941645">"Wifi-gunearen ezarpenak aldatu dira"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Sakatu hau xehetasunak ikusteko"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-fa/strings.xml b/packages/SettingsProvider/res/values-fa/strings.xml
index 946e2c07c576..dbeab8cbe4bc 100644
--- a/packages/SettingsProvider/res/values-fa/strings.xml
+++ b/packages/SettingsProvider/res/values-fa/strings.xml
@@ -20,6 +20,4 @@
<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="wifi_softap_config_change" msgid="5688373762357941645">"تنظیمات نقطه اتصال تغییر کرده است"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"برای مشاهده جزئیات ضربه بزنید"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-fi/strings.xml b/packages/SettingsProvider/res/values-fi/strings.xml
index 829bb3b722cf..83c7f66b7374 100644
--- a/packages/SettingsProvider/res/values-fi/strings.xml
+++ b/packages/SettingsProvider/res/values-fi/strings.xml
@@ -20,6 +20,4 @@
<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">"Asetuksien tallennus"</string>
- <string name="wifi_softap_config_change" msgid="5688373762357941645">"Hotspot-asetuksia on muutettu"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Katso lisätiedot napauttamalla"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-fr-rCA/strings.xml b/packages/SettingsProvider/res/values-fr-rCA/strings.xml
index d6408456222c..c90eb0957e52 100644
--- a/packages/SettingsProvider/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsProvider/res/values-fr-rCA/strings.xml
@@ -20,6 +20,4 @@
<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">"Stockage des paramètres"</string>
- <string name="wifi_softap_config_change" msgid="5688373762357941645">"Les paramètres de point d\'accès ont changé"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Touchez pour afficher les renseignements"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-fr/strings.xml b/packages/SettingsProvider/res/values-fr/strings.xml
index ba6ec0b31444..c90eb0957e52 100644
--- a/packages/SettingsProvider/res/values-fr/strings.xml
+++ b/packages/SettingsProvider/res/values-fr/strings.xml
@@ -20,6 +20,4 @@
<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">"Stockage des paramètres"</string>
- <string name="wifi_softap_config_change" msgid="5688373762357941645">"Les paramètres de point d\'accès ont changé"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Appuyer ici pour plus d\'infos"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-gl/strings.xml b/packages/SettingsProvider/res/values-gl/strings.xml
index 1be162e82783..80ef3102ad62 100644
--- a/packages/SettingsProvider/res/values-gl/strings.xml
+++ b/packages/SettingsProvider/res/values-gl/strings.xml
@@ -20,6 +20,4 @@
<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">"Almacenamento da configuración"</string>
- <string name="wifi_softap_config_change" msgid="5688373762357941645">"A configuración da zona wifi cambiou"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Toca a notificación para ver os detalles"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-gu/strings.xml b/packages/SettingsProvider/res/values-gu/strings.xml
index dded10ea7006..46c34c6fbd90 100644
--- a/packages/SettingsProvider/res/values-gu/strings.xml
+++ b/packages/SettingsProvider/res/values-gu/strings.xml
@@ -20,6 +20,4 @@
<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="wifi_softap_config_change" msgid="5688373762357941645">"હૉટસ્પૉટ સેટિંગ બદલાઈ ગઈ છે"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"વિગતો જોવા માટે ટૅપ કરો"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-hi/strings.xml b/packages/SettingsProvider/res/values-hi/strings.xml
index 9441a59252e8..da8193fa55b9 100644
--- a/packages/SettingsProvider/res/values-hi/strings.xml
+++ b/packages/SettingsProvider/res/values-hi/strings.xml
@@ -20,6 +20,4 @@
<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="wifi_softap_config_change" msgid="5688373762357941645">"हॉटस्पॉट की सेटिंग बदल गई हैं"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"जानकारी देखने के लिए टैप करें"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-hr/strings.xml b/packages/SettingsProvider/res/values-hr/strings.xml
index 206f50f1bc0a..87f1270bb139 100644
--- a/packages/SettingsProvider/res/values-hr/strings.xml
+++ b/packages/SettingsProvider/res/values-hr/strings.xml
@@ -20,6 +20,4 @@
<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">"Postavke pohrane"</string>
- <string name="wifi_softap_config_change" msgid="5688373762357941645">"Promijenile su se postavke žarišne točke"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Dodirnite da biste vidjeli pojedinosti"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-hu/strings.xml b/packages/SettingsProvider/res/values-hu/strings.xml
index a7ca0d28df13..dab1b17758b0 100644
--- a/packages/SettingsProvider/res/values-hu/strings.xml
+++ b/packages/SettingsProvider/res/values-hu/strings.xml
@@ -20,6 +20,4 @@
<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">"Beállítástároló"</string>
- <string name="wifi_softap_config_change" msgid="5688373762357941645">"A hotspot beállításai módosultak"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Koppintson a részletek megtekintéséhez"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-hy/strings.xml b/packages/SettingsProvider/res/values-hy/strings.xml
index 4fdb880197de..b1f1afbaf664 100644
--- a/packages/SettingsProvider/res/values-hy/strings.xml
+++ b/packages/SettingsProvider/res/values-hy/strings.xml
@@ -20,6 +20,4 @@
<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="wifi_softap_config_change" msgid="5688373762357941645">"Թեժ կետի կարգավորումները փոխվել են"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Հպեք՝ ավելին իմանալու համար"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-in/strings.xml b/packages/SettingsProvider/res/values-in/strings.xml
index 911892b09e55..bed20eb8a327 100644
--- a/packages/SettingsProvider/res/values-in/strings.xml
+++ b/packages/SettingsProvider/res/values-in/strings.xml
@@ -20,6 +20,4 @@
<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">"Setelan Penyimpanan"</string>
- <string name="wifi_softap_config_change" msgid="5688373762357941645">"Setelan hotspot telah berubah"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Ketuk untuk melihat detail"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-is/strings.xml b/packages/SettingsProvider/res/values-is/strings.xml
index c72442e3c238..c4e2aa689702 100644
--- a/packages/SettingsProvider/res/values-is/strings.xml
+++ b/packages/SettingsProvider/res/values-is/strings.xml
@@ -20,6 +20,4 @@
<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">"Stillingageymsla"</string>
- <string name="wifi_softap_config_change" msgid="5688373762357941645">"Stillingum heits reits hefur verið breytt"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Ýttu til að sjá upplýsingar"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-it/strings.xml b/packages/SettingsProvider/res/values-it/strings.xml
index 0e11d0648b70..ba1431d821fa 100644
--- a/packages/SettingsProvider/res/values-it/strings.xml
+++ b/packages/SettingsProvider/res/values-it/strings.xml
@@ -20,6 +20,4 @@
<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">"Memoria impostazioni"</string>
- <string name="wifi_softap_config_change" msgid="5688373762357941645">"Le impostazioni di hotspot sono state modificate"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Tocca per vedere i dettagli"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-iw/strings.xml b/packages/SettingsProvider/res/values-iw/strings.xml
index 10765fe90b45..ad2eaf4a2215 100644
--- a/packages/SettingsProvider/res/values-iw/strings.xml
+++ b/packages/SettingsProvider/res/values-iw/strings.xml
@@ -20,6 +20,4 @@
<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="wifi_softap_config_change" msgid="5688373762357941645">"‏הגדרות נקודת האינטרנט (hotspot) השתנו"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"יש להקיש להצגת פרטים"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-ja/strings.xml b/packages/SettingsProvider/res/values-ja/strings.xml
index 5b91b2de1951..d222ca93a0db 100644
--- a/packages/SettingsProvider/res/values-ja/strings.xml
+++ b/packages/SettingsProvider/res/values-ja/strings.xml
@@ -20,6 +20,4 @@
<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="wifi_softap_config_change" msgid="5688373762357941645">"アクセス ポイントの設定が変更されました"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"タップして詳細を確認してください"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-ka/strings.xml b/packages/SettingsProvider/res/values-ka/strings.xml
index 70845acf262a..691a2e966b1a 100644
--- a/packages/SettingsProvider/res/values-ka/strings.xml
+++ b/packages/SettingsProvider/res/values-ka/strings.xml
@@ -20,6 +20,4 @@
<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="wifi_softap_config_change" msgid="5688373762357941645">"უსადენო ქსელის პარამეტრები შეიცვალა"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"შეეხეთ დეტალების სანახავად"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-kk/strings.xml b/packages/SettingsProvider/res/values-kk/strings.xml
index 2823e4e925c0..8cf8af2b2894 100644
--- a/packages/SettingsProvider/res/values-kk/strings.xml
+++ b/packages/SettingsProvider/res/values-kk/strings.xml
@@ -20,6 +20,4 @@
<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="wifi_softap_config_change" msgid="5688373762357941645">"Хотспот параметрлері өзгертілді"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Мәліметтерді көру үшін түртіңіз."</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-km/strings.xml b/packages/SettingsProvider/res/values-km/strings.xml
index cdae41066836..7be624279c50 100644
--- a/packages/SettingsProvider/res/values-km/strings.xml
+++ b/packages/SettingsProvider/res/values-km/strings.xml
@@ -20,6 +20,4 @@
<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="wifi_softap_config_change" msgid="5688373762357941645">"បាន​ប្ដូរ​ការកំណត់​ហតស្ប៉ត"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"ចុច​ដើម្បី​មើល​ព័ត៌មានលម្អិត"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-kn/strings.xml b/packages/SettingsProvider/res/values-kn/strings.xml
index 400b358e7c9b..ca427ec75038 100644
--- a/packages/SettingsProvider/res/values-kn/strings.xml
+++ b/packages/SettingsProvider/res/values-kn/strings.xml
@@ -20,6 +20,4 @@
<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="wifi_softap_config_change" msgid="5688373762357941645">"ಹಾಟ್‌ಸ್ಪಾಟ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳು ಬದಲಾಗಿವೆ"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"ವಿವರಗಳನ್ನು ನೋಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-ko/strings.xml b/packages/SettingsProvider/res/values-ko/strings.xml
index d76b76667747..8e0cc75de7e0 100644
--- a/packages/SettingsProvider/res/values-ko/strings.xml
+++ b/packages/SettingsProvider/res/values-ko/strings.xml
@@ -20,6 +20,4 @@
<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="wifi_softap_config_change" msgid="5688373762357941645">"핫스팟 설정 변경됨"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"세부정보를 보려면 탭하세요."</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-ky/strings.xml b/packages/SettingsProvider/res/values-ky/strings.xml
index 830182b26594..2bbfa3d0d100 100644
--- a/packages/SettingsProvider/res/values-ky/strings.xml
+++ b/packages/SettingsProvider/res/values-ky/strings.xml
@@ -20,6 +20,4 @@
<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="wifi_softap_config_change" msgid="5688373762357941645">"Байланыш түйүнү параметрлери өзгөрдү"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Чоо-жайын билүү үчүн басыңыз"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-lo/strings.xml b/packages/SettingsProvider/res/values-lo/strings.xml
index c2b5df71d11b..4e5793661740 100644
--- a/packages/SettingsProvider/res/values-lo/strings.xml
+++ b/packages/SettingsProvider/res/values-lo/strings.xml
@@ -20,6 +20,4 @@
<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="wifi_softap_config_change" msgid="5688373762357941645">"ບັນທຶກການຕັ້ງຄ່າຮັອດສະປອດແລ້ວ"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"ແຕະເພື່ອເບິ່ງລາຍລະອຽດ"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-lt/strings.xml b/packages/SettingsProvider/res/values-lt/strings.xml
index 64f429b242e5..5b4432ff5f31 100644
--- a/packages/SettingsProvider/res/values-lt/strings.xml
+++ b/packages/SettingsProvider/res/values-lt/strings.xml
@@ -20,6 +20,4 @@
<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">"Nustatymų saugykla"</string>
- <string name="wifi_softap_config_change" msgid="5688373762357941645">"Buvo pakeisti viešosios interneto prieigos taško nustatymai"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Palieskite ir peržiūrėkite išsamią informaciją"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-lv/strings.xml b/packages/SettingsProvider/res/values-lv/strings.xml
index e5af8f785773..c83580c7026e 100644
--- a/packages/SettingsProvider/res/values-lv/strings.xml
+++ b/packages/SettingsProvider/res/values-lv/strings.xml
@@ -20,6 +20,4 @@
<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">"Iestatījumu krātuve"</string>
- <string name="wifi_softap_config_change" msgid="5688373762357941645">"Ir mainīti tīklāja iestatījumi"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Pieskarieties, lai skatītu detalizētāku informāciju."</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-mk/strings.xml b/packages/SettingsProvider/res/values-mk/strings.xml
index 13ff8a26d95d..f281baea384d 100644
--- a/packages/SettingsProvider/res/values-mk/strings.xml
+++ b/packages/SettingsProvider/res/values-mk/strings.xml
@@ -20,6 +20,4 @@
<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="wifi_softap_config_change" msgid="5688373762357941645">"Поставките за точка на пристап се променија"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Допрете за да видите детали"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-ml/strings.xml b/packages/SettingsProvider/res/values-ml/strings.xml
index 8df8ce4e02c8..43a88e1dd5a9 100644
--- a/packages/SettingsProvider/res/values-ml/strings.xml
+++ b/packages/SettingsProvider/res/values-ml/strings.xml
@@ -20,6 +20,4 @@
<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="wifi_softap_config_change" msgid="5688373762357941645">"ഹോട്ട്‌സ്‌പോട്ട് ക്രമീകരണം മാറിയിരിക്കുന്നു"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"വിശദാംശങ്ങൾ കാണാൻ ടാപ്പ് ചെയ്യുക"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-mn/strings.xml b/packages/SettingsProvider/res/values-mn/strings.xml
index a9c2e8ca0e9d..94521451bcee 100644
--- a/packages/SettingsProvider/res/values-mn/strings.xml
+++ b/packages/SettingsProvider/res/values-mn/strings.xml
@@ -20,6 +20,4 @@
<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="wifi_softap_config_change" msgid="5688373762357941645">"Сүлжээний цэгийн тохиргоог өөрчиллөө"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Дэлгэрэнгүй мэдээлэл харахын тулд товшино уу"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-mr/strings.xml b/packages/SettingsProvider/res/values-mr/strings.xml
index 51b8b194df15..65a876f1a02a 100644
--- a/packages/SettingsProvider/res/values-mr/strings.xml
+++ b/packages/SettingsProvider/res/values-mr/strings.xml
@@ -20,6 +20,4 @@
<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="wifi_softap_config_change" msgid="5688373762357941645">"हॉटस्पॉट सेटिंग्ज बदलल्या आहेत"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"तपशील पाहण्यासाठी टॅप करा"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-ms/strings.xml b/packages/SettingsProvider/res/values-ms/strings.xml
index 51a8f2baa4e7..9108b0706899 100644
--- a/packages/SettingsProvider/res/values-ms/strings.xml
+++ b/packages/SettingsProvider/res/values-ms/strings.xml
@@ -20,6 +20,4 @@
<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">"Storan Tetapan"</string>
- <string name="wifi_softap_config_change" msgid="5688373762357941645">"Tetapan tempat liputan telah berubah"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Ketik untuk melihat butiran"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-my/strings.xml b/packages/SettingsProvider/res/values-my/strings.xml
index dc9f53171a28..0c5e8407758a 100644
--- a/packages/SettingsProvider/res/values-my/strings.xml
+++ b/packages/SettingsProvider/res/values-my/strings.xml
@@ -20,6 +20,4 @@
<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="wifi_softap_config_change" msgid="5688373762357941645">"ဟော့စပေါ့ ဆက်တင်များ ပြောင်းသွားပြီ"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"အသေးစိတ်ကြည့်ရန် တို့ပါ"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-nb/strings.xml b/packages/SettingsProvider/res/values-nb/strings.xml
index 8da90c0f32cb..ad18f945d401 100644
--- a/packages/SettingsProvider/res/values-nb/strings.xml
+++ b/packages/SettingsProvider/res/values-nb/strings.xml
@@ -20,6 +20,4 @@
<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">"Lagring av innstillinger"</string>
- <string name="wifi_softap_config_change" msgid="5688373762357941645">"Innstillingene for wifi-sone er endret"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Trykk for å se detaljer"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-ne/strings.xml b/packages/SettingsProvider/res/values-ne/strings.xml
index a0e3465a32ff..af6ef62a17eb 100644
--- a/packages/SettingsProvider/res/values-ne/strings.xml
+++ b/packages/SettingsProvider/res/values-ne/strings.xml
@@ -20,6 +20,4 @@
<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="wifi_softap_config_change" msgid="5688373762357941645">"हटस्पटका सेटिङ परिवर्तन गरिएका छन्"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"विवरणहरू हेर्न ट्याप गर्नुहोस्"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-nl/strings.xml b/packages/SettingsProvider/res/values-nl/strings.xml
index 91b854242938..010fdb574eac 100644
--- a/packages/SettingsProvider/res/values-nl/strings.xml
+++ b/packages/SettingsProvider/res/values-nl/strings.xml
@@ -20,6 +20,4 @@
<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">"Opslagruimte voor instellingen"</string>
- <string name="wifi_softap_config_change" msgid="5688373762357941645">"Hotspot-instellingen zijn gewijzigd"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Tik voor meer informatie"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-or/strings.xml b/packages/SettingsProvider/res/values-or/strings.xml
index 099130c77a00..1087e93ab92a 100644
--- a/packages/SettingsProvider/res/values-or/strings.xml
+++ b/packages/SettingsProvider/res/values-or/strings.xml
@@ -20,6 +20,4 @@
<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="wifi_softap_config_change" msgid="5688373762357941645">"ହଟସ୍ପଟ୍ ସେଟିଂସ ବଦଳାଯାଇଛି"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"ବିବରଣୀ ଦେଖିବାକୁ ଟାପ୍ କରନ୍ତୁ"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-pa/strings.xml b/packages/SettingsProvider/res/values-pa/strings.xml
index 1c9a985677eb..1813becf434a 100644
--- a/packages/SettingsProvider/res/values-pa/strings.xml
+++ b/packages/SettingsProvider/res/values-pa/strings.xml
@@ -20,6 +20,4 @@
<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="wifi_softap_config_change" msgid="5688373762357941645">"ਹੌਟਸਪੌਟ ਸੈਟਿੰਗਾਂ ਬਦਲ ਗਈਆਂ ਹਨ"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"ਵੇਰਵੇ ਦੇਖਣ ਲਈ ਟੈਪ ਕਰੋ"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-pl/strings.xml b/packages/SettingsProvider/res/values-pl/strings.xml
index d86fc4d03fa4..9f81e632a504 100644
--- a/packages/SettingsProvider/res/values-pl/strings.xml
+++ b/packages/SettingsProvider/res/values-pl/strings.xml
@@ -20,6 +20,4 @@
<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">"Pamięć ustawień"</string>
- <string name="wifi_softap_config_change" msgid="5688373762357941645">"Ustawienia hotspotu zostały zmienione"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Kliknij, by zobaczyć szczegóły"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-pt-rBR/strings.xml b/packages/SettingsProvider/res/values-pt-rBR/strings.xml
index a8600188a54e..ade17469292c 100644
--- a/packages/SettingsProvider/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsProvider/res/values-pt-rBR/strings.xml
@@ -20,6 +20,4 @@
<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">"Armazenamento de configurações"</string>
- <string name="wifi_softap_config_change" msgid="5688373762357941645">"As configurações de ponto de acesso mudaram"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Toque para ver os detalhes"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-pt-rPT/strings.xml b/packages/SettingsProvider/res/values-pt-rPT/strings.xml
index a8a8e07b3e86..c7dc9e6dc6dd 100644
--- a/packages/SettingsProvider/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsProvider/res/values-pt-rPT/strings.xml
@@ -20,6 +20,4 @@
<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">"Armazenamento de definições"</string>
- <string name="wifi_softap_config_change" msgid="5688373762357941645">"As definições da zona Wi-Fi foram alteradas"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Toque para ver os detalhes."</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-pt/strings.xml b/packages/SettingsProvider/res/values-pt/strings.xml
index a8600188a54e..ade17469292c 100644
--- a/packages/SettingsProvider/res/values-pt/strings.xml
+++ b/packages/SettingsProvider/res/values-pt/strings.xml
@@ -20,6 +20,4 @@
<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">"Armazenamento de configurações"</string>
- <string name="wifi_softap_config_change" msgid="5688373762357941645">"As configurações de ponto de acesso mudaram"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Toque para ver os detalhes"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-ro/strings.xml b/packages/SettingsProvider/res/values-ro/strings.xml
index db1301966100..53e9429a49cd 100644
--- a/packages/SettingsProvider/res/values-ro/strings.xml
+++ b/packages/SettingsProvider/res/values-ro/strings.xml
@@ -20,6 +20,4 @@
<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">"Stocare setări"</string>
- <string name="wifi_softap_config_change" msgid="5688373762357941645">"Setările hotspotului s-au modificat"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Atinge pentru detalii"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-ru/strings.xml b/packages/SettingsProvider/res/values-ru/strings.xml
index 331fae1c9046..4c15984c7ceb 100644
--- a/packages/SettingsProvider/res/values-ru/strings.xml
+++ b/packages/SettingsProvider/res/values-ru/strings.xml
@@ -20,6 +20,4 @@
<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="wifi_softap_config_change" msgid="5688373762357941645">"Настройки точки доступа изменены"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Нажмите, чтобы узнать больше."</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-si/strings.xml b/packages/SettingsProvider/res/values-si/strings.xml
index a9c4d0b8ef0b..24ef79820220 100644
--- a/packages/SettingsProvider/res/values-si/strings.xml
+++ b/packages/SettingsProvider/res/values-si/strings.xml
@@ -20,6 +20,4 @@
<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="wifi_softap_config_change" msgid="5688373762357941645">"හොට්ස්පොට් සැකසීම් වෙනස් කර ඇත"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"විස්තර බැලීමට තට්ටු කරන්න"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-sk/strings.xml b/packages/SettingsProvider/res/values-sk/strings.xml
index 5712d05f752f..955c834754c2 100644
--- a/packages/SettingsProvider/res/values-sk/strings.xml
+++ b/packages/SettingsProvider/res/values-sk/strings.xml
@@ -20,6 +20,4 @@
<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">"Ukladací priestor nastavení"</string>
- <string name="wifi_softap_config_change" msgid="5688373762357941645">"Nastavenia hotspotu boli zmenené"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Klepnutím zobrazíte podrobnosti"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-sl/strings.xml b/packages/SettingsProvider/res/values-sl/strings.xml
index 4e265fb5ecaf..3d7768dfa024 100644
--- a/packages/SettingsProvider/res/values-sl/strings.xml
+++ b/packages/SettingsProvider/res/values-sl/strings.xml
@@ -20,6 +20,4 @@
<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">"Shramba nastavitev"</string>
- <string name="wifi_softap_config_change" msgid="5688373762357941645">"Nastavitve dostopne ročke so spremenjene"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Dotaknite se za ogled podrobnosti"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-sq/strings.xml b/packages/SettingsProvider/res/values-sq/strings.xml
index 8bbe2e70dbe0..a8e66d5dae80 100644
--- a/packages/SettingsProvider/res/values-sq/strings.xml
+++ b/packages/SettingsProvider/res/values-sq/strings.xml
@@ -20,6 +20,4 @@
<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">"Hapësira ruajtëse e \"Cilësimeve\""</string>
- <string name="wifi_softap_config_change" msgid="5688373762357941645">"Cilësimet e zonës së qasjes për internet kanë ndryshuar"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Trokit për të parë detajet"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-sr/strings.xml b/packages/SettingsProvider/res/values-sr/strings.xml
index 4d0576212d9c..7082761e1f71 100644
--- a/packages/SettingsProvider/res/values-sr/strings.xml
+++ b/packages/SettingsProvider/res/values-sr/strings.xml
@@ -20,6 +20,4 @@
<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="wifi_softap_config_change" msgid="5688373762357941645">"Подешавања хотспота су промењена"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Додирните да бисте видели детаље"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-sv/strings.xml b/packages/SettingsProvider/res/values-sv/strings.xml
index 5ee4703dcfc6..b6de084cdeb9 100644
--- a/packages/SettingsProvider/res/values-sv/strings.xml
+++ b/packages/SettingsProvider/res/values-sv/strings.xml
@@ -20,6 +20,4 @@
<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">"Lagring av inställningar"</string>
- <string name="wifi_softap_config_change" msgid="5688373762357941645">"Inställningarna för surfzon har ändrats"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Tryck här för mer information"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-sw/strings.xml b/packages/SettingsProvider/res/values-sw/strings.xml
index 59f82a948177..d17f60b92aea 100644
--- a/packages/SettingsProvider/res/values-sw/strings.xml
+++ b/packages/SettingsProvider/res/values-sw/strings.xml
@@ -20,6 +20,4 @@
<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">"Hifadhi ya Mipangilio"</string>
- <string name="wifi_softap_config_change" msgid="5688373762357941645">"Mipangilio ya mtandaopepe imebadilika"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Gusa ili uangalie maelezo"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-ta/strings.xml b/packages/SettingsProvider/res/values-ta/strings.xml
index 54d2242dced9..7a868785d952 100644
--- a/packages/SettingsProvider/res/values-ta/strings.xml
+++ b/packages/SettingsProvider/res/values-ta/strings.xml
@@ -20,6 +20,4 @@
<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="wifi_softap_config_change" msgid="5688373762357941645">"ஹாட்ஸ்பாட் அமைப்புகள் மாற்றப்பட்டன"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"விவரங்களைப் பார்க்க, தட்டவும்"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-te/strings.xml b/packages/SettingsProvider/res/values-te/strings.xml
index 95be5c5e9a5d..9bbe7617b02b 100644
--- a/packages/SettingsProvider/res/values-te/strings.xml
+++ b/packages/SettingsProvider/res/values-te/strings.xml
@@ -20,6 +20,4 @@
<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="wifi_softap_config_change" msgid="5688373762357941645">"హాట్‌స్పాట్ సెట్టింగ్‌లు మార్చబడ్డాయి"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"వివరాలను చూడటానికి ట్యాప్ చేయండి"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-th/strings.xml b/packages/SettingsProvider/res/values-th/strings.xml
index ed6317427da4..ae8ba6a430b8 100644
--- a/packages/SettingsProvider/res/values-th/strings.xml
+++ b/packages/SettingsProvider/res/values-th/strings.xml
@@ -20,6 +20,4 @@
<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="wifi_softap_config_change" msgid="5688373762357941645">"การตั้งค่าฮอตสปอตมีการเปลี่ยนแปลง"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"แตะเพื่อดูรายละเอียด"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-tl/strings.xml b/packages/SettingsProvider/res/values-tl/strings.xml
index 3d6be4071715..0fe535eee8e3 100644
--- a/packages/SettingsProvider/res/values-tl/strings.xml
+++ b/packages/SettingsProvider/res/values-tl/strings.xml
@@ -20,6 +20,4 @@
<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">"Storage ng Mga Setting"</string>
- <string name="wifi_softap_config_change" msgid="5688373762357941645">"Nabago ang mga setting ng hotspot"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"I-tap para makita ang mga detalye"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-tr/strings.xml b/packages/SettingsProvider/res/values-tr/strings.xml
index 75e908f46475..e99e99bc82ef 100644
--- a/packages/SettingsProvider/res/values-tr/strings.xml
+++ b/packages/SettingsProvider/res/values-tr/strings.xml
@@ -20,6 +20,4 @@
<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">"Ayarlar Deposu"</string>
- <string name="wifi_softap_config_change" msgid="5688373762357941645">"Hotspot ayarları değişti"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Ayrıntıları görmek için dokunun"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-uk/strings.xml b/packages/SettingsProvider/res/values-uk/strings.xml
index 2dbb360cbffa..900dd0710be5 100644
--- a/packages/SettingsProvider/res/values-uk/strings.xml
+++ b/packages/SettingsProvider/res/values-uk/strings.xml
@@ -20,6 +20,4 @@
<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="wifi_softap_config_change" msgid="5688373762357941645">"Налаштування точки доступу змінились"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Торкніться, щоб переглянути докладні відомості"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-ur/strings.xml b/packages/SettingsProvider/res/values-ur/strings.xml
index 5a1b0f985bb6..e79249b00c18 100644
--- a/packages/SettingsProvider/res/values-ur/strings.xml
+++ b/packages/SettingsProvider/res/values-ur/strings.xml
@@ -20,6 +20,4 @@
<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="wifi_softap_config_change" msgid="5688373762357941645">"ہاٹ اسپاٹ کی ترتیبات تبدیل ہو گئیں"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"تفصیلات دیکھنے کے لیے تھپتھپائیں"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-uz/strings.xml b/packages/SettingsProvider/res/values-uz/strings.xml
index bb6e22eb62ba..38f0ce518bf6 100644
--- a/packages/SettingsProvider/res/values-uz/strings.xml
+++ b/packages/SettingsProvider/res/values-uz/strings.xml
@@ -20,6 +20,4 @@
<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">"Sozlamalar xotirasi"</string>
- <string name="wifi_softap_config_change" msgid="5688373762357941645">"Hotspot sozlamalari oʻzgardi"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Tafsilotlar uchun bosing"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-vi/strings.xml b/packages/SettingsProvider/res/values-vi/strings.xml
index 4608983aa9e1..015fbfda9b82 100644
--- a/packages/SettingsProvider/res/values-vi/strings.xml
+++ b/packages/SettingsProvider/res/values-vi/strings.xml
@@ -20,6 +20,4 @@
<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">"Lưu trữ bộ nhớ"</string>
- <string name="wifi_softap_config_change" msgid="5688373762357941645">"Đã thay đổi các tùy chọn cài đặt điểm phát sóng"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Nhấn để xem chi tiết"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-zh-rCN/strings.xml b/packages/SettingsProvider/res/values-zh-rCN/strings.xml
index a08afc85e9a4..11c5d6c28889 100644
--- a/packages/SettingsProvider/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsProvider/res/values-zh-rCN/strings.xml
@@ -20,6 +20,4 @@
<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="wifi_softap_config_change" msgid="5688373762357941645">"热点设置已更改"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"点按即可查看详细信息"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-zh-rHK/strings.xml b/packages/SettingsProvider/res/values-zh-rHK/strings.xml
index fb91dbbbf4d8..977c9b91d13d 100644
--- a/packages/SettingsProvider/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsProvider/res/values-zh-rHK/strings.xml
@@ -20,6 +20,4 @@
<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="wifi_softap_config_change" msgid="5688373762357941645">"熱點設定已變更"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"輕按以查看詳情"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-zh-rTW/strings.xml b/packages/SettingsProvider/res/values-zh-rTW/strings.xml
index 1b8fcb267737..977c9b91d13d 100644
--- a/packages/SettingsProvider/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsProvider/res/values-zh-rTW/strings.xml
@@ -20,6 +20,4 @@
<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="wifi_softap_config_change" msgid="5688373762357941645">"無線基地台設定有所變更"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"輕觸即可查看詳細資料"</string>
</resources>
diff --git a/packages/SettingsProvider/res/values-zu/strings.xml b/packages/SettingsProvider/res/values-zu/strings.xml
index dad24b496fd9..cb5a7818423b 100644
--- a/packages/SettingsProvider/res/values-zu/strings.xml
+++ b/packages/SettingsProvider/res/values-zu/strings.xml
@@ -20,6 +20,4 @@
<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">"Izilungiselelo zesitoreji"</string>
- <string name="wifi_softap_config_change" msgid="5688373762357941645">"Izilungiselelo ze-Hotspot zishintshile"</string>
- <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Thepha ukuze ubone imininingwane"</string>
</resources>
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 43ea3ec3de4e..02d19dc84f2e 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -564,7 +564,7 @@
<uses-permission android:name="android.permission.TEST_BIOMETRIC" />
<!-- Permission required for CTS test - android.server.biometrics -->
- <uses-permission android:name="android.permission.SET_BIOMETRIC_DIALOG_LOGO" />
+ <uses-permission android:name="android.permission.SET_BIOMETRIC_DIALOG_ADVANCED" />
<!-- Permissions required for CTS test - NotificationManagerTest -->
<uses-permission android:name="android.permission.MANAGE_NOTIFICATION_LISTENERS" />
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/AccessibilityMenuService.java b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/AccessibilityMenuService.java
index 88181e7e2a52..4dd029c038bb 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/AccessibilityMenuService.java
+++ b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/AccessibilityMenuService.java
@@ -280,10 +280,8 @@ public class AccessibilityMenuService extends AccessibilityService
return;
}
- if (Flags.a11yMenuHideBeforeTakingAction()) {
- // Hide the a11y menu UI before performing the following shortcut actions.
- mA11yMenuLayout.hideMenu();
- }
+ // Hide the a11y menu UI before performing the following shortcut actions.
+ mA11yMenuLayout.hideMenu();
if (viewTag == ShortcutId.ID_ASSISTANT_VALUE.ordinal()) {
// Always restart the voice command activity, so that the UI is reloaded.
@@ -299,31 +297,18 @@ public class AccessibilityMenuService extends AccessibilityService
} else if (viewTag == ShortcutId.ID_RECENT_VALUE.ordinal()) {
performGlobalActionInternal(GLOBAL_ACTION_RECENTS);
} else if (viewTag == ShortcutId.ID_LOCKSCREEN_VALUE.ordinal()) {
- if (Flags.a11yMenuHideBeforeTakingAction()) {
- // Delay before locking the screen to give time for the UI to close.
- mHandler.postDelayed(
- () -> performGlobalActionInternal(GLOBAL_ACTION_LOCK_SCREEN),
- HIDE_UI_DELAY_MS);
- } else {
- performGlobalActionInternal(GLOBAL_ACTION_LOCK_SCREEN);
- }
+ // Delay before locking the screen to give time for the UI to close.
+ mHandler.postDelayed(
+ () -> performGlobalActionInternal(GLOBAL_ACTION_LOCK_SCREEN),
+ HIDE_UI_DELAY_MS);
} else if (viewTag == ShortcutId.ID_QUICKSETTING_VALUE.ordinal()) {
performGlobalActionInternal(GLOBAL_ACTION_QUICK_SETTINGS);
} else if (viewTag == ShortcutId.ID_NOTIFICATION_VALUE.ordinal()) {
performGlobalActionInternal(GLOBAL_ACTION_NOTIFICATIONS);
} else if (viewTag == ShortcutId.ID_SCREENSHOT_VALUE.ordinal()) {
- if (Flags.a11yMenuHideBeforeTakingAction()) {
- // Delay before taking a screenshot to give time for the UI to close.
- mHandler.postDelayed(
- () -> performGlobalActionInternal(GLOBAL_ACTION_TAKE_SCREENSHOT),
- HIDE_UI_DELAY_MS);
- } else {
- performGlobalActionInternal(GLOBAL_ACTION_TAKE_SCREENSHOT);
- }
- }
-
- if (!Flags.a11yMenuHideBeforeTakingAction()) {
- mA11yMenuLayout.hideMenu();
+ mHandler.postDelayed(
+ () -> performGlobalActionInternal(GLOBAL_ACTION_TAKE_SCREENSHOT),
+ HIDE_UI_DELAY_MS);
}
}
diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig
index e5e34695f40c..c0fd124fcfd1 100644
--- a/packages/SystemUI/aconfig/systemui.aconfig
+++ b/packages/SystemUI/aconfig/systemui.aconfig
@@ -345,6 +345,16 @@ flag {
}
flag {
+ name: "activity_transition_use_largest_window"
+ namespace: "systemui"
+ description: "Target largest opening window during activity transitions."
+ bug: "323294573"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
name: "centralized_status_bar_height_fix"
namespace: "systemui"
description: "Refactors shade header and keyguard status bar to read status bar dimens from a"
@@ -470,6 +480,27 @@ flag {
}
flag {
+ name: "disable_contextual_tips_frequency_check"
+ description: "Disables frequency capping check for contextual tips."
+ namespace: "systemui"
+ bug: "322891421"
+}
+
+flag {
+ name: "disable_contextual_tips_ios_switcher_check"
+ description: "Disables iOS switcher check which guard the tips designed only for iOS switchers."
+ namespace: "systemui"
+ bug: "322891421"
+}
+
+flag {
+ name: "disable_contextual_tips_first_30d_check"
+ description: "Disables condition check which only show tips within 30 days after phone setup."
+ namespace: "systemui"
+ bug: "322891421"
+}
+
+flag {
name: "enable_contextual_tips"
description: "Enables showing contextual tips."
namespace: "systemui"
diff --git a/packages/SystemUI/animation/Android.bp b/packages/SystemUI/animation/Android.bp
index 99b7c36d6fb9..2268d16e5b0a 100644
--- a/packages/SystemUI/animation/Android.bp
+++ b/packages/SystemUI/animation/Android.bp
@@ -44,6 +44,7 @@ android_library {
"androidx.core_core-animation-nodeps",
"androidx.core_core-ktx",
"androidx.annotation_annotation",
+ "com_android_systemui_flags_lib",
"SystemUIShaderLib",
"WindowManager-Shell-shared",
"animationlib",
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt
index 1b99e19eeb95..ea1cb3441215 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt
@@ -43,6 +43,7 @@ import androidx.annotation.UiThread
import com.android.app.animation.Interpolators
import com.android.internal.annotations.VisibleForTesting
import com.android.internal.policy.ScreenDecorationsUtils
+import com.android.systemui.Flags.activityTransitionUseLargestWindow
import kotlin.math.roundToInt
private const val TAG = "ActivityTransitionAnimator"
@@ -648,11 +649,27 @@ class ActivityTransitionAnimator(
var candidate: RemoteAnimationTarget? = null
for (it in apps) {
if (it.mode == RemoteAnimationTarget.MODE_OPENING) {
- if (!it.hasAnimatingParent) {
- return it
- }
- if (candidate == null) {
- candidate = it
+ if (activityTransitionUseLargestWindow()) {
+ if (
+ candidate == null ||
+ !it.hasAnimatingParent && candidate.hasAnimatingParent
+ ) {
+ candidate = it
+ continue
+ }
+ if (
+ !it.hasAnimatingParent &&
+ it.screenSpaceBounds.hasGreaterAreaThan(candidate.screenSpaceBounds)
+ ) {
+ candidate = it
+ }
+ } else {
+ if (!it.hasAnimatingParent) {
+ return it
+ }
+ if (candidate == null) {
+ candidate = it
+ }
}
}
}
@@ -960,5 +977,9 @@ class ActivityTransitionAnimator(
e.printStackTrace()
}
}
+
+ private fun Rect.hasGreaterAreaThan(other: Rect): Boolean {
+ return (this.width() * this.height()) > (other.width() * other.height())
+ }
}
}
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/PlatformSlider.kt b/packages/SystemUI/compose/core/src/com/android/compose/PlatformSlider.kt
index f779cf3671d7..596a297a6dbe 100644
--- a/packages/SystemUI/compose/core/src/com/android/compose/PlatformSlider.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/PlatformSlider.kt
@@ -241,6 +241,7 @@ private fun Track(
measurePolicy =
TrackMeasurePolicy(
sliderState = sliderState,
+ enabled = enabled,
thumbSize = LocalDensity.current.run { thumbSize.roundToPx() },
isRtl = isRtl,
onDrawingStateMeasured = { drawingState = it }
@@ -304,6 +305,7 @@ private fun TrackBackground(
/** Measures track components sizes and calls [onDrawingStateMeasured] when it's done. */
private class TrackMeasurePolicy(
private val sliderState: SliderState,
+ private val enabled: Boolean,
private val thumbSize: Int,
private val isRtl: Boolean,
private val onDrawingStateMeasured: (DrawingState) -> Unit,
@@ -334,7 +336,7 @@ private class TrackMeasurePolicy(
)
val iconSize = iconPlaceable?.width ?: 0
- val labelMaxWidth = (desiredWidth - iconSize) / 2
+ val labelMaxWidth = if (enabled) (desiredWidth - iconSize) / 2 else desiredWidth - iconSize
val labelPlaceable: Placeable? =
measurables
.fastFirstOrNull { it.layoutId == TrackComponent.Label }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenSceneBlueprintModule.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenSceneBlueprintModule.kt
index 53f400fac7e5..55f7f69a08d6 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenSceneBlueprintModule.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenSceneBlueprintModule.kt
@@ -19,7 +19,6 @@ package com.android.systemui.keyguard.ui.composable
import com.android.systemui.keyguard.ui.composable.blueprint.CommunalBlueprintModule
import com.android.systemui.keyguard.ui.composable.blueprint.DefaultBlueprintModule
import com.android.systemui.keyguard.ui.composable.blueprint.ShortcutsBesideUdfpsBlueprintModule
-import com.android.systemui.keyguard.ui.composable.blueprint.SplitShadeBlueprintModule
import com.android.systemui.keyguard.ui.composable.blueprint.SplitShadeWeatherClockBlueprintModule
import com.android.systemui.keyguard.ui.composable.blueprint.WeatherClockBlueprintModule
import com.android.systemui.keyguard.ui.composable.section.OptionalSectionModule
@@ -32,7 +31,6 @@ import dagger.Module
DefaultBlueprintModule::class,
OptionalSectionModule::class,
ShortcutsBesideUdfpsBlueprintModule::class,
- SplitShadeBlueprintModule::class,
SplitShadeWeatherClockBlueprintModule::class,
WeatherClockBlueprintModule::class,
],
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/ClockTransition.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/ClockTransition.kt
index c5ff859def17..d9ed4976bb34 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/ClockTransition.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/ClockTransition.kt
@@ -38,6 +38,9 @@ object ClockTransition {
from(ClockScenes.largeClockScene, to = ClockScenes.smallClockScene) {
transitioningToSmallClock()
}
+ from(ClockScenes.splitShadeLargeClockScene, to = ClockScenes.largeClockScene) {
+ spec = tween(1000)
+ }
}
private fun TransitionBuilder.transitioningToLargeClock() {
@@ -70,6 +73,8 @@ object ClockTransition {
object ClockScenes {
val smallClockScene = SceneKey("small-clock-scene")
val largeClockScene = SceneKey("large-clock-scene")
+ val splitShadeSmallClockScene = SceneKey("split-shade-small-clock-scene")
+ val splitShadeLargeClockScene = SceneKey("split-shade-large-clock-scene")
}
object ClockElementKeys {
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/DefaultBlueprint.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/DefaultBlueprint.kt
index 9509fd22534a..320c455a8201 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/DefaultBlueprint.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/DefaultBlueprint.kt
@@ -22,18 +22,15 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.Layout
-import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.IntRect
import com.android.compose.animation.scene.SceneScope
import com.android.systemui.keyguard.ui.composable.LockscreenLongPress
import com.android.systemui.keyguard.ui.composable.section.AmbientIndicationSection
import com.android.systemui.keyguard.ui.composable.section.BottomAreaSection
-import com.android.systemui.keyguard.ui.composable.section.DefaultClockSection
import com.android.systemui.keyguard.ui.composable.section.LockSection
-import com.android.systemui.keyguard.ui.composable.section.MediaCarouselSection
-import com.android.systemui.keyguard.ui.composable.section.NotificationSection
import com.android.systemui.keyguard.ui.composable.section.SettingsMenuSection
import com.android.systemui.keyguard.ui.composable.section.StatusBarSection
+import com.android.systemui.keyguard.ui.composable.section.TopAreaSection
import com.android.systemui.keyguard.ui.viewmodel.LockscreenContentViewModel
import dagger.Binds
import dagger.Module
@@ -50,13 +47,11 @@ class DefaultBlueprint
constructor(
private val viewModel: LockscreenContentViewModel,
private val statusBarSection: StatusBarSection,
- private val clockSection: DefaultClockSection,
- private val notificationSection: NotificationSection,
private val lockSection: LockSection,
private val ambientIndicationSectionOptional: Optional<AmbientIndicationSection>,
private val bottomAreaSection: BottomAreaSection,
private val settingsMenuSection: SettingsMenuSection,
- private val mediaCarouselSection: MediaCarouselSection,
+ private val topAreaSection: TopAreaSection,
) : ComposableLockscreenSceneBlueprint {
override val id: String = "default"
@@ -64,7 +59,6 @@ constructor(
@Composable
override fun SceneScope.Content(modifier: Modifier) {
val isUdfpsVisible = viewModel.isUdfpsVisible
- val resources = LocalContext.current.resources
LockscreenLongPress(
viewModel = viewModel.longPress,
@@ -77,17 +71,7 @@ constructor(
modifier = Modifier.fillMaxWidth(),
) {
with(statusBarSection) { StatusBar(modifier = Modifier.fillMaxWidth()) }
- with(clockSection) { DefaultClockLayout() }
- with(mediaCarouselSection) { MediaCarousel() }
-
- if (viewModel.areNotificationsVisible(resources = resources)) {
- with(notificationSection) {
- Notifications(
- modifier = Modifier.fillMaxWidth().weight(weight = 1f)
- )
- }
- }
-
+ with(topAreaSection) { DefaultClockLayoutWithNotifications() }
if (!isUdfpsVisible && ambientIndicationSectionOptional.isPresent) {
with(ambientIndicationSectionOptional.get()) {
AmbientIndication(modifier = Modifier.fillMaxWidth())
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/ShortcutsBesideUdfpsBlueprint.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/ShortcutsBesideUdfpsBlueprint.kt
index 9abfa4233a15..64c2cb3670c8 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/ShortcutsBesideUdfpsBlueprint.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/ShortcutsBesideUdfpsBlueprint.kt
@@ -22,18 +22,15 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.Layout
-import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.IntRect
import com.android.compose.animation.scene.SceneScope
import com.android.systemui.keyguard.ui.composable.LockscreenLongPress
import com.android.systemui.keyguard.ui.composable.section.AmbientIndicationSection
import com.android.systemui.keyguard.ui.composable.section.BottomAreaSection
-import com.android.systemui.keyguard.ui.composable.section.DefaultClockSection
import com.android.systemui.keyguard.ui.composable.section.LockSection
-import com.android.systemui.keyguard.ui.composable.section.MediaCarouselSection
-import com.android.systemui.keyguard.ui.composable.section.NotificationSection
import com.android.systemui.keyguard.ui.composable.section.SettingsMenuSection
import com.android.systemui.keyguard.ui.composable.section.StatusBarSection
+import com.android.systemui.keyguard.ui.composable.section.TopAreaSection
import com.android.systemui.keyguard.ui.viewmodel.LockscreenContentViewModel
import dagger.Binds
import dagger.Module
@@ -50,13 +47,11 @@ class ShortcutsBesideUdfpsBlueprint
constructor(
private val viewModel: LockscreenContentViewModel,
private val statusBarSection: StatusBarSection,
- private val clockSection: DefaultClockSection,
- private val notificationSection: NotificationSection,
private val lockSection: LockSection,
private val ambientIndicationSectionOptional: Optional<AmbientIndicationSection>,
private val bottomAreaSection: BottomAreaSection,
private val settingsMenuSection: SettingsMenuSection,
- private val mediaCarouselSection: MediaCarouselSection,
+ private val topAreaSection: TopAreaSection,
) : ComposableLockscreenSceneBlueprint {
override val id: String = "shortcuts-besides-udfps"
@@ -64,7 +59,6 @@ constructor(
@Composable
override fun SceneScope.Content(modifier: Modifier) {
val isUdfpsVisible = viewModel.isUdfpsVisible
- val resources = LocalContext.current.resources
LockscreenLongPress(
viewModel = viewModel.longPress,
@@ -77,16 +71,7 @@ constructor(
modifier = Modifier.fillMaxWidth(),
) {
with(statusBarSection) { StatusBar(modifier = Modifier.fillMaxWidth()) }
- with(clockSection) { DefaultClockLayout() }
- with(mediaCarouselSection) { MediaCarousel() }
-
- if (viewModel.areNotificationsVisible(resources = resources)) {
- with(notificationSection) {
- Notifications(
- modifier = Modifier.fillMaxWidth().weight(weight = 1f)
- )
- }
- }
+ with(topAreaSection) { DefaultClockLayoutWithNotifications() }
if (!isUdfpsVisible && ambientIndicationSectionOptional.isPresent) {
with(ambientIndicationSectionOptional.get()) {
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/SplitShadeBlueprint.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/SplitShadeBlueprint.kt
deleted file mode 100644
index 652412d13aba..000000000000
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/SplitShadeBlueprint.kt
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * Copyright (C) 2023 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.keyguard.ui.composable.blueprint
-
-import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.fillMaxHeight
-import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.padding
-import androidx.compose.runtime.Composable
-import androidx.compose.ui.Alignment
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.layout.Layout
-import androidx.compose.ui.res.dimensionResource
-import androidx.compose.ui.unit.Dp
-import androidx.compose.ui.unit.IntRect
-import androidx.compose.ui.unit.dp
-import com.android.compose.animation.scene.SceneScope
-import com.android.compose.modifiers.padding
-import com.android.systemui.Flags
-import com.android.systemui.keyguard.ui.composable.LockscreenLongPress
-import com.android.systemui.keyguard.ui.composable.section.AmbientIndicationSection
-import com.android.systemui.keyguard.ui.composable.section.BottomAreaSection
-import com.android.systemui.keyguard.ui.composable.section.DefaultClockSection
-import com.android.systemui.keyguard.ui.composable.section.LockSection
-import com.android.systemui.keyguard.ui.composable.section.MediaCarouselSection
-import com.android.systemui.keyguard.ui.composable.section.NotificationSection
-import com.android.systemui.keyguard.ui.composable.section.SettingsMenuSection
-import com.android.systemui.keyguard.ui.composable.section.StatusBarSection
-import com.android.systemui.keyguard.ui.viewmodel.LockscreenContentViewModel
-import com.android.systemui.res.R
-import com.android.systemui.shade.LargeScreenHeaderHelper
-import dagger.Binds
-import dagger.Module
-import dagger.multibindings.IntoSet
-import java.util.Optional
-import javax.inject.Inject
-
-/**
- * Renders the lockscreen scene when showing with a split shade (e.g. unfolded foldable and/or
- * tablet form factor).
- */
-class SplitShadeBlueprint
-@Inject
-constructor(
- private val viewModel: LockscreenContentViewModel,
- private val statusBarSection: StatusBarSection,
- private val clockSection: DefaultClockSection,
- private val notificationSection: NotificationSection,
- private val lockSection: LockSection,
- private val ambientIndicationSectionOptional: Optional<AmbientIndicationSection>,
- private val bottomAreaSection: BottomAreaSection,
- private val settingsMenuSection: SettingsMenuSection,
- private val mediaCarouselSection: MediaCarouselSection,
- private val largeScreenHeaderHelper: LargeScreenHeaderHelper,
-) : ComposableLockscreenSceneBlueprint {
-
- override val id: String = "split-shade"
-
- @Composable
- override fun SceneScope.Content(modifier: Modifier) {
- val isUdfpsVisible = viewModel.isUdfpsVisible
-
- LockscreenLongPress(
- viewModel = viewModel.longPress,
- modifier = modifier,
- ) { onSettingsMenuPlaced ->
- Layout(
- content = {
- // Constrained to above the lock icon.
- Column(
- modifier = Modifier.fillMaxSize(),
- ) {
- with(statusBarSection) { StatusBar(modifier = Modifier.fillMaxWidth()) }
- Row(
- modifier = Modifier.fillMaxSize(),
- ) {
- Column(
- modifier = Modifier.fillMaxHeight().weight(weight = 1f),
- horizontalAlignment = Alignment.CenterHorizontally,
- ) {
- with(clockSection) { DefaultClockLayout() }
- with(mediaCarouselSection) { MediaCarousel() }
- }
- with(notificationSection) {
- val splitShadeTopMargin: Dp =
- if (Flags.centralizedStatusBarHeightFix()) {
- largeScreenHeaderHelper.getLargeScreenHeaderHeight().dp
- } else {
- dimensionResource(
- id = R.dimen.large_screen_shade_header_height
- )
- }
- Notifications(
- modifier =
- Modifier.fillMaxHeight()
- .weight(weight = 1f)
- .padding(top = splitShadeTopMargin)
- )
- }
- }
-
- if (!isUdfpsVisible && ambientIndicationSectionOptional.isPresent) {
- with(ambientIndicationSectionOptional.get()) {
- AmbientIndication(modifier = Modifier.fillMaxWidth())
- }
- }
- }
-
- with(lockSection) { LockIcon() }
-
- // Aligned to bottom and constrained to below the lock icon.
- Column(modifier = Modifier.fillMaxWidth()) {
- if (isUdfpsVisible && ambientIndicationSectionOptional.isPresent) {
- with(ambientIndicationSectionOptional.get()) {
- AmbientIndication(modifier = Modifier.fillMaxWidth())
- }
- }
-
- with(bottomAreaSection) {
- IndicationArea(modifier = Modifier.fillMaxWidth())
- }
- }
-
- // Aligned to bottom and NOT constrained by the lock icon.
- with(bottomAreaSection) {
- Shortcut(isStart = true, applyPadding = true)
- Shortcut(isStart = false, applyPadding = true)
- }
- with(settingsMenuSection) { SettingsMenu(onSettingsMenuPlaced) }
- },
- modifier = Modifier.fillMaxSize(),
- ) { measurables, constraints ->
- check(measurables.size == 6)
- val aboveLockIconMeasurable = measurables[0]
- val lockIconMeasurable = measurables[1]
- val belowLockIconMeasurable = measurables[2]
- val startShortcutMeasurable = measurables[3]
- val endShortcutMeasurable = measurables[4]
- val settingsMenuMeasurable = measurables[5]
-
- val noMinConstraints =
- constraints.copy(
- minWidth = 0,
- minHeight = 0,
- )
- val lockIconPlaceable = lockIconMeasurable.measure(noMinConstraints)
- val lockIconBounds =
- IntRect(
- left = lockIconPlaceable[BlueprintAlignmentLines.LockIcon.Left],
- top = lockIconPlaceable[BlueprintAlignmentLines.LockIcon.Top],
- right = lockIconPlaceable[BlueprintAlignmentLines.LockIcon.Right],
- bottom = lockIconPlaceable[BlueprintAlignmentLines.LockIcon.Bottom],
- )
-
- val aboveLockIconPlaceable =
- aboveLockIconMeasurable.measure(
- noMinConstraints.copy(maxHeight = lockIconBounds.top)
- )
- val belowLockIconPlaceable =
- belowLockIconMeasurable.measure(
- noMinConstraints.copy(
- maxHeight =
- (constraints.maxHeight - lockIconBounds.bottom).coerceAtLeast(0)
- )
- )
- val startShortcutPleaceable = startShortcutMeasurable.measure(noMinConstraints)
- val endShortcutPleaceable = endShortcutMeasurable.measure(noMinConstraints)
- val settingsMenuPlaceable = settingsMenuMeasurable.measure(noMinConstraints)
-
- layout(constraints.maxWidth, constraints.maxHeight) {
- aboveLockIconPlaceable.place(
- x = 0,
- y = 0,
- )
- lockIconPlaceable.place(
- x = lockIconBounds.left,
- y = lockIconBounds.top,
- )
- belowLockIconPlaceable.place(
- x = 0,
- y = constraints.maxHeight - belowLockIconPlaceable.height,
- )
- startShortcutPleaceable.place(
- x = 0,
- y = constraints.maxHeight - startShortcutPleaceable.height,
- )
- endShortcutPleaceable.place(
- x = constraints.maxWidth - endShortcutPleaceable.width,
- y = constraints.maxHeight - endShortcutPleaceable.height,
- )
- settingsMenuPlaceable.place(
- x = (constraints.maxWidth - settingsMenuPlaceable.width) / 2,
- y = constraints.maxHeight - settingsMenuPlaceable.height,
- )
- }
- }
- }
- }
-}
-
-@Module
-interface SplitShadeBlueprintModule {
- @Binds
- @IntoSet
- fun blueprint(blueprint: SplitShadeBlueprint): ComposableLockscreenSceneBlueprint
-}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/WeatherClockBlueprint.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/WeatherClockBlueprint.kt
index f86623fe935c..ee4e2d697833 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/WeatherClockBlueprint.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/WeatherClockBlueprint.kt
@@ -112,7 +112,7 @@ constructor(
with(mediaCarouselSection) { MediaCarousel() }
- if (viewModel.areNotificationsVisible(resources = resources)) {
+ if (viewModel.areNotificationsVisible) {
with(notificationSection) {
Notifications(
modifier = Modifier.fillMaxWidth().weight(weight = 1f)
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/DefaultClockSection.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/DefaultClockSection.kt
index 1ab2bc76c1fd..82e19e7c154c 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/DefaultClockSection.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/DefaultClockSection.kt
@@ -16,39 +16,29 @@
package com.android.systemui.keyguard.ui.composable.section
+import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
-import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.viewinterop.AndroidView
+import androidx.core.view.contains
import com.android.compose.animation.scene.SceneScope
-import com.android.compose.animation.scene.SceneTransitionLayout
import com.android.compose.modifiers.padding
import com.android.systemui.customization.R as customizationR
-import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor
import com.android.systemui.keyguard.ui.composable.blueprint.ClockElementKeys.largeClockElementKey
import com.android.systemui.keyguard.ui.composable.blueprint.ClockElementKeys.smallClockElementKey
-import com.android.systemui.keyguard.ui.composable.blueprint.ClockElementKeys.smartspaceElementKey
-import com.android.systemui.keyguard.ui.composable.blueprint.ClockScenes.largeClockScene
-import com.android.systemui.keyguard.ui.composable.blueprint.ClockScenes.smallClockScene
-import com.android.systemui.keyguard.ui.composable.blueprint.ClockTransition.defaultClockTransitions
-import com.android.systemui.keyguard.ui.composable.blueprint.rememberBurnIn
import com.android.systemui.keyguard.ui.composable.modifier.burnInAware
import com.android.systemui.keyguard.ui.composable.modifier.onTopPlacementChanged
import com.android.systemui.keyguard.ui.viewmodel.AodBurnInViewModel
import com.android.systemui.keyguard.ui.viewmodel.BurnInParameters
import com.android.systemui.keyguard.ui.viewmodel.KeyguardClockViewModel
-import com.android.systemui.keyguard.ui.viewmodel.LockscreenContentViewModel
-import com.android.systemui.res.R
import javax.inject.Inject
/** Provides small clock and large clock composables for the default clock face. */
@@ -56,91 +46,10 @@ class DefaultClockSection
@Inject
constructor(
private val viewModel: KeyguardClockViewModel,
- private val clockInteractor: KeyguardClockInteractor,
private val aodBurnInViewModel: AodBurnInViewModel,
- private val lockscreenContentViewModel: LockscreenContentViewModel,
- private val smartSpaceSection: SmartSpaceSection,
) {
@Composable
- fun DefaultClockLayout(
- modifier: Modifier = Modifier,
- ) {
- val isLargeClockVisible by viewModel.isLargeClockVisible.collectAsState()
- val burnIn = rememberBurnIn(clockInteractor)
- val currentScene =
- if (isLargeClockVisible) {
- largeClockScene
- } else {
- smallClockScene
- }
-
- LaunchedEffect(isLargeClockVisible) {
- if (isLargeClockVisible) {
- burnIn.onSmallClockTopChanged(null)
- }
- }
-
- SceneTransitionLayout(
- modifier = modifier,
- currentScene = currentScene,
- onChangeScene = {},
- transitions = defaultClockTransitions,
- ) {
- scene(smallClockScene) {
- Column {
- SmallClock(
- burnInParams = burnIn.parameters,
- onTopChanged = burnIn.onSmallClockTopChanged,
- modifier = Modifier.element(smallClockElementKey).fillMaxWidth()
- )
- SmartSpaceContent()
- }
- }
-
- scene(largeClockScene) {
- Column {
- SmartSpaceContent()
- LargeClock(modifier = Modifier.element(largeClockElementKey).fillMaxWidth())
- }
- }
- }
- }
-
- @Composable
- private fun SceneScope.SmartSpaceContent(
- modifier: Modifier = Modifier,
- ) {
- val burnIn = rememberBurnIn(clockInteractor)
- val resources = LocalContext.current.resources
-
- MovableElement(key = smartspaceElementKey, modifier = modifier) {
- content {
- with(smartSpaceSection) {
- this@SmartSpaceContent.SmartSpace(
- burnInParams = burnIn.parameters,
- onTopChanged = burnIn.onSmartspaceTopChanged,
- modifier =
- Modifier.fillMaxWidth()
- .padding(
- top = {
- lockscreenContentViewModel.getSmartSpacePaddingTop(
- resources
- )
- },
- bottom = {
- resources.getDimensionPixelSize(
- R.dimen.keyguard_status_view_bottom_margin
- )
- }
- ),
- )
- }
- }
- }
- }
-
- @Composable
- private fun SceneScope.SmallClock(
+ fun SceneScope.SmallClock(
burnInParams: BurnInParameters,
onTopChanged: (top: Float?) -> Unit,
modifier: Modifier = Modifier,
@@ -152,58 +61,60 @@ constructor(
viewModel.clock = currentClock
val context = LocalContext.current
-
- AndroidView(
- factory = { context ->
- FrameLayout(context).apply {
- val newClockView = checkNotNull(currentClock).smallClock.view
- (newClockView.parent as? ViewGroup)?.removeView(newClockView)
- addView(newClockView)
- }
- },
- update = {
- val newClockView = checkNotNull(currentClock).smallClock.view
- it.removeAllViews()
- (newClockView.parent as? ViewGroup)?.removeView(newClockView)
- it.addView(newClockView)
- },
- modifier =
- modifier
- .padding(
- horizontal = dimensionResource(customizationR.dimen.clock_padding_start)
- )
- .padding(top = { viewModel.getSmallClockTopMargin(context) })
- .onTopPlacementChanged(onTopChanged)
- .burnInAware(
- viewModel = aodBurnInViewModel,
- params = burnInParams,
- ),
- )
+ MovableElement(key = smallClockElementKey, modifier = modifier) {
+ content {
+ AndroidView(
+ factory = { context ->
+ FrameLayout(context).apply {
+ addClockView(checkNotNull(currentClock).smallClock.view)
+ }
+ },
+ update = { it.addClockView(checkNotNull(currentClock).smallClock.view) },
+ modifier =
+ Modifier.padding(
+ horizontal =
+ dimensionResource(customizationR.dimen.clock_padding_start)
+ )
+ .padding(top = { viewModel.getSmallClockTopMargin(context) })
+ .onTopPlacementChanged(onTopChanged)
+ .burnInAware(
+ viewModel = aodBurnInViewModel,
+ params = burnInParams,
+ ),
+ )
+ }
+ }
}
@Composable
- private fun SceneScope.LargeClock(modifier: Modifier = Modifier) {
+ fun SceneScope.LargeClock(modifier: Modifier = Modifier) {
val currentClock by viewModel.currentClock.collectAsState()
viewModel.clock = currentClock
if (currentClock?.largeClock?.view == null) {
return
}
- AndroidView(
- factory = { context ->
- FrameLayout(context).apply {
- val newClockView = checkNotNull(currentClock).largeClock.view
- (newClockView.parent as? ViewGroup)?.removeView(newClockView)
- addView(newClockView)
- }
- },
- update = {
- val newClockView = checkNotNull(currentClock).largeClock.view
- it.removeAllViews()
- (newClockView.parent as? ViewGroup)?.removeView(newClockView)
- it.addView(newClockView)
- },
- modifier = modifier.fillMaxSize()
- )
+ MovableElement(key = largeClockElementKey, modifier = modifier) {
+ content {
+ AndroidView(
+ factory = { context ->
+ FrameLayout(context).apply {
+ addClockView(checkNotNull(currentClock).largeClock.view)
+ }
+ },
+ update = { it.addClockView(checkNotNull(currentClock).largeClock.view) },
+ modifier = Modifier.fillMaxSize()
+ )
+ }
+ }
+ }
+
+ private fun FrameLayout.addClockView(clockView: View) {
+ if (contains(clockView)) {
+ return
+ }
+ removeAllViews()
+ (clockView.parent as? ViewGroup)?.removeView(clockView)
+ addView(clockView)
}
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/NotificationSection.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/NotificationSection.kt
index c7d43fcdf5e6..5c9b271b342c 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/NotificationSection.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/NotificationSection.kt
@@ -31,7 +31,6 @@ import com.android.systemui.statusbar.notification.stack.AmbientState
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
import com.android.systemui.statusbar.notification.stack.NotificationStackSizeCalculator
-import com.android.systemui.statusbar.notification.stack.shared.flexiNotifsEnabled
import com.android.systemui.statusbar.notification.stack.ui.view.SharedNotificationContainer
import com.android.systemui.statusbar.notification.stack.ui.viewbinder.NotificationStackAppearanceViewBinder
import com.android.systemui.statusbar.notification.stack.ui.viewbinder.SharedNotificationContainerBinder
@@ -83,7 +82,7 @@ constructor(
mainImmediateDispatcher = mainImmediateDispatcher,
)
- if (sceneContainerFlags.flexiNotifsEnabled()) {
+ if (sceneContainerFlags.isEnabled()) {
NotificationStackAppearanceViewBinder.bind(
context,
sharedNotificationContainer,
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/SmartSpaceSection.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/SmartSpaceSection.kt
index d1cc53e093a5..fc8b3b9009ce 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/SmartSpaceSection.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/SmartSpaceSection.kt
@@ -30,16 +30,20 @@ import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import com.android.compose.animation.scene.SceneScope
+import com.android.compose.modifiers.padding
import com.android.systemui.keyguard.KeyguardUnlockAnimationController
+import com.android.systemui.keyguard.ui.composable.blueprint.ClockElementKeys
import com.android.systemui.keyguard.ui.composable.modifier.burnInAware
import com.android.systemui.keyguard.ui.composable.modifier.onTopPlacementChanged
import com.android.systemui.keyguard.ui.viewmodel.AodBurnInViewModel
import com.android.systemui.keyguard.ui.viewmodel.BurnInParameters
import com.android.systemui.keyguard.ui.viewmodel.KeyguardSmartspaceViewModel
+import com.android.systemui.keyguard.ui.viewmodel.LockscreenContentViewModel
import com.android.systemui.res.R
import com.android.systemui.statusbar.lockscreen.LockscreenSmartspaceController
import javax.inject.Inject
@@ -51,6 +55,7 @@ constructor(
private val keyguardUnlockAnimationController: KeyguardUnlockAnimationController,
private val keyguardSmartspaceViewModel: KeyguardSmartspaceViewModel,
private val aodBurnInViewModel: AodBurnInViewModel,
+ private val lockscreenContentViewModel: LockscreenContentViewModel,
) {
@Composable
fun SceneScope.SmartSpace(
@@ -58,57 +63,71 @@ constructor(
onTopChanged: (top: Float?) -> Unit,
modifier: Modifier = Modifier,
) {
- Column(
- modifier = modifier.onTopPlacementChanged(onTopChanged),
- ) {
- if (!keyguardSmartspaceViewModel.isSmartspaceEnabled) {
- return
- }
+ val resources = LocalContext.current.resources
+
+ MovableElement(key = ClockElementKeys.smartspaceElementKey, modifier = modifier) {
+ Column(
+ modifier =
+ modifier
+ .onTopPlacementChanged(onTopChanged)
+ .padding(
+ top = { lockscreenContentViewModel.getSmartSpacePaddingTop(resources) },
+ bottom = {
+ resources.getDimensionPixelSize(
+ R.dimen.keyguard_status_view_bottom_margin
+ )
+ }
+ )
+ ) {
+ if (!keyguardSmartspaceViewModel.isSmartspaceEnabled) {
+ return@Column
+ }
- val paddingBelowClockStart = dimensionResource(R.dimen.below_clock_padding_start)
- val paddingBelowClockEnd = dimensionResource(R.dimen.below_clock_padding_end)
+ val paddingBelowClockStart = dimensionResource(R.dimen.below_clock_padding_start)
+ val paddingBelowClockEnd = dimensionResource(R.dimen.below_clock_padding_end)
- if (keyguardSmartspaceViewModel.isDateWeatherDecoupled) {
- Row(
- verticalAlignment = Alignment.CenterVertically,
+ if (keyguardSmartspaceViewModel.isDateWeatherDecoupled) {
+ Row(
+ verticalAlignment = Alignment.CenterVertically,
+ modifier =
+ Modifier.fillMaxWidth()
+ // All items will be constrained to be as tall as the shortest item.
+ .height(IntrinsicSize.Min)
+ .padding(
+ start = paddingBelowClockStart,
+ ),
+ ) {
+ Date(
+ modifier =
+ Modifier.burnInAware(
+ viewModel = aodBurnInViewModel,
+ params = burnInParams,
+ ),
+ )
+ Spacer(modifier = Modifier.width(4.dp))
+ Weather(
+ modifier =
+ Modifier.burnInAware(
+ viewModel = aodBurnInViewModel,
+ params = burnInParams,
+ ),
+ )
+ }
+ }
+
+ Card(
modifier =
Modifier.fillMaxWidth()
- // All items will be constrained to be as tall as the shortest item.
- .height(IntrinsicSize.Min)
.padding(
start = paddingBelowClockStart,
- ),
- ) {
- Date(
- modifier =
- Modifier.burnInAware(
- viewModel = aodBurnInViewModel,
- params = burnInParams,
- ),
- )
- Spacer(modifier = Modifier.width(4.dp))
- Weather(
- modifier =
- Modifier.burnInAware(
+ end = paddingBelowClockEnd,
+ )
+ .burnInAware(
viewModel = aodBurnInViewModel,
params = burnInParams,
),
- )
- }
+ )
}
-
- Card(
- modifier =
- Modifier.fillMaxWidth()
- .padding(
- start = paddingBelowClockStart,
- end = paddingBelowClockEnd,
- )
- .burnInAware(
- viewModel = aodBurnInViewModel,
- params = burnInParams,
- ),
- )
}
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/TopAreaSection.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/TopAreaSection.kt
new file mode 100644
index 000000000000..763584182c97
--- /dev/null
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/TopAreaSection.kt
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2024 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.keyguard.ui.composable.section
+
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.fillMaxHeight
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.collectAsState
+import androidx.compose.runtime.getValue
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.res.dimensionResource
+import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.dp
+import com.android.compose.animation.scene.SceneTransitionLayout
+import com.android.systemui.Flags
+import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor
+import com.android.systemui.keyguard.ui.composable.blueprint.ClockScenes
+import com.android.systemui.keyguard.ui.composable.blueprint.ClockScenes.largeClockScene
+import com.android.systemui.keyguard.ui.composable.blueprint.ClockScenes.smallClockScene
+import com.android.systemui.keyguard.ui.composable.blueprint.ClockScenes.splitShadeLargeClockScene
+import com.android.systemui.keyguard.ui.composable.blueprint.ClockScenes.splitShadeSmallClockScene
+import com.android.systemui.keyguard.ui.composable.blueprint.ClockTransition
+import com.android.systemui.keyguard.ui.composable.blueprint.rememberBurnIn
+import com.android.systemui.keyguard.ui.viewmodel.KeyguardClockViewModel
+import com.android.systemui.res.R
+import com.android.systemui.shade.LargeScreenHeaderHelper
+import javax.inject.Inject
+
+class TopAreaSection
+@Inject
+constructor(
+ private val clockViewModel: KeyguardClockViewModel,
+ private val smartSpaceSection: SmartSpaceSection,
+ private val mediaCarouselSection: MediaCarouselSection,
+ private val notificationSection: NotificationSection,
+ private val clockSection: DefaultClockSection,
+ private val clockInteractor: KeyguardClockInteractor,
+) {
+ @Composable
+ fun DefaultClockLayoutWithNotifications(
+ modifier: Modifier = Modifier,
+ ) {
+ val isLargeClockVisible by clockViewModel.isLargeClockVisible.collectAsState()
+ val currentClockLayout by clockViewModel.currentClockLayout.collectAsState()
+ val currentScene =
+ when (currentClockLayout) {
+ KeyguardClockViewModel.ClockLayout.SPLIT_SHADE_LARGE_CLOCK ->
+ splitShadeLargeClockScene
+ KeyguardClockViewModel.ClockLayout.SPLIT_SHADE_SMALL_CLOCK ->
+ splitShadeSmallClockScene
+ KeyguardClockViewModel.ClockLayout.LARGE_CLOCK -> largeClockScene
+ KeyguardClockViewModel.ClockLayout.SMALL_CLOCK -> smallClockScene
+ }
+
+ val splitShadeTopMargin: Dp =
+ if (Flags.centralizedStatusBarHeightFix()) {
+ LargeScreenHeaderHelper.getLargeScreenHeaderHeight(LocalContext.current).dp
+ } else {
+ dimensionResource(id = R.dimen.large_screen_shade_header_height)
+ }
+ val burnIn = rememberBurnIn(clockInteractor)
+
+ LaunchedEffect(isLargeClockVisible) {
+ if (isLargeClockVisible) {
+ burnIn.onSmallClockTopChanged(null)
+ }
+ }
+
+ SceneTransitionLayout(
+ modifier = modifier.fillMaxSize(),
+ currentScene = currentScene,
+ onChangeScene = {},
+ transitions = ClockTransition.defaultClockTransitions,
+ ) {
+ scene(ClockScenes.splitShadeLargeClockScene) {
+ Row(
+ modifier = Modifier.fillMaxSize(),
+ ) {
+ Column(
+ modifier = Modifier.fillMaxHeight().weight(weight = 1f),
+ horizontalAlignment = Alignment.CenterHorizontally,
+ ) {
+ with(smartSpaceSection) {
+ SmartSpace(
+ burnInParams = burnIn.parameters,
+ onTopChanged = burnIn.onSmartspaceTopChanged,
+ )
+ }
+ with(clockSection) { LargeClock(modifier = Modifier.fillMaxWidth()) }
+ }
+ with(notificationSection) {
+ Notifications(
+ modifier =
+ Modifier.fillMaxHeight()
+ .weight(weight = 1f)
+ .padding(top = splitShadeTopMargin)
+ )
+ }
+ }
+ }
+
+ scene(ClockScenes.splitShadeSmallClockScene) {
+ Row(
+ modifier = Modifier.fillMaxSize(),
+ ) {
+ Column(
+ modifier = Modifier.fillMaxHeight().weight(weight = 1f),
+ horizontalAlignment = Alignment.CenterHorizontally,
+ ) {
+ with(clockSection) {
+ SmallClock(
+ burnInParams = burnIn.parameters,
+ onTopChanged = burnIn.onSmallClockTopChanged,
+ modifier = Modifier.fillMaxWidth()
+ )
+ }
+ with(smartSpaceSection) {
+ SmartSpace(
+ burnInParams = burnIn.parameters,
+ onTopChanged = burnIn.onSmartspaceTopChanged,
+ )
+ }
+ with(mediaCarouselSection) { MediaCarousel() }
+ }
+ with(notificationSection) {
+ Notifications(
+ modifier =
+ Modifier.fillMaxHeight()
+ .weight(weight = 1f)
+ .padding(top = splitShadeTopMargin)
+ )
+ }
+ }
+ }
+
+ scene(ClockScenes.smallClockScene) {
+ Column {
+ with(clockSection) {
+ SmallClock(
+ burnInParams = burnIn.parameters,
+ onTopChanged = burnIn.onSmallClockTopChanged,
+ modifier = Modifier.fillMaxWidth()
+ )
+ }
+ with(smartSpaceSection) {
+ SmartSpace(
+ burnInParams = burnIn.parameters,
+ onTopChanged = burnIn.onSmartspaceTopChanged,
+ )
+ }
+ with(mediaCarouselSection) { MediaCarousel() }
+ with(notificationSection) {
+ Notifications(
+ modifier =
+ androidx.compose.ui.Modifier.fillMaxWidth().weight(weight = 1f)
+ )
+ }
+ }
+ }
+
+ scene(ClockScenes.largeClockScene) {
+ Column {
+ with(smartSpaceSection) {
+ SmartSpace(
+ burnInParams = burnIn.parameters,
+ onTopChanged = burnIn.onSmartspaceTopChanged,
+ )
+ }
+ with(clockSection) { LargeClock(modifier = Modifier.fillMaxWidth()) }
+ }
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/Notifications.kt b/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/Notifications.kt
index 791d629179e6..d78097815b5e 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/Notifications.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/Notifications.kt
@@ -42,7 +42,6 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.snapshotFlow
-import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.drawBehind
@@ -355,18 +354,7 @@ private fun SceneScope.NotificationPlaceholder(
)
}
) {
- content {
- if (viewModel.isPlaceholderTextVisible) {
- Box(Modifier.fillMaxSize()) {
- Text(
- text = "Notifications",
- style = MaterialTheme.typography.titleLarge,
- color = MaterialTheme.colorScheme.onSurface,
- modifier = Modifier.align(Alignment.Center),
- )
- }
- }
- }
+ content {}
}
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSlider.kt b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSlider.kt
index 761292b63c35..24351706cb46 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSlider.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSlider.kt
@@ -16,11 +16,7 @@
package com.android.systemui.volume.panel.component.volume.ui.composable
-import androidx.compose.animation.AnimatedVisibility
-import androidx.compose.animation.animateContentSize
import androidx.compose.animation.core.animateFloatAsState
-import androidx.compose.animation.slideInVertically
-import androidx.compose.animation.slideOutVertically
import androidx.compose.foundation.basicMarquee
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.size
@@ -107,7 +103,7 @@ fun VolumeSlider(
},
colors = sliderColors,
label = {
- Column(modifier = Modifier.animateContentSize()) {
+ Column(modifier = Modifier) {
Text(
modifier = Modifier.basicMarquee(),
text = state.label,
@@ -116,12 +112,8 @@ fun VolumeSlider(
maxLines = 1,
)
- state.disabledMessage?.let { message ->
- AnimatedVisibility(
- !state.isEnabled,
- enter = slideInVertically { it },
- exit = slideOutVertically { it },
- ) {
+ if (!state.isEnabled) {
+ state.disabledMessage?.let { message ->
Text(
modifier = Modifier.basicMarquee(),
text = message,
diff --git a/packages/SystemUI/customization/src/com/android/systemui/util/Assert.java b/packages/SystemUI/customization/src/com/android/systemui/util/Assert.java
index e08936cbf75e..165e9728b9d7 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/util/Assert.java
+++ b/packages/SystemUI/customization/src/com/android/systemui/util/Assert.java
@@ -37,6 +37,39 @@ public class Assert {
sTestThread = thread;
}
+ /**
+ * Run {@code mainThreadWork} synchronously, ensuring that {@link #isMainThread()} will return
+ * {@code true} while it is running.
+ * <ol>
+ * <li>If {@link #isMainThread()} already passes, the work is simply run.
+ * <li>If the test thread is {@code null}, it will be set, the work run, and then cleared.
+ * <li>If the test thread is already set to a different thread, this call will fail the test to
+ * avoid causing spurious errors on other thread
+ * </ol>
+ */
+ @VisibleForTesting
+ public static void runWithCurrentThreadAsMainThread(Runnable mainThreadWork) {
+ if (sMainLooper.isCurrentThread()) {
+ // Already on the main thread; just run
+ mainThreadWork.run();
+ return;
+ }
+ Thread currentThread = Thread.currentThread();
+ Thread originalThread = sTestThread;
+ if (originalThread == currentThread) {
+ // test thread is already set; just run
+ mainThreadWork.run();
+ return;
+ }
+ if (originalThread != null) {
+ throw new AssertionError("Can't run with current thread (" + currentThread
+ + ") as main thread; test thread is already set to " + originalThread);
+ }
+ sTestThread = currentThread;
+ mainThreadWork.run();
+ sTestThread = null;
+ }
+
public static void isMainThread() {
if (!sMainLooper.isCurrentThread()
&& (sTestThread == null || sTestThread != Thread.currentThread())) {
diff --git a/packages/SystemUI/monet/Android.bp b/packages/SystemUI/monet/Android.bp
index 98f7aced7522..c54fdab4e77f 100644
--- a/packages/SystemUI/monet/Android.bp
+++ b/packages/SystemUI/monet/Android.bp
@@ -24,6 +24,7 @@ java_library {
static_libs: [
"androidx.annotation_annotation",
"androidx.core_core",
+ "libmonet",
],
srcs: [
"src/**/*.java",
diff --git a/packages/SystemUI/monet/src/com/android/systemui/monet/ColorScheme.kt b/packages/SystemUI/monet/src/com/android/systemui/monet/ColorScheme.kt
index 46a90f63431a..47a00f408460 100644
--- a/packages/SystemUI/monet/src/com/android/systemui/monet/ColorScheme.kt
+++ b/packages/SystemUI/monet/src/com/android/systemui/monet/ColorScheme.kt
@@ -20,11 +20,17 @@ import android.annotation.ColorInt
import android.app.WallpaperColors
import android.graphics.Color
import com.android.internal.graphics.ColorUtils
-import com.android.internal.graphics.cam.Cam
-import com.android.internal.graphics.cam.CamUtils
+import com.google.ux.material.libmonet.hct.Hct
+import com.google.ux.material.libmonet.scheme.DynamicScheme
+import com.google.ux.material.libmonet.scheme.SchemeContent
+import com.google.ux.material.libmonet.scheme.SchemeExpressive
+import com.google.ux.material.libmonet.scheme.SchemeFruitSalad
+import com.google.ux.material.libmonet.scheme.SchemeMonochrome
+import com.google.ux.material.libmonet.scheme.SchemeNeutral
+import com.google.ux.material.libmonet.scheme.SchemeRainbow
+import com.google.ux.material.libmonet.scheme.SchemeTonalSpot
+import com.google.ux.material.libmonet.scheme.SchemeVibrant
import kotlin.math.absoluteValue
-import kotlin.math.max
-import kotlin.math.min
import kotlin.math.roundToInt
const val TAG = "ColorScheme"
@@ -33,347 +39,65 @@ const val ACCENT1_CHROMA = 48.0f
const val GOOGLE_BLUE = 0xFF1b6ef3.toInt()
const val MIN_CHROMA = 5
-internal interface Hue {
- fun get(sourceColor: Cam): Double
-
- /**
- * Given a hue, and a mapping of hues to hue rotations, find which hues in the mapping the hue
- * fall betweens, and use the hue rotation of the lower hue.
- *
- * @param sourceHue hue of source color
- * @param hueAndRotations list of pairs, where the first item in a pair is a hue, and the second
- * item in the pair is a hue rotation that should be applied
- */
- fun getHueRotation(sourceHue: Float, hueAndRotations: List<Pair<Int, Int>>): Double {
- val sanitizedSourceHue = (if (sourceHue < 0 || sourceHue >= 360) 0 else sourceHue).toFloat()
- for (i in 0..hueAndRotations.size - 2) {
- val thisHue = hueAndRotations[i].first.toFloat()
- val nextHue = hueAndRotations[i + 1].first.toFloat()
- if (thisHue <= sanitizedSourceHue && sanitizedSourceHue < nextHue) {
- return ColorScheme.wrapDegreesDouble(
- sanitizedSourceHue.toDouble() + hueAndRotations[i].second
- )
- }
- }
-
- // If this statement executes, something is wrong, there should have been a rotation
- // found using the arrays.
- return sourceHue.toDouble()
- }
-}
-
-internal class HueSource : Hue {
- override fun get(sourceColor: Cam): Double {
- return sourceColor.hue.toDouble()
- }
-}
-
-internal class HueAdd(val amountDegrees: Double) : Hue {
- override fun get(sourceColor: Cam): Double {
- return ColorScheme.wrapDegreesDouble(sourceColor.hue.toDouble() + amountDegrees)
- }
-}
-
-internal class HueSubtract(val amountDegrees: Double) : Hue {
- override fun get(sourceColor: Cam): Double {
- return ColorScheme.wrapDegreesDouble(sourceColor.hue.toDouble() - amountDegrees)
- }
-}
-
-internal class HueVibrantSecondary() : Hue {
- val hueToRotations =
- listOf(
- Pair(0, 18),
- Pair(41, 15),
- Pair(61, 10),
- Pair(101, 12),
- Pair(131, 15),
- Pair(181, 18),
- Pair(251, 15),
- Pair(301, 12),
- Pair(360, 12)
- )
-
- override fun get(sourceColor: Cam): Double {
- return getHueRotation(sourceColor.hue, hueToRotations)
- }
-}
-
-internal class HueVibrantTertiary() : Hue {
- val hueToRotations =
- listOf(
- Pair(0, 35),
- Pair(41, 30),
- Pair(61, 20),
- Pair(101, 25),
- Pair(131, 30),
- Pair(181, 35),
- Pair(251, 30),
- Pair(301, 25),
- Pair(360, 25)
- )
-
- override fun get(sourceColor: Cam): Double {
- return getHueRotation(sourceColor.hue, hueToRotations)
- }
-}
-
-internal class HueExpressiveSecondary() : Hue {
- val hueToRotations =
- listOf(
- Pair(0, 45),
- Pair(21, 95),
- Pair(51, 45),
- Pair(121, 20),
- Pair(151, 45),
- Pair(191, 90),
- Pair(271, 45),
- Pair(321, 45),
- Pair(360, 45)
- )
-
- override fun get(sourceColor: Cam): Double {
- return getHueRotation(sourceColor.hue, hueToRotations)
- }
-}
-
-internal class HueExpressiveTertiary() : Hue {
- val hueToRotations =
- listOf(
- Pair(0, 120),
- Pair(21, 120),
- Pair(51, 20),
- Pair(121, 45),
- Pair(151, 20),
- Pair(191, 15),
- Pair(271, 20),
- Pair(321, 120),
- Pair(360, 120)
- )
-
- override fun get(sourceColor: Cam): Double {
- return getHueRotation(sourceColor.hue, hueToRotations)
- }
-}
-
-internal interface Chroma {
- fun get(sourceColor: Cam): Double
-
- companion object {
- val MAX_VALUE = 120.0
- val MIN_VALUE = 0.0
- }
-}
-
-internal class ChromaMaxOut : Chroma {
- override fun get(sourceColor: Cam): Double {
- // Intentionally high. Gamut mapping from impossible HCT to sRGB will ensure that
- // the maximum chroma is reached, even if lower than this constant.
- return Chroma.MAX_VALUE + 10.0
- }
-}
-
-internal class ChromaMultiple(val multiple: Double) : Chroma {
- override fun get(sourceColor: Cam): Double {
- return sourceColor.chroma * multiple
- }
-}
-
-internal class ChromaAdd(val amount: Double) : Chroma {
- override fun get(sourceColor: Cam): Double {
- return sourceColor.chroma + amount
- }
-}
-
-internal class ChromaBound(
- val baseChroma: Chroma,
- val minVal: Double,
- val maxVal: Double,
-) : Chroma {
- override fun get(sourceColor: Cam): Double {
- val result = baseChroma.get(sourceColor)
- return min(max(result, minVal), maxVal)
- }
-}
-
-internal class ChromaConstant(val chroma: Double) : Chroma {
- override fun get(sourceColor: Cam): Double {
- return chroma
- }
-}
-
-internal class ChromaSource : Chroma {
- override fun get(sourceColor: Cam): Double {
- return sourceColor.chroma.toDouble()
- }
-}
-
-internal class TonalSpec(val hue: Hue = HueSource(), val chroma: Chroma) {
- fun shades(sourceColor: Cam): List<Int> {
- val hue = hue.get(sourceColor)
- val chroma = chroma.get(sourceColor)
- return Shades.of(hue.toFloat(), chroma.toFloat()).toList()
- }
-
- fun getAtTone(sourceColor: Cam, tone: Float): Int {
- val hue = hue.get(sourceColor)
- val chroma = chroma.get(sourceColor)
- return ColorUtils.CAMToColor(hue.toFloat(), chroma.toFloat(), (1000f - tone) / 10f)
- }
-}
-
-internal class CoreSpec(
- val a1: TonalSpec,
- val a2: TonalSpec,
- val a3: TonalSpec,
- val n1: TonalSpec,
- val n2: TonalSpec
-)
-
-enum class Style(internal val coreSpec: CoreSpec) {
- SPRITZ(
- CoreSpec(
- a1 = TonalSpec(HueSource(), ChromaConstant(12.0)),
- a2 = TonalSpec(HueSource(), ChromaConstant(8.0)),
- a3 = TonalSpec(HueSource(), ChromaConstant(16.0)),
- n1 = TonalSpec(HueSource(), ChromaConstant(2.0)),
- n2 = TonalSpec(HueSource(), ChromaConstant(2.0))
- )
- ),
- TONAL_SPOT(
- CoreSpec(
- a1 = TonalSpec(HueSource(), ChromaConstant(36.0)),
- a2 = TonalSpec(HueSource(), ChromaConstant(16.0)),
- a3 = TonalSpec(HueAdd(60.0), ChromaConstant(24.0)),
- n1 = TonalSpec(HueSource(), ChromaConstant(6.0)),
- n2 = TonalSpec(HueSource(), ChromaConstant(8.0))
- )
- ),
- VIBRANT(
- CoreSpec(
- a1 = TonalSpec(HueSource(), ChromaMaxOut()),
- a2 = TonalSpec(HueVibrantSecondary(), ChromaConstant(24.0)),
- a3 = TonalSpec(HueVibrantTertiary(), ChromaConstant(32.0)),
- n1 = TonalSpec(HueSource(), ChromaConstant(10.0)),
- n2 = TonalSpec(HueSource(), ChromaConstant(12.0))
- )
- ),
- EXPRESSIVE(
- CoreSpec(
- a1 = TonalSpec(HueAdd(240.0), ChromaConstant(40.0)),
- a2 = TonalSpec(HueExpressiveSecondary(), ChromaConstant(24.0)),
- a3 = TonalSpec(HueExpressiveTertiary(), ChromaConstant(32.0)),
- n1 = TonalSpec(HueAdd(15.0), ChromaConstant(8.0)),
- n2 = TonalSpec(HueAdd(15.0), ChromaConstant(12.0))
- )
- ),
- RAINBOW(
- CoreSpec(
- a1 = TonalSpec(HueSource(), ChromaConstant(48.0)),
- a2 = TonalSpec(HueSource(), ChromaConstant(16.0)),
- a3 = TonalSpec(HueAdd(60.0), ChromaConstant(24.0)),
- n1 = TonalSpec(HueSource(), ChromaConstant(0.0)),
- n2 = TonalSpec(HueSource(), ChromaConstant(0.0))
- )
- ),
- FRUIT_SALAD(
- CoreSpec(
- a1 = TonalSpec(HueSubtract(50.0), ChromaConstant(48.0)),
- a2 = TonalSpec(HueSubtract(50.0), ChromaConstant(36.0)),
- a3 = TonalSpec(HueSource(), ChromaConstant(36.0)),
- n1 = TonalSpec(HueSource(), ChromaConstant(10.0)),
- n2 = TonalSpec(HueSource(), ChromaConstant(16.0))
- )
- ),
- CONTENT(
- CoreSpec(
- a1 = TonalSpec(HueSource(), ChromaSource()),
- a2 = TonalSpec(HueSource(), ChromaMultiple(0.33)),
- a3 = TonalSpec(HueSource(), ChromaMultiple(0.66)),
- n1 = TonalSpec(HueSource(), ChromaMultiple(0.0833)),
- n2 = TonalSpec(HueSource(), ChromaMultiple(0.1666))
- )
- ),
- MONOCHROMATIC(
- CoreSpec(
- a1 = TonalSpec(HueSource(), ChromaConstant(.0)),
- a2 = TonalSpec(HueSource(), ChromaConstant(.0)),
- a3 = TonalSpec(HueSource(), ChromaConstant(.0)),
- n1 = TonalSpec(HueSource(), ChromaConstant(.0)),
- n2 = TonalSpec(HueSource(), ChromaConstant(.0))
- )
- ),
- CLOCK(
- CoreSpec(
- a1 = TonalSpec(HueSource(), ChromaBound(ChromaSource(), 20.0, Chroma.MAX_VALUE)),
- a2 = TonalSpec(HueAdd(10.0), ChromaBound(ChromaMultiple(0.85), 17.0, 40.0)),
- a3 = TonalSpec(HueAdd(20.0), ChromaBound(ChromaAdd(20.0), 50.0, Chroma.MAX_VALUE)),
-
- // Not Used
- n1 = TonalSpec(HueSource(), ChromaConstant(0.0)),
- n2 = TonalSpec(HueSource(), ChromaConstant(0.0))
- )
- ),
- CLOCK_VIBRANT(
- CoreSpec(
- a1 = TonalSpec(HueSource(), ChromaBound(ChromaSource(), 70.0, Chroma.MAX_VALUE)),
- a2 = TonalSpec(HueAdd(20.0), ChromaBound(ChromaSource(), 70.0, Chroma.MAX_VALUE)),
- a3 = TonalSpec(HueAdd(60.0), ChromaBound(ChromaSource(), 70.0, Chroma.MAX_VALUE)),
-
- // Not Used
- n1 = TonalSpec(HueSource(), ChromaConstant(0.0)),
- n2 = TonalSpec(HueSource(), ChromaConstant(0.0))
- )
- )
+enum class Style{
+ SPRITZ,
+ TONAL_SPOT,
+ VIBRANT,
+ EXPRESSIVE,
+ RAINBOW,
+ FRUIT_SALAD,
+ CONTENT,
+ MONOCHROMATIC,
+ CLOCK,
+ CLOCK_VIBRANT
}
class TonalPalette
internal constructor(
- private val spec: TonalSpec,
- seedColor: Int,
+ private val materialTonalPalette: com.google.ux.material.libmonet.palettes.TonalPalette
) {
- val seedCam: Cam = Cam.fromInt(seedColor)
- val allShades: List<Int> = spec.shades(seedCam)
- val allShadesMapped: Map<Int, Int> = SHADE_KEYS.zip(allShades).toMap()
- val baseColor: Int
+ @Deprecated("Do not use. For color system only")
+ val allShades: List<Int>
+ val allShadesMapped: Map<Int, Int>
- init {
- val h = spec.hue.get(seedCam).toFloat()
- val c = spec.chroma.get(seedCam).toFloat()
- baseColor = ColorUtils.CAMToColor(h, c, CamUtils.lstarFromInt(seedColor))
+ init{
+ allShades = SHADE_KEYS.map {key -> getAtTone(key.toFloat()) }
+ allShadesMapped = SHADE_KEYS.zip(allShades).toMap()
}
// Dynamically computed tones across the full range from 0 to 1000
- fun getAtTone(tone: Float) = spec.getAtTone(seedCam, tone)
+ fun getAtTone(shade: Float): Int = materialTonalPalette.tone(((1000.0f - shade) / 10f).toInt())
// Predefined & precomputed tones
- val s10: Int
+ val s0: Int
get() = this.allShades[0]
- val s50: Int
+ val s10: Int
get() = this.allShades[1]
- val s100: Int
+ val s50: Int
get() = this.allShades[2]
- val s200: Int
+ val s100: Int
get() = this.allShades[3]
- val s300: Int
+ val s200: Int
get() = this.allShades[4]
- val s400: Int
+ val s300: Int
get() = this.allShades[5]
- val s500: Int
+ val s400: Int
get() = this.allShades[6]
- val s600: Int
+ val s500: Int
get() = this.allShades[7]
- val s700: Int
+ val s600: Int
get() = this.allShades[8]
- val s800: Int
+ val s700: Int
get() = this.allShades[9]
- val s900: Int
+ val s800: Int
get() = this.allShades[10]
- val s1000: Int
+ val s900: Int
get() = this.allShades[11]
+ val s1000: Int
+ get() = this.allShades[12]
companion object {
- val SHADE_KEYS = listOf(10, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000)
+ val SHADE_KEYS = listOf(0, 10, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000)
}
}
@@ -381,9 +105,20 @@ internal constructor(
"instead")
class ColorScheme(
@ColorInt val seed: Int,
- val darkTheme: Boolean,
- val style: Style = Style.TONAL_SPOT
+ val isDark: Boolean,
+ val style: Style,
+ val contrastLevel: Double
) {
+ var materialScheme: DynamicScheme
+
+ private val proposedSeedHct: Hct = Hct.fromInt(seed)
+ private val seedHct: Hct = Hct.fromInt(if (seed == Color.TRANSPARENT) {
+ GOOGLE_BLUE
+ } else if (style != Style.CONTENT && proposedSeedHct.chroma < 5) {
+ GOOGLE_BLUE
+ } else {
+ seed
+ })
val accent1: TonalPalette
val accent2: TonalPalette
@@ -395,62 +130,49 @@ class ColorScheme(
@JvmOverloads
constructor(
+ @ColorInt seed: Int,
+ darkTheme: Boolean,
+ style: Style
+ ) : this(seed, darkTheme, style, 0.5)
+
+ @JvmOverloads
+ constructor(
wallpaperColors: WallpaperColors,
darkTheme: Boolean,
style: Style = Style.TONAL_SPOT
) : this(getSeedColor(wallpaperColors, style != Style.CONTENT), darkTheme, style)
- val allHues: List<TonalPalette>
- get() {
- return listOf(accent1, accent2, accent3, neutral1, neutral2)
- }
-
- val allAccentColors: List<Int>
- get() {
- val allColors = mutableListOf<Int>()
- allColors.addAll(accent1.allShades)
- allColors.addAll(accent2.allShades)
- allColors.addAll(accent3.allShades)
- return allColors
- }
-
- val allNeutralColors: List<Int>
- get() {
- val allColors = mutableListOf<Int>()
- allColors.addAll(neutral1.allShades)
- allColors.addAll(neutral2.allShades)
- return allColors
- }
-
val backgroundColor
- get() = ColorUtils.setAlphaComponent(if (darkTheme) neutral1.s700 else neutral1.s10, 0xFF)
+ get() = ColorUtils.setAlphaComponent(if (isDark) neutral1.s700 else neutral1.s10, 0xFF)
val accentColor
- get() = ColorUtils.setAlphaComponent(if (darkTheme) accent1.s100 else accent1.s500, 0xFF)
+ get() = ColorUtils.setAlphaComponent(if (isDark) accent1.s100 else accent1.s500, 0xFF)
init {
- val proposedSeedCam = Cam.fromInt(seed)
- val seedArgb =
- if (seed == Color.TRANSPARENT) {
- GOOGLE_BLUE
- } else if (style != Style.CONTENT && proposedSeedCam.chroma < 5) {
- GOOGLE_BLUE
- } else {
- seed
- }
+ materialScheme = when (style) {
+ Style.SPRITZ -> SchemeNeutral(seedHct, isDark, contrastLevel)
+ Style.TONAL_SPOT -> SchemeTonalSpot(seedHct, isDark, contrastLevel)
+ Style.VIBRANT -> SchemeVibrant(seedHct, isDark, contrastLevel)
+ Style.EXPRESSIVE -> SchemeExpressive(seedHct, isDark, contrastLevel)
+ Style.RAINBOW -> SchemeRainbow(seedHct, isDark, contrastLevel)
+ Style.FRUIT_SALAD -> SchemeFruitSalad(seedHct, isDark, contrastLevel)
+ Style.CONTENT -> SchemeContent(seedHct, isDark, contrastLevel)
+ Style.MONOCHROMATIC -> SchemeMonochrome(seedHct, isDark, contrastLevel)
+
+ // SystemUI Schemes
+ Style.CLOCK -> SchemeClock(seedHct, isDark, contrastLevel)
+ Style.CLOCK_VIBRANT -> SchemeClockVibrant(seedHct, isDark, contrastLevel)
+ }
- accent1 = TonalPalette(style.coreSpec.a1, seedArgb)
- accent2 = TonalPalette(style.coreSpec.a2, seedArgb)
- accent3 = TonalPalette(style.coreSpec.a3, seedArgb)
- neutral1 = TonalPalette(style.coreSpec.n1, seedArgb)
- neutral2 = TonalPalette(style.coreSpec.n2, seedArgb)
+ accent1 = TonalPalette(materialScheme.primaryPalette)
+ accent2 = TonalPalette(materialScheme.secondaryPalette)
+ accent3 = TonalPalette(materialScheme.tertiaryPalette)
+ neutral1 = TonalPalette(materialScheme.neutralPalette)
+ neutral2 = TonalPalette(materialScheme.neutralVariantPalette)
}
- val shadeCount
- get() = this.accent1.allShades.size
-
val seedTone: Float
- get() = 1000f - CamUtils.lstarFromInt(seed) * 10f
+ get() = 1000f - proposedSeedHct.tone.toFloat() * 10f
override fun toString(): String {
return "ColorScheme {\n" +
@@ -507,7 +229,7 @@ class ColorScheme(
if (!filter) {
true
} else {
- Cam.fromInt(it).chroma >= MIN_CHROMA
+ Hct.fromInt(it).chroma >= MIN_CHROMA
}
}
.toList()
@@ -519,15 +241,15 @@ class ColorScheme(
val intToProportion =
wallpaperColors.allColors.mapValues { it.value.toDouble() / totalPopulation }
- val intToCam = wallpaperColors.allColors.mapValues { Cam.fromInt(it.key) }
+ val intToHct = wallpaperColors.allColors.mapValues { Hct.fromInt(it.key) }
// Get an array with 360 slots. A slot contains the percentage of colors with that hue.
- val hueProportions = huePopulations(intToCam, intToProportion, filter)
+ val hueProportions = huePopulations(intToHct, intToProportion, filter)
// Map each color to the percentage of the image with its hue.
val intToHueProportion =
wallpaperColors.allColors.mapValues {
- val cam = intToCam[it.key]!!
- val hue = cam.hue.roundToInt()
+ val hct = intToHct[it.key]!!
+ val hue = hct.hue.roundToInt()
var proportion = 0.0
for (i in hue - 15..hue + 15) {
proportion += hueProportions[wrapDegrees(i)]
@@ -537,18 +259,18 @@ class ColorScheme(
// Remove any inappropriate seed colors. For example, low chroma colors look grayscale
// raising their chroma will turn them to a much louder color that may not have been
// in the image.
- val filteredIntToCam =
- if (!filter) intToCam
+ val filteredIntToHct =
+ if (!filter) intToHct
else
- (intToCam.filter {
- val cam = it.value
+ (intToHct.filter {
+ val hct = it.value
val proportion = intToHueProportion[it.key]!!
- cam.chroma >= MIN_CHROMA &&
+ hct.chroma >= MIN_CHROMA &&
(totalPopulationMeaningless || proportion > 0.01)
})
// Sort the colors by score, from high to low.
val intToScoreIntermediate =
- filteredIntToCam.mapValues { score(it.value, intToHueProportion[it.key]!!) }
+ filteredIntToHct.mapValues { score(it.value, intToHueProportion[it.key]!!) }
val intToScore = intToScoreIntermediate.entries.toMutableList()
intToScore.sortByDescending { it.value }
@@ -564,8 +286,8 @@ class ColorScheme(
val int = entry.key
val existingSeedNearby =
seeds.find {
- val hueA = intToCam[int]!!.hue
- val hueB = intToCam[it]!!.hue
+ val hueA = intToHct[int]!!.hue
+ val hueB = intToHct[it]!!.hue
hueDiff(hueA, hueB) < i
} != null
if (existingSeedNearby) {
@@ -600,30 +322,16 @@ class ColorScheme(
}
}
- public fun wrapDegreesDouble(degrees: Double): Double {
- return when {
- degrees < 0 -> {
- (degrees % 360) + 360
- }
- degrees >= 360 -> {
- degrees % 360
- }
- else -> {
- degrees
- }
- }
- }
-
- private fun hueDiff(a: Float, b: Float): Float {
+ private fun hueDiff(a: Double, b: Double): Double {
return 180f - ((a - b).absoluteValue - 180f).absoluteValue
}
private fun stringForColor(color: Int): String {
val width = 4
- val hct = Cam.fromInt(color)
+ val hct = Hct.fromInt(color)
val h = "H${hct.hue.roundToInt().toString().padEnd(width)}"
val c = "C${hct.chroma.roundToInt().toString().padEnd(width)}"
- val t = "T${CamUtils.lstarFromInt(color).roundToInt().toString().padEnd(width)}"
+ val t = "T${hct.tone.roundToInt().toString().padEnd(width)}"
val hex = Integer.toHexString(color and 0xffffff).padStart(6, '0').uppercase()
return "$h$c$t = #$hex"
}
@@ -633,16 +341,16 @@ class ColorScheme(
colors.map { stringForColor(it) }.joinToString(separator = "\n") { it }
}
- private fun score(cam: Cam, proportion: Double): Double {
+ private fun score(hct: Hct, proportion: Double): Double {
val proportionScore = 0.7 * 100.0 * proportion
val chromaScore =
- if (cam.chroma < ACCENT1_CHROMA) 0.1 * (cam.chroma - ACCENT1_CHROMA)
- else 0.3 * (cam.chroma - ACCENT1_CHROMA)
+ if (hct.chroma < ACCENT1_CHROMA) 0.1 * (hct.chroma - ACCENT1_CHROMA)
+ else 0.3 * (hct.chroma - ACCENT1_CHROMA)
return chromaScore + proportionScore
}
private fun huePopulations(
- camByColor: Map<Int, Cam>,
+ hctByColor: Map<Int, Hct>,
populationByColor: Map<Int, Double>,
filter: Boolean = true
): List<Double> {
@@ -650,9 +358,9 @@ class ColorScheme(
for (entry in populationByColor.entries) {
val population = populationByColor[entry.key]!!
- val cam = camByColor[entry.key]!!
- val hue = cam.hue.roundToInt() % 360
- if (filter && cam.chroma <= MIN_CHROMA) {
+ val hct = hctByColor[entry.key]!!
+ val hue = hct.hue.roundToInt() % 360
+ if (filter && hct.chroma <= MIN_CHROMA) {
continue
}
huePopulation[hue] = huePopulation[hue] + population
diff --git a/packages/SystemUI/monet/src/com/android/systemui/monet/SchemeClock.java b/packages/SystemUI/monet/src/com/android/systemui/monet/SchemeClock.java
new file mode 100644
index 000000000000..4747cc5dbf9c
--- /dev/null
+++ b/packages/SystemUI/monet/src/com/android/systemui/monet/SchemeClock.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2024 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.monet;
+
+import static com.google.ux.material.libmonet.utils.MathUtils.clampDouble;
+
+import static java.lang.Double.max;
+
+import com.google.ux.material.libmonet.hct.Hct;
+import com.google.ux.material.libmonet.palettes.TonalPalette;
+import com.google.ux.material.libmonet.scheme.DynamicScheme;
+import com.google.ux.material.libmonet.scheme.Variant;
+
+public class SchemeClock extends DynamicScheme {
+ public SchemeClock(Hct sourceColorHct, boolean isDark, double contrastLevel) {
+ super(
+ sourceColorHct,
+ Variant.MONOCHROME,
+ isDark,
+ contrastLevel,
+ /*primary*/
+ TonalPalette.fromHueAndChroma(
+ /*hue*/ sourceColorHct.getHue(),
+ /*chroma*/ max(sourceColorHct.getChroma(), 20)
+ ),
+ /*secondary*/
+ TonalPalette.fromHueAndChroma(
+ /*hue*/ sourceColorHct.getHue() + 10.0,
+ /*chroma*/ clampDouble(17, 40, sourceColorHct.getChroma() * 0.85)
+ ),
+ /*tertiary*/
+ TonalPalette.fromHueAndChroma(
+ /*hue*/ sourceColorHct.getHue() + 20.0,
+ /*chroma*/ max(sourceColorHct.getChroma() + 20, 50)
+ ),
+
+ //not used
+ TonalPalette.fromHueAndChroma(sourceColorHct.getHue(), 0.0),
+ TonalPalette.fromHueAndChroma(sourceColorHct.getHue(), 0.0));
+ }
+}
diff --git a/packages/SystemUI/monet/src/com/android/systemui/monet/SchemeClockVibrant.java b/packages/SystemUI/monet/src/com/android/systemui/monet/SchemeClockVibrant.java
new file mode 100644
index 000000000000..fb5e972434af
--- /dev/null
+++ b/packages/SystemUI/monet/src/com/android/systemui/monet/SchemeClockVibrant.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2024 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.monet;
+
+import static java.lang.Double.max;
+
+import com.google.ux.material.libmonet.hct.Hct;
+import com.google.ux.material.libmonet.palettes.TonalPalette;
+import com.google.ux.material.libmonet.scheme.DynamicScheme;
+import com.google.ux.material.libmonet.scheme.Variant;
+
+public class SchemeClockVibrant extends DynamicScheme {
+ public SchemeClockVibrant(Hct sourceColorHct, boolean isDark, double contrastLevel) {
+ super(
+ sourceColorHct,
+ Variant.MONOCHROME,
+ isDark,
+ contrastLevel,
+ /*primary*/
+ TonalPalette.fromHueAndChroma(
+ /*hue*/ sourceColorHct.getHue(),
+ /*chroma*/ max(sourceColorHct.getChroma(), 70)
+ ),
+ /*secondary*/
+ TonalPalette.fromHueAndChroma(
+ /*hue*/ sourceColorHct.getHue() + 20.0,
+ /*chroma*/ max(sourceColorHct.getChroma(), 70)
+ ),
+ /*tertiary*/
+ TonalPalette.fromHueAndChroma(
+ /*hue*/ sourceColorHct.getHue() + 60.0,
+ /*chroma*/ max(sourceColorHct.getChroma(), 70)
+ ),
+
+ //not used
+ TonalPalette.fromHueAndChroma(sourceColorHct.getHue(), 0.0),
+ TonalPalette.fromHueAndChroma(sourceColorHct.getHue(), 0.0));
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/ui/viewmodel/CommunalTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/ui/viewmodel/CommunalTransitionViewModelTest.kt
new file mode 100644
index 000000000000..02d927a0e5ab
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/ui/viewmodel/CommunalTransitionViewModelTest.kt
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2024 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.communal.ui.viewmodel
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
+import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class CommunalTransitionViewModelTest : SysuiTestCase() {
+ private val kosmos = testKosmos()
+ private val testScope = kosmos.testScope
+
+ val keyguardTransitionRepository = kosmos.fakeKeyguardTransitionRepository
+
+ private lateinit var underTest: CommunalTransitionViewModel
+
+ @Before
+ fun setup() {
+ underTest = kosmos.communalTransitionViewModel
+ }
+
+ @Test
+ fun testIsUmoOnCommunalDuringTransitionBetweenLockscreenAndGlanceableHub() =
+ testScope.runTest {
+ val isUmoOnCommunal by collectLastValue(underTest.isUmoOnCommunal)
+ assertThat(isUmoOnCommunal).isNull()
+
+ keyguardTransitionRepository.sendTransitionSteps(
+ from = KeyguardState.LOCKSCREEN,
+ to = KeyguardState.GLANCEABLE_HUB,
+ testScope
+ )
+ assertThat(isUmoOnCommunal).isTrue()
+
+ keyguardTransitionRepository.sendTransitionSteps(
+ from = KeyguardState.GLANCEABLE_HUB,
+ to = KeyguardState.LOCKSCREEN,
+ testScope
+ )
+ assertThat(isUmoOnCommunal).isFalse()
+ }
+
+ @Test
+ fun testIsUmoOnCommunalDuringTransitionBetweenDreamingAndGlanceableHub() =
+ testScope.runTest {
+ val isUmoOnCommunal by collectLastValue(underTest.isUmoOnCommunal)
+ assertThat(isUmoOnCommunal).isNull()
+
+ keyguardTransitionRepository.sendTransitionSteps(
+ from = KeyguardState.DREAMING,
+ to = KeyguardState.GLANCEABLE_HUB,
+ testScope
+ )
+ assertThat(isUmoOnCommunal).isTrue()
+
+ keyguardTransitionRepository.sendTransitionSteps(
+ from = KeyguardState.GLANCEABLE_HUB,
+ to = KeyguardState.DREAMING,
+ testScope
+ )
+ assertThat(isUmoOnCommunal).isFalse()
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToLockscreenTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToLockscreenTransitionViewModelTest.kt
index af9678022e07..1aa1ec4c22a2 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToLockscreenTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToLockscreenTransitionViewModelTest.kt
@@ -50,7 +50,7 @@ class GlanceableHubToLockscreenTransitionViewModelTest : SysuiTestCase() {
fun lockscreenFadeIn() =
testScope.runTest {
val values by collectValues(underTest.keyguardAlpha)
- assertThat(values).containsExactly(0f)
+ assertThat(values).isEmpty()
keyguardTransitionRepository.sendTransitionSteps(
listOf(
@@ -70,7 +70,7 @@ class GlanceableHubToLockscreenTransitionViewModelTest : SysuiTestCase() {
testScope,
)
- assertThat(values).hasSize(5)
+ assertThat(values).hasSize(4)
values.forEach { assertThat(it).isIn(Range.closed(0f, 1f)) }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt
index 6e15c51e8782..fc604aa5a1d2 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt
@@ -348,6 +348,48 @@ class KeyguardRootViewModelTest : SysuiTestCase() {
}
@Test
+ fun alpha_shadeClosedOverLockscreen_isOne() =
+ testScope.runTest {
+ val alpha by collectLastValue(underTest.alpha(viewState))
+
+ // Transition to the lockscreen.
+ keyguardTransitionRepository.sendTransitionSteps(
+ from = KeyguardState.AOD,
+ to = KeyguardState.LOCKSCREEN,
+ testScope,
+ )
+
+ // Open the shade.
+ shadeRepository.setQsExpansion(1f)
+ assertThat(alpha).isEqualTo(0f)
+
+ // Close the shade, alpha returns to 1.
+ shadeRepository.setQsExpansion(0f)
+ assertThat(alpha).isEqualTo(1f)
+ }
+
+ @Test
+ fun alpha_shadeClosedOverDream_isZero() =
+ testScope.runTest {
+ val alpha by collectLastValue(underTest.alpha(viewState))
+
+ // Transition to dreaming.
+ keyguardTransitionRepository.sendTransitionSteps(
+ from = KeyguardState.LOCKSCREEN,
+ to = KeyguardState.DREAMING,
+ testScope,
+ )
+
+ // Open the shade.
+ shadeRepository.setQsExpansion(1f)
+ assertThat(alpha).isEqualTo(0f)
+
+ // Close the shade, alpha is still 0 since we're not on the lockscreen.
+ shadeRepository.setQsExpansion(0f)
+ assertThat(alpha).isEqualTo(0f)
+ }
+
+ @Test
fun alpha_idleOnOccluded_isZero() =
testScope.runTest {
val alpha by collectLastValue(underTest.alpha(viewState))
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModelTest.kt
index ad1cef1c1e92..751ac1d8b458 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModelTest.kt
@@ -26,7 +26,8 @@ import com.android.systemui.flags.fakeFeatureFlagsClassic
import com.android.systemui.keyguard.data.repository.fakeKeyguardClockRepository
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.testScope
-import com.android.systemui.res.R
+import com.android.systemui.shade.data.repository.shadeRepository
+import com.android.systemui.shade.shared.model.ShadeMode
import com.android.systemui.testKosmos
import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat
@@ -47,7 +48,7 @@ class LockscreenContentViewModelTest : SysuiTestCase() {
fun setup() {
with(kosmos) {
fakeFeatureFlagsClassic.set(Flags.LOCK_SCREEN_LONG_PRESS_ENABLED, true)
- overrideResource(R.bool.config_use_split_notification_shade, false)
+ shadeRepository.setShadeMode(ShadeMode.Single)
underTest = lockscreenContentViewModel
}
}
@@ -92,10 +93,10 @@ class LockscreenContentViewModelTest : SysuiTestCase() {
fun areNotificationsVisible_splitShadeTrue_true() =
with(kosmos) {
testScope.runTest {
- overrideResource(R.bool.config_use_split_notification_shade, true)
+ shadeRepository.setShadeMode(ShadeMode.Split)
kosmos.fakeKeyguardClockRepository.setClockSize(KeyguardClockSwitch.LARGE)
- assertThat(underTest.areNotificationsVisible(context.resources)).isTrue()
+ assertThat(underTest.areNotificationsVisible).isTrue()
}
}
@Test
@@ -103,7 +104,7 @@ class LockscreenContentViewModelTest : SysuiTestCase() {
with(kosmos) {
testScope.runTest {
kosmos.fakeKeyguardClockRepository.setClockSize(KeyguardClockSwitch.SMALL)
- assertThat(underTest.areNotificationsVisible(context.resources)).isTrue()
+ assertThat(underTest.areNotificationsVisible).isTrue()
}
}
@@ -112,7 +113,34 @@ class LockscreenContentViewModelTest : SysuiTestCase() {
with(kosmos) {
testScope.runTest {
kosmos.fakeKeyguardClockRepository.setClockSize(KeyguardClockSwitch.LARGE)
- assertThat(underTest.areNotificationsVisible(context.resources)).isFalse()
+ assertThat(underTest.areNotificationsVisible).isFalse()
+ }
+ }
+
+ @Test
+ fun shouldUseSplitNotificationShade_withConfigTrue_true() =
+ with(kosmos) {
+ testScope.runTest {
+ shadeRepository.setShadeMode(ShadeMode.Split)
+ assertThat(underTest.shouldUseSplitNotificationShade).isTrue()
+ }
+ }
+
+ @Test
+ fun shouldUseSplitNotificationShade_withConfigFalse_false() =
+ with(kosmos) {
+ testScope.runTest {
+ shadeRepository.setShadeMode(ShadeMode.Single)
+ assertThat(underTest.shouldUseSplitNotificationShade).isFalse()
+ }
+ }
+
+ @Test
+ fun sceneKey() =
+ with(kosmos) {
+ testScope.runTest {
+ shadeRepository.setShadeMode(ShadeMode.Single)
+ assertThat(underTest.shouldUseSplitNotificationShade).isFalse()
}
}
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGlanceableHubTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGlanceableHubTransitionViewModelTest.kt
index 241d0b818193..68a7b7e3d384 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGlanceableHubTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGlanceableHubTransitionViewModelTest.kt
@@ -50,7 +50,7 @@ class LockscreenToGlanceableHubTransitionViewModelTest : SysuiTestCase() {
fun lockscreenFadeOut() =
testScope.runTest {
val values by collectValues(underTest.keyguardAlpha)
- assertThat(values).containsExactly(1f)
+ assertThat(values).isEmpty()
keyguardTransitionRepository.sendTransitionSteps(
listOf(
@@ -71,7 +71,7 @@ class LockscreenToGlanceableHubTransitionViewModelTest : SysuiTestCase() {
testScope,
)
- assertThat(values).hasSize(4)
+ assertThat(values).hasSize(3)
values.forEach { assertThat(it).isIn(Range.closed(0f, 1f)) }
}
diff --git a/packages/SystemUI/res/layout/super_notification_shade.xml b/packages/SystemUI/res/layout/super_notification_shade.xml
index b792acc8b097..c9985354b11e 100644
--- a/packages/SystemUI/res/layout/super_notification_shade.xml
+++ b/packages/SystemUI/res/layout/super_notification_shade.xml
@@ -69,7 +69,10 @@
<com.android.systemui.statusbar.notification.stack.ui.view.SharedNotificationContainer
android:id="@+id/shared_notification_container"
android:layout_width="match_parent"
- android:layout_height="match_parent" />
+ android:layout_height="match_parent"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ />
<include layout="@layout/brightness_mirror_container" />
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index cac32892d9fd..2285550d94c7 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -1968,4 +1968,7 @@
<!-- Microns/ums (1000 um = 1mm) per pixel for the given device. If unspecified, UI that
relies on this value will not be sized correctly. -->
<item name="pixel_pitch" format="float" type="dimen">-1</item>
+
+ <!-- SliceView grid gutter for ANC Slice -->
+ <dimen name="abc_slice_grid_gutter">0dp</dimen>
</resources>
diff --git a/packages/SystemUI/res/xml/home_controls_dream_metadata.xml b/packages/SystemUI/res/xml/home_controls_dream_metadata.xml
index eb7c79e24b04..69bd9a477f05 100644
--- a/packages/SystemUI/res/xml/home_controls_dream_metadata.xml
+++ b/packages/SystemUI/res/xml/home_controls_dream_metadata.xml
@@ -16,4 +16,5 @@
<dream xmlns:android="http://schemas.android.com/apk/res/android"
android:showClockAndComplications="false"
android:previewImage="@drawable/homecontrols_sq"
+ android:dreamCategory="home_panel"
/> \ No newline at end of file
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java
index 69aa90996946..c08b0837da8e 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java
@@ -77,7 +77,7 @@ public class QuickStepContract {
// settings is expanded.
public static final int SYSUI_STATE_QUICK_SETTINGS_EXPANDED = 1 << 11;
// Winscope tracing is enabled
- public static final int SYSUI_STATE_DISABLE_GESTURE_SPLIT_INVOCATION = 1 << 12;
+ public static final int SYSUI_STATE_TRACING_ENABLED = 1 << 12;
// The Assistant gesture should be constrained. It is up to the launcher implementation to
// decide how to constrain it
public static final int SYSUI_STATE_ASSIST_GESTURE_CONSTRAINED = 1 << 13;
@@ -148,7 +148,7 @@ public class QuickStepContract {
SYSUI_STATE_OVERVIEW_DISABLED,
SYSUI_STATE_HOME_DISABLED,
SYSUI_STATE_SEARCH_DISABLED,
- SYSUI_STATE_DISABLE_GESTURE_SPLIT_INVOCATION,
+ SYSUI_STATE_TRACING_ENABLED,
SYSUI_STATE_ASSIST_GESTURE_CONSTRAINED,
SYSUI_STATE_BUBBLES_EXPANDED,
SYSUI_STATE_DIALOG_SHOWING,
@@ -211,8 +211,8 @@ public class QuickStepContract {
if ((flags & SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE) != 0) {
str.add("a11y_long_click");
}
- if ((flags & SYSUI_STATE_DISABLE_GESTURE_SPLIT_INVOCATION) != 0) {
- str.add("disable_gesture_split_invocation");
+ if ((flags & SYSUI_STATE_TRACING_ENABLED) != 0) {
+ str.add("tracing");
}
if ((flags & SYSUI_STATE_ASSIST_GESTURE_CONSTRAINED) != 0) {
str.add("asst_gesture_constrain");
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index 05eeac6fc199..70465bc3d0b7 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -343,6 +343,8 @@ public class KeyguardSecurityContainer extends ConstraintLayout {
setPadding(getPaddingLeft(), getPaddingTop() + getResources().getDimensionPixelSize(
R.dimen.keyguard_security_container_padding_top), getPaddingRight(),
getPaddingBottom());
+ setBackgroundColor(Utils.getColorAttrDefaultColor(getContext(),
+ com.android.internal.R.attr.materialColorSurface));
}
void onResume(SecurityMode securityMode, boolean faceAuthEnabled) {
@@ -800,6 +802,8 @@ public class KeyguardSecurityContainer extends ConstraintLayout {
void reloadColors() {
mViewMode.reloadColors();
+ setBackgroundColor(Utils.getColorAttrDefaultColor(getContext(),
+ com.android.internal.R.attr.materialColorSurface));
}
/** Handles density or font scale changes. */
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
index 15ef61ed5934..ea8fe59d3c89 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
@@ -82,6 +82,7 @@ public class SystemUIApplication extends Application implements
public SystemUIApplication() {
super();
+ Trace.registerWithPerfetto();
Log.v(TAG, "SystemUIApplication constructed.");
// SysUI may be building without protolog preprocessing in some cases
ProtoLog.REQUIRE_PROTOLOGTOOL = false;
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationAnimationController.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationAnimationController.java
index 9dd1454d2528..0f4d63c7ebcc 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationAnimationController.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationAnimationController.java
@@ -302,6 +302,14 @@ class WindowMagnificationAnimationController implements ValueAnimator.AnimatorUp
if (mEndAnimationCanceled || mController == null) {
return;
}
+
+ // If the animation is playing backwards, mStartSpec will be the final spec we would
+ // like to reach.
+ AnimationSpec spec = isReverse ? mStartSpec : mEndSpec;
+ mController.enableWindowMagnificationInternal(
+ spec.mScale, spec.mCenterX, spec.mCenterY,
+ mMagnificationFrameOffsetRatioX, mMagnificationFrameOffsetRatioY);
+
if (mState == STATE_DISABLING) {
mController.deleteWindowMagnification();
}
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuView.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuView.java
index 0c9712de3264..1f5a0bf328af 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuView.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuView.java
@@ -185,11 +185,7 @@ class MenuView extends FrameLayout implements
final GradientDrawable gradientDrawable = getContainerViewGradient();
gradientDrawable.setStroke(mMenuViewAppearance.getMenuStrokeWidth(),
mMenuViewAppearance.getMenuStrokeColor());
- if (Flags.floatingMenuRadiiAnimation()) {
- mMenuAnimationController.startRadiiAnimation(mMenuViewAppearance.getMenuRadii());
- } else {
- gradientDrawable.setCornerRadii(mMenuViewAppearance.getMenuRadii());
- }
+ mMenuAnimationController.startRadiiAnimation(mMenuViewAppearance.getMenuRadii());
}
void setRadii(float[] radii) {
@@ -402,13 +398,8 @@ class MenuView extends FrameLayout implements
getContainerViewInsetLayer().setLayerInset(INDEX_MENU_ITEM, insets[0], insets[1], insets[2],
insets[3]);
- if (Flags.floatingMenuRadiiAnimation()) {
- mMenuAnimationController.startRadiiAnimation(
- mMenuViewAppearance.getMenuMovingStateRadii());
- } else {
- final GradientDrawable gradientDrawable = getContainerViewGradient();
- gradientDrawable.setCornerRadii(mMenuViewAppearance.getMenuMovingStateRadii());
- }
+ mMenuAnimationController.startRadiiAnimation(
+ mMenuViewAppearance.getMenuMovingStateRadii());
}
void onBoundsInParentChanged(int newLeft, int newTop) {
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/RadiiAnimator.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/RadiiAnimator.java
index 4aa0d89cddb5..8de12f3e1f34 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/RadiiAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/RadiiAnimator.java
@@ -73,7 +73,7 @@ class RadiiAnimator {
@Override
public void onAnimationRepeat(@NonNull Animator animation) {}
});
- mAnimationDriver.setInterpolator(new android.view.animation.BounceInterpolator());
+ mAnimationDriver.setInterpolator(new android.view.animation.DecelerateInterpolator());
}
void startAnimation(float[] endValues) {
diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalTransitionViewModel.kt
new file mode 100644
index 000000000000..96e4b341cb6d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalTransitionViewModel.kt
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2024 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.communal.ui.viewmodel
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyguard.ui.viewmodel.DreamingToGlanceableHubTransitionViewModel
+import com.android.systemui.keyguard.ui.viewmodel.GlanceableHubToDreamingTransitionViewModel
+import com.android.systemui.keyguard.ui.viewmodel.GlanceableHubToLockscreenTransitionViewModel
+import com.android.systemui.keyguard.ui.viewmodel.LockscreenToGlanceableHubTransitionViewModel
+import javax.inject.Inject
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.merge
+
+/** View model for transitions related to the communal hub. */
+@OptIn(ExperimentalCoroutinesApi::class)
+@SysUISingleton
+class CommunalTransitionViewModel
+@Inject
+constructor(
+ glanceableHubToLockscreenTransitionViewModel: GlanceableHubToLockscreenTransitionViewModel,
+ lockscreenToGlanceableHubTransitionViewModel: LockscreenToGlanceableHubTransitionViewModel,
+ dreamToGlanceableHubTransitionViewModel: DreamingToGlanceableHubTransitionViewModel,
+ glanceableHubToDreamTransitionViewModel: GlanceableHubToDreamingTransitionViewModel,
+) {
+ /**
+ * Whether UMO location should be on communal. This flow is responsive to transitions so that a
+ * new value is emitted at the right step of a transition to/from communal hub that the location
+ * of UMO should be updated.
+ */
+ val isUmoOnCommunal: Flow<Boolean> =
+ merge(
+ lockscreenToGlanceableHubTransitionViewModel.showUmo,
+ glanceableHubToLockscreenTransitionViewModel.showUmo,
+ dreamToGlanceableHubTransitionViewModel.showUmo,
+ glanceableHubToDreamTransitionViewModel.showUmo,
+ )
+ .distinctUntilChanged()
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractor.kt
index 88ddfd4f4347..47f8046a92ad 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractor.kt
@@ -33,7 +33,11 @@ import kotlin.time.Duration.Companion.milliseconds
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.delay
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.launch
@SysUISingleton
@@ -66,6 +70,25 @@ constructor(
listenForTransitionToCamera(scope, keyguardInteractor)
}
+ val surfaceBehindVisibility: Flow<Boolean?> =
+ combine(
+ transitionInteractor.startedKeyguardTransitionStep,
+ transitionInteractor.transitionStepsFromState(KeyguardState.ALTERNATE_BOUNCER)
+ ) { startedStep, fromBouncerStep ->
+ if (startedStep.to != KeyguardState.GONE) {
+ return@combine null
+ }
+
+ // The alt bouncer is pretty fast to hide, so start the surface behind animation
+ // around 30%.
+ fromBouncerStep.value > 0.3f
+ }
+ .onStart {
+ // Default to null ("don't care, use a reasonable default").
+ emit(null)
+ }
+ .distinctUntilChanged()
+
private fun listenForAlternateBouncerToLockscreenHubAodOrDozing() {
scope.launch {
keyguardInteractor.alternateBouncerShowing
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractor.kt
index 391dccc7f444..c7fafba3aa19 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractor.kt
@@ -26,7 +26,6 @@ import com.android.systemui.flags.FeatureFlags
import com.android.systemui.keyguard.KeyguardWmStateRefactor
import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
import com.android.systemui.keyguard.shared.model.KeyguardState
-import com.android.systemui.keyguard.shared.model.KeyguardSurfaceBehindModel
import com.android.systemui.keyguard.shared.model.TransitionModeOnCanceled
import com.android.systemui.power.domain.interactor.PowerInteractor
import com.android.systemui.user.domain.interactor.SelectedUserInteractor
@@ -96,36 +95,6 @@ constructor(
}
.distinctUntilChanged()
- val surfaceBehindModel: Flow<KeyguardSurfaceBehindModel?> =
- combine(
- transitionInteractor.startedKeyguardTransitionStep,
- transitionInteractor.transitionStepsFromState(KeyguardState.PRIMARY_BOUNCER)
- ) { startedStep, fromBouncerStep ->
- if (startedStep.to != KeyguardState.GONE) {
- // BOUNCER to anything but GONE does not require any special surface
- // visibility handling.
- return@combine null
- }
-
- if (fromBouncerStep.value > 0.5f) {
- KeyguardSurfaceBehindModel(
- animateFromAlpha = 0f,
- alpha = 1f,
- animateFromTranslationY = 500f,
- translationY = 0f,
- )
- } else {
- KeyguardSurfaceBehindModel(
- alpha = 0f,
- )
- }
- }
- .onStart {
- // Default to null ("don't care, use a reasonable default").
- emit(null)
- }
- .distinctUntilChanged()
-
fun dismissPrimaryBouncer() {
scope.launch { startTransitionTo(KeyguardState.GONE) }
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardBlueprintInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardBlueprintInteractor.kt
index c877192cd804..d39bd3d5eb12 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardBlueprintInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardBlueprintInteractor.kt
@@ -92,7 +92,7 @@ constructor(
when {
useWeatherClockLayout && useSplitShade -> SPLIT_SHADE_WEATHER_CLOCK_BLUEPRINT_ID
useWeatherClockLayout -> WEATHER_CLOCK_BLUEPRINT_ID
- useSplitShade -> SplitShadeKeyguardBlueprint.ID
+ useSplitShade && !ComposeLockscreen.isEnabled -> SplitShadeKeyguardBlueprint.ID
else -> DefaultKeyguardBlueprint.DEFAULT
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractor.kt
index c496a6ee437f..80e94a27bec5 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractor.kt
@@ -95,7 +95,17 @@ constructor(
}
.distinctUntilChanged()
- val isAnimatingSurface = repository.isAnimatingSurface
+ /**
+ * Whether we're animating the surface, or a notification launch animation is running (which
+ * means we're going to animate the surface, even if animators aren't yet running).
+ */
+ val isAnimatingSurface =
+ combine(
+ repository.isAnimatingSurface,
+ notificationLaunchInteractor.isLaunchAnimationRunning
+ ) { animatingSurface, animatingLaunch ->
+ animatingSurface || animatingLaunch
+ }
fun setAnimatingSurface(animating: Boolean) {
repository.setAnimatingSurface(animating)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt
index cff74b333530..8d02e0efd72d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt
@@ -40,6 +40,7 @@ constructor(
surfaceBehindInteractor: KeyguardSurfaceBehindInteractor,
fromLockscreenInteractor: FromLockscreenTransitionInteractor,
fromBouncerInteractor: FromPrimaryBouncerTransitionInteractor,
+ fromAlternateBouncerInteractor: FromAlternateBouncerTransitionInteractor,
notificationLaunchAnimationInteractor: NotificationLaunchAnimationInteractor,
) {
private val defaultSurfaceBehindVisibility =
@@ -65,6 +66,9 @@ constructor(
KeyguardState.PRIMARY_BOUNCER -> {
fromBouncerInteractor.surfaceBehindVisibility
}
+ KeyguardState.ALTERNATE_BOUNCER -> {
+ fromAlternateBouncerInteractor.surfaceBehindVisibility
+ }
else -> flowOf(null)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/NotificationStackScrollLayoutSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/NotificationStackScrollLayoutSection.kt
index 02c889dd771d..5dea7cbb801d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/NotificationStackScrollLayoutSection.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/NotificationStackScrollLayoutSection.kt
@@ -34,7 +34,6 @@ import com.android.systemui.shade.NotificationPanelView
import com.android.systemui.statusbar.notification.stack.AmbientState
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
import com.android.systemui.statusbar.notification.stack.NotificationStackSizeCalculator
-import com.android.systemui.statusbar.notification.stack.shared.flexiNotifsEnabled
import com.android.systemui.statusbar.notification.stack.ui.view.SharedNotificationContainer
import com.android.systemui.statusbar.notification.stack.ui.viewbinder.NotificationStackAppearanceViewBinder
import com.android.systemui.statusbar.notification.stack.ui.viewbinder.SharedNotificationContainerBinder
@@ -115,7 +114,7 @@ constructor(
)
)
- if (sceneContainerFlags.flexiNotifsEnabled()) {
+ if (sceneContainerFlags.isEnabled()) {
disposableHandles.add(
NotificationStackAppearanceViewBinder.bind(
context,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToGlanceableHubTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToGlanceableHubTransitionViewModel.kt
index 789e4fbd46c2..d948e47e6267 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToGlanceableHubTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToGlanceableHubTransitionViewModel.kt
@@ -29,6 +29,7 @@ import kotlin.time.Duration.Companion.seconds
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.map
@OptIn(ExperimentalCoroutinesApi::class)
@SysUISingleton
@@ -71,6 +72,17 @@ constructor(
name = "DREAMING->GLANCEABLE_HUB: dreamOverlayAlpha",
)
+ // Show UMO once the transition starts.
+ val showUmo: Flow<Boolean> =
+ transitionAnimation
+ .sharedFlow(
+ duration = TO_GLANCEABLE_HUB_DURATION,
+ onStep = { it },
+ onCancel = { 0f },
+ onFinish = { 1f },
+ )
+ .map { step -> step != 0f }
+
private companion object {
val TO_GLANCEABLE_HUB_DURATION = 1.seconds
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToDreamingTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToDreamingTransitionViewModel.kt
index 478c4faa1be3..838c22b0da33 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToDreamingTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToDreamingTransitionViewModel.kt
@@ -28,6 +28,7 @@ import kotlin.time.Duration.Companion.seconds
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.map
@OptIn(ExperimentalCoroutinesApi::class)
@SysUISingleton
@@ -66,6 +67,17 @@ constructor(
)
}
+ // Show UMO until transition finishes.
+ val showUmo: Flow<Boolean> =
+ transitionAnimation
+ .sharedFlow(
+ duration = FROM_GLANCEABLE_HUB_DURATION,
+ onStep = { it },
+ onCancel = { 0f },
+ onFinish = { 1f },
+ )
+ .map { step -> step != 1f }
+
private companion object {
val FROM_GLANCEABLE_HUB_DURATION = 1.seconds
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToLockscreenTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToLockscreenTransitionViewModel.kt
index 6042117eff12..e05b500620d5 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToLockscreenTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToLockscreenTransitionViewModel.kt
@@ -31,7 +31,6 @@ import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.flow.onStart
/**
* Breaks down GLANCEABLE_HUB->LOCKSCREEN transition into discrete steps for corresponding views to
@@ -53,16 +52,17 @@ constructor(
)
val keyguardAlpha: Flow<Float> =
- transitionAnimation
- .sharedFlow(
- duration = 167.milliseconds,
- startTime = 167.milliseconds,
- onStep = { it },
- onFinish = { 1f },
- onCancel = { 0f },
- name = "GLANCEABLE_HUB->LOCKSCREEN: keyguardAlpha",
- )
- .onStart { emit(0f) }
+ transitionAnimation.sharedFlow(
+ duration = 167.milliseconds,
+ startTime = 167.milliseconds,
+ onStep = { it },
+ onFinish = { 1f },
+ onCancel = { 0f },
+ name = "GLANCEABLE_HUB->LOCKSCREEN: keyguardAlpha",
+ )
+
+ // Show UMO as long as keyguard is not visible.
+ val showUmo: Flow<Boolean> = keyguardAlpha.map { alpha -> alpha == 0f }
val keyguardTranslationX: Flow<StateToValue> =
configurationInteractor
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt
index 58c45c74815c..b6622e5c07b1 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt
@@ -28,8 +28,9 @@ import com.android.systemui.keyguard.shared.ComposeLockscreen
import com.android.systemui.keyguard.shared.model.SettingsClockSize
import com.android.systemui.plugins.clocks.ClockController
import com.android.systemui.res.R
+import com.android.systemui.shade.domain.interactor.ShadeInteractor
+import com.android.systemui.shade.shared.model.ShadeMode
import com.android.systemui.statusbar.notification.domain.interactor.NotificationsKeyguardInteractor
-import com.android.systemui.statusbar.policy.SplitShadeStateController
import com.android.systemui.util.Utils
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
@@ -46,8 +47,8 @@ constructor(
keyguardInteractor: KeyguardInteractor,
private val keyguardClockInteractor: KeyguardClockInteractor,
@Application private val applicationScope: CoroutineScope,
- private val splitShadeStateController: SplitShadeStateController,
notifsKeyguardInteractor: NotificationsKeyguardInteractor,
+ private val shadeInteractor: ShadeInteractor,
) {
var burnInLayer: Layer? = null
val useLargeClock: Boolean
@@ -111,12 +112,33 @@ constructor(
initialValue = false
)
+ val currentClockLayout: StateFlow<ClockLayout> =
+ combine(isLargeClockVisible, clockShouldBeCentered, shadeInteractor.shadeMode) {
+ isLargeClockVisible,
+ clockShouldBeCentered,
+ shadeMode ->
+ val shouldUseSplitShade = shadeMode == ShadeMode.Split
+ when {
+ shouldUseSplitShade && clockShouldBeCentered -> ClockLayout.LARGE_CLOCK
+ shouldUseSplitShade && isLargeClockVisible ->
+ ClockLayout.SPLIT_SHADE_LARGE_CLOCK
+ shouldUseSplitShade -> ClockLayout.SPLIT_SHADE_SMALL_CLOCK
+ isLargeClockVisible -> ClockLayout.LARGE_CLOCK
+ else -> ClockLayout.SMALL_CLOCK
+ }
+ }
+ .stateIn(
+ scope = applicationScope,
+ started = SharingStarted.WhileSubscribed(),
+ initialValue = ClockLayout.SMALL_CLOCK
+ )
+
/** Calculates the top margin for the small clock. */
fun getSmallClockTopMargin(context: Context): Int {
var topMargin: Int
val statusBarHeight = Utils.getStatusBarHeaderHeightKeyguard(context)
- if (splitShadeStateController.shouldUseSplitNotificationShade(context.resources)) {
+ if (shadeInteractor.shadeMode.value == ShadeMode.Split) {
topMargin =
context.resources.getDimensionPixelSize(R.dimen.keyguard_split_shade_top_margin)
if (ComposeLockscreen.isEnabled) {
@@ -130,4 +152,11 @@ constructor(
}
return topMargin
}
+
+ enum class ClockLayout {
+ LARGE_CLOCK,
+ SMALL_CLOCK,
+ SPLIT_SHADE_LARGE_CLOCK,
+ SPLIT_SHADE_SMALL_CLOCK,
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt
index 5ca9215ce199..55a402597d5b 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt
@@ -54,8 +54,8 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.combineTransform
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.filterNotNull
@@ -125,13 +125,36 @@ constructor(
.onStart { emit(false) }
.distinctUntilChanged()
- private val alphaOnShadeExpansion: Flow<Float> =
+ private val isOnLockscreen: Flow<Boolean> =
combine(
+ keyguardTransitionInteractor.isFinishedInState(LOCKSCREEN).onStart { emit(false) },
+ keyguardTransitionInteractor
+ .isInTransitionWhere { from, to -> from == LOCKSCREEN || to == LOCKSCREEN }
+ .onStart { emit(false) }
+ ) { onLockscreen, transitioningToOrFromLockscreen ->
+ onLockscreen || transitioningToOrFromLockscreen
+ }
+ .distinctUntilChanged()
+
+ private val alphaOnShadeExpansion: Flow<Float> =
+ combineTransform(
+ isOnLockscreen,
shadeInteractor.qsExpansion,
shadeInteractor.shadeExpansion,
- ) { qsExpansion, shadeExpansion ->
+ ) { isOnLockscreen, qsExpansion, shadeExpansion ->
// Fade out quickly as the shade expands
- 1f - MathUtils.constrainedMap(0f, 1f, 0f, 0.2f, max(qsExpansion, shadeExpansion))
+ if (isOnLockscreen) {
+ val alpha =
+ 1f -
+ MathUtils.constrainedMap(
+ /* rangeMin = */ 0f,
+ /* rangeMax = */ 1f,
+ /* valueMin = */ 0f,
+ /* valueMax = */ 0.2f,
+ /* value = */ max(qsExpansion, shadeExpansion)
+ )
+ emit(alpha)
+ }
}
.distinctUntilChanged()
@@ -159,10 +182,6 @@ constructor(
/** Last point that the root view was tapped */
val lastRootViewTapPosition: Flow<Point?> = keyguardInteractor.lastRootViewTapPosition
- /** the shared notification container bounds *on the lockscreen* */
- val notificationBounds: StateFlow<NotificationContainerBounds> =
- keyguardInteractor.notificationContainerBounds
-
/**
* The keyguard root view can be clipped as the shade is pulled down, typically only for
* non-split shade cases.
@@ -235,11 +254,7 @@ constructor(
burnInJob?.cancel()
burnInJob =
- scope.launch {
- aodBurnInViewModel.movement(params).collect {
- burnInModel.value = it
- }
- }
+ scope.launch { aodBurnInViewModel.movement(params).collect { burnInModel.value = it } }
}
val scale: Flow<BurnInScaleViewModel> =
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModel.kt
index 23320be129fd..1f80441492bc 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModel.kt
@@ -23,7 +23,8 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.keyguard.domain.interactor.KeyguardBlueprintInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor
import com.android.systemui.res.R
-import com.android.systemui.statusbar.policy.SplitShadeStateController
+import com.android.systemui.shade.domain.interactor.ShadeInteractor
+import com.android.systemui.shade.shared.model.ShadeMode
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.SharingStarted
@@ -40,7 +41,7 @@ constructor(
private val interactor: KeyguardBlueprintInteractor,
private val authController: AuthController,
val longPress: KeyguardLongPressViewModel,
- val splitShadeStateController: SplitShadeStateController,
+ val shadeInteractor: ShadeInteractor,
) {
private val clockSize = clockInteractor.clockSize
@@ -48,10 +49,12 @@ constructor(
get() = authController.isUdfpsSupported
val isLargeClockVisible: Boolean
get() = clockSize.value == KeyguardClockSwitch.LARGE
- fun areNotificationsVisible(resources: Resources): Boolean {
- return !isLargeClockVisible ||
- splitShadeStateController.shouldUseSplitNotificationShade(resources)
- }
+
+ val areNotificationsVisible: Boolean
+ get() = !isLargeClockVisible || shouldUseSplitNotificationShade
+
+ val shouldUseSplitNotificationShade: Boolean
+ get() = shadeInteractor.shadeMode.value == ShadeMode.Split
fun getSmartSpacePaddingTop(resources: Resources): Int {
return if (isLargeClockVisible) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGlanceableHubTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGlanceableHubTransitionViewModel.kt
index 5cbc1d4a3745..dae7897a2325 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGlanceableHubTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGlanceableHubTransitionViewModel.kt
@@ -31,7 +31,6 @@ import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.flow.onStart
/**
* Breaks down LOCKSCREEN->GLANCEABLE_HUB transition into discrete steps for corresponding views to
@@ -53,15 +52,16 @@ constructor(
)
val keyguardAlpha: Flow<Float> =
- transitionAnimation
- .sharedFlow(
- duration = 167.milliseconds,
- onStep = { 1f - it },
- onFinish = { 0f },
- onCancel = { 1f },
- name = "LOCKSCREEN->GLANCEABLE_HUB: keyguardAlpha",
- )
- .onStart { emit(1f) }
+ transitionAnimation.sharedFlow(
+ duration = 167.milliseconds,
+ onStep = { 1f - it },
+ onFinish = { 0f },
+ onCancel = { 1f },
+ name = "LOCKSCREEN->GLANCEABLE_HUB: keyguardAlpha",
+ )
+
+ // Show UMO as long as keyguard is not visible.
+ val showUmo: Flow<Boolean> = keyguardAlpha.map { alpha -> alpha == 0f }
val keyguardTranslationX: Flow<StateToValue> =
configurationInteractor
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaHierarchyManager.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaHierarchyManager.kt
index dbd71f3e3a04..a4f3e2174791 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaHierarchyManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaHierarchyManager.kt
@@ -36,7 +36,7 @@ import androidx.annotation.VisibleForTesting
import com.android.app.animation.Interpolators
import com.android.app.tracing.traceSection
import com.android.keyguard.KeyguardViewController
-import com.android.systemui.communal.domain.interactor.CommunalInteractor
+import com.android.systemui.communal.ui.viewmodel.CommunalTransitionViewModel
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Main
@@ -58,7 +58,6 @@ import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.statusbar.policy.SplitShadeStateController
import com.android.systemui.util.animation.UniqueObjectHostView
-import com.android.systemui.util.kotlin.BooleanFlowOperators.and
import com.android.systemui.util.settings.SecureSettings
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
@@ -102,7 +101,7 @@ constructor(
private val mediaManager: MediaDataManager,
private val keyguardViewController: KeyguardViewController,
private val dreamOverlayStateController: DreamOverlayStateController,
- private val communalInteractor: CommunalInteractor,
+ communalTransitionViewModel: CommunalTransitionViewModel,
configurationController: ConfigurationController,
wakefulnessLifecycle: WakefulnessLifecycle,
shadeInteractor: ShadeInteractor,
@@ -587,11 +586,10 @@ constructor(
// Listen to the communal UI state. Make sure that communal UI is showing and hub itself is
// available, ie. not disabled and able to be shown.
coroutineScope.launch {
- and(communalInteractor.isCommunalShowing, communalInteractor.isCommunalAvailable)
- .collect { value ->
- isCommunalShowing = value
- updateDesiredLocation()
- }
+ communalTransitionViewModel.isUmoOnCommunal.collect { value ->
+ isCommunalShowing = value
+ updateDesiredLocation(forceNoAnimation = true)
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java
index 5f0635bdba01..1d820a14be4e 100644
--- a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java
+++ b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java
@@ -21,9 +21,6 @@ import static android.app.NotificationManager.INTERRUPTION_FILTER_ALARMS;
import static android.app.NotificationManager.INTERRUPTION_FILTER_ALL;
import static android.app.NotificationManager.INTERRUPTION_FILTER_NONE;
import static android.app.NotificationManager.INTERRUPTION_FILTER_PRIORITY;
-import static android.appwidget.AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN;
-import static android.appwidget.AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD;
-import static android.appwidget.flags.Flags.generatedPreviews;
import static android.content.Intent.ACTION_BOOT_COMPLETED;
import static android.content.Intent.ACTION_PACKAGE_ADDED;
import static android.content.Intent.ACTION_PACKAGE_REMOVED;
@@ -83,15 +80,12 @@ import android.service.notification.StatusBarNotification;
import android.service.notification.ZenModeConfig;
import android.text.TextUtils;
import android.util.Log;
-import android.util.SparseBooleanArray;
import android.widget.RemoteViews;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.UiEventLoggerImpl;
-import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.systemui.Dumpable;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dagger.SysUISingleton;
@@ -102,8 +96,6 @@ import com.android.systemui.people.PeopleBackupFollowUpJob;
import com.android.systemui.people.PeopleSpaceUtils;
import com.android.systemui.people.PeopleTileViewHelper;
import com.android.systemui.people.SharedPreferencesHelper;
-import com.android.systemui.res.R;
-import com.android.systemui.settings.UserTracker;
import com.android.systemui.statusbar.NotificationListener;
import com.android.systemui.statusbar.NotificationListener.NotificationHandler;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -168,27 +160,13 @@ public class PeopleSpaceWidgetManager implements Dumpable {
@GuardedBy("mLock")
public static Map<Integer, PeopleSpaceTile> mTiles = new HashMap<>();
- @NonNull private final UserTracker mUserTracker;
- @NonNull private final SparseBooleanArray mUpdatedPreviews = new SparseBooleanArray();
- @NonNull private final KeyguardUpdateMonitorCallback mKeyguardUpdateMonitorCallback =
- new KeyguardUpdateMonitorCallback() {
- @Override
- public void onUserUnlocked() {
- if (DEBUG) {
- Log.d(TAG, "onUserUnlocked " + mUserTracker.getUserId());
- }
- updateGeneratedPreviewForUser(mUserTracker.getUserHandle());
- }
- };
-
@Inject
public PeopleSpaceWidgetManager(Context context, LauncherApps launcherApps,
CommonNotifCollection notifCollection,
PackageManager packageManager, Optional<Bubbles> bubblesOptional,
UserManager userManager, NotificationManager notificationManager,
BroadcastDispatcher broadcastDispatcher, @Background Executor bgExecutor,
- DumpManager dumpManager, @NonNull UserTracker userTracker,
- @NonNull KeyguardUpdateMonitor keyguardUpdateMonitor) {
+ DumpManager dumpManager) {
if (DEBUG) Log.d(TAG, "constructor");
mContext = context;
mAppWidgetManager = AppWidgetManager.getInstance(context);
@@ -209,8 +187,6 @@ public class PeopleSpaceWidgetManager implements Dumpable {
mBroadcastDispatcher = broadcastDispatcher;
mBgExecutor = bgExecutor;
dumpManager.registerNormalDumpable(TAG, this);
- mUserTracker = userTracker;
- keyguardUpdateMonitor.registerCallback(mKeyguardUpdateMonitorCallback);
}
/** Initializes {@PeopleSpaceWidgetManager}. */
@@ -270,7 +246,7 @@ public class PeopleSpaceWidgetManager implements Dumpable {
CommonNotifCollection notifCollection, PackageManager packageManager,
Optional<Bubbles> bubblesOptional, UserManager userManager, BackupManager backupManager,
INotificationManager iNotificationManager, NotificationManager notificationManager,
- @Background Executor executor, UserTracker userTracker) {
+ @Background Executor executor) {
mContext = context;
mAppWidgetManager = appWidgetManager;
mIPeopleManager = iPeopleManager;
@@ -286,7 +262,6 @@ public class PeopleSpaceWidgetManager implements Dumpable {
mManager = this;
mSharedPrefs = PreferenceManager.getDefaultSharedPreferences(context);
mBgExecutor = executor;
- mUserTracker = userTracker;
}
/**
@@ -1432,24 +1407,4 @@ public class PeopleSpaceWidgetManager implements Dumpable {
Trace.traceEnd(Trace.TRACE_TAG_APP);
}
-
- @VisibleForTesting
- void updateGeneratedPreviewForUser(UserHandle user) {
- if (!generatedPreviews() || mUpdatedPreviews.get(user.getIdentifier())
- || !mUserManager.isUserUnlocked(user)) {
- return;
- }
- if (DEBUG) {
- Log.d(TAG, "Updating People Space widget preview for user " + user.getIdentifier());
- }
- boolean success = mAppWidgetManager.setWidgetPreview(
- new ComponentName(mContext, PeopleSpaceWidgetProvider.class),
- WIDGET_CATEGORY_HOME_SCREEN | WIDGET_CATEGORY_KEYGUARD,
- new RemoteViews(mContext.getPackageName(),
- R.layout.people_space_placeholder_layout));
- if (DEBUG && !success) {
- Log.d(TAG, "Failed to update generated preview for user " + user.getIdentifier());
- }
- mUpdatedPreviews.put(user.getIdentifier(), success);
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
index c657b55d42d6..9c88eb95c274 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
@@ -17,6 +17,8 @@ package com.android.systemui.qs;
import static android.app.StatusBarManager.DISABLE2_QUICK_SETTINGS;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
+import static com.android.systemui.Flags.centralizedStatusBarHeightFix;
+
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
@@ -27,6 +29,7 @@ import android.view.ViewGroup;
import android.widget.FrameLayout;
import com.android.systemui.res.R;
+import com.android.systemui.shade.LargeScreenHeaderHelper;
import com.android.systemui.util.LargeScreenUtils;
/**
@@ -97,7 +100,9 @@ public class QuickStatusBarHeader extends FrameLayout {
qqsLP.topMargin = mContext.getResources()
.getDimensionPixelSize(R.dimen.qqs_layout_margin_top);
} else {
- qqsLP.topMargin = mContext.getResources()
+ qqsLP.topMargin = centralizedStatusBarHeightFix()
+ ? LargeScreenHeaderHelper.getLargeScreenHeaderHeight(mContext)
+ : mContext.getResources()
.getDimensionPixelSize(R.dimen.large_screen_shade_header_min_height);
}
mHeaderQsPanel.setLayoutParams(qqsLP);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
index 9ae049d6d6f1..d0ff33869a77 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
@@ -37,6 +37,7 @@ import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_F
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_GOING_AWAY;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_TRACING_ENABLED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_VOICE_INTERACTION_WINDOW_SHOWING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_WAKEFULNESS_TRANSITION;
@@ -114,6 +115,8 @@ import com.android.systemui.unfold.progress.UnfoldTransitionProgressForwarder;
import com.android.wm.shell.desktopmode.DesktopModeStatus;
import com.android.wm.shell.sysui.ShellInterface;
+import dagger.Lazy;
+
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
@@ -125,8 +128,6 @@ import java.util.function.Supplier;
import javax.inject.Inject;
import javax.inject.Provider;
-import dagger.Lazy;
-
/**
* Class to send information from overview to launcher with a binder.
*/
@@ -669,7 +670,8 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis
// Listen for tracing state changes
@Override
public void onTracingStateChanged(boolean enabled) {
- // TODO(b/286509643) Cleanup callers of this; Unused downstream
+ mSysUiState.setFlag(SYSUI_STATE_TRACING_ENABLED, enabled)
+ .commitUpdate(mContext.getDisplayId());
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
index 6df57edd34c3..32e8f55e68e7 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
@@ -46,7 +46,6 @@ import com.android.systemui.scene.shared.logger.SceneLogger
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.statusbar.NotificationShadeWindowController
import com.android.systemui.statusbar.notification.domain.interactor.HeadsUpNotificationInteractor
-import com.android.systemui.statusbar.notification.stack.shared.flexiNotifsEnabled
import com.android.systemui.statusbar.phone.CentralSurfaces
import com.android.systemui.statusbar.policy.domain.interactor.DeviceProvisioningInteractor
import com.android.systemui.util.asIndenting
@@ -120,7 +119,6 @@ constructor(
printSection("SceneContainerFlags") {
println("isEnabled", flags.isEnabled())
printSection("requirementDescription") { println(flags.requirementDescription()) }
- println("flexiNotifsEnabled", flags.flexiNotifsEnabled())
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlags.kt b/packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlags.kt
index 1808d98cd692..467089d24f2c 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlags.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlags.kt
@@ -19,9 +19,11 @@
package com.android.systemui.scene.shared.flag
import com.android.systemui.Flags.FLAG_KEYGUARD_BOTTOM_AREA_REFACTOR
+import com.android.systemui.Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR
import com.android.systemui.Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT
import com.android.systemui.Flags.FLAG_SCENE_CONTAINER
import com.android.systemui.Flags.keyguardBottomAreaRefactor
+import com.android.systemui.Flags.keyguardWmStateRefactor
import com.android.systemui.Flags.migrateClocksToBlueprint
import com.android.systemui.Flags.sceneContainer
import com.android.systemui.dagger.SysUISingleton
@@ -46,7 +48,8 @@ object SceneContainerFlag {
keyguardBottomAreaRefactor() &&
migrateClocksToBlueprint() &&
ComposeLockscreen.isEnabled &&
- MediaInSceneContainerFlag.isEnabled
+ MediaInSceneContainerFlag.isEnabled &&
+ keyguardWmStateRefactor()
// NOTE: Changes should also be made in getSecondaryFlags and @EnableSceneContainer
/**
@@ -65,6 +68,7 @@ object SceneContainerFlag {
sequenceOf(
FlagToken(FLAG_KEYGUARD_BOTTOM_AREA_REFACTOR, keyguardBottomAreaRefactor()),
FlagToken(FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT, migrateClocksToBlueprint()),
+ FlagToken(FLAG_KEYGUARD_WM_STATE_REFACTOR, keyguardWmStateRefactor()),
ComposeLockscreen.token,
MediaInSceneContainerFlag.token,
// NOTE: Changes should also be made in isEnabled and @EnableSceneContainer
diff --git a/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootViewBinder.kt b/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootViewBinder.kt
index 7c31ca269eb9..809ac2ea9f82 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootViewBinder.kt
@@ -46,7 +46,6 @@ import com.android.systemui.scene.shared.model.SceneDataSourceDelegator
import com.android.systemui.scene.ui.composable.ComposableScene
import com.android.systemui.scene.ui.composable.SceneContainer
import com.android.systemui.scene.ui.viewmodel.SceneContainerViewModel
-import com.android.systemui.statusbar.notification.stack.shared.flexiNotifsEnabled
import com.android.systemui.statusbar.notification.stack.ui.view.SharedNotificationContainer
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.SharingStarted
@@ -116,7 +115,7 @@ object SceneWindowRootViewBinder {
// the SceneContainerView. This SharedNotificationContainer should contain NSSL
// due to the NotificationStackScrollLayoutSection (legacy) or
// NotificationSection (scene container) moving it there.
- if (flags.flexiNotifsEnabled()) {
+ if (flags.isEnabled()) {
(sharedNotificationContainer.parent as? ViewGroup)?.removeView(
sharedNotificationContainer
)
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
index ac94f39bff5a..b2c01e180ec4 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
@@ -82,7 +82,7 @@ public class RecordingService extends Service implements ScreenMediaRecorderList
private final RecordingController mController;
protected final KeyguardDismissUtil mKeyguardDismissUtil;
private final Handler mMainHandler;
- private ScreenRecordingAudioSource mAudioSource;
+ private ScreenRecordingAudioSource mAudioSource = ScreenRecordingAudioSource.NONE;
private boolean mShowTaps;
private boolean mOriginalShowTaps;
private ScreenMediaRecorder mRecorder;
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index 8b791de429ed..975e146f3940 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -71,6 +71,8 @@ import android.util.IndentingPrintWriter;
import android.util.Log;
import android.util.MathUtils;
import android.view.HapticFeedbackConstants;
+import android.view.InputDevice;
+import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.VelocityTracker;
@@ -355,6 +357,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
private final QuickSettingsControllerImpl mQsController;
private final NaturalScrollingSettingObserver mNaturalScrollingSettingObserver;
private final TouchHandler mTouchHandler = new TouchHandler();
+ private final KeyHandler mKeyHandler = new KeyHandler();
private long mDownTime;
private boolean mTouchSlopExceededBeforeDown;
@@ -816,6 +819,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
mView.addOnLayoutChangeListener(new ShadeLayoutChangeListener());
mView.setOnTouchListener(getTouchHandler());
+ mView.setOnKeyListener(getKeyHandler());
mView.setOnConfigurationChangedListener(config -> loadDimens());
mResources = mView.getResources();
@@ -3590,6 +3594,11 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
return mTouchHandler;
}
+ @VisibleForTesting
+ KeyHandler getKeyHandler() {
+ return mKeyHandler;
+ }
+
@Override
public void disableHeader(int state1, int state2, boolean animated) {
mShadeHeaderController.disable(state1, state2, animated);
@@ -5242,6 +5251,21 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
}
}
+ /** Handles KeyEvents for the Shade. */
+ public final class KeyHandler implements View.OnKeyListener {
+ @Override
+ public boolean onKey(View v, int keyCode, KeyEvent event) {
+ if (event.getAction() == KeyEvent.ACTION_DOWN) {
+ final InputDevice d = event.getDevice();
+ // Trigger user activity if the event comes from a full external keyboard
+ if (d != null && d.isFullKeyboard() && d.isExternal()) {
+ mCentralSurfaces.userActivity();
+ }
+ }
+ return false;
+ }
+ }
+
private final class HeadsUpNotificationViewControllerImpl implements
HeadsUpTouchHelper.HeadsUpNotificationViewController {
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/domain/interactor/StatusBarKeyguardViewManagerInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/domain/interactor/StatusBarKeyguardViewManagerInteractor.kt
index 1bebbfd34ff4..ca7308161e14 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/domain/interactor/StatusBarKeyguardViewManagerInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/domain/interactor/StatusBarKeyguardViewManagerInteractor.kt
@@ -18,12 +18,16 @@ package com.android.systemui.statusbar.domain.interactor
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.keyguard.domain.interactor.KeyguardOcclusionInteractor
+import com.android.systemui.keyguard.domain.interactor.KeyguardSurfaceBehindInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
+import com.android.systemui.keyguard.domain.interactor.WindowManagerLockscreenVisibilityInteractor
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.power.domain.interactor.PowerInteractor
import com.android.systemui.util.kotlin.sample
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.distinctUntilChangedBy
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.map
@@ -46,6 +50,8 @@ constructor(
keyguardTransitionInteractor: KeyguardTransitionInteractor,
keyguardOcclusionInteractor: KeyguardOcclusionInteractor,
powerInteractor: PowerInteractor,
+ wmLockscreenVisibilityInteractor: WindowManagerLockscreenVisibilityInteractor,
+ surfaceBehindInteractor: KeyguardSurfaceBehindInteractor,
) {
/** Occlusion state to apply whenever a keyguard transition is STARTED, if any. */
private val occlusionStateFromStartedStep: Flow<OccludedState> =
@@ -98,11 +104,21 @@ constructor(
OccludedState(occluded = occluded, animate = false)
}
- /** Occlusion state to apply to SKBVM's setOccluded call. */
+ /** Occlusion state to apply to SBKVM's setOccluded call. */
val keyguardViewOcclusionState =
merge(occlusionStateFromStartedStep, occlusionStateFromFinishedStep)
.distinctUntilChangedBy {
// Don't switch 'animate' values mid-transition.
it.occluded
}
+
+ /** Visibility state to apply to SBKVM via show() and hide(). */
+ val keyguardViewVisibility =
+ combine(
+ wmLockscreenVisibilityInteractor.lockscreenVisibility,
+ surfaceBehindInteractor.isAnimatingSurface,
+ ) { lockscreenVisible, animatingSurface ->
+ lockscreenVisible || animatingSurface
+ }
+ .distinctUntilChanged()
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
index 6548967c7462..e31e9c22e38e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
@@ -74,6 +74,8 @@ import com.android.systemui.statusbar.notification.interruption.VisualInterrupti
import com.android.systemui.statusbar.notification.interruption.VisualInterruptionRefactor;
import com.android.systemui.statusbar.notification.logging.NotificationPanelLogger;
import com.android.systemui.statusbar.notification.logging.NotificationPanelLoggerImpl;
+import com.android.systemui.statusbar.notification.row.NotificationEntryProcessorFactory;
+import com.android.systemui.statusbar.notification.row.NotificationEntryProcessorFactoryLooperImpl;
import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
import com.android.systemui.statusbar.notification.row.OnUserInteractionCallback;
import com.android.systemui.statusbar.notification.row.ui.viewmodel.ActivatableNotificationViewModelModule;
@@ -234,6 +236,11 @@ public interface NotificationsModule {
/** */
@Binds
+ NotificationEntryProcessorFactory bindNotificationEntryProcessorFactory(
+ NotificationEntryProcessorFactoryLooperImpl factoryImpl);
+
+ /** */
+ @Binds
ConversationIconManager bindConversationIconManager(IconManager iconManager);
/** */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotifBindPipeline.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotifBindPipeline.java
index ea564ddb9193..a6b6f0d2ee28 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotifBindPipeline.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotifBindPipeline.java
@@ -16,9 +16,6 @@
package com.android.systemui.statusbar.notification.row;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.widget.FrameLayout;
@@ -29,7 +26,6 @@ import androidx.annotation.Nullable;
import androidx.core.os.CancellationSignal;
import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinder;
import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
@@ -82,17 +78,17 @@ public final class NotifBindPipeline {
private final Map<NotificationEntry, BindEntry> mBindEntries = new ArrayMap<>();
private final NotifBindPipelineLogger mLogger;
private final List<BindCallback> mScratchCallbacksList = new ArrayList<>();
- private final Handler mMainHandler;
+ private final Processor<NotificationEntry> mStartProcessor;
private BindStage mStage;
@Inject
NotifBindPipeline(
CommonNotifCollection collection,
NotifBindPipelineLogger logger,
- @Main Looper mainLooper) {
+ NotificationEntryProcessorFactory processorFactory) {
collection.addCollectionListener(mCollectionListener);
mLogger = logger;
- mMainHandler = new NotifBindPipelineHandler(mainLooper);
+ mStartProcessor = processorFactory.create(this::startPipeline);
}
/**
@@ -167,10 +163,7 @@ public final class NotifBindPipeline {
// Abort any existing pipeline run
mStage.abortStage(entry, bindEntry.row);
- if (!mMainHandler.hasMessages(START_PIPELINE_MSG, entry)) {
- Message msg = Message.obtain(mMainHandler, START_PIPELINE_MSG, entry);
- mMainHandler.sendMessage(msg);
- }
+ mStartProcessor.request(entry);
}
/**
@@ -223,7 +216,7 @@ public final class NotifBindPipeline {
mStage.abortStage(entry, row);
}
mStage.deleteStageParams(entry);
- mMainHandler.removeMessages(START_PIPELINE_MSG, entry);
+ mStartProcessor.cancel(entry);
}
};
@@ -247,25 +240,4 @@ public final class NotifBindPipeline {
public final Set<BindCallback> callbacks = new ArraySet<>();
public boolean invalidated;
}
-
- private static final int START_PIPELINE_MSG = 1;
-
- private class NotifBindPipelineHandler extends Handler {
-
- NotifBindPipelineHandler(Looper looper) {
- super(looper);
- }
-
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case START_PIPELINE_MSG:
- NotificationEntry entry = (NotificationEntry) msg.obj;
- startPipeline(entry);
- break;
- default:
- throw new IllegalArgumentException("Unknown message type: " + msg.what);
- }
- }
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationEntryProcessorFactory.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationEntryProcessorFactory.kt
new file mode 100644
index 000000000000..f32351300e99
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationEntryProcessorFactory.kt
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.statusbar.notification.row
+
+import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import java.util.function.Consumer
+
+/** an interface for [NotifBindPipeline] to build a main thread message processor */
+interface NotificationEntryProcessorFactory {
+ /** Creates a [Processor] that will call the given consumer */
+ fun create(consumer: Consumer<NotificationEntry>): Processor<NotificationEntry>
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationEntryProcessorFactoryExecutorImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationEntryProcessorFactoryExecutorImpl.kt
new file mode 100644
index 000000000000..83b92a93b689
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationEntryProcessorFactoryExecutorImpl.kt
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.statusbar.notification.row
+
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.util.concurrency.DelayableExecutor
+import java.util.concurrent.ConcurrentHashMap
+import java.util.function.Consumer
+import javax.inject.Inject
+
+class NotificationEntryProcessorFactoryExecutorImpl
+@Inject
+constructor(@Main private val mMainExecutor: DelayableExecutor) :
+ NotificationEntryProcessorFactory {
+ override fun create(consumer: Consumer<NotificationEntry>): Processor<NotificationEntry> {
+ return ExecutorProcessor(mMainExecutor, consumer)
+ }
+
+ private class ExecutorProcessor(
+ private val executor: DelayableExecutor,
+ private val consumer: Consumer<NotificationEntry>,
+ ) : Processor<NotificationEntry> {
+ val cancellationsByEntry = ConcurrentHashMap<NotificationEntry, Runnable>()
+
+ override fun request(obj: NotificationEntry) {
+ cancellationsByEntry.computeIfAbsent(obj) { entry ->
+ executor.executeDelayed({ processEntry(entry) }, 0L)
+ }
+ }
+
+ private fun processEntry(entry: NotificationEntry) {
+ val cancellation = cancellationsByEntry.remove(entry)
+ if (cancellation != null) {
+ consumer.accept(entry)
+ }
+ }
+
+ override fun cancel(obj: NotificationEntry) {
+ cancellationsByEntry.remove(obj)?.run()
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationEntryProcessorFactoryLooperImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationEntryProcessorFactoryLooperImpl.kt
new file mode 100644
index 000000000000..7f7a6c402f1a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationEntryProcessorFactoryLooperImpl.kt
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.statusbar.notification.row
+
+import android.os.Handler
+import android.os.Looper
+import android.os.Message
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import java.util.function.Consumer
+import javax.inject.Inject
+
+class NotificationEntryProcessorFactoryLooperImpl
+@Inject
+constructor(@Main private val mMainLooper: Looper) : NotificationEntryProcessorFactory {
+ override fun create(consumer: Consumer<NotificationEntry>): Processor<NotificationEntry> {
+ return HandlerProcessor(mMainLooper, consumer)
+ }
+
+ private class HandlerProcessor(
+ looper: Looper,
+ private val consumer: Consumer<NotificationEntry>,
+ ) : Handler(looper), Processor<NotificationEntry> {
+ override fun handleMessage(msg: Message) {
+ if (msg.what == PROCESS_MSG) {
+ val entry = msg.obj as NotificationEntry
+ consumer.accept(entry)
+ } else {
+ throw IllegalArgumentException("Unknown message type: " + msg.what)
+ }
+ }
+
+ override fun request(obj: NotificationEntry) {
+ if (!hasMessages(PROCESS_MSG, obj)) {
+ val msg = Message.obtain(this, PROCESS_MSG, obj)
+ sendMessage(msg)
+ }
+ }
+
+ override fun cancel(obj: NotificationEntry) {
+ removeMessages(PROCESS_MSG, obj)
+ }
+ companion object {
+ private const val PROCESS_MSG = 1
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/Processor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/Processor.kt
new file mode 100644
index 000000000000..7ff9d7155ca5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/Processor.kt
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.statusbar.notification.row
+
+/** A generic interface for requesting async processing of objects, as well as cancellation */
+interface Processor<T> {
+ /** request that the object be processed if it is not already waiting */
+ fun request(obj: T)
+
+ /** cancel a request to process the given object if one is still pending */
+ fun cancel(obj: T)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationStackAppearanceViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationStackAppearanceViewBinder.kt
index 8b1b06eb1453..dbc3138ec435 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationStackAppearanceViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationStackAppearanceViewBinder.kt
@@ -48,11 +48,13 @@ object NotificationStackAppearanceViewBinder {
repeatOnLifecycle(Lifecycle.State.CREATED) {
launch {
viewModel.stackBounds.collect { bounds ->
+ val viewLeft = controller.view.left
+ val viewTop = controller.view.top
controller.setRoundedClippingBounds(
- bounds.left.roundToInt(),
- bounds.top.roundToInt(),
- bounds.right.roundToInt(),
- bounds.bottom.roundToInt(),
+ bounds.left.roundToInt() - viewLeft,
+ bounds.top.roundToInt() - viewTop,
+ bounds.right.roundToInt() - viewLeft,
+ bounds.bottom.roundToInt() - viewTop,
SCRIM_CORNER_RADIUS.dpToPx(context),
0,
)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt
index 5b8b91c6a5fb..7c76ddbec105 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt
@@ -28,7 +28,6 @@ import com.android.systemui.scene.shared.flag.SceneContainerFlags
import com.android.systemui.statusbar.notification.footer.shared.FooterViewRefactor
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
import com.android.systemui.statusbar.notification.stack.NotificationStackSizeCalculator
-import com.android.systemui.statusbar.notification.stack.shared.flexiNotifsEnabled
import com.android.systemui.statusbar.notification.stack.ui.view.SharedNotificationContainer
import com.android.systemui.statusbar.notification.stack.ui.viewmodel.SharedNotificationContainerViewModel
import kotlinx.coroutines.CoroutineDispatcher
@@ -136,7 +135,7 @@ object SharedNotificationContainerBinder {
.collect { controller.setMaxDisplayedNotifications(it) }
}
- if (!sceneContainerFlags.flexiNotifsEnabled()) {
+ if (!sceneContainerFlags.isEnabled()) {
launch {
viewModel.bounds.collect {
val animate =
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModel.kt
index 7ac5cd48f24a..9e2497d5bb41 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModel.kt
@@ -21,11 +21,9 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.flags.FeatureFlagsClassic
import com.android.systemui.flags.Flags
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
-import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.scene.shared.flag.SceneContainerFlags
import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.statusbar.notification.stack.domain.interactor.NotificationStackAppearanceInteractor
-import com.android.systemui.statusbar.notification.stack.shared.flexiNotifsEnabled
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
@@ -43,15 +41,11 @@ constructor(
featureFlags: FeatureFlagsClassic,
private val keyguardInteractor: KeyguardInteractor,
) {
- /** DEBUG: whether the placeholder "Notifications" text should be shown. */
- val isPlaceholderTextVisible: Boolean =
- !flags.flexiNotifsEnabled() && SceneContainerFlag.isEnabled
-
/** DEBUG: whether the placeholder should be made slightly visible for positional debugging. */
val isVisualDebuggingEnabled: Boolean = featureFlags.isEnabled(Flags.NSSL_DEBUG_LINES)
/** DEBUG: whether the debug logging should be output. */
- val isDebugLoggingEnabled: Boolean = flags.flexiNotifsEnabled()
+ val isDebugLoggingEnabled: Boolean = flags.isEnabled()
/**
* Notifies that the bounds of the notification placeholder have changed.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
index 2c4813aec99d..a38840b10b5f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
@@ -448,9 +448,12 @@ constructor(
isOnGlanceableHubWithoutShade,
isOnLockscreen,
merge(
- lockscreenToGlanceableHubTransitionViewModel.notificationAlpha,
- glanceableHubToLockscreenTransitionViewModel.notificationAlpha,
- )
+ lockscreenToGlanceableHubTransitionViewModel.notificationAlpha,
+ glanceableHubToLockscreenTransitionViewModel.notificationAlpha,
+ )
+ // Manually emit on start because [notificationAlpha] only starts emitting
+ // when transitions start.
+ .onStart { emit(1f) }
) { isOnGlanceableHubWithoutShade, isOnLockscreen, alpha,
->
if (isOnGlanceableHubWithoutShade && !isOnLockscreen) {
@@ -506,6 +509,12 @@ constructor(
)
.dumpWhileCollecting("translationX")
+ private val availableHeight: Flow<Float> =
+ bounds
+ .map { it.bottom - it.top }
+ .distinctUntilChanged()
+ .dumpWhileCollecting("availableHeight")
+
/**
* When on keyguard, there is limited space to display notifications so calculate how many could
* be shown. Otherwise, there is no limit since the vertical space will be scrollable.
@@ -527,19 +536,19 @@ constructor(
showLimitedNotifications,
showUnlimitedNotifications,
shadeInteractor.isUserInteracting,
- bounds,
+ availableHeight,
interactor.notificationStackChanged.onStart { emit(Unit) },
interactor.useExtraShelfSpace,
) { flows ->
val showLimitedNotifications = flows[0] as Boolean
val showUnlimitedNotifications = flows[1] as Boolean
val isUserInteracting = flows[2] as Boolean
- val bounds = flows[3] as NotificationContainerBounds
+ val availableHeight = flows[3] as Float
val useExtraShelfSpace = flows[5] as Boolean
if (!isUserInteracting) {
if (showLimitedNotifications) {
- emit(calculateSpace(bounds.bottom - bounds.top, useExtraShelfSpace))
+ emit(calculateSpace(availableHeight, useExtraShelfSpace))
} else if (showUnlimitedNotifications) {
emit(-1)
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 14e934fab701..f99817aa4aad 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -23,7 +23,6 @@ import static com.android.systemui.bouncer.shared.constants.KeyguardBouncerConst
import static com.android.systemui.plugins.ActivityStarter.OnDismissAction;
import static com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_WAKE_AND_UNLOCK;
import static com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_WAKE_AND_UNLOCK_PULSING;
-import static com.android.systemui.util.kotlin.JavaAdapterKt.combineFlows;
import android.content.Context;
import android.content.res.ColorStateList;
@@ -107,8 +106,6 @@ import com.android.systemui.util.kotlin.JavaAdapter;
import dagger.Lazy;
-import kotlin.Unit;
-
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashSet;
@@ -118,6 +115,7 @@ import java.util.Set;
import javax.inject.Inject;
+import kotlin.Unit;
import kotlinx.coroutines.CoroutineDispatcher;
import kotlinx.coroutines.ExperimentalCoroutinesApi;
import kotlinx.coroutines.Job;
@@ -523,16 +521,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
if (KeyguardWmStateRefactor.isEnabled()) {
// Show the keyguard views whenever we've told WM that the lockscreen is visible.
mJavaAdapter.alwaysCollectFlow(
- combineFlows(
- mWmLockscreenVisibilityInteractor.get().getLockscreenVisibility(),
- mSurfaceBehindInteractor.get().isAnimatingSurface(),
- (lockscreenVis, animatingSurface) ->
- // TODO(b/322546110): Waiting until we're not animating the
- // surface is a workaround to avoid jank. We should actually
- // fix the source of the jank, and then hide the keyguard
- // view without waiting for the animation to end.
- lockscreenVis || animatingSurface
- ),
+ mStatusBarKeyguardViewManagerInteractor.getKeyguardViewVisibility(),
this::consumeShowStatusBarKeyguardView);
mJavaAdapter.alwaysCollectFlow(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyConstants.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyConstants.java
index 7ac3e9c2d94c..bf3347327440 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyConstants.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyConstants.java
@@ -31,6 +31,8 @@ import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.util.DeviceConfigProxy;
+import java.util.concurrent.Executor;
+
import javax.inject.Inject;
@SysUISingleton
@@ -60,18 +62,18 @@ public final class SmartReplyConstants {
private volatile int mMaxNumActions;
private volatile long mOnClickInitDelay;
- private final Handler mHandler;
+ private final Executor mMainExecutor;
private final Context mContext;
private final DeviceConfigProxy mDeviceConfig;
private final KeyValueListParser mParser = new KeyValueListParser(',');
@Inject
public SmartReplyConstants(
- @Main Handler handler,
+ @Main Executor mainExecutor,
Context context,
DeviceConfigProxy deviceConfig
) {
- mHandler = handler;
+ mMainExecutor = mainExecutor;
mContext = context;
final Resources resources = mContext.getResources();
mDefaultEnabled = resources.getBoolean(
@@ -104,7 +106,7 @@ public final class SmartReplyConstants {
}
private void postToHandler(Runnable r) {
- this.mHandler.post(r);
+ this.mMainExecutor.execute(r);
}
private final DeviceConfig.OnPropertiesChangedListener mOnPropertiesChangedListener =
diff --git a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
index b5efc44cff39..aac18e365809 100644
--- a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
+++ b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
@@ -86,15 +86,6 @@ import com.android.systemui.util.kotlin.JavaAdapter;
import com.android.systemui.util.settings.SecureSettings;
import com.google.ux.material.libmonet.dynamiccolor.MaterialDynamicColors;
-import com.google.ux.material.libmonet.hct.Hct;
-import com.google.ux.material.libmonet.scheme.DynamicScheme;
-import com.google.ux.material.libmonet.scheme.SchemeExpressive;
-import com.google.ux.material.libmonet.scheme.SchemeFruitSalad;
-import com.google.ux.material.libmonet.scheme.SchemeMonochrome;
-import com.google.ux.material.libmonet.scheme.SchemeNeutral;
-import com.google.ux.material.libmonet.scheme.SchemeRainbow;
-import com.google.ux.material.libmonet.scheme.SchemeTonalSpot;
-import com.google.ux.material.libmonet.scheme.SchemeVibrant;
import org.json.JSONException;
import org.json.JSONObject;
@@ -150,7 +141,7 @@ public class ThemeOverlayController implements CoreStartable, Dumpable {
// Dominant color extracted from wallpaper, NOT the color used on the overlay
protected int mMainWallpaperColor = Color.TRANSPARENT;
// UI contrast as reported by UiModeManager
- private float mContrast = 0;
+ private double mContrast = 0.0;
// Theme variant: Vibrant, Tonal, Expressive, etc
@VisibleForTesting
protected Style mThemeStyle = Style.TONAL_SPOT;
@@ -170,8 +161,8 @@ public class ThemeOverlayController implements CoreStartable, Dumpable {
private final JavaAdapter mJavaAdapter;
private final KeyguardTransitionInteractor mKeyguardTransitionInteractor;
private final UiModeManager mUiModeManager;
- private DynamicScheme mDynamicSchemeDark;
- private DynamicScheme mDynamicSchemeLight;
+ private ColorScheme mDarkColorScheme;
+ private ColorScheme mLightColorScheme;
// Defers changing themes until Setup Wizard is done.
private boolean mDeferredThemeEvaluation;
@@ -210,7 +201,7 @@ public class ThemeOverlayController implements CoreStartable, Dumpable {
boolean currentUser = userId == mUserTracker.getUserId();
boolean isAsleep = themeOverlayControllerWakefulnessDeprecation()
? mKeyguardTransitionInteractor.isFinishedInStateWhereValue(
- state -> KeyguardState.Companion.deviceIsAsleepInState(state))
+ KeyguardState.Companion::deviceIsAsleepInState)
: mWakefulnessLifecycle.getWakefulness() != WAKEFULNESS_ASLEEP;
if (currentUser && !mAcceptColorEvents && isAsleep) {
@@ -483,19 +474,14 @@ public class ThemeOverlayController implements CoreStartable, Dumpable {
reevaluateSystemTheme(true /* forceReload */);
});
+ // All wallpaper color and keyguard logic only applies when Monet is enabled.
if (!mIsMonetEnabled) {
return;
}
mUserTracker.addCallback(mUserTrackerCallback, mMainExecutor);
-
mDeviceProvisionedController.addCallback(mDeviceProvisionedListener);
- // All wallpaper color and keyguard logic only applies when Monet is enabled.
- if (!mIsMonetEnabled) {
- return;
- }
-
// Upon boot, make sure we have the most up to date colors
Runnable updateColors = () -> {
WallpaperColors systemColor = mWallpaperManager.getWallpaperColors(
@@ -589,29 +575,6 @@ public class ThemeOverlayController implements CoreStartable, Dumpable {
return ColorScheme.getSeedColor(wallpaperColors);
}
- private static DynamicScheme dynamicSchemeFromStyle(Style style, int color,
- boolean isDark, double contrastLevel) {
- Hct sourceColorHct = Hct.fromInt(color);
- switch (style) {
- case EXPRESSIVE:
- return new SchemeExpressive(sourceColorHct, isDark, contrastLevel);
- case SPRITZ:
- return new SchemeNeutral(sourceColorHct, isDark, contrastLevel);
- case TONAL_SPOT:
- return new SchemeTonalSpot(sourceColorHct, isDark, contrastLevel);
- case FRUIT_SALAD:
- return new SchemeFruitSalad(sourceColorHct, isDark, contrastLevel);
- case RAINBOW:
- return new SchemeRainbow(sourceColorHct, isDark, contrastLevel);
- case VIBRANT:
- return new SchemeVibrant(sourceColorHct, isDark, contrastLevel);
- case MONOCHROMATIC:
- return new SchemeMonochrome(sourceColorHct, isDark, contrastLevel);
- default:
- return null;
- }
- }
-
@VisibleForTesting
protected boolean isNightMode() {
return (mResources.getConfiguration().uiMode
@@ -626,22 +589,17 @@ public class ThemeOverlayController implements CoreStartable, Dumpable {
@VisibleForTesting
protected boolean isPrivateProfile(UserHandle userHandle) {
Context usercontext = mContext.createContextAsUser(userHandle,0);
- if (usercontext.getSystemService(UserManager.class).isPrivateProfile()) {
- return true;
- }
- return false;
+ return usercontext.getSystemService(UserManager.class).isPrivateProfile();
}
private void createOverlays(int color) {
- boolean nightMode = isNightMode();
- mColorScheme = new ColorScheme(color, nightMode, mThemeStyle);
+ mDarkColorScheme = new ColorScheme(color, true /* isDark */, mThemeStyle, mContrast);
+ mLightColorScheme = new ColorScheme(color, false /* isDark */, mThemeStyle, mContrast);
+ mColorScheme = isNightMode() ? mDarkColorScheme : mLightColorScheme;
+
mNeutralOverlay = createNeutralOverlay();
mSecondaryOverlay = createAccentOverlay();
- mDynamicSchemeDark = dynamicSchemeFromStyle(
- mThemeStyle, color, true /* isDark */, mContrast);
- mDynamicSchemeLight = dynamicSchemeFromStyle(
- mThemeStyle, color, false /* isDark */, mContrast);
mDynamicOverlay = createDynamicOverlay();
}
@@ -682,10 +640,10 @@ public class ThemeOverlayController implements CoreStartable, Dumpable {
private void assignDynamicPaletteToOverlay(FabricatedOverlay overlay, boolean isDark) {
String suffix = isDark ? "dark" : "light";
- DynamicScheme scheme = isDark ? mDynamicSchemeDark : mDynamicSchemeLight;
+ ColorScheme scheme = isDark ? mDarkColorScheme : mLightColorScheme;
DynamicColors.allDynamicColorsMapped(mIsFidelityEnabled).forEach(p -> {
String resourceName = "android:color/system_" + p.first + "_" + suffix;
- int colorValue = p.second.getArgb(scheme);
+ int colorValue = p.second.getArgb(scheme.getMaterialScheme());
overlay.setResourceValue(resourceName, TYPE_INT_COLOR_ARGB8, colorValue,
null /* configuration */);
});
@@ -694,7 +652,7 @@ public class ThemeOverlayController implements CoreStartable, Dumpable {
private void assignFixedColorsToOverlay(FabricatedOverlay overlay) {
DynamicColors.getFixedColorsMapped(mIsFidelityEnabled).forEach(p -> {
String resourceName = "android:color/system_" + p.first;
- int colorValue = p.second.getArgb(mDynamicSchemeLight);
+ int colorValue = p.second.getArgb(mLightColorScheme.getMaterialScheme());
overlay.setResourceValue(resourceName, TYPE_INT_COLOR_ARGB8, colorValue,
null /* configuration */);
});
@@ -702,6 +660,7 @@ public class ThemeOverlayController implements CoreStartable, Dumpable {
/**
* Checks if the color scheme in mColorScheme matches the current system palettes.
+ *
* @param managedProfiles List of managed profiles for this user.
*/
private boolean colorSchemeIsApplied(Set<UserHandle> managedProfiles) {
@@ -723,15 +682,18 @@ public class ThemeOverlayController implements CoreStartable, Dumpable {
&& res.getColor(android.R.color.system_neutral2_500, theme)
== mColorScheme.getNeutral2().getS500()
&& res.getColor(android.R.color.system_outline_variant_dark, theme)
- == dynamicColors.outlineVariant().getArgb(mDynamicSchemeDark)
+ == dynamicColors.outlineVariant().getArgb(mDarkColorScheme.getMaterialScheme())
&& res.getColor(android.R.color.system_outline_variant_light, theme)
- == dynamicColors.outlineVariant().getArgb(mDynamicSchemeLight)
+ == dynamicColors.outlineVariant().getArgb(mLightColorScheme.getMaterialScheme())
&& res.getColor(android.R.color.system_primary_container_dark, theme)
- == dynamicColors.primaryContainer().getArgb(mDynamicSchemeDark)
+ == dynamicColors.primaryContainer().getArgb(
+ mDarkColorScheme.getMaterialScheme())
&& res.getColor(android.R.color.system_primary_container_light, theme)
- == dynamicColors.primaryContainer().getArgb(mDynamicSchemeLight)
+ == dynamicColors.primaryContainer().getArgb(
+ mLightColorScheme.getMaterialScheme())
&& res.getColor(android.R.color.system_primary_fixed, theme)
- == dynamicColors.primaryFixed().getArgb(mDynamicSchemeLight))) {
+ == dynamicColors.primaryFixed().getArgb(
+ mLightColorScheme.getMaterialScheme()))) {
return false;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
index c294bd8e8f63..7931fab91f46 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
@@ -21,7 +21,6 @@ import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_B
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BUBBLES_MANAGE_MENU_EXPANDED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_DIALOG_SHOWING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_FREEFORM_ACTIVE_IN_DESKTOP_MODE;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_DISABLE_GESTURE_SPLIT_INVOCATION;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_ONE_HANDED_ACTIVE;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_QUICK_SETTINGS_EXPANDED;
@@ -266,13 +265,6 @@ public final class WMShell implements
splitScreen.setSplitscreenFocus(leftOrTop);
}
});
- splitScreen.registerSplitAnimationListener(new SplitScreen.SplitInvocationListener() {
- @Override
- public void onSplitAnimationInvoked(boolean animationRunning) {
- mSysUiState.setFlag(SYSUI_STATE_DISABLE_GESTURE_SPLIT_INVOCATION, animationRunning)
- .commitUpdate(mDisplayTracker.getDefaultDisplayId());
- }
- }, mSysUiMainExecutor);
}
@VisibleForTesting
diff --git a/packages/SystemUI/tests/AndroidTest.xml b/packages/SystemUI/tests/AndroidTest.xml
index 31e7bd2614d6..cd2a62de1acc 100644
--- a/packages/SystemUI/tests/AndroidTest.xml
+++ b/packages/SystemUI/tests/AndroidTest.xml
@@ -32,4 +32,11 @@
<option name="test-filter-dir" value="/data/data/com.android.systemui.tests" />
<option name="hidden-api-checks" value="false"/>
</test>
+
+ <metrics_collector class="com.android.tradefed.device.metric.FilePullerLogCollector">
+ <option name="directory-keys"
+ value="/data/user/0/com.android.systemui.tests/files"/>
+ <option name="collect-on-run-ended-only" value="true"/>
+ <option name="clean-up" value="true"/>
+ </metrics_collector>
</configuration>
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationAnimationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationAnimationControllerTest.java
index 64936862bc20..69cd592d8f50 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationAnimationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationAnimationControllerTest.java
@@ -476,12 +476,18 @@ public class WindowMagnificationAnimationControllerTest extends SysuiTestCase {
mValueAnimator.end();
});
- verify(mSpyController).enableWindowMagnificationInternal(
+ // Verify the method is called in
+ // {@link ValueAnimator.AnimatorUpdateListener#onAnimationUpdate} once and
+ // {@link Animator.AnimatorListener#onAnimationEnd} once in {@link ValueAnimator#end()}
+ verify(mSpyController, times(2)).enableWindowMagnificationInternal(
mScaleCaptor.capture(),
mCenterXCaptor.capture(), mCenterYCaptor.capture(),
mOffsetXCaptor.capture(), mOffsetYCaptor.capture());
- //Animating in reverse, so we only check if the start values are greater than current.
+
+ // The animation is playing forwards, so we only check the animated values are greater than
+ // the current one. (Asserting the first captured scale)
assertTrue(mScaleCaptor.getAllValues().get(0) > mCurrentScale.get());
+ // The last captured scale equalsto the targetScale when we enable window magnification.
assertEquals(targetScale, mScaleCaptor.getValue(), 0f);
assertTrue(mCenterXCaptor.getAllValues().get(0) > mCurrentCenterX.get());
assertEquals(targetCenterX, mCenterXCaptor.getValue(), 0f);
@@ -588,10 +594,10 @@ public class WindowMagnificationAnimationControllerTest extends SysuiTestCase {
final float expectedY = (int) (windowBounds.exactCenterY() + expectedOffset
- defaultMagnificationWindowSize / 2);
- // This is called 4 times when (1) first creating WindowlessMirrorWindow (2) SurfaceView is
+ // This is called 5 times when (1) first creating WindowlessMirrorWindow (2) SurfaceView is
// created and we place the mirrored content as a child of the SurfaceView
- // (3) the animation starts (4) the animation updates
- verify(mTransaction, times(4))
+ // (3) the animation starts (4) the animation updates (5) the animation ends
+ verify(mTransaction, times(5))
.setPosition(any(SurfaceControl.class), eq(expectedX), eq(expectedY));
}
@@ -781,16 +787,18 @@ public class WindowMagnificationAnimationControllerTest extends SysuiTestCase {
// wait for animation returns
waitForIdleSync();
- // {@link ValueAnimator.AnimatorUpdateListener#onAnimationUpdate(ValueAnimator)} will only
- // be triggered once in {@link ValueAnimator#end()}
- verify(mSpyController).enableWindowMagnificationInternal(
+ // Verify the method is called in
+ // {@link ValueAnimator.AnimatorUpdateListener#onAnimationUpdate} once and
+ // {@link Animator.AnimatorListener#onAnimationEnd} once in {@link ValueAnimator#end()}
+ verify(mSpyController, times(2)).enableWindowMagnificationInternal(
mScaleCaptor.capture(),
mCenterXCaptor.capture(), mCenterYCaptor.capture(),
mOffsetXCaptor.capture(), mOffsetYCaptor.capture());
- //The animation is in verse, so we only check the start values should no be greater than
- // the current one.
+ // The animation is playing backwards, so we only check the animated values should not be
+ // greater than the current one. (Asserting the first captured scale)
assertTrue(mScaleCaptor.getAllValues().get(0) <= mCurrentScale.get());
+ // The last captured scale is 1.0 when we delete window magnification.
assertEquals(1.0f, mScaleCaptor.getValue(), 0f);
verifyStartValue(mCenterXCaptor, Float.NaN);
verifyStartValue(mCenterYCaptor, Float.NaN);
@@ -823,10 +831,15 @@ public class WindowMagnificationAnimationControllerTest extends SysuiTestCase {
resetMockObjects();
deleteWindowMagnificationAndWaitAnimating(mWaitAnimationDuration, mAnimationCallback2);
- verify(mSpyController).enableWindowMagnificationInternal(
+ // Verify the method is called in
+ // {@link ValueAnimator.AnimatorUpdateListener#onAnimationUpdate} once and
+ // {@link Animator.AnimatorListener#onAnimationEnd} once when running the animation at
+ // the final duration time.
+ verify(mSpyController, times(2)).enableWindowMagnificationInternal(
mScaleCaptor.capture(),
mCenterXCaptor.capture(), mCenterYCaptor.capture(),
mOffsetXCaptor.capture(), mOffsetYCaptor.capture());
+ // The last captured scale is 1.0 when we delete window magnification.
assertEquals(1.0f, mScaleCaptor.getValue(), 0f);
verifyStartValue(mOffsetXCaptor, 0f);
verifyStartValue(mOffsetYCaptor, 0f);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerWindowlessMagnifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerWindowlessMagnifierTest.java
index 08b49e7d2745..cbdc69608367 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerWindowlessMagnifierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerWindowlessMagnifierTest.java
@@ -132,7 +132,8 @@ import java.util.function.Supplier;
public class WindowMagnificationControllerWindowlessMagnifierTest extends SysuiTestCase {
@Rule
- public final AnimatorTestRule mAnimatorTestRule = new AnimatorTestRule(this);
+ // NOTE: pass 'null' to allow this test advances time on the main thread.
+ public final AnimatorTestRule mAnimatorTestRule = new AnimatorTestRule(/* test= */ null);
@Rule
public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractorTest.kt
index 7ee8963aaa15..1839d8d15b0c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractorTest.kt
@@ -37,8 +37,6 @@ import com.android.systemui.kosmos.testScope
import com.android.systemui.testKosmos
import com.android.systemui.user.domain.interactor.selectedUserInteractor
import junit.framework.Assert.assertEquals
-import junit.framework.Assert.assertTrue
-import junit.framework.Assert.fail
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.test.runCurrent
@@ -144,73 +142,6 @@ class FromPrimaryBouncerTransitionInteractorTest : SysuiTestCase() {
}
@Test
- fun testSurfaceBehindModel() =
- testScope.runTest {
- val values by collectValues(underTest.surfaceBehindModel)
-
- transitionRepository.sendTransitionStep(
- TransitionStep(
- transitionState = TransitionState.STARTED,
- from = KeyguardState.PRIMARY_BOUNCER,
- to = KeyguardState.LOCKSCREEN,
- )
- )
- runCurrent()
-
- assertEquals(
- listOf(
- null, // PRIMARY_BOUNCER -> LOCKSCREEN does not have specific view params.
- ),
- values
- )
-
- transitionRepository.sendTransitionStep(
- TransitionStep(
- transitionState = TransitionState.STARTED,
- from = KeyguardState.PRIMARY_BOUNCER,
- to = KeyguardState.GONE,
- )
- )
- runCurrent()
-
- transitionRepository.sendTransitionStep(
- TransitionStep(
- transitionState = TransitionState.RUNNING,
- from = KeyguardState.PRIMARY_BOUNCER,
- to = KeyguardState.GONE,
- value = 0.01f,
- )
- )
- runCurrent()
-
- transitionRepository.sendTransitionStep(
- TransitionStep(
- transitionState = TransitionState.RUNNING,
- from = KeyguardState.PRIMARY_BOUNCER,
- to = KeyguardState.GONE,
- value = 0.99f,
- )
- )
- runCurrent()
-
- assertEquals(3, values.size)
- val model1percent = values[1]
- val model99percent = values[2]
-
- try {
- // We should initially have an alpha of 0f when unlocking, so the surface is not
- // visible
- // while lockscreen UI animates out.
- assertEquals(0f, model1percent!!.alpha)
-
- // By the end it should probably be visible.
- assertTrue(model99percent!!.alpha > 0f)
- } catch (e: NullPointerException) {
- fail("surfaceBehindModel was unexpectedly null.")
- }
- }
-
- @Test
@EnableFlags(FLAG_KEYGUARD_WM_STATE_REFACTOR)
fun testReturnToLockscreen_whenBouncerHides() =
testScope.runTest {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardBlueprintInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardBlueprintInteractorTest.kt
index 170d3486decb..b6b457142a3f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardBlueprintInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardBlueprintInteractorTest.kt
@@ -17,6 +17,8 @@
package com.android.systemui.keyguard.domain.interactor
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.Flags
@@ -76,6 +78,7 @@ class KeyguardBlueprintInteractorTest : SysuiTestCase() {
}
@Test
+ @DisableFlags(Flags.FLAG_COMPOSE_LOCKSCREEN)
fun testAppliesSplitShadeBlueprint() {
testScope.runTest {
val blueprint by collectLastValue(underTest.blueprint)
@@ -88,6 +91,7 @@ class KeyguardBlueprintInteractorTest : SysuiTestCase() {
}
@Test
+ @DisableFlags(Flags.FLAG_COMPOSE_LOCKSCREEN)
fun fingerprintPropertyInitialized_updatesBlueprint() {
testScope.runTest {
val blueprint by collectLastValue(underTest.blueprint)
@@ -99,9 +103,9 @@ class KeyguardBlueprintInteractorTest : SysuiTestCase() {
}
@Test
+ @DisableFlags(Flags.FLAG_COMPOSE_LOCKSCREEN)
fun composeLockscreenOff_DoesAppliesSplitShadeWeatherClockBlueprint() {
testScope.runTest {
- mSetFlagsRule.disableFlags(Flags.FLAG_COMPOSE_LOCKSCREEN)
val blueprint by collectLastValue(underTest.blueprint)
whenever(clockController.config)
.thenReturn(
@@ -121,9 +125,9 @@ class KeyguardBlueprintInteractorTest : SysuiTestCase() {
}
@Test
+ @EnableFlags(Flags.FLAG_COMPOSE_LOCKSCREEN)
fun testDoesAppliesSplitShadeWeatherClockBlueprint() {
testScope.runTest {
- mSetFlagsRule.enableFlags(Flags.FLAG_COMPOSE_LOCKSCREEN)
val blueprint by collectLastValue(underTest.blueprint)
whenever(clockController.config)
.thenReturn(
@@ -143,9 +147,9 @@ class KeyguardBlueprintInteractorTest : SysuiTestCase() {
}
@Test
+ @EnableFlags(Flags.FLAG_COMPOSE_LOCKSCREEN)
fun testAppliesWeatherClockBlueprint() {
testScope.runTest {
- mSetFlagsRule.enableFlags(Flags.FLAG_COMPOSE_LOCKSCREEN)
val blueprint by collectLastValue(underTest.blueprint)
whenever(clockController.config)
.thenReturn(
@@ -163,4 +167,18 @@ class KeyguardBlueprintInteractorTest : SysuiTestCase() {
assertThat(blueprint?.id).isEqualTo(WEATHER_CLOCK_BLUEPRINT_ID)
}
}
+
+ @Test
+ @EnableFlags(Flags.FLAG_COMPOSE_LOCKSCREEN)
+ fun testDoesNotApplySplitShadeBlueprint() {
+ testScope.runTest {
+ overrideResource(R.bool.config_use_split_notification_shade, true)
+ val blueprint by collectLastValue(underTest.blueprint)
+ clockRepository.setCurrentClock(clockController)
+ configurationRepository.onConfigurationChange()
+ runCurrent()
+
+ assertThat(blueprint?.id).isEqualTo(DefaultKeyguardBlueprint.DEFAULT)
+ }
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelTest.kt
index f252163ee332..0322301b3d6b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelTest.kt
@@ -33,6 +33,8 @@ import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory
import com.android.systemui.plugins.clocks.ClockController
import com.android.systemui.plugins.clocks.ClockFaceConfig
import com.android.systemui.plugins.clocks.ClockFaceController
+import com.android.systemui.shade.domain.interactor.ShadeInteractor
+import com.android.systemui.shade.shared.model.ShadeMode
import com.android.systemui.shared.clocks.ClockRegistry
import com.android.systemui.statusbar.notification.domain.interactor.NotificationsKeyguardInteractor
import com.android.systemui.statusbar.policy.SplitShadeStateController
@@ -42,6 +44,7 @@ import com.google.common.truth.Truth.assertThat
import kotlin.test.Test
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.test.StandardTestDispatcher
import kotlinx.coroutines.test.TestCoroutineScheduler
import kotlinx.coroutines.test.TestScope
@@ -72,6 +75,7 @@ class KeyguardClockViewModelTest : SysuiTestCase() {
@Mock private lateinit var splitShadeStateController: SplitShadeStateController
@Mock private lateinit var notifsKeyguardInteractor: NotificationsKeyguardInteractor
@Mock private lateinit var areNotificationsFullyHidden: Flow<Boolean>
+ @Mock private lateinit var shadeInteractor: ShadeInteractor
@Before
fun setup() {
@@ -96,13 +100,14 @@ class KeyguardClockViewModelTest : SysuiTestCase() {
keyguardClockInteractor = KeyguardClockInteractor(keyguardClockRepository)
whenever(notifsKeyguardInteractor.areNotificationsFullyHidden)
.thenReturn(areNotificationsFullyHidden)
+ whenever(shadeInteractor.shadeMode).thenReturn(MutableStateFlow(ShadeMode.Single))
underTest =
KeyguardClockViewModel(
keyguardInteractor,
keyguardClockInteractor,
scope.backgroundScope,
- splitShadeStateController,
- notifsKeyguardInteractor
+ notifsKeyguardInteractor,
+ shadeInteractor,
)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelWithKosmosTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelWithKosmosTest.kt
new file mode 100644
index 000000000000..e53cd11ebe48
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelWithKosmosTest.kt
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2024 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.keyguard.ui.viewmodel
+
+import androidx.test.filters.SmallTest
+import com.android.keyguard.KeyguardClockSwitch
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.keyguard.data.repository.keyguardClockRepository
+import com.android.systemui.keyguard.data.repository.keyguardRepository
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.shade.data.repository.shadeRepository
+import com.android.systemui.shade.shared.model.ShadeMode
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import kotlin.test.Test
+import kotlinx.coroutines.test.runTest
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@SmallTest
+@RunWith(JUnit4::class)
+class KeyguardClockViewModelWithKosmosTest : SysuiTestCase() {
+ private val kosmos = testKosmos()
+ private val underTest = kosmos.keyguardClockViewModel
+ private val testScope = kosmos.testScope
+
+ @Test
+ fun currentClockLayout_splitShadeOn_clockCentered_largeClock() =
+ testScope.runTest {
+ with(kosmos) {
+ shadeRepository.setShadeMode(ShadeMode.Split)
+ keyguardRepository.setClockShouldBeCentered(true)
+ keyguardClockRepository.setClockSize(KeyguardClockSwitch.LARGE)
+ }
+ val currentClockLayout by collectLastValue(underTest.currentClockLayout)
+ assertThat(currentClockLayout).isEqualTo(KeyguardClockViewModel.ClockLayout.LARGE_CLOCK)
+ }
+
+ @Test
+ fun currentClockLayout_splitShadeOn_clockNotCentered_largeClock_splitShadeLargeClock() =
+ testScope.runTest {
+ with(kosmos) {
+ shadeRepository.setShadeMode(ShadeMode.Split)
+ keyguardRepository.setClockShouldBeCentered(false)
+ keyguardClockRepository.setClockSize(KeyguardClockSwitch.LARGE)
+ }
+ val currentClockLayout by collectLastValue(underTest.currentClockLayout)
+ assertThat(currentClockLayout)
+ .isEqualTo(KeyguardClockViewModel.ClockLayout.SPLIT_SHADE_LARGE_CLOCK)
+ }
+
+ @Test
+ fun currentClockLayout_splitShadeOn_clockNotCentered_smallClock_splitShadeSmallClock() =
+ testScope.runTest {
+ with(kosmos) {
+ shadeRepository.setShadeMode(ShadeMode.Split)
+ keyguardRepository.setClockShouldBeCentered(false)
+ keyguardClockRepository.setClockSize(KeyguardClockSwitch.SMALL)
+ }
+ val currentClockLayout by collectLastValue(underTest.currentClockLayout)
+ assertThat(currentClockLayout)
+ .isEqualTo(KeyguardClockViewModel.ClockLayout.SPLIT_SHADE_SMALL_CLOCK)
+ }
+
+ @Test
+ fun currentClockLayout_singleShade_smallClock_smallClock() =
+ testScope.runTest {
+ with(kosmos) {
+ shadeRepository.setShadeMode(ShadeMode.Single)
+ keyguardClockRepository.setClockSize(KeyguardClockSwitch.SMALL)
+ }
+ val currentClockLayout by collectLastValue(underTest.currentClockLayout)
+ assertThat(currentClockLayout).isEqualTo(KeyguardClockViewModel.ClockLayout.SMALL_CLOCK)
+ }
+
+ @Test
+ fun currentClockLayout_singleShade_largeClock_largeClock() =
+ testScope.runTest {
+ with(kosmos) {
+ shadeRepository.setShadeMode(ShadeMode.Single)
+ keyguardClockRepository.setClockSize(KeyguardClockSwitch.LARGE)
+ }
+ val currentClockLayout by collectLastValue(underTest.currentClockLayout)
+ assertThat(currentClockLayout).isEqualTo(KeyguardClockViewModel.ClockLayout.LARGE_CLOCK)
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaHierarchyManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaHierarchyManagerTest.kt
index 29820f7a7249..5f7c3869fee7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaHierarchyManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaHierarchyManagerTest.kt
@@ -24,14 +24,13 @@ import android.view.ViewGroup
import android.widget.FrameLayout
import androidx.test.filters.SmallTest
import com.android.keyguard.KeyguardViewController
-import com.android.systemui.Flags
import com.android.systemui.SysuiTestCase
-import com.android.systemui.communal.domain.interactor.communalInteractor
-import com.android.systemui.communal.domain.interactor.setCommunalAvailable
-import com.android.systemui.communal.shared.model.CommunalScenes
+import com.android.systemui.communal.ui.viewmodel.communalTransitionViewModel
import com.android.systemui.controls.controller.ControlsControllerImplTest.Companion.eq
import com.android.systemui.dreams.DreamOverlayStateController
import com.android.systemui.keyguard.WakefulnessLifecycle
+import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
+import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.kosmos.testScope
import com.android.systemui.media.controls.domain.pipeline.MediaDataManager
import com.android.systemui.media.controls.ui.view.MediaCarouselScrollHandler
@@ -115,10 +114,10 @@ class MediaHierarchyManagerTest : SysuiTestCase() {
private lateinit var isQsBypassingShade: MutableStateFlow<Boolean>
private lateinit var mediaFrame: ViewGroup
private val configurationController = FakeConfigurationController()
- private val communalInteractor = kosmos.communalInteractor
private val settings = FakeSettings()
private lateinit var testableLooper: TestableLooper
private lateinit var fakeHandler: FakeHandler
+ private val keyguardTransitionRepository = kosmos.fakeKeyguardTransitionRepository
@Before
fun setup() {
@@ -142,7 +141,7 @@ class MediaHierarchyManagerTest : SysuiTestCase() {
mediaDataManager,
keyguardViewController,
dreamOverlayStateController,
- communalInteractor,
+ kosmos.communalTransitionViewModel,
configurationController,
wakefulnessLifecycle,
shadeInteractor,
@@ -510,12 +509,11 @@ class MediaHierarchyManagerTest : SysuiTestCase() {
@Test
fun testCommunalLocation() =
testScope.runTest {
- mSetFlagsRule.enableFlags(Flags.FLAG_COMMUNAL_HUB)
- kosmos.setCommunalAvailable(true)
- runCurrent()
-
- communalInteractor.onSceneChanged(CommunalScenes.Communal)
- runCurrent()
+ keyguardTransitionRepository.sendTransitionSteps(
+ from = KeyguardState.LOCKSCREEN,
+ to = KeyguardState.GLANCEABLE_HUB,
+ testScope = testScope,
+ )
verify(mediaCarouselController)
.onDesiredLocationChanged(
eq(MediaHierarchyManager.LOCATION_COMMUNAL_HUB),
@@ -526,8 +524,11 @@ class MediaHierarchyManagerTest : SysuiTestCase() {
)
clearInvocations(mediaCarouselController)
- communalInteractor.onSceneChanged(CommunalScenes.Blank)
- runCurrent()
+ keyguardTransitionRepository.sendTransitionSteps(
+ from = KeyguardState.GLANCEABLE_HUB,
+ to = KeyguardState.LOCKSCREEN,
+ testScope = testScope,
+ )
verify(mediaCarouselController)
.onDesiredLocationChanged(
eq(MediaHierarchyManager.LOCATION_QQS),
@@ -541,16 +542,15 @@ class MediaHierarchyManagerTest : SysuiTestCase() {
@Test
fun testCommunalLocation_showsOverLockscreen() =
testScope.runTest {
- mSetFlagsRule.enableFlags(Flags.FLAG_COMMUNAL_HUB)
- kosmos.setCommunalAvailable(true)
- runCurrent()
-
// Device is on lock screen.
whenever(statusBarStateController.state).thenReturn(StatusBarState.KEYGUARD)
- // UMO goes to communal even over the lock screen.
- communalInteractor.onSceneChanged(CommunalScenes.Communal)
- runCurrent()
+ // UMO goes to communal from the lock screen.
+ keyguardTransitionRepository.sendTransitionSteps(
+ from = KeyguardState.LOCKSCREEN,
+ to = KeyguardState.GLANCEABLE_HUB,
+ testScope = testScope,
+ )
verify(mediaCarouselController)
.onDesiredLocationChanged(
eq(MediaHierarchyManager.LOCATION_COMMUNAL_HUB),
@@ -564,15 +564,14 @@ class MediaHierarchyManagerTest : SysuiTestCase() {
@Test
fun testCommunalLocation_showsUntilQsExpands() =
testScope.runTest {
- mSetFlagsRule.enableFlags(Flags.FLAG_COMMUNAL_HUB)
- kosmos.setCommunalAvailable(true)
- runCurrent()
-
// Device is on lock screen.
whenever(statusBarStateController.state).thenReturn(StatusBarState.KEYGUARD)
- communalInteractor.onSceneChanged(CommunalScenes.Communal)
- runCurrent()
+ keyguardTransitionRepository.sendTransitionSteps(
+ from = KeyguardState.LOCKSCREEN,
+ to = KeyguardState.GLANCEABLE_HUB,
+ testScope = testScope,
+ )
verify(mediaCarouselController)
.onDesiredLocationChanged(
eq(MediaHierarchyManager.LOCATION_COMMUNAL_HUB),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/monet/ColorSchemeTest.kt b/packages/SystemUI/tests/src/com/android/systemui/monet/ColorSchemeTest.kt
new file mode 100644
index 000000000000..261e8c02eba6
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/monet/ColorSchemeTest.kt
@@ -0,0 +1,249 @@
+/*
+ * 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.monet
+
+import android.test.suitebuilder.annotation.SmallTest
+import android.testing.AndroidTestingRunner
+import android.util.Log
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.theme.DynamicColors
+import com.google.ux.material.libmonet.hct.Hct
+import com.google.ux.material.libmonet.scheme.SchemeTonalSpot
+import java.io.File
+import java.io.FileWriter
+import java.io.StringWriter
+import javax.xml.parsers.DocumentBuilderFactory
+import javax.xml.transform.OutputKeys
+import javax.xml.transform.TransformerException
+import javax.xml.transform.TransformerFactory
+import javax.xml.transform.dom.DOMSource
+import javax.xml.transform.stream.StreamResult
+import kotlin.math.abs
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.w3c.dom.Document
+import org.w3c.dom.Element
+import org.w3c.dom.Node
+
+private const val fileHeader =
+ """
+ ~ Copyright (C) 2022 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.
+"""
+
+private fun testName(name: String): String {
+ return "Auto generated by: atest ColorSchemeTest#$name"
+}
+
+private const val commentRoles =
+ "Colors used in Android system, from design system. These " +
+ "values can be overlaid at runtime by OverlayManager RROs."
+
+private const val commentOverlay = "This value can be overlaid at runtime by OverlayManager RROs."
+
+private fun commentWhite(paletteName: String): String {
+ return "Lightest shade of the $paletteName color used by the system. White. $commentOverlay"
+}
+
+private fun commentBlack(paletteName: String): String {
+ return "Darkest shade of the $paletteName color used by the system. Black. $commentOverlay"
+}
+
+private fun commentShade(paletteName: String, tone: Int): String {
+ return "Shade of the $paletteName system color at $tone% perceptual luminance (L* in L*a*b* " +
+ "color space). $commentOverlay"
+}
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class ColorSchemeTest : SysuiTestCase() {
+ @Test
+ fun generateThemeStyles() {
+ val document = buildDoc<Any>()
+
+ val themes = document.createElement("themes")
+ document.appendWithBreak(themes)
+
+ var hue = 0.0
+ while (hue < 360) {
+ val sourceColor = Hct.from(hue, 50.0, 50.0)
+ val sourceColorHex = sourceColor.toInt().toRGBHex()
+
+ val theme = document.createElement("theme")
+ theme.setAttribute("color", sourceColorHex)
+ themes.appendChild(theme)
+
+ for (styleValue in Style.entries) {
+ if (
+ styleValue == Style.CLOCK ||
+ styleValue == Style.CLOCK_VIBRANT ||
+ styleValue == Style.CONTENT
+ ) {
+ continue
+ }
+
+ val style = document.createElement(styleValue.name.lowercase())
+ val colorScheme = ColorScheme(sourceColor.toInt(), false, styleValue)
+
+ style.appendChild(
+ document.createTextNode(
+ listOf(
+ colorScheme.accent1,
+ colorScheme.accent2,
+ colorScheme.accent3,
+ colorScheme.neutral1,
+ colorScheme.neutral2
+ )
+ .flatMap { a -> listOf(*a.allShades.toTypedArray()) }
+ .joinToString(",", transform = Int::toRGBHex)
+ )
+ )
+ theme.appendChild(style)
+ }
+
+ hue += 60
+ }
+
+ saveFile(document, "current_themes.xml")
+ }
+
+ @Test
+ fun generateDefaultValues() {
+ val document = buildDoc<Any>()
+
+ val resources = document.createElement("resources")
+ document.appendWithBreak(resources)
+
+ // shade colors
+ val colorScheme = ColorScheme(GOOGLE_BLUE, false)
+ arrayOf(
+ Triple("accent1", "Primary", colorScheme.accent1),
+ Triple("accent2", "Secondary", colorScheme.accent2),
+ Triple("accent3", "Tertiary", colorScheme.accent3),
+ Triple("neutral1", "Neutral", colorScheme.neutral1),
+ Triple("neutral2", "Secondary Neutral", colorScheme.neutral2)
+ )
+ .forEach {
+ val (paletteName, readable, palette) = it
+ palette.allShadesMapped.entries.forEachIndexed { index, (shade, colorValue) ->
+ val comment =
+ when (index) {
+ 0 -> commentWhite(readable)
+ palette.allShadesMapped.entries.size - 1 -> commentBlack(readable)
+ else -> commentShade(readable, abs(shade / 10 - 100))
+ }
+ resources.createColorEntry("system_${paletteName}_$shade", colorValue, comment)
+ }
+ }
+
+ resources.appendWithBreak(document.createComment(commentRoles), 2)
+
+ // dynamic colors
+ arrayOf(false, true).forEach { isDark ->
+ val suffix = if (isDark) "_dark" else "_light"
+ val dynamicScheme = SchemeTonalSpot(Hct.fromInt(GOOGLE_BLUE), isDark, 0.5)
+ DynamicColors.allDynamicColorsMapped(false).forEach {
+ resources.createColorEntry(
+ "system_${it.first}$suffix",
+ it.second.getArgb(dynamicScheme)
+ )
+ }
+ }
+
+ // fixed colors
+ val dynamicScheme = SchemeTonalSpot(Hct.fromInt(GOOGLE_BLUE), false, 0.5)
+ DynamicColors.getFixedColorsMapped(false).forEach {
+ resources.createColorEntry("system_${it.first}", it.second.getArgb(dynamicScheme))
+ }
+
+ saveFile(document, "role_values.xml")
+ }
+
+ // Helper Functions
+
+ private inline fun <reified T> buildDoc(): Document {
+ val functionName = T::class.simpleName + ""
+ val factory = DocumentBuilderFactory.newInstance()
+ val builder = factory.newDocumentBuilder()
+ val document = builder.newDocument()
+
+ document.appendWithBreak(document.createComment(fileHeader))
+ document.appendWithBreak(document.createComment(testName(functionName)))
+
+ return document
+ }
+
+ private fun documentToString(document: Document): String {
+ try {
+ val transformerFactory = TransformerFactory.newInstance()
+ val transformer = transformerFactory.newTransformer()
+ transformer.setOutputProperty(OutputKeys.MEDIA_TYPE, "application/xml")
+ transformer.setOutputProperty(OutputKeys.METHOD, "xml")
+ transformer.setOutputProperty(OutputKeys.INDENT, "yes")
+ transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4")
+
+ val stringWriter = StringWriter()
+ transformer.transform(DOMSource(document), StreamResult(stringWriter))
+ return stringWriter.toString()
+ } catch (e: TransformerException) {
+ throw RuntimeException("Error transforming XML", e)
+ }
+ }
+
+ private fun saveFile(document: Document, fileName: String) {
+ val outPath = context.filesDir.path + "/" + fileName
+ Log.d("ColorSchemeXml", "Artifact $fileName created")
+ val writer = FileWriter(File(outPath))
+ writer.write(documentToString(document))
+ writer.close()
+ }
+}
+
+private fun Element.createColorEntry(name: String, value: Int, comment: String? = null) {
+ val doc = this.ownerDocument
+
+ if (comment != null) {
+ this.appendChild(doc.createComment(comment))
+ }
+
+ val color = doc.createElement("color")
+ this.appendChild(color)
+
+ color.setAttribute("name", name)
+ color.appendChild(doc.createTextNode("#" + value.toRGBHex()))
+}
+
+private fun Node.appendWithBreak(child: Node, lineBreaks: Int = 1): Node {
+ val doc = if (this is Document) this else this.ownerDocument
+ val node = doc.createTextNode("\n".repeat(lineBreaks))
+ this.appendChild(node)
+ return this.appendChild(child)
+}
+
+private fun Int.toRGBHex(): String {
+ return "%06X".format(0xFFFFFF and this)
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java
index d1d9efc10ea7..a63b2211f71a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java
@@ -101,12 +101,11 @@ import android.text.TextUtils;
import androidx.preference.PreferenceManager;
import androidx.test.filters.SmallTest;
+import com.android.systemui.res.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.people.PeopleBackupFollowUpJob;
import com.android.systemui.people.PeopleSpaceUtils;
import com.android.systemui.people.SharedPreferencesHelper;
-import com.android.systemui.res.R;
-import com.android.systemui.settings.FakeUserTracker;
import com.android.systemui.statusbar.NotificationListener;
import com.android.systemui.statusbar.NotificationListener.NotificationHandler;
import com.android.systemui.statusbar.SbnBuilder;
@@ -266,8 +265,6 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
private final FakeExecutor mFakeExecutor = new FakeExecutor(mClock);
- private final FakeUserTracker mUserTracker = new FakeUserTracker();
-
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
@@ -275,7 +272,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
mManager = new PeopleSpaceWidgetManager(mContext, mAppWidgetManager, mIPeopleManager,
mPeopleManager, mLauncherApps, mNotifCollection, mPackageManager,
Optional.of(mBubbles), mUserManager, mBackupManager, mINotificationManager,
- mNotificationManager, mFakeExecutor, mUserTracker);
+ mNotificationManager, mFakeExecutor);
mManager.attach(mListenerService);
verify(mListenerService).addNotificationHandler(mListenerCaptor.capture());
@@ -1565,43 +1562,6 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
String.valueOf(WIDGET_ID_WITH_KEY_IN_OPTIONS));
}
- @Test
- public void testUpdateGeneratedPreview_flagDisabled() {
- mSetFlagsRule.disableFlags(android.appwidget.flags.Flags.FLAG_GENERATED_PREVIEWS);
- mManager.updateGeneratedPreviewForUser(mUserTracker.getUserHandle());
- verify(mAppWidgetManager, times(0)).setWidgetPreview(any(), anyInt(), any());
- }
-
- @Test
- public void testUpdateGeneratedPreview_userLocked() {
- mSetFlagsRule.enableFlags(android.appwidget.flags.Flags.FLAG_GENERATED_PREVIEWS);
- when(mUserManager.isUserUnlocked(mUserTracker.getUserHandle())).thenReturn(false);
-
- mManager.updateGeneratedPreviewForUser(mUserTracker.getUserHandle());
- verify(mAppWidgetManager, times(0)).setWidgetPreview(any(), anyInt(), any());
- }
-
- @Test
- public void testUpdateGeneratedPreview_userUnlocked() {
- mSetFlagsRule.enableFlags(android.appwidget.flags.Flags.FLAG_GENERATED_PREVIEWS);
- when(mUserManager.isUserUnlocked(mUserTracker.getUserHandle())).thenReturn(true);
- when(mAppWidgetManager.setWidgetPreview(any(), anyInt(), any())).thenReturn(true);
-
- mManager.updateGeneratedPreviewForUser(mUserTracker.getUserHandle());
- verify(mAppWidgetManager, times(1)).setWidgetPreview(any(), anyInt(), any());
- }
-
- @Test
- public void testUpdateGeneratedPreview_doesNotSetTwice() {
- mSetFlagsRule.enableFlags(android.appwidget.flags.Flags.FLAG_GENERATED_PREVIEWS);
- when(mUserManager.isUserUnlocked(mUserTracker.getUserHandle())).thenReturn(true);
- when(mAppWidgetManager.setWidgetPreview(any(), anyInt(), any())).thenReturn(true);
-
- mManager.updateGeneratedPreviewForUser(mUserTracker.getUserHandle());
- mManager.updateGeneratedPreviewForUser(mUserTracker.getUserHandle());
- verify(mAppWidgetManager, times(1)).setWidgetPreview(any(), anyInt(), any());
- }
-
private void setFinalField(String fieldName, int value) {
try {
Field field = NotificationManager.Policy.class.getDeclaredField(fieldName);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotifBindPipelineTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotifBindPipelineTest.java
index 6faebf6ce335..25172deb67a7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotifBindPipelineTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotifBindPipelineTest.java
@@ -34,6 +34,8 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
import com.android.systemui.statusbar.notification.row.NotifBindPipeline.BindCallback;
+import com.android.systemui.util.concurrency.FakeExecutor;
+import com.android.systemui.util.time.FakeSystemClock;
import org.junit.Before;
import org.junit.Test;
@@ -51,7 +53,8 @@ import java.util.List;
public class NotifBindPipelineTest extends SysuiTestCase {
private NotifBindPipeline mBindPipeline;
- private TestBindStage mStage = new TestBindStage();
+ private final TestBindStage mStage = new TestBindStage();
+ private final FakeExecutor mFakeExecutor = new FakeExecutor(new FakeSystemClock());
@Mock private NotificationEntry mEntry;
@Mock private ExpandableNotificationRow mRow;
@@ -64,7 +67,7 @@ public class NotifBindPipelineTest extends SysuiTestCase {
mBindPipeline = new NotifBindPipeline(
collection,
new NotifBindPipelineLogger(logcatLogBuffer()),
- TestableLooper.get(this).getLooper());
+ new NotificationEntryProcessorFactoryExecutorImpl(mFakeExecutor));
mBindPipeline.setStage(mStage);
ArgumentCaptor<NotifCollectionListener> collectionListenerCaptor =
@@ -83,7 +86,7 @@ public class NotifBindPipelineTest extends SysuiTestCase {
// WHEN content is invalidated
BindCallback callback = mock(BindCallback.class);
mStage.requestRebind(mEntry, callback);
- TestableLooper.get(this).processAllMessages();
+ mFakeExecutor.runAllReady();
// WHEN stage finishes its work
mStage.doWorkSynchronously();
@@ -100,7 +103,7 @@ public class NotifBindPipelineTest extends SysuiTestCase {
// GIVEN an in-progress pipeline run
BindCallback callback = mock(BindCallback.class);
CancellationSignal signal = mStage.requestRebind(mEntry, callback);
- TestableLooper.get(this).processAllMessages();
+ mFakeExecutor.runAllReady();
// WHEN the callback is cancelled.
signal.cancel();
@@ -120,12 +123,12 @@ public class NotifBindPipelineTest extends SysuiTestCase {
// WHEN the pipeline is invalidated.
BindCallback callback = mock(BindCallback.class);
mStage.requestRebind(mEntry, callback);
- TestableLooper.get(this).processAllMessages();
+ mFakeExecutor.runAllReady();
// WHEN the pipeline is invalidated again before the work completes.
BindCallback callback2 = mock(BindCallback.class);
mStage.requestRebind(mEntry, callback2);
- TestableLooper.get(this).processAllMessages();
+ mFakeExecutor.runAllReady();
// WHEN the stage finishes all work.
mStage.doWorkSynchronously();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
index 3b78b7e492f5..09a3eb480a49 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
@@ -23,6 +23,7 @@ import static android.app.NotificationManager.IMPORTANCE_HIGH;
import static com.android.systemui.log.LogBufferHelperKt.logcatLogBuffer;
import static com.android.systemui.statusbar.NotificationEntryHelper.modifyRanking;
+import static com.android.systemui.util.Assert.runWithCurrentThreadAsMainThread;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@@ -42,6 +43,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.pm.LauncherApps;
import android.graphics.drawable.Icon;
+import android.os.Looper;
import android.os.UserHandle;
import android.service.notification.StatusBarNotification;
import android.testing.TestableLooper;
@@ -90,6 +92,8 @@ import com.android.systemui.statusbar.policy.InflatedSmartReplyViewHolder;
import com.android.systemui.statusbar.policy.SmartReplyConstants;
import com.android.systemui.statusbar.policy.SmartReplyStateInflater;
import com.android.systemui.statusbar.policy.dagger.RemoteInputViewSubcomponent;
+import com.android.systemui.util.concurrency.FakeExecutor;
+import com.android.systemui.util.time.FakeSystemClock;
import com.android.systemui.util.time.SystemClock;
import com.android.systemui.util.time.SystemClockImpl;
import com.android.systemui.wmshell.BubblesManager;
@@ -123,7 +127,7 @@ public class NotificationTestHelper {
private static final String APP_NAME = "appName";
private final Context mContext;
- private final TestableLooper mTestLooper;
+ private final Runnable mBindPipelineAdvancement;
private int mId;
private final ExpandableNotificationRowLogger mMockLogger;
private final GroupMembershipManager mGroupMembershipManager;
@@ -151,18 +155,23 @@ public class NotificationTestHelper {
public NotificationTestHelper(
Context context,
+ TestableDependency dependency) {
+ this(context, dependency, null);
+ }
+
+ public NotificationTestHelper(
+ Context context,
TestableDependency dependency,
- TestableLooper testLooper) {
+ @Nullable TestableLooper testLooper) {
this(context, dependency, testLooper, new FakeFeatureFlags());
}
public NotificationTestHelper(
Context context,
TestableDependency dependency,
- TestableLooper testLooper,
+ @Nullable TestableLooper testLooper,
@NonNull FakeFeatureFlags featureFlags) {
mContext = context;
- mTestLooper = testLooper;
mFeatureFlags = Objects.requireNonNull(featureFlags);
dependency.injectTestDependency(FeatureFlags.class, mFeatureFlags);
dependency.injectMockDependency(NotificationMediaManager.class);
@@ -198,10 +207,27 @@ public class NotificationTestHelper {
CommonNotifCollection collection = mock(CommonNotifCollection.class);
+ // NOTE: This helper supports using either a TestableLooper or its own private FakeExecutor.
+ final Runnable processorAdvancement;
+ final NotificationEntryProcessorFactory processorFactory;
+ if (testLooper == null) {
+ FakeExecutor fakeExecutor = new FakeExecutor(new FakeSystemClock());
+ processorAdvancement = () -> {
+ runWithCurrentThreadAsMainThread(fakeExecutor::runAllReady);
+ };
+ processorFactory = new NotificationEntryProcessorFactoryExecutorImpl(fakeExecutor);
+ } else {
+ Looper looper = testLooper.getLooper();
+ processorAdvancement = () -> {
+ runWithCurrentThreadAsMainThread(testLooper::processAllMessages);
+ };
+ processorFactory = new NotificationEntryProcessorFactoryLooperImpl(looper);
+ }
+ mBindPipelineAdvancement = processorAdvancement;
mBindPipeline = new NotifBindPipeline(
collection,
new NotifBindPipelineLogger(logcatLogBuffer()),
- mTestLooper.getLooper());
+ processorFactory);
mBindPipeline.setStage(mBindStage);
ArgumentCaptor<NotifCollectionListener> collectionListenerCaptor =
@@ -643,7 +669,7 @@ public class NotificationTestHelper {
private void inflateAndWait(NotificationEntry entry) throws Exception {
CountDownLatch countDownLatch = new CountDownLatch(1);
mBindStage.requestRebind(entry, en -> countDownLatch.countDown());
- mTestLooper.processAllMessages();
+ mBindPipelineAdvancement.run();
assertTrue(countDownLatch.await(500, TimeUnit.MILLISECONDS));
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyConstantsTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyConstantsTest.java
index 3555a7415435..dc0d07cab92d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyConstantsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyConstantsTest.java
@@ -32,6 +32,8 @@ import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
import com.android.systemui.res.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.util.DeviceConfigProxyFake;
+import com.android.systemui.util.concurrency.FakeExecutor;
+import com.android.systemui.util.time.FakeSystemClock;
import org.junit.Before;
import org.junit.Test;
@@ -43,7 +45,8 @@ import org.junit.runner.RunWith;
public class SmartReplyConstantsTest extends SysuiTestCase {
private SmartReplyConstants mConstants;
private DeviceConfigProxyFake mDeviceConfig;
- private TestableLooper mTestableLooper;
+ private final FakeSystemClock mFakeSystemClock = new FakeSystemClock();
+ private final FakeExecutor mFakeExecutor = new FakeExecutor(mFakeSystemClock);
@Before
public void setUp() {
@@ -60,9 +63,8 @@ public class SmartReplyConstantsTest extends SysuiTestCase {
2);
resources.addOverride(
R.integer.config_smart_replies_in_notifications_max_num_actions, -1);
- mTestableLooper = TestableLooper.get(this);
mConstants = new SmartReplyConstants(
- new Handler(mTestableLooper.getLooper()),
+ mFakeExecutor,
mContext,
mDeviceConfig
);
@@ -210,6 +212,6 @@ public class SmartReplyConstantsTest extends SysuiTestCase {
private void overrideSetting(String propertyName, String value) {
mDeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
propertyName, value, false /* makeDefault */);
- mTestableLooper.processAllMessages();
+ mFakeExecutor.runAllReady();
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java
index ab28a2fc830f..ed7c9568a9db 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java
@@ -985,7 +985,7 @@ public class ThemeOverlayControllerTest extends SysuiTestCase {
FabricatedOverlay neutrals = overlays[1];
FabricatedOverlay dynamic = overlays[2];
- final int colorsPerPalette = 12;
+ final int colorsPerPalette = 13;
// Color resources were added for all 3 accent palettes
verify(accents, times(colorsPerPalette * 3))
diff --git a/packages/SystemUI/tests/utils/src/android/animation/AnimatorTestRule.java b/packages/SystemUI/tests/utils/src/android/animation/AnimatorTestRule.java
index 5860c2dd4cdc..3b39e1fc6bc7 100644
--- a/packages/SystemUI/tests/utils/src/android/animation/AnimatorTestRule.java
+++ b/packages/SystemUI/tests/utils/src/android/animation/AnimatorTestRule.java
@@ -16,8 +16,6 @@
package android.animation;
-import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
-
import android.animation.AnimationHandler.AnimationFrameCallback;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -34,6 +32,7 @@ import androidx.test.platform.app.InstrumentationRegistry;
import com.android.internal.util.Preconditions;
+import org.junit.AssumptionViolatedException;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
@@ -204,7 +203,8 @@ public final class AnimatorTestRule implements TestRule {
}
long outputTime = AnimationUtils.currentAnimationTimeMillis();
if (outputTime != desiredTime) {
- throw new AssertionError("currentAnimationTimeMillis() is " + outputTime
+ // Skip the test (rather than fail it) if there's a clock issue
+ throw new AssumptionViolatedException("currentAnimationTimeMillis() is " + outputTime
+ " after locking to " + desiredTime);
}
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/ui/viewmodel/CommunalTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/ui/viewmodel/CommunalTransitionViewModelKosmos.kt
new file mode 100644
index 000000000000..23967224e43a
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/ui/viewmodel/CommunalTransitionViewModelKosmos.kt
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2024 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.communal.ui.viewmodel
+
+import com.android.systemui.keyguard.ui.viewmodel.dreamingToGlanceableHubTransitionViewModel
+import com.android.systemui.keyguard.ui.viewmodel.glanceableHubToDreamingTransitionViewModel
+import com.android.systemui.keyguard.ui.viewmodel.glanceableHubToLockscreenTransitionViewModel
+import com.android.systemui.keyguard.ui.viewmodel.lockscreenToGlanceableHubTransitionViewModel
+import com.android.systemui.kosmos.Kosmos
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+
+@OptIn(ExperimentalCoroutinesApi::class)
+val Kosmos.communalTransitionViewModel by
+ Kosmos.Fixture {
+ CommunalTransitionViewModel(
+ glanceableHubToLockscreenTransitionViewModel,
+ lockscreenToGlanceableHubTransitionViewModel,
+ dreamingToGlanceableHubTransitionViewModel,
+ glanceableHubToDreamingTransitionViewModel,
+ )
+ }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/flags/EnableSceneContainer.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/flags/EnableSceneContainer.kt
index cceb3ffab282..f65c74fcebc8 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/flags/EnableSceneContainer.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/flags/EnableSceneContainer.kt
@@ -19,6 +19,7 @@ package com.android.systemui.flags
import android.platform.test.annotations.EnableFlags
import com.android.systemui.Flags.FLAG_COMPOSE_LOCKSCREEN
import com.android.systemui.Flags.FLAG_KEYGUARD_BOTTOM_AREA_REFACTOR
+import com.android.systemui.Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR
import com.android.systemui.Flags.FLAG_MEDIA_IN_SCENE_CONTAINER
import com.android.systemui.Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT
import com.android.systemui.Flags.FLAG_SCENE_CONTAINER
@@ -33,6 +34,7 @@ import com.android.systemui.Flags.FLAG_SCENE_CONTAINER
FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT,
FLAG_COMPOSE_LOCKSCREEN,
FLAG_MEDIA_IN_SCENE_CONTAINER,
+ FLAG_KEYGUARD_WM_STATE_REFACTOR,
)
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CLASS)
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorKosmos.kt
index d84988da7cc3..29167d64d1f1 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorKosmos.kt
@@ -27,6 +27,7 @@ val Kosmos.windowManagerLockscreenVisibilityInteractor by
surfaceBehindInteractor = keyguardSurfaceBehindInteractor,
fromLockscreenInteractor = fromLockscreenTransitionInteractor,
fromBouncerInteractor = fromPrimaryBouncerTransitionInteractor,
+ fromAlternateBouncerInteractor = fromAlternateBouncerTransitionInteractor,
notificationLaunchAnimationInteractor = notificationLaunchAnimationInteractor,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelKosmos.kt
index 4a85909ae996..60dd48aeaf61 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelKosmos.kt
@@ -20,8 +20,8 @@ import com.android.systemui.keyguard.domain.interactor.keyguardClockInteractor
import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.shade.domain.interactor.shadeInteractor
import com.android.systemui.statusbar.notification.stack.domain.interactor.notificationsKeyguardInteractor
-import com.android.systemui.statusbar.policy.splitShadeStateController
val Kosmos.keyguardClockViewModel by
Kosmos.Fixture {
@@ -29,7 +29,7 @@ val Kosmos.keyguardClockViewModel by
keyguardInteractor = keyguardInteractor,
keyguardClockInteractor = keyguardClockInteractor,
applicationScope = applicationCoroutineScope,
- splitShadeStateController = splitShadeStateController,
notifsKeyguardInteractor = notificationsKeyguardInteractor,
+ shadeInteractor = shadeInteractor,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModelKosmos.kt
index 8da5dd46b62a..f0fedd2ed479 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModelKosmos.kt
@@ -20,7 +20,7 @@ import com.android.systemui.biometrics.authController
import com.android.systemui.keyguard.domain.interactor.keyguardBlueprintInteractor
import com.android.systemui.keyguard.domain.interactor.keyguardClockInteractor
import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.statusbar.policy.splitShadeStateController
+import com.android.systemui.shade.domain.interactor.shadeInteractor
val Kosmos.lockscreenContentViewModel by
Kosmos.Fixture {
@@ -29,6 +29,6 @@ val Kosmos.lockscreenContentViewModel by
interactor = keyguardBlueprintInteractor,
authController = authController,
longPress = keyguardLongPressViewModel,
- splitShadeStateController = splitShadeStateController,
+ shadeInteractor = shadeInteractor,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/domain/interactor/KeyguardViewOcclusionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/domain/interactor/StatusBarKeyguardViewManagerInteractorKosmos.kt
index 9e34fe8d7c61..2ed56ce0bf24 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/domain/interactor/KeyguardViewOcclusionInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/domain/interactor/StatusBarKeyguardViewManagerInteractorKosmos.kt
@@ -16,7 +16,9 @@
package com.android.systemui.statusbar.domain.interactor
+import com.android.systemui.keyguard.domain.interactor.keyguardSurfaceBehindInteractor
import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
+import com.android.systemui.keyguard.domain.interactor.windowManagerLockscreenVisibilityInteractor
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.power.domain.interactor.powerInteractor
@@ -26,5 +28,7 @@ val Kosmos.statusBarKeyguardViewManagerInteractor by
keyguardTransitionInteractor = this.keyguardTransitionInteractor,
keyguardOcclusionInteractor = this.keyguardOcclusionInteractor,
powerInteractor = this.powerInteractor,
+ wmLockscreenVisibilityInteractor = windowManagerLockscreenVisibilityInteractor,
+ surfaceBehindInteractor = keyguardSurfaceBehindInteractor,
)
}
diff --git a/services/Android.bp b/services/Android.bp
index 87096928af7c..98a7979de30a 100644
--- a/services/Android.bp
+++ b/services/Android.bp
@@ -119,6 +119,7 @@ filegroup {
":services.companion-sources",
":services.contentcapture-sources",
":services.contentsuggestions-sources",
+ ":services.contextualsearch-sources",
":services.coverage-sources",
":services.credentials-sources",
":services.devicepolicy-sources",
@@ -208,6 +209,7 @@ java_library {
"services.companion",
"services.contentcapture",
"services.contentsuggestions",
+ "services.contextualsearch",
"services.coverage",
"services.credentials",
"services.devicepolicy",
diff --git a/services/accessibility/java/com/android/server/accessibility/ProxyAccessibilityServiceConnection.java b/services/accessibility/java/com/android/server/accessibility/ProxyAccessibilityServiceConnection.java
index 6aa4702ec7d5..b77b2bef57a2 100644
--- a/services/accessibility/java/com/android/server/accessibility/ProxyAccessibilityServiceConnection.java
+++ b/services/accessibility/java/com/android/server/accessibility/ProxyAccessibilityServiceConnection.java
@@ -126,7 +126,7 @@ public class ProxyAccessibilityServiceConnection extends AccessibilityServiceCon
* @param infos the list of enabled and installed services.
*/
@Override
- public void setInstalledAndEnabledServices(List<AccessibilityServiceInfo> infos) {
+ public void setInstalledAndEnabledServices(@NonNull List<AccessibilityServiceInfo> infos) {
final long identity = Binder.clearCallingIdentity();
try {
synchronized (mLock) {
@@ -216,9 +216,11 @@ public class ProxyAccessibilityServiceConnection extends AccessibilityServiceCon
}
@Override
+ @NonNull
public List<AccessibilityServiceInfo> getInstalledAndEnabledServices() {
synchronized (mLock) {
- return mInstalledAndEnabledServices;
+ return mInstalledAndEnabledServices != null
+ ? mInstalledAndEnabledServices : Collections.emptyList();
}
}
diff --git a/services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java b/services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java
index 1f8736b770e2..c3d97904e430 100644
--- a/services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java
+++ b/services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java
@@ -99,6 +99,9 @@ public class PackageManagerBackupAgent extends BackupAgent {
// The version info of each backed-up app as read from the state file
private HashMap<String, Metadata> mStateVersions = new HashMap<String, Metadata>();
+ // The ancestral record version as read from the state file
+ private int mStoredAncestralRecordVersion;
+
private final HashSet<String> mExisting = new HashSet<String>();
private int mStoredSdkVersion;
private String mStoredIncrementalVersion;
@@ -233,17 +236,32 @@ public class PackageManagerBackupAgent extends BackupAgent {
* int ancestralRecordVersion -- the version of the format in which this backup set is
* produced
*/
+ boolean upgradingAncestralRecordVersion = false;
try {
- if (DEBUG) Slog.v(TAG, "Storing ancestral record version key");
- outputBufferStream.writeInt(ANCESTRAL_RECORD_VERSION);
- writeEntity(data, ANCESTRAL_RECORD_KEY, outputBuffer.toByteArray());
- } catch (IOException e) {
- // Real error writing data
- Slog.e(TAG, "Unable to write package backup data file!");
- return;
- }
+ if (!mExisting.contains(ANCESTRAL_RECORD_KEY)) {
+ // The old state does not store info on ancestral record
+ Slog.v(
+ TAG,
+ "No ancestral record version in the old state. Storing "
+ + "ancestral record version key");
+ outputBufferStream.writeInt(ANCESTRAL_RECORD_VERSION);
+ writeEntity(data, ANCESTRAL_RECORD_KEY, outputBuffer.toByteArray());
+ upgradingAncestralRecordVersion = true;
+ } else if (mStoredAncestralRecordVersion != ANCESTRAL_RECORD_VERSION) {
+ // The current ancestral record version has changed from the old state
+ Slog.v(
+ TAG,
+ "Ancestral record version has changed from old state. Storing"
+ + "ancestral record version key");
+ outputBufferStream.writeInt(ANCESTRAL_RECORD_VERSION);
+ writeEntity(data, ANCESTRAL_RECORD_KEY, outputBuffer.toByteArray());
+ upgradingAncestralRecordVersion = true;
+ mExisting.remove(ANCESTRAL_RECORD_KEY);
+ } else {
+ if (DEBUG) Slog.v(TAG, "Ancestral record version has not changed");
+ mExisting.remove(ANCESTRAL_RECORD_KEY);
+ }
- try {
/*
* Global metadata:
*
@@ -286,13 +304,16 @@ public class PackageManagerBackupAgent extends BackupAgent {
}
if (mExisting.contains(packName)) {
- // We have backed up this app before. Check whether the version
- // of the backup matches the version of the current app; if they
+ // We have backed up this app before. If the current ancestral record
+ // version is the same as what is in the old state, check whether the
+ // version of the backup matches the version of the current app; if they
// don't match, the app has been updated and we need to store its
// metadata again. In either case, take it out of mExisting so that
// we don't consider it deleted later.
mExisting.remove(packName);
- if (info.getLongVersionCode() == mStateVersions.get(packName).versionCode) {
+ if (!upgradingAncestralRecordVersion
+ && info.getLongVersionCode()
+ == mStateVersions.get(packName).versionCode) {
continue;
}
}
@@ -346,18 +367,35 @@ public class PackageManagerBackupAgent extends BackupAgent {
// At this point, the only entries in 'existing' are apps that were
// mentioned in the saved state file, but appear to no longer be present
- // on the device. We want to preserve the entry for them, however,
- // because we want the right thing to happen if the user goes through
- // a backup / uninstall / backup / reinstall sequence.
- if (DEBUG) {
- if (mExisting.size() > 0) {
- StringBuilder sb = new StringBuilder(64);
- sb.append("Preserving metadata for deleted packages:");
- for (String app : mExisting) {
- sb.append(' ');
- sb.append(app);
+ // on the device.
+ if (!mExisting.isEmpty()) {
+ // If the ancestral record version has changed from the previous state we delete the
+ // existing keys for apps that are no longer installed. We should do this, otherwise
+ // we'd leave a key/value pair behind in the old format which could cause problems.
+ if (upgradingAncestralRecordVersion) {
+ for (String pkgName : mExisting) {
+ Slog.i(
+ TAG,
+ "Ancestral state updated - Deleting uninstalled package: "
+ + pkgName
+ + " from existing backup");
+ data.writeEntityHeader(pkgName, -1);
+ }
+ mExisting.clear();
+ } else {
+ // If the ancestral record version is unchanged from the previous state, we
+ // don't to anything to preserve the key/value entry for them. We do this
+ // because we want the right thing to happen if the user goes through a
+ // backup / uninstall / backup / reinstall sequence.
+ if (DEBUG) {
+ StringBuilder sb = new StringBuilder(64);
+ sb.append("Preserving metadata for deleted packages:");
+ for (String app : mExisting) {
+ sb.append(' ');
+ sb.append(app);
+ }
+ Slog.v(TAG, sb.toString());
}
- Slog.v(TAG, sb.toString());
}
}
} catch (IOException e) {
@@ -506,6 +544,7 @@ public class PackageManagerBackupAgent extends BackupAgent {
mStoredHomeComponent = null;
mStoredHomeVersion = 0;
mStoredHomeSigHashes = null;
+ mStoredAncestralRecordVersion = UNDEFINED_ANCESTRAL_RECORD_VERSION;
// The state file is just the list of app names we have stored signatures for
// with the exception of the metadata block, to which is also appended the
@@ -541,7 +580,25 @@ public class PackageManagerBackupAgent extends BackupAgent {
ignoreExisting = true;
}
- // First comes the preferred home app data, if any, headed by the DEFAULT_HOME_KEY tag
+ // First comes the ancestral record block headed by the ANCESTRAL_RECORD_KEY tag
+ if (pkg.equals(ANCESTRAL_RECORD_KEY)) {
+ mStoredAncestralRecordVersion = in.readInt();
+ if (!ignoreExisting) {
+ mExisting.add(ANCESTRAL_RECORD_KEY);
+ }
+ pkg = in.readUTF(); // set up for the next block of state
+ } else {
+ // This is an old version of the state file in which ANCESTRAL_RECORD_KEY is not
+ // stored. In this case onBackup will write the ANCESTRAL_KEY_VALUE to the new
+ // state.
+ Slog.i(
+ TAG,
+ "Older version of saved state - does not contain ancestral record "
+ + "version");
+ }
+
+ // Then comes the preferred home app data, if any, headed by the DEFAULT_HOME_KEY tag
+ // Note that Default home app data is no longer backed up by this agent.
if (pkg.equals(DEFAULT_HOME_KEY)) {
// flattened component name, version, signature of the home app
mStoredHomeComponent = ComponentName.unflattenFromString(in.readUTF());
@@ -606,6 +663,10 @@ public class PackageManagerBackupAgent extends BackupAgent {
out.writeUTF(STATE_FILE_HEADER);
out.writeInt(STATE_FILE_VERSION);
+ // Record the ancestral record
+ out.writeUTF(ANCESTRAL_RECORD_KEY);
+ out.writeInt(ANCESTRAL_RECORD_VERSION);
+
// Conclude with the metadata block
out.writeUTF(GLOBAL_METADATA_KEY);
out.writeInt(Build.VERSION.SDK_INT);
diff --git a/services/companion/java/com/android/server/companion/association/AssociationStore.java b/services/companion/java/com/android/server/companion/association/AssociationStore.java
index 29de764c4d5f..edebb55233d0 100644
--- a/services/companion/java/com/android/server/companion/association/AssociationStore.java
+++ b/services/companion/java/com/android/server/companion/association/AssociationStore.java
@@ -216,7 +216,9 @@ public class AssociationStore {
logCreateAssociation(association.getDeviceProfile());
- broadcastChange(CHANGE_TYPE_ADDED, association);
+ if (association.isActive()) {
+ broadcastChange(CHANGE_TYPE_ADDED, association);
+ }
}
/**
@@ -248,15 +250,20 @@ public class AssociationStore {
Slog.i(TAG, "Done updating association.");
- // Check if the MacAddress has changed.
- final MacAddress updatedAddress = updated.getDeviceMacAddress();
- final MacAddress currentAddress = current.getDeviceMacAddress();
- macAddressChanged = !Objects.equals(currentAddress, updatedAddress);
+ if (current.isActive() && !updated.isActive()) {
+ broadcastChange(CHANGE_TYPE_REMOVED, updated);
+ return;
+ }
- final int changeType = macAddressChanged ? CHANGE_TYPE_UPDATED_ADDRESS_CHANGED
- : CHANGE_TYPE_UPDATED_ADDRESS_UNCHANGED;
+ if (updated.isActive()) {
+ // Check if the MacAddress has changed.
+ final MacAddress updatedAddress = updated.getDeviceMacAddress();
+ final MacAddress currentAddress = current.getDeviceMacAddress();
+ macAddressChanged = !Objects.equals(currentAddress, updatedAddress);
- broadcastChange(changeType, updated);
+ broadcastChange(macAddressChanged ? CHANGE_TYPE_UPDATED_ADDRESS_CHANGED
+ : CHANGE_TYPE_UPDATED_ADDRESS_UNCHANGED, updated);
+ }
}
/**
@@ -282,7 +289,9 @@ public class AssociationStore {
logRemoveAssociation(association.getDeviceProfile());
- broadcastChange(CHANGE_TYPE_REMOVED, association);
+ if (association.isActive()) {
+ broadcastChange(CHANGE_TYPE_REMOVED, association);
+ }
}
private void writeCacheToDisk(@UserIdInt int userId) {
@@ -492,6 +501,8 @@ public class AssociationStore {
}
private void broadcastChange(@ChangeType int changeType, AssociationInfo association) {
+ Slog.i(TAG, "Broadcasting association changes - changeType=[" + changeType + "]...");
+
synchronized (mLocalListeners) {
for (OnChangeListener listener : mLocalListeners) {
listener.onAssociationChanged(changeType, association);
diff --git a/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java b/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java
index ff076192b6ad..9e3f5ce54599 100644
--- a/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java
+++ b/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java
@@ -18,6 +18,7 @@ package com.android.server.companion.virtual;
import static android.content.pm.ActivityInfo.FLAG_CAN_DISPLAY_ON_REMOTE_DEVICES;
import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.Display.INVALID_DISPLAY;
import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
@@ -48,6 +49,8 @@ import com.android.internal.app.BlockedAppStreamingActivity;
import com.android.modules.expresslog.Counter;
import java.util.Set;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
/**
* A controller to control the policies of the windows that can be displayed on the virtual display.
@@ -121,8 +124,12 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController
private final ComponentName mPermissionDialogComponent;
private final Object mGenericWindowPolicyControllerLock = new Object();
@Nullable private final ActivityBlockedCallback mActivityBlockedCallback;
+
+ // Do not access mDisplayId and mIsMirrorDisplay directly, instead use waitAndGetDisplayId()
+ // and waitAndGetIsMirrorDisplay()
private int mDisplayId = Display.INVALID_DISPLAY;
private boolean mIsMirrorDisplay = false;
+ private final CountDownLatch mDisplayIdSetLatch = new CountDownLatch(1);
@NonNull
@GuardedBy("mGenericWindowPolicyControllerLock")
@@ -214,6 +221,33 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController
void setDisplayId(int displayId, boolean isMirrorDisplay) {
mDisplayId = displayId;
mIsMirrorDisplay = isMirrorDisplay;
+ mDisplayIdSetLatch.countDown();
+ }
+
+ private int waitAndGetDisplayId() {
+ try {
+ if (!mDisplayIdSetLatch.await(10, TimeUnit.SECONDS)) {
+ Slog.e(TAG, "Timed out while waiting for GWPC displayId to be set.");
+ return INVALID_DISPLAY;
+ }
+ } catch (InterruptedException e) {
+ Slog.e(TAG, "Interrupted while waiting for GWPC displayId to be set.");
+ return INVALID_DISPLAY;
+ }
+ return mDisplayId;
+ }
+
+ private boolean waitAndGetIsMirrorDisplay() {
+ try {
+ if (!mDisplayIdSetLatch.await(10, TimeUnit.SECONDS)) {
+ Slog.e(TAG, "Timed out while waiting for GWPC isMirrorDisplay to be set.");
+ return false;
+ }
+ } catch (InterruptedException e) {
+ Slog.e(TAG, "Interrupted while waiting for GWPC isMirrorDisplay to be set.");
+ return false;
+ }
+ return mIsMirrorDisplay;
}
/**
@@ -281,7 +315,7 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController
@WindowConfiguration.WindowingMode int windowingMode, int launchingFromDisplayId,
boolean isNewTask) {
// Mirror displays cannot contain activities.
- if (mIsMirrorDisplay) {
+ if (waitAndGetIsMirrorDisplay()) {
Slog.d(TAG, "Mirror virtual displays cannot contain activities.");
return false;
}
@@ -341,11 +375,13 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController
@SuppressWarnings("AndroidFrameworkRequiresPermission")
public boolean keepActivityOnWindowFlagsChanged(ActivityInfo activityInfo, int windowFlags,
int systemWindowFlags) {
+ int displayId = waitAndGetDisplayId();
// The callback is fired only when windowFlags are changed. To let VirtualDevice owner
// aware that the virtual display has a secure window on top.
- if ((windowFlags & FLAG_SECURE) != 0 && mSecureWindowCallback != null) {
+ if ((windowFlags & FLAG_SECURE) != 0 && mSecureWindowCallback != null
+ && displayId != INVALID_DISPLAY) {
// Post callback on the main thread, so it doesn't block activity launching.
- mHandler.post(() -> mSecureWindowCallback.onSecureWindowShown(mDisplayId,
+ mHandler.post(() -> mSecureWindowCallback.onSecureWindowShown(displayId,
activityInfo.applicationInfo.uid));
}
@@ -365,13 +401,14 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController
@Override
public void onTopActivityChanged(ComponentName topActivity, int uid, @UserIdInt int userId) {
+ int displayId = waitAndGetDisplayId();
// Don't send onTopActivityChanged() callback when topActivity is null because it's defined
// as @NonNull in ActivityListener interface. Sends onDisplayEmpty() callback instead when
// there is no activity running on virtual display.
- if (mActivityListener != null && topActivity != null) {
+ if (mActivityListener != null && topActivity != null && displayId != INVALID_DISPLAY) {
// Post callback on the main thread so it doesn't block activity launching
mHandler.post(() ->
- mActivityListener.onTopActivityChanged(mDisplayId, topActivity, userId));
+ mActivityListener.onTopActivityChanged(displayId, topActivity, userId));
}
}
@@ -380,9 +417,11 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController
synchronized (mGenericWindowPolicyControllerLock) {
mRunningUids.clear();
mRunningUids.addAll(runningUids);
- if (mActivityListener != null && mRunningUids.isEmpty()) {
+ int displayId = waitAndGetDisplayId();
+ if (mActivityListener != null && mRunningUids.isEmpty()
+ && displayId != INVALID_DISPLAY) {
// Post callback on the main thread so it doesn't block activity launching
- mHandler.post(() -> mActivityListener.onDisplayEmpty(mDisplayId));
+ mHandler.post(() -> mActivityListener.onDisplayEmpty(displayId));
}
if (!mRunningAppsChangedListeners.isEmpty()) {
final ArraySet<RunningAppsChangedListener> listeners =
@@ -438,10 +477,12 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController
}
private void notifyActivityBlocked(ActivityInfo activityInfo) {
+ int displayId = waitAndGetDisplayId();
// Don't trigger activity blocked callback for mirror displays, because we can't show
// any activity or presentation on it anyway.
- if (!mIsMirrorDisplay && mActivityBlockedCallback != null) {
- mActivityBlockedCallback.onActivityBlocked(mDisplayId, activityInfo);
+ if (!waitAndGetIsMirrorDisplay() && mActivityBlockedCallback != null
+ && displayId != INVALID_DISPLAY) {
+ mActivityBlockedCallback.onActivityBlocked(displayId, activityInfo);
}
if (android.companion.virtualdevice.flags.Flags.metricsCollection()) {
Counter.logIncrementWithUid(
diff --git a/services/contextualsearch/Android.bp b/services/contextualsearch/Android.bp
new file mode 100644
index 000000000000..b4dd20ec5b7c
--- /dev/null
+++ b/services/contextualsearch/Android.bp
@@ -0,0 +1,22 @@
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "frameworks_base_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["frameworks_base_license"],
+}
+
+filegroup {
+ name: "services.contextualsearch-sources",
+ srcs: ["java/**/*.java"],
+ path: "java",
+ visibility: ["//frameworks/base/services"],
+}
+
+java_library_static {
+ name: "services.contextualsearch",
+ defaults: ["platform_service_defaults"],
+ srcs: [":services.contextualsearch-sources"],
+ libs: ["services.core"],
+}
diff --git a/services/contextualsearch/java/com/android/server/contextualsearch/ContextualSearchManagerService.java b/services/contextualsearch/java/com/android/server/contextualsearch/ContextualSearchManagerService.java
new file mode 100644
index 000000000000..b28bc1ffb611
--- /dev/null
+++ b/services/contextualsearch/java/com/android/server/contextualsearch/ContextualSearchManagerService.java
@@ -0,0 +1,315 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.contextualsearch;
+
+import static android.Manifest.permission.ACCESS_CONTEXTUAL_SEARCH;
+import static android.content.Context.CONTEXTUAL_SEARCH_SERVICE;
+import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+import static android.content.Intent.FLAG_ACTIVITY_NO_ANIMATION;
+import static android.content.Intent.FLAG_ACTIVITY_NO_USER_ACTION;
+import static android.content.pm.PackageManager.MATCH_FACTORY_ONLY;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.app.ActivityOptions;
+import android.app.admin.DevicePolicyManagerInternal;
+import android.app.contextualsearch.ContextualSearchManager;
+import android.app.contextualsearch.ContextualSearchState;
+import android.app.contextualsearch.IContextualSearchCallback;
+import android.app.contextualsearch.IContextualSearchManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ResolveInfo;
+import android.graphics.Bitmap;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.ParcelableException;
+import android.os.Process;
+import android.os.RemoteException;
+import android.os.ResultReceiver;
+import android.os.ShellCallback;
+import android.util.Log;
+import android.util.Slog;
+import android.window.ScreenCapture;
+
+import com.android.internal.R;
+import com.android.internal.annotations.GuardedBy;
+import com.android.server.LocalServices;
+import com.android.server.SystemService;
+import com.android.server.wm.ActivityAssistInfo;
+import com.android.server.wm.ActivityTaskManagerInternal;
+import com.android.server.wm.WindowManagerInternal;
+
+import java.io.FileDescriptor;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+public class ContextualSearchManagerService extends SystemService {
+
+ private static final int MSG_RESET_TEMPORARY_PACKAGE = 0;
+ private static final int MAX_TEMP_PACKAGE_DURATION_MS = 1_000 * 60 * 2; // 2 minutes
+ private final Context mContext;
+ private final ActivityTaskManagerInternal mAtmInternal;
+ private final WindowManagerInternal mWmInternal;
+ private final DevicePolicyManagerInternal mDpmInternal;
+
+ private Handler mTemporaryHandler;
+
+ @GuardedBy("this")
+ private String mTemporaryPackage = null;
+ private static final String TAG = ContextualSearchManagerService.class.getSimpleName();
+
+ public ContextualSearchManagerService(@NonNull Context context) {
+ super(context);
+ if (DEBUG_USER) Log.d(TAG, "ContextualSearchManagerService created");
+ mContext = context;
+ mAtmInternal = Objects.requireNonNull(
+ LocalServices.getService(ActivityTaskManagerInternal.class));
+ mWmInternal = Objects.requireNonNull(LocalServices.getService(WindowManagerInternal.class));
+ mDpmInternal = LocalServices.getService(DevicePolicyManagerInternal.class);
+ }
+
+ @Override
+ public void onStart() {
+ publishBinderService(CONTEXTUAL_SEARCH_SERVICE, new ContextualSearchManagerStub());
+ }
+
+ void resetTemporaryPackage() {
+ synchronized (this) {
+ enforceOverridingPermission("resetTemporaryPackage");
+ if (mTemporaryHandler != null) {
+ mTemporaryHandler.removeMessages(MSG_RESET_TEMPORARY_PACKAGE);
+ mTemporaryHandler = null;
+ }
+ if (DEBUG_USER) Log.d(TAG, "mTemporaryPackage reset.");
+ mTemporaryPackage = null;
+ }
+ }
+
+ void setTemporaryPackage(@NonNull String temporaryPackage, int durationMs) {
+ synchronized (this) {
+ enforceOverridingPermission("setTemporaryPackage");
+ final int maxDurationMs = MAX_TEMP_PACKAGE_DURATION_MS;
+ if (durationMs > maxDurationMs) {
+ throw new IllegalArgumentException(
+ "Max duration is " + maxDurationMs + " (called with " + durationMs + ")");
+ }
+ if (mTemporaryHandler == null) {
+ mTemporaryHandler = new Handler(Looper.getMainLooper(), null, true) {
+ @Override
+ public void handleMessage(Message msg) {
+ if (msg.what == MSG_RESET_TEMPORARY_PACKAGE) {
+ synchronized (this) {
+ resetTemporaryPackage();
+ }
+ } else {
+ Slog.wtf(TAG, "invalid handler msg: " + msg);
+ }
+ }
+ };
+ } else {
+ mTemporaryHandler.removeMessages(MSG_RESET_TEMPORARY_PACKAGE);
+ }
+ mTemporaryPackage = temporaryPackage;
+ mTemporaryHandler.sendEmptyMessageDelayed(MSG_RESET_TEMPORARY_PACKAGE, durationMs);
+ if (DEBUG_USER) Log.d(TAG, "mTemporaryPackage set to " + mTemporaryPackage);
+ }
+ }
+
+ private Intent getResolvedLaunchIntent() {
+ synchronized (this) {
+ // If mTemporaryPackage is not null, use it to get the ContextualSearch intent.
+ String csPkgName = mTemporaryPackage != null ? mTemporaryPackage : mContext
+ .getResources().getString(R.string.config_defaultContextualSearchPackageName);
+ if (csPkgName.isEmpty()) {
+ // Return null if csPackageName is not specified.
+ return null;
+ }
+ Intent launchIntent = new Intent(
+ ContextualSearchManager.ACTION_LAUNCH_CONTEXTUAL_SEARCH);
+ launchIntent.setPackage(csPkgName);
+ ResolveInfo resolveInfo = mContext.getPackageManager().resolveActivity(
+ launchIntent, MATCH_FACTORY_ONLY);
+ if (resolveInfo == null) {
+ return null;
+ }
+ ComponentName componentName = resolveInfo.getComponentInfo().getComponentName();
+ if (componentName == null) {
+ return null;
+ }
+ launchIntent.setComponent(componentName);
+ return launchIntent;
+ }
+ }
+
+ private Intent getContextualSearchIntent(int entrypoint, IBinder mToken) {
+ final Intent launchIntent = getResolvedLaunchIntent();
+ if (launchIntent == null) {
+ return null;
+ }
+
+ if (DEBUG_USER) Log.d(TAG, "Launch component: " + launchIntent.getComponent());
+ launchIntent.addFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_NO_ANIMATION
+ | FLAG_ACTIVITY_NO_USER_ACTION);
+ launchIntent.putExtra(ContextualSearchManager.EXTRA_ENTRYPOINT, entrypoint);
+ launchIntent.putExtra(ContextualSearchManager.EXTRA_TOKEN, mToken);
+ boolean isAssistDataAllowed = mAtmInternal.isAssistDataAllowed();
+ final List<ActivityAssistInfo> records = mAtmInternal.getTopVisibleActivities();
+ ArrayList<String> visiblePackageNames = new ArrayList<>();
+ boolean isManagedProfileVisible = false;
+ for (ActivityAssistInfo record : records) {
+ // Add the package name to the list only if assist data is allowed.
+ if (isAssistDataAllowed) {
+ visiblePackageNames.add(record.getComponentName().getPackageName());
+ }
+ if (mDpmInternal != null
+ && mDpmInternal.isUserOrganizationManaged(record.getUserId())) {
+ isManagedProfileVisible = true;
+ }
+ }
+ final ScreenCapture.ScreenshotHardwareBuffer shb;
+ if (mWmInternal != null) {
+ shb = mWmInternal.takeAssistScreenshot();
+ } else {
+ shb = null;
+ }
+ final Bitmap bm = shb != null ? shb.asBitmap() : null;
+ // Now that everything is fetched, putting it in the launchIntent.
+ if (bm != null) {
+ launchIntent.putExtra(ContextualSearchManager.EXTRA_FLAG_SECURE_FOUND,
+ shb.containsSecureLayers());
+ // Only put the screenshot if assist data is allowed
+ if (isAssistDataAllowed) {
+ launchIntent.putExtra(ContextualSearchManager.EXTRA_SCREENSHOT, bm.asShared());
+ }
+ }
+ launchIntent.putExtra(ContextualSearchManager.EXTRA_IS_MANAGED_PROFILE_VISIBLE,
+ isManagedProfileVisible);
+ // Only put the list of visible package names if assist data is allowed
+ if (isAssistDataAllowed) {
+ launchIntent.putExtra(ContextualSearchManager.EXTRA_VISIBLE_PACKAGE_NAMES,
+ visiblePackageNames);
+ }
+ return launchIntent;
+ }
+
+ @RequiresPermission(android.Manifest.permission.START_TASKS_FROM_RECENTS)
+ private int invokeContextualSearchIntent(Intent launchIntent) {
+ // Contextual search starts with a frozen screen - so we launch without
+ // any system animations or starting window.
+ final ActivityOptions opts = ActivityOptions.makeCustomTaskAnimation(mContext,
+ /* enterResId= */ 0, /* exitResId= */ 0, null, null, null);
+ opts.setDisableStartingWindow(true);
+ return mAtmInternal.startActivityWithScreenshot(launchIntent,
+ mContext.getPackageName(), Binder.getCallingUid(), Binder.getCallingPid(), null,
+ opts.toBundle(), Binder.getCallingUserHandle().getIdentifier());
+ }
+
+ private void enforcePermission(@NonNull final String func) {
+ Context ctx = getContext();
+ if (!(ctx.checkCallingPermission(ACCESS_CONTEXTUAL_SEARCH) == PERMISSION_GRANTED
+ || isCallerTemporary())) {
+ String msg = "Permission Denial: Cannot call " + func + " from pid="
+ + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid();
+ throw new SecurityException(msg);
+ }
+ }
+
+ private void enforceOverridingPermission(@NonNull final String func) {
+ if (!(Binder.getCallingUid() == Process.SHELL_UID
+ || Binder.getCallingUid() == Process.ROOT_UID
+ || Binder.getCallingUid() == Process.SYSTEM_UID)) {
+ String msg = "Permission Denial: Cannot override Contextual Search. Called " + func
+ + " from pid=" + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid();
+ throw new SecurityException(msg);
+ }
+ }
+
+ private boolean isCallerTemporary() {
+ synchronized (this) {
+ return mTemporaryPackage != null
+ && mTemporaryPackage.equals(
+ getContext().getPackageManager().getNameForUid(Binder.getCallingUid()));
+ }
+ }
+
+ private class ContextualSearchManagerStub extends IContextualSearchManager.Stub {
+ private @Nullable IBinder mToken;
+
+ @Override
+ public void startContextualSearch(int entrypoint) {
+ synchronized (this) {
+ if (DEBUG_USER) Log.d(TAG, "startContextualSearch");
+ enforcePermission("startContextualSearch");
+ mToken = new Binder();
+ // We get the launch intent with the system server's identity because the system
+ // server has READ_FRAME_BUFFER permission to get the screenshot and because only
+ // the system server can invoke non-exported activities.
+ Binder.withCleanCallingIdentity(() -> {
+ Intent launchIntent = getContextualSearchIntent(entrypoint, mToken);
+ if (launchIntent != null) {
+ int result = invokeContextualSearchIntent(launchIntent);
+ if (DEBUG_USER) Log.d(TAG, "Launch result: " + result);
+ }
+ });
+ }
+ }
+
+ @Override
+ public void getContextualSearchState(
+ @NonNull IBinder token,
+ @NonNull IContextualSearchCallback callback) {
+ if (DEBUG_USER) {
+ Log.i(TAG, "getContextualSearchState token: " + token + ", callback: " + callback);
+ }
+ if (mToken == null || !mToken.equals(token)) {
+ if (DEBUG_USER) {
+ Log.e(TAG, "getContextualSearchState: invalid token, returning error");
+ }
+ try {
+ callback.onError(
+ new ParcelableException(new IllegalArgumentException("Invalid token")));
+ } catch (RemoteException e) {
+ Log.e(TAG, "Could not invoke onError callback", e);
+ }
+ return;
+ }
+ mToken = null;
+ // Process data request
+ try {
+ callback.onResult(new ContextualSearchState(null, null, Bundle.EMPTY));
+ } catch (RemoteException e) {
+ Log.e(TAG, "Could not invoke onResult callback", e);
+ }
+ }
+
+ public void onShellCommand(@Nullable FileDescriptor in, @Nullable FileDescriptor out,
+ @Nullable FileDescriptor err, @NonNull String[] args,
+ @Nullable ShellCallback callback, @NonNull ResultReceiver resultReceiver) {
+ new ContextualSearchManagerShellCommand(ContextualSearchManagerService.this)
+ .exec(this, in, out, err, args, callback, resultReceiver);
+ }
+ }
+}
diff --git a/services/contextualsearch/java/com/android/server/contextualsearch/ContextualSearchManagerShellCommand.java b/services/contextualsearch/java/com/android/server/contextualsearch/ContextualSearchManagerShellCommand.java
new file mode 100644
index 000000000000..5777e1d154de
--- /dev/null
+++ b/services/contextualsearch/java/com/android/server/contextualsearch/ContextualSearchManagerShellCommand.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.contextualsearch;
+
+import android.annotation.NonNull;
+import android.os.ShellCommand;
+
+import java.io.PrintWriter;
+
+public class ContextualSearchManagerShellCommand extends ShellCommand {
+
+ private final ContextualSearchManagerService mService;
+
+ ContextualSearchManagerShellCommand(@NonNull ContextualSearchManagerService service) {
+ mService = service;
+ }
+
+ @Override
+ public int onCommand(String cmd) {
+ if (cmd == null) {
+ return handleDefaultCommands(cmd);
+ }
+ final PrintWriter pw = getOutPrintWriter();
+ switch (cmd) {
+ case "set": {
+ final String what = getNextArgRequired();
+ switch (what) {
+ case "temporary-package": {
+ String packageName = getNextArg();
+ if (packageName == null) {
+ mService.resetTemporaryPackage();
+ pw.println("ContextualSearchManagerService reset.");
+ return 0;
+ }
+ final int duration = Integer.parseInt(getNextArgRequired());
+ mService.setTemporaryPackage(packageName, duration);
+ pw.println("ContextualSearchManagerService temporarily set to "
+ + packageName + " for " + duration + "ms");
+ break;
+ }
+ }
+ }
+ break;
+ default:
+ return handleDefaultCommands(cmd);
+ }
+ return 0;
+ }
+
+ @Override
+ public void onHelp() {
+ try (PrintWriter pw = getOutPrintWriter()) {
+ pw.println("ContextualSearchService commands:");
+ pw.println(" help");
+ pw.println(" Prints this help text.");
+ pw.println("");
+ pw.println(" set temporary-package [PACKAGE_NAME DURATION]");
+ pw.println(" Temporarily (for DURATION ms) changes the Contextual Search "
+ + "implementation.");
+ pw.println(" To reset, call without any arguments.");
+ pw.println("");
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 0012b3d86552..133a77df3573 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -4658,6 +4658,8 @@ public final class ActiveServices {
INVALID_UID /* sdkSandboxClientAppUid */,
null /* sdkSandboxClientAppPackage */,
false /* inSharedIsolatedProcess */);
+ r.foregroundId = fgsDelegateOptions.mClientNotificationId;
+ r.foregroundNoti = fgsDelegateOptions.mClientNotification;
res.setService(r);
smap.mServicesByInstanceName.put(cn, r);
smap.mServicesByIntent.put(filter, r);
@@ -8171,7 +8173,7 @@ public final class ActiveServices {
* @param targetProcess the process of the service to start.
* @return {@link ReasonCode}
*/
- private @ReasonCode int shouldAllowFgsWhileInUsePermissionLocked(String callingPackage,
+ @ReasonCode int shouldAllowFgsWhileInUsePermissionLocked(String callingPackage,
int callingPid, int callingUid, @Nullable ProcessRecord targetProcess,
BackgroundStartPrivileges backgroundStartPrivileges) {
int ret = REASON_DENIED;
@@ -9046,6 +9048,10 @@ public final class ActiveServices {
});
}
signalForegroundServiceObserversLocked(r);
+ if (r.foregroundId != 0 && r.foregroundNoti != null) {
+ r.foregroundNoti.flags |= Notification.FLAG_FOREGROUND_SERVICE;
+ r.postNotification(true);
+ }
return true;
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerConstants.java b/services/core/java/com/android/server/am/ActivityManagerConstants.java
index ff837974bf3c..272e84b80870 100644
--- a/services/core/java/com/android/server/am/ActivityManagerConstants.java
+++ b/services/core/java/com/android/server/am/ActivityManagerConstants.java
@@ -51,6 +51,7 @@ import android.text.TextUtils;
import android.util.ArraySet;
import android.util.KeyValueListParser;
import android.util.Slog;
+import android.util.SparseBooleanArray;
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
@@ -436,6 +437,18 @@ final class ActivityManagerConstants extends ContentObserver {
private static final String KEY_MAX_SERVICE_CONNECTIONS_PER_PROCESS =
"max_service_connections_per_process";
+ private static final String KEY_PROC_STATE_DEBUG_UIDS = "proc_state_debug_uids";
+
+ /**
+ * UIDs we want to print detailed info in OomAdjuster.
+ * It's only used for debugging, and it's almost never updated, so we just create a new
+ * array when it's changed to avoid synchronization.
+ */
+ volatile SparseBooleanArray mProcStateDebugUids = new SparseBooleanArray(0);
+ volatile boolean mEnableProcStateStacktrace = false;
+ volatile int mProcStateDebugSetProcStateDelay = 0;
+ volatile int mProcStateDebugSetUidStateDelay = 0;
+
// Maximum number of cached processes we will allow.
public int MAX_CACHED_PROCESSES = DEFAULT_MAX_CACHED_PROCESSES;
@@ -1339,6 +1352,9 @@ final class ActivityManagerConstants extends ContentObserver {
case KEY_PSS_TO_RSS_THRESHOLD_MODIFIER:
updatePssToRssThresholdModifier();
break;
+ case KEY_PROC_STATE_DEBUG_UIDS:
+ updateProcStateDebugUids();
+ break;
default:
updateFGSPermissionEnforcementFlagsIfNecessary(name);
break;
@@ -2039,6 +2055,76 @@ final class ActivityManagerConstants extends ContentObserver {
DEFAULT_MAX_PREVIOUS_TIME);
}
+ private void updateProcStateDebugUids() {
+ final String val = DeviceConfig.getString(
+ DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+ KEY_PROC_STATE_DEBUG_UIDS,
+ "").trim();
+
+ // Parse KEY_PROC_STATE_DEBUG_UIDS as comma-separated values. Each values can be:
+ // Number: Enable debugging on the given UID.
+ // "stack": Enable stack trace when updating proc/uid-states.s
+ // "u" + delay-ms: Enable sleep when updating uid-state
+ // "p" + delay-ms: Enable sleep when updating procstate
+ //
+ // Example:
+ // device_config put activity_manager proc_state_debug_uids '10177,10202,stack,p500,u100'
+ // means:
+ // - Monitor UID 10177 and 10202
+ // - Also enable stack trace
+ // - Sleep 500 ms when updating the procstate.
+ // - Sleep 100 ms when updating the UID state.
+
+ mEnableProcStateStacktrace = false;
+ mProcStateDebugSetProcStateDelay = 0;
+ mProcStateDebugSetUidStateDelay = 0;
+ if (val.length() == 0) {
+ mProcStateDebugUids = new SparseBooleanArray(0);
+ return;
+ }
+ final String[] uids = val.split(",");
+
+ final SparseBooleanArray newArray = new SparseBooleanArray(0);
+
+ for (String token : uids) {
+ if (token.length() == 0) {
+ continue;
+ }
+ // "stack" -> enable stacktrace.
+ if ("stack".equals(token)) {
+ mEnableProcStateStacktrace = true;
+ continue;
+ }
+ boolean isUid = true;
+ char prefix = token.charAt(0);
+ if ('a' <= prefix && prefix <= 'z') {
+ // If the token starts with an alphabet, it's not a UID.
+ isUid = false;
+ token = token.substring(1);
+ }
+
+ int value = -1;
+ try {
+ value = Integer.parseInt(token.trim());
+ } catch (NumberFormatException e) {
+ Slog.w(TAG, "Invalid number " + token + " in " + val);
+ continue;
+ }
+ if (isUid) {
+ newArray.put(value, true);
+ } else if (prefix == 'p') {
+ // Enable delay in set-proc-state
+ mProcStateDebugSetProcStateDelay = value;
+ } else if (prefix == 'u') {
+ // Enable delay in set-uid-state
+ mProcStateDebugSetUidStateDelay = value;
+ } else {
+ Slog.w(TAG, "Invalid prefix " + prefix + " in " + val);
+ }
+ }
+ mProcStateDebugUids = newArray;
+ }
+
private void updateMinAssocLogDuration() {
MIN_ASSOC_LOG_DURATION = DeviceConfig.getLong(
DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, KEY_MIN_ASSOC_LOG_DURATION,
@@ -2178,6 +2264,28 @@ final class ActivityManagerConstants extends ContentObserver {
mDefaultPssToRssThresholdModifier);
}
+ boolean shouldDebugUidForProcState(int uid) {
+ SparseBooleanArray ar = mProcStateDebugUids;
+ final var size = ar.size();
+ if (size == 0) { // Most common case.
+ return false;
+ }
+ // If the array is small (also common), avoid the binary search.
+ if (size <= 8) {
+ for (int i = 0; i < size; i++) {
+ if (ar.keyAt(i) == uid) {
+ return ar.valueAt(i);
+ }
+ }
+ return false;
+ }
+ return ar.get(uid, false);
+ }
+
+ boolean shouldEnableProcStateDebug() {
+ return mProcStateDebugUids.size() > 0;
+ }
+
@NeverCompile // Avoid size overhead of debugging code.
void dump(PrintWriter pw) {
pw.println("ACTIVITY MANAGER SETTINGS (dumpsys activity settings) "
@@ -2393,5 +2501,12 @@ final class ActivityManagerConstants extends ContentObserver {
pw.print(" OOMADJ_UPDATE_QUICK="); pw.println(OOMADJ_UPDATE_QUICK);
pw.print(" ENABLE_WAIT_FOR_FINISH_ATTACH_APPLICATION=");
pw.println(mEnableWaitForFinishAttachApplication);
+
+ synchronized (mProcStateDebugUids) {
+ pw.print(" "); pw.print(KEY_PROC_STATE_DEBUG_UIDS);
+ pw.print("="); pw.println(mProcStateDebugUids);
+ pw.print(" uid-state-delay="); pw.println(mProcStateDebugSetUidStateDelay);
+ pw.print(" proc-state-delay="); pw.println(mProcStateDebugSetProcStateDelay);
+ }
}
}
diff --git a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
index 5521381e8908..8f0665d497bf 100644
--- a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
+++ b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
@@ -286,9 +286,6 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
// when the flag is fused on.
private static final int MSG_DELIVERY_TIMEOUT_SOFT = 8;
- // TODO: Use the trunk stable flag.
- private static final boolean DEFER_FROZEN_OUTGOING_BCASTS = false;
-
private void enqueueUpdateRunningList() {
mLocalHandler.removeMessages(MSG_UPDATE_RUNNING_LIST);
mLocalHandler.sendEmptyMessage(MSG_UPDATE_RUNNING_LIST);
@@ -361,6 +358,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
* Return the total number of active queues contained inside
* {@link #mRunning}.
*/
+ @GuardedBy("mService")
private int getRunningSize() {
int size = 0;
for (int i = 0; i < mRunning.length; i++) {
@@ -372,6 +370,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
/**
* Return the number of active queues that are delivering "urgent" broadcasts
*/
+ @GuardedBy("mService")
private int getRunningUrgentCount() {
int count = 0;
for (int i = 0; i < mRunning.length; i++) {
@@ -386,6 +385,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
* Return the first index of the given value contained inside
* {@link #mRunning}, otherwise {@code -1}.
*/
+ @GuardedBy("mService")
private int getRunningIndexOf(@Nullable BroadcastProcessQueue test) {
for (int i = 0; i < mRunning.length; i++) {
if (mRunning[i] == test) return i;
@@ -585,6 +585,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
traceEnd(cookie);
}
+ @GuardedBy("mService")
private boolean isPendingColdStartValid() {
if (mRunningColdStart.app.getPid() > 0) {
// If the process has already started, check if it wasn't killed.
@@ -595,6 +596,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
}
}
+ @GuardedBy("mService")
private void clearInvalidPendingColdStart() {
logw("Clearing invalid pending cold start: " + mRunningColdStart);
if (mRunningColdStart.wasActiveBroadcastReEnqueued()) {
@@ -629,6 +631,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
}
}
+ @GuardedBy("mService")
private void finishOrReEnqueueActiveBroadcast(@NonNull BroadcastProcessQueue queue) {
checkState(queue.isActive(), "isActive");
@@ -646,6 +649,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
}
}
+ @GuardedBy("mService")
@Override
public boolean onApplicationAttachedLocked(@NonNull ProcessRecord app)
throws BroadcastRetryException {
@@ -689,16 +693,19 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
return didSomething;
}
+ @GuardedBy("mService")
@Override
public void onApplicationTimeoutLocked(@NonNull ProcessRecord app) {
onApplicationCleanupLocked(app);
}
+ @GuardedBy("mService")
@Override
public void onApplicationProblemLocked(@NonNull ProcessRecord app) {
onApplicationCleanupLocked(app);
}
+ @GuardedBy("mService")
@Override
public void onApplicationCleanupLocked(@NonNull ProcessRecord app) {
if (DEBUG_BROADCAST) {
@@ -735,6 +742,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
}
}
+ @GuardedBy("mService")
private void clearRunningColdStart() {
mRunningColdStart.traceProcessEnd();
@@ -746,12 +754,14 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
enqueueUpdateRunningList();
}
+ @GuardedBy("mService")
@Override
public void onProcessFreezableChangedLocked(@NonNull ProcessRecord app) {
mLocalHandler.removeMessages(MSG_PROCESS_FREEZABLE_CHANGED, app);
mLocalHandler.obtainMessage(MSG_PROCESS_FREEZABLE_CHANGED, app).sendToTarget();
}
+ @GuardedBy("mService")
@Override
public int getPreferredSchedulingGroupLocked(@NonNull ProcessRecord app) {
final BroadcastProcessQueue queue = getProcessQueue(app);
@@ -761,12 +771,13 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
return ProcessList.SCHED_GROUP_UNDEFINED;
}
+ @GuardedBy("mService")
@Override
public void enqueueBroadcastLocked(@NonNull BroadcastRecord r) {
// TODO: Apply delivery group policies and FLAG_REPLACE_PENDING to collapse the
// outgoing broadcasts.
// TODO: Add traces/logs for the enqueueing outgoing broadcasts logic.
- if (DEFER_FROZEN_OUTGOING_BCASTS && isProcessFreezable(r.callerApp)) {
+ if (Flags.deferOutgoingBroadcasts() && isProcessFreezable(r.callerApp)) {
final BroadcastProcessQueue queue = getOrCreateProcessQueue(
r.callerApp.processName, r.callerApp.uid);
if (queue.getOutgoingBroadcastCount() >= mConstants.MAX_FROZEN_OUTGOING_BROADCASTS) {
@@ -846,6 +857,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
traceEnd(cookie);
}
+ @GuardedBy("mService")
private void skipAndCancelReplacedBroadcasts(ArraySet<BroadcastRecord> replacedBroadcasts) {
for (int i = 0; i < replacedBroadcasts.size(); ++i) {
final BroadcastRecord r = replacedBroadcasts.valueAt(i);
@@ -858,6 +870,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
}
}
+ @GuardedBy("mService")
private void applyDeliveryGroupPolicy(@NonNull BroadcastRecord r) {
if (mService.shouldIgnoreDeliveryGroupPolicy(r.intent.getAction())) {
return;
@@ -921,6 +934,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
mRecordsLookupCache.compareAndSet(null, recordsLookupCache);
}
+ @GuardedBy("mService")
@NonNull
private ArrayMap<BroadcastRecord, Boolean> getRecordsLookupCache() {
ArrayMap<BroadcastRecord, Boolean> recordsLookupCache =
@@ -931,6 +945,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
return recordsLookupCache;
}
+ @GuardedBy("mService")
private boolean containsAllReceivers(@NonNull BroadcastRecord record,
@NonNull BroadcastRecord testRecord,
@NonNull ArrayMap<BroadcastRecord, Boolean> recordsLookupCache) {
@@ -1064,6 +1079,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
* Consults {@link BroadcastSkipPolicy} and the receiver process state to decide whether or
* not the broadcast to a receiver can be skipped.
*/
+ @GuardedBy("mService")
private String shouldSkipReceiver(@NonNull BroadcastProcessQueue queue,
@NonNull BroadcastRecord r, int index) {
final int oldDeliveryState = getDeliveryState(r, index);
@@ -1104,6 +1120,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
* finishReceiver() to be called before moving to the next broadcast. Otherwise,
* {@code false}.
*/
+ @GuardedBy("mService")
@CheckResult
private boolean dispatchReceivers(@NonNull BroadcastProcessQueue queue,
@NonNull BroadcastRecord r, int index) throws BroadcastRetryException {
@@ -1215,6 +1232,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
* Schedule the final {@link BroadcastRecord#resultTo} delivery for an
* ordered broadcast; assumes the sender is still a warm process.
*/
+ @GuardedBy("mService")
private void scheduleResultTo(@NonNull BroadcastRecord r) {
if (r.resultTo == null) return;
final ProcessRecord app = r.resultToApp;
@@ -1248,6 +1266,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
// Required when Flags.anrTimerServiceEnabled is false. This function can be replaced with a
// single call to {@code mAnrTimer.start()} if and when the flag is fused on.
+ @GuardedBy("mService")
private void startDeliveryTimeoutLocked(@NonNull BroadcastProcessQueue queue,
int softTimeoutMillis) {
if (mAnrTimer.serviceEnabled()) {
@@ -1261,6 +1280,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
// Required when Flags.anrTimerServiceEnabled is false. This function can be replaced with a
// single call to {@code mAnrTimer.cancel()} if and when the flag is fused on.
+ @GuardedBy("mService")
private void cancelDeliveryTimeoutLocked(@NonNull BroadcastProcessQueue queue) {
mAnrTimer.cancel(queue);
if (!mAnrTimer.serviceEnabled()) {
@@ -1270,6 +1290,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
// Required when Flags.anrTimerServiceEnabled is false. This function can be deleted entirely
// if and when the flag is fused on.
+ @GuardedBy("mService")
private void deliveryTimeoutSoftLocked(@NonNull BroadcastProcessQueue queue,
int softTimeoutMillis) {
if (queue.app != null) {
@@ -1292,6 +1313,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
traceEnd(cookie);
}
+ @GuardedBy("mService")
private void deliveryTimeoutLocked(@NonNull BroadcastProcessQueue queue) {
finishReceiverActiveLocked(queue, BroadcastRecord.DELIVERY_TIMEOUT,
"deliveryTimeoutLocked");
@@ -1309,6 +1331,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
}
}
+ @GuardedBy("mService")
@Override
public boolean finishReceiverLocked(@NonNull ProcessRecord app, int resultCode,
@Nullable String resultData, @Nullable Bundle resultExtras, boolean resultAbort,
@@ -1369,6 +1392,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
/**
* Return true if there are no more broadcasts in the queue or if the queue is not runnable.
*/
+ @GuardedBy("mService")
private boolean shouldRetire(@NonNull BroadcastProcessQueue queue) {
// If we've made reasonable progress, periodically retire ourselves to
// avoid starvation of other processes and stack overflow when a
@@ -1392,6 +1416,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
/**
* Terminate all active broadcasts on the queue.
*/
+ @GuardedBy("mService")
private void finishReceiverActiveLocked(@NonNull BroadcastProcessQueue queue,
@DeliveryState int deliveryState, @NonNull String reason) {
if (!queue.isActive()) {
@@ -1493,6 +1518,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
* Set the delivery state on the given broadcast, then apply any additional
* bookkeeping related to ordered broadcasts.
*/
+ @GuardedBy("mService")
private void setDeliveryState(@Nullable BroadcastProcessQueue queue,
@Nullable ProcessRecord app, @NonNull BroadcastRecord r, int index,
@NonNull Object receiver, @DeliveryState int newDeliveryState,
@@ -1558,10 +1584,12 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
traceEnd(cookie);
}
+ @GuardedBy("mService")
private @DeliveryState int getDeliveryState(@NonNull BroadcastRecord r, int index) {
return r.getDeliveryState(index);
}
+ @GuardedBy("mService")
@Override
public boolean cleanupDisabledPackageReceiversLocked(@Nullable String packageName,
@Nullable Set<String> filterByClasses, int userId) {
@@ -1627,6 +1655,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
* Typical consumer that will skip the given broadcast, usually as a result
* of it matching a predicate.
*/
+ @GuardedBy("mService")
private final BroadcastConsumer mBroadcastConsumerSkip = (r, i) -> {
setDeliveryState(null, null, r, i, r.receivers.get(i), BroadcastRecord.DELIVERY_SKIPPED,
"mBroadcastConsumerSkip");
@@ -1636,6 +1665,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
* Typical consumer that will both skip the given broadcast and mark it as
* cancelled, usually as a result of it matching a predicate.
*/
+ @GuardedBy("mService")
private final BroadcastConsumer mBroadcastConsumerSkipAndCanceled = (r, i) -> {
setDeliveryState(null, null, r, i, r.receivers.get(i), BroadcastRecord.DELIVERY_SKIPPED,
"mBroadcastConsumerSkipAndCanceled");
@@ -1645,23 +1675,27 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
};
@VisibleForTesting
+ @GuardedBy("mService")
final BroadcastConsumer mBroadcastConsumerDeferApply = (r, i) -> {
setDeliveryState(null, null, r, i, r.receivers.get(i), BroadcastRecord.DELIVERY_DEFERRED,
"mBroadcastConsumerDeferApply");
};
@VisibleForTesting
+ @GuardedBy("mService")
final BroadcastConsumer mBroadcastConsumerDeferClear = (r, i) -> {
setDeliveryState(null, null, r, i, r.receivers.get(i), BroadcastRecord.DELIVERY_PENDING,
"mBroadcastConsumerDeferClear");
};
+ @GuardedBy("mService")
final BroadcastRecordConsumer mBroadcastRecordConsumerEnqueue = this::enqueueBroadcastLocked;
/**
* Verify that all known {@link #mProcessQueues} are in the state tested by
* the given {@link Predicate}.
*/
+ @GuardedBy("mService")
private boolean testAllProcessQueues(@NonNull Predicate<BroadcastProcessQueue> test,
@NonNull String label, @NonNull PrintWriter pw) {
for (int i = 0; i < mProcessQueues.size(); i++) {
@@ -1685,6 +1719,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
return true;
}
+ @GuardedBy("mService")
private boolean forEachMatchingBroadcast(
@NonNull Predicate<BroadcastProcessQueue> queuePredicate,
@NonNull BroadcastPredicate broadcastPredicate,
@@ -1709,6 +1744,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
return didSomething;
}
+ @GuardedBy("mService")
private boolean forEachMatchingQueue(
@NonNull Predicate<BroadcastProcessQueue> queuePredicate,
@NonNull Consumer<BroadcastProcessQueue> queueConsumer) {
@@ -1730,6 +1766,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
return didSomething;
}
+ @GuardedBy("mService")
@Override
public void start(@NonNull ContentResolver resolver) {
mFgConstants.startObserving(mHandler, resolver);
@@ -1750,35 +1787,42 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
mLocalHandler.sendEmptyMessage(MSG_CHECK_HEALTH);
}
+ @GuardedBy("mService")
@Override
public boolean isIdleLocked() {
return isIdleLocked(LOG_WRITER_INFO);
}
+ @GuardedBy("mService")
public boolean isIdleLocked(@NonNull PrintWriter pw) {
return testAllProcessQueues(q -> q.isIdle(), "idle", pw);
}
+ @GuardedBy("mService")
@Override
public boolean isBeyondBarrierLocked(@UptimeMillisLong long barrierTime) {
return isBeyondBarrierLocked(barrierTime, LOG_WRITER_INFO);
}
+ @GuardedBy("mService")
public boolean isBeyondBarrierLocked(@UptimeMillisLong long barrierTime,
@NonNull PrintWriter pw) {
return testAllProcessQueues(q -> q.isBeyondBarrierLocked(barrierTime), "barrier", pw);
}
+ @GuardedBy("mService")
@Override
public boolean isDispatchedLocked(@NonNull Intent intent) {
return isDispatchedLocked(intent, LOG_WRITER_INFO);
}
+ @GuardedBy("mService")
public boolean isDispatchedLocked(@NonNull Intent intent, @NonNull PrintWriter pw) {
return testAllProcessQueues(q -> q.isDispatched(intent),
"dispatch of " + intent, pw);
}
+ @GuardedBy("mService")
@Override
public void waitForIdle(@NonNull PrintWriter pw) {
waitFor(() -> isIdleLocked(pw));
@@ -1801,6 +1845,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
}
}
+ @GuardedBy("mService")
@Override
public void waitForDispatched(@NonNull Intent intent, @NonNull PrintWriter pw) {
waitFor(() -> isDispatchedLocked(intent, pw));
@@ -1819,6 +1864,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
}
}
+ @GuardedBy("mService")
private void checkAndRemoveWaitingFor() {
if (!mWaitingFor.isEmpty()) {
mWaitingFor.removeIf((pair) -> {
@@ -1854,6 +1900,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
return false;
}
+ @GuardedBy("mService")
@Override
public void backgroundServicesFinishedLocked(int userId) {
// Modern queue does not alter the broadcasts delivery behavior based on background
@@ -1866,6 +1913,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
}
}
+ @GuardedBy("mService")
private void checkHealthLocked() {
try {
assertHealthLocked();
@@ -1888,6 +1936,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
* current state once and stop future health checks to avoid spamming.
*/
@VisibleForTesting
+ @GuardedBy("mService")
void assertHealthLocked() {
// Verify all runnable queues are sorted
BroadcastProcessQueue prev = null;
@@ -1927,6 +1976,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
}
@SuppressWarnings("CheckResult")
+ @GuardedBy("mService")
private void updateWarmProcess(@NonNull BroadcastProcessQueue queue) {
if (!queue.isProcessWarm()) {
// This is a bit awkward; we're in the middle of traversing the
@@ -1946,6 +1996,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
* {@link BroadcastProcessQueue}. Also updates any runnable status that
* might have changed as a side-effect.
*/
+ @GuardedBy("mService")
private void setQueueProcess(@NonNull BroadcastProcessQueue queue,
@Nullable ProcessRecord app) {
if (queue.setProcessAndUidState(app, mUidForeground.get(queue.uid, false),
@@ -2008,6 +2059,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
* Inform other parts of OS that the given broadcast queue has started
* running, typically for internal bookkeeping.
*/
+ @GuardedBy("mService")
private void notifyStartedRunning(@NonNull BroadcastProcessQueue queue) {
if (queue.app != null) {
queue.app.mReceivers.incrementCurReceivers();
@@ -2032,6 +2084,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
* Inform other parts of OS that the given broadcast queue has stopped
* running, typically for internal bookkeeping.
*/
+ @GuardedBy("mService")
private void notifyStoppedRunning(@NonNull BroadcastProcessQueue queue) {
if (queue.app != null) {
queue.app.mReceivers.decrementCurReceivers();
@@ -2046,6 +2099,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
* Inform other parts of OS that the given broadcast was just scheduled for
* a registered receiver, typically for internal bookkeeping.
*/
+ @GuardedBy("mService")
private void notifyScheduleRegisteredReceiver(@NonNull ProcessRecord app,
@NonNull BroadcastRecord r, @NonNull BroadcastFilter receiver) {
reportUsageStatsBroadcastDispatched(app, r);
@@ -2055,6 +2109,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
* Inform other parts of OS that the given broadcast was just scheduled for
* a manifest receiver, typically for internal bookkeeping.
*/
+ @GuardedBy("mService")
private void notifyScheduleReceiver(@NonNull ProcessRecord app,
@NonNull BroadcastRecord r, @NonNull ResolveInfo receiver) {
reportUsageStatsBroadcastDispatched(app, r);
@@ -2077,6 +2132,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
receiverPackageName, r.userId, r.callerPackage, r.toString());
}
+ @GuardedBy("mService")
private void reportUsageStatsBroadcastDispatched(@NonNull ProcessRecord app,
@NonNull BroadcastRecord r) {
final long idForResponseEvent = (r.options != null)
@@ -2102,6 +2158,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
* Inform other parts of OS that the given broadcast was just finished,
* typically for internal bookkeeping.
*/
+ @GuardedBy("mService")
private void notifyFinishReceiver(@Nullable BroadcastProcessQueue queue,
@Nullable ProcessRecord app, @NonNull BroadcastRecord r, int index,
@NonNull Object receiver) {
@@ -2115,6 +2172,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
}
}
+ @GuardedBy("mService")
private void logBroadcastDeliveryEventReported(@Nullable BroadcastProcessQueue queue,
@Nullable ProcessRecord app, @NonNull BroadcastRecord r, int index,
@NonNull Object receiver) {
@@ -2165,6 +2223,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
}
}
+ @GuardedBy("mService")
private void notifyFinishBroadcast(@NonNull BroadcastRecord r) {
mService.notifyBroadcastFinishedLocked(r);
r.finishTime = SystemClock.uptimeMillis();
@@ -2193,11 +2252,13 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
}
@VisibleForTesting
+ @GuardedBy("mService")
@NonNull BroadcastProcessQueue getOrCreateProcessQueue(@NonNull ProcessRecord app) {
return getOrCreateProcessQueue(app.processName, app.info.uid);
}
@VisibleForTesting
+ @GuardedBy("mService")
@NonNull BroadcastProcessQueue getOrCreateProcessQueue(@NonNull String processName,
int uid) {
BroadcastProcessQueue leaf = mProcessQueues.get(uid);
@@ -2222,11 +2283,13 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
}
@VisibleForTesting
+ @GuardedBy("mService")
@Nullable BroadcastProcessQueue getProcessQueue(@NonNull ProcessRecord app) {
return getProcessQueue(app.processName, app.info.uid);
}
@VisibleForTesting
+ @GuardedBy("mService")
@Nullable BroadcastProcessQueue getProcessQueue(@NonNull String processName, int uid) {
BroadcastProcessQueue leaf = mProcessQueues.get(uid);
while (leaf != null) {
@@ -2239,11 +2302,13 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
}
@VisibleForTesting
+ @GuardedBy("mService")
@Nullable BroadcastProcessQueue removeProcessQueue(@NonNull ProcessRecord app) {
return removeProcessQueue(app.processName, app.info.uid);
}
@VisibleForTesting
+ @GuardedBy("mService")
@Nullable BroadcastProcessQueue removeProcessQueue(@NonNull String processName,
int uid) {
BroadcastProcessQueue prev = null;
@@ -2267,6 +2332,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
return null;
}
+ @GuardedBy("mService")
private void logBootCompletedBroadcastCompletionLatencyIfPossible(BroadcastRecord r) {
// Only log after last receiver.
// In case of split BOOT_COMPLETED broadcast, make sure only call this method on the
@@ -2322,6 +2388,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
@Override
@NeverCompile
+ @GuardedBy("mService")
public void dumpDebug(@NonNull ProtoOutputStream proto, long fieldId) {
long token = proto.start(fieldId);
proto.write(BroadcastQueueProto.QUEUE_NAME, mQueueName);
@@ -2331,6 +2398,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
@Override
@NeverCompile
+ @GuardedBy("mService")
public boolean dumpLocked(@NonNull FileDescriptor fd, @NonNull PrintWriter pw,
@NonNull String[] args, int opti, boolean dumpConstants, boolean dumpHistory,
boolean dumpAll, @Nullable String dumpPackage, boolean needSep) {
diff --git a/services/core/java/com/android/server/am/EventLogTags.logtags b/services/core/java/com/android/server/am/EventLogTags.logtags
index 80387322b038..b142781418e8 100644
--- a/services/core/java/com/android/server/am/EventLogTags.logtags
+++ b/services/core/java/com/android/server/am/EventLogTags.logtags
@@ -135,3 +135,9 @@ option java_package com.android.server.am
# Caller information to clear application data
30120 am_clear_app_data_caller (pid|1),(uid|1),(package|3)
+
+30111 am_uid_state_changed (UID|1|5),(Seq|1|5),(UidState|1|5),(OldUidState|1|5),(Capability|1|5),(OldCapability|1|5),(Flags|1|5),(reason|3)
+30112 am_proc_state_changed (UID|1|5),(PID|1|5),(Seq|1|5),(ProcState|1|5),(OldProcState|1|5),(OomAdj|1|5),(OldOomAdj|1|5),(reason|3)
+
+# "Misc" events. See OomAdjusterDebugLogger.java
+30113 am_oom_adj_misc (Event|1|5),(UID|1|5),(PID|1|5),(Seq|1|5),(Arg1|1|5),(Arg2|1|5),(reason|3)
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index 7f6d62c29648..1a7629f3182d 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -401,6 +401,14 @@ public class OomAdjuster {
@GuardedBy("mService")
private boolean mPendingFullOomAdjUpdate = false;
+ /**
+ * Most recent reason string. We update it in sync with the trace.
+ */
+ @OomAdjReason
+ protected int mLastReason;
+
+ private final OomAdjusterDebugLogger mLogger;
+
/** Overrideable by a test */
@VisibleForTesting
protected boolean isChangeEnabled(@CachedCompatChangeId int cachedCompatChangeId,
@@ -433,6 +441,8 @@ public class OomAdjuster {
mCachedAppOptimizer = new CachedAppOptimizer(mService);
mCacheOomRanker = new CacheOomRanker(service);
+ mLogger = new OomAdjusterDebugLogger(this, mService.mConstants);
+
mProcessGroupHandler = new Handler(adjusterThread.getLooper(), msg -> {
final int pid = msg.arg1;
final int group = msg.arg2;
@@ -636,6 +646,7 @@ public class OomAdjuster {
protected boolean performUpdateOomAdjLSP(ProcessRecord app, @OomAdjReason int oomAdjReason) {
final ProcessRecord topApp = mService.getTopApp();
+ mLastReason = oomAdjReason;
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, oomAdjReasonToString(oomAdjReason));
mService.mOomAdjProfiler.oomAdjStarted();
mAdjSeq++;
@@ -916,6 +927,7 @@ public class OomAdjuster {
protected void performUpdateOomAdjPendingTargetsLocked(@OomAdjReason int oomAdjReason) {
final ProcessRecord topApp = mService.getTopApp();
+ mLastReason = oomAdjReason;
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, oomAdjReasonToString(oomAdjReason));
mService.mOomAdjProfiler.oomAdjStarted();
@@ -958,6 +970,7 @@ public class OomAdjuster {
}
}
+ mLastReason = oomAdjReason;
if (startProfiling) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, oomAdjReasonToString(oomAdjReason));
mService.mOomAdjProfiler.oomAdjStarted();
@@ -1491,6 +1504,7 @@ public class OomAdjuster {
|| uidRec.isSetAllowListed() != uidRec.isCurAllowListed()
|| uidRec.getProcAdjChanged()) {
int uidChange = 0;
+ final boolean shouldLog = mLogger.shouldLog(uidRec.getUid());
if (DEBUG_UID_OBSERVERS) {
Slog.i(TAG_UID_OBSERVERS, "Changes in " + uidRec
+ ": proc state from " + uidRec.getSetProcState() + " to "
@@ -1511,14 +1525,21 @@ public class OomAdjuster {
|| uidRec.isSetAllowListed()
|| uidRec.getLastBackgroundTime() == 0) {
uidRec.setLastBackgroundTime(nowElapsed);
+ if (shouldLog) {
+ mLogger.logSetLastBackgroundTime(uidRec.getUid(), nowElapsed);
+ }
if (mService.mDeterministicUidIdle
|| !mService.mHandler.hasMessages(IDLE_UIDS_MSG)) {
// Note: the background settle time is in elapsed realtime, while
// the handler time base is uptime. All this means is that we may
// stop background uids later than we had intended, but that only
// happens because the device was sleeping so we are okay anyway.
+ if (shouldLog) {
+ mLogger.logScheduleUidIdle1(uidRec.getUid(),
+ mConstants.BACKGROUND_SETTLE_TIME);
+ }
mService.mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
- mConstants.BACKGROUND_SETTLE_TIME);
+ mConstants.BACKGROUND_SETTLE_TIME); // XXX
}
}
if (uidRec.isIdle() && !uidRec.isSetIdle()) {
@@ -1536,6 +1557,9 @@ public class OomAdjuster {
}
uidRec.setLastBackgroundTime(0);
uidRec.setLastIdleTime(0);
+ if (shouldLog) {
+ mLogger.logClearLastBackgroundTime(uidRec.getUid());
+ }
}
final boolean wasCached = uidRec.getSetProcState()
> ActivityManager.PROCESS_STATE_RECEIVER;
@@ -1555,11 +1579,25 @@ public class OomAdjuster {
if (uidRec.getProcAdjChanged()) {
uidChange |= UidRecord.CHANGE_PROCADJ;
}
+ int oldProcState = uidRec.getSetProcState();
+ int oldCapability = uidRec.getSetCapability();
uidRec.setSetProcState(uidRec.getCurProcState());
uidRec.setSetCapability(uidRec.getCurCapability());
uidRec.setSetAllowListed(uidRec.isCurAllowListed());
uidRec.setSetIdle(uidRec.isIdle());
uidRec.clearProcAdjChanged();
+ if (shouldLog
+ && ((uidRec.getSetProcState() != oldProcState)
+ || (uidRec.getSetCapability() != oldCapability))) {
+ int flags = 0;
+ if (uidRec.isSetAllowListed()) {
+ flags |= 1;
+ }
+ mLogger.logUidStateChanged(uidRec.getUid(),
+ uidRec.getSetProcState(), oldProcState,
+ uidRec.getSetCapability(), oldCapability,
+ flags);
+ }
if ((uidChange & UidRecord.CHANGE_PROCSTATE) != 0
|| (uidChange & UidRecord.CHANGE_CAPABILITY) != 0) {
mService.mAtmInternal.onUidProcStateChanged(
@@ -3300,6 +3338,7 @@ public class OomAdjuster {
mCachedAppOptimizer.onOomAdjustChanged(state.getSetAdj(), state.getCurAdj(), app);
}
+ final int oldOomAdj = state.getSetAdj();
if (state.getCurAdj() != state.getSetAdj()) {
ProcessList.setOomAdj(app.getPid(), app.uid, state.getCurAdj());
if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mService.mCurOomAdjUid == app.info.uid) {
@@ -3457,6 +3496,7 @@ public class OomAdjuster {
mService.mAppProfiler.updateNextPssTimeLPf(
state.getCurProcState(), app.mProfile, now, forceUpdatePssTime);
}
+ int oldProcState = state.getSetProcState();
if (state.getSetProcState() != state.getCurProcState()) {
if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mService.mCurOomAdjUid == app.uid) {
String msg = "Proc state change of " + app.processName
@@ -3556,6 +3596,11 @@ public class OomAdjuster {
// Kick off the delayed checkup message if needed.
if (mService.mDeterministicUidIdle
|| !mService.mHandler.hasMessages(IDLE_UIDS_MSG)) {
+ if (mLogger.shouldLog(app.uid)) {
+ mLogger.logScheduleUidIdle2(
+ uidRec.getUid(), app.getPid(),
+ mConstants.mKillBgRestrictedAndCachedIdleSettleTimeMs);
+ }
mService.mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
mConstants.mKillBgRestrictedAndCachedIdleSettleTimeMs);
}
@@ -3563,6 +3608,12 @@ public class OomAdjuster {
}
state.setSetCached(state.isCached());
state.setSetNoKillOnBgRestrictedAndIdle(state.shouldNotKillOnBgRestrictedAndIdle());
+ if (((oldProcState != state.getSetProcState()) || (oldOomAdj != state.getSetAdj()))
+ && mLogger.shouldLog(app.uid)) {
+ mLogger.logProcStateChanged(app.uid, app.getPid(),
+ state.getSetProcState(), oldProcState,
+ state.getSetAdj(), oldOomAdj);
+ }
return success;
}
@@ -3704,6 +3755,7 @@ public class OomAdjuster {
if (mService.mLocalPowerManager != null) {
mService.mLocalPowerManager.startUidChanges();
}
+ boolean shouldLogMisc = false;
for (int i = N - 1; i >= 0; i--) {
final UidRecord uidRec = mActiveUids.valueAt(i);
final long bgTime = uidRec.getLastBackgroundTime();
@@ -3721,6 +3773,9 @@ public class OomAdjuster {
if (nextTime == 0 || nextTime > bgTime) {
nextTime = bgTime;
}
+ if (mLogger.shouldLog(uidRec.getUid())) {
+ shouldLogMisc = true;
+ }
}
}
}
@@ -3742,8 +3797,11 @@ public class OomAdjuster {
}
}
if (nextTime > 0) {
- mService.mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
- nextTime + mConstants.BACKGROUND_SETTLE_TIME - nowElapsed);
+ long delay = nextTime + mConstants.BACKGROUND_SETTLE_TIME - nowElapsed;
+ if (shouldLogMisc) {
+ mLogger.logScheduleUidIdle3(delay);
+ }
+ mService.mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, delay);
}
}
diff --git a/services/core/java/com/android/server/am/OomAdjusterDebugLogger.java b/services/core/java/com/android/server/am/OomAdjusterDebugLogger.java
new file mode 100644
index 000000000000..1294a4d25c44
--- /dev/null
+++ b/services/core/java/com/android/server/am/OomAdjusterDebugLogger.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.am;
+
+import android.app.StackTrace;
+import android.util.Slog;
+
+/**
+ * Helper for writing debug log about proc/uid state changes.
+ */
+class OomAdjusterDebugLogger {
+ // Use the "am_" tag to make it similar to event logs.
+ private static final String STACK_TRACE_TAG = "am_stack";
+
+ private final OomAdjuster mOomAdjuster;
+ private final ActivityManagerConstants mConstants;
+
+ private static final int MISC_SCHEDULE_IDLE_UIDS_MSG_1 = 1;
+ private static final int MISC_SCHEDULE_IDLE_UIDS_MSG_2 = 2;
+ private static final int MISC_SCHEDULE_IDLE_UIDS_MSG_3 = 3;
+
+ private static final int MISC_SET_LAST_BG_TIME = 10;
+ private static final int MISC_CLEAR_LAST_BG_TIME = 11;
+
+ OomAdjusterDebugLogger(OomAdjuster oomAdjuster, ActivityManagerConstants constants) {
+ mOomAdjuster = oomAdjuster;
+ mConstants = constants;
+ }
+
+ boolean shouldLog(int uid) {
+ return mConstants.shouldDebugUidForProcState(uid);
+ }
+
+ private void maybeLogStacktrace(String msg) {
+ if (!mConstants.mEnableProcStateStacktrace) {
+ return;
+ }
+ Slog.i(STACK_TRACE_TAG,
+ msg + ": " + OomAdjuster.oomAdjReasonToString(mOomAdjuster.mLastReason),
+ new StackTrace("Called here"));
+ }
+
+ private void maybeSleep(int millis) {
+ if (millis == 0) {
+ return;
+ }
+ try {
+ Thread.sleep(millis);
+ } catch (InterruptedException e) {
+ }
+ }
+
+ void logUidStateChanged(int uid, int uidstate, int olduidstate,
+ int capability, int oldcapability, int flags) {
+ EventLogTags.writeAmUidStateChanged(
+ uid, mOomAdjuster.mAdjSeq, uidstate, olduidstate, capability, oldcapability, flags,
+ OomAdjuster.oomAdjReasonToString(mOomAdjuster.mLastReason));
+ maybeLogStacktrace("uidStateChanged");
+ maybeSleep(mConstants.mProcStateDebugSetUidStateDelay);
+ }
+
+ void logProcStateChanged(int uid, int pid, int procstate, int oldprocstate,
+ int oomadj, int oldoomadj) {
+ EventLogTags.writeAmProcStateChanged(
+ uid, pid, mOomAdjuster.mAdjSeq, procstate, oldprocstate, oomadj, oldoomadj,
+ OomAdjuster.oomAdjReasonToString(mOomAdjuster.mLastReason));
+ maybeLogStacktrace("procStateChanged");
+ maybeSleep(mConstants.mProcStateDebugSetProcStateDelay);
+ }
+
+ void logScheduleUidIdle1(int uid, long delay) {
+ EventLogTags.writeAmOomAdjMisc(MISC_SCHEDULE_IDLE_UIDS_MSG_1,
+ uid, 0, mOomAdjuster.mAdjSeq, (int) delay, 0, "");
+ }
+
+ void logScheduleUidIdle2(int uid, int pid, long delay) {
+ EventLogTags.writeAmOomAdjMisc(MISC_SCHEDULE_IDLE_UIDS_MSG_2,
+ uid, pid, mOomAdjuster.mAdjSeq, (int) delay, 0, "");
+ }
+
+ void logScheduleUidIdle3(long delay) {
+ EventLogTags.writeAmOomAdjMisc(MISC_SCHEDULE_IDLE_UIDS_MSG_3,
+ 0, 0, mOomAdjuster.mAdjSeq, (int) delay, 0, "");
+ }
+
+ void logSetLastBackgroundTime(int uid, long time) {
+ EventLogTags.writeAmOomAdjMisc(MISC_SET_LAST_BG_TIME,
+ uid, 0, mOomAdjuster.mAdjSeq, (int) time, 0,
+ OomAdjuster.oomAdjReasonToString(mOomAdjuster.mLastReason));
+ }
+
+ void logClearLastBackgroundTime(int uid) {
+ EventLogTags.writeAmOomAdjMisc(MISC_CLEAR_LAST_BG_TIME,
+ uid, 0, mOomAdjuster.mAdjSeq, 0, 0,
+ OomAdjuster.oomAdjReasonToString(mOomAdjuster.mLastReason));
+ }
+}
diff --git a/services/core/java/com/android/server/am/OomAdjusterModernImpl.java b/services/core/java/com/android/server/am/OomAdjusterModernImpl.java
index 46bdfe892040..5feac1ff92cb 100644
--- a/services/core/java/com/android/server/am/OomAdjusterModernImpl.java
+++ b/services/core/java/com/android/server/am/OomAdjusterModernImpl.java
@@ -741,6 +741,7 @@ public class OomAdjusterModernImpl extends OomAdjuster {
mPendingProcessSet.clear();
mService.mAppProfiler.mHasPreviousProcess = mService.mAppProfiler.mHasHomeProcess = false;
+ mLastReason = oomAdjReason;
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, oomAdjReasonToString(oomAdjReason));
mService.mOomAdjProfiler.oomAdjStarted();
@@ -761,6 +762,7 @@ public class OomAdjusterModernImpl extends OomAdjuster {
@GuardedBy("mService")
@Override
protected void performUpdateOomAdjPendingTargetsLocked(@OomAdjReason int oomAdjReason) {
+ mLastReason = oomAdjReason;
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, oomAdjReasonToString(oomAdjReason));
mService.mOomAdjProfiler.oomAdjStarted();
diff --git a/services/core/java/com/android/server/am/PendingIntentController.java b/services/core/java/com/android/server/am/PendingIntentController.java
index 5df910716ba6..fb0d6957129a 100644
--- a/services/core/java/com/android/server/am/PendingIntentController.java
+++ b/services/core/java/com/android/server/am/PendingIntentController.java
@@ -146,6 +146,21 @@ public class PendingIntentController {
ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED);
}
+ if (opts != null && opts.isPendingIntentBackgroundActivityLaunchAllowedByPermission()) {
+ Slog.wtf(TAG,
+ "Resetting option pendingIntentBackgroundActivityLaunchAllowedByPermission"
+ + " which is set by the pending intent creator ("
+ + packageName
+ + ") because this option is meant for the pending intent sender");
+ if (CompatChanges.isChangeEnabled(PendingIntent.PENDING_INTENT_OPTIONS_CHECK,
+ callingUid)) {
+ throw new IllegalArgumentException(
+ "pendingIntentBackgroundActivityLaunchAllowedByPermission "
+ + "can not be set by creator of a PendingIntent");
+ }
+ opts.setPendingIntentBackgroundActivityLaunchAllowedByPermission(false);
+ }
+
final boolean noCreate = (flags & PendingIntent.FLAG_NO_CREATE) != 0;
final boolean cancelCurrent = (flags & PendingIntent.FLAG_CANCEL_CURRENT) != 0;
final boolean updateCurrent = (flags & PendingIntent.FLAG_UPDATE_CURRENT) != 0;
diff --git a/services/core/java/com/android/server/am/flags.aconfig b/services/core/java/com/android/server/am/flags.aconfig
index e955b00566b8..7611f4078c73 100644
--- a/services/core/java/com/android/server/am/flags.aconfig
+++ b/services/core/java/com/android/server/am/flags.aconfig
@@ -52,6 +52,14 @@ flag {
flag {
namespace: "backstage_power"
+ name: "defer_outgoing_broadcasts"
+ description: "Defer outgoing broadcasts from processes in freezable state"
+ bug: "327496592"
+ is_fixed_read_only: true
+}
+
+flag {
+ namespace: "backstage_power"
name: "avoid_repeated_bcast_re_enqueues"
description: "Avoid re-enqueueing a broadcast repeatedly"
bug: "319225224"
@@ -60,3 +68,10 @@ flag {
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ namespace: "backstage_power"
+ name: "log_excessive_binder_proxies"
+ description: "Log the excessive incoming binder proxies into statsd"
+ bug: "298263955"
+}
diff --git a/services/core/java/com/android/server/biometrics/AuthService.java b/services/core/java/com/android/server/biometrics/AuthService.java
index e915688b95b1..b7e11a7fe261 100644
--- a/services/core/java/com/android/server/biometrics/AuthService.java
+++ b/services/core/java/com/android/server/biometrics/AuthService.java
@@ -20,7 +20,7 @@ package com.android.server.biometrics;
// TODO(b/141025588): Create separate internal and external permissions for AuthService.
// TODO(b/141025588): Get rid of the USE_FINGERPRINT permission.
-import static android.Manifest.permission.SET_BIOMETRIC_DIALOG_LOGO;
+import static android.Manifest.permission.SET_BIOMETRIC_DIALOG_ADVANCED;
import static android.Manifest.permission.TEST_BIOMETRIC;
import static android.Manifest.permission.USE_BIOMETRIC;
import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL;
@@ -1030,8 +1030,8 @@ public class AuthService extends SystemService {
}
private void checkManageBiometricPermission() {
- getContext().enforceCallingOrSelfPermission(SET_BIOMETRIC_DIALOG_LOGO,
- "Must have SET_BIOMETRIC_DIALOG_LOGO permission");
+ getContext().enforceCallingOrSelfPermission(SET_BIOMETRIC_DIALOG_ADVANCED,
+ "Must have SET_BIOMETRIC_DIALOG_ADVANCED permission");
}
private void checkPermission() {
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index b6a6658b6a64..d0a83a66dfba 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -5862,6 +5862,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
p.println(" curSession=" + c.mCurSession);
};
mClientController.forAllClients(clientControllerDump);
+ p.println(" mCurrentUserId=" + mCurrentUserId);
p.println(" mCurMethodId=" + getSelectedMethodIdLocked());
client = mCurClient;
p.println(" mCurClient=" + client + " mCurSeq=" + getSequenceNumberLocked());
@@ -5887,8 +5888,6 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
? Arrays.toString(mStylusIds.toArray()) : ""));
p.println(" mSwitchingController:");
mSwitchingController.dump(p);
- p.println(" mSettings:");
- settings.dump(p, " ");
p.println(" mStartInputHistory:");
mStartInputHistory.dump(pw, " ");
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 97ce77c71138..18b495bfce5d 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -340,8 +340,6 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
static final String TAG = NetworkPolicyLogger.TAG;
private static final boolean LOGD = NetworkPolicyLogger.LOGD;
private static final boolean LOGV = NetworkPolicyLogger.LOGV;
- // TODO: b/304347838 - Remove once the feature is in staging.
- private static final boolean ALWAYS_RESTRICT_BACKGROUND_NETWORK = false;
/**
* No opportunistic quota could be calculated from user data plan or data settings.
@@ -1070,8 +1068,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
}
// The flag is boot-stable.
- mBackgroundNetworkRestricted = ALWAYS_RESTRICT_BACKGROUND_NETWORK
- && Flags.networkBlockedForTopSleepingAndAbove();
+ mBackgroundNetworkRestricted = Flags.networkBlockedForTopSleepingAndAbove();
if (mBackgroundNetworkRestricted) {
// Firewall rules and UidBlockedState will get updated in
// updateRulesForGlobalChangeAL below.
diff --git a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
index c9fd2610bfb7..19191374f12a 100644
--- a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
+++ b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
@@ -217,8 +217,7 @@ public class UserRestrictionsUtils {
private static final Set<String> IMMUTABLE_BY_OWNERS = Sets.newArraySet(
UserManager.DISALLOW_RECORD_AUDIO,
UserManager.DISALLOW_WALLPAPER,
- UserManager.DISALLOW_OEM_UNLOCK,
- UserManager.DISALLOW_ADD_PRIVATE_PROFILE
+ UserManager.DISALLOW_OEM_UNLOCK
);
/**
@@ -293,7 +292,8 @@ public class UserRestrictionsUtils {
UserManager.DISALLOW_USB_FILE_TRANSFER,
UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA,
UserManager.DISALLOW_UNMUTE_MICROPHONE,
- UserManager.DISALLOW_CONFIG_DEFAULT_APPS
+ UserManager.DISALLOW_CONFIG_DEFAULT_APPS,
+ UserManager.DISALLOW_ADD_PRIVATE_PROFILE
);
/**
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 6ff8cf3cc2c8..ea9ab30e6293 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -3949,7 +3949,7 @@ public final class PowerManagerService extends SystemService
UserspaceRebootLogger.noteUserspaceRebootWasRequested();
}
if (mHandler == null || !mSystemReady) {
- if (RescueParty.isAttemptingFactoryReset()) {
+ if (RescueParty.isRecoveryTriggeredReboot()) {
// If we're stuck in a really low-level reboot loop, and a
// rescue party is trying to prompt the user for a factory data
// reset, we must GET TO DA CHOPPA!
diff --git a/services/core/java/com/android/server/power/ShutdownThread.java b/services/core/java/com/android/server/power/ShutdownThread.java
index 4bf8a78a1f16..afcf49daf0c4 100644
--- a/services/core/java/com/android/server/power/ShutdownThread.java
+++ b/services/core/java/com/android/server/power/ShutdownThread.java
@@ -337,7 +337,7 @@ public final class ShutdownThread extends Thread {
com.android.internal.R.string.reboot_to_update_reboot));
}
} else if (mReason != null && mReason.equals(PowerManager.REBOOT_RECOVERY)) {
- if (RescueParty.isAttemptingFactoryReset()) {
+ if (RescueParty.isRecoveryTriggeredReboot()) {
// We're not actually doing a factory reset yet; we're rebooting
// to ask the user if they'd like to reset, so give them a less
// scary dialog message.
diff --git a/services/core/java/com/android/server/power/hint/HintManagerService.java b/services/core/java/com/android/server/power/hint/HintManagerService.java
index 35717af962ef..aa1a41eee220 100644
--- a/services/core/java/com/android/server/power/hint/HintManagerService.java
+++ b/services/core/java/com/android/server/power/hint/HintManagerService.java
@@ -24,6 +24,7 @@ import android.app.ActivityManagerInternal;
import android.app.StatsManager;
import android.app.UidObserver;
import android.content.Context;
+import android.hardware.power.WorkDuration;
import android.os.Binder;
import android.os.IBinder;
import android.os.IHintManager;
@@ -32,7 +33,6 @@ import android.os.PerformanceHintManager;
import android.os.Process;
import android.os.RemoteException;
import android.os.SystemProperties;
-import android.os.WorkDuration;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -198,8 +198,8 @@ public final class HintManagerService extends SystemService {
private static native void nativeSetMode(long halPtr, int mode, boolean enabled);
- private static native void nativeReportActualWorkDuration(long halPtr,
- WorkDuration[] workDurations);
+ private static native void nativeReportActualWorkDuration(
+ long halPtr, WorkDuration[] workDurations);
/** Wrapper for HintManager.nativeInit */
public void halInit() {
@@ -670,46 +670,46 @@ public final class HintManagerService extends SystemService {
void validateWorkDuration(WorkDuration workDuration) {
if (DEBUG) {
- Slogf.d(TAG, "WorkDuration(" + workDuration.getTimestampNanos() + ", "
- + workDuration.getWorkPeriodStartTimestampNanos() + ", "
- + workDuration.getActualTotalDurationNanos() + ", "
- + workDuration.getActualCpuDurationNanos() + ", "
- + workDuration.getActualGpuDurationNanos() + ")");
+ Slogf.d(TAG, "WorkDuration("
+ + workDuration.durationNanos + ", "
+ + workDuration.workPeriodStartTimestampNanos + ", "
+ + workDuration.cpuDurationNanos + ", "
+ + workDuration.gpuDurationNanos + ")");
}
// Allow work period start timestamp to be zero in system server side because
// legacy API call will use zero value. It can not be estimated with the timestamp
// the sample is received because the samples could stack up.
- if (workDuration.getWorkPeriodStartTimestampNanos() < 0) {
+ if (workDuration.durationNanos <= 0) {
throw new IllegalArgumentException(
- TextUtils.formatSimple(
- "Work period start timestamp (%d) should be greater than 0",
- workDuration.getWorkPeriodStartTimestampNanos()));
+ TextUtils.formatSimple("Actual total duration (%d) should be greater than 0",
+ workDuration.durationNanos));
}
- if (workDuration.getActualTotalDurationNanos() <= 0) {
+ if (workDuration.workPeriodStartTimestampNanos < 0) {
throw new IllegalArgumentException(
- TextUtils.formatSimple("Actual total duration (%d) should be greater than 0",
- workDuration.getActualTotalDurationNanos()));
+ TextUtils.formatSimple(
+ "Work period start timestamp (%d) should be greater than 0",
+ workDuration.workPeriodStartTimestampNanos));
}
- if (workDuration.getActualCpuDurationNanos() < 0) {
+ if (workDuration.cpuDurationNanos < 0) {
throw new IllegalArgumentException(
TextUtils.formatSimple(
"Actual CPU duration (%d) should be greater than or equal to 0",
- workDuration.getActualCpuDurationNanos()));
+ workDuration.cpuDurationNanos));
}
- if (workDuration.getActualGpuDurationNanos() < 0) {
+ if (workDuration.gpuDurationNanos < 0) {
throw new IllegalArgumentException(
TextUtils.formatSimple(
"Actual GPU duration (%d) should greater than or equal to 0",
- workDuration.getActualGpuDurationNanos()));
+ workDuration.gpuDurationNanos));
}
- if (workDuration.getActualCpuDurationNanos()
- + workDuration.getActualGpuDurationNanos() <= 0) {
+ if (workDuration.cpuDurationNanos
+ + workDuration.gpuDurationNanos <= 0) {
throw new IllegalArgumentException(
TextUtils.formatSimple(
"The actual CPU duration (%d) and the actual GPU duration (%d)"
- + " should not both be 0", workDuration.getActualCpuDurationNanos(),
- workDuration.getActualGpuDurationNanos()));
+ + " should not both be 0", workDuration.cpuDurationNanos,
+ workDuration.gpuDurationNanos));
}
}
diff --git a/services/core/java/com/android/server/vcn/TelephonySubscriptionTracker.java b/services/core/java/com/android/server/vcn/TelephonySubscriptionTracker.java
index 7206c0377bf7..ecd140e23ab6 100644
--- a/services/core/java/com/android/server/vcn/TelephonySubscriptionTracker.java
+++ b/services/core/java/com/android/server/vcn/TelephonySubscriptionTracker.java
@@ -89,7 +89,7 @@ public class TelephonySubscriptionTracker extends BroadcastReceiver {
@NonNull private final TelephonyManager mTelephonyManager;
@NonNull private final SubscriptionManager mSubscriptionManager;
- @NonNull private final CarrierConfigManager mCarrierConfigManager;
+ @Nullable private final CarrierConfigManager mCarrierConfigManager;
@NonNull private final ActiveDataSubscriptionIdListener mActiveDataSubIdListener;
@@ -158,8 +158,10 @@ public class TelephonySubscriptionTracker extends BroadcastReceiver {
mSubscriptionManager.addOnSubscriptionsChangedListener(
executor, mSubscriptionChangedListener);
mTelephonyManager.registerTelephonyCallback(executor, mActiveDataSubIdListener);
- mCarrierConfigManager.registerCarrierConfigChangeListener(executor,
- mCarrierConfigChangeListener);
+ if (mCarrierConfigManager != null) {
+ mCarrierConfigManager.registerCarrierConfigChangeListener(executor,
+ mCarrierConfigChangeListener);
+ }
registerCarrierPrivilegesCallbacks();
}
@@ -200,7 +202,10 @@ public class TelephonySubscriptionTracker extends BroadcastReceiver {
mContext.unregisterReceiver(this);
mSubscriptionManager.removeOnSubscriptionsChangedListener(mSubscriptionChangedListener);
mTelephonyManager.unregisterTelephonyCallback(mActiveDataSubIdListener);
- mCarrierConfigManager.unregisterCarrierConfigChangeListener(mCarrierConfigChangeListener);
+ if (mCarrierConfigManager != null) {
+ mCarrierConfigManager.unregisterCarrierConfigChangeListener(
+ mCarrierConfigChangeListener);
+ }
unregisterCarrierPrivilegesCallbacks();
}
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperDataParser.java b/services/core/java/com/android/server/wallpaper/WallpaperDataParser.java
index 65ab12930c59..7f53ea372687 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperDataParser.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperDataParser.java
@@ -336,6 +336,9 @@ public class WallpaperDataParser {
parser.getAttributeInt(null, "cropRight" + pair.second, 0),
parser.getAttributeInt(null, "cropBottom" + pair.second, 0));
if (!cropHint.isEmpty()) wallpaper.mCropHints.put(pair.first, cropHint);
+ if (!cropHint.isEmpty() && cropHint.equals(legacyCropHint)) {
+ wallpaper.mOrientationWhenSet = pair.first;
+ }
}
if (wallpaper.mCropHints.size() == 0 && totalCropHint.isEmpty()) {
// migration case: the crops per screen orientation are not specified.
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 04e298810dad..6fa6957f2949 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -328,7 +328,6 @@ import android.os.Process;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.SystemClock;
-import android.os.SystemProperties;
import android.os.Trace;
import android.os.UserHandle;
import android.service.contentcapture.ActivityEvent;
@@ -1004,10 +1003,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
// Whether the Activity allows state sharing in untrusted embedding
private final boolean mAllowUntrustedEmbeddingStateSharing;
- // TODO(b/329378309): Remove this once the overview handles the configuration correctly.
- private static final boolean OVERRIDE_OVERVIEW_CONFIGURATION =
- SystemProperties.getBoolean("persist.wm.debug.override_overview_configuration", true);
-
// Records whether client has overridden the WindowAnimation_(Open/Close)(Enter/Exit)Animation.
private CustomAppTransition mCustomOpenTransition;
private CustomAppTransition mCustomCloseTransition;
@@ -8613,12 +8608,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
if (rotation == ROTATION_UNDEFINED && !isFixedRotationTransforming()) {
rotation = mDisplayContent.getRotation();
}
- final int activityType = inOutConfig.windowConfiguration.getActivityType();
- if (OVERRIDE_OVERVIEW_CONFIGURATION
- && (activityType == ACTIVITY_TYPE_HOME || activityType == ACTIVITY_TYPE_RECENTS)) {
- // Do not early return and provide the override. This should be removed shortly as we
- // don't override 1P components.
- } else if (!mWmService.mFlags.mInsetsDecoupledConfiguration
+ if (!mWmService.mFlags.mInsetsDecoupledConfiguration
|| info.isChangeEnabled(INSETS_DECOUPLED_CONFIGURATION_ENFORCED)
|| getCompatDisplayInsets() != null
|| isFloating(parentWindowingMode) || fullBounds == null
diff --git a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
index f7baa7914f86..2788342cb097 100644
--- a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
+++ b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
@@ -449,7 +449,48 @@ public class BackgroundActivityStartController {
this.mResultForRealCaller = resultForRealCaller;
}
- private String dump() {
+ public boolean isPendingIntentBalAllowedByPermission() {
+ return PendingIntentRecord.isPendingIntentBalAllowedByPermission(mCheckedOptions);
+ }
+
+ public boolean callerExplicitOptInOrAutoOptIn() {
+ if (mAutoOptInCaller) {
+ return !callerExplicitOptOut();
+ }
+ return mCheckedOptions.getPendingIntentCreatorBackgroundActivityStartMode()
+ == MODE_BACKGROUND_ACTIVITY_START_ALLOWED;
+ }
+
+ public boolean realCallerExplicitOptInOrAutoOptIn() {
+ if (mAutoOptInReason != null) {
+ return !realCallerExplicitOptOut();
+ }
+ return mCheckedOptions.getPendingIntentBackgroundActivityStartMode()
+ == MODE_BACKGROUND_ACTIVITY_START_ALLOWED;
+ }
+
+ public boolean callerExplicitOptOut() {
+ return mCheckedOptions.getPendingIntentCreatorBackgroundActivityStartMode()
+ == MODE_BACKGROUND_ACTIVITY_START_DENIED;
+ }
+
+ public boolean realCallerExplicitOptOut() {
+ return mCheckedOptions.getPendingIntentBackgroundActivityStartMode()
+ == MODE_BACKGROUND_ACTIVITY_START_DENIED;
+ }
+
+ public boolean callerExplicitOptInOrOut() {
+ return mCheckedOptions.getPendingIntentCreatorBackgroundActivityStartMode()
+ != MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED;
+ }
+
+ public boolean realCallerExplicitOptInOrOut() {
+ return mCheckedOptions.getPendingIntentBackgroundActivityStartMode()
+ != MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED;
+ }
+
+ @Override
+ public String toString() {
StringBuilder sb = new StringBuilder(2048);
sb.append("[callingPackage: ")
.append(getDebugPackageName(mCallingPackage, mCallingUid));
@@ -501,51 +542,6 @@ public class BackgroundActivityStartController {
sb.append("]");
return sb.toString();
}
-
- public boolean isPendingIntentBalAllowedByPermission() {
- return PendingIntentRecord.isPendingIntentBalAllowedByPermission(mCheckedOptions);
- }
-
- public boolean callerExplicitOptInOrAutoOptIn() {
- if (mAutoOptInCaller) {
- return !callerExplicitOptOut();
- }
- return mCheckedOptions.getPendingIntentCreatorBackgroundActivityStartMode()
- == MODE_BACKGROUND_ACTIVITY_START_ALLOWED;
- }
-
- public boolean realCallerExplicitOptInOrAutoOptIn() {
- if (mAutoOptInReason != null) {
- return !realCallerExplicitOptOut();
- }
- return mCheckedOptions.getPendingIntentBackgroundActivityStartMode()
- == MODE_BACKGROUND_ACTIVITY_START_ALLOWED;
- }
-
- public boolean callerExplicitOptOut() {
- return mCheckedOptions.getPendingIntentCreatorBackgroundActivityStartMode()
- == MODE_BACKGROUND_ACTIVITY_START_DENIED;
- }
-
- public boolean realCallerExplicitOptOut() {
- return mCheckedOptions.getPendingIntentBackgroundActivityStartMode()
- == MODE_BACKGROUND_ACTIVITY_START_DENIED;
- }
-
- public boolean callerExplicitOptInOrOut() {
- return mCheckedOptions.getPendingIntentCreatorBackgroundActivityStartMode()
- != MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED;
- }
-
- public boolean realCallerExplicitOptInOrOut() {
- return mCheckedOptions.getPendingIntentBackgroundActivityStartMode()
- != MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED;
- }
-
- @Override
- public String toString() {
- return dump();
- }
}
static class BalVerdict {
@@ -700,8 +696,7 @@ public class BackgroundActivityStartController {
if (!state.hasRealCaller()) {
if (resultForCaller.allows()) {
if (DEBUG_ACTIVITY_STARTS) {
- Slog.d(TAG, "Background activity start allowed. "
- + state.dump());
+ Slog.d(TAG, "Background activity start allowed. " + state);
}
return allowBasedOnCaller(state);
}
@@ -729,15 +724,13 @@ public class BackgroundActivityStartController {
// Handle cases with explicit opt-in
if (resultForCaller.allows() && state.callerExplicitOptInOrAutoOptIn()) {
if (DEBUG_ACTIVITY_STARTS) {
- Slog.d(TAG, "Activity start explicitly allowed by caller. "
- + state.dump());
+ Slog.d(TAG, "Activity start explicitly allowed by caller. " + state);
}
return allowBasedOnCaller(state);
}
if (resultForRealCaller.allows() && state.realCallerExplicitOptInOrAutoOptIn()) {
if (DEBUG_ACTIVITY_STARTS) {
- Slog.d(TAG, "Activity start explicitly allowed by real caller. "
- + state.dump());
+ Slog.d(TAG, "Activity start explicitly allowed by real caller. " + state);
}
return allowBasedOnRealCaller(state);
}
@@ -750,7 +743,7 @@ public class BackgroundActivityStartController {
if (state.mBalAllowedByPiCreator.allowsBackgroundActivityStarts()) {
Slog.wtf(TAG, "With Android 15 BAL hardening this activity start may be blocked"
+ " if the PI creator upgrades target_sdk to 35+! "
- + " (missing opt in by PI creator)!" + state.dump());
+ + " (missing opt in by PI creator)!" + state);
return allowBasedOnCaller(state);
}
}
@@ -759,7 +752,7 @@ public class BackgroundActivityStartController {
if (state.mBalAllowedByPiSender.allowsBackgroundActivityStarts()) {
Slog.wtf(TAG, "With Android 14 BAL hardening this activity start will be blocked"
+ " if the PI sender upgrades target_sdk to 34+! "
- + " (missing opt in by PI sender)!" + state.dump());
+ + " (missing opt in by PI sender)!" + state);
return allowBasedOnRealCaller(state);
}
}
@@ -773,23 +766,20 @@ public class BackgroundActivityStartController {
private BalVerdict allowBasedOnCaller(BalState state) {
if (DEBUG_ACTIVITY_STARTS) {
- Slog.d(TAG, "Background activity launch allowed based on caller. "
- + state.dump());
+ Slog.d(TAG, "Background activity launch allowed based on caller. " + state);
}
return statsLog(state.mResultForCaller, state);
}
private BalVerdict allowBasedOnRealCaller(BalState state) {
if (DEBUG_ACTIVITY_STARTS) {
- Slog.d(TAG, "Background activity launch allowed based on real caller. "
- + state.dump());
+ Slog.d(TAG, "Background activity launch allowed based on real caller. " + state);
}
return statsLog(state.mResultForRealCaller, state);
}
private BalVerdict abortLaunch(BalState state) {
- Slog.wtf(TAG, "Background activity launch blocked! "
- + state.dump());
+ Slog.wtf(TAG, "Background activity launch blocked! " + state);
if (balShowToastsBlocked()
&& (state.mResultForCaller.allows() || state.mResultForRealCaller.allows())) {
// only show a toast if either caller or real caller could launch if they opted in
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 56e6107d489e..1dcfde464a97 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -3521,6 +3521,9 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
}
void enableHighPerfTransition(boolean enable) {
+ if (!mWmService.mSupportsHighPerfTransitions) {
+ return;
+ }
if (!explicitRefreshRateHints()) {
if (enable) {
getPendingTransaction().setEarlyWakeupStart();
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index e789fecb8625..16f7373ebc5e 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -117,6 +117,7 @@ import android.view.InsetsState;
import android.view.Surface;
import android.view.View;
import android.view.ViewDebug;
+import android.view.WindowInsets;
import android.view.WindowInsets.Type;
import android.view.WindowInsets.Type.InsetsType;
import android.view.WindowLayout;
@@ -969,19 +970,30 @@ public class DisplayPolicy {
break;
case TYPE_BASE_APPLICATION:
-
- // A non-translucent main app window isn't allowed to fit insets or display cutouts,
- // as it would create a hole on the display!
if (attrs.isFullscreen() && win.mActivityRecord != null
&& win.mActivityRecord.fillsParent()
- && (attrs.privateFlags & PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS) != 0
- && (attrs.getFitInsetsTypes() != 0
- || (attrs.privateFlags & PRIVATE_FLAG_EDGE_TO_EDGE_ENFORCED) != 0
- && attrs.layoutInDisplayCutoutMode
- != LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS)) {
- throw new IllegalArgumentException("Illegal attributes: Main activity window"
- + " that isn't translucent trying to fit insets or display cutouts."
- + " attrs=" + attrs);
+ && (attrs.privateFlags & PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS) != 0) {
+ if (attrs.getFitInsetsTypes() != 0) {
+ // A non-translucent main app window isn't allowed to fit insets,
+ // as it would create a hole on the display!
+ throw new IllegalArgumentException("Illegal attributes: Main window of "
+ + win.mActivityRecord.getName() + " that isn't translucent trying"
+ + " to fit insets. fitInsetsTypes=" + WindowInsets.Type.toString(
+ attrs.getFitInsetsTypes()));
+ }
+ if ((attrs.privateFlags & PRIVATE_FLAG_EDGE_TO_EDGE_ENFORCED) != 0
+ && attrs.layoutInDisplayCutoutMode
+ != LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS) {
+ // A non-translucent main window of the app enforced to go edge-to-edge
+ // isn't allowed to fit display cutout, or it will cause software bezels.
+ throw new IllegalArgumentException("Illegal attributes: Main window of "
+ + win.mActivityRecord.getName() + " that isn't translucent and"
+ + " targets SDK level " + win.mActivityRecord.mTargetSdk
+ + " (>= 35) trying to specify layoutInDisplayCutoutMode as '"
+ + WindowManager.LayoutParams.layoutInDisplayCutoutModeToString(
+ attrs.layoutInDisplayCutoutMode)
+ + "' instead of 'always'");
+ }
}
break;
}
diff --git a/services/core/java/com/android/server/wm/DragDropController.java b/services/core/java/com/android/server/wm/DragDropController.java
index 34ea4ac35224..8116f6870f66 100644
--- a/services/core/java/com/android/server/wm/DragDropController.java
+++ b/services/core/java/com/android/server/wm/DragDropController.java
@@ -16,6 +16,7 @@
package com.android.server.wm;
+import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.view.View.DRAG_FLAG_GLOBAL;
import static android.view.View.DRAG_FLAG_GLOBAL_SAME_APPLICATION;
import static android.view.View.DRAG_FLAG_START_INTENT_SENDER_ON_UNHANDLED_DRAG;
@@ -36,6 +37,7 @@ import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
+import android.os.Trace;
import android.util.Slog;
import android.view.Display;
import android.view.DragEvent;
@@ -52,6 +54,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.server.wm.WindowManagerInternal.IDragDropCallback;
import java.util.Objects;
+import java.util.Random;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
@@ -386,6 +389,9 @@ class DragDropController {
+ "(listener=" + mGlobalDragListener + ", flags=" + mDragState.mFlags + ")");
return false;
}
+ final int traceCookie = new Random().nextInt();
+ Trace.asyncTraceBegin(TRACE_TAG_WINDOW_MANAGER, "DragDropController#notifyUnhandledDrop",
+ traceCookie);
if (DEBUG_DRAG) Slog.d(TAG_WM, "Sending DROP to unhandled listener (" + reason + ")");
try {
// Schedule timeout for the unhandled drag listener to call back
@@ -396,6 +402,8 @@ class DragDropController {
if (DEBUG_DRAG) Slog.d(TAG_WM, "Unhandled listener finished handling DROP");
synchronized (mService.mGlobalLock) {
onUnhandledDropCallback(consumedByListener);
+ Trace.asyncTraceEnd(TRACE_TAG_WINDOW_MANAGER,
+ "DragDropController#notifyUnhandledDrop", traceCookie);
}
}
});
diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java
index b266caa82056..5ed343a4d028 100644
--- a/services/core/java/com/android/server/wm/DragState.java
+++ b/services/core/java/com/android/server/wm/DragState.java
@@ -20,6 +20,7 @@ import static android.content.ClipDescription.MIMETYPE_APPLICATION_ACTIVITY;
import static android.content.ClipDescription.MIMETYPE_APPLICATION_SHORTCUT;
import static android.content.ClipDescription.MIMETYPE_APPLICATION_TASK;
import static android.os.InputConstants.DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
+import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_INTERCEPT_GLOBAL_DRAG_AND_DROP;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ORIENTATION;
@@ -49,6 +50,7 @@ import android.os.Binder;
import android.os.Build;
import android.os.IBinder;
import android.os.RemoteException;
+import android.os.Trace;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.Slog;
@@ -258,6 +260,7 @@ class DragState {
}
mNotifiedWindows.clear();
mDragInProgress = false;
+ Trace.instant(TRACE_TAG_WINDOW_MANAGER, "DragDropController#DRAG_ENDED");
}
// Take the cursor back if it has been changed.
@@ -343,6 +346,18 @@ class DragState {
if (mAnimator != null) {
return false;
}
+ try {
+ Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "DragDropController#DROP");
+ return reportDropWindowLockInner(token, x, y);
+ } finally {
+ Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
+ }
+ }
+
+ private boolean reportDropWindowLockInner(IBinder token, float x, float y) {
+ if (mAnimator != null) {
+ return false;
+ }
final WindowState touchedWin = mService.mInputToWindowMap.get(token);
final DragEvent unhandledDropEvent = createDropEvent(x, y, null /* touchedWin */,
@@ -355,10 +370,12 @@ class DragState {
return true;
}
+ Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "DragDropController#noWindow");
// "drop" outside a valid window -- no recipient to apply a timeout to, and we can send
// the drag-ended message immediately.
endDragLocked(false /* consumed */, false /* relinquishDragSurfaceToDropTarget */);
if (DEBUG_DRAG) Slog.d(TAG_WM, "Drop outside a valid window " + touchedWin);
+ Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
return false;
}
@@ -367,6 +384,7 @@ class DragState {
final IBinder clientToken = touchedWin.mClient.asBinder();
final DragEvent event = createDropEvent(x, y, touchedWin, false /* includePrivateInfo */);
try {
+ Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "DragDropController#dispatchDrop");
touchedWin.mClient.dispatchDragEvent(event);
// 5 second timeout for this window to respond to the drop
@@ -380,6 +398,7 @@ class DragState {
if (MY_PID != touchedWin.mSession.mPid) {
event.recycle();
}
+ Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
mToken = clientToken;
mUnhandledDropEvent = unhandledDropEvent;
@@ -471,6 +490,7 @@ class DragState {
/* call out to each visible window/session informing it about the drag
*/
void broadcastDragStartedLocked(final float touchX, final float touchY) {
+ Trace.instant(TRACE_TAG_WINDOW_MANAGER, "DragDropController#DRAG_STARTED");
mOriginalX = mCurrentX = touchX;
mOriginalY = mCurrentY = touchY;
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 0e66fcf4b2f0..207b1bbcea16 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -538,7 +538,7 @@ public class WindowManagerService extends IWindowManager.Stub
final boolean mHasPermanentDpad;
final long mDrawLockTimeoutMillis;
final boolean mAllowAnimationsInLowPowerMode;
-
+ final boolean mSupportsHighPerfTransitions;
final boolean mAllowBootMessages;
// Indicates whether the Assistant should show on top of the Dream (respectively, above
@@ -1181,6 +1181,8 @@ public class WindowManagerService extends IWindowManager.Stub
com.android.internal.R.bool.config_allowAnimationsInLowPowerMode);
mMaxUiWidth = context.getResources().getInteger(
com.android.internal.R.integer.config_maxUiWidth);
+ mSupportsHighPerfTransitions = context.getResources().getBoolean(
+ com.android.internal.R.bool.config_deviceSupportsHighPerfTransitions);
mDisableTransitionAnimation = context.getResources().getBoolean(
com.android.internal.R.bool.config_disableTransitionAnimation);
mPerDisplayFocusEnabled = context.getResources().getBoolean(
@@ -1192,6 +1194,7 @@ public class WindowManagerService extends IWindowManager.Stub
final boolean isScreenSizeDecoupledFromStatusBarAndCutout = context.getResources()
.getBoolean(R.bool.config_decoupleStatusBarAndDisplayCutoutFromScreenSize)
&& mFlags.mAllowsScreenSizeDecoupledFromStatusBarAndCutout;
+
if (mFlags.mInsetsDecoupledConfiguration) {
mDecorTypes = 0;
mConfigTypes = 0;
diff --git a/services/core/java/com/android/server/wm/utils/OptPropFactory.java b/services/core/java/com/android/server/wm/utils/OptPropFactory.java
new file mode 100644
index 000000000000..8201969b7c46
--- /dev/null
+++ b/services/core/java/com/android/server/wm/utils/OptPropFactory.java
@@ -0,0 +1,233 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.utils;
+
+import static java.lang.Boolean.FALSE;
+import static java.lang.Boolean.TRUE;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.content.pm.PackageManager;
+import android.util.Slog;
+
+import java.util.function.BooleanSupplier;
+
+/**
+ * Utility class which helps with handling with properties to opt-in or
+ * opt-out a specific feature.
+ */
+public class OptPropFactory {
+
+ @NonNull
+ private final PackageManager mPackageManager;
+
+ @NonNull
+ private final String mPackageName;
+
+ /**
+ * Object responsible to handle optIn and optOut properties.
+ *
+ * @param packageManager The PackageManager reference
+ * @param packageName The name of the package.
+ */
+ public OptPropFactory(@NonNull PackageManager packageManager, @NonNull String packageName) {
+ mPackageManager = packageManager;
+ mPackageName = packageName;
+ }
+
+ /**
+ * Creates an OptProp for the given property
+ *
+ * @param propertyName The name of the property.
+ * @return The OptProp for the given property
+ */
+ @NonNull
+ public OptProp create(@NonNull String propertyName) {
+ return OptProp.create(
+ () -> mPackageManager.getProperty(propertyName, mPackageName).getBoolean(),
+ propertyName);
+ }
+
+ /**
+ * Creates an OptProp for the given property behind a gate condition.
+ *
+ * @param propertyName The name of the property.
+ * @param gateCondition If this resolves to false, the property is unset. This is evaluated at
+ * every interaction with the OptProp.
+ * @return The OptProp for the given property
+ */
+ @NonNull
+ public OptProp create(@NonNull String propertyName, @NonNull BooleanSupplier gateCondition) {
+ return OptProp.create(
+ () -> mPackageManager.getProperty(propertyName, mPackageName).getBoolean(),
+ propertyName,
+ gateCondition);
+ }
+
+ @FunctionalInterface
+ private interface ThrowableBooleanSupplier {
+ boolean get() throws Exception;
+ }
+
+ public static class OptProp {
+
+ private static final int VALUE_UNSET = -2;
+ private static final int VALUE_UNDEFINED = -1;
+ private static final int VALUE_FALSE = 0;
+ private static final int VALUE_TRUE = 1;
+
+ @IntDef(prefix = {"VALUE_"}, value = {
+ VALUE_UNSET,
+ VALUE_UNDEFINED,
+ VALUE_FALSE,
+ VALUE_TRUE,
+ })
+ @interface OptionalValue {}
+
+ private static final String TAG = "OptProp";
+
+ // The condition is evaluated every time the OptProp state is accessed.
+ @NonNull
+ private final BooleanSupplier mCondition;
+
+ // This is evaluated only once in the lifetime of an OptProp.
+ @NonNull
+ private final ThrowableBooleanSupplier mValueSupplier;
+
+ @NonNull
+ private final String mPropertyName;
+
+ @OptionalValue
+ private int mValue = VALUE_UNDEFINED;
+
+ private OptProp(@NonNull ThrowableBooleanSupplier valueSupplier,
+ @NonNull String propertyName,
+ @NonNull BooleanSupplier condition) {
+ mValueSupplier = valueSupplier;
+ mPropertyName = propertyName;
+ mCondition = condition;
+ }
+
+ @NonNull
+ private static OptProp create(@NonNull ThrowableBooleanSupplier valueSupplier,
+ @NonNull String propertyName) {
+ return new OptProp(valueSupplier, propertyName, () -> true);
+ }
+
+ @NonNull
+ private static OptProp create(@NonNull ThrowableBooleanSupplier valueSupplier,
+ @NonNull String propertyName, @NonNull BooleanSupplier condition) {
+ return new OptProp(valueSupplier, propertyName, condition);
+ }
+
+ /**
+ * @return {@code true} when the guarding condition is {@code true} and the property has
+ * been explicitly set to {@code true}. {@code false} otherwise. The guarding condition is
+ * evaluated every time this method is invoked.
+ */
+ public boolean isTrue() {
+ return mCondition.getAsBoolean() && getValue() == VALUE_TRUE;
+ }
+
+ /**
+ * @return {@code true} when the guarding condition is {@code true} and the property has
+ * been explicitly set to {@code false}. {@code false} otherwise. The guarding condition is
+ * evaluated every time this method is invoked.
+ */
+ public boolean isFalse() {
+ return mCondition.getAsBoolean() && getValue() == VALUE_FALSE;
+ }
+
+ /**
+ * Returns {@code true} when the following conditions are met:
+ * <ul>
+ * <li>{@code gatingCondition} doesn't evaluate to {@code false}
+ * <li>App developers didn't opt out with a component {@code property}
+ * <li>App developers opted in with a component {@code property} or an OEM opted in with
+ * a per-app override
+ * </ul>
+ *
+ * <p>This is used for the treatments that are enabled only on per-app basis.
+ */
+ public boolean shouldEnableWithOverrideAndProperty(boolean overrideValue) {
+ if (!mCondition.getAsBoolean()) {
+ return false;
+ }
+ if (getValue() == VALUE_FALSE) {
+ return false;
+ }
+ return getValue() == VALUE_TRUE || overrideValue;
+ }
+
+ /**
+ * Returns {@code true} when the following conditions are met:
+ * <ul>
+ * <li>{@code gatingCondition} doesn't evaluate to {@code false}
+ * <li>App developers didn't opt out with a component {@code property}
+ * <li>OEM opted in with a per-app override
+ * </ul>
+ *
+ * <p>This is used for the treatments that are enabled based with the heuristic but can be
+ * disabled on per-app basis by OEMs or app developers.
+ */
+ public boolean shouldEnableWithOptInOverrideAndOptOutProperty(
+ boolean overrideValue) {
+ if (!mCondition.getAsBoolean()) {
+ return false;
+ }
+ return getValue() != VALUE_FALSE && overrideValue;
+ }
+
+ /**
+ * Returns {@code true} when the following conditions are met:
+ * <ul>
+ * <li>{@code gatingCondition} doesn't resolve to {@code false}
+ * <li>OEM didn't opt out with a per-app override
+ * <li>App developers didn't opt out with a component {@code property}
+ * </ul>
+ *
+ * <p>This is used for the treatments that are enabled based with the heuristic but can be
+ * disabled on per-app basis by OEMs or app developers.
+ */
+ public boolean shouldEnableWithOptOutOverrideAndProperty(boolean overrideValue) {
+ if (!mCondition.getAsBoolean()) {
+ return false;
+ }
+ return getValue() != VALUE_FALSE && !overrideValue;
+ }
+
+ @OptionalValue
+ private int getValue() {
+ if (mValue == VALUE_UNDEFINED) {
+ try {
+ final Boolean value = mValueSupplier.get();
+ if (TRUE.equals(value)) {
+ mValue = VALUE_TRUE;
+ } else if (FALSE.equals(value)) {
+ mValue = VALUE_FALSE;
+ } else {
+ mValue = VALUE_UNSET;
+ }
+ } catch (Exception e) {
+ Slog.w(TAG, "Cannot read opt property " + mPropertyName);
+ mValue = VALUE_UNSET;
+ }
+ }
+ return mValue;
+ }
+ }
+}
diff --git a/services/core/jni/com_android_server_hint_HintManagerService.cpp b/services/core/jni/com_android_server_hint_HintManagerService.cpp
index b2bdaa35f28c..5b8ef19ea179 100644
--- a/services/core/jni/com_android_server_hint_HintManagerService.cpp
+++ b/services/core/jni/com_android_server_hint_HintManagerService.cpp
@@ -19,8 +19,11 @@
//#define LOG_NDEBUG 0
#include <aidl/android/hardware/power/IPower.h>
+#include <aidl/android/os/IHintManager.h>
#include <android-base/stringprintf.h>
-#include <inttypes.h>
+#include <android/binder_manager.h>
+#include <android/binder_parcel.h>
+#include <android/binder_parcel_utils.h>
#include <nativehelper/JNIHelp.h>
#include <nativehelper/ScopedPrimitiveArray.h>
#include <powermanager/PowerHalController.h>
@@ -43,15 +46,16 @@ namespace android {
static struct {
jclass clazz{};
jfieldID workPeriodStartTimestampNanos{};
- jfieldID actualTotalDurationNanos{};
- jfieldID actualCpuDurationNanos{};
- jfieldID actualGpuDurationNanos{};
- jfieldID timestampNanos{};
+ jfieldID durationNanos{};
+ jfieldID cpuDurationNanos{};
+ jfieldID gpuDurationNanos{};
+ jfieldID timeStampNanos{};
} gWorkDurationInfo;
static power::PowerHalController gPowerHalController;
-static std::unordered_map<jlong, std::shared_ptr<PowerHintSessionWrapper>> gSessionMap;
static std::mutex gSessionMapLock;
+static std::unordered_map<jlong, std::shared_ptr<PowerHintSessionWrapper>> gSessionMap
+ GUARDED_BY(gSessionMapLock);
static int64_t getHintSessionPreferredRate() {
int64_t rate = -1;
@@ -63,15 +67,15 @@ static int64_t getHintSessionPreferredRate() {
}
static jlong createHintSession(JNIEnv* env, int32_t tgid, int32_t uid,
- std::vector<int32_t> threadIds, int64_t durationNanos) {
+ std::vector<int32_t>& threadIds, int64_t durationNanos) {
auto result = gPowerHalController.createHintSession(tgid, uid, threadIds, durationNanos);
if (result.isOk()) {
- auto session_ptr = reinterpret_cast<jlong>(result.value().get());
- {
- std::unique_lock<std::mutex> sessionLock(gSessionMapLock);
- auto res = gSessionMap.insert({session_ptr, result.value()});
- return res.second ? session_ptr : 0;
- }
+ jlong session_ptr = reinterpret_cast<jlong>(result.value().get());
+ std::scoped_lock sessionLock(gSessionMapLock);
+ auto res = gSessionMap.insert({session_ptr, result.value()});
+ return res.second ? session_ptr : 0;
+ } else if (result.isFailed()) {
+ ALOGW("createHintSession failed with message: %s", result.errorMessage());
}
return 0;
}
@@ -89,7 +93,7 @@ static void resumeHintSession(JNIEnv* env, int64_t session_ptr) {
static void closeHintSession(JNIEnv* env, int64_t session_ptr) {
auto appSession = reinterpret_cast<PowerHintSessionWrapper*>(session_ptr);
appSession->close();
- std::unique_lock<std::mutex> sessionLock(gSessionMapLock);
+ std::scoped_lock sessionLock(gSessionMapLock);
gSessionMap.erase(session_ptr);
}
@@ -135,11 +139,8 @@ static jlong nativeCreateHintSession(JNIEnv* env, jclass /* clazz */, jint tgid,
ALOGW("GetIntArrayElements returns nullptr.");
return 0;
}
- std::vector<int32_t> threadIds(tidArray.size());
- for (size_t i = 0; i < tidArray.size(); i++) {
- threadIds[i] = tidArray[i];
- }
- return createHintSession(env, tgid, uid, std::move(threadIds), durationNanos);
+ std::vector<int32_t> threadIds(tidArray.get(), tidArray.get() + tidArray.size());
+ return createHintSession(env, tgid, uid, threadIds, durationNanos);
}
static void nativePauseHintSession(JNIEnv* env, jclass /* clazz */, jlong session_ptr) {
@@ -177,12 +178,9 @@ static void nativeSendHint(JNIEnv* env, jclass /* clazz */, jlong session_ptr, j
}
static void nativeSetThreads(JNIEnv* env, jclass /* clazz */, jlong session_ptr, jintArray tids) {
- ScopedIntArrayRO arrayThreadIds(env, tids);
+ ScopedIntArrayRO tidArray(env, tids);
- std::vector<int32_t> threadIds(arrayThreadIds.size());
- for (size_t i = 0; i < arrayThreadIds.size(); i++) {
- threadIds[i] = arrayThreadIds[i];
- }
+ std::vector<int32_t> threadIds(tidArray.get(), tidArray.get() + tidArray.size());
setThreads(session_ptr, threadIds);
}
@@ -200,13 +198,13 @@ static void nativeReportActualWorkDuration2(JNIEnv* env, jclass /* clazz */, jlo
workDurations[i].workPeriodStartTimestampNanos =
env->GetLongField(workDuration, gWorkDurationInfo.workPeriodStartTimestampNanos);
workDurations[i].durationNanos =
- env->GetLongField(workDuration, gWorkDurationInfo.actualTotalDurationNanos);
+ env->GetLongField(workDuration, gWorkDurationInfo.durationNanos);
workDurations[i].cpuDurationNanos =
- env->GetLongField(workDuration, gWorkDurationInfo.actualCpuDurationNanos);
+ env->GetLongField(workDuration, gWorkDurationInfo.cpuDurationNanos);
workDurations[i].gpuDurationNanos =
- env->GetLongField(workDuration, gWorkDurationInfo.actualGpuDurationNanos);
+ env->GetLongField(workDuration, gWorkDurationInfo.gpuDurationNanos);
workDurations[i].timeStampNanos =
- env->GetLongField(workDuration, gWorkDurationInfo.timestampNanos);
+ env->GetLongField(workDuration, gWorkDurationInfo.timeStampNanos);
}
reportActualWorkDuration(session_ptr, workDurations);
}
@@ -225,22 +223,22 @@ static const JNINativeMethod sHintManagerServiceMethods[] = {
{"nativeSendHint", "(JI)V", (void*)nativeSendHint},
{"nativeSetThreads", "(J[I)V", (void*)nativeSetThreads},
{"nativeSetMode", "(JIZ)V", (void*)nativeSetMode},
- {"nativeReportActualWorkDuration", "(J[Landroid/os/WorkDuration;)V",
+ {"nativeReportActualWorkDuration", "(J[Landroid/hardware/power/WorkDuration;)V",
(void*)nativeReportActualWorkDuration2},
};
int register_android_server_HintManagerService(JNIEnv* env) {
- gWorkDurationInfo.clazz = env->FindClass("android/os/WorkDuration");
+ gWorkDurationInfo.clazz = env->FindClass("android/hardware/power/WorkDuration");
gWorkDurationInfo.workPeriodStartTimestampNanos =
- env->GetFieldID(gWorkDurationInfo.clazz, "mWorkPeriodStartTimestampNanos", "J");
- gWorkDurationInfo.actualTotalDurationNanos =
- env->GetFieldID(gWorkDurationInfo.clazz, "mActualTotalDurationNanos", "J");
- gWorkDurationInfo.actualCpuDurationNanos =
- env->GetFieldID(gWorkDurationInfo.clazz, "mActualCpuDurationNanos", "J");
- gWorkDurationInfo.actualGpuDurationNanos =
- env->GetFieldID(gWorkDurationInfo.clazz, "mActualGpuDurationNanos", "J");
- gWorkDurationInfo.timestampNanos =
- env->GetFieldID(gWorkDurationInfo.clazz, "mTimestampNanos", "J");
+ env->GetFieldID(gWorkDurationInfo.clazz, "workPeriodStartTimestampNanos", "J");
+ gWorkDurationInfo.durationNanos =
+ env->GetFieldID(gWorkDurationInfo.clazz, "durationNanos", "J");
+ gWorkDurationInfo.cpuDurationNanos =
+ env->GetFieldID(gWorkDurationInfo.clazz, "cpuDurationNanos", "J");
+ gWorkDurationInfo.gpuDurationNanos =
+ env->GetFieldID(gWorkDurationInfo.clazz, "gpuDurationNanos", "J");
+ gWorkDurationInfo.timeStampNanos =
+ env->GetFieldID(gWorkDurationInfo.clazz, "timeStampNanos", "J");
return jniRegisterNativeMethods(env,
"com/android/server/power/hint/"
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index c6189ed405a1..3b2a3dd9763a 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -408,6 +408,8 @@ public final class SystemServer implements Dumpable {
"com.android.server.searchui.SearchUiManagerService";
private static final String SMARTSPACE_MANAGER_SERVICE_CLASS =
"com.android.server.smartspace.SmartspaceManagerService";
+ private static final String CONTEXTUAL_SEARCH_MANAGER_SERVICE_CLASS =
+ "com.android.server.contextualsearch.ContextualSearchManagerService";
private static final String DEVICE_IDLE_CONTROLLER_CLASS =
"com.android.server.DeviceIdleController";
private static final String BLOB_STORE_MANAGER_SERVICE_CLASS =
@@ -2016,6 +2018,16 @@ public final class SystemServer implements Dumpable {
Slog.d(TAG, "SmartspaceManagerService not defined by OEM or disabled by flag");
}
+ // Contextual search manager service
+ if (deviceHasConfigString(context,
+ R.string.config_defaultContextualSearchPackageName)) {
+ t.traceBegin("StartContextualSearchService");
+ mSystemServiceManager.startService(CONTEXTUAL_SEARCH_MANAGER_SERVICE_CLASS);
+ t.traceEnd();
+ } else {
+ Slog.d(TAG, "ContextualSearchManagerService not defined or disabled by flag");
+ }
+
t.traceBegin("InitConnectivityModuleConnector");
try {
ConnectivityModuleConnector.getInstance().init(context);
diff --git a/services/tests/dreamservicetests/res/xml/test_dream_metadata.xml b/services/tests/dreamservicetests/res/xml/test_dream_metadata.xml
index 9211ec1a2f14..6e7d9ad00e34 100644
--- a/services/tests/dreamservicetests/res/xml/test_dream_metadata.xml
+++ b/services/tests/dreamservicetests/res/xml/test_dream_metadata.xml
@@ -17,4 +17,6 @@
<dream xmlns:android="http://schemas.android.com/apk/res/android"
android:settingsActivity=
"com.android.frameworks.dreamservicetests/.TestDreamSettingsActivity"
- android:showClockAndComplications="false" />
+ android:showClockAndComplications="false"
+ android:dreamCategory="home_panel"
+ />
diff --git a/services/tests/dreamservicetests/src/com/android/server/dreams/DreamServiceTest.java b/services/tests/dreamservicetests/src/com/android/server/dreams/DreamServiceTest.java
index d231e40f5d0d..293ab7baa355 100644
--- a/services/tests/dreamservicetests/src/com/android/server/dreams/DreamServiceTest.java
+++ b/services/tests/dreamservicetests/src/com/android/server/dreams/DreamServiceTest.java
@@ -48,6 +48,7 @@ public class DreamServiceTest {
assertThat(metadata.settingsActivity).isEqualTo(
ComponentName.unflattenFromString(testSettingsActivity));
assertFalse(metadata.showComplications);
+ assertThat(metadata.dreamCategory).isEqualTo(DreamService.DREAM_CATEGORY_HOME_PANEL);
}
@Test
@@ -58,6 +59,7 @@ public class DreamServiceTest {
final DreamService.DreamMetadata metadata = getDreamMetadata(testDreamClassName);
assertThat(metadata.settingsActivity).isNull();
+ assertThat(metadata.dreamCategory).isEqualTo(DreamService.DREAM_CATEGORY_DEFAULT);
}
private DreamService.DreamMetadata getDreamMetadata(String dreamClassName)
diff --git a/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java b/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java
index 211a83d8588e..c30ac2d6c248 100644
--- a/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java
@@ -439,19 +439,19 @@ public class RescuePartyTest {
}
@Test
- public void testIsAttemptingFactoryReset() {
+ public void testIsRecoveryTriggeredReboot() {
for (int i = 0; i < LEVEL_FACTORY_RESET; i++) {
noteBoot(i + 1);
}
assertFalse(RescueParty.isFactoryResetPropertySet());
setCrashRecoveryPropAttemptingReboot(false);
noteBoot(LEVEL_FACTORY_RESET + 1);
- assertTrue(RescueParty.isAttemptingFactoryReset());
+ assertTrue(RescueParty.isRecoveryTriggeredReboot());
assertTrue(RescueParty.isFactoryResetPropertySet());
}
@Test
- public void testIsAttemptingFactoryResetOnlyAfterRebootCompleted() {
+ public void testIsRecoveryTriggeredRebootOnlyAfterRebootCompleted() {
for (int i = 0; i < LEVEL_FACTORY_RESET; i++) {
noteBoot(i + 1);
}
@@ -464,7 +464,7 @@ public class RescuePartyTest {
noteBoot(mitigationCount++);
setCrashRecoveryPropAttemptingReboot(false);
noteBoot(mitigationCount + 1);
- assertTrue(RescueParty.isAttemptingFactoryReset());
+ assertTrue(RescueParty.isRecoveryTriggeredReboot());
assertTrue(RescueParty.isFactoryResetPropertySet());
}
@@ -477,7 +477,7 @@ public class RescuePartyTest {
for (int i = 1; i <= LEVEL_FACTORY_RESET; i++) {
noteBoot(i);
}
- assertFalse(RescueParty.isAttemptingFactoryReset());
+ assertFalse(RescueParty.isRecoveryTriggeredReboot());
}
@Test
@@ -489,7 +489,7 @@ public class RescuePartyTest {
for (int i = 0; i <= LEVEL_FACTORY_RESET; i++) {
noteAppCrash(i + 1, true);
}
- assertFalse(RescueParty.isAttemptingFactoryReset());
+ assertFalse(RescueParty.isRecoveryTriggeredReboot());
}
@Test
@@ -501,7 +501,7 @@ public class RescuePartyTest {
for (int i = 1; i <= LEVEL_FACTORY_RESET; i++) {
noteBoot(i);
}
- assertTrue(RescueParty.isAttemptingFactoryReset());
+ assertTrue(RescueParty.isRecoveryTriggeredReboot());
}
@Test
public void testNotThrottlingAfterTimeoutOnAppCrash() {
@@ -512,7 +512,7 @@ public class RescuePartyTest {
for (int i = 0; i <= LEVEL_FACTORY_RESET; i++) {
noteAppCrash(i + 1, true);
}
- assertTrue(RescueParty.isAttemptingFactoryReset());
+ assertTrue(RescueParty.isRecoveryTriggeredReboot());
}
@Test
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerServiceTest.java
index fcb3caa19b85..dc5b00a18d7b 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerServiceTest.java
@@ -28,10 +28,15 @@ import static android.app.ActivityManager.PROCESS_STATE_SERVICE;
import static android.app.ActivityManager.PROCESS_STATE_TOP;
import static android.app.ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
import static android.app.ActivityManager.PROCESS_STATE_UNKNOWN;
+import static android.os.PowerExemptionManager.REASON_DENIED;
import static android.util.DebugUtils.valueToString;
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
import static com.android.server.am.ActivityManagerInternalTest.CustomThread;
import static com.android.server.am.ActivityManagerService.Injector;
import static com.android.server.am.ProcessList.NETWORK_STATE_BLOCK;
@@ -52,28 +57,40 @@ import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.nullable;
+import static org.mockito.Mockito.after;
+import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.mockito.Mockito.when;
import android.Manifest;
import android.app.ActivityManager;
+import android.app.AppGlobals;
import android.app.AppOpsManager;
+import android.app.BackgroundStartPrivileges;
import android.app.BroadcastOptions;
+import android.app.ForegroundServiceDelegationOptions;
import android.app.IApplicationThread;
import android.app.IUidObserver;
+import android.app.Notification;
+import android.app.NotificationChannel;
import android.app.SyncNotedAppOp;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.ServiceConnection;
import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageManager;
import android.content.pm.PackageManagerInternal;
+import android.content.pm.ServiceInfo;
+import android.graphics.drawable.Icon;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
@@ -84,6 +101,7 @@ import android.os.Message;
import android.os.Process;
import android.os.RemoteException;
import android.os.SystemClock;
+import android.permission.IPermissionManager;
import android.platform.test.annotations.Presubmit;
import android.platform.test.annotations.RequiresFlagsEnabled;
import android.platform.test.flag.junit.CheckFlagsRule;
@@ -105,18 +123,20 @@ import com.android.server.am.ProcessList.IsolatedUidRange;
import com.android.server.am.ProcessList.IsolatedUidRangeAllocator;
import com.android.server.am.UidObserverController.ChangeRecord;
import com.android.server.appop.AppOpsService;
+import com.android.server.notification.NotificationManagerInternal;
+import com.android.server.wm.ActivityTaskManagerInternal;
import com.android.server.wm.ActivityTaskManagerService;
import org.junit.After;
-import org.junit.AfterClass;
import org.junit.Before;
-import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.MockitoSession;
+import org.mockito.quality.Strictness;
+import org.mockito.verification.VerificationMode;
import java.io.File;
import java.util.ArrayList;
@@ -127,13 +147,15 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
import java.util.function.Function;
/**
* Test class for {@link ActivityManagerService}.
*
* Build/Install/Run:
- * atest FrameworksServicesTests:ActivityManagerServiceTest
+ * atest FrameworksMockingServicesTests:ActivityManagerServiceTest
*/
@Presubmit
@SmallTest
@@ -148,6 +170,9 @@ public class ActivityManagerServiceTest {
private static final String TEST_EXTRA_KEY1 = "com.android.server.am.TEST_EXTRA_KEY1";
private static final String TEST_EXTRA_VALUE1 = "com.android.server.am.TEST_EXTRA_VALUE1";
+
+ private static final String TEST_PACKAGE_NAME = "com.android.server.am.testpackage";
+
private static final String PROPERTY_APPLY_SDK_SANDBOX_AUDIT_RESTRICTIONS =
"apply_sdk_sandbox_audit_restrictions";
private static final String PROPERTY_APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS =
@@ -155,6 +180,7 @@ public class ActivityManagerServiceTest {
private static final String APPLY_SDK_SANDBOX_AUDIT_RESTRICTIONS = ":isSdkSandboxAudit";
private static final String APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS = ":isSdkSandboxNext";
private static final int TEST_UID = 11111;
+ private static final int TEST_PID = 22222;
private static final int USER_ID = 666;
private static final long TEST_PROC_STATE_SEQ1 = 555;
@@ -169,22 +195,8 @@ public class ActivityManagerServiceTest {
UidRecord.CHANGE_CAPABILITY,
};
- private static PackageManagerInternal sPackageManagerInternal;
private static ProcessList.ProcessListSettingsListener sProcessListSettingsListener;
- @BeforeClass
- public static void setUpOnce() {
- sPackageManagerInternal = mock(PackageManagerInternal.class);
- doReturn(new ComponentName("", "")).when(sPackageManagerInternal)
- .getSystemUiServiceComponent();
- LocalServices.addService(PackageManagerInternal.class, sPackageManagerInternal);
- }
-
- @AfterClass
- public static void tearDownOnce() {
- LocalServices.removeServiceForTest(PackageManagerInternal.class);
- }
-
@Rule
public final ApplicationExitInfoTest.ServiceThreadRule
mServiceThreadRule = new ApplicationExitInfoTest.ServiceThreadRule();
@@ -196,15 +208,41 @@ public class ActivityManagerServiceTest {
@Mock private AppOpsService mAppOpsService;
@Mock private UserController mUserController;
+ @Mock private IPackageManager mPackageManager;
+ @Mock private IPermissionManager mPermissionManager;
+ @Mock private BatteryStatsService mBatteryStatsService;
+ @Mock private PackageManagerInternal mPackageManagerInternal;
+ @Mock private ActivityTaskManagerInternal mActivityTaskManagerInternal;
+ @Mock private NotificationManagerInternal mNotificationManagerInternal;
+
private TestInjector mInjector;
private ActivityManagerService mAms;
+ private ActiveServices mActiveServices;
private HandlerThread mHandlerThread;
private TestHandler mHandler;
+ private MockitoSession mMockingSession;
+
@Before
- public void setUp() {
+ public void setUp() throws Exception {
+ mMockingSession = mockitoSession()
+ .initMocks(this)
+ .mockStatic(AppGlobals.class)
+ .strictness(Strictness.LENIENT)
+ .startMocking();
MockitoAnnotations.initMocks(this);
+ LocalServices.addService(PackageManagerInternal.class, mPackageManagerInternal);
+ LocalServices.addService(ActivityTaskManagerInternal.class, mActivityTaskManagerInternal);
+ LocalServices.addService(NotificationManagerInternal.class, mNotificationManagerInternal);
+
+ doReturn(new ComponentName("", "")).when(mPackageManagerInternal)
+ .getSystemUiServiceComponent();
+
+ doReturn(mPackageManager).when(AppGlobals::getPackageManager);
+ doReturn(mPermissionManager).when(AppGlobals::getPermissionManager);
+ doReturn(new String[]{""}).when(mPackageManager).getPackagesForUid(eq(Process.myUid()));
+
mHandlerThread = new HandlerThread(TAG);
mHandlerThread.start();
mHandler = new TestHandler(mHandlerThread.getLooper());
@@ -220,6 +258,7 @@ public class ActivityManagerServiceTest {
mAms.mConstants.mNetworkAccessTimeoutMs = 2000;
mAms.mActivityTaskManager = new ActivityTaskManagerService(mContext);
mAms.mActivityTaskManager.initialize(null, null, mHandler.getLooper());
+ mAms.mAtmInternal = mActivityTaskManagerInternal;
mHandler.setRunnablesToIgnore(
List.of(mAms.mUidObserverController.getDispatchRunnableForTest()));
@@ -250,6 +289,15 @@ public class ActivityManagerServiceTest {
if (sProcessListSettingsListener != null) {
sProcessListSettingsListener.unregisterObserver();
}
+ clearInvocations(mNotificationManagerInternal);
+
+ LocalServices.removeServiceForTest(PackageManagerInternal.class);
+ LocalServices.removeServiceForTest(ActivityTaskManagerInternal.class);
+ LocalServices.removeServiceForTest(NotificationManagerInternal.class);
+
+ if (mMockingSession != null) {
+ mMockingSession.finishMocking();
+ }
}
@SuppressWarnings("GuardedBy")
@@ -445,6 +493,7 @@ public class ActivityManagerServiceTest {
}
}
+ @SuppressWarnings("GuardedBy")
private UidRecord addUidRecord(int uid) {
final UidRecord uidRec = new UidRecord(uid, mAms);
uidRec.procStateSeqWaitingForNetwork = 1;
@@ -453,10 +502,13 @@ public class ActivityManagerServiceTest {
ApplicationInfo info = new ApplicationInfo();
info.packageName = "";
+ info.uid = uid;
final ProcessRecord appRec = new ProcessRecord(mAms, info, TAG, uid);
- final ProcessStatsService tracker = new ProcessStatsService(mAms, mContext.getCacheDir());
- appRec.makeActive(mock(IApplicationThread.class), tracker);
+ final ProcessStatsService tracker = mAms.mProcessStats;
+ final IApplicationThread appThread = mock(IApplicationThread.class);
+ doReturn(mock(IBinder.class)).when(appThread).asBinder();
+ appRec.makeActive(appThread, tracker);
mAms.mProcessList.getLruProcessesLSP().add(appRec);
return uidRec;
@@ -1209,6 +1261,108 @@ public class ActivityManagerServiceTest {
mAms.mUidObserverController.getPendingUidChangesForTest().clear();
}
+ @Test
+ public void testStartForegroundServiceDelegateWithNotification() throws Exception {
+ testStartForegroundServiceDelegate(true);
+ }
+
+ @Test
+ public void testStartForegroundServiceDelegateWithoutNotification() throws Exception {
+ testStartForegroundServiceDelegate(false);
+ }
+
+ @SuppressWarnings("GuardedBy")
+ private void testStartForegroundServiceDelegate(boolean withNotification) throws Exception {
+ mockNoteOperation();
+
+ final int notificationId = 42;
+ final Notification notification = mock(Notification.class);
+
+ addUidRecord(TEST_UID);
+ final ProcessRecord app = mAms.mProcessList.getLruProcessesLSP().get(0);
+ app.mPid = TEST_PID;
+ app.info.packageName = TEST_PACKAGE_NAME;
+ app.info.processName = TEST_PACKAGE_NAME;
+
+ doReturn(app.info).when(mPackageManager).getApplicationInfo(
+ eq(app.info.packageName), anyLong(), anyInt());
+
+ doReturn(true).when(mActiveServices)
+ .canStartForegroundServiceLocked(anyInt(), anyInt(), anyString());
+ doReturn(REASON_DENIED).when(mActiveServices)
+ .shouldAllowFgsWhileInUsePermissionLocked(anyString(), anyInt(), anyInt(),
+ any(ProcessRecord.class), any(BackgroundStartPrivileges.class));
+
+ doReturn(true).when(mNotificationManagerInternal).areNotificationsEnabledForPackage(
+ anyString(), anyInt());
+ doReturn(mock(Icon.class)).when(notification).getSmallIcon();
+ doReturn("").when(notification).getChannelId();
+ doReturn(mock(NotificationChannel.class)).when(mNotificationManagerInternal)
+ .getNotificationChannel(anyString(), anyInt(), anyString());
+
+ mAms.mAppProfiler.mCachedAppsWatermarkData.mCachedAppHighWatermark = Integer.MAX_VALUE;
+
+ final ForegroundServiceDelegationOptions.Builder optionsBuilder =
+ new ForegroundServiceDelegationOptions.Builder()
+ .setClientPid(app.mPid)
+ .setClientUid(app.uid)
+ .setClientPackageName(app.info.packageName)
+ .setClientAppThread(app.getThread())
+ .setSticky(false)
+ .setClientInstanceName(
+ "SystemExemptedFgsDelegate_"
+ + Process.myUid()
+ + "_"
+ + app.uid
+ + "_"
+ + app.info.packageName)
+ .setForegroundServiceTypes(ServiceInfo.FOREGROUND_SERVICE_TYPE_SYSTEM_EXEMPTED)
+ .setDelegationService(
+ ForegroundServiceDelegationOptions.DELEGATION_SERVICE_SYSTEM_EXEMPTED);
+ if (withNotification) {
+ optionsBuilder.setClientNotification(notificationId, notification);
+ }
+ final ForegroundServiceDelegationOptions options = optionsBuilder.build();
+
+ final CountDownLatch[] latchHolder = new CountDownLatch[1];
+ final ServiceConnection conn = new ServiceConnection() {
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ latchHolder[0].countDown();
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ latchHolder[0].countDown();
+ }
+ };
+
+ latchHolder[0] = new CountDownLatch(1);
+ mAms.mInternal.startForegroundServiceDelegate(options, conn);
+
+ assertThat(latchHolder[0].await(5, TimeUnit.SECONDS)).isTrue();
+ assertEquals(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE,
+ app.mState.getCurProcState());
+ final long timeoutMs = 5000L;
+ final VerificationMode mode = withNotification
+ ? timeout(timeoutMs) : after(timeoutMs).atMost(0);
+ verify(mNotificationManagerInternal, mode)
+ .enqueueNotification(eq(app.info.packageName), eq(app.info.packageName),
+ eq(app.info.uid), eq(app.mPid), eq(null),
+ eq(notificationId), eq(notification), anyInt(), eq(true));
+
+ latchHolder[0] = new CountDownLatch(1);
+ mAms.mInternal.stopForegroundServiceDelegate(options);
+
+ assertThat(latchHolder[0].await(5, TimeUnit.SECONDS)).isTrue();
+ assertEquals(ActivityManager.PROCESS_STATE_CACHED_EMPTY,
+ app.mState.getCurProcState());
+ verify(mNotificationManagerInternal, mode)
+ .cancelNotification(eq(app.info.packageName), eq(app.info.packageName),
+ eq(app.info.uid), eq(app.mPid), eq(null),
+ eq(notificationId), anyInt());
+ }
+
private static class TestHandler extends Handler {
private static final long WAIT_FOR_MSG_TIMEOUT_MS = 4000; // 4 sec
private static final long WAIT_FOR_MSG_INTERVAL_MS = 400; // 0.4 sec
@@ -1291,6 +1445,19 @@ public class ActivityManagerServiceTest {
usersStartedOnSecondaryDisplays.add(new Pair<>(userId, displayId));
return returnValueForstartUserOnSecondaryDisplay;
}
+
+ @Override
+ public ActiveServices getActiveServices(ActivityManagerService service) {
+ if (mActiveServices == null) {
+ mActiveServices = spy(new ActiveServices(service));
+ }
+ return mActiveServices;
+ }
+
+ @Override
+ public BatteryStatsService getBatteryStatsService() {
+ return mBatteryStatsService;
+ }
}
// TODO: [b/302724778] Remove manual JNI load
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/BaseBroadcastQueueTest.java b/services/tests/mockingservicestests/src/com/android/server/am/BaseBroadcastQueueTest.java
index bd20ae26821e..ce281daf41c4 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/BaseBroadcastQueueTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/BaseBroadcastQueueTest.java
@@ -56,6 +56,7 @@ import com.android.server.wm.ActivityTaskManagerService;
import org.junit.Rule;
import org.mockito.Mock;
+import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import java.io.File;
@@ -160,6 +161,7 @@ public abstract class BaseBroadcastQueueTest {
realAms.mActivityTaskManager = new ActivityTaskManagerService(mContext);
realAms.mActivityTaskManager.initialize(null, null, mContext.getMainLooper());
realAms.mAtmInternal = spy(realAms.mActivityTaskManager.getAtmInternal());
+ realAms.mOomAdjuster.mCachedAppOptimizer = Mockito.mock(CachedAppOptimizer.class);
realAms.mOomAdjuster = spy(realAms.mOomAdjuster);
ExtendedMockito.doNothing().when(() -> ProcessList.setOomAdj(anyInt(), anyInt(), anyInt()));
realAms.mPackageManagerInt = mPackageManagerInt;
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java
index 66ab8076a217..420af86c4408 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java
@@ -86,7 +86,6 @@ import androidx.test.platform.app.InstrumentationRegistry;
import org.junit.After;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
import org.mockito.ArgumentMatcher;
import org.mockito.InOrder;
@@ -2335,8 +2334,8 @@ public class BroadcastQueueTest extends BaseBroadcastQueueTest {
.isGreaterThan(getReceiverScheduledTime(prioritizedRecord, receiverBlue));
}
- @Ignore
@Test
+ @RequiresFlagsEnabled(Flags.FLAG_DEFER_OUTGOING_BROADCASTS)
public void testDeferOutgoingBroadcasts() throws Exception {
final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED);
setProcessFreezable(callerApp, true /* pendingFreeze */, false /* frozen */);
@@ -2350,6 +2349,8 @@ public class BroadcastQueueTest extends BaseBroadcastQueueTest {
makeRegisteredReceiver(receiverGreenApp),
makeManifestReceiver(PACKAGE_BLUE, CLASS_BLUE),
makeManifestReceiver(PACKAGE_YELLOW, CLASS_YELLOW))));
+ // Verify that we invoke the call to freeze the caller app.
+ verify(mAms.mOomAdjuster.mCachedAppOptimizer).freezeAppAsyncImmediateLSP(callerApp);
waitForIdle();
verifyScheduleRegisteredReceiver(never(), receiverGreenApp, timeTick);
diff --git a/services/tests/mockingservicestests/src/com/android/server/backup/PackageManagerBackupAgentTest.java b/services/tests/mockingservicestests/src/com/android/server/backup/PackageManagerBackupAgentTest.java
index d1b6de08db51..20e198c192bf 100644
--- a/services/tests/mockingservicestests/src/com/android/server/backup/PackageManagerBackupAgentTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/backup/PackageManagerBackupAgentTest.java
@@ -55,20 +55,21 @@ public class PackageManagerBackupAgentTest {
@Rule public TemporaryFolder folder = new TemporaryFolder();
+ private PackageManager mPackageManager;
private PackageManagerBackupAgent mPackageManagerBackupAgent;
private ImmutableList<PackageInfo> mPackages;
private File mBackupData, mOldState, mNewState;
@Before
public void setUp() throws Exception {
- PackageManager packageManager = getApplicationContext().getPackageManager();
+ mPackageManager = getApplicationContext().getPackageManager();
PackageInfo existingPackageInfo =
- packageManager.getPackageInfoAsUser(
+ mPackageManager.getPackageInfoAsUser(
EXISTING_PACKAGE_NAME, PackageManager.GET_SIGNING_CERTIFICATES, USER_ID);
mPackages = ImmutableList.of(existingPackageInfo);
mPackageManagerBackupAgent =
- new PackageManagerBackupAgent(packageManager, mPackages, USER_ID);
+ new PackageManagerBackupAgent(mPackageManager, mPackages, USER_ID);
mBackupData = folder.newFile("backup_data");
mOldState = folder.newFile("old_state");
@@ -101,11 +102,8 @@ public class PackageManagerBackupAgentTest {
runBackupAgentOnBackup();
- // We shouldn't have written anything, but a known issue is that we always write the
- // ancestral record version.
ImmutableMap<String, Optional<ByteBuffer>> keyValues = getKeyValues(mBackupData);
- assertThat(keyValues.keySet())
- .containsExactly(PackageManagerBackupAgent.ANCESTRAL_RECORD_KEY);
+ assertThat(keyValues).isEmpty();
assertThat(mNewState.length()).isGreaterThan(0);
assertThat(mNewState.length()).isEqualTo(mOldState.length());
}
@@ -122,9 +120,7 @@ public class PackageManagerBackupAgentTest {
// Note that uninstalledPackageName should not exist, i.e. it did not get deleted.
ImmutableMap<String, Optional<ByteBuffer>> keyValues = getKeyValues(mBackupData);
- assertThat(keyValues.keySet())
- .containsExactly(
- PackageManagerBackupAgent.ANCESTRAL_RECORD_KEY, EXISTING_PACKAGE_NAME);
+ assertThat(keyValues.keySet()).containsExactly(EXISTING_PACKAGE_NAME);
assertThat(mNewState.length()).isGreaterThan(0);
}
@@ -133,7 +129,9 @@ public class PackageManagerBackupAgentTest {
String uninstalledPackageName = "does.not.exist";
writeLegacyStateFile(
mOldState,
- ImmutableList.of(createPackage(uninstalledPackageName, 1), mPackages.getFirst()));
+ ImmutableList.of(createPackage(uninstalledPackageName, 1), mPackages.getFirst()),
+ /* writeStateFileVersion= */ false,
+ /* writeAncestralRecordVersion= */ false);
runBackupAgentOnBackup();
@@ -147,6 +145,30 @@ public class PackageManagerBackupAgentTest {
}
@Test
+ public void onBackup_noAncestralRecordInfo_deletesUninstalledPackagesFromBackup()
+ throws Exception {
+ PackageInfo pkgNotInstalled = createPackage("does.not.exist", 2);
+ PackageInfo pkgInstalled =
+ mPackageManager.getPackageInfoAsUser(
+ EXISTING_PACKAGE_NAME, PackageManager.GET_SIGNING_CERTIFICATES, USER_ID);
+ writeLegacyStateFile(
+ mOldState,
+ ImmutableList.of(pkgInstalled, pkgNotInstalled),
+ /* writeStateFileVersion= */ true,
+ /* writeAncestralRecordVersion= */ false);
+
+ runBackupAgentOnBackup();
+
+ ImmutableMap<String, Optional<ByteBuffer>> keyValues = getKeyValues(mBackupData);
+ assertThat(keyValues.keySet())
+ .containsExactly(
+ PackageManagerBackupAgent.ANCESTRAL_RECORD_KEY,
+ pkgInstalled.packageName,
+ pkgNotInstalled.packageName);
+ assertThat(keyValues).containsEntry(pkgNotInstalled.packageName, Optional.empty());
+ }
+
+ @Test
public void onRestore_recentBackup_restoresBackup() throws Exception {
runBackupAgentOnBackup();
@@ -229,7 +251,11 @@ public class PackageManagerBackupAgentTest {
}
/** This creates a legacy state file in which {@code STATE_FILE_HEADER} was not yet present. */
- private static void writeLegacyStateFile(File stateFile, ImmutableList<PackageInfo> packages)
+ private static void writeLegacyStateFile(
+ File stateFile,
+ ImmutableList<PackageInfo> packages,
+ boolean writeStateFileVersion,
+ boolean writeAncestralRecordVersion)
throws Exception {
try (ParcelFileDescriptor stateFileDescriptor = openForWriting(stateFile);
DataOutputStream out =
@@ -237,6 +263,19 @@ public class PackageManagerBackupAgentTest {
new BufferedOutputStream(
new FileOutputStream(
stateFileDescriptor.getFileDescriptor())))) {
+
+ if (writeStateFileVersion) {
+ // state file version header
+ out.writeUTF(PackageManagerBackupAgent.STATE_FILE_HEADER);
+ out.writeInt(PackageManagerBackupAgent.STATE_FILE_VERSION);
+ }
+
+ if (writeAncestralRecordVersion) {
+ // Record the ancestral record
+ out.writeUTF(PackageManagerBackupAgent.ANCESTRAL_RECORD_KEY);
+ out.writeInt(PackageManagerBackupAgent.ANCESTRAL_RECORD_VERSION);
+ }
+
out.writeUTF(PackageManagerBackupAgent.GLOBAL_METADATA_KEY);
out.writeInt(Build.VERSION.SDK_INT);
out.writeUTF(Build.VERSION.INCREMENTAL);
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/ProxyAccessibilityServiceConnectionTest.java b/services/tests/servicestests/src/com/android/server/accessibility/ProxyAccessibilityServiceConnectionTest.java
index 6ac3658bc3b4..3d0db71ba17f 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/ProxyAccessibilityServiceConnectionTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/ProxyAccessibilityServiceConnectionTest.java
@@ -24,6 +24,13 @@ import static android.accessibilityservice.AccessibilityServiceInfo.FLAG_REQUEST
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertThrows;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
import android.accessibilityservice.AccessibilityServiceInfo;
import android.accessibilityservice.AccessibilityTrace;
import android.content.ComponentName;
@@ -33,13 +40,6 @@ import android.graphics.Color;
import android.os.Handler;
import android.view.accessibility.AccessibilityEvent;
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.junit.Assert.assertThrows;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
import com.android.server.wm.WindowManagerInternal;
import org.junit.Before;
@@ -225,7 +225,7 @@ public class ProxyAccessibilityServiceConnectionTest {
}
@Test
- public void testDisableSelf_setIllegalOperationExceptionThrown_() {
+ public void testDisableSelf_setIllegalOperationExceptionThrown() {
UnsupportedOperationException thrown =
assertThrows(
UnsupportedOperationException.class,
@@ -233,4 +233,9 @@ public class ProxyAccessibilityServiceConnectionTest {
assertThat(thrown).hasMessageThat().contains("disableSelf is not supported");
}
+
+ @Test
+ public void getInstalledAndEnabledServices_noServices_returnEmpty() {
+ assertThat(mProxyConnection.getInstalledAndEnabledServices()).isEmpty();
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
index 67b131fcbb75..124970758fa5 100644
--- a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
@@ -206,7 +206,6 @@ import libcore.io.Streams;
import org.junit.After;
import org.junit.Assume;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.MethodRule;
@@ -2151,14 +2150,12 @@ public class NetworkPolicyManagerServiceTest {
assertFalse(mService.isUidNetworkingBlocked(UID_E, false));
}
- @Ignore("Temporarily disabled until the feature is enabled")
@Test
@RequiresFlagsEnabled(Flags.FLAG_NETWORK_BLOCKED_FOR_TOP_SLEEPING_AND_ABOVE)
public void testBackgroundChainEnabled() throws Exception {
verify(mNetworkManager).setFirewallChainEnabled(FIREWALL_CHAIN_BACKGROUND, true);
}
- @Ignore("Temporarily disabled until the feature is enabled")
@Test
@RequiresFlagsEnabled(Flags.FLAG_NETWORK_BLOCKED_FOR_TOP_SLEEPING_AND_ABOVE)
public void testBackgroundChainOnProcStateChange() throws Exception {
@@ -2188,7 +2185,6 @@ public class NetworkPolicyManagerServiceTest {
assertTrue(mService.isUidNetworkingBlocked(UID_A, false));
}
- @Ignore("Temporarily disabled until the feature is enabled")
@Test
@RequiresFlagsEnabled(Flags.FLAG_NETWORK_BLOCKED_FOR_TOP_SLEEPING_AND_ABOVE)
public void testBackgroundChainOnAllowlistChange() throws Exception {
@@ -2227,7 +2223,6 @@ public class NetworkPolicyManagerServiceTest {
assertFalse(mService.isUidNetworkingBlocked(UID_B, false));
}
- @Ignore("Temporarily disabled until the feature is enabled")
@Test
@RequiresFlagsEnabled(Flags.FLAG_NETWORK_BLOCKED_FOR_TOP_SLEEPING_AND_ABOVE)
public void testBackgroundChainOnTempAllowlistChange() throws Exception {
@@ -2266,7 +2261,6 @@ public class NetworkPolicyManagerServiceTest {
&& uidState.procState == procState && uidState.capability == capability;
}
- @Ignore("Temporarily disabled until the feature is enabled")
@Test
@RequiresFlagsEnabled(Flags.FLAG_NETWORK_BLOCKED_FOR_TOP_SLEEPING_AND_ABOVE)
public void testUidObserverFiltersProcStateChanges() throws Exception {
@@ -2329,7 +2323,6 @@ public class NetworkPolicyManagerServiceTest {
waitForUidEventHandlerIdle();
}
- @Ignore("Temporarily disabled until the feature is enabled")
@Test
@RequiresFlagsEnabled(Flags.FLAG_NETWORK_BLOCKED_FOR_TOP_SLEEPING_AND_ABOVE)
public void testUidObserverFiltersStaleChanges() throws Exception {
@@ -2350,7 +2343,6 @@ public class NetworkPolicyManagerServiceTest {
waitForUidEventHandlerIdle();
}
- @Ignore("Temporarily disabled until the feature is enabled")
@Test
@RequiresFlagsEnabled(Flags.FLAG_NETWORK_BLOCKED_FOR_TOP_SLEEPING_AND_ABOVE)
public void testUidObserverFiltersCapabilityChanges() throws Exception {
@@ -2430,7 +2422,6 @@ public class NetworkPolicyManagerServiceTest {
assertFalse(mService.isUidNetworkingBlocked(UID_A, false));
}
- @Ignore("Temporarily disabled until the feature is enabled")
@Test
@RequiresFlagsEnabled(Flags.FLAG_NETWORK_BLOCKED_FOR_TOP_SLEEPING_AND_ABOVE)
public void testObsoleteHandleUidChanged() throws Exception {
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserRestrictionsUtilsTest.java b/services/tests/servicestests/src/com/android/server/pm/UserRestrictionsUtilsTest.java
index e249cd7311cf..55c48e07162b 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserRestrictionsUtilsTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserRestrictionsUtilsTest.java
@@ -90,8 +90,6 @@ public class UserRestrictionsUtilsTest {
public void testCanDeviceOwnerChange() {
assertFalse(UserRestrictionsUtils.canDeviceOwnerChange(UserManager.DISALLOW_RECORD_AUDIO));
assertFalse(UserRestrictionsUtils.canDeviceOwnerChange(UserManager.DISALLOW_WALLPAPER));
- assertFalse(UserRestrictionsUtils.canDeviceOwnerChange(
- UserManager.DISALLOW_ADD_PRIVATE_PROFILE));
assertTrue(UserRestrictionsUtils.canDeviceOwnerChange(UserManager.DISALLOW_ADD_USER));
assertTrue(UserRestrictionsUtils.canDeviceOwnerChange(UserManager.DISALLOW_USER_SWITCH));
}
@@ -110,10 +108,6 @@ public class UserRestrictionsUtilsTest {
UserManager.DISALLOW_USER_SWITCH,
true,
false));
- assertFalse(UserRestrictionsUtils.canProfileOwnerChange(
- UserManager.DISALLOW_ADD_PRIVATE_PROFILE,
- true,
- false));
assertTrue(UserRestrictionsUtils.canProfileOwnerChange(
UserManager.DISALLOW_ADD_USER,
true,
diff --git a/services/tests/servicestests/src/com/android/server/power/hint/HintManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/power/hint/HintManagerServiceTest.java
index 4ab9d3ecf624..66599e9e9125 100644
--- a/services/tests/servicestests/src/com/android/server/power/hint/HintManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/hint/HintManagerServiceTest.java
@@ -39,12 +39,12 @@ import static org.mockito.Mockito.when;
import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
import android.content.Context;
+import android.hardware.power.WorkDuration;
import android.os.Binder;
import android.os.IBinder;
import android.os.IHintSession;
import android.os.PerformanceHintManager;
import android.os.Process;
-import android.os.WorkDuration;
import android.util.Log;
import com.android.server.FgThread;
@@ -76,6 +76,18 @@ import java.util.concurrent.locks.LockSupport;
public class HintManagerServiceTest {
private static final String TAG = "HintManagerServiceTest";
+ private static WorkDuration makeWorkDuration(
+ long timestamp, long duration, long workPeriodStartTime,
+ long cpuDuration, long gpuDuration) {
+ WorkDuration out = new WorkDuration();
+ out.timeStampNanos = timestamp;
+ out.durationNanos = duration;
+ out.workPeriodStartTimestampNanos = workPeriodStartTime;
+ out.cpuDurationNanos = cpuDuration;
+ out.gpuDurationNanos = gpuDuration;
+ return out;
+ }
+
private static final long DEFAULT_HINT_PREFERRED_RATE = 16666666L;
private static final long DEFAULT_TARGET_DURATION = 16666666L;
private static final long CONCURRENCY_TEST_DURATION_SEC = 10;
@@ -91,11 +103,11 @@ public class HintManagerServiceTest {
private static final long[] TIMESTAMPS_ZERO = new long[] {};
private static final long[] TIMESTAMPS_TWO = new long[] {1L, 2L};
private static final WorkDuration[] WORK_DURATIONS_FIVE = new WorkDuration[] {
- new WorkDuration(1L, 11L, 8L, 4L, 1L),
- new WorkDuration(2L, 13L, 8L, 6L, 2L),
- new WorkDuration(3L, 333333333L, 8L, 333333333L, 3L),
- new WorkDuration(2L, 13L, 0L, 6L, 2L),
- new WorkDuration(2L, 13L, 8L, 0L, 2L),
+ makeWorkDuration(1L, 11L, 1L, 8L, 4L),
+ makeWorkDuration(2L, 13L, 2L, 8L, 6L),
+ makeWorkDuration(3L, 333333333L, 3L, 8L, 333333333L),
+ makeWorkDuration(2L, 13L, 2L, 0L, 6L),
+ makeWorkDuration(2L, 13L, 2L, 8L, 0L),
};
@Mock private Context mContext;
@@ -621,20 +633,20 @@ public class HintManagerServiceTest {
assertThrows(IllegalArgumentException.class, () -> {
a.reportActualWorkDuration2(
- new WorkDuration[] {new WorkDuration(-1L, 11L, 8L, 4L, 1L)});
+ new WorkDuration[] {makeWorkDuration(1L, 11L, -1L, 8L, 4L)});
});
assertThrows(IllegalArgumentException.class, () -> {
- a.reportActualWorkDuration2(new WorkDuration[] {new WorkDuration(1L, 0L, 8L, 4L, 1L)});
+ a.reportActualWorkDuration2(new WorkDuration[] {makeWorkDuration(1L, 0L, 1L, 8L, 4L)});
});
assertThrows(IllegalArgumentException.class, () -> {
- a.reportActualWorkDuration2(new WorkDuration[] {new WorkDuration(1L, 11L, 0L, 0L, 1L)});
+ a.reportActualWorkDuration2(new WorkDuration[] {makeWorkDuration(1L, 11L, 1L, 0L, 0L)});
});
assertThrows(IllegalArgumentException.class, () -> {
a.reportActualWorkDuration2(
- new WorkDuration[] {new WorkDuration(1L, 11L, 8L, -1L, 1L)});
+ new WorkDuration[] {makeWorkDuration(1L, 11L, 1L, 8L, -1L)});
});
reset(mNativeWrapperMock);
diff --git a/services/tests/wmtests/src/com/android/server/wm/utils/OptPropFactoryTest.java b/services/tests/wmtests/src/com/android/server/wm/utils/OptPropFactoryTest.java
new file mode 100644
index 000000000000..004de1fc962b
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/utils/OptPropFactoryTest.java
@@ -0,0 +1,286 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.utils;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.pm.PackageManager;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.server.wm.utils.OptPropFactory.OptProp;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import java.util.function.BooleanSupplier;
+
+/**
+ * Build/Install/Run:
+ * atest WmTests:OptPropFactoryTest
+ */
+@SmallTest
+@Presubmit
+public class OptPropFactoryTest {
+
+ private PackageManager mPackageManager;
+ private OptPropFactory mOptPropFactory;
+
+ @Before
+ public void setUp() {
+ mPackageManager = mock(PackageManager.class);
+ mOptPropFactory = new OptPropFactory(mPackageManager, "");
+ }
+
+ @Test
+ public void optProp_laziness() throws PackageManager.NameNotFoundException {
+ initPropAs(/* propertyValue */ true);
+ // When OptPropBuilder is created the PackageManager is not used
+ verify(mPackageManager, never()).getProperty(anyString(), anyString());
+
+ // Accessing the value multiple times only uses PackageManager once
+ final OptProp optProp = createOptProp();
+ optProp.isTrue();
+ optProp.isFalse();
+
+ verify(mPackageManager).getProperty(anyString(), anyString());
+ }
+
+ @Test
+ public void optProp_withSetValueTrue() throws PackageManager.NameNotFoundException {
+ initPropAs(/* propertyValue */ true);
+
+ final OptProp optProp = createOptProp();
+
+ assertTrue(optProp.isTrue());
+ assertFalse(optProp.isFalse());
+ }
+
+ @Test
+ public void optProp_withSetValueFalse() throws PackageManager.NameNotFoundException {
+ initPropAs(/* propertyValue */ false);
+
+ final OptProp optProp = createOptProp();
+
+ assertFalse(optProp.isTrue());
+ assertTrue(optProp.isFalse());
+ }
+
+ @Test
+ public void optProp_withSetValueWithConditionFalse()
+ throws PackageManager.NameNotFoundException {
+ initPropAs(/* propertyValue */ true);
+
+ final OptProp optProp = createOptProp(() -> false);
+
+ assertFalse(optProp.isTrue());
+ assertFalse(optProp.isFalse());
+ }
+
+ @Test
+ public void optProp_withUnsetValue() {
+ final OptProp optProp = createOptProp();
+
+ assertFalse(optProp.isTrue());
+ assertFalse(optProp.isFalse());
+ }
+
+ @Test
+ public void optProp_isUnsetWhenPropertyIsNotPresent()
+ throws PackageManager.NameNotFoundException {
+ initPropAsWithException();
+ // Property is unset
+ final OptProp optUnset = createOptProp();
+ assertFalse(optUnset.isTrue());
+ assertFalse(optUnset.isFalse());
+ }
+
+ @Test
+ public void optProp_shouldEnableWithOverrideAndProperty()
+ throws PackageManager.NameNotFoundException {
+ // Property is unset
+ final OptProp optUnset = createOptProp(() -> false);
+ assertFalse(optUnset.shouldEnableWithOverrideAndProperty(/* override */ true));
+
+ // The value is the override one
+ final OptProp optUnsetOn = createOptProp();
+ assertTrue(optUnsetOn.shouldEnableWithOverrideAndProperty(/* override */ true));
+ assertFalse(optUnsetOn.shouldEnableWithOverrideAndProperty(/* override */ false));
+
+ // Property is set to true
+ initPropAs(true);
+ final OptProp optTrue = createOptProp(() -> false);
+ assertFalse(optTrue.shouldEnableWithOverrideAndProperty(/* override */ true));
+
+ final OptProp optTrueOn = createOptProp(() -> true);
+ assertTrue(optTrueOn.shouldEnableWithOverrideAndProperty(/* override */ true));
+ assertTrue(optTrueOn.shouldEnableWithOverrideAndProperty(/* override */ false));
+
+ // Property is set to false
+ initPropAs(false);
+ final OptProp optFalse = createOptProp(() -> false);
+ assertFalse(optFalse.shouldEnableWithOverrideAndProperty(/* override */ true));
+
+ final OptProp optFalseOn = createOptProp();
+ assertFalse(optFalseOn.shouldEnableWithOverrideAndProperty(/* override */ true));
+ assertFalse(optFalseOn.shouldEnableWithOverrideAndProperty(/* override */ false));
+ }
+
+ @Test
+ public void optProp_shouldEnableWithOptInOverrideAndOptOutProperty()
+ throws PackageManager.NameNotFoundException {
+ // Property is unset
+ final OptProp optUnset = createOptProp(() -> false);
+ assertFalse(optUnset.shouldEnableWithOptInOverrideAndOptOutProperty(/* override */ true));
+
+ final OptProp optUnsetOn = createOptProp();
+ assertTrue(optUnsetOn.shouldEnableWithOptInOverrideAndOptOutProperty(/* override */ true));
+ assertFalse(
+ optUnsetOn.shouldEnableWithOptInOverrideAndOptOutProperty(/* override */ false));
+
+ // Property is set to true
+ initPropAs(true);
+ final OptProp optTrue = createOptProp(() -> false);
+ assertFalse(optTrue.shouldEnableWithOptInOverrideAndOptOutProperty(/* override */ true));
+
+ // Is the value of the override
+ final OptProp optTrueOn = createOptProp(() -> true);
+ assertTrue(optTrueOn.shouldEnableWithOptInOverrideAndOptOutProperty(/* override */ true));
+ assertFalse(optTrueOn.shouldEnableWithOptInOverrideAndOptOutProperty(/* override */ false));
+
+ // Property is set to false
+ initPropAs(false);
+ final OptProp optFalse = createOptProp(() -> false);
+ assertFalse(optFalse.shouldEnableWithOptInOverrideAndOptOutProperty(/* override */ true));
+
+ // Always false ahatever is the value of the override
+ final OptProp optFalseOn = createOptProp();
+ assertFalse(optFalseOn.shouldEnableWithOptInOverrideAndOptOutProperty(/* override */ true));
+ assertFalse(
+ optFalseOn.shouldEnableWithOptInOverrideAndOptOutProperty(/* override */ false));
+ }
+
+ @Test
+ public void optProp_shouldEnableWithOptOutOverrideAndProperty()
+ throws PackageManager.NameNotFoundException {
+ // Property is unset
+ final OptProp optUnset = createOptProp(() -> false);
+ assertFalse(optUnset.shouldEnableWithOptOutOverrideAndProperty(/* override */ true));
+
+ // Is the negate of the override value
+ final OptProp optUnsetOn = createOptProp();
+ assertTrue(optUnsetOn.shouldEnableWithOptOutOverrideAndProperty(/* override */ false));
+ assertFalse(optUnsetOn.shouldEnableWithOptOutOverrideAndProperty(/* override */ true));
+
+ // Property is set to true
+ initPropAs(true);
+ final OptProp optTrue = createOptProp(() -> false);
+ assertFalse(optTrue.shouldEnableWithOptOutOverrideAndProperty(/* override */ true));
+
+ // Is the negate of the override value
+ final OptProp optTrueOn = createOptProp(() -> true);
+ assertTrue(optTrueOn.shouldEnableWithOptOutOverrideAndProperty(/* override */ false));
+ assertFalse(optTrueOn.shouldEnableWithOptOutOverrideAndProperty(/* override */ true));
+
+ // Property is set to false
+ initPropAs(false);
+ final OptProp optFalse = createOptProp(() -> false);
+ assertFalse(optFalse.shouldEnableWithOptOutOverrideAndProperty(/* override */ true));
+
+ // Always false ahatever is the value of the override
+ final OptProp optFalseOn = createOptProp();
+ assertFalse(optFalseOn.shouldEnableWithOptOutOverrideAndProperty(/* override */ true));
+ assertFalse(optFalseOn.shouldEnableWithOptOutOverrideAndProperty(/* override */ false));
+ }
+
+ @Test
+ public void optProp_gateConditionIsInvokedOnlyOncePerInvocation()
+ throws PackageManager.NameNotFoundException {
+
+ final FakeGateCondition trueCondition = new FakeGateCondition(/* returnValue */ true);
+ final OptProp optProp = createOptProp(trueCondition);
+
+ optProp.shouldEnableWithOverrideAndProperty(/* override value */ true);
+ assertEquals(1, trueCondition.getInvocationCount());
+ trueCondition.clearInvocationCount();
+
+ initPropAs(true);
+ optProp.shouldEnableWithOptInOverrideAndOptOutProperty(/* override value */ true);
+ assertEquals(1, trueCondition.getInvocationCount());
+ trueCondition.clearInvocationCount();
+
+ optProp.shouldEnableWithOptOutOverrideAndProperty(/* override value */ true);
+ assertEquals(1, trueCondition.getInvocationCount());
+ trueCondition.clearInvocationCount();
+ }
+
+ private void initPropAs(boolean propertyValue) throws PackageManager.NameNotFoundException {
+ Mockito.clearInvocations(mPackageManager);
+ final PackageManager.Property prop = new PackageManager.Property(
+ "", /* value */ propertyValue, "", "");
+ when(mPackageManager.getProperty(anyString(), anyString())).thenReturn(prop);
+ }
+
+ private void initPropAsWithException() throws PackageManager.NameNotFoundException {
+ Mockito.clearInvocations(mPackageManager);
+ when(mPackageManager.getProperty("", "")).thenThrow(
+ new PackageManager.NameNotFoundException());
+ }
+
+ private OptProp createOptProp() {
+ return mOptPropFactory.create("");
+ }
+
+ private OptProp createOptProp(BooleanSupplier condition) {
+ return mOptPropFactory.create("", condition);
+ }
+
+ private static class FakeGateCondition implements BooleanSupplier {
+
+ private int mInvocationCount = 0;
+ private final boolean mReturnValue;
+
+ private FakeGateCondition(boolean returnValue) {
+ mReturnValue = returnValue;
+ }
+
+ @Override
+ public boolean getAsBoolean() {
+ mInvocationCount++;
+ return mReturnValue;
+ }
+
+ int getInvocationCount() {
+ return mInvocationCount;
+ }
+
+ void clearInvocationCount() {
+ mInvocationCount = 0;
+ }
+
+ }
+}
diff --git a/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java b/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java
index 2ff21ad40558..40537c85784d 100644
--- a/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java
+++ b/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java
@@ -978,8 +978,14 @@ public class UsbProfileGroupSettingsManager {
shouldRestrictOverlayActivities = filteredAppProcessInfos.stream().anyMatch(pkg -> {
try {
- return mPackageManager.getProperty(PROPERTY_RESTRICT_USB_OVERLAY_ACTIVITIES, pkg)
- .getBoolean();
+ boolean restrictUsbOverlayActivitiesForPackage = mPackageManager
+ .getProperty(PROPERTY_RESTRICT_USB_OVERLAY_ACTIVITIES, pkg).getBoolean();
+
+ if (restrictUsbOverlayActivitiesForPackage) {
+ Slog.d(TAG, "restricting usb overlay activities as package " + pkg
+ + " is in foreground");
+ }
+ return restrictUsbOverlayActivitiesForPackage;
} catch (NameNotFoundException e) {
if (DEBUG) {
Slog.d(TAG, "property PROPERTY_RESTRICT_USB_OVERLAY_ACTIVITIES "
@@ -989,8 +995,8 @@ public class UsbProfileGroupSettingsManager {
}
});
- if (shouldRestrictOverlayActivities) {
- Slog.d(TAG, "restricting starting of usb overlay activities");
+ if (!shouldRestrictOverlayActivities) {
+ Slog.d(TAG, "starting of usb overlay activities");
}
return shouldRestrictOverlayActivities;
}
diff --git a/telephony/common/com/android/internal/telephony/CarrierAppUtils.java b/telephony/common/com/android/internal/telephony/CarrierAppUtils.java
index 8531b507a92f..6482432f4049 100644
--- a/telephony/common/com/android/internal/telephony/CarrierAppUtils.java
+++ b/telephony/common/com/android/internal/telephony/CarrierAppUtils.java
@@ -33,6 +33,7 @@ import android.util.ArrayMap;
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.flags.Flags;
import com.android.internal.telephony.util.TelephonyUtils;
import java.util.ArrayList;
@@ -41,7 +42,7 @@ import java.util.Map;
import java.util.Set;
/**
- * Utilities for handling carrier applications.
+ * Utilities to control the states of the system bundled (preinstalled) carrier applications.
* @hide
*/
public final class CarrierAppUtils {
@@ -246,17 +247,27 @@ public final class CarrierAppUtils {
// Always re-grant default permissions to carrier apps w/ privileges.
enabledCarrierPackages.add(ai.packageName);
} else { // No carrier privileges
- // Only update enabled state for the app on /system. Once it has been
- // updated we shouldn't touch it.
- if (!isUpdatedSystemApp(ai) && enabledSetting
- == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
- && (ai.flags & ApplicationInfo.FLAG_INSTALLED) != 0) {
- Log.i(TAG, "Update state (" + packageName
- + "): DISABLED_UNTIL_USED for user " + userId);
- context.createContextAsUser(UserHandle.of(userId), 0)
- .getPackageManager()
- .setSystemAppState(
- packageName, PackageManager.SYSTEM_APP_STATE_UNINSTALLED);
+ // Only uninstall system carrier apps that fulfill ALL conditions below:
+ // 1. It has no carrier privileges
+ // 2. It has never been uninstalled before (i.e. we uninstall at most once)
+ // 3. It has not been installed as an update from its system built-in version
+ // 4. It is in default state (not explicitly DISABLED/DISABLED_BY_USER/ENABLED)
+ // 5. It is currently installed for the calling user
+ // TODO(b/329739019):
+ // 1. Merge the nested if conditions below during flag cleaning up phase
+ // 2. Support user case that NEW carrier app is added during OTA, when emerge.
+ if (!Flags.hidePreinstalledCarrierAppAtMostOnce() || !hasRunEver) {
+ if (!isUpdatedSystemApp(ai) && enabledSetting
+ == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
+ && (ai.flags & ApplicationInfo.FLAG_INSTALLED) != 0) {
+ Log.i(TAG, "Update state (" + packageName
+ + "): DISABLED_UNTIL_USED for user " + userId);
+ context.createContextAsUser(UserHandle.of(userId), 0)
+ .getPackageManager()
+ .setSystemAppState(
+ packageName,
+ PackageManager.SYSTEM_APP_STATE_UNINSTALLED);
+ }
}
// Associated apps are more brittle, because we can't rely on the distinction
diff --git a/telephony/java/android/telephony/euicc/EuiccManager.java b/telephony/java/android/telephony/euicc/EuiccManager.java
index e3ce766b40bc..ebabbf911399 100644
--- a/telephony/java/android/telephony/euicc/EuiccManager.java
+++ b/telephony/java/android/telephony/euicc/EuiccManager.java
@@ -512,6 +512,7 @@ public class EuiccManager {
EUICC_ACTIVATION_TYPE_BACKUP,
EUICC_ACTIVATION_TYPE_TRANSFER,
EUICC_ACTIVATION_TYPE_ACCOUNT_REQUIRED,
+ EUICC_ACTIVATION_TYPE_TRANSFER_FINAL_HOLD,
})
public @interface EuiccActivationType{}
@@ -555,6 +556,15 @@ public class EuiccManager {
public static final int EUICC_ACTIVATION_TYPE_ACCOUNT_REQUIRED = 4;
/**
+ * The activation flow of eSIM transfer to block the transfer process before B&R flow.
+ * This is needed to avoid connection overlapping between eSIM connection B&R connection.
+ *
+ * @hide
+ */
+ // TODO(b/329212614): add system api annotation during the allowed api timeline.
+ public static final int EUICC_ACTIVATION_TYPE_TRANSFER_FINAL_HOLD = 5;
+
+ /**
* Euicc OTA update status which can be got by {@link #getOtaStatus}
* @removed mistakenly exposed as system-api previously
*/
diff --git a/tools/aapt2/optimize/VersionCollapser.cpp b/tools/aapt2/optimize/VersionCollapser.cpp
index cd791bda250b..27fff9a05334 100644
--- a/tools/aapt2/optimize/VersionCollapser.cpp
+++ b/tools/aapt2/optimize/VersionCollapser.cpp
@@ -70,7 +70,7 @@ FilterIterator<Iterator, Pred> make_filter_iterator(Iterator begin,
* exception is when there is no exact matching resource for the minSdk. The next smallest one will
* be kept.
*/
-static void CollapseVersions(int min_sdk, ResourceEntry* entry) {
+static void CollapseVersions(IAaptContext* context, int min_sdk, ResourceEntry* entry) {
// First look for all sdks less than minSdk.
for (auto iter = entry->values.rbegin(); iter != entry->values.rend();
++iter) {
@@ -102,7 +102,14 @@ static void CollapseVersions(int min_sdk, ResourceEntry* entry) {
auto filter_iter =
make_filter_iterator(iter + 1, entry->values.rend(), pred);
while (filter_iter.HasNext()) {
- filter_iter.Next() = {};
+ auto& next = filter_iter.Next();
+ if (context->IsVerbose()) {
+ context->GetDiagnostics()->Note(android::DiagMessage()
+ << "removing configuration " << next->config.to_string()
+ << " for entry: " << entry->name
+ << ", because its SDK version is smaller than minSdk");
+ }
+ next = {};
}
}
}
@@ -126,6 +133,12 @@ static void CollapseVersions(int min_sdk, ResourceEntry* entry) {
util::make_unique<ResourceConfigValue>(
config_value->config.CopyWithoutSdkVersion(),
config_value->product);
+ if (context->IsVerbose()) {
+ context->GetDiagnostics()->Note(android::DiagMessage()
+ << "overriding resource: " << entry->name
+ << ", removing SDK version from configuration "
+ << config_value->config.to_string());
+ }
new_value->value = std::move(config_value->value);
config_value = std::move(new_value);
@@ -147,10 +160,14 @@ static void CollapseVersions(int min_sdk, ResourceEntry* entry) {
bool VersionCollapser::Consume(IAaptContext* context, ResourceTable* table) {
TRACE_NAME("VersionCollapser::Consume");
const int min_sdk = context->GetMinSdkVersion();
+ if (context->IsVerbose()) {
+ context->GetDiagnostics()->Note(android::DiagMessage()
+ << "Running VersionCollapser with minSdk = " << min_sdk);
+ }
for (auto& package : table->packages) {
for (auto& type : package->types) {
for (auto& entry : type->entries) {
- CollapseVersions(min_sdk, entry.get());
+ CollapseVersions(context, min_sdk, entry.get());
}
}
}