summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java36
-rw-r--r--core/api/current.txt96
-rw-r--r--core/api/module-lib-current.txt1
-rw-r--r--core/api/system-current.txt17
-rw-r--r--core/api/test-current.txt4
-rw-r--r--core/java/android/app/ContextImpl.java18
-rw-r--r--core/java/android/app/IActivityManager.aidl1
-rw-r--r--core/java/android/app/INotificationManager.aidl1
-rw-r--r--core/java/android/app/LoadedApk.java12
-rw-r--r--core/java/android/app/NotificationChannel.java15
-rw-r--r--core/java/android/app/admin/flags/flags.aconfig8
-rw-r--r--core/java/android/app/backup/NotificationLoggingConstants.java46
-rw-r--r--core/java/android/app/contextualsearch/flags.aconfig14
-rw-r--r--core/java/android/companion/virtual/flags/flags.aconfig8
-rw-r--r--core/java/android/content/Context.java23
-rw-r--r--core/java/android/content/ContextWrapper.java7
-rw-r--r--core/java/android/content/Intent.java25
-rw-r--r--core/java/android/content/om/OverlayManager.java5
-rw-r--r--core/java/android/content/om/OverlayManagerTransaction.java15
-rw-r--r--core/java/android/content/pm/multiuser.aconfig2
-rw-r--r--core/java/android/content/res/AssetManager.java5
-rw-r--r--core/java/android/content/res/flags.aconfig9
-rw-r--r--core/java/android/content/res/loader/ResourcesProvider.java2
-rw-r--r--core/java/android/hardware/camera2/CameraCharacteristics.java40
-rw-r--r--core/java/android/hardware/camera2/CameraMetadata.java16
-rw-r--r--core/java/android/hardware/camera2/CaptureRequest.java60
-rw-r--r--core/java/android/hardware/camera2/CaptureResult.java60
-rw-r--r--core/java/android/hardware/camera2/params/OutputConfiguration.java2
-rw-r--r--core/java/android/hardware/display/DisplayManager.java8
-rw-r--r--core/java/android/hardware/display/DisplayManagerGlobal.java75
-rw-r--r--core/java/android/hardware/display/VirtualDisplayConfig.java48
-rw-r--r--core/java/android/hardware/input/KeyGestureEvent.java26
-rw-r--r--core/java/android/os/CombinedMessageQueue/MessageQueue.java114
-rw-r--r--core/java/android/os/ConcurrentMessageQueue/MessageQueue.java22
-rw-r--r--core/java/android/permission/flags.aconfig18
-rw-r--r--core/java/android/security/advancedprotection/AdvancedProtectionFeature.aidl23
-rw-r--r--core/java/android/security/advancedprotection/AdvancedProtectionFeature.java77
-rw-r--r--core/java/android/security/advancedprotection/AdvancedProtectionManager.java19
-rw-r--r--core/java/android/security/advancedprotection/IAdvancedProtectionService.aidl3
-rw-r--r--core/java/android/security/responsible_apis_flags.aconfig8
-rw-r--r--core/java/android/service/contextualsearch/OWNERS3
-rw-r--r--core/java/android/service/notification/NotificationListenerService.java32
-rw-r--r--core/java/android/service/notification/flags.aconfig8
-rw-r--r--core/java/android/service/wallpaper/WallpaperService.java4
-rw-r--r--core/java/android/view/SurfaceControl.java13
-rw-r--r--core/java/android/view/SurfaceView.java34
-rw-r--r--core/java/android/view/View.java139
-rw-r--r--core/java/android/view/accessibility/AccessibilityEvent.java24
-rw-r--r--core/java/android/view/accessibility/AccessibilityNodeInfo.java65
-rw-r--r--core/java/android/view/accessibility/flags/accessibility_flags.aconfig7
-rw-r--r--core/java/android/widget/RemoteViews.java109
-rw-r--r--core/java/android/widget/TextClock.java22
-rw-r--r--core/java/android/window/DesktopModeFlags.java7
-rw-r--r--core/java/com/android/internal/app/SuggestedLocaleAdapter.java69
-rw-r--r--core/java/com/android/internal/content/om/OverlayConfig.java3
-rw-r--r--core/java/com/android/internal/content/om/OverlayManagerImpl.java20
-rw-r--r--core/java/com/android/internal/jank/FrameTracker.java5
-rw-r--r--core/java/com/android/server/FgThread.java1
-rw-r--r--core/java/com/android/server/ServiceThread.java1
-rw-r--r--core/jni/Android.bp50
-rw-r--r--core/jni/android_view_SurfaceControl.cpp20
-rw-r--r--core/res/AndroidManifest.xml6
-rw-r--r--core/res/res/layout/app_language_picker_locale_item.xml (renamed from core/res/res/layout/app_language_picker_current_locale_item.xml)37
-rw-r--r--core/res/res/values-en-rCA/strings.xml15
-rw-r--r--core/res/res/values-it/strings.xml15
-rw-r--r--core/res/res/values-ne/strings.xml2
-rw-r--r--core/res/res/values-pt-rPT/strings.xml15
-rw-r--r--core/res/res/values-te/strings.xml2
-rw-r--r--core/res/res/values/attrs.xml6
-rw-r--r--core/res/res/values/public-staging.xml2
-rw-r--r--core/res/res/values/symbols.xml2
-rw-r--r--core/tests/coretests/src/android/view/accessibility/AccessibilityNodeInfoTest.java2
-rw-r--r--core/tests/coretests/src/com/android/internal/jank/FrameTrackerTest.java8
-rw-r--r--core/tests/overlaytests/device_self_targeting/src/com/android/overlaytest/OverlayManagerImplTest.java15
-rw-r--r--graphics/java/android/graphics/RenderNode.java13
-rw-r--r--graphics/java/android/graphics/RuntimeColorFilter.java305
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/DividerPresenter.java28
-rw-r--r--libs/WindowManager/Shell/multivalentScreenshotTests/Android.bp36
-rw-r--r--libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleStackViewTest.kt25
-rw-r--r--libs/WindowManager/Shell/res/values-ar/strings.xml6
-rw-r--r--libs/WindowManager/Shell/res/values-as/strings.xml6
-rw-r--r--libs/WindowManager/Shell/res/values-bn/strings.xml6
-rw-r--r--libs/WindowManager/Shell/res/values-bs/strings.xml6
-rw-r--r--libs/WindowManager/Shell/res/values-cs/strings.xml6
-rw-r--r--libs/WindowManager/Shell/res/values-el/strings.xml6
-rw-r--r--libs/WindowManager/Shell/res/values-en-rAU/strings.xml6
-rw-r--r--libs/WindowManager/Shell/res/values-en-rGB/strings.xml6
-rw-r--r--libs/WindowManager/Shell/res/values-en-rIN/strings.xml6
-rw-r--r--libs/WindowManager/Shell/res/values-hi/strings.xml6
-rw-r--r--libs/WindowManager/Shell/res/values-hr/strings.xml6
-rw-r--r--libs/WindowManager/Shell/res/values-is/strings.xml6
-rw-r--r--libs/WindowManager/Shell/res/values-it/strings.xml6
-rw-r--r--libs/WindowManager/Shell/res/values-ja/strings.xml6
-rw-r--r--libs/WindowManager/Shell/res/values-ka/strings.xml6
-rw-r--r--libs/WindowManager/Shell/res/values-km/strings.xml6
-rw-r--r--libs/WindowManager/Shell/res/values-kn/strings.xml6
-rw-r--r--libs/WindowManager/Shell/res/values-lt/strings.xml6
-rw-r--r--libs/WindowManager/Shell/res/values-mr/strings.xml6
-rw-r--r--libs/WindowManager/Shell/res/values-ms/strings.xml6
-rw-r--r--libs/WindowManager/Shell/res/values-ne/strings.xml6
-rw-r--r--libs/WindowManager/Shell/res/values-pl/strings.xml6
-rw-r--r--libs/WindowManager/Shell/res/values-pt-rPT/strings.xml6
-rw-r--r--libs/WindowManager/Shell/res/values-sl/strings.xml6
-rw-r--r--libs/WindowManager/Shell/res/values-ta/strings.xml6
-rw-r--r--libs/WindowManager/Shell/res/values-te/strings.xml6
-rw-r--r--libs/WindowManager/Shell/res/values-th/strings.xml6
-rw-r--r--libs/WindowManager/Shell/res/values-tl/strings.xml6
-rw-r--r--libs/WindowManager/Shell/res/values-zh-rCN/strings.xml6
-rw-r--r--libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/pip/PipContentOverlay.java39
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java44
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java30
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerSnapAlgorithm.java73
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java52
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopImmersiveController.kt5
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt10
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandler.java3
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopRepositoryInitializerImpl.kt4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java79
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java104
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java8
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java24
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipTransition.java6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip2/animation/PipResizeAnimator.java89
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/recents/IRecentTasksListener.aidl3
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java26
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/recents/TaskStackTransitionObserver.kt17
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java14
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java31
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java74
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopStatusBarInputLayerSupplier.kt117
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java16
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/additionalviewcontainer/AdditionalSystemViewContainer.kt92
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModel.kt26
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDividerWindowManager.kt26
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/TilingDividerView.kt2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolder.kt109
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java12
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandlerTest.java40
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/education/AppHandleEducationControllerTest.kt1
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java2
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/animation/PipResizeAnimatorTest.java276
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/TaskStackTransitionObserverTest.kt166
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt4
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java10
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java8
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModelTest.kt27
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDividerWindowManagerTest.kt30
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt2
-rw-r--r--libs/hwui/Android.bp2
-rw-r--r--libs/hwui/ColorFilter.h31
-rw-r--r--libs/hwui/hwui/ImageDecoder.cpp4
-rw-r--r--libs/hwui/jni/BitmapFactory.cpp4
-rw-r--r--libs/hwui/jni/BitmapRegionDecoder.cpp4
-rw-r--r--libs/hwui/jni/ColorFilter.cpp93
-rw-r--r--libs/hwui/jni/ImageDecoder.cpp4
-rw-r--r--libs/hwui/jni/RuntimeEffectUtils.cpp101
-rw-r--r--libs/hwui/jni/RuntimeEffectUtils.h37
-rw-r--r--libs/hwui/jni/android_graphics_RenderNode.cpp10
-rw-r--r--libs/hwui/libhwui.map.txt1
-rw-r--r--libs/hwui/utils/StatsUtils.cpp102
-rw-r--r--libs/hwui/utils/StatsUtils.h33
-rw-r--r--media/java/android/media/AudioAttributes.java36
-rw-r--r--media/java/android/media/AudioDeviceInfo.java33
-rw-r--r--media/java/android/media/AudioManager.java5
-rw-r--r--media/java/android/media/AudioSystem.java7
-rw-r--r--media/java/android/media/MediaCodecInfo.java260
-rw-r--r--media/java/android/media/MediaFormat.java3
-rw-r--r--media/java/android/media/MediaRecorder.java4
-rw-r--r--native/graphics/jni/Android.bp9
-rw-r--r--native/graphics/jni/imagedecoder.cpp41
-rw-r--r--packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/HandlerExecutor.kt2
-rw-r--r--packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/KeyedObserver.kt4
-rw-r--r--packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceScreenBindingHelper.kt3
-rw-r--r--packages/SettingsLib/res/values-bs/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-in/arrays.xml4
-rw-r--r--packages/SettingsLib/res/values-in/strings.xml4
-rw-r--r--packages/SettingsLib/res/values-ky/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-mk/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-or/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-sk/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-sv/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-th/strings.xml2
-rw-r--r--packages/SystemUI/aconfig/systemui.aconfig7
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractorTest.kt2
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractorTest.kt82
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/composefragment/viewmodel/AbstractQSFragmentComposeViewModelTest.kt12
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelTest.kt103
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModelTest.kt45
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowControllerTest.kt9
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java7
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManagerTest.kt19
-rw-r--r--packages/SystemUI/res/values-af/strings.xml8
-rw-r--r--packages/SystemUI/res/values-am/strings.xml8
-rw-r--r--packages/SystemUI/res/values-ar/strings.xml8
-rw-r--r--packages/SystemUI/res/values-as/strings.xml14
-rw-r--r--packages/SystemUI/res/values-az/strings.xml8
-rw-r--r--packages/SystemUI/res/values-b+sr+Latn/strings.xml14
-rw-r--r--packages/SystemUI/res/values-be/strings.xml8
-rw-r--r--packages/SystemUI/res/values-bg/strings.xml8
-rw-r--r--packages/SystemUI/res/values-bn/strings.xml14
-rw-r--r--packages/SystemUI/res/values-bs/strings.xml14
-rw-r--r--packages/SystemUI/res/values-ca/strings.xml8
-rw-r--r--packages/SystemUI/res/values-cs/strings.xml8
-rw-r--r--packages/SystemUI/res/values-da/strings.xml14
-rw-r--r--packages/SystemUI/res/values-de/strings.xml8
-rw-r--r--packages/SystemUI/res/values-el/strings.xml8
-rw-r--r--packages/SystemUI/res/values-en-rAU/strings.xml8
-rw-r--r--packages/SystemUI/res/values-en-rCA/strings.xml23
-rw-r--r--packages/SystemUI/res/values-en-rGB/strings.xml8
-rw-r--r--packages/SystemUI/res/values-en-rIN/strings.xml8
-rw-r--r--packages/SystemUI/res/values-es-rUS/strings.xml14
-rw-r--r--packages/SystemUI/res/values-es/strings.xml8
-rw-r--r--packages/SystemUI/res/values-et/strings.xml8
-rw-r--r--packages/SystemUI/res/values-eu/strings.xml8
-rw-r--r--packages/SystemUI/res/values-fa/strings.xml14
-rw-r--r--packages/SystemUI/res/values-fi/strings.xml8
-rw-r--r--packages/SystemUI/res/values-fr-rCA/strings.xml8
-rw-r--r--packages/SystemUI/res/values-fr/strings.xml8
-rw-r--r--packages/SystemUI/res/values-gl/strings.xml8
-rw-r--r--packages/SystemUI/res/values-gu/strings.xml14
-rw-r--r--packages/SystemUI/res/values-hi/strings.xml8
-rw-r--r--packages/SystemUI/res/values-hr/strings.xml8
-rw-r--r--packages/SystemUI/res/values-hu/strings.xml8
-rw-r--r--packages/SystemUI/res/values-hy/strings.xml8
-rw-r--r--packages/SystemUI/res/values-in/strings.xml12
-rw-r--r--packages/SystemUI/res/values-is/strings.xml14
-rw-r--r--packages/SystemUI/res/values-it/strings.xml23
-rw-r--r--packages/SystemUI/res/values-iw/strings.xml14
-rw-r--r--packages/SystemUI/res/values-ja/strings.xml8
-rw-r--r--packages/SystemUI/res/values-ka/strings.xml8
-rw-r--r--packages/SystemUI/res/values-kk/strings.xml8
-rw-r--r--packages/SystemUI/res/values-km/strings.xml8
-rw-r--r--packages/SystemUI/res/values-kn/strings.xml14
-rw-r--r--packages/SystemUI/res/values-ko/strings.xml16
-rw-r--r--packages/SystemUI/res/values-ky/strings.xml8
-rw-r--r--packages/SystemUI/res/values-lo/strings.xml8
-rw-r--r--packages/SystemUI/res/values-lt/strings.xml8
-rw-r--r--packages/SystemUI/res/values-lv/strings.xml8
-rw-r--r--packages/SystemUI/res/values-mk/strings.xml14
-rw-r--r--packages/SystemUI/res/values-ml/strings.xml14
-rw-r--r--packages/SystemUI/res/values-mn/strings.xml14
-rw-r--r--packages/SystemUI/res/values-mr/strings.xml14
-rw-r--r--packages/SystemUI/res/values-ms/strings.xml8
-rw-r--r--packages/SystemUI/res/values-my/strings.xml8
-rw-r--r--packages/SystemUI/res/values-nb/strings.xml8
-rw-r--r--packages/SystemUI/res/values-ne/strings.xml8
-rw-r--r--packages/SystemUI/res/values-nl/strings.xml14
-rw-r--r--packages/SystemUI/res/values-or/strings.xml8
-rw-r--r--packages/SystemUI/res/values-pa/strings.xml14
-rw-r--r--packages/SystemUI/res/values-pl/strings.xml8
-rw-r--r--packages/SystemUI/res/values-pt-rBR/strings.xml8
-rw-r--r--packages/SystemUI/res/values-pt-rPT/strings.xml23
-rw-r--r--packages/SystemUI/res/values-pt/strings.xml8
-rw-r--r--packages/SystemUI/res/values-ro/strings.xml8
-rw-r--r--packages/SystemUI/res/values-ru/strings.xml14
-rw-r--r--packages/SystemUI/res/values-si/strings.xml8
-rw-r--r--packages/SystemUI/res/values-sk/strings.xml14
-rw-r--r--packages/SystemUI/res/values-sl/strings.xml8
-rw-r--r--packages/SystemUI/res/values-sq/strings.xml8
-rw-r--r--packages/SystemUI/res/values-sr/strings.xml14
-rw-r--r--packages/SystemUI/res/values-sv/strings.xml8
-rw-r--r--packages/SystemUI/res/values-sw/strings.xml8
-rw-r--r--packages/SystemUI/res/values-ta/strings.xml8
-rw-r--r--packages/SystemUI/res/values-te/strings.xml14
-rw-r--r--packages/SystemUI/res/values-th/strings.xml8
-rw-r--r--packages/SystemUI/res/values-tl/strings.xml8
-rw-r--r--packages/SystemUI/res/values-tr/strings.xml8
-rw-r--r--packages/SystemUI/res/values-uk/strings.xml10
-rw-r--r--packages/SystemUI/res/values-ur/strings.xml8
-rw-r--r--packages/SystemUI/res/values-uz/strings.xml8
-rw-r--r--packages/SystemUI/res/values-vi/strings.xml14
-rw-r--r--packages/SystemUI/res/values-zh-rCN/strings.xml8
-rw-r--r--packages/SystemUI/res/values-zh-rHK/strings.xml8
-rw-r--r--packages/SystemUI/res/values-zh-rTW/strings.xml8
-rw-r--r--packages/SystemUI/res/values-zu/strings.xml8
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/MultitaskingShortcutsSource.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt24
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSImpl.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt81
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/composefragment/dagger/QSFragmentComposeModule.kt40
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModel.kt82
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PaginatedGridLayout.kt13
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/QuickQuickSettings.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/InfiniteGridLayout.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/InFirstPageViewModel.kt29
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/InfiniteGridViewModel.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModel.kt59
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/QSColumnsViewModel.kt22
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModel.kt90
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModel.kt13
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java38
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java15
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java1
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java36
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardTransitionRepository.kt35
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/domain/pipeline/LegacyMediaDataManagerImplKosmos.kt23
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/domain/pipeline/MediaDataManagerKosmos.kt21
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/controller/MediaCarouselControllerKosmos.kt23
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/controller/MediaCarouselControllerLoggerKosmos.kt23
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/controller/MediaHierarchyManagerKosmos.kt11
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/controller/MediaHostStatesManagerKosmos.kt21
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/view/MediaHostKosmos.kt42
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/qs/composefragment/dagger/QSFragmentComposeModuleKosmos.kt21
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelKosmos.kt10
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/InFirstPageViewModelKosmos.kt21
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModelKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModelKosmos.kt24
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModelKosmos.kt4
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManagerKosmos.kt2
-rw-r--r--ravenwood/texts/ravenwood-annotation-allowed-classes.txt3
-rw-r--r--services/Android.bp23
-rw-r--r--services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java216
-rw-r--r--services/companion/java/com/android/server/companion/CompanionExemptionProcessor.java219
-rw-r--r--services/companion/java/com/android/server/companion/devicepresence/CompanionAppBinder.java5
-rw-r--r--services/companion/java/com/android/server/companion/devicepresence/DevicePresenceProcessor.java27
-rw-r--r--services/core/Android.bp1
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java8
-rw-r--r--services/core/java/com/android/server/am/BroadcastController.java15
-rw-r--r--services/core/java/com/android/server/am/SettingsToPropertiesMapper.java1
-rw-r--r--services/core/java/com/android/server/audio/AudioDeviceBroker.java14
-rw-r--r--services/core/java/com/android/server/audio/AudioService.java30
-rw-r--r--services/core/java/com/android/server/audio/MediaFocusControl.java1
-rw-r--r--services/core/java/com/android/server/display/DisplayManagerService.java61
-rw-r--r--services/core/java/com/android/server/input/KeyGestureController.java49
-rw-r--r--services/core/java/com/android/server/locksettings/LockSettingsService.java21
-rw-r--r--services/core/java/com/android/server/notification/NotificationManagerService.java30
-rw-r--r--services/core/java/com/android/server/pm/BroadcastHelper.java106
-rw-r--r--services/core/java/com/android/server/security/advancedprotection/AdvancedProtectionService.java36
-rw-r--r--services/core/java/com/android/server/security/advancedprotection/features/AdvancedProtectionHook.java4
-rw-r--r--services/core/java/com/android/server/security/advancedprotection/features/AdvancedProtectionProvider.java27
-rw-r--r--services/core/java/com/android/server/stats/pull/netstats/NetworkStatsAccumulator.java24
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecordInputSink.java3
-rw-r--r--services/core/java/com/android/server/wm/ActivityStartController.java2
-rw-r--r--services/core/java/com/android/server/wm/ActivityStarter.java43
-rw-r--r--services/core/java/com/android/server/wm/AppCompatAspectRatioOverrides.java12
-rw-r--r--services/core/java/com/android/server/wm/AppCompatOrientationPolicy.java13
-rw-r--r--services/core/java/com/android/server/wm/AppCompatSizeCompatModePolicy.java2
-rw-r--r--services/core/java/com/android/server/wm/AppCompatUtils.java18
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java11
-rw-r--r--services/core/java/com/android/server/wm/DisplayWindowSettings.java40
-rw-r--r--services/core/java/com/android/server/wm/Task.java3
-rw-r--r--services/core/java/com/android/server/wm/WindowContainer.java4
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerInternal.java12
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java14
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java4
-rw-r--r--services/core/java/com/android/server/wm/utils/RegionUtils.java5
-rw-r--r--services/tests/servicestests/src/com/android/server/security/advancedprotection/AdvancedProtectionServiceTest.java96
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java220
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java4
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/AppCompatActivityRobot.java4
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/AppCompatAspectRatioOverridesTest.java98
-rw-r--r--test-mock/src/android/test/mock/MockContext.java7
-rw-r--r--tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt80
-rw-r--r--tests/graphics/HwAccelerationTest/AndroidManifest.xml20
-rw-r--r--tests/graphics/HwAccelerationTest/res/layout/scrolling_zabove_surfaceview.xml131
-rw-r--r--tests/graphics/HwAccelerationTest/src/com/android/test/hwui/ScrollingZAboveScaledSurfaceView.kt58
-rw-r--r--tests/graphics/HwAccelerationTest/src/com/android/test/hwui/ScrollingZAboveSurfaceView.kt57
364 files changed, 6902 insertions, 1890 deletions
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java
index ff4af69fd77c..8bd3ef4f4d1a 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java
@@ -121,6 +121,9 @@ public final class QuotaController extends StateController {
private static final String ALARM_TAG_CLEANUP = "*job.cleanup*";
private static final String ALARM_TAG_QUOTA_CHECK = "*job.quota_check*";
+ private static final String TRACE_QUOTA_STATE_CHANGED_TAG = "QuotaStateChanged:";
+ private static final String TRACE_QUOTA_STATE_CHANGED_DELIMITER = "#";
+
private static final int SYSTEM_APP_CHECK_FLAGS =
PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
| PackageManager.GET_PERMISSIONS | PackageManager.MATCH_KNOWN_PACKAGES;
@@ -2657,11 +2660,12 @@ public final class QuotaController extends StateController {
if (timeRemainingMs <= 50) {
// Less than 50 milliseconds left. Start process of shutting down jobs.
if (DEBUG) Slog.d(TAG, pkg + " has reached its quota.");
- if (Trace.isTagEnabled(Trace.TRACE_TAG_SYSTEM_SERVER)) {
- Trace.instantForTrack(Trace.TRACE_TAG_SYSTEM_SERVER,
- JobSchedulerService.TRACE_TRACK_NAME,
- pkg + "#" + MSG_REACHED_TIME_QUOTA);
- }
+ final StringBuilder traceMsg = new StringBuilder();
+ traceMsg.append(TRACE_QUOTA_STATE_CHANGED_TAG)
+ .append(pkg)
+ .append(TRACE_QUOTA_STATE_CHANGED_DELIMITER)
+ .append(MSG_REACHED_TIME_QUOTA);
+ Trace.instant(Trace.TRACE_TAG_POWER, traceMsg.toString());
mStateChangedListener.onControllerStateChanged(
maybeUpdateConstraintForPkgLocked(
sElapsedRealtimeClock.millis(),
@@ -2690,11 +2694,12 @@ public final class QuotaController extends StateController {
pkg.userId, pkg.packageName);
if (timeRemainingMs <= 0) {
if (DEBUG) Slog.d(TAG, pkg + " has reached its EJ quota.");
- if (Trace.isTagEnabled(Trace.TRACE_TAG_SYSTEM_SERVER)) {
- Trace.instantForTrack(Trace.TRACE_TAG_SYSTEM_SERVER,
- JobSchedulerService.TRACE_TRACK_NAME,
- pkg + "#" + MSG_REACHED_EJ_TIME_QUOTA);
- }
+ final StringBuilder traceMsg = new StringBuilder();
+ traceMsg.append(TRACE_QUOTA_STATE_CHANGED_TAG)
+ .append(pkg)
+ .append(TRACE_QUOTA_STATE_CHANGED_DELIMITER)
+ .append(MSG_REACHED_EJ_TIME_QUOTA);
+ Trace.instant(Trace.TRACE_TAG_POWER, traceMsg.toString());
mStateChangedListener.onControllerStateChanged(
maybeUpdateConstraintForPkgLocked(
sElapsedRealtimeClock.millis(),
@@ -2719,11 +2724,12 @@ public final class QuotaController extends StateController {
Slog.d(TAG, pkg + " has reached its count quota.");
}
- if (Trace.isTagEnabled(Trace.TRACE_TAG_SYSTEM_SERVER)) {
- Trace.instantForTrack(Trace.TRACE_TAG_SYSTEM_SERVER,
- JobSchedulerService.TRACE_TRACK_NAME,
- pkg + "#" + MSG_REACHED_COUNT_QUOTA);
- }
+ final StringBuilder traceMsg = new StringBuilder();
+ traceMsg.append(TRACE_QUOTA_STATE_CHANGED_TAG)
+ .append(pkg)
+ .append(TRACE_QUOTA_STATE_CHANGED_DELIMITER)
+ .append(MSG_REACHED_COUNT_QUOTA);
+ Trace.instant(Trace.TRACE_TAG_POWER, traceMsg.toString());
mStateChangedListener.onControllerStateChanged(
maybeUpdateConstraintForPkgLocked(
diff --git a/core/api/current.txt b/core/api/current.txt
index 522d2f28a6fc..4b90f7256628 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -1609,6 +1609,7 @@ package android {
field public static final int summaryColumn = 16843426; // 0x10102a2
field public static final int summaryOff = 16843248; // 0x10101f0
field public static final int summaryOn = 16843247; // 0x10101ef
+ field @FlaggedApi("android.view.accessibility.supplemental_description") public static final int supplementalDescription;
field public static final int supportedTypes = 16844369; // 0x1010651
field public static final int supportsAssist = 16844016; // 0x10104f0
field public static final int supportsBatteryGameMode = 16844374; // 0x1010656
@@ -17368,6 +17369,25 @@ package android.graphics {
method public boolean setUseCompositingLayer(boolean, @Nullable android.graphics.Paint);
}
+ @FlaggedApi("com.android.graphics.hwui.flags.runtime_color_filters_blenders") public class RuntimeColorFilter extends android.graphics.ColorFilter {
+ ctor public RuntimeColorFilter(@NonNull String);
+ method public void setColorUniform(@NonNull String, @ColorInt int);
+ method public void setColorUniform(@NonNull String, @ColorLong long);
+ method public void setColorUniform(@NonNull String, @NonNull android.graphics.Color);
+ method public void setFloatUniform(@NonNull String, float);
+ method public void setFloatUniform(@NonNull String, float, float);
+ method public void setFloatUniform(@NonNull String, float, float, float);
+ method public void setFloatUniform(@NonNull String, float, float, float, float);
+ method public void setFloatUniform(@NonNull String, @NonNull float[]);
+ method public void setInputColorFilter(@NonNull String, @NonNull android.graphics.ColorFilter);
+ method public void setInputShader(@NonNull String, @NonNull android.graphics.Shader);
+ method public void setIntUniform(@NonNull String, int);
+ method public void setIntUniform(@NonNull String, int, int);
+ method public void setIntUniform(@NonNull String, int, int, int);
+ method public void setIntUniform(@NonNull String, int, int, int, int);
+ method public void setIntUniform(@NonNull String, @NonNull int[]);
+ }
+
public class RuntimeShader extends android.graphics.Shader {
ctor public RuntimeShader(@NonNull String);
method public void setColorUniform(@NonNull String, @ColorInt int);
@@ -19321,6 +19341,8 @@ package android.hardware.camera2 {
field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> AUTOMOTIVE_LENS_FACING;
field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> AUTOMOTIVE_LOCATION;
field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES;
+ field @FlaggedApi("com.android.internal.camera.flags.color_temperature") @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> COLOR_CORRECTION_AVAILABLE_MODES;
+ field @FlaggedApi("com.android.internal.camera.flags.color_temperature") @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<android.util.Range<java.lang.Integer>> COLOR_CORRECTION_COLOR_TEMPERATURE_RANGE;
field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> CONTROL_AE_AVAILABLE_ANTIBANDING_MODES;
field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> CONTROL_AE_AVAILABLE_MODES;
field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<android.util.Range<java.lang.Integer>[]> CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES;
@@ -19622,6 +19644,7 @@ package android.hardware.camera2 {
field public static final int COLOR_CORRECTION_ABERRATION_MODE_FAST = 1; // 0x1
field public static final int COLOR_CORRECTION_ABERRATION_MODE_HIGH_QUALITY = 2; // 0x2
field public static final int COLOR_CORRECTION_ABERRATION_MODE_OFF = 0; // 0x0
+ field @FlaggedApi("com.android.internal.camera.flags.color_temperature") public static final int COLOR_CORRECTION_MODE_CCT = 3; // 0x3
field public static final int COLOR_CORRECTION_MODE_FAST = 1; // 0x1
field public static final int COLOR_CORRECTION_MODE_HIGH_QUALITY = 2; // 0x2
field public static final int COLOR_CORRECTION_MODE_TRANSFORM_MATRIX = 0; // 0x0
@@ -19908,6 +19931,8 @@ package android.hardware.camera2 {
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Boolean> BLACK_LEVEL_LOCK;
field @NonNull public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> COLOR_CORRECTION_ABERRATION_MODE;
+ field @FlaggedApi("com.android.internal.camera.flags.color_temperature") @NonNull public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> COLOR_CORRECTION_COLOR_TEMPERATURE;
+ field @FlaggedApi("com.android.internal.camera.flags.color_temperature") @NonNull public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> COLOR_CORRECTION_COLOR_TINT;
field @NonNull public static final android.hardware.camera2.CaptureRequest.Key<android.hardware.camera2.params.RggbChannelVector> COLOR_CORRECTION_GAINS;
field @NonNull public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> COLOR_CORRECTION_MODE;
field @NonNull public static final android.hardware.camera2.CaptureRequest.Key<android.hardware.camera2.params.ColorSpaceTransform> COLOR_CORRECTION_TRANSFORM;
@@ -19998,6 +20023,8 @@ package android.hardware.camera2 {
method public int getSequenceId();
field @NonNull public static final android.hardware.camera2.CaptureResult.Key<java.lang.Boolean> BLACK_LEVEL_LOCK;
field @NonNull public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> COLOR_CORRECTION_ABERRATION_MODE;
+ field @FlaggedApi("com.android.internal.camera.flags.color_temperature") @NonNull public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> COLOR_CORRECTION_COLOR_TEMPERATURE;
+ field @FlaggedApi("com.android.internal.camera.flags.color_temperature") @NonNull public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> COLOR_CORRECTION_COLOR_TINT;
field @NonNull public static final android.hardware.camera2.CaptureResult.Key<android.hardware.camera2.params.RggbChannelVector> COLOR_CORRECTION_GAINS;
field @NonNull public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> COLOR_CORRECTION_MODE;
field @NonNull public static final android.hardware.camera2.CaptureResult.Key<android.hardware.camera2.params.ColorSpaceTransform> COLOR_CORRECTION_TRANSFORM;
@@ -21379,6 +21406,7 @@ package android.media {
field public static final int TYPE_IP = 20; // 0x14
field public static final int TYPE_LINE_ANALOG = 5; // 0x5
field public static final int TYPE_LINE_DIGITAL = 6; // 0x6
+ field @FlaggedApi("android.media.audio.enable_multichannel_group_device") public static final int TYPE_MULTICHANNEL_GROUP = 32; // 0x20
field public static final int TYPE_REMOTE_SUBMIX = 25; // 0x19
field public static final int TYPE_TELEPHONY = 18; // 0x12
field public static final int TYPE_TV_TUNER = 17; // 0x11
@@ -23096,6 +23124,65 @@ package android.media {
field public static final int AC4Profile11 = 514; // 0x202
field public static final int AC4Profile21 = 1026; // 0x402
field public static final int AC4Profile22 = 1028; // 0x404
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel11Band0 = 513; // 0x201
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel11Band1 = 514; // 0x202
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel11Band2 = 516; // 0x204
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel11Band3 = 520; // 0x208
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel1Band0 = 257; // 0x101
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel1Band1 = 258; // 0x102
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel1Band2 = 260; // 0x104
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel1Band3 = 264; // 0x108
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel21Band0 = 2049; // 0x801
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel21Band1 = 2050; // 0x802
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel21Band2 = 2052; // 0x804
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel21Band3 = 2056; // 0x808
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel2Band0 = 1025; // 0x401
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel2Band1 = 1026; // 0x402
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel2Band2 = 1028; // 0x404
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel2Band3 = 1032; // 0x408
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel31Band0 = 8193; // 0x2001
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel31Band1 = 8194; // 0x2002
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel31Band2 = 8196; // 0x2004
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel31Band3 = 8200; // 0x2008
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel3Band0 = 4097; // 0x1001
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel3Band1 = 4098; // 0x1002
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel3Band2 = 4100; // 0x1004
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel3Band3 = 4104; // 0x1008
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel41Band0 = 32769; // 0x8001
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel41Band1 = 32770; // 0x8002
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel41Band2 = 32772; // 0x8004
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel41Band3 = 32776; // 0x8008
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel4Band0 = 16385; // 0x4001
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel4Band1 = 16386; // 0x4002
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel4Band2 = 16388; // 0x4004
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel4Band3 = 16392; // 0x4008
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel51Band0 = 131073; // 0x20001
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel51Band1 = 131074; // 0x20002
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel51Band2 = 131076; // 0x20004
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel51Band3 = 131080; // 0x20008
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel5Band0 = 65537; // 0x10001
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel5Band1 = 65538; // 0x10002
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel5Band2 = 65540; // 0x10004
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel5Band3 = 65544; // 0x10008
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel61Band0 = 524289; // 0x80001
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel61Band1 = 524290; // 0x80002
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel61Band2 = 524292; // 0x80004
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel61Band3 = 524296; // 0x80008
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel6Band0 = 262145; // 0x40001
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel6Band1 = 262146; // 0x40002
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel6Band2 = 262148; // 0x40004
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel6Band3 = 262152; // 0x40008
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel71Band0 = 2097153; // 0x200001
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel71Band1 = 2097154; // 0x200002
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel71Band2 = 2097156; // 0x200004
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel71Band3 = 2097160; // 0x200008
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel7Band0 = 1048577; // 0x100001
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel7Band1 = 1048578; // 0x100002
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel7Band2 = 1048580; // 0x100004
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVLevel7Band3 = 1048584; // 0x100008
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVProfile422_10 = 1; // 0x1
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVProfile422_10HDR10 = 4096; // 0x1000
+ field @FlaggedApi("android.media.codec.apv_support") public static final int APVProfile422_10HDR10Plus = 8192; // 0x2000
field public static final int AV1Level2 = 1; // 0x1
field public static final int AV1Level21 = 2; // 0x2
field public static final int AV1Level22 = 4; // 0x4
@@ -23946,6 +24033,7 @@ package android.media {
field public static final String MIMETYPE_TEXT_CEA_708 = "text/cea-708";
field public static final String MIMETYPE_TEXT_SUBRIP = "application/x-subrip";
field public static final String MIMETYPE_TEXT_VTT = "text/vtt";
+ field @FlaggedApi("android.media.codec.apv_support") public static final String MIMETYPE_VIDEO_APV = "video/apv";
field public static final String MIMETYPE_VIDEO_AV1 = "video/av01";
field public static final String MIMETYPE_VIDEO_AVC = "video/avc";
field public static final String MIMETYPE_VIDEO_DOLBY_VISION = "video/dolby-vision";
@@ -39822,7 +39910,7 @@ package android.security {
package android.security.advancedprotection {
- @FlaggedApi("android.security.aapm_api") public class AdvancedProtectionManager {
+ @FlaggedApi("android.security.aapm_api") public final class AdvancedProtectionManager {
method @RequiresPermission(android.Manifest.permission.QUERY_ADVANCED_PROTECTION_MODE) public boolean isAdvancedProtectionEnabled();
method @RequiresPermission(android.Manifest.permission.QUERY_ADVANCED_PROTECTION_MODE) public void registerAdvancedProtectionCallback(@NonNull java.util.concurrent.Executor, @NonNull android.security.advancedprotection.AdvancedProtectionManager.Callback);
method @RequiresPermission(android.Manifest.permission.QUERY_ADVANCED_PROTECTION_MODE) public void unregisterAdvancedProtectionCallback(@NonNull android.security.advancedprotection.AdvancedProtectionManager.Callback);
@@ -41488,6 +41576,7 @@ package android.service.notification {
method public final void cancelNotification(String);
method public final void cancelNotifications(String[]);
method public final void clearRequestedListenerHints();
+ method @FlaggedApi("android.service.notification.notification_conversation_channel_management") @Nullable public final android.app.NotificationChannel createConversationNotificationChannelForPackage(@NonNull String, @NonNull android.os.UserHandle, @NonNull String, @NonNull String);
method public android.service.notification.StatusBarNotification[] getActiveNotifications();
method public android.service.notification.StatusBarNotification[] getActiveNotifications(String[]);
method public final int getCurrentInterruptionFilter();
@@ -53135,6 +53224,7 @@ package android.view {
method public android.animation.StateListAnimator getStateListAnimator();
method protected int getSuggestedMinimumHeight();
method protected int getSuggestedMinimumWidth();
+ method @FlaggedApi("android.view.accessibility.supplemental_description") @Nullable public CharSequence getSupplementalDescription();
method @NonNull public java.util.List<android.graphics.Rect> getSystemGestureExclusionRects();
method @Deprecated public int getSystemUiVisibility();
method public Object getTag();
@@ -53515,6 +53605,7 @@ package android.view {
method public void setSoundEffectsEnabled(boolean);
method public void setStateDescription(@Nullable CharSequence);
method public void setStateListAnimator(android.animation.StateListAnimator);
+ method @FlaggedApi("android.view.accessibility.supplemental_description") public void setSupplementalDescription(@Nullable CharSequence);
method public void setSystemGestureExclusionRects(@NonNull java.util.List<android.graphics.Rect>);
method @Deprecated public void setSystemUiVisibility(int);
method public void setTag(Object);
@@ -55121,6 +55212,7 @@ package android.view.accessibility {
field public static final int CONTENT_CHANGE_TYPE_PANE_TITLE = 8; // 0x8
field public static final int CONTENT_CHANGE_TYPE_STATE_DESCRIPTION = 64; // 0x40
field public static final int CONTENT_CHANGE_TYPE_SUBTREE = 1; // 0x1
+ field @FlaggedApi("android.view.accessibility.supplemental_description") public static final int CONTENT_CHANGE_TYPE_SUPPLEMENTAL_DESCRIPTION = 32768; // 0x8000
field public static final int CONTENT_CHANGE_TYPE_TEXT = 2; // 0x2
field public static final int CONTENT_CHANGE_TYPE_UNDEFINED = 0; // 0x0
field @NonNull public static final android.os.Parcelable.Creator<android.view.accessibility.AccessibilityEvent> CREATOR;
@@ -55283,6 +55375,7 @@ package android.view.accessibility {
method @Nullable public android.view.accessibility.AccessibilityNodeInfo getParent(int);
method public android.view.accessibility.AccessibilityNodeInfo.RangeInfo getRangeInfo();
method @Nullable public CharSequence getStateDescription();
+ method @FlaggedApi("android.view.accessibility.supplemental_description") @Nullable public CharSequence getSupplementalDescription();
method public CharSequence getText();
method public int getTextSelectionEnd();
method public int getTextSelectionStart();
@@ -55391,6 +55484,7 @@ package android.view.accessibility {
method public void setSource(android.view.View);
method public void setSource(android.view.View, int);
method public void setStateDescription(@Nullable CharSequence);
+ method @FlaggedApi("android.view.accessibility.supplemental_description") public void setSupplementalDescription(@Nullable CharSequence);
method public void setText(CharSequence);
method public void setTextEntryKey(boolean);
method public void setTextSelectable(boolean);
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index 4c9ce07664db..bc73220cb4c1 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -102,6 +102,7 @@ package android.content {
method @NonNull public android.os.UserHandle getUser();
field public static final String PAC_PROXY_SERVICE = "pac_proxy";
field public static final String TEST_NETWORK_SERVICE = "test_network";
+ field @FlaggedApi("android.os.mainline_vcn_platform_api") public static final String VCN_MANAGEMENT_SERVICE = "vcn_management";
field @FlaggedApi("android.webkit.update_service_ipc_wrapper") public static final String WEBVIEW_UPDATE_SERVICE = "webviewupdate";
}
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index c21d07752cbf..e202bfb535e8 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -1047,6 +1047,7 @@ package android.app {
method public int getUserLockedFields();
method public boolean isDeleted();
method public void populateFromXml(org.xmlpull.v1.XmlPullParser);
+ method @FlaggedApi("android.service.notification.notification_conversation_channel_management") public void setImportantConversation(boolean);
method public org.json.JSONObject toJson() throws org.json.JSONException;
method public void writeXml(org.xmlpull.v1.XmlSerializer) throws java.io.IOException;
field public static final int USER_LOCKED_SOUND = 32; // 0x20
@@ -5286,11 +5287,13 @@ package android.hardware.display {
public final class VirtualDisplayConfig implements android.os.Parcelable {
method @FlaggedApi("android.companion.virtualdevice.flags.virtual_display_insets") @Nullable public android.view.DisplayCutout getDisplayCutout();
method @FlaggedApi("android.companion.virtual.flags.vdm_custom_home") public boolean isHomeSupported();
+ method @FlaggedApi("com.android.window.flags.vdm_force_app_universal_resizable_api") public boolean isIgnoreActivitySizeRestrictions();
}
public static final class VirtualDisplayConfig.Builder {
method @FlaggedApi("android.companion.virtualdevice.flags.virtual_display_insets") @NonNull public android.hardware.display.VirtualDisplayConfig.Builder setDisplayCutout(@Nullable android.view.DisplayCutout);
method @FlaggedApi("android.companion.virtual.flags.vdm_custom_home") @NonNull public android.hardware.display.VirtualDisplayConfig.Builder setHomeSupported(boolean);
+ method @FlaggedApi("com.android.window.flags.vdm_force_app_universal_resizable_api") @NonNull public android.hardware.display.VirtualDisplayConfig.Builder setIgnoreActivitySizeRestrictions(boolean);
}
}
@@ -7227,7 +7230,6 @@ package android.media {
field @RequiresPermission(allOf={android.Manifest.permission.MODIFY_PHONE_STATE, android.Manifest.permission.MODIFY_AUDIO_ROUTING}) public static final int USAGE_CALL_ASSISTANT = 17; // 0x11
field @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static final int USAGE_EMERGENCY = 1000; // 0x3e8
field @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static final int USAGE_SAFETY = 1001; // 0x3e9
- field @FlaggedApi("android.media.audio.speaker_cleanup_usage") @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static final int USAGE_SPEAKER_CLEANUP = 1004; // 0x3ec
field @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static final int USAGE_VEHICLE_STATUS = 1002; // 0x3ea
}
@@ -7602,7 +7604,7 @@ package android.media {
public final class MediaRecorder.AudioSource {
field @RequiresPermission(android.Manifest.permission.CAPTURE_AUDIO_OUTPUT) public static final int ECHO_REFERENCE = 1997; // 0x7cd
field @RequiresPermission(android.Manifest.permission.CAPTURE_AUDIO_HOTWORD) public static final int HOTWORD = 1999; // 0x7cf
- field @RequiresPermission(android.Manifest.permission.CAPTURE_AUDIO_OUTPUT) public static final int RADIO_TUNER = 1998; // 0x7ce
+ field @RequiresPermission(android.Manifest.permission.CAPTURE_TUNER_AUDIO_INPUT) public static final int RADIO_TUNER = 1998; // 0x7ce
field @RequiresPermission(android.Manifest.permission.ACCESS_ULTRASOUND) public static final int ULTRASOUND = 2000; // 0x7d0
}
@@ -12464,7 +12466,16 @@ package android.security {
package android.security.advancedprotection {
- @FlaggedApi("android.security.aapm_api") public class AdvancedProtectionManager {
+ @FlaggedApi("android.security.aapm_api") public final class AdvancedProtectionFeature implements android.os.Parcelable {
+ ctor public AdvancedProtectionFeature(@NonNull String);
+ method public int describeContents();
+ method @NonNull public String getId();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.security.advancedprotection.AdvancedProtectionFeature> CREATOR;
+ }
+
+ @FlaggedApi("android.security.aapm_api") public final class AdvancedProtectionManager {
+ method @NonNull @RequiresPermission(android.Manifest.permission.SET_ADVANCED_PROTECTION_MODE) public java.util.List<android.security.advancedprotection.AdvancedProtectionFeature> getAdvancedProtectionFeatures();
method @RequiresPermission(android.Manifest.permission.SET_ADVANCED_PROTECTION_MODE) public void setAdvancedProtectionEnabled(boolean);
}
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index a0c4fdb90bf1..98d6f58e6bcf 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -369,6 +369,7 @@ package android.app {
}
public final class NotificationChannel implements android.os.Parcelable {
+ method @FlaggedApi("android.service.notification.notification_conversation_channel_management") @NonNull public android.app.NotificationChannel copy();
method public int getOriginalImportance();
method public boolean isImportanceLockedByCriticalDeviceFunction();
method public void lockFields(int);
@@ -376,7 +377,7 @@ package android.app {
method public void setDeletedTimeMs(long);
method public void setDemoted(boolean);
method public void setImportanceLockedByCriticalDeviceFunction(boolean);
- method public void setImportantConversation(boolean);
+ method @FlaggedApi("android.service.notification.notification_conversation_channel_management") public void setImportantConversation(boolean);
method public void setOriginalImportance(int);
method public void setUserVisibleTaskShown(boolean);
field @FlaggedApi("android.service.notification.notification_classification") public static final String NEWS_ID = "android.app.news";
@@ -1029,6 +1030,7 @@ package android.content {
public abstract class Context {
method @NonNull public java.io.File getCrateDir(@NonNull String);
method public abstract int getDisplayId();
+ method @NonNull public java.util.List<android.content.IntentFilter> getRegisteredIntentFilters(@NonNull android.content.BroadcastReceiver);
method @NonNull public android.os.UserHandle getUser();
method public int getUserId();
method public void setAutofillOptions(@Nullable android.content.AutofillOptions);
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index ecef0db46bb2..2cf718ef364f 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -1962,6 +1962,24 @@ class ContextImpl extends Context {
}
}
+ @Override
+ @NonNull
+ public List<IntentFilter> getRegisteredIntentFilters(@NonNull BroadcastReceiver receiver) {
+ if (mPackageInfo != null) {
+ IIntentReceiver rd = mPackageInfo.findRegisteredReceiverDispatcher(
+ receiver, getOuterContext());
+ try {
+ final List<IntentFilter> filters = ActivityManager.getService()
+ .getRegisteredIntentFilters(rd);
+ return filters == null ? new ArrayList<>() : filters;
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ } else {
+ throw new RuntimeException("Not supported in system context");
+ }
+ }
+
private void validateServiceIntent(Intent service) {
if (service.getComponent() == null && service.getPackage() == null) {
if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP) {
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index f880901429f7..34a3ad19b270 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -181,6 +181,7 @@ interface IActivityManager {
in IntentFilter filter, in String requiredPermission, int userId, int flags);
@UnsupportedAppUsage
void unregisterReceiver(in IIntentReceiver receiver);
+ List<IntentFilter> getRegisteredIntentFilters(in IIntentReceiver receiver);
/** @deprecated Use {@link #broadcastIntentWithFeature} instead */
@UnsupportedAppUsage(maxTargetSdk=29, publicAlternatives="Use {@link android.content.Context#sendBroadcast(android.content.Intent)} instead")
int broadcastIntent(in IApplicationThread caller, in Intent intent,
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index a7597b4d566d..a97fa18a3599 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -175,6 +175,7 @@ interface INotificationManager
void setOnNotificationPostedTrimFromListener(in INotificationListener token, int trim);
void setInterruptionFilter(String pkg, int interruptionFilter, boolean fromUser);
+ NotificationChannel createConversationNotificationChannelForPackageFromPrivilegedListener(in INotificationListener token, String pkg, in UserHandle user, String parentChannelId, String conversationId);
void updateNotificationChannelGroupFromPrivilegedListener(in INotificationListener token, String pkg, in UserHandle user, in NotificationChannelGroup group);
void updateNotificationChannelFromPrivilegedListener(in INotificationListener token, String pkg, in UserHandle user, in NotificationChannel channel);
ParceledListSlice getNotificationChannelsFromPrivilegedListener(in INotificationListener token, String pkg, in UserHandle user);
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index 1e45d6fd1674..b8233bc498b8 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -1627,6 +1627,18 @@ public final class LoadedApk {
}
}
+ IIntentReceiver findRegisteredReceiverDispatcher(BroadcastReceiver r, Context context) {
+ synchronized (mReceivers) {
+ final ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> map =
+ mReceivers.get(context);
+ if (map != null) {
+ final LoadedApk.ReceiverDispatcher rd = map.get(r);
+ return rd == null ? null : rd.getIIntentReceiver();
+ }
+ return null;
+ }
+ }
+
public IIntentReceiver forgetReceiverDispatcher(Context context,
BroadcastReceiver r) {
synchronized (mReceivers) {
diff --git a/core/java/android/app/NotificationChannel.java b/core/java/android/app/NotificationChannel.java
index ebe7b3a4fc51..73d26b834497 100644
--- a/core/java/android/app/NotificationChannel.java
+++ b/core/java/android/app/NotificationChannel.java
@@ -15,6 +15,8 @@
*/
package android.app;
+import static android.service.notification.Flags.FLAG_NOTIFICATION_CONVERSATION_CHANNEL_MANAGEMENT;
+
import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -475,9 +477,10 @@ public final class NotificationChannel implements Parcelable {
dest.writeBoolean(mImportanceLockedDefaultApp);
}
- /**
- * @hide
- */
+ /** @hide */
+ @TestApi
+ @NonNull
+ @FlaggedApi(FLAG_NOTIFICATION_CONVERSATION_CHANNEL_MANAGEMENT)
public NotificationChannel copy() {
NotificationChannel copy = new NotificationChannel(mId, mName, mImportance);
copy.setDescription(mDesc);
@@ -548,10 +551,10 @@ public final class NotificationChannel implements Parcelable {
mDeletedTime = time;
}
- /**
- * @hide
- */
+ /** @hide */
@TestApi
+ @SystemApi
+ @FlaggedApi(FLAG_NOTIFICATION_CONVERSATION_CHANNEL_MANAGEMENT)
public void setImportantConversation(boolean importantConvo) {
mImportantConvo = importantConvo;
}
diff --git a/core/java/android/app/admin/flags/flags.aconfig b/core/java/android/app/admin/flags/flags.aconfig
index fd583773d4e9..3aaca25eca15 100644
--- a/core/java/android/app/admin/flags/flags.aconfig
+++ b/core/java/android/app/admin/flags/flags.aconfig
@@ -341,3 +341,11 @@ flag {
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ name: "set_mte_policy_coexistence"
+ is_exported: true
+ namespace: "enterprise"
+ description: "Enables coexistence support for Setting MTE policy."
+ bug: "376213673"
+}
diff --git a/core/java/android/app/backup/NotificationLoggingConstants.java b/core/java/android/app/backup/NotificationLoggingConstants.java
index add456286df3..3601e862c02f 100644
--- a/core/java/android/app/backup/NotificationLoggingConstants.java
+++ b/core/java/android/app/backup/NotificationLoggingConstants.java
@@ -23,10 +23,56 @@ public class NotificationLoggingConstants {
// Key under which the payload blob is stored
public static final String KEY_NOTIFICATIONS = "notifications";
+ /**
+ * Events for android.service.notification.ZenModeConfig - the configuration for all modes
+ * settings for a single user
+ */
@BackupRestoreEventLogger.BackupRestoreDataType
public static final String DATA_TYPE_ZEN_CONFIG = KEY_NOTIFICATIONS + ":zen_config";
+ /**
+ * Events for android.service.notification.ZenModeConfig.ZenRule - a single mode within a
+ * ZenModeConfig
+ */
@BackupRestoreEventLogger.BackupRestoreDataType
public static final String DATA_TYPE_ZEN_RULES = KEY_NOTIFICATIONS + ":zen_rules";
+ /**
+ * Events for globally stored notifications data that aren't stored in settings, like whether
+ * to hide silent notification in the status bar
+ */
+ @BackupRestoreEventLogger.BackupRestoreDataType
+ public static final String DATA_TYPE_NOTIF_GLOBAL = KEY_NOTIFICATIONS + ":global";
+ /**
+ * Events for package specific notification settings, including app and
+ * android.app.NotificationChannel level settings.
+ */
+ @BackupRestoreEventLogger.BackupRestoreDataType
+ public static final String DATA_TYPE_NOTIF_PACKAGES = KEY_NOTIFICATIONS + ":packages";
+ /**
+ * Events for approved ManagedServices (NotificationListenerServices,
+ * NotificationAssistantService, ConditionProviderService).
+ */
+ @BackupRestoreEventLogger.BackupRestoreDataType
+ public static final String DATA_TYPE_MANAGED_SERVICE_PRIMARY_APPROVED = KEY_NOTIFICATIONS +
+ ":managed_service_primary_approved";
+ /**
+ * Events for what types of notifications NotificationListenerServices cannot see
+ */
+ @BackupRestoreEventLogger.BackupRestoreDataType
+ public static final String DATA_TYPE_NLS_RESTRICTED = KEY_NOTIFICATIONS +
+ ":nls_restricted";
+ /**
+ * Events for ManagedServices that are approved because they have a different primary
+ * ManagedService (ConditionProviderService).
+ */
+ @BackupRestoreEventLogger.BackupRestoreDataType
+ public static final String DATA_TYPE_MANAGED_SERVICE_SECONDARY_APPROVED = KEY_NOTIFICATIONS +
+ ":managed_service_secondary_approved";
+ /**
+ * Events for individual snoozed notifications.
+ */
+ @BackupRestoreEventLogger.BackupRestoreDataType
+ public static final String DATA_TYPE_SNOOZED = KEY_NOTIFICATIONS + ":snoozed";
+
@BackupRestoreEventLogger.BackupRestoreError
public static final String ERROR_XML_PARSING = KEY_NOTIFICATIONS + ":invalid_xml_parsing";
diff --git a/core/java/android/app/contextualsearch/flags.aconfig b/core/java/android/app/contextualsearch/flags.aconfig
index 3b0c86795738..5e09517d1edc 100644
--- a/core/java/android/app/contextualsearch/flags.aconfig
+++ b/core/java/android/app/contextualsearch/flags.aconfig
@@ -12,4 +12,18 @@ flag {
namespace: "machine_learning"
description: "Flag to refresh the token to the callback"
bug: "309689654"
+}
+
+flag {
+ name: "multi_window_screen_context"
+ namespace: "machine_learning"
+ description: "Report screen context and positions for all windows."
+ bug: "371065456"
+}
+
+flag {
+ name: "contextual_search_window_layer"
+ namespace: "machine_learning"
+ description: "Identify live contextual search UI to exclude from contextual search screenshot."
+ bug: "372510690"
} \ No newline at end of file
diff --git a/core/java/android/companion/virtual/flags/flags.aconfig b/core/java/android/companion/virtual/flags/flags.aconfig
index 9eb6d5624f75..9af20164a66d 100644
--- a/core/java/android/companion/virtual/flags/flags.aconfig
+++ b/core/java/android/companion/virtual/flags/flags.aconfig
@@ -145,3 +145,11 @@ flag {
bug: "370657575"
is_exported: true
}
+
+flag {
+ namespace: "virtual_devices"
+ name: "default_device_camera_access_policy"
+ description: "API for default device camera access policy"
+ bug: "371173368"
+ is_exported: true
+}
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 5893da371ed1..1d26b77af5c7 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -3658,6 +3658,27 @@ public abstract class Context {
public abstract void unregisterReceiver(BroadcastReceiver receiver);
/**
+ * Returns the list of {@link IntentFilter} objects that have been registered for the given
+ * {@link BroadcastReceiver}.
+ *
+ * @param receiver The {@link BroadcastReceiver} whose registered intent filters
+ * should be retrieved.
+ *
+ * @return A list of registered intent filters, or an empty list if the given receiver is not
+ * registered.
+ *
+ * @throws NullPointerException if the {@code receiver} is {@code null}.
+ *
+ * @hide
+ */
+ @SuppressLint("UnflaggedApi") // TestApi
+ @TestApi
+ @NonNull
+ public List<IntentFilter> getRegisteredIntentFilters(@NonNull BroadcastReceiver receiver) {
+ throw new RuntimeException("Not implemented. Must override in a subclass.");
+ }
+
+ /**
* Request that a given application service be started. The Intent
* should either contain the complete class name of a specific service
* implementation to start, or a specific package name to target. If the
@@ -4873,6 +4894,8 @@ public abstract class Context {
* @see android.net.vcn.VcnManager
* @hide
*/
+ @FlaggedApi(android.os.Flags.FLAG_MAINLINE_VCN_PLATFORM_API)
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final String VCN_MANAGEMENT_SERVICE = "vcn_management";
/**
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index 79fa6ea4d157..23d17cb5ce50 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -843,6 +843,13 @@ public class ContextWrapper extends Context {
mBase.unregisterReceiver(receiver);
}
+ /** @hide */
+ @Override
+ @NonNull
+ public List<IntentFilter> getRegisteredIntentFilters(@NonNull BroadcastReceiver receiver) {
+ return mBase.getRegisteredIntentFilters(receiver);
+ }
+
@Override
public @Nullable ComponentName startService(Intent service) {
return mBase.startService(service);
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 9bec5981261e..6fa5a9b82858 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -41,10 +41,7 @@ import android.app.Activity;
import android.app.ActivityThread;
import android.app.AppGlobals;
import android.app.StatusBarManager;
-import android.app.compat.CompatChanges;
import android.bluetooth.BluetoothDevice;
-import android.compat.annotation.ChangeId;
-import android.compat.annotation.Overridable;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
@@ -673,12 +670,6 @@ import java.util.TimeZone;
@android.ravenwood.annotation.RavenwoodKeepWholeClass
public class Intent implements Parcelable, Cloneable {
private static final String TAG = "Intent";
-
- /** @hide */
- @ChangeId
- @Overridable
- public static final long ENABLE_PREVENT_INTENT_REDIRECT = 29076063L;
-
private static final String ATTR_ACTION = "action";
private static final String TAG_CATEGORIES = "categories";
private static final String ATTR_CATEGORY = "category";
@@ -908,7 +899,7 @@ public class Intent implements Parcelable, Cloneable {
boolean isForeign = (intent.mLocalFlags & LOCAL_FLAG_FROM_PARCEL) != 0;
boolean isWithoutTrustedCreatorToken =
(intent.mLocalFlags & Intent.LOCAL_FLAG_TRUSTED_CREATOR_TOKEN_PRESENT) == 0;
- if (isForeign && isWithoutTrustedCreatorToken) {
+ if (isForeign && isWithoutTrustedCreatorToken && preventIntentRedirect()) {
intent.addExtendedFlags(EXTENDED_FLAG_MISSING_CREATOR_OR_INVALID_TOKEN);
}
}
@@ -12255,7 +12246,7 @@ public class Intent implements Parcelable, Cloneable {
* @hide
*/
public void collectExtraIntentKeys() {
- if (!isPreventIntentRedirectEnabled()) return;
+ if (!preventIntentRedirect()) return;
if (mExtras != null && !mExtras.isEmpty()) {
for (String key : mExtras.keySet()) {
@@ -12272,14 +12263,6 @@ public class Intent implements Parcelable, Cloneable {
}
}
- /**
- * @hide
- */
- public static boolean isPreventIntentRedirectEnabled() {
- return preventIntentRedirect() && CompatChanges.isChangeEnabled(
- ENABLE_PREVENT_INTENT_REDIRECT);
- }
-
/** @hide */
public void checkCreatorToken() {
if (mExtras == null) return;
@@ -12368,7 +12351,7 @@ public class Intent implements Parcelable, Cloneable {
out.writeInt(0);
}
- if (isPreventIntentRedirectEnabled()) {
+ if (preventIntentRedirect()) {
if (mCreatorTokenInfo == null) {
out.writeInt(0);
} else {
@@ -12435,7 +12418,7 @@ public class Intent implements Parcelable, Cloneable {
mOriginalIntent = new Intent(in);
}
- if (isPreventIntentRedirectEnabled()) {
+ if (preventIntentRedirect()) {
if (in.readInt() != 0) {
mCreatorTokenInfo = new CreatorTokenInfo();
mCreatorTokenInfo.mCreatorToken = in.readStrongBinder();
diff --git a/core/java/android/content/om/OverlayManager.java b/core/java/android/content/om/OverlayManager.java
index 6db7dfe4f705..ed965b3d1777 100644
--- a/core/java/android/content/om/OverlayManager.java
+++ b/core/java/android/content/om/OverlayManager.java
@@ -78,8 +78,7 @@ public class OverlayManager {
/**
* Applications can use OverlayManager to create overlays to overlay on itself resources. The
- * overlay target is itself, or the Android package, and the work range is only in caller
- * application.
+ * overlay target is itself and the work range is only in caller application.
*
* <p>In {@link android.content.Context#getSystemService(String)}, it crashes because of {@link
* java.lang.NullPointerException} if the parameter is OverlayManager. if the self-targeting is
@@ -402,7 +401,7 @@ public class OverlayManager {
}
/**
- * Get the related information of self-targeting overlays for {@code targetPackageName}.
+ * Get the related information of overlays for {@code targetPackageName}.
*
* @param targetPackageName the target package name
* @return a list of overlay information
diff --git a/core/java/android/content/om/OverlayManagerTransaction.java b/core/java/android/content/om/OverlayManagerTransaction.java
index 87b2e9350aa1..becd0ea285af 100644
--- a/core/java/android/content/om/OverlayManagerTransaction.java
+++ b/core/java/android/content/om/OverlayManagerTransaction.java
@@ -209,7 +209,6 @@ public final class OverlayManagerTransaction implements Parcelable {
*/
public static final class Builder {
private final List<Request> mRequests = new ArrayList<>();
- private boolean mSelfTargeting = false;
/**
* Request that an overlay package be enabled and change its loading
@@ -247,18 +246,6 @@ public final class OverlayManagerTransaction implements Parcelable {
}
/**
- * Request that an overlay package be self-targeting. Self-targeting overlays enable
- * applications to overlay on itself resources. The overlay target is itself, or the Android
- * package, and the work range is only in caller application.
- * @param selfTargeting whether the overlay is self-targeting, the default is false.
- * @hide
- */
- public Builder setSelfTargeting(boolean selfTargeting) {
- mSelfTargeting = selfTargeting;
- return this;
- }
-
- /**
* Registers the fabricated overlay with the overlay manager so it can be enabled and
* disabled for any user.
*
@@ -299,7 +286,7 @@ public final class OverlayManagerTransaction implements Parcelable {
*/
@NonNull
public OverlayManagerTransaction build() {
- return new OverlayManagerTransaction(mRequests, mSelfTargeting);
+ return new OverlayManagerTransaction(mRequests, false /* selfTargeting */);
}
}
diff --git a/core/java/android/content/pm/multiuser.aconfig b/core/java/android/content/pm/multiuser.aconfig
index 35f9cff1aedb..528bde80cd3d 100644
--- a/core/java/android/content/pm/multiuser.aconfig
+++ b/core/java/android/content/pm/multiuser.aconfig
@@ -536,7 +536,7 @@ flag {
flag {
name: "ignore_restrictions_when_deleting_private_profile"
- namespace: "multiuser"
+ namespace: "profile_experiences"
description: "Ignore any user restrictions when deleting private profiles."
bug: "350953833"
metadata {
diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java
index 347bebdf46e7..6fd4d0141977 100644
--- a/core/java/android/content/res/AssetManager.java
+++ b/core/java/android/content/res/AssetManager.java
@@ -75,10 +75,7 @@ public final class AssetManager implements AutoCloseable {
private static final String TAG = "AssetManager";
private static final boolean DEBUG_REFS = false;
- /**
- * @hide
- */
- public static final String FRAMEWORK_APK_PATH = getFrameworkApkPath();
+ private static final String FRAMEWORK_APK_PATH = getFrameworkApkPath();
private static final String FRAMEWORK_APK_PATH_DEVICE = "/system/framework/framework-res.apk";
private static final String FRAMEWORK_APK_PATH_RAVENWOOD = "ravenwood-data/framework-res.apk";
diff --git a/core/java/android/content/res/flags.aconfig b/core/java/android/content/res/flags.aconfig
index 0af2f2576137..e98fc0c9d02c 100644
--- a/core/java/android/content/res/flags.aconfig
+++ b/core/java/android/content/res/flags.aconfig
@@ -74,3 +74,12 @@ flag {
description: "Feature flag for passing a dimension to create an frro"
bug: "369672322"
}
+
+flag {
+ name: "rro_control_for_android_no_overlayable"
+ is_exported: true
+ namespace: "resource_manager"
+ description: "Allow enabling and disabling RROs targeting android package with no overlayable"
+ bug: "364035303"
+}
+
diff --git a/core/java/android/content/res/loader/ResourcesProvider.java b/core/java/android/content/res/loader/ResourcesProvider.java
index 830b7e0fa2d0..b097bc0dcd8c 100644
--- a/core/java/android/content/res/loader/ResourcesProvider.java
+++ b/core/java/android/content/res/loader/ResourcesProvider.java
@@ -90,6 +90,8 @@ public class ResourcesProvider implements AutoCloseable, Closeable {
throws IOException {
Objects.requireNonNull(overlayInfo);
Preconditions.checkArgument(overlayInfo.isFabricated(), "Not accepted overlay");
+ Preconditions.checkStringNotEmpty(
+ overlayInfo.getTargetOverlayableName(), "Without overlayable name");
final String overlayName =
OverlayManagerImpl.checkOverlayNameValid(overlayInfo.getOverlayName());
final String path =
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index 1137e1e89f67..16d82caa6c1a 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -775,6 +775,46 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
new Key<int[]>("android.colorCorrection.availableAberrationModes", int[].class);
/**
+ * <p>The range of supported color temperature values for
+ * {@link CaptureRequest#COLOR_CORRECTION_COLOR_TEMPERATURE android.colorCorrection.colorTemperature}.</p>
+ * <p>This key lists the valid range of color temperature values for
+ * {@link CaptureRequest#COLOR_CORRECTION_COLOR_TEMPERATURE android.colorCorrection.colorTemperature} supported by this camera device.</p>
+ * <p>This key will be null on devices that do not support CCT mode for
+ * {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode}.</p>
+ * <p><b>Range of valid values:</b><br></p>
+ * <p>The minimum supported range will be [2856K,6500K]. The maximum supported
+ * range will be [1000K,40000K].</p>
+ * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
+ *
+ * @see CaptureRequest#COLOR_CORRECTION_COLOR_TEMPERATURE
+ * @see CaptureRequest#COLOR_CORRECTION_MODE
+ */
+ @PublicKey
+ @NonNull
+ @FlaggedApi(Flags.FLAG_COLOR_TEMPERATURE)
+ public static final Key<android.util.Range<Integer>> COLOR_CORRECTION_COLOR_TEMPERATURE_RANGE =
+ new Key<android.util.Range<Integer>>("android.colorCorrection.colorTemperatureRange", new TypeReference<android.util.Range<Integer>>() {{ }});
+
+ /**
+ * <p>List of color correction modes for {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode} that are
+ * supported by this camera device.</p>
+ * <p>This key lists the valid modes for {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode}. If no
+ * color correction modes are available for a device, this key will be null.</p>
+ * <p>Camera devices that have a FULL hardware level will always include at least
+ * FAST, HIGH_QUALITY, and TRANSFORM_MATRIX modes.</p>
+ * <p><b>Range of valid values:</b><br>
+ * Any value listed in {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode}</p>
+ * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
+ *
+ * @see CaptureRequest#COLOR_CORRECTION_MODE
+ */
+ @PublicKey
+ @NonNull
+ @FlaggedApi(Flags.FLAG_COLOR_TEMPERATURE)
+ public static final Key<int[]> COLOR_CORRECTION_AVAILABLE_MODES =
+ new Key<int[]>("android.colorCorrection.availableModes", int[].class);
+
+ /**
* <p>List of auto-exposure antibanding modes for {@link CaptureRequest#CONTROL_AE_ANTIBANDING_MODE android.control.aeAntibandingMode} that are
* supported by this camera device.</p>
* <p>Not all of the auto-exposure anti-banding modes may be
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index acb48f328f1a..86bbd4a57a63 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -2169,6 +2169,22 @@ public abstract class CameraMetadata<TKey> {
*/
public static final int COLOR_CORRECTION_MODE_HIGH_QUALITY = 2;
+ /**
+ * <p>Use
+ * {@link CaptureRequest#COLOR_CORRECTION_COLOR_TEMPERATURE android.colorCorrection.colorTemperature} and
+ * {@link CaptureRequest#COLOR_CORRECTION_COLOR_TINT android.colorCorrection.colorTint} to adjust the white balance based
+ * on correlated color temperature.</p>
+ * <p>If AWB is enabled with <code>{@link CaptureRequest#CONTROL_AWB_MODE android.control.awbMode} != OFF</code>, then
+ * CCT is ignored.</p>
+ *
+ * @see CaptureRequest#COLOR_CORRECTION_COLOR_TEMPERATURE
+ * @see CaptureRequest#COLOR_CORRECTION_COLOR_TINT
+ * @see CaptureRequest#CONTROL_AWB_MODE
+ * @see CaptureRequest#COLOR_CORRECTION_MODE
+ */
+ @FlaggedApi(Flags.FLAG_COLOR_TEMPERATURE)
+ public static final int COLOR_CORRECTION_MODE_CCT = 3;
+
//
// Enumeration values for CaptureRequest#COLOR_CORRECTION_ABERRATION_MODE
//
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index a5c5a9952879..8142bbe9b838 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -1086,11 +1086,17 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>>
* <li>{@link #COLOR_CORRECTION_MODE_HIGH_QUALITY HIGH_QUALITY}</li>
* </ul>
*
+ * <p><b>Available values for this device:</b><br>
+ * Starting from API level 36, {@link CameraCharacteristics#COLOR_CORRECTION_AVAILABLE_MODES android.colorCorrection.availableModes}
+ * can be used to check the list of supported values. Prior to API level 36,
+ * TRANSFORM_MATRIX, HIGH_QUALITY, and FAST are guaranteed to be available
+ * as valid modes on devices that support this key.</p>
* <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
* <p><b>Full capability</b> -
* Present on all camera devices that report being {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_FULL HARDWARE_LEVEL_FULL} devices in the
* {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel} key</p>
*
+ * @see CameraCharacteristics#COLOR_CORRECTION_AVAILABLE_MODES
* @see CaptureRequest#COLOR_CORRECTION_GAINS
* @see CaptureRequest#COLOR_CORRECTION_TRANSFORM
* @see CaptureRequest#CONTROL_AWB_MODE
@@ -1195,6 +1201,60 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>>
new Key<Integer>("android.colorCorrection.aberrationMode", int.class);
/**
+ * <p>Specifies the color temperature for CCT mode in Kelvin
+ * to adjust the white balance of the image.</p>
+ * <p>Sets the color temperature in Kelvin units for when
+ * {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode} is CCT to adjust the
+ * white balance of the image.</p>
+ * <p>If CCT mode is enabled without a requested color temperature,
+ * a default value will be set by the camera device. The default value can be
+ * retrieved by checking the corresponding capture result. Color temperatures
+ * requested outside the advertised {@link CameraCharacteristics#COLOR_CORRECTION_COLOR_TEMPERATURE_RANGE android.colorCorrection.colorTemperatureRange}
+ * will be clamped.</p>
+ * <p><b>Units</b>: Kelvin</p>
+ * <p><b>Range of valid values:</b><br>
+ * {@link CameraCharacteristics#COLOR_CORRECTION_COLOR_TEMPERATURE_RANGE android.colorCorrection.colorTemperatureRange}</p>
+ * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
+ *
+ * @see CameraCharacteristics#COLOR_CORRECTION_COLOR_TEMPERATURE_RANGE
+ * @see CaptureRequest#COLOR_CORRECTION_MODE
+ */
+ @PublicKey
+ @NonNull
+ @FlaggedApi(Flags.FLAG_COLOR_TEMPERATURE)
+ public static final Key<Integer> COLOR_CORRECTION_COLOR_TEMPERATURE =
+ new Key<Integer>("android.colorCorrection.colorTemperature", int.class);
+
+ /**
+ * <p>Specifies the color tint for CCT mode to adjust the white
+ * balance of the image.</p>
+ * <p>Sets the color tint for when {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode}
+ * is CCT to adjust the white balance of the image.</p>
+ * <p>If CCT mode is enabled without a requested color tint,
+ * a default value will be set by the camera device. The default value can be
+ * retrieved by checking the corresponding capture result. Color tints requested
+ * outside the supported range will be clamped to the nearest limit (-50 or +50).</p>
+ * <p><b>Units</b>: D_uv defined as the distance from the Planckian locus on the CIE 1931 xy
+ * chromaticity diagram, with the range ±50 mapping to ±0.01 D_uv</p>
+ * <p><b>Range of valid values:</b><br>
+ * The supported range, -50 to +50, corresponds to a D_uv distance
+ * of ±0.01 below and above the Planckian locus. Some camera devices may have
+ * limitations to achieving the full ±0.01 D_uv range at some color temperatures
+ * (e.g., below 1500K). In these cases, the applied D_uv value may be clamped and
+ * the actual color tint will be reported in the {@link CaptureRequest#COLOR_CORRECTION_COLOR_TINT android.colorCorrection.colorTint}
+ * result.</p>
+ * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
+ *
+ * @see CaptureRequest#COLOR_CORRECTION_COLOR_TINT
+ * @see CaptureRequest#COLOR_CORRECTION_MODE
+ */
+ @PublicKey
+ @NonNull
+ @FlaggedApi(Flags.FLAG_COLOR_TEMPERATURE)
+ public static final Key<Integer> COLOR_CORRECTION_COLOR_TINT =
+ new Key<Integer>("android.colorCorrection.colorTint", int.class);
+
+ /**
* <p>The desired setting for the camera device's auto-exposure
* algorithm's antibanding compensation.</p>
* <p>Some kinds of lighting fixtures, such as some fluorescent
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index a6bdb3f1bb07..ae72ca40fc5a 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -487,11 +487,17 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> {
* <li>{@link #COLOR_CORRECTION_MODE_HIGH_QUALITY HIGH_QUALITY}</li>
* </ul>
*
+ * <p><b>Available values for this device:</b><br>
+ * Starting from API level 36, {@link CameraCharacteristics#COLOR_CORRECTION_AVAILABLE_MODES android.colorCorrection.availableModes}
+ * can be used to check the list of supported values. Prior to API level 36,
+ * TRANSFORM_MATRIX, HIGH_QUALITY, and FAST are guaranteed to be available
+ * as valid modes on devices that support this key.</p>
* <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
* <p><b>Full capability</b> -
* Present on all camera devices that report being {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_FULL HARDWARE_LEVEL_FULL} devices in the
* {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel} key</p>
*
+ * @see CameraCharacteristics#COLOR_CORRECTION_AVAILABLE_MODES
* @see CaptureRequest#COLOR_CORRECTION_GAINS
* @see CaptureRequest#COLOR_CORRECTION_TRANSFORM
* @see CaptureRequest#CONTROL_AWB_MODE
@@ -596,6 +602,60 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> {
new Key<Integer>("android.colorCorrection.aberrationMode", int.class);
/**
+ * <p>Specifies the color temperature for CCT mode in Kelvin
+ * to adjust the white balance of the image.</p>
+ * <p>Sets the color temperature in Kelvin units for when
+ * {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode} is CCT to adjust the
+ * white balance of the image.</p>
+ * <p>If CCT mode is enabled without a requested color temperature,
+ * a default value will be set by the camera device. The default value can be
+ * retrieved by checking the corresponding capture result. Color temperatures
+ * requested outside the advertised {@link CameraCharacteristics#COLOR_CORRECTION_COLOR_TEMPERATURE_RANGE android.colorCorrection.colorTemperatureRange}
+ * will be clamped.</p>
+ * <p><b>Units</b>: Kelvin</p>
+ * <p><b>Range of valid values:</b><br>
+ * {@link CameraCharacteristics#COLOR_CORRECTION_COLOR_TEMPERATURE_RANGE android.colorCorrection.colorTemperatureRange}</p>
+ * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
+ *
+ * @see CameraCharacteristics#COLOR_CORRECTION_COLOR_TEMPERATURE_RANGE
+ * @see CaptureRequest#COLOR_CORRECTION_MODE
+ */
+ @PublicKey
+ @NonNull
+ @FlaggedApi(Flags.FLAG_COLOR_TEMPERATURE)
+ public static final Key<Integer> COLOR_CORRECTION_COLOR_TEMPERATURE =
+ new Key<Integer>("android.colorCorrection.colorTemperature", int.class);
+
+ /**
+ * <p>Specifies the color tint for CCT mode to adjust the white
+ * balance of the image.</p>
+ * <p>Sets the color tint for when {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode}
+ * is CCT to adjust the white balance of the image.</p>
+ * <p>If CCT mode is enabled without a requested color tint,
+ * a default value will be set by the camera device. The default value can be
+ * retrieved by checking the corresponding capture result. Color tints requested
+ * outside the supported range will be clamped to the nearest limit (-50 or +50).</p>
+ * <p><b>Units</b>: D_uv defined as the distance from the Planckian locus on the CIE 1931 xy
+ * chromaticity diagram, with the range ±50 mapping to ±0.01 D_uv</p>
+ * <p><b>Range of valid values:</b><br>
+ * The supported range, -50 to +50, corresponds to a D_uv distance
+ * of ±0.01 below and above the Planckian locus. Some camera devices may have
+ * limitations to achieving the full ±0.01 D_uv range at some color temperatures
+ * (e.g., below 1500K). In these cases, the applied D_uv value may be clamped and
+ * the actual color tint will be reported in the {@link CaptureRequest#COLOR_CORRECTION_COLOR_TINT android.colorCorrection.colorTint}
+ * result.</p>
+ * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
+ *
+ * @see CaptureRequest#COLOR_CORRECTION_COLOR_TINT
+ * @see CaptureRequest#COLOR_CORRECTION_MODE
+ */
+ @PublicKey
+ @NonNull
+ @FlaggedApi(Flags.FLAG_COLOR_TEMPERATURE)
+ public static final Key<Integer> COLOR_CORRECTION_COLOR_TINT =
+ new Key<Integer>("android.colorCorrection.colorTint", int.class);
+
+ /**
* <p>The desired setting for the camera device's auto-exposure
* algorithm's antibanding compensation.</p>
* <p>Some kinds of lighting fixtures, such as some fluorescent
diff --git a/core/java/android/hardware/camera2/params/OutputConfiguration.java b/core/java/android/hardware/camera2/params/OutputConfiguration.java
index 22dbf5bdde37..d38be9b7b694 100644
--- a/core/java/android/hardware/camera2/params/OutputConfiguration.java
+++ b/core/java/android/hardware/camera2/params/OutputConfiguration.java
@@ -1457,7 +1457,7 @@ public final class OutputConfiguration implements Parcelable {
/**
* Set the mirroring mode for a surface belonging to this OutputConfiguration
*
- * <p>This function is identical to {@link #setMirroMode(int)} if {@code surface} is
+ * <p>This function is identical to {@link #setMirrorMode(int)} if {@code surface} is
* the only surface belonging to this OutputConfiguration.</p>
*
* <p>If this OutputConfiguration contains a deferred surface, the application can either
diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java
index b0ea92d140a5..a81bcbcce9c9 100644
--- a/core/java/android/hardware/display/DisplayManager.java
+++ b/core/java/android/hardware/display/DisplayManager.java
@@ -580,7 +580,7 @@ public final class DisplayManager {
EVENT_FLAG_DISPLAY_CONNECTION_CHANGED,
})
@Retention(RetentionPolicy.SOURCE)
- public @interface EventsMask {}
+ public @interface EventFlag {}
/**
* Event type for when a new display is added.
@@ -774,7 +774,7 @@ public final class DisplayManager {
* @param listener The listener to register.
* @param handler The handler on which the listener should be invoked, or null
* if the listener should be invoked on the calling thread's looper.
- * @param eventsMask A bitmask of the event types for which this listener is subscribed.
+ * @param eventFlagsMask A bitmask of the event types for which this listener is subscribed.
*
* @see #EVENT_FLAG_DISPLAY_ADDED
* @see #EVENT_FLAG_DISPLAY_CHANGED
@@ -786,8 +786,8 @@ public final class DisplayManager {
* @hide
*/
public void registerDisplayListener(@NonNull DisplayListener listener,
- @Nullable Handler handler, @EventsMask long eventsMask) {
- mGlobal.registerDisplayListener(listener, handler, eventsMask,
+ @Nullable Handler handler, @EventFlag long eventFlagsMask) {
+ mGlobal.registerDisplayListener(listener, handler, eventFlagsMask,
ActivityThread.currentPackageName());
}
diff --git a/core/java/android/hardware/display/DisplayManagerGlobal.java b/core/java/android/hardware/display/DisplayManagerGlobal.java
index 6affd123bfde..3c6841cd8aeb 100644
--- a/core/java/android/hardware/display/DisplayManagerGlobal.java
+++ b/core/java/android/hardware/display/DisplayManagerGlobal.java
@@ -17,7 +17,7 @@
package android.hardware.display;
-import static android.hardware.display.DisplayManager.EventsMask;
+import static android.hardware.display.DisplayManager.EventFlag;
import static android.view.Display.HdrCapabilities.HdrType;
import android.Manifest;
@@ -130,7 +130,7 @@ public final class DisplayManagerGlobal {
private final IDisplayManager mDm;
private DisplayManagerCallback mCallback;
- private @EventsMask long mRegisteredEventsMask = 0;
+ private @EventFlag long mRegisteredEventFlagsMask = 0;
private final CopyOnWriteArrayList<DisplayListenerDelegate> mDisplayListeners =
new CopyOnWriteArrayList<>();
@@ -346,10 +346,11 @@ public final class DisplayManagerGlobal {
* @param packageName of the calling package.
*/
public void registerDisplayListener(@NonNull DisplayListener listener,
- @Nullable Handler handler, @EventsMask long eventsMask, String packageName) {
+ @Nullable Handler handler, @EventFlag long eventFlagsMask,
+ String packageName) {
Looper looper = getLooperForHandler(handler);
Handler springBoard = new Handler(looper);
- registerDisplayListener(listener, new HandlerExecutor(springBoard), eventsMask,
+ registerDisplayListener(listener, new HandlerExecutor(springBoard), eventFlagsMask,
packageName);
}
@@ -358,32 +359,32 @@ public final class DisplayManagerGlobal {
*
* @param listener The listener that will be called when display changes occur.
* @param executor Executor for the thread that will be receiving the callbacks. Cannot be null.
- * @param eventsMask Mask of events to be listened to.
+ * @param eventFlagsMask Flag of events to be listened to.
* @param packageName of the calling package.
*/
public void registerDisplayListener(@NonNull DisplayListener listener,
- @NonNull Executor executor, @EventsMask long eventsMask, String packageName) {
+ @NonNull Executor executor, @EventFlag long eventFlagsMask, String packageName) {
if (listener == null) {
throw new IllegalArgumentException("listener must not be null");
}
- if (eventsMask == 0) {
+ if (eventFlagsMask == 0) {
throw new IllegalArgumentException("The set of events to listen to must not be empty.");
}
if (extraLogging()) {
Slog.i(TAG, "Registering Display Listener: "
- + Long.toBinaryString(eventsMask) + ", packageName: " + packageName);
+ + Long.toBinaryString(eventFlagsMask) + ", packageName: " + packageName);
}
synchronized (mLock) {
int index = findDisplayListenerLocked(listener);
if (index < 0) {
- mDisplayListeners.add(new DisplayListenerDelegate(listener, executor, eventsMask,
- packageName));
+ mDisplayListeners.add(new DisplayListenerDelegate(listener, executor,
+ eventFlagsMask, packageName));
registerCallbackIfNeededLocked();
} else {
- mDisplayListeners.get(index).setEventsMask(eventsMask);
+ mDisplayListeners.get(index).setEventFlagsMask(eventFlagsMask);
}
updateCallbackIfNeededLocked();
maybeLogAllDisplayListeners();
@@ -455,12 +456,12 @@ public final class DisplayManagerGlobal {
return -1;
}
- @EventsMask
- private int calculateEventsMaskLocked() {
+ @EventFlag
+ private int calculateEventFlagsMaskLocked() {
int mask = 0;
final int numListeners = mDisplayListeners.size();
for (int i = 0; i < numListeners; i++) {
- mask |= mDisplayListeners.get(i).mEventsMask;
+ mask |= mDisplayListeners.get(i).mEventFlagsMask;
}
if (mDispatchNativeCallbacks) {
mask |= DisplayManager.EVENT_FLAG_DISPLAY_ADDED
@@ -478,14 +479,14 @@ public final class DisplayManagerGlobal {
}
private void updateCallbackIfNeededLocked() {
- int mask = calculateEventsMaskLocked();
+ int mask = calculateEventFlagsMaskLocked();
if (DEBUG) {
- Log.d(TAG, "Mask for listener: " + mask);
+ Log.d(TAG, "Flag for listener: " + mask);
}
- if (mask != mRegisteredEventsMask) {
+ if (mask != mRegisteredEventFlagsMask) {
try {
mDm.registerCallbackWithEventMask(mCallback, mask);
- mRegisteredEventsMask = mask;
+ mRegisteredEventFlagsMask = mask;
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
@@ -1276,7 +1277,7 @@ public final class DisplayManagerGlobal {
private static final class DisplayListenerDelegate {
public final DisplayListener mListener;
- public volatile long mEventsMask;
+ public volatile long mEventFlagsMask;
private final DisplayInfo mDisplayInfo = new DisplayInfo();
private final Executor mExecutor;
@@ -1284,10 +1285,10 @@ public final class DisplayManagerGlobal {
private final String mPackageName;
DisplayListenerDelegate(DisplayListener listener, @NonNull Executor executor,
- @EventsMask long eventsMask, String packageName) {
+ @EventFlag long eventFlag, String packageName) {
mExecutor = executor;
mListener = listener;
- mEventsMask = eventsMask;
+ mEventFlagsMask = eventFlag;
mPackageName = packageName;
}
@@ -1309,16 +1310,16 @@ public final class DisplayManagerGlobal {
mGenerationId.incrementAndGet();
}
- void setEventsMask(@EventsMask long newEventsMask) {
- mEventsMask = newEventsMask;
+ void setEventFlagsMask(@EventFlag long newEventsFlag) {
+ mEventFlagsMask = newEventsFlag;
}
- private void handleDisplayEventInner(int displayId, @DisplayEvent int event,
+ private void handleDisplayEventInner(int displayId, @DisplayEvent int eventFlagsMask,
@Nullable DisplayInfo info, boolean forceUpdate) {
if (extraLogging()) {
- Slog.i(TAG, "DLD(" + eventToString(event)
+ Slog.i(TAG, "DLD(" + eventToString(eventFlagsMask)
+ ", display=" + displayId
- + ", mEventsMask=" + Long.toBinaryString(mEventsMask)
+ + ", mEventsFlagMask=" + Long.toBinaryString(mEventFlagsMask)
+ ", mPackageName=" + mPackageName
+ ", displayInfo=" + info
+ ", listener=" + mListener.getClass() + ")");
@@ -1326,18 +1327,18 @@ public final class DisplayManagerGlobal {
if (DEBUG) {
Trace.beginSection(
TextUtils.trimToSize(
- "DLD(" + eventToString(event)
+ "DLD(" + eventToString(eventFlagsMask)
+ ", display=" + displayId
+ ", listener=" + mListener.getClass() + ")", 127));
}
- switch (event) {
+ switch (eventFlagsMask) {
case EVENT_DISPLAY_ADDED:
- if ((mEventsMask & DisplayManager.EVENT_FLAG_DISPLAY_ADDED) != 0) {
+ if ((mEventFlagsMask & DisplayManager.EVENT_FLAG_DISPLAY_ADDED) != 0) {
mListener.onDisplayAdded(displayId);
}
break;
case EVENT_DISPLAY_CHANGED:
- if ((mEventsMask & DisplayManager.EVENT_FLAG_DISPLAY_CHANGED) != 0) {
+ if ((mEventFlagsMask & DisplayManager.EVENT_FLAG_DISPLAY_CHANGED) != 0) {
if (info != null && (forceUpdate || !info.equals(mDisplayInfo))) {
if (extraLogging()) {
Slog.i(TAG, "Sending onDisplayChanged: Display Changed. Info: "
@@ -1349,27 +1350,29 @@ public final class DisplayManagerGlobal {
}
break;
case EVENT_DISPLAY_BRIGHTNESS_CHANGED:
- if ((mEventsMask & DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS) != 0) {
+ if ((mEventFlagsMask & DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS) != 0) {
mListener.onDisplayChanged(displayId);
}
break;
case EVENT_DISPLAY_REMOVED:
- if ((mEventsMask & DisplayManager.EVENT_FLAG_DISPLAY_REMOVED) != 0) {
+ if ((mEventFlagsMask & DisplayManager.EVENT_FLAG_DISPLAY_REMOVED) != 0) {
mListener.onDisplayRemoved(displayId);
}
break;
case EVENT_DISPLAY_HDR_SDR_RATIO_CHANGED:
- if ((mEventsMask & DisplayManager.EVENT_FLAG_HDR_SDR_RATIO_CHANGED) != 0) {
+ if ((mEventFlagsMask & DisplayManager.EVENT_FLAG_HDR_SDR_RATIO_CHANGED) != 0) {
mListener.onDisplayChanged(displayId);
}
break;
case EVENT_DISPLAY_CONNECTED:
- if ((mEventsMask & DisplayManager.EVENT_FLAG_DISPLAY_CONNECTION_CHANGED) != 0) {
+ if ((mEventFlagsMask & DisplayManager.EVENT_FLAG_DISPLAY_CONNECTION_CHANGED)
+ != 0) {
mListener.onDisplayConnected(displayId);
}
break;
case EVENT_DISPLAY_DISCONNECTED:
- if ((mEventsMask & DisplayManager.EVENT_FLAG_DISPLAY_CONNECTION_CHANGED) != 0) {
+ if ((mEventFlagsMask & DisplayManager.EVENT_FLAG_DISPLAY_CONNECTION_CHANGED)
+ != 0) {
mListener.onDisplayDisconnected(displayId);
}
break;
@@ -1381,7 +1384,7 @@ public final class DisplayManagerGlobal {
@Override
public String toString() {
- return "mask: {" + mEventsMask + "}, for " + mListener.getClass();
+ return "mEventFlagsMask: {" + mEventFlagsMask + "}, for " + mListener.getClass();
}
}
diff --git a/core/java/android/hardware/display/VirtualDisplayConfig.java b/core/java/android/hardware/display/VirtualDisplayConfig.java
index b0994e6145ef..49944c76eb99 100644
--- a/core/java/android/hardware/display/VirtualDisplayConfig.java
+++ b/core/java/android/hardware/display/VirtualDisplayConfig.java
@@ -60,6 +60,7 @@ public final class VirtualDisplayConfig implements Parcelable {
private final float mRequestedRefreshRate;
private final boolean mIsHomeSupported;
private final DisplayCutout mDisplayCutout;
+ private final boolean mIgnoreActivitySizeRestrictions;
private VirtualDisplayConfig(
@NonNull String name,
@@ -74,7 +75,8 @@ public final class VirtualDisplayConfig implements Parcelable {
@NonNull ArraySet<String> displayCategories,
float requestedRefreshRate,
boolean isHomeSupported,
- @Nullable DisplayCutout displayCutout) {
+ @Nullable DisplayCutout displayCutout,
+ boolean ignoreActivitySizeRestrictions) {
mName = name;
mWidth = width;
mHeight = height;
@@ -88,6 +90,7 @@ public final class VirtualDisplayConfig implements Parcelable {
mRequestedRefreshRate = requestedRefreshRate;
mIsHomeSupported = isHomeSupported;
mDisplayCutout = displayCutout;
+ mIgnoreActivitySizeRestrictions = ignoreActivitySizeRestrictions;
}
/**
@@ -193,6 +196,20 @@ public final class VirtualDisplayConfig implements Parcelable {
}
/**
+ * Whether this virtual display ignores fixed orientation, aspect ratio and resizability
+ * of apps.
+ *
+ * @see Builder#setIgnoreActivitySizeRestrictions(boolean)
+ * @hide
+ */
+ @FlaggedApi(com.android.window.flags.Flags.FLAG_VDM_FORCE_APP_UNIVERSAL_RESIZABLE_API)
+ @SystemApi
+ public boolean isIgnoreActivitySizeRestrictions() {
+ return mIgnoreActivitySizeRestrictions
+ && com.android.window.flags.Flags.vdmForceAppUniversalResizableApi();
+ }
+
+ /**
* Returns the display categories.
*
* @see Builder#setDisplayCategories
@@ -227,6 +244,7 @@ public final class VirtualDisplayConfig implements Parcelable {
dest.writeFloat(mRequestedRefreshRate);
dest.writeBoolean(mIsHomeSupported);
DisplayCutout.ParcelableWrapper.writeCutoutToParcel(mDisplayCutout, dest, flags);
+ dest.writeBoolean(mIgnoreActivitySizeRestrictions);
}
@Override
@@ -253,6 +271,7 @@ public final class VirtualDisplayConfig implements Parcelable {
&& Objects.equals(mDisplayCategories, that.mDisplayCategories)
&& mRequestedRefreshRate == that.mRequestedRefreshRate
&& mIsHomeSupported == that.mIsHomeSupported
+ && mIgnoreActivitySizeRestrictions == that.mIgnoreActivitySizeRestrictions
&& Objects.equals(mDisplayCutout, that.mDisplayCutout);
}
@@ -261,7 +280,8 @@ public final class VirtualDisplayConfig implements Parcelable {
int hashCode = Objects.hash(
mName, mWidth, mHeight, mDensityDpi, mFlags, mSurface, mUniqueId,
mDisplayIdToMirror, mWindowManagerMirroringEnabled, mDisplayCategories,
- mRequestedRefreshRate, mIsHomeSupported, mDisplayCutout);
+ mRequestedRefreshRate, mIsHomeSupported, mDisplayCutout,
+ mIgnoreActivitySizeRestrictions);
return hashCode;
}
@@ -282,6 +302,7 @@ public final class VirtualDisplayConfig implements Parcelable {
+ " mRequestedRefreshRate=" + mRequestedRefreshRate
+ " mIsHomeSupported=" + mIsHomeSupported
+ " mDisplayCutout=" + mDisplayCutout
+ + " mIgnoreActivitySizeRestrictions=" + mIgnoreActivitySizeRestrictions
+ ")";
}
@@ -299,6 +320,7 @@ public final class VirtualDisplayConfig implements Parcelable {
mRequestedRefreshRate = in.readFloat();
mIsHomeSupported = in.readBoolean();
mDisplayCutout = DisplayCutout.ParcelableWrapper.readCutoutFromParcel(in);
+ mIgnoreActivitySizeRestrictions = in.readBoolean();
}
@NonNull
@@ -332,6 +354,7 @@ public final class VirtualDisplayConfig implements Parcelable {
private float mRequestedRefreshRate = 0.0f;
private boolean mIsHomeSupported = false;
private DisplayCutout mDisplayCutout = null;
+ private boolean mIgnoreActivitySizeRestrictions = false;
/**
* Creates a new Builder.
@@ -506,6 +529,24 @@ public final class VirtualDisplayConfig implements Parcelable {
}
/**
+ * Sets whether this display ignores fixed orientation, aspect ratio and resizability
+ * of apps.
+ *
+ * <p>Note: setting to {@code true} requires the display to have
+ * {@link DisplayManager#VIRTUAL_DISPLAY_FLAG_TRUSTED}. If this is false, this property
+ * is ignored.</p>
+ *
+ * @hide
+ */
+ @FlaggedApi(com.android.window.flags.Flags.FLAG_VDM_FORCE_APP_UNIVERSAL_RESIZABLE_API)
+ @SystemApi
+ @NonNull
+ public Builder setIgnoreActivitySizeRestrictions(boolean enabled) {
+ mIgnoreActivitySizeRestrictions = enabled;
+ return this;
+ }
+
+ /**
* Builds the {@link VirtualDisplayConfig} instance.
*/
@NonNull
@@ -523,7 +564,8 @@ public final class VirtualDisplayConfig implements Parcelable {
mDisplayCategories,
mRequestedRefreshRate,
mIsHomeSupported,
- mDisplayCutout);
+ mDisplayCutout,
+ mIgnoreActivitySizeRestrictions);
}
}
}
diff --git a/core/java/android/hardware/input/KeyGestureEvent.java b/core/java/android/hardware/input/KeyGestureEvent.java
index 0f290d90770f..9d42b67bf5a8 100644
--- a/core/java/android/hardware/input/KeyGestureEvent.java
+++ b/core/java/android/hardware/input/KeyGestureEvent.java
@@ -113,6 +113,10 @@ public final class KeyGestureEvent {
public static final int KEY_GESTURE_TYPE_TOGGLE_BOUNCE_KEYS = 65;
public static final int KEY_GESTURE_TYPE_TOGGLE_SLOW_KEYS = 66;
public static final int KEY_GESTURE_TYPE_TOGGLE_MOUSE_KEYS = 67;
+ public static final int KEY_GESTURE_TYPE_SNAP_LEFT_FREEFORM_WINDOW = 68;
+ public static final int KEY_GESTURE_TYPE_SNAP_RIGHT_FREEFORM_WINDOW = 69;
+ public static final int KEY_GESTURE_TYPE_MAXIMIZE_FREEFORM_WINDOW = 70;
+ public static final int KEY_GESTURE_TYPE_RESTORE_FREEFORM_WINDOW_SIZE = 71;
public static final int FLAG_CANCELLED = 1;
@@ -194,7 +198,11 @@ public final class KeyGestureEvent {
KEY_GESTURE_TYPE_TOGGLE_STICKY_KEYS,
KEY_GESTURE_TYPE_TOGGLE_BOUNCE_KEYS,
KEY_GESTURE_TYPE_TOGGLE_SLOW_KEYS,
- KEY_GESTURE_TYPE_TOGGLE_MOUSE_KEYS
+ KEY_GESTURE_TYPE_TOGGLE_MOUSE_KEYS,
+ KEY_GESTURE_TYPE_SNAP_LEFT_FREEFORM_WINDOW,
+ KEY_GESTURE_TYPE_SNAP_RIGHT_FREEFORM_WINDOW,
+ KEY_GESTURE_TYPE_MAXIMIZE_FREEFORM_WINDOW,
+ KEY_GESTURE_TYPE_RESTORE_FREEFORM_WINDOW_SIZE,
})
@Retention(RetentionPolicy.SOURCE)
public @interface KeyGestureType {
@@ -541,6 +549,14 @@ public final class KeyGestureEvent {
return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__DESKTOP_MODE;
case KEY_GESTURE_TYPE_MULTI_WINDOW_NAVIGATION:
return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__MULTI_WINDOW_NAVIGATION;
+ case KEY_GESTURE_TYPE_SNAP_LEFT_FREEFORM_WINDOW:
+ return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__SNAP_LEFT_FREEFORM_WINDOW;
+ case KEY_GESTURE_TYPE_SNAP_RIGHT_FREEFORM_WINDOW:
+ return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__SNAP_RIGHT_FREEFORM_WINDOW;
+ case KEY_GESTURE_TYPE_MAXIMIZE_FREEFORM_WINDOW:
+ return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__MAXIMIZE_FREEFORM_WINDOW;
+ case KEY_GESTURE_TYPE_RESTORE_FREEFORM_WINDOW_SIZE:
+ return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__RESTORE_FREEFORM_WINDOW_SIZE;
default:
return LOG_EVENT_UNSPECIFIED;
}
@@ -749,6 +765,14 @@ public final class KeyGestureEvent {
return "KEY_GESTURE_TYPE_TOGGLE_SLOW_KEYS";
case KEY_GESTURE_TYPE_TOGGLE_MOUSE_KEYS:
return "KEY_GESTURE_TYPE_TOGGLE_MOUSE_KEYS";
+ case KEY_GESTURE_TYPE_SNAP_LEFT_FREEFORM_WINDOW:
+ return "KEY_GESTURE_TYPE_SNAP_LEFT_FREEFORM_WINDOW";
+ case KEY_GESTURE_TYPE_SNAP_RIGHT_FREEFORM_WINDOW:
+ return "KEY_GESTURE_TYPE_SNAP_RIGHT_FREEFORM_WINDOW";
+ case KEY_GESTURE_TYPE_MAXIMIZE_FREEFORM_WINDOW:
+ return "KEY_GESTURE_TYPE_SNAP_RIGHT_FREEFORM_WINDOW";
+ case KEY_GESTURE_TYPE_RESTORE_FREEFORM_WINDOW_SIZE:
+ return "KEY_GESTURE_TYPE_RESTORE_FREEFORM_WINDOW_SIZE";
default:
return Integer.toHexString(value);
}
diff --git a/core/java/android/os/CombinedMessageQueue/MessageQueue.java b/core/java/android/os/CombinedMessageQueue/MessageQueue.java
index 3e5ac6ff5a4a..9806ab25745c 100644
--- a/core/java/android/os/CombinedMessageQueue/MessageQueue.java
+++ b/core/java/android/os/CombinedMessageQueue/MessageQueue.java
@@ -76,19 +76,14 @@ public final class MessageQueue {
private final ArrayList<IdleHandler> mIdleHandlers = new ArrayList<IdleHandler>();
private SparseArray<FileDescriptorRecord> mFileDescriptorRecords;
private IdleHandler[] mPendingIdleHandlers;
- private boolean mLegacyQuitting;
+ private boolean mQuitting;
// Indicates whether next() is blocked waiting in pollOnce() with a non-zero timeout.
- private boolean mLegacyBlocked;
+ private boolean mBlocked;
// Tracks the number of async message. We use this in enqueueMessage() to avoid searching the
// queue for async messages when inserting a message at the tail.
- private int mLegacyAsyncMessageCount;
-
- // The next barrier token.
- // Barriers are indicated by messages with a null target whose arg1 field carries the token.
- @UnsupportedAppUsage
- private int mLegacyNextBarrierToken;
+ private int mAsyncMessageCount;
/*
* Select between two implementations of message queue. The legacy implementation is used
@@ -139,7 +134,7 @@ public final class MessageQueue {
}
}
- private class MatchDeliverableMessages extends MessageCompare {
+ private static final class MatchDeliverableMessages extends MessageCompare {
@Override
public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
long when) {
@@ -266,8 +261,8 @@ public final class MessageQueue {
private boolean isPollingLocked() {
// If the loop is quitting then it must not be idling.
- // We can assume mPtr != 0 when mLegacyQuitting is false.
- return !mLegacyQuitting && nativeIsPolling(mPtr);
+ // We can assume mPtr != 0 when mQuitting is false.
+ return !mQuitting && nativeIsPolling(mPtr);
}
/**
@@ -748,7 +743,7 @@ public final class MessageQueue {
nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE);
} else {
// Got a message.
- mLegacyBlocked = false;
+ mBlocked = false;
if (prevMsg != null) {
prevMsg.next = msg.next;
if (prevMsg.next == null) {
@@ -764,7 +759,7 @@ public final class MessageQueue {
if (DEBUG) Log.v(TAG_L, "Returning message: " + msg);
msg.markInUse();
if (msg.isAsynchronous()) {
- mLegacyAsyncMessageCount--;
+ mAsyncMessageCount--;
}
if (TRACE) {
Trace.setCounter("MQ.Delivered", mMessagesDelivered.incrementAndGet());
@@ -777,7 +772,7 @@ public final class MessageQueue {
}
// Process the quit message now that all pending messages have been handled.
- if (mLegacyQuitting) {
+ if (mQuitting) {
dispose();
return null;
}
@@ -791,7 +786,7 @@ public final class MessageQueue {
}
if (pendingIdleHandlerCount <= 0) {
// No idle handlers to run. Loop and wait some more.
- mLegacyBlocked = true;
+ mBlocked = true;
continue;
}
@@ -850,10 +845,10 @@ public final class MessageQueue {
}
} else {
synchronized (this) {
- if (mLegacyQuitting) {
+ if (mQuitting) {
return;
}
- mLegacyQuitting = true;
+ mQuitting = true;
if (safe) {
removeAllFutureMessagesLocked();
@@ -861,7 +856,7 @@ public final class MessageQueue {
removeAllMessagesLocked();
}
- // We can assume mPtr != 0 because mLegacyQuitting was previously false.
+ // We can assume mPtr != 0 because mQuitting was previously false.
nativeWake(mPtr);
}
}
@@ -900,7 +895,12 @@ public final class MessageQueue {
// Enqueue a new sync barrier token.
// We don't need to wake the queue because the purpose of a barrier is to stall it.
if (sForceConcurrent) {
- final int token = mNextBarrierToken.getAndIncrement();
+ final int token = mNextBarrierTokenAtomic.getAndIncrement();
+
+ // b/376573804: apps and tests may expect to be able to use reflection
+ // to read this value. Make some effort to support this legacy use case.
+ mNextBarrierToken = token + 1;
+
final Message msg = Message.obtain();
msg.markInUse();
@@ -915,7 +915,7 @@ public final class MessageQueue {
}
synchronized (this) {
- final int token = mLegacyNextBarrierToken++;
+ final int token = mNextBarrierToken++;
final Message msg = Message.obtain();
msg.markInUse();
msg.when = when;
@@ -954,7 +954,7 @@ public final class MessageQueue {
}
}
- private class MatchBarrierToken extends MessageCompare {
+ private static final class MatchBarrierToken extends MessageCompare {
int mBarrierToken;
MatchBarrierToken(int token) {
@@ -1042,8 +1042,8 @@ public final class MessageQueue {
p.recycleUnchecked();
// If the loop is quitting then it is already awake.
- // We can assume mPtr != 0 when mLegacyQuitting is false.
- if (needWake && !mLegacyQuitting) {
+ // We can assume mPtr != 0 when mQuitting is false.
+ if (needWake && !mQuitting) {
nativeWake(mPtr);
}
}
@@ -1067,7 +1067,7 @@ public final class MessageQueue {
throw new IllegalStateException(msg + " This message is already in use.");
}
- if (mLegacyQuitting) {
+ if (mQuitting) {
IllegalStateException e = new IllegalStateException(
msg.target + " sending message to a Handler on a dead thread");
Log.w(TAG_L, e.getMessage(), e);
@@ -1083,7 +1083,7 @@ public final class MessageQueue {
// New head, wake up the event queue if blocked.
msg.next = p;
mMessages = msg;
- needWake = mLegacyBlocked;
+ needWake = mBlocked;
if (p == null) {
mLast = mMessages;
}
@@ -1091,14 +1091,14 @@ public final class MessageQueue {
// Message is to be inserted at tail or middle of queue. Usually we don't have to
// wake up the event queue unless there is a barrier at the head of the queue and
// the message is the earliest asynchronous message in the queue.
- needWake = mLegacyBlocked && p.target == null && msg.isAsynchronous();
+ needWake = mBlocked && p.target == null && msg.isAsynchronous();
// For readability, we split this portion of the function into two blocks based on
// whether tail tracking is enabled. This has a minor implication for the case
// where tail tracking is disabled. See the comment below.
if (Flags.messageQueueTailTracking()) {
if (when >= mLast.when) {
- needWake = needWake && mLegacyAsyncMessageCount == 0;
+ needWake = needWake && mAsyncMessageCount == 0;
msg.next = null;
mLast.next = msg;
mLast = msg;
@@ -1156,10 +1156,10 @@ public final class MessageQueue {
}
if (msg.isAsynchronous()) {
- mLegacyAsyncMessageCount++;
+ mAsyncMessageCount++;
}
- // We can assume mPtr != 0 because mLegacyQuitting is false.
+ // We can assume mPtr != 0 because mQuitting is false.
if (needWake) {
nativeWake(mPtr);
}
@@ -1167,7 +1167,7 @@ public final class MessageQueue {
return true;
}
- private static class MatchHandlerWhatAndObject extends MessageCompare {
+ private static final class MatchHandlerWhatAndObject extends MessageCompare {
@Override
public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
long when) {
@@ -1199,7 +1199,7 @@ public final class MessageQueue {
}
}
- private static class MatchHandlerWhatAndObjectEquals extends MessageCompare {
+ private static final class MatchHandlerWhatAndObjectEquals extends MessageCompare {
@Override
public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
long when) {
@@ -1232,7 +1232,7 @@ public final class MessageQueue {
}
}
- private static class MatchHandlerRunnableAndObject extends MessageCompare {
+ private static final class MatchHandlerRunnableAndObject extends MessageCompare {
@Override
public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
long when) {
@@ -1266,7 +1266,7 @@ public final class MessageQueue {
}
}
- private static class MatchHandler extends MessageCompare {
+ private static final class MatchHandler extends MessageCompare {
@Override
public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
long when) {
@@ -1313,7 +1313,7 @@ public final class MessageQueue {
Message n = p.next;
mMessages = n;
if (p.isAsynchronous()) {
- mLegacyAsyncMessageCount--;
+ mAsyncMessageCount--;
}
p.recycleUnchecked();
p = n;
@@ -1331,7 +1331,7 @@ public final class MessageQueue {
&& (object == null || n.obj == object)) {
Message nn = n.next;
if (n.isAsynchronous()) {
- mLegacyAsyncMessageCount--;
+ mAsyncMessageCount--;
}
n.recycleUnchecked();
p.next = nn;
@@ -1365,7 +1365,7 @@ public final class MessageQueue {
Message n = p.next;
mMessages = n;
if (p.isAsynchronous()) {
- mLegacyAsyncMessageCount--;
+ mAsyncMessageCount--;
}
p.recycleUnchecked();
p = n;
@@ -1383,7 +1383,7 @@ public final class MessageQueue {
&& (object == null || object.equals(n.obj))) {
Message nn = n.next;
if (n.isAsynchronous()) {
- mLegacyAsyncMessageCount--;
+ mAsyncMessageCount--;
}
n.recycleUnchecked();
p.next = nn;
@@ -1416,7 +1416,7 @@ public final class MessageQueue {
Message n = p.next;
mMessages = n;
if (p.isAsynchronous()) {
- mLegacyAsyncMessageCount--;
+ mAsyncMessageCount--;
}
p.recycleUnchecked();
p = n;
@@ -1434,7 +1434,7 @@ public final class MessageQueue {
&& (object == null || n.obj == object)) {
Message nn = n.next;
if (n.isAsynchronous()) {
- mLegacyAsyncMessageCount--;
+ mAsyncMessageCount--;
}
n.recycleUnchecked();
p.next = nn;
@@ -1449,7 +1449,7 @@ public final class MessageQueue {
}
}
- private static class MatchHandlerRunnableAndObjectEquals extends MessageCompare {
+ private static final class MatchHandlerRunnableAndObjectEquals extends MessageCompare {
@Override
public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
long when) {
@@ -1479,7 +1479,7 @@ public final class MessageQueue {
Message n = p.next;
mMessages = n;
if (p.isAsynchronous()) {
- mLegacyAsyncMessageCount--;
+ mAsyncMessageCount--;
}
p.recycleUnchecked();
p = n;
@@ -1497,7 +1497,7 @@ public final class MessageQueue {
&& (object == null || object.equals(n.obj))) {
Message nn = n.next;
if (n.isAsynchronous()) {
- mLegacyAsyncMessageCount--;
+ mAsyncMessageCount--;
}
n.recycleUnchecked();
p.next = nn;
@@ -1512,7 +1512,7 @@ public final class MessageQueue {
}
}
- private static class MatchHandlerAndObject extends MessageCompare {
+ private static final class MatchHandlerAndObject extends MessageCompare {
@Override
public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
long when) {
@@ -1541,7 +1541,7 @@ public final class MessageQueue {
Message n = p.next;
mMessages = n;
if (p.isAsynchronous()) {
- mLegacyAsyncMessageCount--;
+ mAsyncMessageCount--;
}
p.recycleUnchecked();
p = n;
@@ -1558,7 +1558,7 @@ public final class MessageQueue {
if (n.target == h && (object == null || n.obj == object)) {
Message nn = n.next;
if (n.isAsynchronous()) {
- mLegacyAsyncMessageCount--;
+ mAsyncMessageCount--;
}
n.recycleUnchecked();
p.next = nn;
@@ -1573,7 +1573,7 @@ public final class MessageQueue {
}
}
- private static class MatchHandlerAndObjectEquals extends MessageCompare {
+ private static final class MatchHandlerAndObjectEquals extends MessageCompare {
@Override
public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
long when) {
@@ -1603,7 +1603,7 @@ public final class MessageQueue {
Message n = p.next;
mMessages = n;
if (p.isAsynchronous()) {
- mLegacyAsyncMessageCount--;
+ mAsyncMessageCount--;
}
p.recycleUnchecked();
p = n;
@@ -1620,7 +1620,7 @@ public final class MessageQueue {
if (n.target == h && (object == null || object.equals(n.obj))) {
Message nn = n.next;
if (n.isAsynchronous()) {
- mLegacyAsyncMessageCount--;
+ mAsyncMessageCount--;
}
n.recycleUnchecked();
p.next = nn;
@@ -1644,7 +1644,7 @@ public final class MessageQueue {
}
mMessages = null;
mLast = null;
- mLegacyAsyncMessageCount = 0;
+ mAsyncMessageCount = 0;
}
private void removeAllFutureMessagesLocked() {
@@ -1672,7 +1672,7 @@ public final class MessageQueue {
p = n;
n = p.next;
if (p.isAsynchronous()) {
- mLegacyAsyncMessageCount--;
+ mAsyncMessageCount--;
}
p.recycleUnchecked();
} while (n != null);
@@ -1680,7 +1680,7 @@ public final class MessageQueue {
}
}
- private static class MatchAllMessages extends MessageCompare {
+ private static final class MatchAllMessages extends MessageCompare {
@Override
public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
long when) {
@@ -1692,7 +1692,7 @@ public final class MessageQueue {
findOrRemoveMessages(null, -1, null, null, 0, mMatchAllMessages, true);
}
- private static class MatchAllFutureMessages extends MessageCompare {
+ private static final class MatchAllFutureMessages extends MessageCompare {
@Override
public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
long when) {
@@ -1780,7 +1780,7 @@ public final class MessageQueue {
n++;
}
pw.println(prefix + "(Total messages: " + n + ", polling=" + isPollingLocked()
- + ", quitting=" + mLegacyQuitting + ")");
+ + ", quitting=" + mQuitting + ")");
}
}
@@ -1824,7 +1824,7 @@ public final class MessageQueue {
msg.dumpDebug(proto, MessageQueueProto.MESSAGES);
}
proto.write(MessageQueueProto.IS_POLLING_LOCKED, isPollingLocked());
- proto.write(MessageQueueProto.IS_QUITTING, mLegacyQuitting);
+ proto.write(MessageQueueProto.IS_QUITTING, mQuitting);
}
proto.end(messageQueueToken);
}
@@ -2292,7 +2292,11 @@ public final class MessageQueue {
// The next barrier token.
// Barriers are indicated by messages with a null target whose arg1 field carries the token.
- private final AtomicInteger mNextBarrierToken = new AtomicInteger(1);
+ private final AtomicInteger mNextBarrierTokenAtomic = new AtomicInteger(1);
+
+ // Must retain this for compatibility reasons.
+ @UnsupportedAppUsage
+ private int mNextBarrierToken;
/* Protects mNextIsDrainingStack */
private final ReentrantLock mDrainingLock = new ReentrantLock();
diff --git a/core/java/android/os/ConcurrentMessageQueue/MessageQueue.java b/core/java/android/os/ConcurrentMessageQueue/MessageQueue.java
index 0efa02f24af5..9db88d17614b 100644
--- a/core/java/android/os/ConcurrentMessageQueue/MessageQueue.java
+++ b/core/java/android/os/ConcurrentMessageQueue/MessageQueue.java
@@ -382,7 +382,7 @@ public final class MessageQueue {
}
}
- private class MatchDeliverableMessages extends MessageCompare {
+ private static final class MatchDeliverableMessages extends MessageCompare {
@Override
public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
long when) {
@@ -984,7 +984,7 @@ public final class MessageQueue {
return token;
}
- private class MatchBarrierToken extends MessageCompare {
+ private static final class MatchBarrierToken extends MessageCompare {
int mBarrierToken;
MatchBarrierToken(int token) {
@@ -1165,7 +1165,7 @@ public final class MessageQueue {
return foundInStack || foundInQueue;
}
- private static class MatchHandlerWhatAndObject extends MessageCompare {
+ private static final class MatchHandlerWhatAndObject extends MessageCompare {
@Override
public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
long when) {
@@ -1185,7 +1185,7 @@ public final class MessageQueue {
return findOrRemoveMessages(h, what, object, null, 0, mMatchHandlerWhatAndObject, false);
}
- private static class MatchHandlerWhatAndObjectEquals extends MessageCompare {
+ private static final class MatchHandlerWhatAndObjectEquals extends MessageCompare {
@Override
public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
long when) {
@@ -1206,7 +1206,7 @@ public final class MessageQueue {
false);
}
- private static class MatchHandlerRunnableAndObject extends MessageCompare {
+ private static final class MatchHandlerRunnableAndObject extends MessageCompare {
@Override
public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
long when) {
@@ -1227,7 +1227,7 @@ public final class MessageQueue {
return findOrRemoveMessages(h, -1, object, r, 0, mMatchHandlerRunnableAndObject, false);
}
- private static class MatchHandler extends MessageCompare {
+ private static final class MatchHandler extends MessageCompare {
@Override
public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
long when) {
@@ -1266,7 +1266,7 @@ public final class MessageQueue {
findOrRemoveMessages(h, -1, object, r, 0, mMatchHandlerRunnableAndObject, true);
}
- private static class MatchHandlerRunnableAndObjectEquals extends MessageCompare {
+ private static final class MatchHandlerRunnableAndObjectEquals extends MessageCompare {
@Override
public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
long when) {
@@ -1285,7 +1285,7 @@ public final class MessageQueue {
findOrRemoveMessages(h, -1, object, r, 0, mMatchHandlerRunnableAndObjectEquals, true);
}
- private static class MatchHandlerAndObject extends MessageCompare {
+ private static final class MatchHandlerAndObject extends MessageCompare {
@Override
public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
long when) {
@@ -1303,7 +1303,7 @@ public final class MessageQueue {
findOrRemoveMessages(h, -1, object, null, 0, mMatchHandlerAndObject, true);
}
- private static class MatchHandlerAndObjectEquals extends MessageCompare {
+ private static final class MatchHandlerAndObjectEquals extends MessageCompare {
@Override
public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
long when) {
@@ -1322,7 +1322,7 @@ public final class MessageQueue {
findOrRemoveMessages(h, -1, object, null, 0, mMatchHandlerAndObjectEquals, true);
}
- private static class MatchAllMessages extends MessageCompare {
+ private static final class MatchAllMessages extends MessageCompare {
@Override
public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
long when) {
@@ -1334,7 +1334,7 @@ public final class MessageQueue {
findOrRemoveMessages(null, -1, null, null, 0, mMatchAllMessages, true);
}
- private static class MatchAllFutureMessages extends MessageCompare {
+ private static final class MatchAllFutureMessages extends MessageCompare {
@Override
public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
long when) {
diff --git a/core/java/android/permission/flags.aconfig b/core/java/android/permission/flags.aconfig
index 7944be140960..6a4932211f27 100644
--- a/core/java/android/permission/flags.aconfig
+++ b/core/java/android/permission/flags.aconfig
@@ -314,3 +314,21 @@ flag {
description: "Enable AppOp mode caching in AppOpsManager"
bug: "366013082"
}
+
+flag {
+ name: "permission_tree_apis_deprecated"
+ is_fixed_read_only: true
+ is_exported: true
+ namespace: "permissions"
+ description: "This flag is used to deprecate permission tree related APIs"
+ bug: "376535612"
+}
+
+flag {
+ name: "enable_otp_in_text_classifiers"
+ is_fixed_read_only: true
+ is_exported: true
+ namespace: "permissions"
+ description: "Enables ExtServices to leverage TextClassifier for OTP detection"
+ bug: "351976749"
+}
diff --git a/core/java/android/security/advancedprotection/AdvancedProtectionFeature.aidl b/core/java/android/security/advancedprotection/AdvancedProtectionFeature.aidl
new file mode 100644
index 000000000000..3ecef0248e1f
--- /dev/null
+++ b/core/java/android/security/advancedprotection/AdvancedProtectionFeature.aidl
@@ -0,0 +1,23 @@
+/*
+ * 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.security.advancedprotection;
+
+/**
+ * Represents an advanced protection feature providing protections
+ * @hide
+ */
+parcelable AdvancedProtectionFeature; \ No newline at end of file
diff --git a/core/java/android/security/advancedprotection/AdvancedProtectionFeature.java b/core/java/android/security/advancedprotection/AdvancedProtectionFeature.java
new file mode 100644
index 000000000000..a086bf7f8b08
--- /dev/null
+++ b/core/java/android/security/advancedprotection/AdvancedProtectionFeature.java
@@ -0,0 +1,77 @@
+/*
+ * 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.security.advancedprotection;
+
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.security.Flags;
+
+/**
+ * An advanced protection feature providing protections.
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_AAPM_API)
+@SystemApi
+public final class AdvancedProtectionFeature implements Parcelable {
+ private final String mId;
+
+ /**
+ * Create an object identifying an Advanced Protection feature for AdvancedProtectionManager
+ * @param id A unique ID to identify this feature. It is used by Settings screens to display
+ * information about this feature.
+ */
+ public AdvancedProtectionFeature(@NonNull String id) {
+ mId = id;
+ }
+
+ private AdvancedProtectionFeature(Parcel in) {
+ mId = in.readString8();
+ }
+
+ /**
+ * @return the unique ID representing this feature
+ */
+ @NonNull
+ public String getId() {
+ return mId;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeString8(mId);
+ }
+
+ @NonNull
+ public static final Parcelable.Creator<AdvancedProtectionFeature> CREATOR =
+ new Parcelable.Creator<>() {
+ public AdvancedProtectionFeature createFromParcel(Parcel in) {
+ return new AdvancedProtectionFeature(in);
+ }
+
+ public AdvancedProtectionFeature[] newArray(int size) {
+ return new AdvancedProtectionFeature[size];
+ }
+ };
+}
diff --git a/core/java/android/security/advancedprotection/AdvancedProtectionManager.java b/core/java/android/security/advancedprotection/AdvancedProtectionManager.java
index 43b6ebe2a735..6f3e3d8f0d3b 100644
--- a/core/java/android/security/advancedprotection/AdvancedProtectionManager.java
+++ b/core/java/android/security/advancedprotection/AdvancedProtectionManager.java
@@ -29,6 +29,7 @@ import android.os.RemoteException;
import android.security.Flags;
import android.util.Log;
+import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;
@@ -41,7 +42,7 @@ import java.util.concurrent.Executor;
*/
@FlaggedApi(Flags.FLAG_AAPM_API)
@SystemService(Context.ADVANCED_PROTECTION_SERVICE)
-public class AdvancedProtectionManager {
+public final class AdvancedProtectionManager {
private static final String TAG = "AdvancedProtectionMgr";
private final ConcurrentHashMap<Callback, IAdvancedProtectionCallback>
@@ -147,6 +148,22 @@ public class AdvancedProtectionManager {
}
/**
+ * Returns the list of advanced protection features which are available on this device.
+ *
+ * @hide
+ */
+ @SystemApi
+ @NonNull
+ @RequiresPermission(Manifest.permission.SET_ADVANCED_PROTECTION_MODE)
+ public List<AdvancedProtectionFeature> getAdvancedProtectionFeatures() {
+ try {
+ return mService.getAdvancedProtectionFeatures();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* A callback class for monitoring changes to Advanced Protection state
*
* <p>To register a callback, implement this interface, and register it with
diff --git a/core/java/android/security/advancedprotection/IAdvancedProtectionService.aidl b/core/java/android/security/advancedprotection/IAdvancedProtectionService.aidl
index ef0abf4f23a0..68307632027a 100644
--- a/core/java/android/security/advancedprotection/IAdvancedProtectionService.aidl
+++ b/core/java/android/security/advancedprotection/IAdvancedProtectionService.aidl
@@ -16,6 +16,7 @@
package android.security.advancedprotection;
+import android.security.advancedprotection.AdvancedProtectionFeature;
import android.security.advancedprotection.IAdvancedProtectionCallback;
/**
@@ -32,4 +33,6 @@ interface IAdvancedProtectionService {
void unregisterAdvancedProtectionCallback(IAdvancedProtectionCallback callback);
@EnforcePermission("SET_ADVANCED_PROTECTION_MODE")
void setAdvancedProtectionEnabled(boolean enabled);
+ @EnforcePermission("SET_ADVANCED_PROTECTION_MODE")
+ List<AdvancedProtectionFeature> getAdvancedProtectionFeatures();
} \ No newline at end of file
diff --git a/core/java/android/security/responsible_apis_flags.aconfig b/core/java/android/security/responsible_apis_flags.aconfig
index dec28c34ae5b..5995760a41ec 100644
--- a/core/java/android/security/responsible_apis_flags.aconfig
+++ b/core/java/android/security/responsible_apis_flags.aconfig
@@ -87,6 +87,14 @@ flag {
}
flag {
+ name: "prevent_intent_redirect_show_toast"
+ namespace: "responsible_apis"
+ description: "Prevent intent redirect attacks by showing a toast when activity start is blocked"
+ bug: "361143368"
+ is_fixed_read_only: true
+}
+
+flag {
name: "enable_intent_matching_flags"
is_exported: true
namespace: "permissions"
diff --git a/core/java/android/service/contextualsearch/OWNERS b/core/java/android/service/contextualsearch/OWNERS
index b7238721bc60..c435bd87be21 100644
--- a/core/java/android/service/contextualsearch/OWNERS
+++ b/core/java/android/service/contextualsearch/OWNERS
@@ -1,2 +1,3 @@
srazdan@google.com
-hackz@google.com
+hyunyoungs@google.com
+awickham@google.com
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index bd9ab86fa8d1..a8ab2115d97f 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -17,6 +17,7 @@
package android.service.notification;
import android.annotation.CurrentTimeMillisLong;
+import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -882,6 +883,35 @@ public abstract class NotificationListenerService extends Service {
}
}
+ /**
+ * Creates a conversation notification channel for a given package for a given user.
+ *
+ * <p>This method will throw a security exception if you don't have access to notifications
+ * for the given user.</p>
+ * <p>The caller must have {@link CompanionDeviceManager#getAssociations() an associated
+ * device} or be the notification assistant in order to use this method.
+ *
+ * @param pkg The package the channel belongs to.
+ * @param user The user the channel belongs to.
+ * @param parentChannelId The parent channel id of the conversation channel belongs to.
+ * @param conversationId The conversation id of the conversation channel.
+ *
+ * @return The created conversation channel.
+ */
+ @FlaggedApi(Flags.FLAG_NOTIFICATION_CONVERSATION_CHANNEL_MANAGEMENT)
+ public final @Nullable NotificationChannel createConversationNotificationChannelForPackage(
+ @NonNull String pkg, @NonNull UserHandle user, @NonNull String parentChannelId,
+ @NonNull String conversationId) {
+ if (!isBound()) return null;
+ try {
+ return getNotificationInterface()
+ .createConversationNotificationChannelForPackageFromPrivilegedListener(
+ mWrapper, pkg, user, parentChannelId, conversationId);
+ } catch (RemoteException e) {
+ Log.v(TAG, "Unable to contact notification manager", e);
+ throw e.rethrowFromSystemServer();
+ }
+ }
/**
* Updates a notification channel for a given package for a given user. This should only be used
@@ -890,7 +920,7 @@ public abstract class NotificationListenerService extends Service {
* <p>This method will throw a security exception if you don't have access to notifications
* for the given user.</p>
* <p>The caller must have {@link CompanionDeviceManager#getAssociations() an associated
- * device} in order to use this method.
+ * device} or be the notification assistant in order to use this method.
*
* @param pkg The package the channel belongs to.
* @param user The user the channel belongs to.
diff --git a/core/java/android/service/notification/flags.aconfig b/core/java/android/service/notification/flags.aconfig
index 51961a85d307..34e311f8c932 100644
--- a/core/java/android/service/notification/flags.aconfig
+++ b/core/java/android/service/notification/flags.aconfig
@@ -57,4 +57,12 @@ flag {
namespace: "systemui"
description: "Guards the new FLAG_SILENT Notification flag"
bug: "336488844"
+}
+
+flag {
+ name: "notification_conversation_channel_management"
+ is_exported: true
+ namespace: "systemui"
+ description: "Allows the NAS to create and modify conversation notifications"
+ bug: "373599715"
} \ No newline at end of file
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index 2ab16e91d987..7f54cf0999b0 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -221,14 +221,14 @@ public abstract class WallpaperService extends Service {
/**
* Wear products currently force a slight scaling transition to wallpapers
- * when the QSS is opened. However, on Wear 6 (SDK 35) and above, 1P watch faces
+ * when the QSS is opened. However, on Wear 7 (SDK 37) and above, 1P watch faces
* will be expected to either implement their own scaling, or to override this
* method to allow the WallpaperController to continue to scale for them.
*
* @hide
*/
@ChangeId
- @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM)
+ @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.BAKLAVA)
public static final long WEAROS_WALLPAPER_HANDLES_SCALING = 272527315L;
static final class WallpaperCommand {
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 0d5554484dc1..b8b22e283175 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -87,6 +87,7 @@ import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.List;
import java.util.Objects;
import java.util.concurrent.Executor;
import java.util.function.Consumer;
@@ -463,7 +464,7 @@ public final class SurfaceControl implements Parcelable {
/**
* Called when new jank classifications are available.
*/
- void onJankDataAvailable(JankData[] jankData);
+ void onJankDataAvailable(@NonNull List<JankData> jankData);
}
@@ -2686,7 +2687,9 @@ public final class SurfaceControl implements Parcelable {
* Adds a callback to be informed about SF's jank classification for this surface.
* @hide
*/
- public OnJankDataListenerRegistration addJankDataListener(OnJankDataListener listener) {
+ @NonNull
+ public OnJankDataListenerRegistration addOnJankDataListener(
+ @NonNull OnJankDataListener listener) {
return new OnJankDataListenerRegistration(this, listener);
}
@@ -3459,15 +3462,15 @@ public final class SurfaceControl implements Parcelable {
* @return this This transaction for chaining
* @hide
*/
- public @NonNull Transaction setCrop(@NonNull SurfaceControl sc, float top, float left,
- float bottom, float right) {
+ public @NonNull Transaction setCrop(@NonNull SurfaceControl sc, float left, float top,
+ float right, float bottom) {
checkPreconditions(sc);
if (SurfaceControlRegistry.sCallStackDebuggingEnabled) {
SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging(
"setCrop", this, sc, "crop={" + top + ", " + left + ", " +
bottom + ", " + right + "}");
}
- nativeSetCrop(mNativeObject, sc.mNativeObject, top, left, bottom, right);
+ nativeSetCrop(mNativeObject, sc.mNativeObject, left, top, right, bottom);
return this;
}
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 9cad3e58fa02..4df7649e1c9b 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -40,6 +40,7 @@ import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
+import android.graphics.RectF;
import android.graphics.Region;
import android.graphics.RenderNode;
import android.hardware.input.InputManager;
@@ -1666,7 +1667,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
}
private final Rect mRTLastReportedPosition = new Rect();
- private final Rect mRTLastSetCrop = new Rect();
+ private final RectF mRTLastSetCrop = new RectF();
private class SurfaceViewPositionUpdateListener implements RenderNode.PositionUpdateListener {
private final int mRtSurfaceWidth;
@@ -1711,16 +1712,18 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
@Override
public void positionChanged(long frameNumber, int left, int top, int right, int bottom,
- int clipLeft, int clipTop, int clipRight, int clipBottom) {
+ int clipLeft, int clipTop, int clipRight, int clipBottom,
+ int nodeWidth, int nodeHeight) {
try {
if (DEBUG_POSITION) {
Log.d(TAG, String.format(
"%d updateSurfacePosition RenderWorker, frameNr = %d, "
+ "position = [%d, %d, %d, %d] clip = [%d, %d, %d, %d] "
- + "surfaceSize = %dx%d",
+ + "surfaceSize = %dx%d renderNodeSize = %d%d",
System.identityHashCode(SurfaceView.this), frameNumber,
left, top, right, bottom, clipLeft, clipTop, clipRight, clipBottom,
- mRtSurfaceWidth, mRtSurfaceHeight));
+ mRtSurfaceWidth, mRtSurfaceHeight,
+ nodeWidth, nodeHeight));
}
synchronized (mSurfaceControlLock) {
if (mSurfaceControl == null) return;
@@ -1735,14 +1738,29 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
mRTLastReportedPosition.top /*positionTop*/,
postScaleX, postScaleY);
- mRTLastSetCrop.set(clipLeft, clipTop, clipRight, clipBottom);
+ // The computed crop is in view-relative dimensions, however we need it to be
+ // in buffer-relative dimensions. So scale the crop by the ratio between
+ // the view's unscaled width/height (nodeWidth/Height), and the surface's
+ // width/height
+ // That is, if the Surface has a fixed size of 50x50, the SurfaceView is laid
+ // out to a size of 100x100, and the SurfaceView is ultimately scaled to
+ // 1000x1000, then we need to scale the crop by just the 2x from surface
+ // domain to SV domain.
+ final float surfaceToNodeScaleX = (float) mRtSurfaceWidth / (float) nodeWidth;
+ final float surfaceToNodeScaleY = (float) mRtSurfaceHeight / (float) nodeHeight;
+ mRTLastSetCrop.set(clipLeft * surfaceToNodeScaleX,
+ clipTop * surfaceToNodeScaleY,
+ clipRight * surfaceToNodeScaleX,
+ clipBottom * surfaceToNodeScaleY);
+
if (DEBUG_POSITION) {
- Log.d(TAG, String.format("Setting layer crop = [%d, %d, %d, %d] "
+ Log.d(TAG, String.format("Setting layer crop = [%f, %f, %f, %f] "
+ "from scale %f, %f", mRTLastSetCrop.left,
mRTLastSetCrop.top, mRTLastSetCrop.right, mRTLastSetCrop.bottom,
- postScaleX, postScaleY));
+ surfaceToNodeScaleX, surfaceToNodeScaleY));
}
- mPositionChangedTransaction.setCrop(mSurfaceControl, mRTLastSetCrop);
+ mPositionChangedTransaction.setCrop(mSurfaceControl, mRTLastSetCrop.left,
+ mRTLastSetCrop.top, mRTLastSetCrop.right, mRTLastSetCrop.bottom);
if (mRTLastSetCrop.isEmpty()) {
mPositionChangedTransaction.hide(mSurfaceControl);
} else {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index d5fc26281fc6..6090b5ec1622 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -30,7 +30,9 @@ import static android.view.Surface.FRAME_RATE_COMPATIBILITY_FIXED_SOURCE;
import static android.view.Surface.FRAME_RATE_COMPATIBILITY_GTE;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
import static android.view.accessibility.AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED;
+import static android.view.accessibility.Flags.FLAG_SUPPLEMENTAL_DESCRIPTION;
import static android.view.accessibility.Flags.removeChildHoverCheckForTouchExploration;
+import static android.view.accessibility.Flags.supplementalDescription;
import static android.view.displayhash.DisplayHashResultCallback.DISPLAY_HASH_ERROR_INVALID_BOUNDS;
import static android.view.displayhash.DisplayHashResultCallback.DISPLAY_HASH_ERROR_MISSING_WINDOW;
import static android.view.displayhash.DisplayHashResultCallback.DISPLAY_HASH_ERROR_NOT_VISIBLE_ON_SCREEN;
@@ -40,7 +42,6 @@ import static android.view.displayhash.DisplayHashResultCallback.EXTRA_DISPLAY_H
import static android.view.flags.Flags.FLAG_SENSITIVE_CONTENT_APP_PROTECTION_API;
import static android.view.flags.Flags.FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY;
import static android.view.flags.Flags.FLAG_VIEW_VELOCITY_API;
-import static android.view.flags.Flags.calculateBoundsInParentFromBoundsInScreen;
import static android.view.flags.Flags.enableUseMeasureCacheDuringForceLayout;
import static android.view.flags.Flags.sensitiveContentAppProtection;
import static android.view.flags.Flags.toolkitFrameRateAnimationBugfix25q1;
@@ -968,13 +969,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
private static boolean sAlwaysRemeasureExactly = false;
/**
- * When true calculates the bounds in parent from bounds in screen relative to its parents.
- * This addresses the deprecated API (setBoundsInParent) in Compose, which causes empty
- * getBoundsInParent call for Compose apps.
- */
- private static boolean sCalculateBoundsInParentFromBoundsInScreenFlagValue = false;
-
- /**
* When true makes it possible to use onMeasure caches also when the force layout flag is
* enabled. This helps avoiding multiple measures in the same frame with the same dimensions.
*/
@@ -2564,8 +2558,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
sToolkitSetFrameRateReadOnlyFlagValue = toolkitSetFrameRateReadOnly();
sToolkitMetricsForFrameRateDecisionFlagValue = toolkitMetricsForFrameRateDecision();
- sCalculateBoundsInParentFromBoundsInScreenFlagValue =
- calculateBoundsInParentFromBoundsInScreen();
sUseMeasureCacheDuringForceLayoutFlagValue = enableUseMeasureCacheDuringForceLayout();
}
@@ -4874,6 +4866,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
private CharSequence mContentDescription;
/**
+ * Brief supplemental information for view and is primarily used for accessibility support.
+ */
+ private CharSequence mSupplementalDescription;
+
+ /**
* If this view represents a distinct part of the window, it can have a title that labels the
* area.
*/
@@ -6544,6 +6541,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
case R.styleable.View_contentSensitivity:
setContentSensitivity(a.getInt(attr, CONTENT_SENSITIVITY_AUTO));
break;
+ default: {
+ if (supplementalDescription()) {
+ if (attr == com.android.internal.R.styleable.View_supplementalDescription) {
+ setSupplementalDescription(a.getString(attr));
+ }
+ }
+ }
}
}
@@ -9786,7 +9790,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
structure.setChildCount(1);
final ViewStructure root = structure.newChild(0);
if (info != null) {
- populateVirtualStructure(root, provider, info, null, forAutofill);
+ populateVirtualStructure(root, provider, info, forAutofill);
info.recycle();
} else {
Log.w(AUTOFILL_LOG_TAG, "AccessibilityNodeInfo is null.");
@@ -11085,19 +11089,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
private void populateVirtualStructure(ViewStructure structure,
AccessibilityNodeProvider provider, AccessibilityNodeInfo info,
- @Nullable AccessibilityNodeInfo parentInfo, boolean forAutofill) {
+ boolean forAutofill) {
structure.setId(AccessibilityNodeInfo.getVirtualDescendantId(info.getSourceNodeId()),
null, null, info.getViewIdResourceName());
Rect rect = structure.getTempRect();
- // The bounds in parent for Jetpack Compose views aren't set as setBoundsInParent is
- // deprecated, and only setBoundsInScreen is called.
- // The bounds in parent can be calculated by diff'ing the child view's bounds in screen with
- // the parent's.
- if (sCalculateBoundsInParentFromBoundsInScreenFlagValue) {
- getBoundsInParent(info, parentInfo, rect);
- } else {
- info.getBoundsInParent(rect);
- }
+ info.getBoundsInParent(rect);
structure.setDimens(rect.left, rect.top, 0, 0, rect.width(), rect.height());
structure.setVisibility(VISIBLE);
structure.setEnabled(info.isEnabled());
@@ -11181,32 +11177,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
AccessibilityNodeInfo.getVirtualDescendantId(info.getChildId(i)));
if (cinfo != null) {
ViewStructure child = structure.newChild(i);
- populateVirtualStructure(child, provider, cinfo, info, forAutofill);
+ populateVirtualStructure(child, provider, cinfo, forAutofill);
cinfo.recycle();
}
}
}
}
- private void getBoundsInParent(@NonNull AccessibilityNodeInfo info,
- @Nullable AccessibilityNodeInfo parentInfo, @NonNull Rect rect) {
- info.getBoundsInParent(rect);
- // Fallback to calculate bounds in parent by diffing the bounds in
- // screen if it's all 0.
- if ((rect.left | rect.top | rect.right | rect.bottom) == 0) {
- if (parentInfo != null) {
- Rect parentBoundsInScreen = parentInfo.getBoundsInScreen();
- Rect boundsInScreen = info.getBoundsInScreen();
- rect.set(boundsInScreen.left - parentBoundsInScreen.left,
- boundsInScreen.top - parentBoundsInScreen.top,
- boundsInScreen.right - parentBoundsInScreen.left,
- boundsInScreen.bottom - parentBoundsInScreen.top);
- } else {
- info.getBoundsInScreen(rect);
- }
- }
- }
-
/**
* Dispatch creation of {@link ViewStructure} down the hierarchy. The default
* implementation calls {@link #onProvideStructure} and
@@ -11843,6 +11820,39 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
/**
+ * Returns the {@link View}'s supplemental description.
+ * <p>
+ * A supplemental description provides
+ * brief supplemental information for this node, such as the purpose of the node when
+ * that purpose is not conveyed within its textual representation. For example, if a
+ * dropdown select has a purpose of setting font family, the supplemental description
+ * could be "font family". If this node has children, its supplemental description serves
+ * as additional information and is not intended to replace any existing information
+ * in the subtree. This is different from the {@link #getContentDescription()} in that
+ * this description is purely supplemental while a content description may be used
+ * to replace a description for a node or its subtree that an assistive technology
+ * would otherwise compute based on other properties of the node and its descendants.
+ *
+ * <p>
+ * <strong>Note:</strong> Do not override this method, as it will have no
+ * effect on the supplemental description presented to accessibility services.
+ * You must call {@link #setSupplementalDescription(CharSequence)} to modify the
+ * supplemental description.
+ *
+ * @return the supplemental description
+ * @see #setSupplementalDescription(CharSequence)
+ * @see #getContentDescription()
+ * @attr ref android.R.styleable#View_supplementalDescription
+ */
+ @FlaggedApi(FLAG_SUPPLEMENTAL_DESCRIPTION)
+ @ViewDebug.ExportedProperty(category = "accessibility")
+ @InspectableProperty
+ @Nullable
+ public CharSequence getSupplementalDescription() {
+ return mSupplementalDescription;
+ }
+
+ /**
* Sets the {@link View}'s state description.
* <p>
* A state description briefly describes the states of the view and is primarily used
@@ -11929,6 +11939,53 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
/**
+ * Sets the {@link View}'s supplemental description.
+ * <p>
+ * A supplemental description provides
+ * brief supplemental information for this node, such as the purpose of the node when
+ * that purpose is not conveyed within its textual representation. For example, if a
+ * dropdown select has a purpose of setting font family, the supplemental description
+ * could be "font family". If this node has children, its supplemental description serves
+ * as additional information and is not intended to replace any existing information
+ * in the subtree. This is different from the {@link #setContentDescription(CharSequence)}
+ * in that this description is purely supplemental while a content description may be used
+ * to replace a description for a node or its subtree that an assistive technology
+ * would otherwise compute based on other properties of the node and its descendants.
+ *
+ * <p>
+ * This should omit role or state. Role refers to the kind of user-interface element the View
+ * is, such as a Button or Checkbox. State refers to a frequently changing property of the View,
+ * such as an On/Off state of a button or the audio level of a volume slider.
+ *
+ * @param supplementalDescription The supplemental description.
+ * @see #getSupplementalDescription()
+ * @see #setContentDescription(CharSequence)
+ * @see #setStateDescription(CharSequence) for state changes.
+ * @attr ref android.R.styleable#View_supplementalDescription
+ */
+ @FlaggedApi(FLAG_SUPPLEMENTAL_DESCRIPTION)
+ @RemotableViewMethod
+ public void setSupplementalDescription(@Nullable CharSequence supplementalDescription) {
+ if (mSupplementalDescription == null) {
+ if (supplementalDescription == null) {
+ return;
+ }
+ } else if (mSupplementalDescription.equals(supplementalDescription)) {
+ return;
+ }
+ mSupplementalDescription = supplementalDescription;
+ final boolean nonEmptyDesc = supplementalDescription != null
+ && !supplementalDescription.isEmpty();
+ if (nonEmptyDesc && getImportantForAccessibility() == IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
+ setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
+ notifySubtreeAccessibilityStateChangedIfNeeded();
+ } else {
+ notifyViewAccessibilityStateChangedIfNeeded(
+ AccessibilityEvent.CONTENT_CHANGE_TYPE_SUPPLEMENTAL_DESCRIPTION);
+ }
+ }
+
+ /**
* Sets the id of a view that screen readers are requested to visit after this view.
*
* <p>
diff --git a/core/java/android/view/accessibility/AccessibilityEvent.java b/core/java/android/view/accessibility/AccessibilityEvent.java
index 4e9d054dae07..c690787e4a33 100644
--- a/core/java/android/view/accessibility/AccessibilityEvent.java
+++ b/core/java/android/view/accessibility/AccessibilityEvent.java
@@ -810,6 +810,20 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par
@FlaggedApi(Flags.FLAG_A11Y_EXPANSION_STATE_API)
public static final int CONTENT_CHANGE_TYPE_EXPANDED = 1 << 14;
+ /**
+ * Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event:
+ * The source node changed its supplemental description, which is returned by
+ * {@link AccessibilityNodeInfo#getSupplementalDescription()}.
+ * The view changing its supplemental description should call
+ * {@link AccessibilityNodeInfo#setSupplementalDescription(CharSequence)} and
+ * then send this event.
+ *
+ * @see AccessibilityNodeInfo#getSupplementalDescription()
+ * @see AccessibilityNodeInfo#setSupplementalDescription(CharSequence)
+ */
+ @FlaggedApi(Flags.FLAG_SUPPLEMENTAL_DESCRIPTION)
+ public static final int CONTENT_CHANGE_TYPE_SUPPLEMENTAL_DESCRIPTION = 1 << 15;
+
// Speech state change types.
/** Change type for {@link #TYPE_SPEECH_STATE_CHANGE} event: another service is speaking. */
@@ -942,6 +956,7 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par
CONTENT_CHANGE_TYPE_CONTENT_INVALID,
CONTENT_CHANGE_TYPE_ERROR,
CONTENT_CHANGE_TYPE_ENABLED,
+ CONTENT_CHANGE_TYPE_SUPPLEMENTAL_DESCRIPTION,
})
public @interface ContentChangeTypes {}
@@ -1222,7 +1237,14 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par
return "CONTENT_CHANGE_TYPE_CONTENT_INVALID";
case CONTENT_CHANGE_TYPE_ERROR: return "CONTENT_CHANGE_TYPE_ERROR";
case CONTENT_CHANGE_TYPE_ENABLED: return "CONTENT_CHANGE_TYPE_ENABLED";
- default: return Integer.toHexString(type);
+ default: {
+ if (Flags.supplementalDescription()) {
+ if (type == CONTENT_CHANGE_TYPE_SUPPLEMENTAL_DESCRIPTION) {
+ return "CONTENT_CHANGE_TYPE_SUPPLEMENTAL_DESCRIPTION";
+ }
+ }
+ return Integer.toHexString(type);
+ }
}
}
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index f70f7e6a59c0..e7acfdf7b26e 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -1085,6 +1085,7 @@ public class AccessibilityNodeInfo implements Parcelable {
private CharSequence mPaneTitle;
private CharSequence mStateDescription;
private CharSequence mContentDescription;
+ private CharSequence mSupplementalDescription;
private CharSequence mTooltipText;
private String mViewIdResourceName;
private String mUniqueId;
@@ -3686,6 +3687,27 @@ public class AccessibilityNodeInfo implements Parcelable {
return mContentDescription;
}
+ /**
+ * Gets the supplemental description of this node. A supplemental description provides
+ * brief supplemental information for this node, such as the purpose of the node when
+ * that purpose is not conveyed within its textual representation. For example, if a
+ * dropdown select has a purpose of setting font family, the supplemental description
+ * could be "font family". If this node has children, its supplemental description serves
+ * as additional information and is not intended to replace any existing information
+ * in the subtree. This is different from the {@link #getContentDescription()} in that
+ * this description is purely supplemental while a content description may be used
+ * to replace a description for a node or its subtree that an assistive technology
+ * would otherwise compute based on other properties of the node and its descendants.
+ *
+ * @return The supplemental description.
+ * @see #setSupplementalDescription(CharSequence)
+ * @see #getContentDescription()
+ */
+ @FlaggedApi(Flags.FLAG_SUPPLEMENTAL_DESCRIPTION)
+ @Nullable
+ public CharSequence getSupplementalDescription() {
+ return mSupplementalDescription;
+ }
/**
* Sets the state description of this node.
@@ -3724,6 +3746,35 @@ public class AccessibilityNodeInfo implements Parcelable {
}
/**
+ * Sets the supplemental description of this node. A supplemental description provides
+ * brief supplemental information for this node, such as the purpose of the node when
+ * that purpose is not conveyed within its textual representation. For example, if a
+ * dropdown select has a purpose of setting font family, the supplemental description
+ * could be "font family". If this node has children, its supplemental description serves
+ * as additional information and is not intended to replace any existing information
+ * in the subtree. This is different from the {@link #setContentDescription(CharSequence)}
+ * in that this description is purely supplemental while a content description may be used
+ * to replace a description for a node or its subtree that an assistive technology
+ * would otherwise compute based on other properties of the node and its descendants.
+ * <p>
+ * <strong>Note:</strong> Cannot be called from an
+ * {@link android.accessibilityservice.AccessibilityService}.
+ * This class is made immutable before being delivered to an AccessibilityService.
+ *
+ * @param supplementalDescription The supplemental description.
+ *
+ * @throws IllegalStateException If called from an AccessibilityService.
+ * @see #getSupplementalDescription()
+ * @see #setContentDescription(CharSequence)
+ */
+ @FlaggedApi(Flags.FLAG_SUPPLEMENTAL_DESCRIPTION)
+ public void setSupplementalDescription(@Nullable CharSequence supplementalDescription) {
+ enforceNotSealed();
+ mSupplementalDescription = (supplementalDescription == null) ? null
+ : supplementalDescription.subSequence(0, supplementalDescription.length());
+ }
+
+ /**
* Gets the tooltip text of this node.
*
* @return The tooltip text.
@@ -4657,6 +4708,10 @@ public class AccessibilityNodeInfo implements Parcelable {
nonDefaultFields |= bitAt(fieldIndex);
}
fieldIndex++;
+ if (!Objects.equals(mSupplementalDescription, DEFAULT.mSupplementalDescription)) {
+ nonDefaultFields |= bitAt(fieldIndex);
+ }
+ fieldIndex++;
if (!Objects.equals(mPaneTitle, DEFAULT.mPaneTitle)) {
nonDefaultFields |= bitAt(fieldIndex);
}
@@ -4843,6 +4898,9 @@ public class AccessibilityNodeInfo implements Parcelable {
if (isBitSet(nonDefaultFields, fieldIndex++)) {
parcel.writeCharSequence(mContentDescription);
}
+ if (isBitSet(nonDefaultFields, fieldIndex++)) {
+ parcel.writeCharSequence(mSupplementalDescription);
+ }
if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeCharSequence(mPaneTitle);
if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeCharSequence(mTooltipText);
if (isBitSet(nonDefaultFields, fieldIndex++)) parcel.writeCharSequence(mContainerTitle);
@@ -4950,6 +5008,7 @@ public class AccessibilityNodeInfo implements Parcelable {
mError = other.mError;
mStateDescription = other.mStateDescription;
mContentDescription = other.mContentDescription;
+ mSupplementalDescription = other.mSupplementalDescription;
mPaneTitle = other.mPaneTitle;
mTooltipText = other.mTooltipText;
mContainerTitle = other.mContainerTitle;
@@ -5119,6 +5178,9 @@ public class AccessibilityNodeInfo implements Parcelable {
if (isBitSet(nonDefaultFields, fieldIndex++)) {
mContentDescription = parcel.readCharSequence();
}
+ if (isBitSet(nonDefaultFields, fieldIndex++)) {
+ mSupplementalDescription = parcel.readCharSequence();
+ }
if (isBitSet(nonDefaultFields, fieldIndex++)) mPaneTitle = parcel.readCharSequence();
if (isBitSet(nonDefaultFields, fieldIndex++)) mTooltipText = parcel.readCharSequence();
if (isBitSet(nonDefaultFields, fieldIndex++)) mContainerTitle = parcel.readCharSequence();
@@ -5483,6 +5545,9 @@ public class AccessibilityNodeInfo implements Parcelable {
builder.append("; maxTextLength: ").append(mMaxTextLength);
builder.append("; stateDescription: ").append(mStateDescription);
builder.append("; contentDescription: ").append(mContentDescription);
+ if (Flags.supplementalDescription()) {
+ builder.append("; supplementalDescription: ").append(mSupplementalDescription);
+ }
builder.append("; tooltipText: ").append(mTooltipText);
builder.append("; containerTitle: ").append(mContainerTitle);
builder.append("; viewIdResName: ").append(mViewIdResourceName);
diff --git a/core/java/android/view/accessibility/flags/accessibility_flags.aconfig b/core/java/android/view/accessibility/flags/accessibility_flags.aconfig
index ffa819f1f183..fde42af85420 100644
--- a/core/java/android/view/accessibility/flags/accessibility_flags.aconfig
+++ b/core/java/android/view/accessibility/flags/accessibility_flags.aconfig
@@ -222,6 +222,13 @@ flag {
}
flag {
+ name: "supplemental_description"
+ namespace: "accessibility"
+ description: "Feature flag for supplemental description api"
+ bug: "375266174"
+}
+
+flag {
name: "support_multiple_labeledby"
namespace: "accessibility"
description: "Feature flag for supporting multiple labels in AccessibilityNodeInfo labeledby api"
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index e6eec3760804..9b6311f35d17 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -20,7 +20,6 @@ import static android.appwidget.flags.Flags.FLAG_DRAW_DATA_PARCEL;
import static android.appwidget.flags.Flags.FLAG_REMOTE_VIEWS_PROTO;
import static android.appwidget.flags.Flags.drawDataParcel;
import static android.appwidget.flags.Flags.remoteAdapterConversion;
-import static android.util.TypedValue.TYPE_INT_COLOR_ARGB8;
import static android.util.proto.ProtoInputStream.NO_MORE_FIELDS;
import static android.view.inputmethod.Flags.FLAG_HOME_SCREEN_HANDWRITING_DELEGATOR;
@@ -55,10 +54,6 @@ import android.content.ContextWrapper;
import android.content.Intent;
import android.content.IntentSender;
import android.content.ServiceConnection;
-import android.content.om.FabricatedOverlay;
-import android.content.om.OverlayInfo;
-import android.content.om.OverlayManager;
-import android.content.om.OverlayManagerTransaction;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.ColorStateList;
@@ -84,12 +79,14 @@ import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.IBinder;
import android.os.Parcel;
+import android.os.ParcelFileDescriptor;
import android.os.Parcelable;
import android.os.Process;
import android.os.RemoteException;
import android.os.StrictMode;
import android.os.Trace;
import android.os.UserHandle;
+import android.system.Os;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.DisplayMetrics;
@@ -131,8 +128,11 @@ import com.android.internal.widget.remotecompose.player.RemoteComposePlayer;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
+import java.io.FileDescriptor;
+import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.OutputStream;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -8552,8 +8552,12 @@ public class RemoteViews implements Parcelable, Filter {
* @hide
*/
public static final class ColorResources {
- private static final String OVERLAY_NAME = "remote_views_color_resources";
- private static final String OVERLAY_TARGET_PACKAGE_NAME = "android";
+ // Set of valid colors resources.
+ private static final int FIRST_RESOURCE_COLOR_ID = android.R.color.system_neutral1_0;
+ private static final int LAST_RESOURCE_COLOR_ID =
+ android.R.color.system_error_1000;
+ // Size, in bytes, of an entry in the array of colors in an ARSC file.
+ private static final int ARSC_ENTRY_SIZE = 16;
private final ResourcesLoader mLoader;
private final SparseIntArray mColorMapping;
@@ -8587,6 +8591,44 @@ public class RemoteViews implements Parcelable, Filter {
}
/**
+ * Creates the compiled resources content from the asset stored in the APK.
+ *
+ * The asset is a compiled resource with the correct resources name and correct ids, only
+ * the values are incorrect. The last value is at the very end of the file. The resources
+ * are in an array, the array's entries are 16 bytes each. We use this to work out the
+ * location of all the positions of the various resources.
+ */
+ @Nullable
+ private static byte[] createCompiledResourcesContent(Context context,
+ SparseIntArray colorResources) throws IOException {
+ byte[] content;
+ try (InputStream input = context.getResources().openRawResource(
+ com.android.internal.R.raw.remote_views_color_resources)) {
+ ByteArrayOutputStream rawContent = readFileContent(input);
+ content = rawContent.toByteArray();
+ }
+ int valuesOffset =
+ content.length - (LAST_RESOURCE_COLOR_ID & 0xffff) * ARSC_ENTRY_SIZE - 4;
+ if (valuesOffset < 0) {
+ Log.e(LOG_TAG, "ARSC file for theme colors is invalid.");
+ return null;
+ }
+ for (int colorRes = FIRST_RESOURCE_COLOR_ID; colorRes <= LAST_RESOURCE_COLOR_ID;
+ colorRes++) {
+ // The last 2 bytes are the index in the color array.
+ int index = colorRes & 0xffff;
+ int offset = valuesOffset + index * ARSC_ENTRY_SIZE;
+ int value = colorResources.get(colorRes, context.getColor(colorRes));
+ // Write the 32 bit integer in little endian
+ for (int b = 0; b < 4; b++) {
+ content[offset + b] = (byte) (value & 0xff);
+ value >>= 8;
+ }
+ }
+ return content;
+ }
+
+ /**
* Adds a resource loader for theme colors to the given context.
*
* @param context Context of the view hosting the widget.
@@ -8597,38 +8639,31 @@ public class RemoteViews implements Parcelable, Filter {
@Nullable
public static ColorResources create(Context context, SparseIntArray colorMapping) {
try {
- String owningPackage = context.getPackageName();
- FabricatedOverlay overlay = new FabricatedOverlay.Builder(owningPackage,
- OVERLAY_NAME, OVERLAY_TARGET_PACKAGE_NAME).build();
-
- for (int i = 0; i < colorMapping.size(); i++) {
- overlay.setResourceValue(
- context.getResources().getResourceName(colorMapping.keyAt(i)),
- TYPE_INT_COLOR_ARGB8, colorMapping.valueAt(i), null);
- }
- OverlayManager overlayManager = context.getSystemService(OverlayManager.class);
- OverlayManagerTransaction.Builder transaction =
- new OverlayManagerTransaction.Builder()
- .registerFabricatedOverlay(overlay)
- .setSelfTargeting(true);
- overlayManager.commit(transaction.build());
-
- OverlayInfo overlayInfo =
- overlayManager.getOverlayInfosForTarget(OVERLAY_TARGET_PACKAGE_NAME)
- .stream()
- .filter(info -> TextUtils.equals(info.overlayName, OVERLAY_NAME)
- && TextUtils.equals(info.packageName, owningPackage))
- .findFirst()
- .orElse(null);
- if (overlayInfo == null) {
- Log.e(LOG_TAG, "Failed to get overlay info ", new Throwable());
+ byte[] contentBytes = createCompiledResourcesContent(context, colorMapping);
+ if (contentBytes == null) {
return null;
}
- ResourcesLoader colorsLoader = new ResourcesLoader();
- colorsLoader.addProvider(ResourcesProvider.loadOverlay(overlayInfo));
- return new ColorResources(colorsLoader, colorMapping.clone());
- } catch (Exception e) {
- Log.e(LOG_TAG, "Failed to add theme color overlay into loader", e);
+ FileDescriptor arscFile = null;
+ try {
+ arscFile = Os.memfd_create("remote_views_theme_colors.arsc", 0 /* flags */);
+ // Note: This must not be closed through the OutputStream.
+ try (OutputStream pipeWriter = new FileOutputStream(arscFile)) {
+ pipeWriter.write(contentBytes);
+
+ try (ParcelFileDescriptor pfd = ParcelFileDescriptor.dup(arscFile)) {
+ ResourcesLoader colorsLoader = new ResourcesLoader();
+ colorsLoader.addProvider(ResourcesProvider
+ .loadFromTable(pfd, null /* assetsProvider */));
+ return new ColorResources(colorsLoader, colorMapping.clone());
+ }
+ }
+ } finally {
+ if (arscFile != null) {
+ Os.close(arscFile);
+ }
+ }
+ } catch (Exception ex) {
+ Log.e(LOG_TAG, "Failed to setup the context for theme colors", ex);
}
return null;
}
diff --git a/core/java/android/widget/TextClock.java b/core/java/android/widget/TextClock.java
index 255bd679dc35..65cd190725a4 100644
--- a/core/java/android/widget/TextClock.java
+++ b/core/java/android/widget/TextClock.java
@@ -45,6 +45,7 @@ import android.view.inspector.InspectableProperty;
import com.android.internal.R;
import com.android.internal.util.Preconditions;
+import java.time.DateTimeException;
import java.time.Duration;
import java.time.Instant;
import java.time.ZoneId;
@@ -291,11 +292,26 @@ public class TextClock extends TextView {
}
private void createTime(String timeZone) {
- if (timeZone != null) {
- mTime = Calendar.getInstance(TimeZone.getTimeZone(timeZone));
+ TimeZone tz = null;
+ if (timeZone == null) {
+ tz = TimeZone.getDefault();
+ // Note that mTimeZone should always be null if timeZone is.
} else {
- mTime = Calendar.getInstance();
+ tz = TimeZone.getTimeZone(timeZone);
+ try {
+ // Try converting this TZ to a zoneId to make sure it's valid. This
+ // performs a different set of checks than TimeZone.getTimeZone so
+ // we can avoid exceptions later when we do need this conversion.
+ tz.toZoneId();
+ } catch (DateTimeException ex) {
+ // If we're here, the user supplied timezone is invalid, so reset
+ // mTimeZone to something sane.
+ tz = TimeZone.getDefault();
+ mTimeZone = tz.getID();
+ }
}
+
+ mTime = Calendar.getInstance(tz);
}
/**
diff --git a/core/java/android/window/DesktopModeFlags.java b/core/java/android/window/DesktopModeFlags.java
index 22eec2940e19..dae87ddcb1bd 100644
--- a/core/java/android/window/DesktopModeFlags.java
+++ b/core/java/android/window/DesktopModeFlags.java
@@ -70,7 +70,12 @@ public enum DesktopModeFlags {
ENABLE_DESKTOP_WINDOWING_ENTER_TRANSITIONS(Flags::enableDesktopWindowingTransitions, false),
ENABLE_DESKTOP_WINDOWING_EXIT_TRANSITIONS(Flags::enableDesktopWindowingExitTransitions, false),
ENABLE_WINDOWING_TRANSITION_HANDLERS_OBSERVERS(
- Flags::enableWindowingTransitionHandlersObservers, false);
+ Flags::enableWindowingTransitionHandlersObservers, false),
+ ENABLE_DESKTOP_APP_LAUNCH_ALTTAB_TRANSITIONS(
+ Flags::enableDesktopAppLaunchAlttabTransitions, false),
+ ENABLE_DESKTOP_APP_LAUNCH_TRANSITIONS(
+ Flags::enableDesktopAppLaunchTransitions, false),
+ ENABLE_DESKTOP_WINDOWING_PERSISTENCE(Flags::enableDesktopWindowingPersistence, false);
private static final String TAG = "DesktopModeFlagsUtil";
// Function called to obtain aconfig flag value.
diff --git a/core/java/com/android/internal/app/SuggestedLocaleAdapter.java b/core/java/com/android/internal/app/SuggestedLocaleAdapter.java
index be3f10acbed3..091975cf855a 100644
--- a/core/java/com/android/internal/app/SuggestedLocaleAdapter.java
+++ b/core/java/com/android/internal/app/SuggestedLocaleAdapter.java
@@ -28,6 +28,7 @@ import android.widget.BaseAdapter;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.LinearLayout;
+import android.widget.RadioButton;
import android.widget.TextView;
import com.android.internal.R;
@@ -242,11 +243,7 @@ public class SuggestedLocaleAdapter extends BaseAdapter implements Filterable {
break;
case TYPE_SYSTEM_LANGUAGE_FOR_APP_LANGUAGE_PICKER:
TextView title;
- LocaleStore.LocaleInfo info = (LocaleStore.LocaleInfo) getItem(position);
- if (info == null) {
- throw new NullPointerException("Non header locale cannot be null.");
- }
- if (info.isAppCurrentLocale()) {
+ if (mHasSpecificAppPackageName) {
title = itemView.findViewById(R.id.language_picker_item);
} else {
title = itemView.findViewById(R.id.locale);
@@ -254,11 +251,22 @@ public class SuggestedLocaleAdapter extends BaseAdapter implements Filterable {
title.setText(R.string.system_locale_title);
break;
case TYPE_CURRENT_LOCALE:
- updateTextView(itemView,
- itemView.findViewById(R.id.language_picker_item), position);
+ updateTextView(
+ itemView, itemView.findViewById(R.id.language_picker_item), position);
break;
default:
- updateTextView(itemView, itemView.findViewById(R.id.locale), position);
+ LocaleStore.LocaleInfo localeInfo = (LocaleStore.LocaleInfo) getItem(position);
+ if (localeInfo == null) {
+ throw new NullPointerException("Non header locale cannot be null.");
+ }
+ if (mHasSpecificAppPackageName && localeInfo.isSuggested() && !mCountryMode) {
+ updateTextView(
+ itemView,
+ itemView.findViewById(R.id.language_picker_item),
+ position);
+ } else {
+ updateTextView(itemView, itemView.findViewById(R.id.locale), position);
+ }
break;
}
return itemView;
@@ -280,20 +288,21 @@ public class SuggestedLocaleAdapter extends BaseAdapter implements Filterable {
}
break;
case TYPE_SYSTEM_LANGUAGE_FOR_APP_LANGUAGE_PICKER:
- if (((LocaleStore.LocaleInfo) getItem(position)).isAppCurrentLocale()) {
- shouldReuseView = convertView instanceof LinearLayout
- && convertView.findViewById(R.id.language_picker_item) != null;
- if (!shouldReuseView) {
- updatedView = mInflater.inflate(
- R.layout.app_language_picker_current_locale_item,
- parent, false);
+ if (mHasSpecificAppPackageName) {
+ updatedView = mInflater.inflate(
+ R.layout.app_language_picker_locale_item, parent, false);
+ RadioButton option = updatedView.findViewById(R.id.checkbox);
+ if (((LocaleStore.LocaleInfo) getItem(position)).isAppCurrentLocale()) {
+ option.setChecked(true);
+ } else {
+ option.setChecked(false);
}
} else {
shouldReuseView = convertView instanceof TextView
- && convertView.findViewById(R.id.locale) != null;
+ && convertView.findViewById(R.id.locale) != null;
if (!shouldReuseView) {
- updatedView = mInflater.inflate(
- R.layout.language_picker_item, parent, false);
+ updatedView =
+ mInflater.inflate(R.layout.language_picker_item, parent, false);
}
}
break;
@@ -302,14 +311,30 @@ public class SuggestedLocaleAdapter extends BaseAdapter implements Filterable {
&& convertView.findViewById(R.id.language_picker_item) != null;
if (!shouldReuseView) {
updatedView = mInflater.inflate(
- R.layout.app_language_picker_current_locale_item, parent, false);
+ R.layout.app_language_picker_locale_item, parent, false);
+ RadioButton option = updatedView.findViewById(R.id.checkbox);
+ option.setChecked(true);
}
break;
default:
- shouldReuseView = convertView instanceof TextView
+ LocaleStore.LocaleInfo localeInfo = (LocaleStore.LocaleInfo) getItem(position);
+ if (mHasSpecificAppPackageName
+ && localeInfo.isSuggested() && !mCountryMode) {
+ shouldReuseView = convertView instanceof LinearLayout
+ && convertView.findViewById(R.id.language_picker_item) != null;
+ if ((!shouldReuseView)) {
+ updatedView = mInflater.inflate(
+ R.layout.app_language_picker_locale_item, parent, false);
+ RadioButton option = updatedView.findViewById(R.id.checkbox);
+ option.setChecked(false);
+ }
+ } else {
+ shouldReuseView = convertView instanceof TextView
&& convertView.findViewById(R.id.locale) != null;
- if (!shouldReuseView) {
- updatedView = mInflater.inflate(R.layout.language_picker_item, parent, false);
+ if ((!shouldReuseView)) {
+ updatedView = mInflater.inflate(
+ R.layout.language_picker_item, parent, false);
+ }
}
break;
}
diff --git a/core/java/com/android/internal/content/om/OverlayConfig.java b/core/java/com/android/internal/content/om/OverlayConfig.java
index 38593b4a2a99..07e178c0ba27 100644
--- a/core/java/com/android/internal/content/om/OverlayConfig.java
+++ b/core/java/com/android/internal/content/om/OverlayConfig.java
@@ -19,7 +19,6 @@ package com.android.internal.content.om;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.pm.PackagePartitions;
-import android.content.res.AssetManager;
import android.os.Build;
import android.os.Trace;
import android.util.ArrayMap;
@@ -534,7 +533,7 @@ public class OverlayConfig {
*/
@NonNull
public String[] createImmutableFrameworkIdmapsInZygote() {
- final String targetPath = AssetManager.FRAMEWORK_APK_PATH;
+ final String targetPath = "/system/framework/framework-res.apk";
final ArrayList<String> idmapPaths = new ArrayList<>();
final ArrayList<IdmapInvocation> idmapInvocations =
getImmutableFrameworkOverlayIdmapInvocations();
diff --git a/core/java/com/android/internal/content/om/OverlayManagerImpl.java b/core/java/com/android/internal/content/om/OverlayManagerImpl.java
index fa5cf2a396b9..c4624498138d 100644
--- a/core/java/com/android/internal/content/om/OverlayManagerImpl.java
+++ b/core/java/com/android/internal/content/om/OverlayManagerImpl.java
@@ -35,7 +35,6 @@ import android.content.om.OverlayManagerTransaction.Request;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.parsing.FrameworkParsingPackageUtils;
-import android.content.res.AssetManager;
import android.os.FabricatedOverlayInfo;
import android.os.FabricatedOverlayInternal;
import android.os.FabricatedOverlayInternalEntry;
@@ -61,8 +60,8 @@ import java.util.List;
import java.util.Objects;
/**
- * This class provides the functionalities for managing self-targeting overlays, including
- * registering an overlay, unregistering an overlay, and getting the list of overlays information.
+ * This class provides the functionalities of registering an overlay, unregistering an overlay, and
+ * getting the list of overlays information.
*/
public class OverlayManagerImpl {
private static final String TAG = "OverlayManagerImpl";
@@ -235,17 +234,14 @@ public class OverlayManagerImpl {
Preconditions.checkArgument(!entryList.isEmpty(), "overlay entries shouldn't be empty");
final String overlayName = checkOverlayNameValid(overlayInternal.overlayName);
checkPackageName(overlayInternal.packageName);
- Preconditions.checkStringNotEmpty(overlayInternal.targetPackageName);
+ checkPackageName(overlayInternal.targetPackageName);
+ Preconditions.checkStringNotEmpty(
+ overlayInternal.targetOverlayable,
+ "Target overlayable should be neither null nor empty string.");
final ApplicationInfo applicationInfo = mContext.getApplicationInfo();
- String targetPackage = null;
- if (TextUtils.equals(overlayInternal.targetPackageName, "android")) {
- targetPackage = AssetManager.FRAMEWORK_APK_PATH;
- } else {
- targetPackage = Preconditions.checkStringNotEmpty(
- applicationInfo.getBaseCodePath());
- }
-
+ final String targetPackage = Preconditions.checkStringNotEmpty(
+ applicationInfo.getBaseCodePath());
final Path frroPath = mBasePath.resolve(overlayName + FRRO_EXTENSION);
final Path idmapPath = mBasePath.resolve(overlayName + IDMAP_EXTENSION);
diff --git a/core/java/com/android/internal/jank/FrameTracker.java b/core/java/com/android/internal/jank/FrameTracker.java
index 0af4bea70e65..44c0bd01d545 100644
--- a/core/java/com/android/internal/jank/FrameTracker.java
+++ b/core/java/com/android/internal/jank/FrameTracker.java
@@ -54,6 +54,7 @@ import com.android.internal.util.FrameworkStatsLog;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.List;
import java.util.concurrent.TimeUnit;
/**
@@ -448,7 +449,7 @@ public class FrameTracker implements HardwareRendererObserver.OnFrameMetricsAvai
}
@Override
- public void onJankDataAvailable(SurfaceControl.JankData[] jankData) {
+ public void onJankDataAvailable(List<SurfaceControl.JankData> jankData) {
postCallback(() -> {
try {
Trace.beginSection("FrameTracker#onJankDataAvailable");
@@ -832,7 +833,7 @@ public class FrameTracker implements HardwareRendererObserver.OnFrameMetricsAvai
/** adds the jank listener to the given surface */
public SurfaceControl.OnJankDataListenerRegistration addJankStatsListener(
SurfaceControl.OnJankDataListener listener, SurfaceControl surfaceControl) {
- return surfaceControl.addJankDataListener(listener);
+ return surfaceControl.addOnJankDataListener(listener);
}
}
diff --git a/core/java/com/android/server/FgThread.java b/core/java/com/android/server/FgThread.java
index f54ee5e70265..f8a6bb06798e 100644
--- a/core/java/com/android/server/FgThread.java
+++ b/core/java/com/android/server/FgThread.java
@@ -33,6 +33,7 @@ import java.util.concurrent.Executor;
*
* @hide
*/
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
public final class FgThread extends ServiceThread {
private static final long SLOW_DISPATCH_THRESHOLD_MS = 100;
private static final long SLOW_DELIVERY_THRESHOLD_MS = 200;
diff --git a/core/java/com/android/server/ServiceThread.java b/core/java/com/android/server/ServiceThread.java
index 0eff1fca1e25..86e507b76771 100644
--- a/core/java/com/android/server/ServiceThread.java
+++ b/core/java/com/android/server/ServiceThread.java
@@ -27,6 +27,7 @@ import android.os.StrictMode;
*
* @hide
*/
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
public class ServiceThread extends HandlerThread {
private static final String TAG = "ServiceThread";
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 2283b88e5d97..2bb6e71e9000 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -105,18 +105,7 @@ cc_library_shared_for_libandroid_runtime {
],
shared_libs: [
- "libbase",
- "libcutils",
"libtracing_perfetto",
- "libharfbuzz_ng",
- "liblog",
- "libmediautils",
- "libminikin",
- "libz",
- "server_configurable_flags",
- "libaconfig_storage_read_api_cc",
- "android.database.sqlite-aconfig-cc",
- "android.media.audiopolicy-aconfig-cc",
],
static_libs: [
@@ -303,6 +292,14 @@ cc_library_shared_for_libandroid_runtime {
],
shared_libs: [
+ "libbase",
+ "libharfbuzz_ng",
+ "liblog",
+ "libmediautils",
+ "libminikin",
+ "libz",
+ "android.database.sqlite-aconfig-cc",
+ "android.media.audiopolicy-aconfig-cc",
"audioclient-types-aidl-cpp",
"audioflinger-aidl-cpp",
"audiopolicy-types-aidl-cpp",
@@ -412,20 +409,24 @@ cc_library_shared_for_libandroid_runtime {
"frameworks/native/libs/nativebase/include",
"frameworks/native/libs/nativewindow/include",
],
- shared_libs: [
- "libicui18n",
- "libicuuc",
- ],
static_libs: [
"libandroidfw",
+ "libbase",
"libbinary_parse",
+ "libcutils",
"libdng_sdk",
"libft2",
+ "libharfbuzz_ng",
"libhostgraphics",
"libhwui",
+ "libicui18n",
+ "libicuuc",
+ "libicuuc_stubdata",
"libimage_type_recognition",
"libinput",
"libjpeg",
+ "liblog",
+ "libminikin",
"libnativehelper_jvm",
"libpiex",
"libpng",
@@ -435,11 +436,18 @@ cc_library_shared_for_libandroid_runtime {
"libwebp-decode",
"libwebp-encode",
"libwuffs_mirror_release_c",
+ "libz",
"libimage_io",
"libjpegdecoder",
"libjpegencoder",
"libultrahdr",
+ "server_configurable_flags",
+ ],
+ export_static_lib_headers: [
+ "libnativehelper_jvm",
+ "libui-types",
],
+ stl: "libc++_static",
},
host_linux: {
srcs: [
@@ -465,14 +473,18 @@ cc_library_shared_for_libandroid_runtime {
"libbinderthreadstateutils",
"libsqlite",
"libgui_window_info_static",
- ],
- shared_libs: [
- // libbinder needs to be shared since it has global state
- // (e.g. gDefaultServiceManager)
"libbinder",
"libhidlbase", // libhwbinder is in here
],
},
+ linux_glibc_x86_64: {
+ ldflags: ["-static-libgcc"],
+ dist: {
+ targets: ["layoutlib"],
+ dir: "layoutlib_native/linux",
+ tag: "stripped_all",
+ },
+ },
},
}
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 7fefe1755fa9..df87a69f02ce 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -298,6 +298,11 @@ static struct {
jmethodID ctor;
} gFrameRateCategoryRateClassInfo;
+static struct {
+ jclass clazz;
+ jmethodID asList;
+} gUtilArrays;
+
constexpr ui::Dataspace pickDataspaceFromColorMode(const ui::ColorMode colorMode) {
switch (colorMode) {
case ui::ColorMode::DISPLAY_P3:
@@ -2206,10 +2211,13 @@ public:
env->SetObjectArrayElement(jJankDataArray, i, jJankData);
env->DeleteLocalRef(jJankData);
}
- env->CallVoidMethod(target,
- gJankDataListenerClassInfo.onJankDataAvailable,
- jJankDataArray);
+
+ jobject jJankDataList =
+ env->CallStaticObjectMethod(gUtilArrays.clazz, gUtilArrays.asList, jJankDataArray);
env->DeleteLocalRef(jJankDataArray);
+
+ env->CallVoidMethod(target, gJankDataListenerClassInfo.onJankDataAvailable, jJankDataList);
+ env->DeleteLocalRef(jJankDataList);
env->DeleteLocalRef(target);
return true;
@@ -2858,7 +2866,7 @@ int register_android_view_SurfaceControl(JNIEnv* env)
gJankDataListenerClassInfo.clazz = MakeGlobalRefOrDie(env, onJankDataListenerClazz);
gJankDataListenerClassInfo.onJankDataAvailable =
GetMethodIDOrDie(env, onJankDataListenerClazz, "onJankDataAvailable",
- "([Landroid/view/SurfaceControl$JankData;)V");
+ "(Ljava/util/List;)V");
jclass transactionCommittedListenerClazz =
FindClassOrDie(env, "android/view/SurfaceControl$TransactionCommittedListener");
@@ -2933,6 +2941,10 @@ int register_android_view_SurfaceControl(JNIEnv* env)
gStalledTransactionInfoClassInfo.frameNumber =
GetFieldIDOrDie(env, stalledTransactionInfoClazz, "frameNumber", "J");
+ jclass utilArrays = FindClassOrDie(env, "java/util/Arrays");
+ gUtilArrays.clazz = MakeGlobalRefOrDie(env, utilArrays);
+ gUtilArrays.asList = GetStaticMethodIDOrDie(env, utilArrays, "asList",
+ "([Ljava/lang/Object;)Ljava/util/List;");
return err;
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 97682c8137eb..5044a300cc8e 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -8535,10 +8535,14 @@
@hide
-->
<permission
- android:name="android.permission.RECEIVE_PACKAGE_CHANGED_BROADCAST_ON_COMPONENT_STATE_CHANGED"
+ android:name="android.permission.INTERNAL_RECEIVE_PACKAGE_CHANGED_BROADCAST_ON_COMPONENT_STATE_CHANGED"
android:protectionLevel="internal"
android:featureFlag="android.content.pm.reduce_broadcasts_for_component_state_changes"/>
+ <uses-permission
+ android:name="android.permission.INTERNAL_RECEIVE_PACKAGE_CHANGED_BROADCAST_ON_COMPONENT_STATE_CHANGED"
+ android:featureFlag="android.content.pm.reduce_broadcasts_for_component_state_changes"/>
+
<!-- Attribution for Geofencing service. -->
<attribution android:tag="GeofencingService" android:label="@string/geofencing_service"/>
<!-- Attribution for Country Detector. -->
diff --git a/core/res/res/layout/app_language_picker_current_locale_item.xml b/core/res/res/layout/app_language_picker_locale_item.xml
index edd6d648ea99..bcad9ce751bc 100644
--- a/core/res/res/layout/app_language_picker_current_locale_item.xml
+++ b/core/res/res/layout/app_language_picker_locale_item.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- ~ Copyright (C) 2022 The Android Open Source Project
+ ~ 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.
@@ -20,10 +20,27 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical">
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:gravity="center"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ android:layout_marginStart="20dip">
+
+ <RadioButton
+ android:id="@+id/checkbox"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:background="@null"
+ android:focusable="false"
+ android:clickable="false" />
+
+ </LinearLayout>
+
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginEnd="6dip"
android:layout_marginTop="6dip"
android:layout_marginBottom="6dip"
android:layout_weight="1">
@@ -31,20 +48,4 @@
android:id="@+id/language_picker_item"
layout="@layout/language_picker_item" />
</RelativeLayout>
-
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:gravity="center"
- android:minHeight="?android:attr/listPreferredItemHeight">
- <ImageView
- android:id="@+id/imageView"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_centerVertical="true"
- android:layout_marginHorizontal="16dp"
- android:src="@drawable/ic_check_24dp"
- app:tint="?attr/colorAccentPrimaryVariant"
- android:contentDescription="@*android:string/checked"/>
- </LinearLayout>
</LinearLayout>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index ef420eb0a35a..3fac7360c8f2 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -1943,8 +1943,7 @@
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Off"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> to <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Any calendar"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> is muting some sounds"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"There\'s an internal problem with your device, and it may be unstable until you factory data reset."</string>
@@ -2426,14 +2425,10 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Send and receive messages without a mobile or Wi-Fi network"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Open Messages"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"How it works"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"Turn on \"Automatically select network\""</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"Turn on \"Automatically select network\" in Settings so your phone can find a network that works with satellite"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Turn on"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Go back"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Pending..."</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Set up Fingerprint Unlock again"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> can no longer be recognized."</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 051c61a26373..4070f1160aec 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -1944,8 +1944,7 @@
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Off"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"Da <xliff:g id="START">%1$s</xliff:g> a <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Qualsiasi calendario"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> sta disattivando alcuni suoni"</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Si è verificato un problema interno con il dispositivo, che potrebbe essere instabile fino al ripristino dei dati di fabbrica."</string>
@@ -2427,14 +2426,10 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Invia e ricevi messaggi senza una rete mobile o Wi-Fi"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Apri Messaggi"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Come funziona"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"Attiva \"Seleziona rete automaticamente\""</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"Attiva \"Seleziona rete automaticamente\" nelle Impostazioni in modo che lo smartphone possa trovare una rete compatibile con il satellite"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Attiva"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Indietro"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"In attesa…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Riconfigura lo Sblocco con l\'Impronta"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> non può più essere riconosciuto."</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 2fea96252ebc..5684d780be8f 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -590,7 +590,7 @@
<string name="permdesc_changeWifiMulticastState" product="default" msgid="8296627590220222740">"तपाईँको फोन मात्र होइन, मल्टिकास्ट ठेगानाहरूको प्रयोग गरे Wi-Fi नेटवर्कका सबै उपकरणहरूमा पठाइएका प्याकेटहरू प्राप्त गर्न एपलाई अनुमति दिन्छ। यसले गैर-मल्टिकास्ट मोडभन्दा बढी उर्जा प्रयोग गर्छ।"</string>
<string name="permlab_bluetoothAdmin" msgid="6490373569441946064">"ब्लुटुथ सेटिङहरूमा पहुँच गर्नुहोस्"</string>
<string name="permdesc_bluetoothAdmin" product="tablet" msgid="5370837055438574863">"स्थानीय ब्लुटुथ ट्याब्लेटलाई कन्फिगर गर्नको लागि र टाढाका उपकरणहरूलाई पत्ता लगाउन र जोड्नको लागि एपलाई अनुमति दिन्छ।"</string>
- <string name="permdesc_bluetoothAdmin" product="tv" msgid="1623992984547014588">"एपलाई तपाईंको Android टिभी डिभाइसको ब्लुटुथ कन्फिगर गर्ने तथा टाढा रहेका यन्त्रहरू पत्ता लगाई ती यन्त्रहरूसँग जोडा बनाउने अनुमति दिन्छ।"</string>
+ <string name="permdesc_bluetoothAdmin" product="tv" msgid="1623992984547014588">"एपलाई तपाईंको Android टिभी डिभाइसको ब्लुटुथ कन्फिगर गर्ने तथा टाढा रहेका यन्त्रहरू पत्ता लगाई ती यन्त्रहरूसँग कनेक्ट गर्ने अनुमति दिन्छ।"</string>
<string name="permdesc_bluetoothAdmin" product="default" msgid="7381341743021234863">"एपलाई स्थानीय ब्लुटुथ फोन कन्फिगर गर्न र टाढाका उपकरणहरूसँग खोज गर्न र जोडी गर्न अनुमति दिन्छ।"</string>
<string name="permlab_accessWimaxState" msgid="7029563339012437434">"WiMAXसँग जोड्नुहोस् वा छुटाउनुहोस्"</string>
<string name="permdesc_accessWimaxState" msgid="5372734776802067708">"एपलाई वाइम्याक्स सक्षम छ कि छैन र जडान भएको कुनै पनि वाइम्याक्स नेटवर्कहरूको बारेमा जानकारी निर्धारिण गर्न अनुमति दिन्छ।"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 388c5a9077ae..86e0fcdad8a1 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -1944,8 +1944,7 @@
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Desativada"</string>
<string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
<string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
- <!-- no translation found for zen_mode_trigger_summary_range_words (7228261413029290750) -->
- <skip />
+ <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
<string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Qualquer calendário"</string>
<string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> está a desativar alguns sons."</string>
<string name="system_error_wipe_data" msgid="5910572292172208493">"Existe um problema interno no seu dispositivo e pode ficar instável até efetuar uma reposição de dados de fábrica."</string>
@@ -2427,14 +2426,10 @@
<string name="satellite_notification_manual_summary" msgid="901206289846283445">"Envie e receba mensagens sem uma rede móvel ou Wi-Fi"</string>
<string name="satellite_notification_open_message" msgid="4149234979688273729">"Abre a app Mensagens"</string>
<string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Como funciona"</string>
- <!-- no translation found for satellite_manual_selection_state_popup_title (8545991934926661974) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_message (1928101658551382450) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_ok (2459664752624985095) -->
- <skip />
- <!-- no translation found for satellite_manual_selection_state_popup_cancel (973605633339469252) -->
- <skip />
+ <string name="satellite_manual_selection_state_popup_title" msgid="8545991934926661974">"Ative a opção \"Selecionar rede automaticamente\""</string>
+ <string name="satellite_manual_selection_state_popup_message" msgid="1928101658551382450">"Ative a opção \"Selecionar rede automaticamente\" nas Definições para que o telemóvel possa encontrar uma rede que funcione com o satélite"</string>
+ <string name="satellite_manual_selection_state_popup_ok" msgid="2459664752624985095">"Ativar"</string>
+ <string name="satellite_manual_selection_state_popup_cancel" msgid="973605633339469252">"Retroceder"</string>
<string name="unarchival_session_app_label" msgid="6811856981546348205">"Pendente…"</string>
<string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Configure o Desbloqueio por impressão digital novamente"</string>
<string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"Já não é possível reconhecer <xliff:g id="FINGERPRINT">%s</xliff:g>."</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 492dca723c21..1d9e00c012bb 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -1937,7 +1937,7 @@
<string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"వారపు రోజుల్లో రాత్రి"</string>
<string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"వారాంతం"</string>
<string name="zen_mode_default_events_name" msgid="2280682960128512257">"ఈవెంట్"</string>
- <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"నిద్ర"</string>
+ <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"స్లీప్ మోడ్"</string>
<string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"<xliff:g id="APP_NAME">%1$s</xliff:g> ద్వారా మేనేజ్ చేయబడుతోంది"</string>
<string name="zen_mode_implicit_activated" msgid="2634285680776672994">"ఆన్‌లో ఉంది"</string>
<string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"ఆఫ్‌లో ఉంది"</string>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index d750ff6623f2..4c9da6959fe2 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -3486,6 +3486,12 @@
representation this attribute can be used for providing such. -->
<attr name="contentDescription" format="string" localization="suggested" />
+ <!-- Provides brief supplemental information for the view, such as the purpose of
+ the view when that purpose is not conveyed within its textual representation.
+ This property is used primarily for accessibility. -->
+ <!-- @FlaggedApi("android.view.accessibility.supplemental_description") -->
+ <attr name="supplementalDescription" format="string" localization="suggested" />
+
<!-- Sets the id of a view that screen readers are requested to visit after this view.
Requests that a screen-reader visits the content of this view before the content of the
one it precedes. This does nothing if either view is not important for accessibility.
diff --git a/core/res/res/values/public-staging.xml b/core/res/res/values/public-staging.xml
index 81215453b3ef..09dc08420a01 100644
--- a/core/res/res/values/public-staging.xml
+++ b/core/res/res/values/public-staging.xml
@@ -121,6 +121,8 @@
<!-- @FlaggedApi("android.permission.flags.replace_body_sensor_permission_enabled")
@hide @SystemApi -->
<public name="backgroundPermission"/>
+ <!-- @FlaggedApi(android.view.accessibility.supplemental_description) -->
+ <public name="supplementalDescription"/>
</staging-public-group>
<staging-public-group type="id" first-id="0x01b60000">
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index b32d4cf17cf5..515ebd54b5eb 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -5264,7 +5264,7 @@
<java-symbol type="string" name="system_locale_title" />
<java-symbol type="layout" name="app_language_picker_system_default" />
<java-symbol type="layout" name="app_language_picker_system_current" />
- <java-symbol type="layout" name="app_language_picker_current_locale_item" />
+ <java-symbol type="layout" name="app_language_picker_locale_item" />
<java-symbol type="id" name="system_locale_subtitle" />
<java-symbol type="id" name="language_picker_item" />
<java-symbol type="id" name="language_picker_header" />
diff --git a/core/tests/coretests/src/android/view/accessibility/AccessibilityNodeInfoTest.java b/core/tests/coretests/src/android/view/accessibility/AccessibilityNodeInfoTest.java
index 930e03dfd6db..bef65d42ba79 100644
--- a/core/tests/coretests/src/android/view/accessibility/AccessibilityNodeInfoTest.java
+++ b/core/tests/coretests/src/android/view/accessibility/AccessibilityNodeInfoTest.java
@@ -46,7 +46,7 @@ public class AccessibilityNodeInfoTest {
// The number of fields tested in the corresponding CTS AccessibilityNodeInfoTest:
// See fullyPopulateAccessibilityNodeInfo, assertEqualsAccessibilityNodeInfo,
// and assertAccessibilityNodeInfoCleared in that class.
- private static final int NUM_MARSHALLED_PROPERTIES = 46;
+ private static final int NUM_MARSHALLED_PROPERTIES = 47;
/**
* The number of properties that are purposely not marshalled
diff --git a/core/tests/coretests/src/com/android/internal/jank/FrameTrackerTest.java b/core/tests/coretests/src/com/android/internal/jank/FrameTrackerTest.java
index 60b5a422ea80..e7a6cb7291c5 100644
--- a/core/tests/coretests/src/com/android/internal/jank/FrameTrackerTest.java
+++ b/core/tests/coretests/src/com/android/internal/jank/FrameTrackerTest.java
@@ -67,6 +67,7 @@ import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
+import java.util.Arrays;
import java.util.concurrent.TimeUnit;
@SmallTest
@@ -690,10 +691,9 @@ public class FrameTrackerTest {
FrameTracker tracker, long durationMillis, long vsyncId, @JankType int jankType) {
final ArgumentCaptor<Runnable> captor = ArgumentCaptor.forClass(Runnable.class);
doNothing().when(tracker).postCallback(captor.capture());
- mListenerCapture.getValue().onJankDataAvailable(new JankData[] {
- new JankData(vsyncId, jankType, FRAME_TIME_60Hz, FRAME_TIME_60Hz,
- TimeUnit.MILLISECONDS.toNanos(durationMillis))
- });
+ mListenerCapture.getValue().onJankDataAvailable(Arrays.asList(new JankData(
+ vsyncId, jankType, FRAME_TIME_60Hz, FRAME_TIME_60Hz,
+ TimeUnit.MILLISECONDS.toNanos(durationMillis))));
captor.getValue().run();
}
}
diff --git a/core/tests/overlaytests/device_self_targeting/src/com/android/overlaytest/OverlayManagerImplTest.java b/core/tests/overlaytests/device_self_targeting/src/com/android/overlaytest/OverlayManagerImplTest.java
index 28d6545c8a5b..40d0bef2fb0f 100644
--- a/core/tests/overlaytests/device_self_targeting/src/com/android/overlaytest/OverlayManagerImplTest.java
+++ b/core/tests/overlaytests/device_self_targeting/src/com/android/overlaytest/OverlayManagerImplTest.java
@@ -210,6 +210,21 @@ public class OverlayManagerImplTest {
}
@Test
+ public void registerOverlay_forAndroidPackage_shouldFail() {
+ FabricatedOverlayInternal overlayInternal =
+ createOverlayWithName(
+ mOverlayName,
+ SYSTEM_APP_OVERLAYABLE,
+ "android",
+ List.of(Pair.create("color/white", Pair.create(null, Color.BLACK))));
+
+ assertThrows(
+ "Wrong target package name",
+ IllegalArgumentException.class,
+ () -> mOverlayManagerImpl.registerFabricatedOverlay(overlayInternal));
+ }
+
+ @Test
public void getOverlayInfosForTarget_defaultShouldBeZero() {
List<OverlayInfo> overlayInfos =
mOverlayManagerImpl.getOverlayInfosForTarget(mContext.getPackageName());
diff --git a/graphics/java/android/graphics/RenderNode.java b/graphics/java/android/graphics/RenderNode.java
index 211f74a47bdd..03a8b306f99d 100644
--- a/graphics/java/android/graphics/RenderNode.java
+++ b/graphics/java/android/graphics/RenderNode.java
@@ -279,7 +279,8 @@ public final class RenderNode {
* @hide
*/
default void positionChanged(long frameNumber, int left, int top, int right, int bottom,
- int clipLeft, int clipTop, int clipRight, int clipBottom) {
+ int clipLeft, int clipTop, int clipRight, int clipBottom,
+ int nodeWidth, int nodeHeight) {
positionChanged(frameNumber, left, top, right, bottom);
}
@@ -304,11 +305,12 @@ public final class RenderNode {
* @hide */
static boolean callPositionChanged2(WeakReference<PositionUpdateListener> weakListener,
long frameNumber, int left, int top, int right, int bottom,
- int clipLeft, int clipTop, int clipRight, int clipBottom) {
+ int clipLeft, int clipTop, int clipRight, int clipBottom,
+ int nodeWidth, int nodeHeight) {
final PositionUpdateListener listener = weakListener.get();
if (listener != null) {
listener.positionChanged(frameNumber, left, top, right, bottom, clipLeft,
- clipTop, clipRight, clipBottom);
+ clipTop, clipRight, clipBottom, nodeWidth, nodeHeight);
return true;
} else {
return false;
@@ -401,10 +403,11 @@ public final class RenderNode {
@Override
public void positionChanged(long frameNumber, int left, int top, int right, int bottom,
- int clipLeft, int clipTop, int clipRight, int clipBottom) {
+ int clipLeft, int clipTop, int clipRight, int clipBottom,
+ int nodeWidth, int nodeHeight) {
for (PositionUpdateListener pul : mListeners) {
pul.positionChanged(frameNumber, left, top, right, bottom, clipLeft, clipTop,
- clipRight, clipBottom);
+ clipRight, clipBottom, nodeWidth, nodeHeight);
}
}
diff --git a/graphics/java/android/graphics/RuntimeColorFilter.java b/graphics/java/android/graphics/RuntimeColorFilter.java
new file mode 100644
index 000000000000..52724ceaf301
--- /dev/null
+++ b/graphics/java/android/graphics/RuntimeColorFilter.java
@@ -0,0 +1,305 @@
+/*
+ * Copyright 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.graphics;
+
+import android.annotation.ColorInt;
+import android.annotation.ColorLong;
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
+
+import com.android.graphics.hwui.flags.Flags;
+
+
+/**
+ * <p>A {@link RuntimeColorFilter} calculates a per-pixel color based on the output of a user
+ * * defined Android Graphics Shading Language (AGSL) function.</p>
+ *
+ * <p>This AGSL function takes in an input color to be operated on. This color is in sRGB and the
+ * * output is also interpreted as sRGB. The AGSL function signature expects a single input
+ * * of color (packed as a half4 or float4 or vec4).</p>
+ *
+ * <pre class="prettyprint">
+ * vec4 main(half4 in_color);
+ * </pre>
+ */
+@FlaggedApi(Flags.FLAG_RUNTIME_COLOR_FILTERS_BLENDERS)
+public class RuntimeColorFilter extends ColorFilter {
+
+ private String mAgsl;
+
+ /**
+ * Creates a new RuntimeColorFilter.
+ *
+ * @param agsl The text of AGSL color filter program to run.
+ */
+ public RuntimeColorFilter(@NonNull String agsl) {
+ if (agsl == null) {
+ throw new NullPointerException("RuntimeColorFilter requires a non-null AGSL string");
+ }
+ mAgsl = agsl;
+ // call to parent class to register native RuntimeColorFilter
+ // TODO: find way to get super class to create native instance without requiring the storage
+ // of agsl string
+ getNativeInstance();
+
+ }
+ /**
+ * Sets the uniform color value corresponding to this color filter. If the effect does not have
+ * a uniform with that name or if the uniform is declared with a type other than vec3 or vec4
+ * and corresponding layout(color) annotation then an IllegalArgumentException is thrown.
+ *
+ * @param uniformName name matching the color uniform declared in the AGSL program
+ * @param color the provided sRGB color
+ */
+ public void setColorUniform(@NonNull String uniformName, @ColorInt int color) {
+ setUniform(uniformName, Color.valueOf(color).getComponents(), true);
+ }
+
+ /**
+ * Sets the uniform color value corresponding to this color filter. If the effect does not have
+ * a uniform with that name or if the uniform is declared with a type other than vec3 or vec4
+ * and corresponding layout(color) annotation then an IllegalArgumentException is thrown.
+ *
+ * @param uniformName name matching the color uniform declared in the AGSL program
+ * @param color the provided sRGB color
+ */
+ public void setColorUniform(@NonNull String uniformName, @ColorLong long color) {
+ Color exSRGB = Color.valueOf(color).convert(ColorSpace.get(ColorSpace.Named.EXTENDED_SRGB));
+ setUniform(uniformName, exSRGB.getComponents(), true);
+ }
+
+ /**
+ * Sets the uniform color value corresponding to this color filter. If the effect does not have
+ * a uniform with that name or if the uniform is declared with a type other than vec3 or vec4
+ * and corresponding layout(color) annotation then an IllegalArgumentException is thrown.
+ *
+ * @param uniformName name matching the color uniform declared in the AGSL program
+ * @param color the provided sRGB color
+ */
+ public void setColorUniform(@NonNull String uniformName, @NonNull Color color) {
+ if (color == null) {
+ throw new NullPointerException("The color parameter must not be null");
+ }
+ Color exSRGB = color.convert(ColorSpace.get(ColorSpace.Named.EXTENDED_SRGB));
+ setUniform(uniformName, exSRGB.getComponents(), true);
+ }
+
+ /**
+ * Sets the uniform value corresponding to this color filter. If the effect does not have a
+ * uniform with that name or if the uniform is declared with a type other than a float or
+ * float[1] then an IllegalArgumentException is thrown.
+ *
+ * @param uniformName name matching the uniform declared in the AGSL program
+ */
+ public void setFloatUniform(@NonNull String uniformName, float value) {
+ setFloatUniform(uniformName, value, 0.0f, 0.0f, 0.0f, 1);
+ }
+
+ /**
+ * Sets the uniform value corresponding to this color filter. If the effect does not have a
+ * uniform with that name or if the uniform is declared with a type other than a vec2 or
+ * float[2] then an IllegalArgumentException is thrown.
+ *
+ * @param uniformName name matching the uniform declared in the AGSL program
+ */
+ public void setFloatUniform(@NonNull String uniformName, float value1, float value2) {
+ setFloatUniform(uniformName, value1, value2, 0.0f, 0.0f, 2);
+ }
+
+ /**
+ * Sets the uniform value corresponding to this color filter. If the effect does not have a
+ * uniform with that name or if the uniform is declared with a type other than a vec3 or
+ * float[3] then an IllegalArgumentException is thrown.
+ *
+ * @param uniformName name matching the uniform declared in the AGSL program
+ */
+ public void setFloatUniform(@NonNull String uniformName, float value1, float value2,
+ float value3) {
+ setFloatUniform(uniformName, value1, value2, value3, 0.0f, 3);
+
+ }
+
+ /**
+ * Sets the uniform value corresponding to this color filter. If the effect does not have a
+ * uniform with that name or if the uniform is declared with a type other than a vec4 or
+ * float[4] then an IllegalArgumentException is thrown.
+ *
+ * @param uniformName name matching the uniform declared in the AGSL program
+ */
+ public void setFloatUniform(@NonNull String uniformName, float value1, float value2,
+ float value3, float value4) {
+ setFloatUniform(uniformName, value1, value2, value3, value4, 4);
+ }
+
+ /**
+ * Sets the uniform value corresponding to this color filter. If the effect does not have a
+ * uniform with that name or if the uniform is declared with a type other than a float
+ * (for N=1), vecN, or float[N] where N is the length of the values param then an
+ * IllegalArgumentException is thrown.
+ *
+ * @param uniformName name matching the uniform declared in the AGSL program
+ */
+ public void setFloatUniform(@NonNull String uniformName, @NonNull float[] values) {
+ setUniform(uniformName, values, false);
+ }
+
+ private void setFloatUniform(@NonNull String uniformName, float value1, float value2,
+ float value3, float value4, int count) {
+ if (uniformName == null) {
+ throw new NullPointerException("The uniformName parameter must not be null");
+ }
+ nativeUpdateUniforms(getNativeInstance(), uniformName, value1, value2, value3, value4,
+ count);
+ }
+
+ private void setUniform(@NonNull String uniformName, @NonNull float[] values, boolean isColor) {
+ if (uniformName == null) {
+ throw new NullPointerException("The uniformName parameter must not be null");
+ }
+ if (values == null) {
+ throw new NullPointerException("The uniform values parameter must not be null");
+ }
+ nativeUpdateUniforms(getNativeInstance(), uniformName, values, isColor);
+ }
+
+ /**
+ * Sets the uniform value corresponding to this color filter. If the effect does not have a
+ * uniform with that name or if the uniform is declared with a type other than an int or int[1]
+ * then an IllegalArgumentException is thrown.
+ *
+ * @param uniformName name matching the uniform declared in the AGSL program
+ */
+ public void setIntUniform(@NonNull String uniformName, int value) {
+ setIntUniform(uniformName, value, 0, 0, 0, 1);
+ }
+
+ /**
+ * Sets the uniform value corresponding to this color filter. If the effect does not have a
+ * uniform with that name or if the uniform is declared with a type other than an ivec2 or
+ * int[2] then an IllegalArgumentException is thrown.
+ *
+ * @param uniformName name matching the uniform declared in the AGSL program
+ */
+ public void setIntUniform(@NonNull String uniformName, int value1, int value2) {
+ setIntUniform(uniformName, value1, value2, 0, 0, 2);
+ }
+
+ /**
+ * Sets the uniform value corresponding to this color filter. If the effect does not have a
+ * uniform with that name or if the uniform is declared with a type other than an ivec3 or
+ * int[3] then an IllegalArgumentException is thrown.
+ *
+ * @param uniformName name matching the uniform declared in the AGSL program
+ */
+ public void setIntUniform(@NonNull String uniformName, int value1, int value2, int value3) {
+ setIntUniform(uniformName, value1, value2, value3, 0, 3);
+ }
+
+ /**
+ * Sets the uniform value corresponding to this color filter. If the effect does not have a
+ * uniform with that name or if the uniform is declared with a type other than an ivec4 or
+ * int[4] then an IllegalArgumentException is thrown.
+ *
+ * @param uniformName name matching the uniform declared in the AGSL program
+ */
+ public void setIntUniform(@NonNull String uniformName, int value1, int value2,
+ int value3, int value4) {
+ setIntUniform(uniformName, value1, value2, value3, value4, 4);
+ }
+
+ /**
+ * Sets the uniform value corresponding to this color filter. If the effect does not have a
+ * uniform with that name or if the uniform is declared with a type other than an int (for N=1),
+ * ivecN, or int[N] where N is the length of the values param then an IllegalArgumentException
+ * is thrown.
+ *
+ * @param uniformName name matching the uniform declared in the AGSL program
+ */
+ public void setIntUniform(@NonNull String uniformName, @NonNull int[] values) {
+ if (uniformName == null) {
+ throw new NullPointerException("The uniformName parameter must not be null");
+ }
+ if (values == null) {
+ throw new NullPointerException("The uniform values parameter must not be null");
+ }
+ nativeUpdateUniforms(getNativeInstance(), uniformName, values);
+ }
+
+ private void setIntUniform(@NonNull String uniformName, int value1, int value2, int value3,
+ int value4, int count) {
+ if (uniformName == null) {
+ throw new NullPointerException("The uniformName parameter must not be null");
+ }
+ nativeUpdateUniforms(getNativeInstance(), uniformName, value1, value2, value3, value4,
+ count);
+ }
+
+ /**
+ * Assigns the uniform shader to the provided shader parameter. If the shader program does not
+ * have a uniform shader with that name then an IllegalArgumentException is thrown.
+ *
+ * @param shaderName name matching the uniform declared in the AGSL program
+ * @param shader shader passed into the AGSL program for sampling
+ */
+ public void setInputShader(@NonNull String shaderName, @NonNull Shader shader) {
+ if (shaderName == null) {
+ throw new NullPointerException("The shaderName parameter must not be null");
+ }
+ if (shader == null) {
+ throw new NullPointerException("The shader parameter must not be null");
+ }
+ nativeUpdateChild(getNativeInstance(), shaderName, shader.getNativeInstance());
+ }
+
+ /**
+ * Assigns the uniform color filter to the provided color filter parameter. If the shader
+ * program does not have a uniform color filter with that name then an IllegalArgumentException
+ * is thrown.
+ *
+ * @param filterName name matching the uniform declared in the AGSL program
+ * @param colorFilter filter passed into the AGSL program for sampling
+ */
+ public void setInputColorFilter(@NonNull String filterName, @NonNull ColorFilter colorFilter) {
+ if (filterName == null) {
+ throw new NullPointerException("The filterName parameter must not be null");
+ }
+ if (colorFilter == null) {
+ throw new NullPointerException("The colorFilter parameter must not be null");
+ }
+ nativeUpdateChild(getNativeInstance(), filterName, colorFilter.getNativeInstance());
+ }
+
+ /** @hide */
+ @Override
+ protected long createNativeInstance() {
+ return nativeCreateRuntimeColorFilter(mAgsl);
+ }
+
+ private static native long nativeCreateRuntimeColorFilter(String agsl);
+ private static native void nativeUpdateUniforms(
+ long colorFilter, String uniformName, float[] uniforms, boolean isColor);
+ private static native void nativeUpdateUniforms(
+ long colorFilter, String uniformName, float value1, float value2, float value3,
+ float value4, int count);
+ private static native void nativeUpdateUniforms(
+ long colorFilter, String uniformName, int[] uniforms);
+ private static native void nativeUpdateUniforms(
+ long colorFilter, String uniformName, int value1, int value2, int value3,
+ int value4, int count);
+ private static native void nativeUpdateChild(long colorFilter, String childName, long child);
+
+}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/DividerPresenter.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/DividerPresenter.java
index ad194f707cf3..6398c7a2f498 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/DividerPresenter.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/DividerPresenter.java
@@ -39,6 +39,7 @@ import static androidx.window.extensions.embedding.SplitPresenter.CONTAINER_POSI
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
+import android.annotation.ColorInt;
import android.annotation.Nullable;
import android.app.Activity;
import android.app.ActivityThread;
@@ -1394,10 +1395,14 @@ class DividerPresenter implements View.OnTouchListener {
}
private void showVeils(@NonNull SurfaceControl.Transaction t) {
- final Color primaryVeilColor = getContainerBackgroundColor(
- mProperties.mPrimaryContainer, DEFAULT_PRIMARY_VEIL_COLOR);
- final Color secondaryVeilColor = getContainerBackgroundColor(
- mProperties.mSecondaryContainer, DEFAULT_SECONDARY_VEIL_COLOR);
+ final Color primaryVeilColor = getVeilColor(
+ mProperties.mDividerAttributes.getPrimaryVeilColor(),
+ mProperties.mPrimaryContainer,
+ DEFAULT_PRIMARY_VEIL_COLOR);
+ final Color secondaryVeilColor = getVeilColor(
+ mProperties.mDividerAttributes.getSecondaryVeilColor(),
+ mProperties.mSecondaryContainer,
+ DEFAULT_SECONDARY_VEIL_COLOR);
t.setColor(mPrimaryVeil, colorToFloatArray(primaryVeilColor))
.setColor(mSecondaryVeil, colorToFloatArray(secondaryVeilColor))
.setLayer(mDividerSurface, DIVIDER_LAYER)
@@ -1444,6 +1449,21 @@ class DividerPresenter implements View.OnTouchListener {
}
}
+ /**
+ * Returns the veil color.
+ *
+ * If the configured color is not transparent, we use the configured color, otherwise we use
+ * the window background color of the top activity. If the background color of the top
+ * activity is unavailable, the default color is used.
+ */
+ @NonNull
+ private static Color getVeilColor(@ColorInt int configuredColor,
+ @NonNull TaskFragmentContainer container, @NonNull Color defaultColor) {
+ return configuredColor != Color.TRANSPARENT
+ ? Color.valueOf(configuredColor)
+ : getContainerBackgroundColor(container, defaultColor);
+ }
+
private static float[] colorToFloatArray(@NonNull Color color) {
return new float[]{color.red(), color.green(), color.blue()};
}
diff --git a/libs/WindowManager/Shell/multivalentScreenshotTests/Android.bp b/libs/WindowManager/Shell/multivalentScreenshotTests/Android.bp
index 61c09f2c396b..7f54c75929fb 100644
--- a/libs/WindowManager/Shell/multivalentScreenshotTests/Android.bp
+++ b/libs/WindowManager/Shell/multivalentScreenshotTests/Android.bp
@@ -22,42 +22,6 @@ package {
default_team: "trendy_team_multitasking_windowing",
}
-android_app {
- name: "WMShellRobolectricScreenshotTestApp",
- platform_apis: true,
- certificate: "platform",
- static_libs: [
- "WindowManager-Shell",
- "platform-screenshot-diff-core",
- "ScreenshotComposeUtilsLib", // ComposableScreenshotTestRule & Theme.PlatformUi.Screenshot
- "SystemUI-res", // Theme.SystemUI (dragged in by ScreenshotComposeUtilsLib)
- ],
- asset_dirs: ["goldens/robolectric"],
- manifest: "AndroidManifestRobolectric.xml",
- use_resource_processor: true,
-}
-
-android_robolectric_test {
- name: "WMShellRobolectricScreenshotTests",
- instrumentation_for: "WMShellRobolectricScreenshotTestApp",
- upstream: true,
- java_resource_dirs: [
- "robolectric/config",
- ],
- srcs: [
- "src/**/*.kt",
- ],
- static_libs: [
- "junit",
- "androidx.test.runner",
- "androidx.test.rules",
- "androidx.test.ext.junit",
- "truth",
- "platform-parametric-runner-lib",
- ],
- auto_gen_config: true,
-}
-
android_test {
name: "WMShellMultivalentScreenshotTestsOnDevice",
srcs: [
diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleStackViewTest.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleStackViewTest.kt
index 52ce8cb5c0dc..0b515f590f98 100644
--- a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleStackViewTest.kt
+++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleStackViewTest.kt
@@ -23,14 +23,15 @@ import android.content.res.Resources
import android.graphics.Color
import android.graphics.drawable.Icon
import android.os.UserHandle
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
import android.platform.test.flag.junit.SetFlagsRule
-import android.view.IWindowManager
import android.view.WindowManager
-import android.view.WindowManagerGlobal
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
+import com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn
import com.android.internal.logging.testing.UiEventLoggerFake
import com.android.internal.protolog.ProtoLog
import com.android.launcher3.icons.BubbleIconFactory
@@ -41,6 +42,7 @@ import com.android.wm.shell.bubbles.animation.AnimatableScaleMatrix
import com.android.wm.shell.common.FloatingContentCoordinator
import com.android.wm.shell.common.ShellExecutor
import com.android.wm.shell.shared.animation.PhysicsAnimatorTestUtils
+import com.android.wm.shell.shared.bubbles.BubbleBarLocation
import com.android.wm.shell.taskview.TaskView
import com.android.wm.shell.taskview.TaskViewTaskController
import com.google.common.truth.Truth.assertThat
@@ -51,9 +53,7 @@ import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.kotlin.mock
-import android.platform.test.annotations.DisableFlags
-import android.platform.test.annotations.EnableFlags
-import com.android.wm.shell.shared.bubbles.BubbleBarLocation
+import org.mockito.kotlin.verify
import java.util.concurrent.Semaphore
import java.util.concurrent.TimeUnit
import java.util.function.Consumer
@@ -72,7 +72,7 @@ class BubbleStackViewTest {
private lateinit var expandedViewManager: FakeBubbleExpandedViewManager
private lateinit var bubbleStackView: BubbleStackView
private lateinit var shellExecutor: ShellExecutor
- private lateinit var windowManager: IWindowManager
+ private lateinit var windowManager: WindowManager
private lateinit var bubbleTaskViewFactory: BubbleTaskViewFactory
private lateinit var bubbleData: BubbleData
private lateinit var bubbleStackViewManager: FakeBubbleStackViewManager
@@ -83,9 +83,8 @@ class BubbleStackViewTest {
PhysicsAnimatorTestUtils.prepareForTest()
// Disable protolog tool when running the tests from studio
ProtoLog.REQUIRE_PROTOLOGTOOL = false
- windowManager = WindowManagerGlobal.getWindowManagerService()!!
shellExecutor = TestShellExecutor()
- val windowManager = context.getSystemService(WindowManager::class.java)
+ windowManager = context.getSystemService(WindowManager::class.java)
iconFactory =
BubbleIconFactory(
context,
@@ -354,6 +353,16 @@ class BubbleStackViewTest {
assertThat(bubbleStackView.getBubbleIndex(bubbleOverflow)).isGreaterThan(-1)
}
+ @Test
+ fun removeFromWindow_stopMonitoringSwipeUpGesture() {
+ spyOn(bubbleStackView)
+ InstrumentationRegistry.getInstrumentation().runOnMainSync {
+ // No way to add to window in the test environment right now so just pretend
+ bubbleStackView.onDetachedFromWindow()
+ }
+ verify(bubbleStackView).stopMonitoringSwipeUpGesture()
+ }
+
private fun createAndInflateChatBubble(key: String): Bubble {
val icon = Icon.createWithResource(context.resources, R.drawable.bubble_ic_overflow_button)
val shortcutInfo = ShortcutInfo.Builder(context, "fakeId").setIcon(icon).build()
diff --git a/libs/WindowManager/Shell/res/values-ar/strings.xml b/libs/WindowManager/Shell/res/values-ar/strings.xml
index c36783f8f488..a8febc80ffc1 100644
--- a/libs/WindowManager/Shell/res/values-ar/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ar/strings.xml
@@ -133,10 +133,8 @@
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"تكبير الشاشة إلى أقصى حدّ"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"التقاط صورة للشاشة"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"لا يمكن نقل التطبيق إلى هنا"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"مجسَّم"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"استعادة"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"تكبير"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"استعادة"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"المحاذاة إلى اليسار"</string>
diff --git a/libs/WindowManager/Shell/res/values-as/strings.xml b/libs/WindowManager/Shell/res/values-as/strings.xml
index 71d95edccea6..8c924e342875 100644
--- a/libs/WindowManager/Shell/res/values-as/strings.xml
+++ b/libs/WindowManager/Shell/res/values-as/strings.xml
@@ -133,10 +133,8 @@
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"স্ক্ৰীন মেক্সিমাইজ কৰক"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"স্ক্ৰীন স্নেপ কৰক"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ইয়ালৈ এপ্‌টো আনিব নোৱাৰি"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"ইমাৰ্ছিভ"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"পুনঃস্থাপন কৰক"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"মেক্সিমাইজ কৰক"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"পুনঃস্থাপন কৰক"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"বাওঁফাললৈ স্নেপ কৰক"</string>
diff --git a/libs/WindowManager/Shell/res/values-bn/strings.xml b/libs/WindowManager/Shell/res/values-bn/strings.xml
index 4412497c3862..22a445f1754c 100644
--- a/libs/WindowManager/Shell/res/values-bn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bn/strings.xml
@@ -133,10 +133,8 @@
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"স্ক্রিন বড় করুন"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"স্ক্রিনে অ্যাপ মানানসই হিসেবে ছোট বড় করুন"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"অ্যাপটি এখানে সরানো যাবে না"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"ইমারসিভ"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"ফিরিয়ে আনুন"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"বড় করুন"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"ফিরিয়ে আনুন"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"বাঁদিকে স্ন্যাপ করুন"</string>
diff --git a/libs/WindowManager/Shell/res/values-bs/strings.xml b/libs/WindowManager/Shell/res/values-bs/strings.xml
index 674022be39a2..73f30d797883 100644
--- a/libs/WindowManager/Shell/res/values-bs/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bs/strings.xml
@@ -133,10 +133,8 @@
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimiziraj ekran"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Snimi ekran"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Ne možete premjestiti aplikaciju ovdje"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Interaktivno"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Vrati"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maksimiziranje"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Vraćanje"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Pomicanje ulijevo"</string>
diff --git a/libs/WindowManager/Shell/res/values-cs/strings.xml b/libs/WindowManager/Shell/res/values-cs/strings.xml
index fc6b679a3a09..6a5780e01822 100644
--- a/libs/WindowManager/Shell/res/values-cs/strings.xml
+++ b/libs/WindowManager/Shell/res/values-cs/strings.xml
@@ -133,10 +133,8 @@
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximalizovat obrazovku"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Rozpůlit obrazovku"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikaci sem nelze přesunout"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Pohlcující"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Obnovit"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maximalizovat"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Obnovit"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Přichytit vlevo"</string>
diff --git a/libs/WindowManager/Shell/res/values-el/strings.xml b/libs/WindowManager/Shell/res/values-el/strings.xml
index d06b46fb40d4..d02fae2a986d 100644
--- a/libs/WindowManager/Shell/res/values-el/strings.xml
+++ b/libs/WindowManager/Shell/res/values-el/strings.xml
@@ -133,10 +133,8 @@
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Μεγιστοποίηση οθόνης"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Προβολή στο μισό της οθόνης"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Δεν είναι δυνατή η μετακίνηση της εφαρμογής εδώ"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Καθηλωτικό"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Επαναφορά"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Μεγιστοποίηση"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Επαναφορά"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Κούμπωμα αριστερά"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
index c1a4244896c5..f9911451f4b5 100644
--- a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
@@ -133,10 +133,8 @@
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximise screen"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Snap screen"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"App can\'t be moved here"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Immersive"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Restore"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maximise"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Restore"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Snap left"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
index c1a4244896c5..f9911451f4b5 100644
--- a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
@@ -133,10 +133,8 @@
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximise screen"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Snap screen"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"App can\'t be moved here"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Immersive"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Restore"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maximise"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Restore"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Snap left"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
index c1a4244896c5..f9911451f4b5 100644
--- a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
@@ -133,10 +133,8 @@
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximise screen"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Snap screen"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"App can\'t be moved here"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Immersive"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Restore"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maximise"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Restore"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Snap left"</string>
diff --git a/libs/WindowManager/Shell/res/values-hi/strings.xml b/libs/WindowManager/Shell/res/values-hi/strings.xml
index ff675a9f6356..527793eac9c3 100644
--- a/libs/WindowManager/Shell/res/values-hi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hi/strings.xml
@@ -133,10 +133,8 @@
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"स्क्रीन को बड़ा करें"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"स्नैप स्क्रीन"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ऐप्लिकेशन को यहां मूव नहीं किया जा सकता"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"इमर्सिव"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"वापस लाएं"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"बड़ा करें"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"पहले जैसा करें"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"बाईं ओर स्नैप करें"</string>
diff --git a/libs/WindowManager/Shell/res/values-hr/strings.xml b/libs/WindowManager/Shell/res/values-hr/strings.xml
index 16fbcd0565fa..659d1ec39b73 100644
--- a/libs/WindowManager/Shell/res/values-hr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hr/strings.xml
@@ -133,10 +133,8 @@
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimalno povećaj zaslon"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Izradi snimku zaslona"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikacija se ne može premjestiti ovdje"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Interaktivno"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Vrati"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maksimiziraj"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Vrati"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Poravnaj lijevo"</string>
diff --git a/libs/WindowManager/Shell/res/values-is/strings.xml b/libs/WindowManager/Shell/res/values-is/strings.xml
index f595765a797e..ca1bc15edf33 100644
--- a/libs/WindowManager/Shell/res/values-is/strings.xml
+++ b/libs/WindowManager/Shell/res/values-is/strings.xml
@@ -133,10 +133,8 @@
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Stækka skjá"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Smelluskjár"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Ekki er hægt að færa forritið hingað"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Umlykjandi"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Endurheimta"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Stækka"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Endurheimta"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Smella til vinstri"</string>
diff --git a/libs/WindowManager/Shell/res/values-it/strings.xml b/libs/WindowManager/Shell/res/values-it/strings.xml
index 8b7c15ffeb15..87919b5dc1ff 100644
--- a/libs/WindowManager/Shell/res/values-it/strings.xml
+++ b/libs/WindowManager/Shell/res/values-it/strings.xml
@@ -133,10 +133,8 @@
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Massimizza schermo"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Aggancia schermo"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Impossibile spostare l\'app qui"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Immersivo"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Ripristina"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Ingrandisci"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Ripristina"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Aggancia a sinistra"</string>
diff --git a/libs/WindowManager/Shell/res/values-ja/strings.xml b/libs/WindowManager/Shell/res/values-ja/strings.xml
index 5464cfa28b3c..c7a77d9b9214 100644
--- a/libs/WindowManager/Shell/res/values-ja/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ja/strings.xml
@@ -133,10 +133,8 @@
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"画面の最大化"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"画面のスナップ"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"アプリはここに移動できません"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"没入モード"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"復元"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"最大化"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"復元"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"左にスナップ"</string>
diff --git a/libs/WindowManager/Shell/res/values-ka/strings.xml b/libs/WindowManager/Shell/res/values-ka/strings.xml
index 7ea9daffca18..39362ef4ca57 100644
--- a/libs/WindowManager/Shell/res/values-ka/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ka/strings.xml
@@ -133,10 +133,8 @@
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"აპლიკაციის გაშლა სრულ ეკრანზე"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"აპლიკაციის დაპატარავება ეკრანზე"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"აპის აქ გადატანა შეუძლებელია"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"იმერსიული"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"აღდგენა"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"მაქსიმალურად გაშლა"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"აღდგენა"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"მარცხნივ გადატანა"</string>
diff --git a/libs/WindowManager/Shell/res/values-km/strings.xml b/libs/WindowManager/Shell/res/values-km/strings.xml
index 83bd3744d27a..9c4ae05f3a36 100644
--- a/libs/WindowManager/Shell/res/values-km/strings.xml
+++ b/libs/WindowManager/Shell/res/values-km/strings.xml
@@ -133,10 +133,8 @@
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"ពង្រីកអេក្រង់"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"ថតអេក្រង់"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"មិនអាចផ្លាស់ទីកម្មវិធីមកទីនេះបានទេ"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"ជក់ចិត្ត"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"ស្ដារ"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"ពង្រីក"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"ស្ដារ"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"ផ្លាស់ទីទៅឆ្វេង"</string>
diff --git a/libs/WindowManager/Shell/res/values-kn/strings.xml b/libs/WindowManager/Shell/res/values-kn/strings.xml
index 502e0c92f844..f365cfb34412 100644
--- a/libs/WindowManager/Shell/res/values-kn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-kn/strings.xml
@@ -133,10 +133,8 @@
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"ಸ್ಕ್ರೀನ್ ಅನ್ನು ಮ್ಯಾಕ್ಸಿಮೈಸ್ ಮಾಡಿ"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"ಸ್ನ್ಯಾಪ್ ಸ್ಕ್ರೀನ್"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ಆ್ಯಪ್ ಅನ್ನು ಇಲ್ಲಿಗೆ ಸರಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"ಇಮ್ಮರ್ಸಿವ್"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"ಮರುಸ್ಥಾಪಿಸಿ"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"ಮ್ಯಾಕ್ಸಿಮೈಸ್ ಮಾಡಿ"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"ಮರುಸ್ಥಾಪಿಸಿ"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"ಎಡಕ್ಕೆ ಸ್ನ್ಯಾಪ್ ಮಾಡಿ"</string>
diff --git a/libs/WindowManager/Shell/res/values-lt/strings.xml b/libs/WindowManager/Shell/res/values-lt/strings.xml
index 4551f72eb635..5a7f58e5781a 100644
--- a/libs/WindowManager/Shell/res/values-lt/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lt/strings.xml
@@ -133,10 +133,8 @@
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Išskleisti ekraną"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Sutraukti ekraną"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Programos negalima perkelti čia"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Įtraukiantis"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Atkurti"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Padidinti"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Atkurti"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Pritraukti kairėje"</string>
diff --git a/libs/WindowManager/Shell/res/values-mr/strings.xml b/libs/WindowManager/Shell/res/values-mr/strings.xml
index a2c610e82823..871bc3fcc8e7 100644
--- a/libs/WindowManager/Shell/res/values-mr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mr/strings.xml
@@ -133,10 +133,8 @@
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"स्क्रीन मोठी करा"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"स्क्रीन स्नॅप करा"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"अ‍ॅप इथे हलवू शकत नाही"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"इमर्सिव्ह"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"रिस्टोअर करा"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"मोठे करा"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"रिस्टोअर करा"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"डावीकडे स्नॅप करा"</string>
diff --git a/libs/WindowManager/Shell/res/values-ms/strings.xml b/libs/WindowManager/Shell/res/values-ms/strings.xml
index 2102a382d232..71666cae93c8 100644
--- a/libs/WindowManager/Shell/res/values-ms/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ms/strings.xml
@@ -133,10 +133,8 @@
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimumkan Skrin"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Tangkap Skrin"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Apl tidak boleh dialihkan ke sini"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Mengasyikkan"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Pulihkan"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maksimumkan"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Pulihkan"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Autojajar ke kiri"</string>
diff --git a/libs/WindowManager/Shell/res/values-ne/strings.xml b/libs/WindowManager/Shell/res/values-ne/strings.xml
index e9a530621c7e..7015b2c11b32 100644
--- a/libs/WindowManager/Shell/res/values-ne/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ne/strings.xml
@@ -133,10 +133,8 @@
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"स्क्रिन ठुलो बनाउनुहोस्"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"स्क्रिन स्न्याप गर्नुहोस्"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"एप सारेर यहाँ ल्याउन सकिएन"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"इमर्सिभ"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"रिस्टोर गर्नुहोस्"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"ठुलो बनाउनुहोस्"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"रिस्टोर गर्नुहोस्"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"बायाँतिर स्न्याप गर्नुहोस्"</string>
diff --git a/libs/WindowManager/Shell/res/values-pl/strings.xml b/libs/WindowManager/Shell/res/values-pl/strings.xml
index 14b7a09f6143..5f78b134ad22 100644
--- a/libs/WindowManager/Shell/res/values-pl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pl/strings.xml
@@ -133,10 +133,8 @@
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksymalizuj ekran"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Przyciągnij ekran"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Nie można przenieść aplikacji tutaj"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Tryb immersyjny"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Przywróć"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maksymalizuj"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Przywróć"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Przyciągnij do lewej"</string>
diff --git a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
index 9631c45a8097..cd78ef95d88e 100644
--- a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
@@ -133,10 +133,8 @@
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximizar ecrã"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Encaixar ecrã"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Não é possível mover a app para aqui"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Envolvente"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Restaurar"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maximizar"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Restaurar"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Encaixar à esquerda"</string>
diff --git a/libs/WindowManager/Shell/res/values-sl/strings.xml b/libs/WindowManager/Shell/res/values-sl/strings.xml
index 2012c8a6754e..ae7e524da6cc 100644
--- a/libs/WindowManager/Shell/res/values-sl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sl/strings.xml
@@ -133,10 +133,8 @@
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimiraj zaslon"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"Pripni zaslon"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikacije ni mogoče premakniti sem"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Poglobljeno"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"Obnovi"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"Maksimiraj"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"Obnovi"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"Pripni levo"</string>
diff --git a/libs/WindowManager/Shell/res/values-ta/strings.xml b/libs/WindowManager/Shell/res/values-ta/strings.xml
index c4243f7ae90d..2c73d3a14620 100644
--- a/libs/WindowManager/Shell/res/values-ta/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ta/strings.xml
@@ -133,10 +133,8 @@
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"திரையைப் பெரிதாக்கு"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"திரையை ஸ்னாப் செய்"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ஆப்ஸை இங்கே நகர்த்த முடியாது"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"ஈடுபட வைக்கும்"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"மீட்டெடுக்கும்"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"பெரிதாக்கும்"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"மீட்டெடுக்கும்"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"இடதுபுறம் நகர்த்தும்"</string>
diff --git a/libs/WindowManager/Shell/res/values-te/strings.xml b/libs/WindowManager/Shell/res/values-te/strings.xml
index 47fc48ddc3c3..b17d4d1afaf7 100644
--- a/libs/WindowManager/Shell/res/values-te/strings.xml
+++ b/libs/WindowManager/Shell/res/values-te/strings.xml
@@ -133,10 +133,8 @@
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"స్క్రీన్ సైజ్‌ను పెంచండి"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"స్క్రీన్‌ను స్నాప్ చేయండి"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"యాప్‌ను ఇక్కడకి తరలించడం సాధ్యం కాదు"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"లీనమయ్యే"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"రీస్టోర్ చేయండి"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"మ్యాగ్జిమైజ్ చేయండి"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"రీస్టోర్ చేయండి"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"ఎడమ వైపున స్నాప్ చేయండి"</string>
diff --git a/libs/WindowManager/Shell/res/values-th/strings.xml b/libs/WindowManager/Shell/res/values-th/strings.xml
index 260807537385..43cee41f5a15 100644
--- a/libs/WindowManager/Shell/res/values-th/strings.xml
+++ b/libs/WindowManager/Shell/res/values-th/strings.xml
@@ -133,10 +133,8 @@
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"ขยายหน้าจอให้ใหญ่สุด"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"สแนปหน้าจอ"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ย้ายแอปมาที่นี่ไม่ได้"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"สมจริง"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"คืนค่า"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"ขยายใหญ่สุด"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"คืนค่า"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"จัดพอดีกับทางซ้าย"</string>
diff --git a/libs/WindowManager/Shell/res/values-tl/strings.xml b/libs/WindowManager/Shell/res/values-tl/strings.xml
index 94166ef5db5e..428499532005 100644
--- a/libs/WindowManager/Shell/res/values-tl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-tl/strings.xml
@@ -133,10 +133,8 @@
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"I-maximize ang Screen"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"I-snap ang Screen"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Hindi mailipat dito ang app"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"Immersive"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"I-restore"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"I-maximize"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"I-restore"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"I-snap pakaliwa"</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
index ad50a045c924..2fb3f5ab5ea4 100644
--- a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
@@ -133,10 +133,8 @@
<string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"最大化屏幕"</string>
<string name="desktop_mode_maximize_menu_snap_text" msgid="2065251022783880154">"屏幕快照"</string>
<string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"无法将应用移至此处"</string>
- <!-- no translation found for desktop_mode_maximize_menu_immersive_button_text (559492223133829481) -->
- <skip />
- <!-- no translation found for desktop_mode_maximize_menu_immersive_restore_button_text (4900114367354709257) -->
- <skip />
+ <string name="desktop_mode_maximize_menu_immersive_button_text" msgid="559492223133829481">"沉浸式"</string>
+ <string name="desktop_mode_maximize_menu_immersive_restore_button_text" msgid="4900114367354709257">"恢复"</string>
<string name="desktop_mode_maximize_menu_maximize_button_text" msgid="3090199175564175845">"最大化"</string>
<string name="desktop_mode_maximize_menu_restore_button_text" msgid="4234449220944704387">"恢复"</string>
<string name="desktop_mode_maximize_menu_snap_left_button_text" msgid="8077452201179893424">"贴靠左侧"</string>
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/pip/PipContentOverlay.java b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/pip/PipContentOverlay.java
index eb7ef1478a90..62ca5c687a2a 100644
--- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/pip/PipContentOverlay.java
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/pip/PipContentOverlay.java
@@ -18,6 +18,7 @@ package com.android.wm.shell.shared.pip;
import static android.util.TypedValue.COMPLEX_UNIT_DIP;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.content.res.TypedArray;
@@ -170,26 +171,34 @@ public abstract class PipContentOverlay {
private final Context mContext;
private final int mAppIconSizePx;
- private final Rect mAppBounds;
+ /**
+ * The bounds of the application window relative to the task leash.
+ */
+ private final Rect mRelativeAppBounds;
private final int mOverlayHalfSize;
private final Matrix mTmpTransform = new Matrix();
private final float[] mTmpFloat9 = new float[9];
private Bitmap mBitmap;
- public PipAppIconOverlay(Context context, Rect appBounds, Rect destinationBounds,
- Drawable appIcon, int appIconSizePx) {
+ // TODO(b/356277166): add non-match_parent support on PIP2.
+ /**
+ * @param context the {@link Context} that contains the icon information
+ * @param relativeAppBounds the bounds of the app window frame relative to the task leash
+ * @param destinationBounds the bounds for rhe PIP task
+ * @param appIcon the app icon {@link Drawable}
+ * @param appIconSizePx the icon dimension in pixel
+ */
+ public PipAppIconOverlay(@NonNull Context context, @NonNull Rect relativeAppBounds,
+ @NonNull Rect destinationBounds, @NonNull Drawable appIcon, int appIconSizePx) {
mContext = context;
final int maxAppIconSizePx = (int) TypedValue.applyDimension(COMPLEX_UNIT_DIP,
MAX_APP_ICON_SIZE_DP, context.getResources().getDisplayMetrics());
mAppIconSizePx = Math.min(maxAppIconSizePx, appIconSizePx);
- final int overlaySize = getOverlaySize(appBounds, destinationBounds);
+ final int overlaySize = getOverlaySize(relativeAppBounds, destinationBounds);
mOverlayHalfSize = overlaySize >> 1;
-
- // When the activity is in the secondary split, make sure the scaling center is not
- // offset.
- mAppBounds = new Rect(0, 0, appBounds.width(), appBounds.height());
+ mRelativeAppBounds = relativeAppBounds;
mBitmap = Bitmap.createBitmap(overlaySize, overlaySize, Bitmap.Config.ARGB_8888);
prepareAppIconOverlay(appIcon);
@@ -206,9 +215,9 @@ public abstract class PipContentOverlay {
* the overlay will be drawn with the max size of the start and end bounds in different
* rotation.
*/
- public static int getOverlaySize(Rect appBounds, Rect destinationBounds) {
- final int appWidth = appBounds.width();
- final int appHeight = appBounds.height();
+ public static int getOverlaySize(Rect overlayBounds, Rect destinationBounds) {
+ final int appWidth = overlayBounds.width();
+ final int appHeight = overlayBounds.height();
return Math.max(Math.max(appWidth, appHeight),
Math.max(destinationBounds.width(), destinationBounds.height())) + 1;
@@ -230,15 +239,15 @@ public abstract class PipContentOverlay {
mTmpTransform.reset();
// In order for the overlay to always cover the pip window, the overlay may have a
// size larger than the pip window. Make sure that app icon is at the center.
- final int appBoundsCenterX = mAppBounds.centerX();
- final int appBoundsCenterY = mAppBounds.centerY();
+ final int appBoundsCenterX = mRelativeAppBounds.centerX();
+ final int appBoundsCenterY = mRelativeAppBounds.centerY();
mTmpTransform.setTranslate(
appBoundsCenterX - mOverlayHalfSize,
appBoundsCenterY - mOverlayHalfSize);
// Scale back the bitmap with the pivot point at center.
final float scale = Math.min(
- (float) mAppBounds.width() / currentBounds.width(),
- (float) mAppBounds.height() / currentBounds.height());
+ (float) mRelativeAppBounds.width() / currentBounds.width(),
+ (float) mRelativeAppBounds.height() / currentBounds.height());
mTmpTransform.postScale(scale, scale, appBoundsCenterX, appBoundsCenterY);
atomicTx.setMatrix(mLeash, mTmpTransform, mTmpFloat9)
.setAlpha(mLeash, fraction < 0.5f ? 0 : (fraction - 0.5f) * 2);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
index ae0485f0ad07..f296c710f9a0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
@@ -1300,7 +1300,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
final TransitionInfo init = mOpenTransitionInfo;
// Find prepare open target
boolean openShowWallpaper = false;
- final ArrayList<OpenChangeInfo> targets = new ArrayList<>();
+ final ArrayList<SurfaceControl> openSurfaces = new ArrayList<>();
int tmpSize;
for (int j = init.getChanges().size() - 1; j >= 0; --j) {
final TransitionInfo.Change change = init.getChanges().get(j);
@@ -1313,13 +1313,13 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
&& openToken == null) {
continue;
}
- targets.add(new OpenChangeInfo(openComponent, openTaskId, openToken));
+ openSurfaces.add(change.getLeash());
if (change.hasFlags(FLAG_SHOW_WALLPAPER)) {
openShowWallpaper = true;
}
}
}
- if (targets.isEmpty()) {
+ if (openSurfaces.isEmpty()) {
// This shouldn't happen, but if that happen, consume the initial transition anyway.
Log.e(TAG, "Unable to merge following transition, cannot find the gesture "
+ "animated target from the open transition=" + mOpenTransitionInfo);
@@ -1331,7 +1331,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
tmpSize = info.getChanges().size();
for (int j = 0; j < tmpSize; ++j) {
final TransitionInfo.Change change = info.getChanges().get(j);
- if (isOpenChangeMatched(targets, change)) {
+ if (isOpenSurfaceMatched(openSurfaces, change)) {
// This is original close target, potential be close, but cannot determine
// from it.
if (change.hasFlags(FLAG_BACK_GESTURE_ANIMATED)) {
@@ -1352,7 +1352,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
boolean mergePredictive = false;
for (int j = info.getChanges().size() - 1; j >= 0; --j) {
final TransitionInfo.Change change = info.getChanges().get(j);
- if (isOpenChangeMatched(targets, change)) {
+ if (isOpenSurfaceMatched(openSurfaces, change)) {
if (TransitionUtil.isClosingMode(change.getMode())) {
excludeOpenTarget = true;
}
@@ -1373,7 +1373,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
if (change.hasFlags(FLAG_IS_WALLPAPER)) {
continue;
}
- if (isOpenChangeMatched(targets, change)) {
+ if (isOpenSurfaceMatched(openSurfaces, change)) {
if (excludeOpenTarget) {
// App has triggered another change during predictive back
// transition, filter out predictive back target.
@@ -1408,7 +1408,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
if (nonBackClose && nonBackOpen) {
for (int j = info.getChanges().size() - 1; j >= 0; --j) {
final TransitionInfo.Change change = info.getChanges().get(j);
- if (isOpenChangeMatched(targets, change)) {
+ if (isOpenSurfaceMatched(openSurfaces, change)) {
info.getChanges().remove(j);
} else if ((openShowWallpaper && change.hasFlags(FLAG_IS_WALLPAPER))) {
info.getChanges().remove(j);
@@ -1692,22 +1692,10 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
return INVALID_TASK_ID;
}
- private static boolean isSameChangeTarget(ComponentName topActivity, int taskId,
- WindowContainerToken token, TransitionInfo.Change change) {
- final ComponentName openChange = findComponentName(change);
- final int firstTaskId = findTaskId(change);
- final WindowContainerToken openToken = findToken(change);
- return (openChange != null && openChange.equals(topActivity))
- || (firstTaskId != INVALID_TASK_ID && firstTaskId == taskId)
- || (openToken != null && openToken.equals(token));
- }
-
- static boolean isOpenChangeMatched(@NonNull ArrayList<OpenChangeInfo> targets,
+ static boolean isOpenSurfaceMatched(@NonNull ArrayList<SurfaceControl> openSurfaces,
TransitionInfo.Change change) {
- for (int i = targets.size() - 1; i >= 0; --i) {
- final OpenChangeInfo next = targets.get(i);
- if (isSameChangeTarget(next.mOpenComponent, next.mOpenTaskId, next.mOpenToken,
- change)) {
+ for (int i = openSurfaces.size() - 1; i >= 0; --i) {
+ if (openSurfaces.get(i).isSameSurface(change.getLeash())) {
return true;
}
}
@@ -1771,16 +1759,4 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
}
}
}
-
- static class OpenChangeInfo {
- final ComponentName mOpenComponent;
- final int mOpenTaskId;
- final WindowContainerToken mOpenToken;
- OpenChangeInfo(ComponentName openComponent, int openTaskId,
- WindowContainerToken openToken) {
- mOpenComponent = openComponent;
- mOpenTaskId = openTaskId;
- mOpenToken = openToken;
- }
- }
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
index d1246d35e35e..5f0eed9daa1a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
@@ -1212,7 +1212,7 @@ public class BubbleController implements ConfigurationChangeListener,
*/
public void startBubbleDrag(String bubbleKey) {
if (mBubbleData.getSelectedBubble() != null) {
- mBubbleBarViewCallback.expansionChanged(/* isExpanded = */ false);
+ collapseExpandedViewForBubbleBar();
}
if (mBubbleStateListener != null) {
boolean overflow = BubbleOverflow.KEY.equals(bubbleKey);
@@ -1304,6 +1304,7 @@ public class BubbleController implements ConfigurationChangeListener,
if (BubbleOverflow.KEY.equals(key)) {
mBubbleData.setSelectedBubbleFromLauncher(mBubbleData.getOverflow());
mLayerView.showExpandedView(mBubbleData.getOverflow());
+ mLogger.log(BubbleLogger.Event.BUBBLE_BAR_EXPANDED);
return;
}
@@ -1315,6 +1316,7 @@ public class BubbleController implements ConfigurationChangeListener,
// already in the stack
mBubbleData.setSelectedBubbleFromLauncher(b);
mLayerView.showExpandedView(b);
+ mLogger.log(b, BubbleLogger.Event.BUBBLE_BAR_EXPANDED);
} else if (mBubbleData.hasOverflowBubbleWithKey(b.getKey())) {
// TODO: (b/271468319) handle overflow
} else {
@@ -2024,12 +2026,16 @@ public class BubbleController implements ConfigurationChangeListener,
public void expansionChanged(boolean isExpanded) {
// in bubble bar mode, let the request to show the expanded view come from launcher.
// only collapse here if we're collapsing.
- if (mLayerView != null && !isExpanded) {
- if (mBubblePositioner.isImeVisible()) {
- // If we're collapsing, hide the IME
- hideCurrentInputMethod();
- }
- mLayerView.collapse();
+ if (!isExpanded) {
+ collapseExpandedViewForBubbleBar();
+ }
+
+ BubbleLogger.Event event = isExpanded ? BubbleLogger.Event.BUBBLE_BAR_EXPANDED
+ : BubbleLogger.Event.BUBBLE_BAR_COLLAPSED;
+ if (mBubbleData.getSelectedBubble() instanceof Bubble bubble) {
+ mLogger.log(bubble, event);
+ } else {
+ mLogger.log(event);
}
}
@@ -2182,6 +2188,16 @@ public class BubbleController implements ConfigurationChangeListener,
}
}
+ private void collapseExpandedViewForBubbleBar() {
+ if (mLayerView != null && mLayerView.isExpanded()) {
+ if (mBubblePositioner.isImeVisible()) {
+ // If we're collapsing, hide the IME
+ hideCurrentInputMethod();
+ }
+ mLayerView.collapse();
+ }
+ }
+
private void updateOverflowButtonDot() {
BubbleOverflow overflow = mBubbleData.getOverflow();
if (overflow == null) return;
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 35a0d07a63b2..88f55b8af8f7 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
@@ -1704,6 +1704,7 @@ public class BubbleStackView extends FrameLayout
getViewTreeObserver().removeOnPreDrawListener(mViewUpdater);
getViewTreeObserver().removeOnDrawListener(mSystemGestureExcludeUpdater);
getViewTreeObserver().removeOnComputeInternalInsetsListener(this);
+ stopMonitoringSwipeUpGesture();
}
@Override
@@ -2313,7 +2314,8 @@ public class BubbleStackView extends FrameLayout
/**
* Stop monitoring for swipe up gesture
*/
- void stopMonitoringSwipeUpGesture() {
+ @VisibleForTesting
+ public void stopMonitoringSwipeUpGesture() {
stopMonitoringSwipeUpGestureInternal();
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerSnapAlgorithm.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerSnapAlgorithm.java
index b29e49a48428..813772f20a8a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerSnapAlgorithm.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerSnapAlgorithm.java
@@ -71,6 +71,11 @@ public class DividerSnapAlgorithm {
*/
private static final int SNAP_MODE_MINIMIZED = 3;
+ /**
+ * A mode where apps can be "flexibly offscreen" on smaller displays.
+ */
+ private static final int SNAP_FLEXIBLE_SPLIT = 4;
+
private final float mMinFlingVelocityPxPerSecond;
private final float mMinDismissVelocityPxPerSecond;
private final int mDisplayWidth;
@@ -78,6 +83,7 @@ public class DividerSnapAlgorithm {
private final int mDividerSize;
private final ArrayList<SnapTarget> mTargets = new ArrayList<>();
private final Rect mInsets = new Rect();
+ private final Rect mPinnedTaskbarInsets = new Rect();
private final int mSnapMode;
private final boolean mFreeSnapMode;
private final int mMinimalSizeResizableTask;
@@ -88,6 +94,8 @@ public class DividerSnapAlgorithm {
/** Allows split ratios that go offscreen (a.k.a. "flexible split") */
private final boolean mAllowOffscreenRatios;
private final boolean mIsLeftRightSplit;
+ /** In SNAP_MODE_MINIMIZED, the side of the screen on which an app will "dock" when minimized */
+ private final int mDockSide;
/** The first target which is still splitting the screen */
private final SnapTarget mFirstSplitTarget;
@@ -101,14 +109,14 @@ public class DividerSnapAlgorithm {
public DividerSnapAlgorithm(Resources res, int displayWidth, int displayHeight, int dividerSize,
- boolean isLeftRightSplit, Rect insets, int dockSide) {
+ boolean isLeftRightSplit, Rect insets, Rect pinnedTaskbarInsets, int dockSide) {
this(res, displayWidth, displayHeight, dividerSize, isLeftRightSplit, insets,
- dockSide, false /* minimized */, true /* resizable */);
+ pinnedTaskbarInsets, dockSide, false /* minimized */, true /* resizable */);
}
public DividerSnapAlgorithm(Resources res, int displayWidth, int displayHeight, int dividerSize,
- boolean isLeftRightSplit, Rect insets, int dockSide, boolean isMinimizedMode,
- boolean isHomeResizable) {
+ boolean isLeftRightSplit, Rect insets, Rect pinnedTaskbarInsets, int dockSide,
+ boolean isMinimizedMode, boolean isHomeResizable) {
mMinFlingVelocityPxPerSecond =
MIN_FLING_VELOCITY_DP_PER_SECOND * res.getDisplayMetrics().density;
mMinDismissVelocityPxPerSecond =
@@ -117,10 +125,11 @@ public class DividerSnapAlgorithm {
mDisplayWidth = displayWidth;
mDisplayHeight = displayHeight;
mIsLeftRightSplit = isLeftRightSplit;
+ mDockSide = dockSide;
mInsets.set(insets);
+ mPinnedTaskbarInsets.set(pinnedTaskbarInsets);
if (Flags.enableFlexibleTwoAppSplit()) {
- // In flexible split, we always use a fixed ratio (50%, 66%, or 90%) for splitting
- mSnapMode = SNAP_FIXED_RATIO;
+ mSnapMode = SNAP_FLEXIBLE_SPLIT;
} else {
// Set SNAP_MODE_MINIMIZED, SNAP_MODE_16_9, or SNAP_FIXED_RATIO depending on config
mSnapMode = isMinimizedMode
@@ -140,7 +149,7 @@ public class DividerSnapAlgorithm {
mAllowOffscreenRatios = SplitScreenUtils.allowOffscreenRatios(res);
mTaskHeightInMinimizedMode = isHomeResizable ? res.getDimensionPixelSize(
com.android.internal.R.dimen.task_height_of_minimized_mode) : 0;
- calculateTargets(isLeftRightSplit, dockSide);
+ calculateTargets();
mFirstSplitTarget = mTargets.get(1);
mLastSplitTarget = mTargets.get(mTargets.size() - 2);
mDismissStartTarget = mTargets.get(0);
@@ -276,28 +285,31 @@ public class DividerSnapAlgorithm {
return mTargets.get(minIndex);
}
- private void calculateTargets(boolean isLeftRightSplit, int dockedSide) {
+ private void calculateTargets() {
mTargets.clear();
- int dividerMax = isLeftRightSplit
+ int dividerMax = mIsLeftRightSplit
? mDisplayWidth
: mDisplayHeight;
int startPos = -mDividerSize;
- if (dockedSide == DOCKED_RIGHT) {
+ if (mDockSide == DOCKED_RIGHT) {
startPos += mInsets.left;
}
mTargets.add(new SnapTarget(startPos, SNAP_TO_START_AND_DISMISS, 0.35f));
switch (mSnapMode) {
case SNAP_MODE_16_9:
- addRatio16_9Targets(isLeftRightSplit, dividerMax);
+ addRatio16_9Targets(mIsLeftRightSplit, dividerMax);
break;
case SNAP_FIXED_RATIO:
- addFixedDivisionTargets(isLeftRightSplit, dividerMax);
+ addFixedDivisionTargets(mIsLeftRightSplit, dividerMax);
break;
case SNAP_ONLY_1_1:
- addMiddleTarget(isLeftRightSplit);
+ addMiddleTarget(mIsLeftRightSplit);
break;
case SNAP_MODE_MINIMIZED:
- addMinimizedTarget(isLeftRightSplit, dockedSide);
+ addMinimizedTarget(mIsLeftRightSplit, mDockSide);
+ break;
+ case SNAP_FLEXIBLE_SPLIT:
+ addFlexSplitTargets(mIsLeftRightSplit, dividerMax);
break;
}
mTargets.add(new SnapTarget(dividerMax, SNAP_TO_END_AND_DISMISS, 0.35f));
@@ -321,18 +333,9 @@ public class DividerSnapAlgorithm {
? mDisplayWidth - mInsets.right
: mDisplayHeight - mInsets.bottom;
- int size;
- if (Flags.enableFlexibleTwoAppSplit()) {
- float ratio = areOffscreenRatiosSupported()
- ? SplitLayout.OFFSCREEN_ASYMMETRIC_RATIO
- : SplitLayout.ONSCREEN_ONLY_ASYMMETRIC_RATIO;
- size = (int) (ratio * (end - start)) - mDividerSize / 2;
- } else {
- size = (int) (mFixedRatio * (end - start)) - mDividerSize / 2;
-
- if (mCalculateRatiosBasedOnAvailableSpace) {
- size = Math.max(size, mMinimalSizeResizableTask);
- }
+ int size = (int) (mFixedRatio * (end - start)) - mDividerSize / 2;
+ if (mCalculateRatiosBasedOnAvailableSpace) {
+ size = Math.max(size, mMinimalSizeResizableTask);
}
int topPosition = start + size;
@@ -340,6 +343,24 @@ public class DividerSnapAlgorithm {
addNonDismissingTargets(isLeftRightSplit, topPosition, bottomPosition, dividerMax);
}
+ private void addFlexSplitTargets(boolean isLeftRightSplit, int dividerMax) {
+ int start = 0;
+ int end = isLeftRightSplit ? mDisplayWidth : mDisplayHeight;
+ int pinnedTaskbarShiftStart = isLeftRightSplit
+ ? mPinnedTaskbarInsets.left : mPinnedTaskbarInsets.top;
+ int pinnedTaskbarShiftEnd = isLeftRightSplit
+ ? mPinnedTaskbarInsets.right : mPinnedTaskbarInsets.bottom;
+
+ float ratio = areOffscreenRatiosSupported()
+ ? SplitLayout.OFFSCREEN_ASYMMETRIC_RATIO
+ : SplitLayout.ONSCREEN_ONLY_ASYMMETRIC_RATIO;
+ int size = (int) (ratio * (end - start)) - mDividerSize / 2;
+
+ int leftTopPosition = start + pinnedTaskbarShiftStart + size;
+ int rightBottomPosition = end - pinnedTaskbarShiftEnd - size - mDividerSize;
+ addNonDismissingTargets(isLeftRightSplit, leftTopPosition, rightBottomPosition, dividerMax);
+ }
+
private void addRatio16_9Targets(boolean isLeftRightSplit, int dividerMax) {
int start = isLeftRightSplit ? mInsets.left : mInsets.top;
int end = isLeftRightSplit
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
index b1e0e9eab5d0..dab30b0f0b96 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
@@ -49,10 +49,13 @@ import android.app.ActivityManager;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
+import android.graphics.Insets;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Handler;
import android.view.Display;
+import android.view.InsetsController;
+import android.view.InsetsSource;
import android.view.InsetsSourceControl;
import android.view.InsetsState;
import android.view.RoundedCorner;
@@ -153,6 +156,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
private final ResizingEffectPolicy mSurfaceEffectPolicy;
private final ShellTaskOrganizer mTaskOrganizer;
private final InsetsState mInsetsState = new InsetsState();
+ private Insets mPinnedTaskbarInsets = Insets.NONE;
private Context mContext;
@VisibleForTesting DividerSnapAlgorithm mDividerSnapAlgorithm;
@@ -523,6 +527,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
@Override
public void insetsChanged(InsetsState insetsState) {
mInsetsState.set(insetsState);
+
if (!mInitialized) {
return;
}
@@ -531,9 +536,51 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
// flicker.
return;
}
+
+ // Check to see if insets changed in such a way that the divider algorithm needs to be
+ // recalculated.
+ Insets pinnedTaskbarInsets = calculatePinnedTaskbarInsets(insetsState);
+ if (!mPinnedTaskbarInsets.equals(pinnedTaskbarInsets)) {
+ mPinnedTaskbarInsets = pinnedTaskbarInsets;
+ // Refresh the DividerSnapAlgorithm.
+ mDividerSnapAlgorithm = getSnapAlgorithm(mContext, mRootBounds);
+ // If the divider is no longer placed on a snap point, animate it to the nearest one.
+ DividerSnapAlgorithm.SnapTarget snapTarget =
+ findSnapTarget(mDividerPosition, 0, false /* hardDismiss */);
+ if (snapTarget.position != mDividerPosition) {
+ snapToTarget(mDividerPosition, snapTarget,
+ InsetsController.ANIMATION_DURATION_RESIZE,
+ InsetsController.RESIZE_INTERPOLATOR);
+ }
+ }
+
mSplitWindowManager.onInsetsChanged(insetsState);
}
+ /**
+ * Calculates the insets that might trigger a divider algorithm recalculation. Currently, only
+ * pinned Taskbar does this, and only when the IME is not showing.
+ */
+ private Insets calculatePinnedTaskbarInsets(InsetsState insetsState) {
+ if (insetsState.isSourceOrDefaultVisible(InsetsSource.ID_IME, WindowInsets.Type.ime())) {
+ return Insets.NONE;
+ }
+
+ // If IME is not showing...
+ for (int i = insetsState.sourceSize() - 1; i >= 0; i--) {
+ final InsetsSource source = insetsState.sourceAt(i);
+ // and Taskbar is pinned...
+ if (source.getType() == WindowInsets.Type.navigationBars()
+ && source.hasFlags(InsetsSource.FLAG_INSETS_ROUNDED_CORNER)) {
+ // Return Insets representing the pinned taskbar state.
+ return source.calculateVisibleInsets(mRootBounds);
+ }
+ }
+
+ // Else, divider can calculate based on the full display.
+ return Insets.NONE;
+ }
+
@Override
public void insetsControlChanged(InsetsState insetsState,
InsetsSourceControl[] activeControls) {
@@ -631,8 +678,8 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
}
/**
- * Same as {@link #snapToTarget(int, SnapTarget)}, with default animation duration and
- * interpolator.
+ * Same as {@link #snapToTarget(int, SnapTarget, int, Interpolator)}, with default animation
+ * duration and interpolator.
*/
public void snapToTarget(int currentPosition, SnapTarget snapTarget) {
snapToTarget(currentPosition, snapTarget, FLING_RESIZE_DURATION,
@@ -683,6 +730,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
mDividerSize,
mIsLeftRightSplit,
insets,
+ mPinnedTaskbarInsets.toRect(),
mIsLeftRightSplit ? DOCKED_LEFT : DOCKED_TOP /* dockSide */);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopImmersiveController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopImmersiveController.kt
index e741892bf6fc..f69aa6df6a1d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopImmersiveController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopImmersiveController.kt
@@ -224,9 +224,9 @@ class DesktopImmersiveController(
finishTransaction: SurfaceControl.Transaction,
finishCallback: Transitions.TransitionFinishCallback
): Boolean {
- logD("startAnimation transition=%s", transition)
val state = requireState()
if (transition != state.transition) return false
+ logD("startAnimation transition=%s", transition)
animateResize(
targetTaskId = state.taskId,
info = info,
@@ -334,7 +334,6 @@ class DesktopImmersiveController(
startTransaction: SurfaceControl.Transaction,
finishTransaction: SurfaceControl.Transaction,
) {
- logD("onTransitionReady transition=%s", transition)
// Check if this is a pending external exit transition.
val pendingExit = pendingExternalExitTransitions
.firstOrNull { pendingExit -> pendingExit.transition == transition }
@@ -402,7 +401,6 @@ class DesktopImmersiveController(
}
override fun onTransitionMerged(merged: IBinder, playing: IBinder) {
- logD("onTransitionMerged merged=%s playing=%s", merged, playing)
val pendingExit = pendingExternalExitTransitions
.firstOrNull { pendingExit -> pendingExit.transition == merged }
if (pendingExit != null) {
@@ -415,7 +413,6 @@ class DesktopImmersiveController(
}
override fun onTransitionFinished(transition: IBinder, aborted: Boolean) {
- logD("onTransitionFinished transition=%s aborted=%b", transition, aborted)
val pendingExit = pendingExternalExitTransitions
.firstOrNull { pendingExit -> pendingExit.transition == transition }
if (pendingExit != null) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt
index 5648feb96b06..fda709a4a2d7 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt
@@ -23,12 +23,12 @@ import android.util.ArrayMap
import android.util.ArraySet
import android.util.SparseArray
import android.view.Display.INVALID_DISPLAY
+import android.window.DesktopModeFlags
import android.window.WindowContainerToken
import androidx.core.util.forEach
import androidx.core.util.keyIterator
import androidx.core.util.valueIterator
import com.android.internal.protolog.ProtoLog
-import com.android.window.flags.Flags
import com.android.wm.shell.desktopmode.persistence.DesktopPersistentRepository
import com.android.wm.shell.desktopmode.persistence.DesktopRepositoryInitializer
import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
@@ -294,7 +294,7 @@ class DesktopRepository (
taskId, isVisible, displayId)
logD("VisibleTaskCount has changed from %d to %d", prevCount, newCount)
notifyVisibleTaskListeners(displayId, newCount)
- if (Flags.enableDesktopWindowingPersistence()) {
+ if (DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PERSISTENCE.isTrue()) {
updatePersistentRepository(displayId)
}
}
@@ -344,7 +344,7 @@ class DesktopRepository (
desktopTaskDataByDisplayId.getOrCreate(displayId).freeformTasksInZOrder.add(0, taskId)
// Unminimize the task if it is minimized.
unminimizeTask(displayId, taskId)
- if (Flags.enableDesktopWindowingPersistence()) {
+ if (DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PERSISTENCE.isTrue()) {
updatePersistentRepository(displayId)
}
}
@@ -362,7 +362,7 @@ class DesktopRepository (
desktopTaskDataByDisplayId.getOrCreate(displayId).minimizedTasks.add(taskId)
}
updateTask(displayId, taskId, isVisible = false)
- if (Flags.enableDesktopWindowingPersistence()) {
+ if (DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PERSISTENCE.isTrue()) {
updatePersistentRepository(displayId)
}
}
@@ -410,7 +410,7 @@ class DesktopRepository (
unminimizeTask(displayId, taskId)
removeActiveTask(taskId)
removeVisibleTask(taskId)
- if (Flags.enableDesktopWindowingPersistence()) {
+ if (DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PERSISTENCE.isTrue()) {
updatePersistentRepository(displayId)
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
index 133f0693b227..515b203dd492 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
@@ -1161,7 +1161,7 @@ class DesktopTasksController(
if (runningTaskInfo != null) {
// Task is already running, reorder it to the front
wct.reorder(runningTaskInfo.token, /* onTop= */ true)
- } else if (Flags.enableDesktopWindowingPersistence()) {
+ } else if (DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PERSISTENCE.isTrue()) {
// Task is not running, start it
wct.startTask(
taskId,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandler.java
index dedd44f3950a..d537da802efd 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandler.java
@@ -60,7 +60,8 @@ import java.util.function.Supplier;
* entering and exiting freeform.
*/
public class ExitDesktopTaskTransitionHandler implements Transitions.TransitionHandler {
- private static final int FULLSCREEN_ANIMATION_DURATION = 336;
+ @VisibleForTesting
+ static final int FULLSCREEN_ANIMATION_DURATION = 336;
private final Context mContext;
private final Transitions mTransitions;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopRepositoryInitializerImpl.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopRepositoryInitializerImpl.kt
index fc4ed15157d6..d8156561ff19 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopRepositoryInitializerImpl.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopRepositoryInitializerImpl.kt
@@ -17,7 +17,7 @@
package com.android.wm.shell.desktopmode.persistence
import android.content.Context
-import com.android.window.flags.Flags
+import android.window.DesktopModeFlags
import com.android.wm.shell.desktopmode.DesktopRepository
import com.android.wm.shell.shared.annotations.ShellMainThread
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus
@@ -36,7 +36,7 @@ class DesktopRepositoryInitializerImpl(
@ShellMainThread private val mainCoroutineScope: CoroutineScope,
) : DesktopRepositoryInitializer {
override fun initialize(repository: DesktopRepository) {
- if (!Flags.enableDesktopWindowingPersistence()) return
+ if (!DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PERSISTENCE.isTrue()) return
// TODO: b/365962554 - Handle the case that user moves to desktop before it's initialized
mainCoroutineScope.launch {
val desktop = persistentRepository.readDesktop() ?: return@launch
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
index f060158766fe..4aeecbec7dfb 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
@@ -30,6 +30,7 @@ import android.annotation.NonNull;
import android.app.TaskInfo;
import android.content.Context;
import android.content.pm.ActivityInfo;
+import android.graphics.Point;
import android.graphics.Rect;
import android.os.SystemClock;
import android.view.Surface;
@@ -152,7 +153,6 @@ public class PipAnimationController {
return mCurrentAnimator;
}
- @SuppressWarnings("unchecked")
/**
* Construct and return an animator that animates from the {@param startBounds} to the
* {@param endBounds} with the given {@param direction}. If {@param direction} is type
@@ -171,6 +171,7 @@ public class PipAnimationController {
* leaving PiP to fullscreen, and the {@param endBounds} is the fullscreen bounds before the
* rotation change.
*/
+ @SuppressWarnings("unchecked")
@VisibleForTesting
public PipTransitionAnimator getAnimator(TaskInfo taskInfo, SurfaceControl leash,
Rect baseBounds, Rect startBounds, Rect endBounds, Rect sourceHintRect,
@@ -566,7 +567,7 @@ public class PipAnimationController {
}
getSurfaceTransactionHelper()
.resetScale(tx, leash, getDestinationBounds())
- .crop(tx, leash, getDestinationBounds())
+ .cropAndPosition(tx, leash, getDestinationBounds())
.round(tx, leash, true /* applyCornerRadius */)
.shadow(tx, leash, shouldApplyShadowRadius());
tx.show(leash);
@@ -590,18 +591,50 @@ public class PipAnimationController {
// Just for simplicity we'll interpolate between the source rect hint insets and empty
// insets to calculate the window crop
final Rect initialSourceValue;
+ final Rect mainWindowFrame = taskInfo.topActivityMainWindowFrame;
+ final boolean hasNonMatchFrame = mainWindowFrame != null;
+ final boolean changeOrientation =
+ rotationDelta == ROTATION_90 || rotationDelta == ROTATION_270;
+ final Rect baseBounds = new Rect(baseValue);
+ final Rect startBounds = new Rect(startValue);
+ final Rect endBounds = new Rect(endValue);
if (isOutPipDirection) {
- initialSourceValue = new Rect(endValue);
+ // TODO(b/356277166): handle rotation change with activity that provides main window
+ // frame.
+ if (hasNonMatchFrame && !changeOrientation) {
+ endBounds.set(mainWindowFrame);
+ }
+ initialSourceValue = new Rect(endBounds);
+ } else if (isInPipDirection) {
+ if (hasNonMatchFrame) {
+ baseBounds.set(mainWindowFrame);
+ if (startValue.equals(baseValue)) {
+ // If the start value is at initial state as in PIP animation, also override
+ // the start bounds with nonMatchParentBounds.
+ startBounds.set(mainWindowFrame);
+ }
+ }
+ initialSourceValue = new Rect(baseBounds);
} else {
- initialSourceValue = new Rect(baseValue);
+ // Note that we assume the window bounds always match task bounds in PIP mode.
+ initialSourceValue = new Rect(baseBounds);
+ }
+
+ final Point leashOffset;
+ if (isInPipDirection) {
+ leashOffset = new Point(baseValue.left, baseValue.top);
+ } else if (isOutPipDirection) {
+ leashOffset = new Point(endValue.left, endValue.top);
+ } else {
+ leashOffset = new Point(baseValue.left, baseValue.top);
}
final Rect rotatedEndRect;
final Rect lastEndRect;
final Rect initialContainerRect;
- if (rotationDelta == ROTATION_90 || rotationDelta == ROTATION_270) {
- lastEndRect = new Rect(endValue);
- rotatedEndRect = new Rect(endValue);
+ if (changeOrientation) {
+ lastEndRect = new Rect(endBounds);
+ rotatedEndRect = new Rect(endBounds);
// Rotate the end bounds according to the rotation delta because the display will
// be rotated to the same orientation.
rotateBounds(rotatedEndRect, initialSourceValue, rotationDelta);
@@ -617,9 +650,9 @@ public class PipAnimationController {
// Crop a Rect matches the aspect ratio and pivots at the center point.
// This is done for entering case only.
if (isInPipDirection(direction)) {
- final float aspectRatio = endValue.width() / (float) endValue.height();
+ final float aspectRatio = endBounds.width() / (float) endBounds.height();
adjustedSourceRectHint.set(PipUtils.getEnterPipWithOverlaySrcRectHint(
- startValue, aspectRatio));
+ startBounds, aspectRatio));
}
} else {
adjustedSourceRectHint.set(sourceRectHint);
@@ -644,7 +677,7 @@ public class PipAnimationController {
// construct new Rect instances in case they are recycled
return new PipTransitionAnimator<Rect>(taskInfo, leash, ANIM_TYPE_BOUNDS,
- endValue, new Rect(baseValue), new Rect(startValue), new Rect(endValue)) {
+ endBounds, new Rect(baseBounds), new Rect(startBounds), new Rect(endBounds)) {
private final RectEvaluator mRectEvaluator = new RectEvaluator(new Rect());
private final RectEvaluator mInsetsEvaluator = new RectEvaluator(new Rect());
@@ -668,11 +701,22 @@ public class PipAnimationController {
setCurrentValue(bounds);
if (inScaleTransition() || adjustedSourceRectHint.isEmpty()) {
if (isOutPipDirection) {
- getSurfaceTransactionHelper().crop(tx, leash, end)
- .scale(tx, leash, end, bounds);
+ // Use the bounds relative to the task leash in case the leash does not
+ // start from (0, 0).
+ final Rect relativeEndBounds = new Rect(end);
+ relativeEndBounds.offset(-leashOffset.x, -leashOffset.y);
+ getSurfaceTransactionHelper()
+ .crop(tx, leash, relativeEndBounds)
+ .scale(tx, leash, relativeEndBounds, bounds,
+ false /* shouldOffset */);
} else {
- getSurfaceTransactionHelper().crop(tx, leash, base)
- .scale(tx, leash, base, bounds, angle)
+ // TODO(b/356277166): add support to specify sourceRectHint with
+ // non-match parent activity.
+ // If there's a PIP resize animation, we should offset the bounds to
+ // (0, 0) since the window bounds should match the leash bounds in PIP
+ // mode.
+ getSurfaceTransactionHelper().cropAndPosition(tx, leash, base)
+ .scale(tx, leash, base, bounds, angle, inScaleTransition())
.round(tx, leash, base, bounds)
.shadow(tx, leash, shouldApplyShadowRadius());
}
@@ -680,7 +724,7 @@ public class PipAnimationController {
final Rect insets = computeInsets(fraction);
getSurfaceTransactionHelper().scaleAndCrop(tx, leash,
adjustedSourceRectHint, initialSourceValue, bounds, insets,
- isInPipDirection, fraction);
+ isInPipDirection, fraction, leashOffset);
final Rect sourceBounds = new Rect(initialContainerRect);
sourceBounds.inset(insets);
getSurfaceTransactionHelper()
@@ -733,8 +777,7 @@ public class PipAnimationController {
getSurfaceTransactionHelper()
.rotateAndScaleWithCrop(tx, leash, initialContainerRect, bounds,
insets, degree, x, y, isOutPipDirection,
- rotationDelta == ROTATION_270 /* clockwise */);
- getSurfaceTransactionHelper()
+ rotationDelta == ROTATION_270 /* clockwise */)
.round(tx, leash, sourceBounds, bounds)
.shadow(tx, leash, shouldApplyShadowRadius());
if (!handlePipTransaction(leash, tx, bounds, 1f /* alpha */)) {
@@ -772,7 +815,7 @@ public class PipAnimationController {
tx.setPosition(leash, 0, 0);
tx.setWindowCrop(leash, 0, 0);
} else {
- getSurfaceTransactionHelper().crop(tx, leash, destBounds);
+ getSurfaceTransactionHelper().cropAndPosition(tx, leash, destBounds);
}
if (mContentOverlay != null) {
clearContentOverlay();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java
index 3d1994cac534..b02bd0ffec6c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java
@@ -16,8 +16,10 @@
package com.android.wm.shell.pip;
+import android.annotation.NonNull;
import android.content.Context;
import android.graphics.Matrix;
+import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
import android.view.Choreographer;
@@ -68,52 +70,102 @@ public class PipSurfaceTransactionHelper {
* Operates the crop (and position) on a given transaction and leash
* @return same {@link PipSurfaceTransactionHelper} instance for method chaining
*/
- public PipSurfaceTransactionHelper crop(SurfaceControl.Transaction tx, SurfaceControl leash,
- Rect destinationBounds) {
+ public PipSurfaceTransactionHelper cropAndPosition(@NonNull SurfaceControl.Transaction tx,
+ @NonNull SurfaceControl leash, @NonNull Rect destinationBounds) {
tx.setWindowCrop(leash, destinationBounds.width(), destinationBounds.height())
.setPosition(leash, destinationBounds.left, destinationBounds.top);
return this;
}
/**
+ * Operates {@link SurfaceControl.Transaction#setCrop} on a given transaction and leash.
+ *
+ * @param tx the transaction to apply
+ * @param leash the leash to crop
+ * @param relativeDestinationBounds the bounds to crop, which is relative to the leash
+ * coordinate
+ * @return same {@link PipSurfaceTransactionHelper} instance for method chaining
+ */
+ public PipSurfaceTransactionHelper crop(@NonNull SurfaceControl.Transaction tx,
+ @NonNull SurfaceControl leash, @NonNull Rect relativeDestinationBounds) {
+ tx.setCrop(leash, relativeDestinationBounds);
+ return this;
+ }
+
+ /**
* Operates the scale (setMatrix) on a given transaction and leash
* @return same {@link PipSurfaceTransactionHelper} instance for method chaining
*/
public PipSurfaceTransactionHelper scale(SurfaceControl.Transaction tx, SurfaceControl leash,
Rect sourceBounds, Rect destinationBounds) {
mTmpDestinationRectF.set(destinationBounds);
- return scale(tx, leash, sourceBounds, mTmpDestinationRectF, 0 /* degrees */);
+ return scale(tx, leash, sourceBounds, mTmpDestinationRectF, 0 /* degrees */,
+ true /* shouldOffset */);
}
/**
* Operates the scale (setMatrix) on a given transaction and leash
* @return same {@link PipSurfaceTransactionHelper} instance for method chaining
*/
- public PipSurfaceTransactionHelper scale(SurfaceControl.Transaction tx, SurfaceControl leash,
- Rect sourceBounds, RectF destinationBounds) {
- return scale(tx, leash, sourceBounds, destinationBounds, 0 /* degrees */);
+ public PipSurfaceTransactionHelper scale(@NonNull SurfaceControl.Transaction tx,
+ @NonNull SurfaceControl leash, @NonNull Rect sourceBounds,
+ @NonNull RectF destinationBounds) {
+ return scale(tx, leash, sourceBounds, destinationBounds, 0 /* degrees */,
+ true /* shouldOffset */);
}
/**
- * Operates the scale (setMatrix) on a given transaction and leash
+ * Operates the scale (setMatrix) on a given transaction and leash.
+ *
+ * @param shouldOffset {@code true} to offset the leash to (0, 0)
* @return same {@link PipSurfaceTransactionHelper} instance for method chaining
*/
- public PipSurfaceTransactionHelper scale(SurfaceControl.Transaction tx, SurfaceControl leash,
- Rect sourceBounds, Rect destinationBounds, float degrees) {
+ public PipSurfaceTransactionHelper scale(@NonNull SurfaceControl.Transaction tx,
+ @NonNull SurfaceControl leash, @NonNull Rect sourceBounds,
+ @NonNull Rect destinationBounds, boolean shouldOffset) {
+ mTmpDestinationRectF.set(destinationBounds);
+ return scale(tx, leash, sourceBounds, mTmpDestinationRectF, 0 /* degrees */, shouldOffset);
+ }
+
+ /**
+ * Operates the scale (setMatrix) on a given transaction and leash.
+ *
+ * @return same {@link PipSurfaceTransactionHelper} instance for method chaining
+ */
+ public PipSurfaceTransactionHelper scale(@NonNull SurfaceControl.Transaction tx,
+ @NonNull SurfaceControl leash, @NonNull Rect sourceBounds,
+ @NonNull Rect destinationBounds, float degrees) {
+ return scale(tx, leash, sourceBounds, destinationBounds, degrees, true /* shouldOffset */);
+ }
+
+ /**
+ * Operates the scale (setMatrix) on a given transaction and leash.
+ *
+ * @param shouldOffset {@code true} to offset the leash to (0, 0)
+ * @return same {@link PipSurfaceTransactionHelper} instance for method chaining
+ */
+ public PipSurfaceTransactionHelper scale(@NonNull SurfaceControl.Transaction tx,
+ @NonNull SurfaceControl leash, @NonNull Rect sourceBounds,
+ @NonNull Rect destinationBounds, float degrees, boolean shouldOffset) {
mTmpDestinationRectF.set(destinationBounds);
- return scale(tx, leash, sourceBounds, mTmpDestinationRectF, degrees);
+ return scale(tx, leash, sourceBounds, mTmpDestinationRectF, degrees, shouldOffset);
}
/**
* Operates the scale (setMatrix) on a given transaction and leash, along with a rotation.
+ *
+ * @param shouldOffset {@code true} to offset the leash to (0, 0)
* @return same {@link PipSurfaceTransactionHelper} instance for method chaining
*/
- public PipSurfaceTransactionHelper scale(SurfaceControl.Transaction tx, SurfaceControl leash,
- Rect sourceBounds, RectF destinationBounds, float degrees) {
+ public PipSurfaceTransactionHelper scale(@NonNull SurfaceControl.Transaction tx,
+ @NonNull SurfaceControl leash, @NonNull Rect sourceBounds,
+ @NonNull RectF destinationBounds, float degrees, boolean shouldOffset) {
mTmpSourceRectF.set(sourceBounds);
// We want the matrix to position the surface relative to the screen coordinates so offset
- // the source to 0,0
- mTmpSourceRectF.offsetTo(0, 0);
+ // the source to (0, 0) if {@code shouldOffset} is true.
+ if (shouldOffset) {
+ mTmpSourceRectF.offsetTo(0, 0);
+ }
mTmpDestinationRectF.set(destinationBounds);
mTmpTransform.setRectToRect(mTmpSourceRectF, mTmpDestinationRectF, Matrix.ScaleToFit.FILL);
mTmpTransform.postRotate(degrees,
@@ -123,17 +175,19 @@ public class PipSurfaceTransactionHelper {
}
/**
- * Operates the scale (setMatrix) on a given transaction and leash
+ * Operates the scale (setMatrix) on a given transaction and leash.
+ *
+ * @param leashOffset the offset of the leash bounds relative to the screen coordinate
* @return same {@link PipSurfaceTransactionHelper} instance for method chaining
*/
- public PipSurfaceTransactionHelper scaleAndCrop(SurfaceControl.Transaction tx,
- SurfaceControl leash, Rect sourceRectHint,
- Rect sourceBounds, Rect destinationBounds, Rect insets,
- boolean isInPipDirection, float fraction) {
+ public PipSurfaceTransactionHelper scaleAndCrop(@NonNull SurfaceControl.Transaction tx,
+ @NonNull SurfaceControl leash, @NonNull Rect sourceRectHint, @NonNull Rect sourceBounds,
+ @NonNull Rect destinationBounds, @NonNull Rect insets, boolean isInPipDirection,
+ float fraction, @NonNull Point leashOffset) {
mTmpDestinationRect.set(sourceBounds);
// Similar to {@link #scale}, we want to position the surface relative to the screen
- // coordinates so offset the bounds to 0,0
- mTmpDestinationRect.offsetTo(0, 0);
+ // coordinates so offset the bounds relative to the leash.
+ mTmpDestinationRect.offset(-leashOffset.x, -leashOffset.y);
mTmpDestinationRect.inset(insets);
// Scale to the bounds no smaller than the destination and offset such that the top/left
// of the scaled inset source rect aligns with the top/left of the destination bounds
@@ -152,13 +206,13 @@ public class PipSurfaceTransactionHelper {
scale = Math.max((float) destinationBounds.width() / sourceBounds.width(),
(float) destinationBounds.height() / sourceBounds.height());
}
- float left = destinationBounds.left - insets.left * scale;
- float top = destinationBounds.top - insets.top * scale;
+ float left = destinationBounds.left - mTmpDestinationRect.left * scale;
+ float top = destinationBounds.top - mTmpDestinationRect.top * scale;
if (scale == 1) {
// Work around the 1 pixel off error by rounding the position down at very beginning.
// We noticed such error from flicker tests, not visually.
- left = sourceBounds.left;
- top = sourceBounds.top;
+ left = leashOffset.x;
+ top = leashOffset.y;
}
mTmpTransform.setScale(scale, scale);
tx.setMatrix(leash, mTmpTransform, mTmpFloat9)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
index b4e03299f14c..c4e63dfdade9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
@@ -960,7 +960,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
final SurfaceControl.Transaction boundsChangeTx =
mSurfaceControlTransactionFactory.getTransaction();
mSurfaceTransactionHelper
- .crop(boundsChangeTx, mLeash, destinationBounds)
+ .cropAndPosition(boundsChangeTx, mLeash, destinationBounds)
.round(boundsChangeTx, mLeash, true /* applyCornerRadius */);
mPipTransitionState.setTransitionState(PipTransitionState.ENTRY_SCHEDULED);
@@ -988,7 +988,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
final SurfaceControl.Transaction tx = mSurfaceControlTransactionFactory.getTransaction();
mSurfaceTransactionHelper
.resetScale(tx, mLeash, destinationBounds)
- .crop(tx, mLeash, destinationBounds)
+ .cropAndPosition(tx, mLeash, destinationBounds)
.round(tx, mLeash, isInPip());
// The animation is finished in the Launcher and here we directly apply the final touch.
applyEnterPipSyncTransaction(destinationBounds, () -> {
@@ -1525,7 +1525,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
mPipBoundsState.setBounds(toBounds);
final SurfaceControl.Transaction tx = mSurfaceControlTransactionFactory.getTransaction();
mSurfaceTransactionHelper
- .crop(tx, mLeash, toBounds)
+ .cropAndPosition(tx, mLeash, toBounds)
.round(tx, mLeash, mPipTransitionState.isInPip());
if (shouldSyncPipTransactionWithMenu()) {
mPipMenuController.resizePipMenu(mLeash, tx, toBounds);
@@ -1628,7 +1628,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
Rect destinationBounds) {
final SurfaceControl.Transaction tx = mSurfaceControlTransactionFactory.getTransaction();
mSurfaceTransactionHelper
- .crop(tx, mLeash, destinationBounds)
+ .cropAndPosition(tx, mLeash, destinationBounds)
.resetScale(tx, mLeash, destinationBounds)
.round(tx, mLeash, mPipTransitionState.isInPip());
return tx;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
index 6da39951efbe..9aa5066fc76c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
@@ -551,7 +551,7 @@ public class PipTransition extends PipTransitionController {
}
// Reset the scale with bounds change synchronously.
if (hasValidLeash) {
- mSurfaceTransactionHelper.crop(tx, leash, destinationBounds)
+ mSurfaceTransactionHelper.cropAndPosition(tx, leash, destinationBounds)
.resetScale(tx, leash, destinationBounds)
.round(tx, leash, true /* applyCornerRadius */);
final Rect appBounds = mPipOrganizer.mAppBounds;
@@ -588,7 +588,8 @@ public class PipTransition extends PipTransitionController {
ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
"%s: Destination bounds were changed during animation", TAG);
rotateBounds(finishBounds, displayBounds, mEndFixedRotation, displayRotation);
- mSurfaceTransactionHelper.crop(mFinishTransaction, leash, finishBounds);
+ mSurfaceTransactionHelper.cropAndPosition(mFinishTransaction, leash,
+ finishBounds);
}
}
mFinishTransaction = null;
@@ -1068,6 +1069,11 @@ public class PipTransition extends PipTransitionController {
mPipBoundsState.mayUseCachedLauncherShelfHeight();
final Rect destinationBounds = mPipBoundsAlgorithm.getEntryDestinationBounds();
final Rect currentBounds = pipChange.getStartAbsBounds();
+ // The app bounds should offset relative to the task leash to make the center calculation
+ // correctly.
+ final Rect relativeAppBounds = new Rect(taskInfo.topActivityMainWindowFrame != null
+ ? taskInfo.topActivityMainWindowFrame : currentBounds);
+ relativeAppBounds.offset(-currentBounds.left, -currentBounds.top);
int rotationDelta = deltaRotation(startRotation, endRotation);
Rect sourceHintRect = mPipOrganizer.takeSwipeSourceRectHint();
@@ -1089,6 +1095,8 @@ public class PipTransition extends PipTransitionController {
if (taskInfo.pictureInPictureParams != null
&& taskInfo.pictureInPictureParams.isAutoEnterEnabled()
&& mPipTransitionState.getInSwipePipToHomeTransition()) {
+ // TODO(b/356277166): add support to swipe PIP to home with
+ // non-match parent activity.
handleSwipePipToHomeTransition(startTransaction, finishTransaction, leash,
sourceHintRect, destinationBounds, taskInfo);
return;
@@ -1119,8 +1127,8 @@ public class PipTransition extends PipTransitionController {
// TODO(b/272819817): cleanup the null-check and extra logging.
final boolean hasTopActivityInfo = taskInfo.topActivityInfo != null;
if (hasTopActivityInfo && mFixedRotationState != FIXED_ROTATION_TRANSITION) {
- animator.setAppIconContentOverlay(
- mContext, currentBounds, destinationBounds, taskInfo.topActivityInfo,
+ animator.setAppIconContentOverlay(mContext, relativeAppBounds,
+ destinationBounds, taskInfo.topActivityInfo,
mPipBoundsState.getLauncherState().getAppIconSizePx());
} else {
ProtoLog.w(ShellProtoLogGroup.WM_SHELL_TRANSITIONS,
@@ -1149,14 +1157,14 @@ public class PipTransition extends PipTransitionController {
animationDuration = 0;
}
mSurfaceTransactionHelper
- .crop(finishTransaction, leash, destinationBounds)
+ .cropAndPosition(finishTransaction, leash, destinationBounds)
.round(finishTransaction, leash, true /* applyCornerRadius */);
// Always reset to bounds animation type afterwards.
setEnterAnimationType(ANIM_TYPE_BOUNDS);
} else {
throw new RuntimeException("Unrecognized animation type: " + enterAnimationType);
}
- mPipOrganizer.setContentOverlay(animator.getContentOverlayLeash(), currentBounds);
+ mPipOrganizer.setContentOverlay(animator.getContentOverlayLeash(), relativeAppBounds);
animator.setTransitionDirection(TRANSITION_DIRECTION_TO_PIP)
.setPipAnimationCallback(mPipAnimationCallback)
.setDuration(animationDuration);
@@ -1340,11 +1348,11 @@ public class PipTransition extends PipTransitionController {
"%s: Update pip for unhandled transition, change=%s, destBounds=%s, isInPip=%b",
TAG, pipChange, destBounds, isInPip);
mSurfaceTransactionHelper
- .crop(startTransaction, leash, destBounds)
+ .cropAndPosition(startTransaction, leash, destBounds)
.round(startTransaction, leash, isInPip)
.shadow(startTransaction, leash, isInPip);
mSurfaceTransactionHelper
- .crop(finishTransaction, leash, destBounds)
+ .cropAndPosition(finishTransaction, leash, destBounds)
.round(finishTransaction, leash, isInPip)
.shadow(finishTransaction, leash, isInPip);
// Make sure the PiP keeps invisible if it was faded out. If it needs to fade in, that will
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipTransition.java
index 7a0e6694cb51..affa6aaa5d07 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipTransition.java
@@ -338,7 +338,7 @@ public class TvPipTransition extends PipTransitionController {
final Rect pipBounds = mPipBoundsState.getBounds();
mSurfaceTransactionHelper
.resetScale(startTransaction, pipLeash, pipBounds)
- .crop(startTransaction, pipLeash, pipBounds)
+ .cropAndPosition(startTransaction, pipLeash, pipBounds)
.shadow(startTransaction, pipLeash, false);
final SurfaceControl.Transaction transaction = mTransactionFactory.getTransaction();
@@ -420,7 +420,7 @@ public class TvPipTransition extends PipTransitionController {
mSurfaceTransactionHelper
.resetScale(finishTransaction, leash, pipBounds)
- .crop(finishTransaction, leash, pipBounds)
+ .cropAndPosition(finishTransaction, leash, pipBounds)
.shadow(finishTransaction, leash, false);
final Rect currentBounds = pipChange.getStartAbsBounds();
@@ -443,7 +443,7 @@ public class TvPipTransition extends PipTransitionController {
SurfaceControl.Transaction tx = mTransactionFactory.getTransaction();
mSurfaceTransactionHelper
.resetScale(tx, leash, pipBounds)
- .crop(tx, leash, pipBounds)
+ .cropAndPosition(tx, leash, pipBounds)
.shadow(tx, leash, false);
mShellTaskOrganizer.applyTransaction(resizePipWct);
tx.apply();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/animation/PipResizeAnimator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/animation/PipResizeAnimator.java
index d565776c9917..012dabbbb9f8 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/animation/PipResizeAnimator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/animation/PipResizeAnimator.java
@@ -17,6 +17,7 @@
package com.android.wm.shell.pip2.animation;
import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
import android.animation.RectEvaluator;
import android.animation.ValueAnimator;
import android.content.Context;
@@ -27,13 +28,13 @@ import android.view.SurfaceControl;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.wm.shell.pip2.PipSurfaceTransactionHelper;
/**
* Animator that handles any resize related animation for PIP.
*/
-public class PipResizeAnimator extends ValueAnimator
- implements ValueAnimator.AnimatorUpdateListener, Animator.AnimatorListener{
+public class PipResizeAnimator extends ValueAnimator {
@NonNull
private final Context mContext;
@NonNull
@@ -61,9 +62,47 @@ public class PipResizeAnimator extends ValueAnimator
private final Rect mAnimatedRect = new Rect();
private final float mDelta;
- private final PipSurfaceTransactionHelper.SurfaceControlTransactionFactory
+ private PipSurfaceTransactionHelper.SurfaceControlTransactionFactory
mSurfaceControlTransactionFactory;
+ private final Animator.AnimatorListener mAnimatorListener = new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ super.onAnimationStart(animation);
+ if (mAnimationStartCallback != null) {
+ mAnimationStartCallback.run();
+ }
+ if (mStartTx != null) {
+ setBoundsAndRotation(mStartTx, mLeash, mBaseBounds, mStartBounds, mDelta);
+ mStartTx.apply();
+ }
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ super.onAnimationEnd(animation);
+ if (mFinishTx != null) {
+ setBoundsAndRotation(mFinishTx, mLeash, mBaseBounds, mEndBounds, 0f);
+ }
+ if (mAnimationEndCallback != null) {
+ mAnimationEndCallback.run();
+ }
+ }
+ };
+
+ private final ValueAnimator.AnimatorUpdateListener mAnimatorUpdateListener =
+ new AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(@NonNull ValueAnimator animation) {
+ final SurfaceControl.Transaction tx =
+ mSurfaceControlTransactionFactory.getTransaction();
+ final float fraction = getAnimatedFraction();
+ final float degrees = (1.0f - fraction) * mDelta;
+ setBoundsAndRotation(tx, mLeash, mBaseBounds, mAnimatedRect, degrees);
+ tx.apply();
+ }
+ };
+
public PipResizeAnimator(@NonNull Context context,
@NonNull SurfaceControl leash,
@Nullable SurfaceControl.Transaction startTransaction,
@@ -89,8 +128,8 @@ public class PipResizeAnimator extends ValueAnimator
mRectEvaluator = new RectEvaluator(mAnimatedRect);
setObjectValues(startBounds, endBounds);
- addListener(this);
- addUpdateListener(this);
+ addListener(mAnimatorListener);
+ addUpdateListener(mAnimatorUpdateListener);
setEvaluator(mRectEvaluator);
setDuration(duration);
}
@@ -103,26 +142,6 @@ public class PipResizeAnimator extends ValueAnimator
mAnimationEndCallback = runnable;
}
- @Override
- public void onAnimationStart(@NonNull Animator animation) {
- if (mAnimationStartCallback != null) {
- mAnimationStartCallback.run();
- }
- if (mStartTx != null) {
- setBoundsAndRotation(mStartTx, mLeash, mBaseBounds, mStartBounds, mDelta);
- mStartTx.apply();
- }
- }
-
- @Override
- public void onAnimationUpdate(@NonNull ValueAnimator animation) {
- final SurfaceControl.Transaction tx = mSurfaceControlTransactionFactory.getTransaction();
- final float fraction = getAnimatedFraction();
- final float degrees = (1.0f - fraction) * mDelta;
- setBoundsAndRotation(tx, mLeash, mBaseBounds, mAnimatedRect, degrees);
- tx.apply();
- }
-
/**
* Set a proper transform matrix for a leash to move it to given bounds with a certain rotation.
*
@@ -130,7 +149,7 @@ public class PipResizeAnimator extends ValueAnimator
* @param targetBounds bounds to which we are scaling the leash.
* @param degrees degrees of rotation - counter-clockwise is positive by convention.
*/
- public static void setBoundsAndRotation(SurfaceControl.Transaction tx, SurfaceControl leash,
+ private static void setBoundsAndRotation(SurfaceControl.Transaction tx, SurfaceControl leash,
Rect baseBounds, Rect targetBounds, float degrees) {
Matrix transformTensor = new Matrix();
final float[] mMatrixTmp = new float[9];
@@ -144,19 +163,9 @@ public class PipResizeAnimator extends ValueAnimator
tx.setMatrix(leash, transformTensor, mMatrixTmp);
}
- @Override
- public void onAnimationEnd(@NonNull Animator animation) {
- if (mFinishTx != null) {
- setBoundsAndRotation(mFinishTx, mLeash, mBaseBounds, mEndBounds, 0f);
- }
- if (mAnimationEndCallback != null) {
- mAnimationEndCallback.run();
- }
+ @VisibleForTesting
+ void setSurfaceControlTransactionFactory(@NonNull
+ PipSurfaceTransactionHelper.SurfaceControlTransactionFactory factory) {
+ mSurfaceControlTransactionFactory = factory;
}
-
- @Override
- public void onAnimationCancel(@NonNull Animator animation) {}
-
- @Override
- public void onAnimationRepeat(@NonNull Animator animation) {}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/IRecentTasksListener.aidl b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/IRecentTasksListener.aidl
index 245829ecafb3..371bdd5c6469 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/IRecentTasksListener.aidl
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/IRecentTasksListener.aidl
@@ -45,4 +45,7 @@ oneway interface IRecentTasksListener {
/** A task has moved to front. */
oneway void onTaskMovedToFront(in RunningTaskInfo taskInfo);
+
+ /** A task info has changed. */
+ oneway void onTaskInfoChanged(in RunningTaskInfo taskInfo);
} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
index 6086801491e2..faa20159f64a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
@@ -47,7 +47,6 @@ import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import com.android.internal.protolog.ProtoLog;
-import com.android.window.flags.Flags;
import com.android.wm.shell.common.ExternalInterfaceBinder;
import com.android.wm.shell.common.RemoteCallable;
import com.android.wm.shell.common.ShellExecutor;
@@ -289,6 +288,11 @@ public class RecentTasksController implements TaskStackListenerCallback,
}
@Override
+ public void onTaskChangedThroughTransition(@NonNull ActivityManager.RunningTaskInfo taskInfo) {
+ notifyTaskInfoChanged(taskInfo);
+ }
+
+ @Override
public void onTaskMovedToFrontThroughTransition(
ActivityManager.RunningTaskInfo runningTaskInfo) {
notifyTaskMovedToFront(runningTaskInfo);
@@ -355,6 +359,19 @@ public class RecentTasksController implements TaskStackListenerCallback,
}
}
+ private void notifyTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo) {
+ if (mListener == null
+ || !DesktopModeFlags.ENABLE_TASK_STACK_OBSERVER_IN_SHELL.isTrue()
+ || taskInfo.realActivity == null) {
+ return;
+ }
+ try {
+ mListener.onTaskInfoChanged(taskInfo);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Failed call onTaskInfoChanged", e);
+ }
+ }
+
private void notifyTaskMovedToFront(ActivityManager.RunningTaskInfo taskInfo) {
if (mListener == null
|| !DesktopModeFlags.ENABLE_TASK_STACK_OBSERVER_IN_SHELL.isTrue()
@@ -426,7 +443,7 @@ public class RecentTasksController implements TaskStackListenerCallback,
// If task has their app bounds set to null which happens after reboot, set the
// app bounds to persisted lastFullscreenBounds. Also set the position in parent
// to the top left of the bounds.
- if (Flags.enableDesktopWindowingPersistence()
+ if (DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PERSISTENCE.isTrue()
&& taskInfo.configuration.windowConfiguration.getAppBounds() == null) {
taskInfo.configuration.windowConfiguration.setAppBounds(
taskInfo.lastNonFullscreenBounds);
@@ -636,6 +653,11 @@ public class RecentTasksController implements TaskStackListenerCallback,
public void onTaskMovedToFront(ActivityManager.RunningTaskInfo taskInfo) {
mListener.call(l -> l.onTaskMovedToFront(taskInfo));
}
+
+ @Override
+ public void onTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo) {
+ mListener.call(l -> l.onTaskInfoChanged(taskInfo));
+ }
};
public IRecentTasksImpl(RecentTasksController controller) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/TaskStackTransitionObserver.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/TaskStackTransitionObserver.kt
index 1af99f974a28..d28a462546f9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/TaskStackTransitionObserver.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/TaskStackTransitionObserver.kt
@@ -20,8 +20,9 @@ import android.app.ActivityManager.RunningTaskInfo
import android.os.IBinder
import android.util.ArrayMap
import android.view.SurfaceControl
-import android.window.TransitionInfo
+import android.view.WindowManager.TRANSIT_CHANGE
import android.window.DesktopModeFlags
+import android.window.TransitionInfo
import com.android.wm.shell.shared.TransitionUtil
import com.android.wm.shell.sysui.ShellInit
import com.android.wm.shell.transition.Transitions
@@ -69,8 +70,10 @@ class TaskStackTransitionObserver(
// Find the first task that is opening, this should be the one at the front after
// the transition
if (TransitionUtil.isOpeningType(change.mode)) {
- notifyTaskStackTransitionObserverListeners(taskInfo)
+ notifyOnTaskMovedToFront(taskInfo)
break
+ } else if (change.mode == TRANSIT_CHANGE) {
+ notifyOnTaskChanged(taskInfo)
}
}
}
@@ -95,15 +98,23 @@ class TaskStackTransitionObserver(
taskStackTransitionObserverListeners.remove(taskStackTransitionObserverListener)
}
- private fun notifyTaskStackTransitionObserverListeners(taskInfo: RunningTaskInfo) {
+ private fun notifyOnTaskMovedToFront(taskInfo: RunningTaskInfo) {
taskStackTransitionObserverListeners.forEach { (listener, executor) ->
executor.execute { listener.onTaskMovedToFrontThroughTransition(taskInfo) }
}
}
+ private fun notifyOnTaskChanged(taskInfo: RunningTaskInfo) {
+ taskStackTransitionObserverListeners.forEach { (listener, executor) ->
+ executor.execute { listener.onTaskChangedThroughTransition(taskInfo) }
+ }
+ }
+
/** Listener to use to get updates regarding task stack from this observer */
interface TaskStackTransitionObserverListener {
/** Called when a task is moved to front. */
fun onTaskMovedToFrontThroughTransition(taskInfo: RunningTaskInfo) {}
+ /** Called when a task info has changed. */
+ fun onTaskChangedThroughTransition(taskInfo: RunningTaskInfo) {}
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
index 3946b6173b0b..c9546731a193 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
@@ -180,12 +180,13 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
// all other cases, it is expected that the transition handler positions and crops the task
// in order to allow the handler time to animate before the task before the final
// position and crop are set.
- final boolean shouldSetTaskPositionAndCrop = mTaskDragResizer.isResizingOrAnimating();
+ final boolean shouldSetTaskVisibilityPositionAndCrop =
+ mTaskDragResizer.isResizingOrAnimating();
// Use |applyStartTransactionOnDraw| so that the transaction (that applies task crop) is
// synced with the buffer transaction (that draws the View). Both will be shown on screen
// at the same, whereas applying them independently causes flickering. See b/270202228.
relayout(taskInfo, t, t, true /* applyStartTransactionOnDraw */,
- shouldSetTaskPositionAndCrop, hasGlobalFocus);
+ shouldSetTaskVisibilityPositionAndCrop, hasGlobalFocus);
}
@VisibleForTesting
@@ -193,7 +194,7 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
RelayoutParams relayoutParams,
ActivityManager.RunningTaskInfo taskInfo,
boolean applyStartTransactionOnDraw,
- boolean setTaskCropAndPosition,
+ boolean shouldSetTaskVisibilityPositionAndCrop,
boolean isStatusBarVisible,
boolean isKeyguardVisibleAndOccluded,
InsetsState displayInsetsState,
@@ -206,7 +207,7 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
? R.dimen.freeform_decor_shadow_focused_thickness
: R.dimen.freeform_decor_shadow_unfocused_thickness;
relayoutParams.mApplyStartTransactionOnDraw = applyStartTransactionOnDraw;
- relayoutParams.mSetTaskPositionAndCrop = setTaskCropAndPosition;
+ relayoutParams.mSetTaskVisibilityPositionAndCrop = shouldSetTaskVisibilityPositionAndCrop;
relayoutParams.mIsCaptionVisible = taskInfo.isFreeform()
|| (isStatusBarVisible && !isKeyguardVisibleAndOccluded);
@@ -234,7 +235,7 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
@SuppressLint("MissingPermission")
void relayout(RunningTaskInfo taskInfo,
SurfaceControl.Transaction startT, SurfaceControl.Transaction finishT,
- boolean applyStartTransactionOnDraw, boolean setTaskCropAndPosition,
+ boolean applyStartTransactionOnDraw, boolean shouldSetTaskVisibilityPositionAndCrop,
boolean hasGlobalFocus) {
final boolean isFreeform =
taskInfo.getWindowingMode() == WindowConfiguration.WINDOWING_MODE_FREEFORM;
@@ -246,7 +247,8 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
final WindowContainerTransaction wct = new WindowContainerTransaction();
updateRelayoutParams(mRelayoutParams, taskInfo, applyStartTransactionOnDraw,
- setTaskCropAndPosition, mIsStatusBarVisible, mIsKeyguardVisibleAndOccluded,
+ shouldSetTaskVisibilityPositionAndCrop, mIsStatusBarVisible,
+ mIsKeyguardVisibleAndOccluded,
mDisplayController.getInsetsState(taskInfo.displayId), hasGlobalFocus);
relayout(mRelayoutParams, startT, finishT, wct, oldRootView, mResult);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
index a3324cc6f286..29b8ddd03970 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
@@ -130,7 +130,6 @@ import com.android.wm.shell.sysui.ShellInit;
import com.android.wm.shell.transition.FocusTransitionObserver;
import com.android.wm.shell.transition.Transitions;
import com.android.wm.shell.windowdecor.DesktopModeWindowDecoration.ExclusionRegionListener;
-import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalSystemViewContainer;
import com.android.wm.shell.windowdecor.extension.InsetsStateKt;
import com.android.wm.shell.windowdecor.extension.TaskInfoKt;
import com.android.wm.shell.windowdecor.viewholder.AppHeaderViewHolder;
@@ -181,7 +180,6 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
private boolean mTransitionDragActive;
private SparseArray<EventReceiver> mEventReceiversByDisplay = new SparseArray<>();
- private DesktopStatusBarInputLayerSupplier mStatusBarInputLayerSupplier;
private final ExclusionRegionListener mExclusionRegionListener =
new ExclusionRegionListenerImpl();
@@ -420,11 +418,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
return Unit.INSTANCE;
});
}
- if (Flags.enableHandleInputFix()) {
- mStatusBarInputLayerSupplier =
- new DesktopStatusBarInputLayerSupplier(mContext, mMainHandler);
- mFocusTransitionObserver.setLocalFocusTransitionListener(this, mMainExecutor);
- }
+ mFocusTransitionObserver.setLocalFocusTransitionListener(this, mMainExecutor);
}
@Override
@@ -480,7 +474,6 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
removeTaskFromEventReceiver(oldTaskInfo.displayId);
incrementEventReceiverTasks(taskInfo.displayId);
}
- decoration.setStatusBarInputLayer(getStatusBarInputLayer(taskInfo));
decoration.relayout(taskInfo, decoration.mHasGlobalFocus);
mActivityOrientationChangeHandler.ifPresent(handler ->
handler.handleActivityOrientationChange(oldTaskInfo, taskInfo));
@@ -519,7 +512,6 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
if (decoration == null) {
createWindowDecoration(taskInfo, taskSurface, startT, finishT);
} else {
- decoration.setStatusBarInputLayer(getStatusBarInputLayer(taskInfo));
decoration.relayout(taskInfo, startT, finishT, false /* applyStartTransactionOnDraw */,
false /* shouldSetTaskPositionAndCrop */,
mFocusTransitionObserver.hasGlobalFocus(taskInfo));
@@ -673,7 +665,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
decoration.closeHandleMenu();
// When the app enters split-select, the handle will no longer be visible, meaning
// we shouldn't receive input for it any longer.
- decoration.detachStatusBarInputLayer();
+ decoration.disposeStatusBarInputLayer();
mDesktopTasksController.requestSplit(decoration.mTaskInfo, false /* leftOrTop */);
}
@@ -1314,8 +1306,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
// should not be receiving any input.
if (resultType == TO_SPLIT_LEFT_INDICATOR
|| resultType == TO_SPLIT_RIGHT_INDICATOR) {
- relevantDecor.detachStatusBarInputLayer();
- // We should also detach the other split task's input layer if
+ relevantDecor.disposeStatusBarInputLayer();
+ // We should also dispose the other split task's input layer if
// applicable.
final int splitPosition = mSplitScreenController
.getSplitPosition(relevantDecor.mTaskInfo.taskId);
@@ -1328,7 +1320,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
mSplitScreenController.getTaskInfo(oppositePosition);
if (oppositeTaskInfo != null) {
mWindowDecorByTaskId.get(oppositeTaskInfo.taskId)
- .detachStatusBarInputLayer();
+ .disposeStatusBarInputLayer();
}
}
}
@@ -1578,7 +1570,6 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
touchEventListener, touchEventListener, touchEventListener, touchEventListener);
windowDecoration.setExclusionRegionListener(mExclusionRegionListener);
windowDecoration.setDragPositioningCallback(taskPositioner);
- windowDecoration.setStatusBarInputLayer(getStatusBarInputLayer(taskInfo));
windowDecoration.relayout(taskInfo, startT, finishT,
false /* applyStartTransactionOnDraw */, false /* shouldSetTaskPositionAndCrop */,
mFocusTransitionObserver.hasGlobalFocus(taskInfo));
@@ -1587,18 +1578,6 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
}
}
- /** Decide which cached status bar input layer should be used for a decoration. */
- private AdditionalSystemViewContainer getStatusBarInputLayer(
- RunningTaskInfo taskInfo
- ) {
- if (mStatusBarInputLayerSupplier == null) return null;
- return mStatusBarInputLayerSupplier.getStatusBarInputLayer(
- taskInfo,
- mSplitScreenController.getSplitPosition(taskInfo.taskId),
- mSplitScreenController.isLeftRightSplit()
- );
- }
-
private RunningTaskInfo getOtherSplitTask(int taskId) {
@SplitPosition int remainingTaskPosition = mSplitScreenController
.getSplitPosition(taskId) == SPLIT_POSITION_BOTTOM_OR_RIGHT
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
index 9f37358b6044..c443b760f7d1 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
@@ -106,7 +106,6 @@ import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
import com.android.wm.shell.shared.desktopmode.DesktopModeTransitionSource;
import com.android.wm.shell.shared.desktopmode.ManageWindowsViewContainer;
import com.android.wm.shell.splitscreen.SplitScreenController;
-import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalSystemViewContainer;
import com.android.wm.shell.windowdecor.extension.TaskInfoKt;
import com.android.wm.shell.windowdecor.viewholder.AppHandleViewHolder;
import com.android.wm.shell.windowdecor.viewholder.AppHeaderViewHolder;
@@ -206,7 +205,6 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
private final MultiInstanceHelper mMultiInstanceHelper;
private final WindowDecorCaptionHandleRepository mWindowDecorCaptionHandleRepository;
private final DesktopRepository mDesktopRepository;
- private AdditionalSystemViewContainer mStatusBarInputLayer;
DesktopModeWindowDecoration(
Context context,
@@ -392,18 +390,25 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
@Override
void relayout(ActivityManager.RunningTaskInfo taskInfo, boolean hasGlobalFocus) {
final SurfaceControl.Transaction t = mSurfaceControlTransactionSupplier.get();
- // The crop and position of the task should only be set when a task is fluid resizing. In
- // all other cases, it is expected that the transition handler positions and crops the task
- // in order to allow the handler time to animate before the task before the final
- // position and crop are set.
- final boolean shouldSetTaskPositionAndCrop = !DesktopModeStatus.isVeiledResizeEnabled()
- && mTaskDragResizer.isResizingOrAnimating();
+ // The visibility, crop and position of the task should only be set when a task is
+ // fluid resizing. In all other cases, it is expected that the transition handler sets
+ // those task properties to allow the handler time to animate with full control of the task
+ // leash. In general, allowing the window decoration to set any of these is likely to cause
+ // incorrect frames and flickering because relayouts from TaskListener#onTaskInfoChanged
+ // aren't synchronized with shell transition callbacks, so if they come too early it
+ // might show/hide or crop the task at a bad time.
+ // Fluid resizing is exempt from this because it intentionally doesn't use shell
+ // transitions to resize the task, so onTaskInfoChanged relayouts is the only way to make
+ // sure the crop is set correctly.
+ final boolean shouldSetTaskVisibilityPositionAndCrop =
+ !DesktopModeStatus.isVeiledResizeEnabled()
+ && mTaskDragResizer.isResizingOrAnimating();
// For headers only (i.e. in freeform): use |applyStartTransactionOnDraw| so that the
// transaction (that applies task crop) is synced with the buffer transaction (that draws
// the View). Both will be shown on screen at the same, whereas applying them independently
// causes flickering. See b/270202228.
final boolean applyTransactionOnDraw = taskInfo.isFreeform();
- relayout(taskInfo, t, t, applyTransactionOnDraw, shouldSetTaskPositionAndCrop,
+ relayout(taskInfo, t, t, applyTransactionOnDraw, shouldSetTaskVisibilityPositionAndCrop,
hasGlobalFocus);
if (!applyTransactionOnDraw) {
t.apply();
@@ -430,19 +435,19 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
void relayout(ActivityManager.RunningTaskInfo taskInfo,
SurfaceControl.Transaction startT, SurfaceControl.Transaction finishT,
- boolean applyStartTransactionOnDraw, boolean shouldSetTaskPositionAndCrop,
+ boolean applyStartTransactionOnDraw, boolean shouldSetTaskVisibilityPositionAndCrop,
boolean hasGlobalFocus) {
Trace.beginSection("DesktopModeWindowDecoration#relayout");
if (taskInfo.isFreeform()) {
// The Task is in Freeform mode -> show its header in sync since it's an integral part
// of the window itself - a delayed header might cause bad UX.
relayoutInSync(taskInfo, startT, finishT, applyStartTransactionOnDraw,
- shouldSetTaskPositionAndCrop, hasGlobalFocus);
+ shouldSetTaskVisibilityPositionAndCrop, hasGlobalFocus);
} else {
// The Task is outside Freeform mode -> allow the handle view to be delayed since the
// handle is just a small addition to the window.
relayoutWithDelayedViewHost(taskInfo, startT, finishT, applyStartTransactionOnDraw,
- shouldSetTaskPositionAndCrop, hasGlobalFocus);
+ shouldSetTaskVisibilityPositionAndCrop, hasGlobalFocus);
}
Trace.endSection();
}
@@ -450,12 +455,12 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
/** Run the whole relayout phase immediately without delay. */
private void relayoutInSync(ActivityManager.RunningTaskInfo taskInfo,
SurfaceControl.Transaction startT, SurfaceControl.Transaction finishT,
- boolean applyStartTransactionOnDraw, boolean shouldSetTaskPositionAndCrop,
+ boolean applyStartTransactionOnDraw, boolean shouldSetTaskVisibilityPositionAndCrop,
boolean hasGlobalFocus) {
// Clear the current ViewHost runnable as we will update the ViewHost here
clearCurrentViewHostRunnable();
updateRelayoutParamsAndSurfaces(taskInfo, startT, finishT, applyStartTransactionOnDraw,
- shouldSetTaskPositionAndCrop, hasGlobalFocus);
+ shouldSetTaskVisibilityPositionAndCrop, hasGlobalFocus);
if (mResult.mRootView != null) {
updateViewHost(mRelayoutParams, startT, mResult);
}
@@ -477,7 +482,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
*/
private void relayoutWithDelayedViewHost(ActivityManager.RunningTaskInfo taskInfo,
SurfaceControl.Transaction startT, SurfaceControl.Transaction finishT,
- boolean applyStartTransactionOnDraw, boolean shouldSetTaskPositionAndCrop,
+ boolean applyStartTransactionOnDraw, boolean shouldSetTaskVisibilityPositionAndCrop,
boolean hasGlobalFocus) {
if (applyStartTransactionOnDraw) {
throw new IllegalArgumentException(
@@ -486,7 +491,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
// Clear the current ViewHost runnable as we will update the ViewHost here
clearCurrentViewHostRunnable();
updateRelayoutParamsAndSurfaces(taskInfo, startT, finishT,
- false /* applyStartTransactionOnDraw */, shouldSetTaskPositionAndCrop,
+ false /* applyStartTransactionOnDraw */, shouldSetTaskVisibilityPositionAndCrop,
hasGlobalFocus);
if (mResult.mRootView == null) {
// This means something blocks the window decor from showing, e.g. the task is hidden.
@@ -501,7 +506,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
@SuppressLint("MissingPermission")
private void updateRelayoutParamsAndSurfaces(ActivityManager.RunningTaskInfo taskInfo,
SurfaceControl.Transaction startT, SurfaceControl.Transaction finishT,
- boolean applyStartTransactionOnDraw, boolean shouldSetTaskPositionAndCrop,
+ boolean applyStartTransactionOnDraw, boolean shouldSetTaskVisibilityPositionAndCrop,
boolean hasGlobalFocus) {
Trace.beginSection("DesktopModeWindowDecoration#updateRelayoutParamsAndSurfaces");
@@ -526,9 +531,9 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
final boolean inFullImmersive = mDesktopRepository
.isTaskInFullImmersiveState(taskInfo.taskId);
updateRelayoutParams(mRelayoutParams, mContext, taskInfo, applyStartTransactionOnDraw,
- shouldSetTaskPositionAndCrop, mIsStatusBarVisible, mIsKeyguardVisibleAndOccluded,
- inFullImmersive, mDisplayController.getInsetsState(taskInfo.displayId),
- hasGlobalFocus);
+ shouldSetTaskVisibilityPositionAndCrop, mIsStatusBarVisible,
+ mIsKeyguardVisibleAndOccluded, inFullImmersive,
+ mDisplayController.getInsetsState(taskInfo.displayId), hasGlobalFocus);
final WindowDecorLinearLayout oldRootView = mResult.mRootView;
final SurfaceControl oldDecorationSurface = mDecorationContainerSurface;
@@ -550,13 +555,13 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
notifyNoCaptionHandle();
}
mExclusionRegionListener.onExclusionRegionDismissed(mTaskInfo.taskId);
- detachStatusBarInputLayer();
+ disposeStatusBarInputLayer();
Trace.endSection(); // DesktopModeWindowDecoration#updateRelayoutParamsAndSurfaces
return;
}
if (oldRootView != mResult.mRootView) {
- detachStatusBarInputLayer();
+ disposeStatusBarInputLayer();
mWindowDecorViewHolder = createViewHolder();
}
Trace.beginSection("DesktopModeWindowDecoration#relayout-binding");
@@ -574,9 +579,6 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
mTaskInfo, position, mResult.mCaptionWidth, mResult.mCaptionHeight,
isCaptionVisible()
));
- if (mStatusBarInputLayer != null) {
- asAppHandle(mWindowDecorViewHolder).bindStatusBarInputLayer(mStatusBarInputLayer);
- }
} else {
mWindowDecorViewHolder.bindData(new AppHeaderViewHolder.HeaderData(
mTaskInfo,
@@ -790,15 +792,15 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
}
/**
- * Detach the status bar input layer from this decoration. Intended to be
+ * Dispose of the view used to forward inputs in status bar region. Intended to be
* used any time handle is no longer visible.
*/
- void detachStatusBarInputLayer() {
+ void disposeStatusBarInputLayer() {
if (!isAppHandle(mWindowDecorViewHolder)
|| !Flags.enableHandleInputFix()) {
return;
}
- asAppHandle(mWindowDecorViewHolder).detachStatusBarInputLayer();
+ asAppHandle(mWindowDecorViewHolder).disposeStatusBarInputLayer();
}
private WindowDecorationViewHolder createViewHolder() {
@@ -857,7 +859,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
Context context,
ActivityManager.RunningTaskInfo taskInfo,
boolean applyStartTransactionOnDraw,
- boolean shouldSetTaskPositionAndCrop,
+ boolean shouldSetTaskVisibilityPositionAndCrop,
boolean isStatusBarVisible,
boolean isKeyguardVisibleAndOccluded,
boolean inFullImmersiveMode,
@@ -953,7 +955,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
: R.dimen.freeform_decor_shadow_unfocused_thickness;
}
relayoutParams.mApplyStartTransactionOnDraw = applyStartTransactionOnDraw;
- relayoutParams.mSetTaskPositionAndCrop = shouldSetTaskPositionAndCrop;
+ relayoutParams.mSetTaskVisibilityPositionAndCrop = shouldSetTaskVisibilityPositionAndCrop;
// The configuration used to layout the window decoration. A copy is made instead of using
// the original reference so that the configuration isn't mutated on config changes and
@@ -1638,7 +1640,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
closeManageWindowsMenu();
mExclusionRegionListener.onExclusionRegionDismissed(mTaskInfo.taskId);
disposeResizeVeil();
- detachStatusBarInputLayer();
+ disposeStatusBarInputLayer();
clearCurrentViewHostRunnable();
if (canEnterDesktopMode(mContext) && Flags.enableDesktopWindowingAppHandleEducation()) {
notifyNoCaptionHandle();
@@ -1755,16 +1757,6 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
+ "}";
}
- /**
- * Set the view container to be used to forward input through status bar. Null in cases
- * where input forwarding isn't needed.
- */
- public void setStatusBarInputLayer(
- @Nullable AdditionalSystemViewContainer additionalSystemViewContainer
- ) {
- mStatusBarInputLayer = additionalSystemViewContainer;
- }
-
static class Factory {
DesktopModeWindowDecoration create(
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopStatusBarInputLayerSupplier.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopStatusBarInputLayerSupplier.kt
deleted file mode 100644
index 9c5215d1249c..000000000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopStatusBarInputLayerSupplier.kt
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * 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.wm.shell.windowdecor
-
-import android.app.ActivityManager.RunningTaskInfo
-import android.app.WindowConfiguration
-import android.content.Context
-import android.graphics.PixelFormat
-import android.os.Handler
-import android.view.Gravity
-import android.view.View
-import android.view.WindowManager
-import com.android.wm.shell.shared.annotations.ShellMainThread
-import com.android.wm.shell.shared.split.SplitScreenConstants
-import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalSystemViewContainer
-
-/**
- * Supplier for [AdditionalSystemViewContainer] objects to be used for forwarding input
- * events through status bar to an app handle. Currently supports two simultaneous input layers.
- *
- * The supplier will pick one of two input layer view containers to use: one for tasks in
- * fullscreen or top/left split stage, and one for tasks in right split stage.
- */
-class DesktopStatusBarInputLayerSupplier(
- private val context: Context,
- @ShellMainThread handler: Handler
-) {
- private val inputLayers: MutableList<AdditionalSystemViewContainer> = mutableListOf()
-
- init {
- // Post this as creation of the input layer views is a relatively expensive operation.
- handler.post {
- repeat(TOTAL_INPUT_LAYERS) {
- inputLayers.add(createInputLayer())
- }
- }
- }
-
- private fun createInputLayer(): AdditionalSystemViewContainer {
- val lp = WindowManager.LayoutParams(
- WindowManager.LayoutParams.TYPE_STATUS_BAR_ADDITIONAL,
- WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
- PixelFormat.TRANSPARENT
- )
- lp.title = "Desktop status bar input layer"
- lp.gravity = Gravity.LEFT or Gravity.TOP
- lp.setTrustedOverlay()
-
- // Make this window a spy window to enable it to pilfer pointers from the system-wide
- // gesture listener that receives events before window. This is to prevent notification
- // shade gesture when we swipe down to enter desktop.
- lp.inputFeatures = WindowManager.LayoutParams.INPUT_FEATURE_SPY
- lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
- val view = View(context)
- view.visibility = View.GONE
- return AdditionalSystemViewContainer(
- WindowManagerWrapper(
- context.getSystemService<WindowManager>(WindowManager::class.java)
- ),
- view,
- lp
- )
- }
-
- /**
- * Decide which cached status bar input layer should be used for a decoration, if any.
- *
- * [splitPosition] and [isLeftRightSplit] are used to determine which input layer we use.
- * The first one is reserved for fullscreen tasks or tasks in top/left split,
- * while the second one is exclusively used for tasks in right split stage. Note we care about
- * left-right vs top-bottom split as the bottom stage should not use an input layer.
- */
- fun getStatusBarInputLayer(
- taskInfo: RunningTaskInfo,
- @SplitScreenConstants.SplitPosition splitPosition: Int,
- isLeftRightSplit: Boolean
- ): AdditionalSystemViewContainer? {
- if (!taskInfo.isVisibleRequested) return null
- // Fullscreen and top/left split tasks will use the first input layer.
- if (taskInfo.windowingMode == WindowConfiguration.WINDOWING_MODE_FULLSCREEN
- || splitPosition == SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT
- ) {
- return inputLayers[LEFT_TOP_INPUT_LAYER]
- }
- // Right split tasks will use the second one.
- if (isLeftRightSplit && splitPosition == SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT
- ) {
- return inputLayers[RIGHT_SPLIT_INPUT_LAYER]
- }
- // Which leaves bottom split and freeform tasks, which do not need an input layer
- // as the status bar is not blocking them.
- return null
- }
-
- companion object {
- private const val TOTAL_INPUT_LAYERS = 2
- // Input layer index for fullscreen tasks and tasks in top-left split
- private const val LEFT_TOP_INPUT_LAYER = 0
- // Input layer index for tasks in right split stage. Does not include bottom split as that
- // stage is not blocked by status bar.
- private const val RIGHT_SPLIT_INPUT_LAYER = 1
- }
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
index f97dfb89bc0d..b016c755e323 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
@@ -249,7 +249,9 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
if (!mTaskInfo.isVisible) {
releaseViews(wct);
- finishT.hide(mTaskSurface);
+ if (params.mSetTaskVisibilityPositionAndCrop) {
+ finishT.hide(mTaskSurface);
+ }
return;
}
@@ -422,7 +424,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
private void updateTaskSurface(RelayoutParams params, SurfaceControl.Transaction startT,
SurfaceControl.Transaction finishT, RelayoutResult<T> outResult) {
- if (params.mSetTaskPositionAndCrop) {
+ if (params.mSetTaskVisibilityPositionAndCrop) {
final Point taskPosition = mTaskInfo.positionInParent;
startT.setWindowCrop(mTaskSurface, outResult.mWidth, outResult.mHeight);
finishT.setWindowCrop(mTaskSurface, outResult.mWidth, outResult.mHeight)
@@ -437,9 +439,13 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
shadowRadius =
loadDimension(mDecorWindowContext.getResources(), params.mShadowRadiusId);
}
- startT.setShadowRadius(mTaskSurface, shadowRadius).show(mTaskSurface);
+ startT.setShadowRadius(mTaskSurface, shadowRadius);
finishT.setShadowRadius(mTaskSurface, shadowRadius);
+ if (params.mSetTaskVisibilityPositionAndCrop) {
+ startT.show(mTaskSurface);
+ }
+
if (mTaskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
if (!DesktopModeStatus.isVeiledResizeEnabled()) {
// When fluid resize is enabled, add a background to freeform tasks
@@ -758,7 +764,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
Configuration mWindowDecorConfig;
boolean mApplyStartTransactionOnDraw;
- boolean mSetTaskPositionAndCrop;
+ boolean mSetTaskVisibilityPositionAndCrop;
boolean mHasGlobalFocus;
void reset() {
@@ -777,7 +783,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
mIsCaptionVisible = false;
mApplyStartTransactionOnDraw = false;
- mSetTaskPositionAndCrop = false;
+ mSetTaskVisibilityPositionAndCrop = false;
mWindowDecorConfig = null;
mHasGlobalFocus = false;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/additionalviewcontainer/AdditionalSystemViewContainer.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/additionalviewcontainer/AdditionalSystemViewContainer.kt
index 1451f363ec73..8b6aaaf619e0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/additionalviewcontainer/AdditionalSystemViewContainer.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/additionalviewcontainer/AdditionalSystemViewContainer.kt
@@ -23,8 +23,8 @@ import android.view.Gravity
import android.view.LayoutInflater
import android.view.SurfaceControl
import android.view.View
+import android.view.WindowInsets
import android.view.WindowManager
-import android.view.WindowManager.LayoutParams
import com.android.wm.shell.windowdecor.WindowManagerWrapper
/**
@@ -33,11 +33,27 @@ import com.android.wm.shell.windowdecor.WindowManagerWrapper
*/
class AdditionalSystemViewContainer(
private val windowManagerWrapper: WindowManagerWrapper,
- override val view: View,
- val lp: LayoutParams
+ taskId: Int,
+ x: Int,
+ y: Int,
+ width: Int,
+ height: Int,
+ flags: Int,
+ @WindowInsets.Type.InsetsType forciblyShownTypes: Int = 0,
+ override val view: View
) : AdditionalViewContainer() {
+ val lp: WindowManager.LayoutParams = WindowManager.LayoutParams(
+ width, height, x, y,
+ WindowManager.LayoutParams.TYPE_STATUS_BAR_ADDITIONAL,
+ flags,
+ PixelFormat.TRANSPARENT
+ ).apply {
+ title = "Additional view container of Task=$taskId"
+ gravity = Gravity.LEFT or Gravity.TOP
+ setTrustedOverlay()
+ this.forciblyShownTypes = forciblyShownTypes
+ }
- /** Provide a layout id of a view to inflate for this view container. */
constructor(
context: Context,
windowManagerWrapper: WindowManagerWrapper,
@@ -50,30 +66,15 @@ class AdditionalSystemViewContainer(
@LayoutRes layoutId: Int
) : this(
windowManagerWrapper = windowManagerWrapper,
- view = LayoutInflater.from(context).inflate(layoutId, null /* parent */),
- lp = createLayoutParams(x, y, width, height, flags, taskId)
+ taskId = taskId,
+ x = x,
+ y = y,
+ width = width,
+ height = height,
+ flags = flags,
+ view = LayoutInflater.from(context).inflate(layoutId, null /* parent */)
)
- /** Provide a view directly for this view container */
- constructor(
- windowManagerWrapper: WindowManagerWrapper,
- taskId: Int,
- x: Int,
- y: Int,
- width: Int,
- height: Int,
- flags: Int,
- view: View,
- forciblyShownTypes: Int = 0
- ) : this(
- windowManagerWrapper = windowManagerWrapper,
- view = view,
- lp = createLayoutParams(x, y, width, height, flags, taskId).apply {
- this.forciblyShownTypes = forciblyShownTypes
- }
- )
-
- /** Do not supply a view at all, instead creating the view container with a basic view. */
constructor(
context: Context,
windowManagerWrapper: WindowManagerWrapper,
@@ -85,7 +86,12 @@ class AdditionalSystemViewContainer(
flags: Int
) : this(
windowManagerWrapper = windowManagerWrapper,
- lp = createLayoutParams(x, y, width, height, flags, taskId),
+ taskId = taskId,
+ x = x,
+ y = y,
+ width = width,
+ height = height,
+ flags = flags,
view = View(context)
)
@@ -98,7 +104,7 @@ class AdditionalSystemViewContainer(
}
override fun setPosition(t: SurfaceControl.Transaction, x: Float, y: Float) {
- lp.apply {
+ val lp = (view.layoutParams as WindowManager.LayoutParams).apply {
this.x = x.toInt()
this.y = y.toInt()
}
@@ -118,29 +124,13 @@ class AdditionalSystemViewContainer(
): AdditionalSystemViewContainer =
AdditionalSystemViewContainer(
windowManagerWrapper = windowManagerWrapper,
- view = view,
- lp = createLayoutParams(x, y, width, height, flags, taskId)
+ taskId = taskId,
+ x = x,
+ y = y,
+ width = width,
+ height = height,
+ flags = flags,
+ view = view
)
}
- companion object {
- fun createLayoutParams(
- x: Int,
- y: Int,
- width: Int,
- height: Int,
- flags: Int,
- taskId: Int
- ): LayoutParams {
- return LayoutParams(
- width, height, x, y,
- LayoutParams.TYPE_STATUS_BAR_ADDITIONAL,
- flags,
- PixelFormat.TRANSPARENT
- ).apply {
- title = "Additional view container of Task=$taskId"
- gravity = Gravity.LEFT or Gravity.TOP
- setTrustedOverlay()
- }
- }
- }
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModel.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModel.kt
index ff418c6daa02..e43c3a613157 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModel.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModel.kt
@@ -21,10 +21,13 @@ import android.app.ActivityManager.RunningTaskInfo
import android.content.Context
import android.graphics.Rect
import android.util.SparseArray
+import android.window.DisplayAreaInfo
+import android.window.WindowContainerTransaction
import androidx.core.util.valueIterator
import com.android.internal.annotations.VisibleForTesting
import com.android.wm.shell.RootTaskDisplayAreaOrganizer
import com.android.wm.shell.ShellTaskOrganizer
+import com.android.wm.shell.common.DisplayChangeController
import com.android.wm.shell.common.DisplayController
import com.android.wm.shell.common.SyncTransactionQueue
import com.android.wm.shell.desktopmode.DesktopRepository
@@ -45,10 +48,16 @@ class DesktopTilingDecorViewModel(
private val toggleResizeDesktopTaskTransitionHandler: ToggleResizeDesktopTaskTransitionHandler,
private val returnToDragStartAnimator: ReturnToDragStartAnimator,
private val taskRepository: DesktopRepository,
-) {
+) : DisplayChangeController.OnDisplayChangingListener {
@VisibleForTesting
var tilingTransitionHandlerByDisplayId = SparseArray<DesktopTilingWindowDecoration>()
+ init {
+ // TODO(b/374309287): Move this interface implementation to
+ // [DesktopModeWindowDecorViewModel] when the migration is done.
+ displayController.addDisplayChangingController(this)
+ }
+
fun snapToHalfScreen(
taskInfo: ActivityManager.RunningTaskInfo,
desktopModeWindowDecoration: DesktopModeWindowDecoration,
@@ -102,7 +111,20 @@ class DesktopTilingDecorViewModel(
fun onUserChange() {
for (tilingHandler in tilingTransitionHandlerByDisplayId.valueIterator()) {
- tilingHandler.onUserChange()
+ tilingHandler.resetTilingSession()
}
}
+
+ override fun onDisplayChange(
+ displayId: Int,
+ fromRotation: Int,
+ toRotation: Int,
+ newDisplayAreaInfo: DisplayAreaInfo?,
+ t: WindowContainerTransaction?,
+ ) {
+ // Exit if the rotation hasn't changed or is changed by 180 degrees. [fromRotation] and
+ // [toRotation] can be one of the [@Surface.Rotation] values.
+ if ((fromRotation % 2 == toRotation % 2)) return
+ tilingTransitionHandlerByDisplayId.get(displayId)?.resetTilingSession()
+ }
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDividerWindowManager.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDividerWindowManager.kt
index 9bf1304f2b39..209eb5e501b2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDividerWindowManager.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDividerWindowManager.kt
@@ -23,6 +23,7 @@ import android.graphics.Rect
import android.graphics.Region
import android.os.Binder
import android.view.LayoutInflater
+import android.view.RoundedCorner
import android.view.SurfaceControl
import android.view.SurfaceControlViewHost
import android.view.View
@@ -53,12 +54,14 @@ class DesktopTilingDividerWindowManager(
private val transitionHandler: DesktopTilingWindowDecoration,
private val transactionSupplier: Supplier<SurfaceControl.Transaction>,
private var dividerBounds: Rect,
+ private val displayContext: Context,
) : WindowlessWindowManager(config, leash, null), DividerMoveCallback, View.OnLayoutChangeListener {
private lateinit var viewHost: SurfaceControlViewHost
private var tilingDividerView: TilingDividerView? = null
private var dividerShown = false
private var handleRegionWidth: Int = -1
private var setTouchRegion = true
+ private val maxRoundedCornerRadius = getMaxRoundedCornerRadius()
/**
* Gets bounds of divider window with screen based coordinate on the param Rect.
@@ -93,7 +96,11 @@ class DesktopTilingDividerWindowManager(
getDividerBounds(tmpDividerBounds)
dividerView.setup(this, tmpDividerBounds)
t.setRelativeLayer(leash, relativeLeash, 1)
- .setPosition(leash, dividerBounds.left.toFloat(), dividerBounds.top.toFloat())
+ .setPosition(
+ leash,
+ dividerBounds.left.toFloat() - maxRoundedCornerRadius,
+ dividerBounds.top.toFloat(),
+ )
.show(leash)
syncQueue.runInSync { transaction ->
transaction.merge(t)
@@ -144,7 +151,7 @@ class DesktopTilingDividerWindowManager(
*/
override fun onDividerMove(pos: Int): Boolean {
val t = transactionSupplier.get()
- t.setPosition(leash, pos.toFloat(), dividerBounds.top.toFloat())
+ t.setPosition(leash, pos.toFloat() - maxRoundedCornerRadius, dividerBounds.top.toFloat())
val dividerWidth = dividerBounds.width()
dividerBounds.set(pos, dividerBounds.top, pos + dividerWidth, dividerBounds.bottom)
return transitionHandler.onDividerHandleMoved(dividerBounds, t)
@@ -157,7 +164,7 @@ class DesktopTilingDividerWindowManager(
override fun onDividerMovedEnd(pos: Int) {
setSlippery(true)
val t = transactionSupplier.get()
- t.setPosition(leash, pos.toFloat(), dividerBounds.top.toFloat())
+ t.setPosition(leash, pos.toFloat() - maxRoundedCornerRadius, dividerBounds.top.toFloat())
val dividerWidth = dividerBounds.width()
dividerBounds.set(pos, dividerBounds.top, pos + dividerWidth, dividerBounds.bottom)
transitionHandler.onDividerHandleDragEnd(dividerBounds, t)
@@ -166,7 +173,7 @@ class DesktopTilingDividerWindowManager(
private fun getWindowManagerParams(): WindowManager.LayoutParams {
val lp =
WindowManager.LayoutParams(
- dividerBounds.width(),
+ dividerBounds.width() + 2 * maxRoundedCornerRadius,
dividerBounds.height(),
TYPE_DOCK_DIVIDER,
FLAG_NOT_FOCUSABLE or
@@ -225,4 +232,15 @@ class DesktopTilingDividerWindowManager(
}
viewHost.relayout(lp)
}
+
+ private fun getMaxRoundedCornerRadius(): Int {
+ val display = displayContext.display
+ return listOf(
+ RoundedCorner.POSITION_TOP_LEFT,
+ RoundedCorner.POSITION_TOP_RIGHT,
+ RoundedCorner.POSITION_BOTTOM_RIGHT,
+ RoundedCorner.POSITION_BOTTOM_LEFT,
+ )
+ .maxOf { position -> display.getRoundedCorner(position)?.getRadius() ?: 0 }
+ }
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt
index a7087aec3bb5..c46767c3a51d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt
@@ -195,6 +195,7 @@ class DesktopTilingWindowDecoration(
val builder = SurfaceControl.Builder()
rootTdaOrganizer.attachToDisplayArea(displayId, builder)
val leash = builder.setName(TILING_DIVIDER_TAG).setContainerLayer().build()
+ val displayContext = displayController.getDisplayContext(displayId) ?: return null
val tilingManager =
displayLayout?.let {
dividerBounds = inflateDividerBounds(it)
@@ -207,6 +208,7 @@ class DesktopTilingWindowDecoration(
this,
transactionSupplier,
dividerBounds,
+ displayContext,
)
}
// a leash to present the divider on top of, without re-parenting.
@@ -483,7 +485,7 @@ class DesktopTilingWindowDecoration(
}
}
- fun onUserChange() {
+ fun resetTilingSession() {
if (leftTaskResizingHelper != null) {
removeTask(leftTaskResizingHelper, taskVanished = false, shouldDelayUpdate = true)
leftTaskResizingHelper = null
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/TilingDividerView.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/TilingDividerView.kt
index f8113c219bd1..89229051941c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/TilingDividerView.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/TilingDividerView.kt
@@ -118,7 +118,7 @@ class TilingDividerView : FrameLayout, View.OnTouchListener, DragDetector.Motion
val dividerSize = resources.getDimensionPixelSize(R.dimen.split_divider_bar_width)
val backgroundLeft = (width - dividerSize) / 2
val backgroundTop = 0
- val backgroundRight = left + dividerSize
+ val backgroundRight = backgroundLeft + dividerSize
val backgroundBottom = height
backgroundRect.set(backgroundLeft, backgroundTop, backgroundRight, backgroundBottom)
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolder.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolder.kt
index c4e49466343e..b5700ffb046b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolder.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolder.kt
@@ -36,10 +36,13 @@ import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction
import android.widget.ImageButton
import androidx.core.view.ViewCompat
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat
+import com.android.internal.policy.SystemBarUtils
+import com.android.window.flags.Flags
import com.android.wm.shell.R
import com.android.wm.shell.shared.animation.Interpolators
import com.android.wm.shell.windowdecor.WindowManagerWrapper
import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalSystemViewContainer
+import com.android.wm.shell.windowdecor.viewholder.WindowDecorationViewHolder.Data
/**
* A desktop mode window decoration used when the window is in full "focus" (i.e. fullscreen/split).
@@ -66,12 +69,10 @@ internal class AppHandleViewHolder(
) : Data()
private lateinit var taskInfo: RunningTaskInfo
- private val position: Point = Point()
- private var width: Int = 0
- private var height: Int = 0
private val captionView: View = rootView.requireViewById(R.id.desktop_mode_caption)
private val captionHandle: ImageButton = rootView.requireViewById(R.id.caption_handle)
private val inputManager = context.getSystemService(InputManager::class.java)
+ private var statusBarInputLayerExists = false
// An invisible View that takes up the same coordinates as captionHandle but is layered
// above the status bar. The purpose of this View is to receive input intended for
@@ -111,54 +112,21 @@ internal class AppHandleViewHolder(
) {
captionHandle.imageTintList = ColorStateList.valueOf(getCaptionHandleBarColor(taskInfo))
this.taskInfo = taskInfo
- this.position.set(position)
- this.width = width
- this.height = height
- if (!isCaptionVisible && statusBarInputLayer != null) {
- detachStatusBarInputLayer()
+ // If handle is not in status bar region(i.e., bottom stage in vertical split),
+ // do not create an input layer
+ if (position.y >= SystemBarUtils.getStatusBarHeight(context)) return
+ if (!isCaptionVisible && statusBarInputLayerExists) {
+ disposeStatusBarInputLayer()
return
}
- }
-
- fun bindStatusBarInputLayer(
- statusBarLayer: AdditionalSystemViewContainer
- ) {
- // Input layer view modification takes a significant amount of time;
+ // Input layer view creation / modification takes a significant amount of time;
// post them so we don't hold up DesktopModeWindowDecoration#relayout.
- if (statusBarLayer == statusBarInputLayer) {
+ if (statusBarInputLayerExists) {
handler.post { updateStatusBarInputLayer(position) }
- return
- }
- // Remove the old input layer when changing to a new one.
- if (statusBarInputLayer != null) detachStatusBarInputLayer()
- if (statusBarLayer.view.visibility == View.GONE) {
- statusBarLayer.view.visibility = View.VISIBLE
- }
- statusBarInputLayer = statusBarLayer
- statusBarInputLayer?.let {
- inputLayer -> setupAppHandleA11y(inputLayer.view)
- }
- handler.post {
- val view = statusBarInputLayer?.view
- ?: error("Unable to find statusBarInputLayer View")
- // Caption handle is located within the status bar region, meaning the
- // DisplayPolicy will attempt to transfer this input to status bar if it's
- // a swipe down. Pilfer here to keep the gesture in handle alone.
- view.setOnTouchListener { v, event ->
- if (event.actionMasked == ACTION_DOWN) {
- inputManager.pilferPointers(v.viewRootImpl.inputToken)
- }
- captionHandle.dispatchTouchEvent(event)
- return@setOnTouchListener true
- }
- view.setOnHoverListener { _, event ->
- captionHandle.onHoverEvent(event)
- }
- val lp = statusBarInputLayer?.view?.layoutParams as WindowManager.LayoutParams
- lp.x = position.x
- lp.y = position.y
- lp.width = width
- lp.height = height
+ } else {
+ // Input layer is created on a delay; prevent multiple from being created.
+ statusBarInputLayerExists = true
+ handler.post { createStatusBarInputLayer(position, width, height) }
}
}
@@ -170,6 +138,40 @@ internal class AppHandleViewHolder(
animateCaptionHandleAlpha(startValue = 0f, endValue = 1f)
}
+ private fun createStatusBarInputLayer(handlePosition: Point,
+ handleWidth: Int,
+ handleHeight: Int) {
+ if (!Flags.enableHandleInputFix()) return
+ statusBarInputLayer = AdditionalSystemViewContainer(context, windowManagerWrapper,
+ taskInfo.taskId, handlePosition.x, handlePosition.y, handleWidth, handleHeight,
+ WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+ )
+ val view = statusBarInputLayer?.view ?: error("Unable to find statusBarInputLayer View")
+ val lp = statusBarInputLayer?.lp ?: error("Unable to find statusBarInputLayer " +
+ "LayoutParams")
+ lp.title = "Handle Input Layer of task " + taskInfo.taskId
+ lp.setTrustedOverlay()
+ // Make this window a spy window to enable it to pilfer pointers from the system-wide
+ // gesture listener that receives events before window. This is to prevent notification
+ // shade gesture when we swipe down to enter desktop.
+ lp.inputFeatures = WindowManager.LayoutParams.INPUT_FEATURE_SPY
+ view.setOnHoverListener { _, event ->
+ captionHandle.onHoverEvent(event)
+ }
+ // Caption handle is located within the status bar region, meaning the
+ // DisplayPolicy will attempt to transfer this input to status bar if it's
+ // a swipe down. Pilfer here to keep the gesture in handle alone.
+ view.setOnTouchListener { v, event ->
+ if (event.actionMasked == ACTION_DOWN) {
+ inputManager.pilferPointers(v.viewRootImpl.inputToken)
+ }
+ captionHandle.dispatchTouchEvent(event)
+ return@setOnTouchListener true
+ }
+ setupAppHandleA11y(view)
+ windowManagerWrapper.updateViewLayout(view, lp)
+ }
+
private fun setupAppHandleA11y(view: View) {
view.accessibilityDelegate = object : View.AccessibilityDelegate() {
override fun onInitializeAccessibilityNodeInfo(
@@ -222,12 +224,15 @@ internal class AppHandleViewHolder(
}
/**
- * Remove the input listeners from the input layer and remove it from this view holder.
+ * Remove the input layer from [WindowManager]. Should be used when caption handle
+ * is not visible.
*/
- fun detachStatusBarInputLayer() {
- statusBarInputLayer?.view?.setOnTouchListener(null)
- statusBarInputLayer?.view?.setOnHoverListener(null)
- statusBarInputLayer = null
+ fun disposeStatusBarInputLayer() {
+ statusBarInputLayerExists = false
+ handler.post {
+ statusBarInputLayer?.releaseView()
+ statusBarInputLayer = null
+ }
}
private fun getCaptionHandleBarColor(taskInfo: RunningTaskInfo): Int {
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
index 72d4dc6ffac9..13a8518ae8ed 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
@@ -700,7 +700,7 @@ public class BackAnimationControllerTest extends ShellTestCase {
eq(tInfo), eq(st), eq(ft), eq(callback));
mBackTransitionHandler.onAnimationFinished();
- final TransitionInfo.Change openToClose = createAppChange(openTaskId, TRANSIT_CLOSE,
+ final TransitionInfo.Change openToClose = createAppChangeFromChange(open, TRANSIT_CLOSE,
FLAG_BACK_GESTURE_ANIMATED);
tInfo2 = createTransitionInfo(TRANSIT_CLOSE_PREPARE_BACK_NAVIGATION, openToClose);
mBackTransitionHandler.mClosePrepareTransition = mock(IBinder.class);
@@ -830,6 +830,16 @@ public class BackAnimationControllerTest extends ShellTestCase {
return change;
}
+ private TransitionInfo.Change createAppChangeFromChange(
+ TransitionInfo.Change originalChange, @TransitionInfo.TransitionMode int mode,
+ @TransitionInfo.ChangeFlags int flags) {
+ final TransitionInfo.Change change = new TransitionInfo.Change(
+ originalChange.getTaskInfo().token, originalChange.getLeash());
+ change.setMode(mode);
+ change.setFlags(flags);
+ return change;
+ }
+
private static TransitionInfo createTransitionInfo(
@WindowManager.TransitionType int type, TransitionInfo.Change ... changes) {
final TransitionInfo info = new TransitionInfo(type, 0);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandlerTest.java
index fefa933c5208..a82e5e8434b2 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandlerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandlerTest.java
@@ -19,8 +19,6 @@ package com.android.wm.shell.desktopmode;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
-import static androidx.test.internal.runner.junit4.statement.UiThreadStatement.runOnUiThread;
-
import static com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_EXIT_DESKTOP_MODE_UNKNOWN;
import static org.junit.Assert.assertTrue;
@@ -28,6 +26,7 @@ import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
+import android.animation.AnimatorTestRule;
import android.annotation.NonNull;
import android.app.ActivityManager;
import android.app.WindowConfiguration;
@@ -36,6 +35,8 @@ import android.content.res.Resources;
import android.graphics.Point;
import android.os.Handler;
import android.os.IBinder;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
import android.util.DisplayMetrics;
import android.view.SurfaceControl;
import android.view.WindowManager;
@@ -53,17 +54,23 @@ import com.android.wm.shell.shared.desktopmode.DesktopModeTransitionSource;
import com.android.wm.shell.transition.Transitions;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
+import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import java.util.ArrayList;
import java.util.function.Supplier;
/** Tests of {@link com.android.wm.shell.desktopmode.ExitDesktopTaskTransitionHandler} */
@SmallTest
+@TestableLooper.RunWithLooper
+@RunWith(AndroidTestingRunner.class)
public class ExitDesktopTaskTransitionHandlerTest extends ShellTestCase {
+ @Rule
+ public final AnimatorTestRule mAnimatorTestRule = new AnimatorTestRule(this);
+
@Mock
private Transitions mTransitions;
@Mock
@@ -105,7 +112,7 @@ public class ExitDesktopTaskTransitionHandlerTest extends ShellTestCase {
}
@Test
- public void testTransitExitDesktopModeAnimation() throws Throwable {
+ public void testTransitExitDesktopModeAnimation() {
final int transitionType = TRANSIT_EXIT_DESKTOP_MODE_UNKNOWN;
final int taskId = 1;
WindowContainerTransaction wct = new WindowContainerTransaction();
@@ -118,21 +125,16 @@ public class ExitDesktopTaskTransitionHandlerTest extends ShellTestCase {
TransitionInfo.Change change =
createChange(WindowManager.TRANSIT_CHANGE, taskId, WINDOWING_MODE_FULLSCREEN);
TransitionInfo info = createTransitionInfo(TRANSIT_EXIT_DESKTOP_MODE_UNKNOWN, change);
- ArrayList<Exception> exceptions = new ArrayList<>();
- runOnUiThread(() -> {
- try {
- assertTrue(mExitDesktopTaskTransitionHandler
- .startAnimation(mToken, info,
- new SurfaceControl.Transaction(),
- new SurfaceControl.Transaction(),
- mTransitionFinishCallback));
- } catch (Exception e) {
- exceptions.add(e);
- }
- });
- if (!exceptions.isEmpty()) {
- throw exceptions.get(0);
- }
+
+ final boolean animated = mExitDesktopTaskTransitionHandler
+ .startAnimation(mToken, info,
+ new SurfaceControl.Transaction(),
+ new SurfaceControl.Transaction(),
+ mTransitionFinishCallback);
+ mAnimatorTestRule.advanceTimeBy(
+ ExitDesktopTaskTransitionHandler.FULLSCREEN_ANIMATION_DURATION);
+
+ assertTrue(animated);
}
private TransitionInfo.Change createChange(@WindowManager.TransitionType int type, int taskId,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/education/AppHandleEducationControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/education/AppHandleEducationControllerTest.kt
index 54198876955a..7dbadc9d9083 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/education/AppHandleEducationControllerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/education/AppHandleEducationControllerTest.kt
@@ -68,7 +68,6 @@ import org.mockito.kotlin.whenever
@SmallTest
@RunWith(AndroidTestingRunner::class)
@OptIn(ExperimentalCoroutinesApi::class)
-@Ignore("b/374328725")
class AppHandleEducationControllerTest : ShellTestCase() {
@JvmField
@Rule
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java
index e74c804d4f40..bcb7461bfae7 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java
@@ -280,7 +280,7 @@ public class PipTaskOrganizerTest extends ShellTestCase {
private void preparePipSurfaceTransactionHelper() {
doReturn(mMockPipSurfaceTransactionHelper).when(mMockPipSurfaceTransactionHelper)
- .crop(any(), any(), any());
+ .cropAndPosition(any(), any(), any());
doReturn(mMockPipSurfaceTransactionHelper).when(mMockPipSurfaceTransactionHelper)
.resetScale(any(), any(), any());
doReturn(mMockPipSurfaceTransactionHelper).when(mMockPipSurfaceTransactionHelper)
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/animation/PipResizeAnimatorTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/animation/PipResizeAnimatorTest.java
new file mode 100644
index 000000000000..0adb50b81896
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/animation/PipResizeAnimatorTest.java
@@ -0,0 +1,276 @@
+/*
+ * 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.wm.shell.pip2.animation;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
+import static org.mockito.kotlin.MatchersKt.eq;
+import static org.junit.Assert.assertEquals;
+
+import android.content.Context;
+import android.graphics.Matrix;
+import android.graphics.Rect;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.view.SurfaceControl;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.wm.shell.pip2.PipSurfaceTransactionHelper;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Unit test against {@link PipResizeAnimator}.
+ */
+@SmallTest
+@TestableLooper.RunWithLooper
+@RunWith(AndroidTestingRunner.class)
+public class PipResizeAnimatorTest {
+
+ private static final float FLOAT_COMPARISON_DELTA = 0.001f;
+
+ @Mock private Context mMockContext;
+
+ @Mock private PipSurfaceTransactionHelper.SurfaceControlTransactionFactory mMockFactory;
+
+ @Mock private SurfaceControl.Transaction mMockTransaction;
+
+ @Mock private SurfaceControl.Transaction mMockStartTransaction;
+
+ @Mock private SurfaceControl.Transaction mMockFinishTransaction;
+
+ @Mock private Runnable mMockStartCallback;
+
+ @Mock private Runnable mMockEndCallback;
+
+ private PipResizeAnimator mPipResizeAnimator;
+ private Rect mBaseBounds;
+ private Rect mStartBounds;
+ private Rect mEndBounds;
+ private SurfaceControl mTestLeash;
+ private ArgumentCaptor<Matrix> mArgumentCaptor;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ when(mMockFactory.getTransaction()).thenReturn(mMockTransaction);
+ when(mMockTransaction.setMatrix(any(SurfaceControl.class), any(Matrix.class), any()))
+ .thenReturn(mMockTransaction);
+ when(mMockStartTransaction.setMatrix(any(SurfaceControl.class), any(Matrix.class), any()))
+ .thenReturn(mMockStartTransaction);
+ when(mMockFinishTransaction.setMatrix(any(SurfaceControl.class), any(Matrix.class), any()))
+ .thenReturn(mMockFinishTransaction);
+
+ mArgumentCaptor = ArgumentCaptor.forClass(Matrix.class);
+ mTestLeash = new SurfaceControl.Builder()
+ .setContainerLayer()
+ .setName("PipResizeAnimatorTest")
+ .setCallsite("PipResizeAnimatorTest")
+ .build();
+ }
+
+ @Test
+ public void setAnimationStartCallback_resize_callbackStartCallback() {
+ mBaseBounds = new Rect(100, 100, 500, 500);
+ mStartBounds = new Rect(200, 200, 1_000, 1_000);
+ mEndBounds = new Rect(mBaseBounds);
+ final int duration = 10;
+ final float delta = 0;
+ mPipResizeAnimator = new PipResizeAnimator(mMockContext, mTestLeash,
+ mMockStartTransaction, mMockFinishTransaction,
+ mBaseBounds, mStartBounds, mEndBounds,
+ duration, delta);
+
+ mPipResizeAnimator.setAnimationStartCallback(mMockStartCallback);
+ mPipResizeAnimator.setAnimationEndCallback(mMockEndCallback);
+ InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
+ mPipResizeAnimator.start();
+ mPipResizeAnimator.pause();
+ });
+
+ verify(mMockStartCallback).run();
+ verifyZeroInteractions(mMockEndCallback);
+ }
+
+ @Test
+ public void setAnimationEndCallback_resize_callbackStartAndEndCallback() {
+ mBaseBounds = new Rect(100, 100, 500, 500);
+ mStartBounds = new Rect(200, 200, 1_000, 1_000);
+ mEndBounds = new Rect(mBaseBounds);
+ final int duration = 10;
+ final float delta = 0;
+ mPipResizeAnimator = new PipResizeAnimator(mMockContext, mTestLeash,
+ mMockStartTransaction, mMockFinishTransaction,
+ mBaseBounds, mStartBounds, mEndBounds,
+ duration, delta);
+
+ mPipResizeAnimator.setAnimationStartCallback(mMockStartCallback);
+ mPipResizeAnimator.setAnimationEndCallback(mMockEndCallback);
+ InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
+ mPipResizeAnimator.start();
+ mPipResizeAnimator.end();
+ });
+
+ verify(mMockStartCallback).run();
+ verify(mMockEndCallback).run();
+ }
+
+ @Test
+ public void onAnimationEnd_resizeDown_sizeChanged() {
+ // Resize from 800x800 to 400x400, eg. resize down
+ mBaseBounds = new Rect(100, 100, 500, 500);
+ mStartBounds = new Rect(200, 200, 1_000, 1_000);
+ mEndBounds = new Rect(mBaseBounds);
+ final int duration = 10;
+ final float delta = 0;
+ final float[] matrix = new float[9];
+ mPipResizeAnimator = new PipResizeAnimator(mMockContext, mTestLeash,
+ mMockStartTransaction, mMockFinishTransaction,
+ mBaseBounds, mStartBounds, mEndBounds,
+ duration, delta);
+ mPipResizeAnimator.setSurfaceControlTransactionFactory(mMockFactory);
+
+ mPipResizeAnimator.setAnimationStartCallback(mMockStartCallback);
+ mPipResizeAnimator.setAnimationEndCallback(mMockEndCallback);
+ InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
+ mPipResizeAnimator.start();
+ clearInvocations(mMockTransaction);
+ mPipResizeAnimator.end();
+ });
+
+ // Start transaction scales down from its final state
+ verify(mMockStartTransaction).setMatrix(eq(mTestLeash), mArgumentCaptor.capture(), any());
+ mArgumentCaptor.getValue().getValues(matrix);
+ assertEquals(matrix[Matrix.MSCALE_X],
+ mStartBounds.width() / (float) mEndBounds.width(), FLOAT_COMPARISON_DELTA);
+ assertEquals(matrix[Matrix.MSCALE_Y],
+ mStartBounds.height() / (float) mEndBounds.height(), FLOAT_COMPARISON_DELTA);
+ assertEquals(matrix[Matrix.MTRANS_X], mStartBounds.left, FLOAT_COMPARISON_DELTA);
+ assertEquals(matrix[Matrix.MTRANS_Y], mStartBounds.top, FLOAT_COMPARISON_DELTA);
+
+ // Final animation transaction scales to 1 and puts the leash at final position
+ verify(mMockTransaction).setMatrix(eq(mTestLeash), mArgumentCaptor.capture(), any());
+ mArgumentCaptor.getValue().getValues(matrix);
+ assertEquals(matrix[Matrix.MSCALE_X], 1f, FLOAT_COMPARISON_DELTA);
+ assertEquals(matrix[Matrix.MSCALE_Y], 1f, FLOAT_COMPARISON_DELTA);
+ assertEquals(matrix[Matrix.MTRANS_X], mEndBounds.left, FLOAT_COMPARISON_DELTA);
+ assertEquals(matrix[Matrix.MTRANS_Y], mEndBounds.top, FLOAT_COMPARISON_DELTA);
+
+ // Finish transaction resets scale and puts the leash at final position
+ verify(mMockFinishTransaction).setMatrix(eq(mTestLeash), mArgumentCaptor.capture(), any());
+ mArgumentCaptor.getValue().getValues(matrix);
+ assertEquals(matrix[Matrix.MSCALE_X], 1f, FLOAT_COMPARISON_DELTA);
+ assertEquals(matrix[Matrix.MSCALE_Y], 1f, FLOAT_COMPARISON_DELTA);
+ assertEquals(matrix[Matrix.MTRANS_X], mEndBounds.left, FLOAT_COMPARISON_DELTA);
+ assertEquals(matrix[Matrix.MTRANS_Y], mEndBounds.top, FLOAT_COMPARISON_DELTA);
+ }
+
+ @Test
+ public void onAnimationEnd_resizeUp_sizeChanged() {
+ // Resize from 400x400 to 800x800, eg. resize up
+ mBaseBounds = new Rect(200, 200, 1_000, 1_000);
+ mStartBounds = new Rect(100, 100, 500, 500);
+ mEndBounds = new Rect(mBaseBounds);
+ final int duration = 10;
+ final float delta = 0;
+ final float[] matrix = new float[9];
+ mPipResizeAnimator = new PipResizeAnimator(mMockContext, mTestLeash,
+ mMockStartTransaction, mMockFinishTransaction,
+ mBaseBounds, mStartBounds, mEndBounds,
+ duration, delta);
+ mPipResizeAnimator.setSurfaceControlTransactionFactory(mMockFactory);
+
+ mPipResizeAnimator.setAnimationStartCallback(mMockStartCallback);
+ mPipResizeAnimator.setAnimationEndCallback(mMockEndCallback);
+ InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
+ mPipResizeAnimator.start();
+ clearInvocations(mMockTransaction);
+ mPipResizeAnimator.end();
+ });
+
+ // Start transaction scales up from its final state
+ verify(mMockStartTransaction).setMatrix(eq(mTestLeash), mArgumentCaptor.capture(), any());
+ mArgumentCaptor.getValue().getValues(matrix);
+ assertEquals(matrix[Matrix.MSCALE_X],
+ mStartBounds.width() / (float) mEndBounds.width(), FLOAT_COMPARISON_DELTA);
+ assertEquals(matrix[Matrix.MSCALE_Y],
+ mStartBounds.height() / (float) mEndBounds.height(), FLOAT_COMPARISON_DELTA);
+ assertEquals(matrix[Matrix.MTRANS_X], mStartBounds.left, FLOAT_COMPARISON_DELTA);
+ assertEquals(matrix[Matrix.MTRANS_Y], mStartBounds.top, FLOAT_COMPARISON_DELTA);
+
+ // Final animation transaction scales to 1 and puts the leash at final position
+ verify(mMockTransaction).setMatrix(eq(mTestLeash), mArgumentCaptor.capture(), any());
+ mArgumentCaptor.getValue().getValues(matrix);
+ assertEquals(matrix[Matrix.MSCALE_X], 1f, FLOAT_COMPARISON_DELTA);
+ assertEquals(matrix[Matrix.MSCALE_Y], 1f, FLOAT_COMPARISON_DELTA);
+ assertEquals(matrix[Matrix.MTRANS_X], mEndBounds.left, FLOAT_COMPARISON_DELTA);
+ assertEquals(matrix[Matrix.MTRANS_Y], mEndBounds.top, FLOAT_COMPARISON_DELTA);
+
+ // Finish transaction resets scale and puts the leash at final position
+ verify(mMockFinishTransaction).setMatrix(eq(mTestLeash), mArgumentCaptor.capture(), any());
+ mArgumentCaptor.getValue().getValues(matrix);
+ assertEquals(matrix[Matrix.MSCALE_X], 1f, FLOAT_COMPARISON_DELTA);
+ assertEquals(matrix[Matrix.MSCALE_Y], 1f, FLOAT_COMPARISON_DELTA);
+ assertEquals(matrix[Matrix.MTRANS_X], mEndBounds.left, FLOAT_COMPARISON_DELTA);
+ assertEquals(matrix[Matrix.MTRANS_Y], mEndBounds.top, FLOAT_COMPARISON_DELTA);
+ }
+
+ @Test
+ public void onAnimationEnd_withInitialDelta_rotateToZeroDegree() {
+ mBaseBounds = new Rect(200, 200, 1_000, 1_000);
+ mStartBounds = new Rect(100, 100, 500, 500);
+ mEndBounds = new Rect(mBaseBounds);
+ final int duration = 10;
+ final float delta = 45;
+ final float[] matrix = new float[9];
+ mPipResizeAnimator = new PipResizeAnimator(mMockContext, mTestLeash,
+ mMockStartTransaction, mMockFinishTransaction,
+ mBaseBounds, mStartBounds, mEndBounds,
+ duration, delta);
+ mPipResizeAnimator.setSurfaceControlTransactionFactory(mMockFactory);
+
+ mPipResizeAnimator.setAnimationStartCallback(mMockStartCallback);
+ mPipResizeAnimator.setAnimationEndCallback(mMockEndCallback);
+ InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
+ mPipResizeAnimator.start();
+ clearInvocations(mMockTransaction);
+ mPipResizeAnimator.end();
+ });
+
+ // Final animation transaction sets skew to zero
+ verify(mMockTransaction).setMatrix(eq(mTestLeash), mArgumentCaptor.capture(), any());
+ mArgumentCaptor.getValue().getValues(matrix);
+ assertEquals(matrix[Matrix.MSKEW_X], 0f, FLOAT_COMPARISON_DELTA);
+ assertEquals(matrix[Matrix.MSKEW_Y], 0f, FLOAT_COMPARISON_DELTA);
+
+ // Finish transaction sets skew to zero
+ verify(mMockFinishTransaction).setMatrix(eq(mTestLeash), mArgumentCaptor.capture(), any());
+ mArgumentCaptor.getValue().getValues(matrix);
+ assertEquals(matrix[Matrix.MSKEW_X], 0f, FLOAT_COMPARISON_DELTA);
+ assertEquals(matrix[Matrix.MSKEW_Y], 0f, FLOAT_COMPARISON_DELTA);
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/TaskStackTransitionObserverTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/TaskStackTransitionObserverTest.kt
index afdb68776d04..efe4fb18f273 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/TaskStackTransitionObserverTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/TaskStackTransitionObserverTest.kt
@@ -34,6 +34,7 @@ import com.android.wm.shell.common.ShellExecutor
import com.android.wm.shell.sysui.ShellInit
import com.android.wm.shell.transition.TransitionInfoBuilder
import com.android.wm.shell.transition.Transitions
+import com.android.wm.shell.windowdecor.extension.isFullscreen
import com.google.common.truth.Truth.assertThat
import dagger.Lazy
import org.junit.Before
@@ -107,8 +108,8 @@ class TaskStackTransitionObserverTest {
callOnTransitionFinished()
executor.flushAll()
- assertThat(listener.taskInfoToBeNotified.taskId).isEqualTo(change.taskInfo?.taskId)
- assertThat(listener.taskInfoToBeNotified.windowingMode)
+ assertThat(listener.taskInfoOnTaskMovedToFront.taskId).isEqualTo(change.taskInfo?.taskId)
+ assertThat(listener.taskInfoOnTaskMovedToFront.windowingMode)
.isEqualTo(change.taskInfo?.windowingMode)
}
@@ -130,8 +131,8 @@ class TaskStackTransitionObserverTest {
callOnTransitionFinished()
executor.flushAll()
- assertThat(listener.taskInfoToBeNotified.taskId).isEqualTo(1)
- assertThat(listener.taskInfoToBeNotified.windowingMode)
+ assertThat(listener.taskInfoOnTaskMovedToFront.taskId).isEqualTo(1)
+ assertThat(listener.taskInfoOnTaskMovedToFront.windowingMode)
.isEqualTo(WindowConfiguration.WINDOWING_MODE_FULLSCREEN)
}
@@ -161,9 +162,9 @@ class TaskStackTransitionObserverTest {
callOnTransitionFinished()
executor.flushAll()
- assertThat(listener.taskInfoToBeNotified.taskId)
+ assertThat(listener.taskInfoOnTaskMovedToFront.taskId)
.isEqualTo(freeformOpenChange.taskInfo?.taskId)
- assertThat(listener.taskInfoToBeNotified.windowingMode)
+ assertThat(listener.taskInfoOnTaskMovedToFront.windowingMode)
.isEqualTo(freeformOpenChange.taskInfo?.windowingMode)
}
@@ -199,9 +200,15 @@ class TaskStackTransitionObserverTest {
callOnTransitionFinished()
executor.flushAll()
- assertThat(listener.taskInfoToBeNotified.taskId).isEqualTo(change.taskInfo?.taskId)
- assertThat(listener.taskInfoToBeNotified.windowingMode)
+ assertThat(listener.taskInfoOnTaskMovedToFront.taskId).isEqualTo(change.taskInfo?.taskId)
+ assertThat(listener.taskInfoOnTaskMovedToFront.windowingMode)
.isEqualTo(change.taskInfo?.windowingMode)
+
+ assertThat(listener.taskInfoOnTaskChanged.size).isEqualTo(1)
+ with(listener.taskInfoOnTaskChanged.last()) {
+ assertThat(taskId).isEqualTo(mergedChange.taskInfo?.taskId)
+ assertThat(windowingMode).isEqualTo(mergedChange.taskInfo?.windowingMode)
+ }
}
@Test
@@ -236,18 +243,151 @@ class TaskStackTransitionObserverTest {
callOnTransitionFinished()
executor.flushAll()
- assertThat(listener.taskInfoToBeNotified.taskId).isEqualTo(mergedChange.taskInfo?.taskId)
- assertThat(listener.taskInfoToBeNotified.windowingMode)
- .isEqualTo(mergedChange.taskInfo?.windowingMode)
+ assertThat(listener.taskInfoOnTaskMovedToFront.taskId)
+ .isEqualTo(mergedChange.taskInfo?.taskId)
+ assertThat(listener.taskInfoOnTaskMovedToFront.windowingMode)
+ .isEqualTo(mergedChange.taskInfo?.windowingMode)
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_TASK_STACK_OBSERVER_IN_SHELL)
+ fun taskChange_freeformWindowToFullscreenWindow_listenerNotified() {
+ val listener = TestListener()
+ val executor = TestShellExecutor()
+ transitionObserver.addTaskStackTransitionObserverListener(listener, executor)
+ val freeformState =
+ createChange(
+ WindowManager.TRANSIT_OPEN,
+ createTaskInfo(1, WindowConfiguration.WINDOWING_MODE_FREEFORM)
+ )
+ val transitionInfoOpen =
+ TransitionInfoBuilder(WindowManager.TRANSIT_OPEN, 0).addChange(freeformState).build()
+ callOnTransitionReady(transitionInfoOpen)
+ callOnTransitionFinished()
+ executor.flushAll()
+
+ assertThat(listener.taskInfoOnTaskMovedToFront.taskId)
+ .isEqualTo(freeformState.taskInfo?.taskId)
+ assertThat(listener.taskInfoOnTaskMovedToFront.windowingMode)
+ .isEqualTo(freeformState.taskInfo?.windowingMode)
+ assertThat(listener.taskInfoOnTaskMovedToFront.isFullscreen).isEqualTo(false)
+
+ // create change transition to update the windowing mode to full screen.
+ val fullscreenState =
+ createChange(
+ WindowManager.TRANSIT_CHANGE,
+ createTaskInfo(1, WindowConfiguration.WINDOWING_MODE_FULLSCREEN)
+ )
+ val transitionInfoChange =
+ TransitionInfoBuilder(WindowManager.TRANSIT_CHANGE, 0)
+ .addChange(fullscreenState)
+ .build()
+
+ callOnTransitionReady(transitionInfoChange)
+ callOnTransitionFinished()
+ executor.flushAll()
+
+ // Asserting whether freeformState remains the same as before the change
+ assertThat(listener.taskInfoOnTaskMovedToFront.taskId)
+ .isEqualTo(freeformState.taskInfo?.taskId)
+ assertThat(listener.taskInfoOnTaskMovedToFront.isFullscreen).isEqualTo(false)
+
+ // Asserting changes
+ assertThat(listener.taskInfoOnTaskChanged.size).isEqualTo(1)
+ with(listener.taskInfoOnTaskChanged.last()) {
+ assertThat(taskId).isEqualTo(fullscreenState.taskInfo?.taskId)
+ assertThat(isFullscreen).isEqualTo(true)
+ }
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_TASK_STACK_OBSERVER_IN_SHELL)
+ fun singleTransition_withOpenAndChange_onlyOpenIsNotified() {
+ val listener = TestListener()
+ val executor = TestShellExecutor()
+ transitionObserver.addTaskStackTransitionObserverListener(listener, executor)
+
+ // Creating multiple changes to be fired in a single transition
+ val freeformState =
+ createChange(
+ mode = WindowManager.TRANSIT_OPEN,
+ taskInfo = createTaskInfo(1, WindowConfiguration.WINDOWING_MODE_FREEFORM)
+ )
+ val fullscreenState =
+ createChange(
+ mode = WindowManager.TRANSIT_CHANGE,
+ taskInfo = createTaskInfo(1, WindowConfiguration.WINDOWING_MODE_FULLSCREEN)
+ )
+
+ val transitionInfoWithChanges =
+ TransitionInfoBuilder(WindowManager.TRANSIT_CHANGE, 0)
+ .addChange(freeformState)
+ .addChange(fullscreenState)
+ .build()
+
+ callOnTransitionReady(transitionInfoWithChanges)
+ callOnTransitionFinished()
+ executor.flushAll()
+
+ assertThat(listener.taskInfoOnTaskMovedToFront.taskId)
+ .isEqualTo(freeformState.taskInfo?.taskId)
+ assertThat(listener.taskInfoOnTaskMovedToFront.isFullscreen).isEqualTo(false)
+ assertThat(listener.taskInfoOnTaskChanged.size).isEqualTo(0)
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_ENABLE_TASK_STACK_OBSERVER_IN_SHELL)
+ fun singleTransition_withMultipleChanges_listenerNotified_forEachChange() {
+ val listener = TestListener()
+ val executor = TestShellExecutor()
+ transitionObserver.addTaskStackTransitionObserverListener(listener, executor)
+
+ val taskId = 1
+
+ // Creating multiple changes to be fired in a single transition
+ val changes =
+ listOf(
+ WindowConfiguration.WINDOWING_MODE_FREEFORM,
+ WindowConfiguration.WINDOW_CONFIG_DISPLAY_ROTATION,
+ WindowConfiguration.WINDOWING_MODE_FULLSCREEN
+ )
+ .map { change ->
+ createChange(
+ mode = WindowManager.TRANSIT_CHANGE,
+ taskInfo = createTaskInfo(taskId, change)
+ )
+ }
+
+ val transitionInfoWithChanges =
+ TransitionInfoBuilder(WindowManager.TRANSIT_CHANGE, 0)
+ .apply { changes.forEach { c -> this@apply.addChange(c) } }
+ .build()
+
+ callOnTransitionReady(transitionInfoWithChanges)
+ callOnTransitionFinished()
+ executor.flushAll()
+
+ assertThat(listener.taskInfoOnTaskChanged.size).isEqualTo(changes.size)
+ changes.forEachIndexed { index, change ->
+ assertThat(listener.taskInfoOnTaskChanged[index].taskId)
+ .isEqualTo(change.taskInfo?.taskId)
+ assertThat(listener.taskInfoOnTaskChanged[index].windowingMode)
+ .isEqualTo(change.taskInfo?.windowingMode)
+ }
}
class TestListener : TaskStackTransitionObserver.TaskStackTransitionObserverListener {
- var taskInfoToBeNotified = ActivityManager.RunningTaskInfo()
+ var taskInfoOnTaskMovedToFront = ActivityManager.RunningTaskInfo()
+ var taskInfoOnTaskChanged = mutableListOf<ActivityManager.RunningTaskInfo>()
override fun onTaskMovedToFrontThroughTransition(
taskInfo: ActivityManager.RunningTaskInfo
) {
- taskInfoToBeNotified = taskInfo
+ taskInfoOnTaskMovedToFront = taskInfo
+ }
+
+ override fun onTaskChangedThroughTransition(taskInfo: ActivityManager.RunningTaskInfo) {
+ taskInfoOnTaskChanged += taskInfo
}
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
index c42be7fef2a6..36c5be1d7191 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
@@ -946,7 +946,7 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
}
@Test
- fun testDecor_onClickToSplitScreen_detachesStatusBarInputLayer() {
+ fun testDecor_onClickToSplitScreen_disposesStatusBarInputLayer() {
val toSplitScreenListenerCaptor = forClass(Function0::class.java)
as ArgumentCaptor<Function0<Unit>>
val decor = createOpenTaskDecoration(
@@ -956,7 +956,7 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
toSplitScreenListenerCaptor.value.invoke()
- verify(decor).detachStatusBarInputLayer()
+ verify(decor).disposeStatusBarInputLayer()
}
@Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java
index 8a2c7782906d..f6fed29bbbe8 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java
@@ -49,6 +49,7 @@ import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import static org.mockito.kotlin.VerificationKt.times;
import android.app.ActivityManager;
import android.app.assist.AssistContent;
@@ -849,7 +850,8 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
ArgumentCaptor<Runnable> runnableArgument = ArgumentCaptor.forClass(Runnable.class);
spyWindowDecor.relayout(taskInfo, true /* hasGlobalFocus */);
- verify(mMockHandler).post(runnableArgument.capture());
+ // Once for view host, the other for the AppHandle input layer.
+ verify(mMockHandler, times(2)).post(runnableArgument.capture());
runnableArgument.getValue().run();
verify(mMockSurfaceControlViewHostFactory).create(any(), any(), any());
}
@@ -876,7 +878,8 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
ArgumentCaptor<Runnable> runnableArgument = ArgumentCaptor.forClass(Runnable.class);
spyWindowDecor.relayout(taskInfo, true /* hasGlobalFocus */);
- verify(mMockHandler).post(runnableArgument.capture());
+ // Once for view host, the other for the AppHandle input layer.
+ verify(mMockHandler, times(2)).post(runnableArgument.capture());
spyWindowDecor.relayout(taskInfo, true /* hasGlobalFocus */);
@@ -890,7 +893,8 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
ArgumentCaptor<Runnable> runnableArgument = ArgumentCaptor.forClass(Runnable.class);
spyWindowDecor.relayout(taskInfo, true /* hasGlobalFocus */);
- verify(mMockHandler).post(runnableArgument.capture());
+ // Once for view host, the other for the AppHandle input layer.
+ verify(mMockHandler, times(2)).post(runnableArgument.capture());
spyWindowDecor.close();
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java
index cb7fadee9822..8e0434cb28f7 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java
@@ -218,8 +218,6 @@ public class WindowDecorationTests extends ShellTestCase {
verify(captionContainerSurfaceBuilder, never()).build();
verify(mMockSurfaceControlViewHostFactory, never()).create(any(), any(), any());
- verify(mMockSurfaceControlFinishT).hide(mMockTaskSurface);
-
assertNull(mRelayoutResult.mRootView);
}
@@ -281,8 +279,6 @@ public class WindowDecorationTests extends ShellTestCase {
verify(mMockSurfaceControlStartT).setCornerRadius(mMockTaskSurface, CORNER_RADIUS);
verify(mMockSurfaceControlFinishT).setCornerRadius(mMockTaskSurface, CORNER_RADIUS);
- verify(mMockSurfaceControlStartT)
- .show(mMockTaskSurface);
verify(mMockSurfaceControlStartT).setShadowRadius(mMockTaskSurface, 10);
assertEquals(300, mRelayoutResult.mWidth);
@@ -863,7 +859,7 @@ public class WindowDecorationTests extends ShellTestCase {
final TestWindowDecoration windowDecor = createWindowDecoration(taskInfo);
- mRelayoutParams.mSetTaskPositionAndCrop = false;
+ mRelayoutParams.mSetTaskVisibilityPositionAndCrop = false;
windowDecor.relayout(taskInfo, true /* hasGlobalFocus */);
verify(mMockSurfaceControlStartT, never()).setWindowCrop(
@@ -891,7 +887,7 @@ public class WindowDecorationTests extends ShellTestCase {
taskInfo.configuration.densityDpi = DisplayMetrics.DENSITY_DEFAULT * 2;
final TestWindowDecoration windowDecor = createWindowDecoration(taskInfo);
- mRelayoutParams.mSetTaskPositionAndCrop = true;
+ mRelayoutParams.mSetTaskVisibilityPositionAndCrop = true;
windowDecor.relayout(taskInfo, true /* hasGlobalFocus */);
verify(mMockSurfaceControlStartT).setWindowCrop(
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModelTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModelTest.kt
index 52e93bb87ea3..80ad1df44a1b 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModelTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModelTest.kt
@@ -36,6 +36,7 @@ import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.kotlin.any
+import org.mockito.kotlin.eq
import org.mockito.kotlin.mock
import org.mockito.kotlin.times
import org.mockito.kotlin.verify
@@ -145,7 +146,7 @@ class DesktopTilingDecorViewModelTest : ShellTestCase() {
}
@Test
- fun userChange_starting_allTilingSessionsShouldBeDestroyed() {
+ fun onUserChange_allTilingSessionsShouldBeDestroyed() {
desktopTilingDecorViewModel.tilingTransitionHandlerByDisplayId.put(
1,
desktopTilingDecoration,
@@ -157,7 +158,29 @@ class DesktopTilingDecorViewModelTest : ShellTestCase() {
desktopTilingDecorViewModel.onUserChange()
- verify(desktopTilingDecoration, times(2)).onUserChange()
+ verify(desktopTilingDecoration, times(2)).resetTilingSession()
+ }
+
+ @Test
+ fun displayOrientationChange_tilingForDisplayShouldBeDestroyed() {
+ desktopTilingDecorViewModel.tilingTransitionHandlerByDisplayId.put(
+ 1,
+ desktopTilingDecoration,
+ )
+ desktopTilingDecorViewModel.tilingTransitionHandlerByDisplayId.put(
+ 2,
+ desktopTilingDecoration,
+ )
+
+ desktopTilingDecorViewModel.onDisplayChange(1, 1, 2, null, null)
+
+ verify(desktopTilingDecoration, times(1)).resetTilingSession()
+ verify(displayControllerMock, times(1))
+ .addDisplayChangingController(eq(desktopTilingDecorViewModel))
+
+ desktopTilingDecorViewModel.onDisplayChange(1, 1, 3, null, null)
+ // No extra calls after 180 degree change.
+ verify(desktopTilingDecoration, times(1)).resetTilingSession()
}
companion object {
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDividerWindowManagerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDividerWindowManagerTest.kt
index 0ee3f4695e85..3143946fa828 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDividerWindowManagerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDividerWindowManagerTest.kt
@@ -16,9 +16,12 @@
package com.android.wm.shell.windowdecor.tiling
+import android.content.Context
import android.content.res.Configuration
import android.graphics.Rect
import android.testing.AndroidTestingRunner
+import android.view.Display
+import android.view.RoundedCorner
import android.view.SurfaceControl
import androidx.test.annotation.UiThreadTest
import androidx.test.filters.SmallTest
@@ -29,6 +32,7 @@ import kotlin.test.Test
import org.junit.Before
import org.junit.runner.RunWith
import org.mockito.kotlin.any
+import org.mockito.kotlin.eq
import org.mockito.kotlin.mock
import org.mockito.kotlin.times
import org.mockito.kotlin.verify
@@ -55,10 +59,17 @@ class DesktopTilingDividerWindowManagerTest : ShellTestCase() {
private lateinit var desktopTilingWindowManager: DesktopTilingDividerWindowManager
+ private val context = mock<Context>()
+ private val display = mock<Display>()
+ private val roundedCorner = mock<RoundedCorner>()
+
@Before
fun setup() {
config = Configuration()
config.setToDefaults()
+ whenever(context.display).thenReturn(display)
+ whenever(display.getRoundedCorner(any())).thenReturn(roundedCorner)
+ whenever(roundedCorner.radius).thenReturn(CORNER_RADIUS)
desktopTilingWindowManager =
DesktopTilingDividerWindowManager(
config,
@@ -69,6 +80,7 @@ class DesktopTilingDividerWindowManagerTest : ShellTestCase() {
transitionHandlerMock,
transactionSupplierMock,
BOUNDS,
+ context,
)
}
@@ -85,7 +97,6 @@ class DesktopTilingDividerWindowManagerTest : ShellTestCase() {
// Ensure a surfaceControl transaction runs to show the divider.
verify(transactionSupplierMock, times(1)).get()
- verify(syncQueueMock, times(1)).runInSync(any())
desktopTilingWindowManager.release()
verify(transaction, times(1)).hide(any())
@@ -93,7 +104,24 @@ class DesktopTilingDividerWindowManagerTest : ShellTestCase() {
verify(transaction, times(1)).apply()
}
+ @Test
+ @UiThreadTest
+ fun testWindowManager_accountsForRoundedCornerDimensions() {
+ whenever(transactionSupplierMock.get()).thenReturn(transaction)
+ whenever(transaction.setRelativeLayer(any(), any(), any())).thenReturn(transaction)
+ whenever(transaction.setRelativeLayer(any(), any(), any())).thenReturn(transaction)
+ whenever(transaction.setPosition(any(), any(), any())).thenReturn(transaction)
+ whenever(transaction.show(any())).thenReturn(transaction)
+
+ desktopTilingWindowManager.generateViewHost(surfaceControl)
+
+ // Ensure a surfaceControl transaction runs to show the divider.
+ verify(transaction, times(1))
+ .setPosition(any(), eq(BOUNDS.left.toFloat() - CORNER_RADIUS), any())
+ }
+
companion object {
private val BOUNDS = Rect(1, 2, 3, 4)
+ private val CORNER_RADIUS = 28
}
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt
index 2ae2461c8f69..f371f5223419 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt
@@ -475,7 +475,7 @@ class DesktopTilingWindowDecorationTest : ShellTestCase() {
tilingDecoration.rightTaskResizingHelper = tiledTaskHelper
tilingDecoration.desktopTilingDividerWindowManager = desktopTilingDividerWindowManager
- tilingDecoration.onUserChange()
+ tilingDecoration.resetTilingSession()
assertThat(tilingDecoration.leftTaskResizingHelper).isNull()
assertThat(tilingDecoration.rightTaskResizingHelper).isNull()
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index 266c23631800..fcb7efc35c94 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -384,6 +384,7 @@ cc_defaults {
"jni/ScopedParcel.cpp",
"jni/Shader.cpp",
"jni/RenderEffect.cpp",
+ "jni/RuntimeEffectUtils.cpp",
"jni/Typeface.cpp",
"jni/Utils.cpp",
"jni/YuvToJpegEncoder.cpp",
@@ -579,6 +580,7 @@ cc_defaults {
"utils/Color.cpp",
"utils/LinearAllocator.cpp",
"utils/StringUtils.cpp",
+ "utils/StatsUtils.cpp",
"utils/TypefaceUtils.cpp",
"utils/VectorDrawableUtils.cpp",
"AnimationContext.cpp",
diff --git a/libs/hwui/ColorFilter.h b/libs/hwui/ColorFilter.h
index 3a3bfb47dfdd..f6b6be08997a 100644
--- a/libs/hwui/ColorFilter.h
+++ b/libs/hwui/ColorFilter.h
@@ -22,6 +22,7 @@
#include <memory>
#include "GraphicsJNI.h"
+#include "RuntimeEffectUtils.h"
#include "SkColorFilter.h"
namespace android {
@@ -113,6 +114,36 @@ private:
std::vector<float> mMatrix;
};
+class RuntimeColorFilter : public ColorFilter {
+public:
+ RuntimeColorFilter(SkRuntimeEffectBuilder* builder) : mBuilder(builder) {}
+
+ void updateUniforms(JNIEnv* env, const char* name, const float vals[], int count,
+ bool isColor) {
+ UpdateFloatUniforms(env, mBuilder, name, vals, count, isColor);
+ discardInstance();
+ }
+
+ void updateUniforms(JNIEnv* env, const char* name, const int vals[], int count) {
+ UpdateIntUniforms(env, mBuilder, name, vals, count);
+ discardInstance();
+ }
+
+ void updateChild(JNIEnv* env, const char* name, SkFlattenable* childEffect) {
+ UpdateChild(env, mBuilder, name, childEffect);
+ discardInstance();
+ }
+
+private:
+ sk_sp<SkColorFilter> createInstance() override {
+ // TODO: throw error if null
+ return mBuilder->makeColorFilter();
+ }
+
+private:
+ SkRuntimeEffectBuilder* mBuilder;
+};
+
} // namespace uirenderer
} // namespace android
diff --git a/libs/hwui/hwui/ImageDecoder.cpp b/libs/hwui/hwui/ImageDecoder.cpp
index e074a27db38f..a9a5db8181ba 100644
--- a/libs/hwui/hwui/ImageDecoder.cpp
+++ b/libs/hwui/hwui/ImageDecoder.cpp
@@ -27,8 +27,8 @@
#include <SkColorSpace.h>
#include <SkColorType.h>
#include <SkEncodedOrigin.h>
-#include <SkImageInfo.h>
#include <SkGainmapInfo.h>
+#include <SkImageInfo.h>
#include <SkMatrix.h>
#include <SkPaint.h>
#include <SkPngChunkReader.h>
@@ -43,6 +43,8 @@
#include <memory>
+#include "modules/skcms/src/skcms_public.h"
+
using namespace android;
sk_sp<SkColorSpace> ImageDecoder::getDefaultColorSpace() const {
diff --git a/libs/hwui/jni/BitmapFactory.cpp b/libs/hwui/jni/BitmapFactory.cpp
index 49a7f73fb3a3..8b43f1db84af 100644
--- a/libs/hwui/jni/BitmapFactory.cpp
+++ b/libs/hwui/jni/BitmapFactory.cpp
@@ -10,6 +10,7 @@
#include <stdint.h>
#include <stdio.h>
#include <sys/stat.h>
+#include <utils/StatsUtils.h>
#include <memory>
@@ -630,6 +631,7 @@ static jobject doDecode(JNIEnv* env, std::unique_ptr<SkStreamRewindable> stream,
}
bitmap::reinitBitmap(env, javaBitmap, outputBitmap.info(), isPremultiplied);
outputBitmap.notifyPixelsChanged();
+ uirenderer::logBitmapDecode(*reuseBitmap);
// If a java bitmap was passed in for reuse, pass it back
return javaBitmap;
}
@@ -650,6 +652,7 @@ static jobject doDecode(JNIEnv* env, std::unique_ptr<SkStreamRewindable> stream,
}
}
+ uirenderer::logBitmapDecode(*hardwareBitmap);
return bitmap::createBitmap(env, hardwareBitmap.release(), bitmapCreateFlags,
ninePatchChunk, ninePatchInsets, -1);
}
@@ -659,6 +662,7 @@ static jobject doDecode(JNIEnv* env, std::unique_ptr<SkStreamRewindable> stream,
heapBitmap->setGainmap(std::move(gainmap));
}
+ uirenderer::logBitmapDecode(*heapBitmap);
// now create the java bitmap
return bitmap::createBitmap(env, heapBitmap, bitmapCreateFlags, ninePatchChunk, ninePatchInsets,
-1);
diff --git a/libs/hwui/jni/BitmapRegionDecoder.cpp b/libs/hwui/jni/BitmapRegionDecoder.cpp
index f7e8e073a272..5ffd5b9016d8 100644
--- a/libs/hwui/jni/BitmapRegionDecoder.cpp
+++ b/libs/hwui/jni/BitmapRegionDecoder.cpp
@@ -19,6 +19,7 @@
#include <HardwareBitmapUploader.h>
#include <androidfw/Asset.h>
#include <sys/stat.h>
+#include <utils/StatsUtils.h>
#include <memory>
@@ -376,6 +377,7 @@ static jobject nativeDecodeRegion(JNIEnv* env, jobject, jlong brdHandle, jint in
recycledBitmap->setGainmap(std::move(gainmap));
}
bitmap::reinitBitmap(env, javaBitmap, recycledBitmap->info(), !requireUnpremul);
+ uirenderer::logBitmapDecode(*recycledBitmap);
return javaBitmap;
}
@@ -392,12 +394,14 @@ static jobject nativeDecodeRegion(JNIEnv* env, jobject, jlong brdHandle, jint in
hardwareBitmap->setGainmap(std::move(gm));
}
}
+ uirenderer::logBitmapDecode(*hardwareBitmap);
return bitmap::createBitmap(env, hardwareBitmap.release(), bitmapCreateFlags);
}
Bitmap* heapBitmap = heapAlloc.getStorageObjAndReset();
if (hasGainmap && heapBitmap != nullptr) {
heapBitmap->setGainmap(std::move(gainmap));
}
+ uirenderer::logBitmapDecode(*heapBitmap);
return android::bitmap::createBitmap(env, heapBitmap, bitmapCreateFlags);
}
diff --git a/libs/hwui/jni/ColorFilter.cpp b/libs/hwui/jni/ColorFilter.cpp
index 0b95148d3c82..20301d2c76ec 100644
--- a/libs/hwui/jni/ColorFilter.cpp
+++ b/libs/hwui/jni/ColorFilter.cpp
@@ -18,7 +18,9 @@
#include "ColorFilter.h"
#include "GraphicsJNI.h"
+#include "RuntimeEffectUtils.h"
#include "SkBlendMode.h"
+#include "include/effects/SkRuntimeEffect.h"
namespace android {
@@ -89,6 +91,78 @@ public:
filter->setMatrix(getMatrixFromJFloatArray(env, jarray));
}
}
+
+ static jlong RuntimeColorFilter_createColorFilter(JNIEnv* env, jobject, jstring agsl) {
+ ScopedUtfChars strSksl(env, agsl);
+ auto result = SkRuntimeEffect::MakeForColorFilter(SkString(strSksl.c_str()),
+ SkRuntimeEffect::Options{});
+ if (result.effect.get() == nullptr) {
+ doThrowIAE(env, result.errorText.c_str());
+ return 0;
+ }
+ auto builder = new SkRuntimeEffectBuilder(std::move(result.effect));
+ auto* runtimeColorFilter = new RuntimeColorFilter(builder);
+ runtimeColorFilter->incStrong(nullptr);
+ return static_cast<jlong>(reinterpret_cast<uintptr_t>(runtimeColorFilter));
+ }
+
+ static void RuntimeColorFilter_updateUniformsFloatArray(JNIEnv* env, jobject,
+ jlong colorFilterPtr,
+ jstring uniformName,
+ jfloatArray uniforms,
+ jboolean isColor) {
+ auto* filter = reinterpret_cast<RuntimeColorFilter*>(colorFilterPtr);
+ ScopedUtfChars name(env, uniformName);
+ AutoJavaFloatArray autoValues(env, uniforms, 0, kRO_JNIAccess);
+ if (filter) {
+ filter->updateUniforms(env, name.c_str(), autoValues.ptr(), autoValues.length(),
+ isColor);
+ }
+ }
+
+ static void RuntimeColorFilter_updateUniformsFloats(JNIEnv* env, jobject, jlong colorFilterPtr,
+ jstring uniformName, jfloat value1,
+ jfloat value2, jfloat value3, jfloat value4,
+ jint count) {
+ auto* filter = reinterpret_cast<RuntimeColorFilter*>(colorFilterPtr);
+ ScopedUtfChars name(env, uniformName);
+ const float values[4] = {value1, value2, value3, value4};
+ if (filter) {
+ filter->updateUniforms(env, name.c_str(), values, count, false);
+ }
+ }
+
+ static void RuntimeColorFilter_updateUniformsIntArray(JNIEnv* env, jobject,
+ jlong colorFilterPtr, jstring uniformName,
+ jintArray uniforms) {
+ auto* filter = reinterpret_cast<RuntimeColorFilter*>(colorFilterPtr);
+ ScopedUtfChars name(env, uniformName);
+ AutoJavaIntArray autoValues(env, uniforms, 0);
+ if (filter) {
+ filter->updateUniforms(env, name.c_str(), autoValues.ptr(), autoValues.length());
+ }
+ }
+
+ static void RuntimeColorFilter_updateUniformsInts(JNIEnv* env, jobject, jlong colorFilterPtr,
+ jstring uniformName, jint value1, jint value2,
+ jint value3, jint value4, jint count) {
+ auto* filter = reinterpret_cast<RuntimeColorFilter*>(colorFilterPtr);
+ ScopedUtfChars name(env, uniformName);
+ const int values[4] = {value1, value2, value3, value4};
+ if (filter) {
+ filter->updateUniforms(env, name.c_str(), values, count);
+ }
+ }
+
+ static void RuntimeColorFilter_updateChild(JNIEnv* env, jobject, jlong colorFilterPtr,
+ jstring childName, jlong childPtr) {
+ auto* filter = reinterpret_cast<RuntimeColorFilter*>(colorFilterPtr);
+ ScopedUtfChars name(env, childName);
+ auto* child = reinterpret_cast<SkFlattenable*>(childPtr);
+ if (filter && child) {
+ filter->updateChild(env, name.c_str(), child);
+ }
+ }
};
static const JNINativeMethod colorfilter_methods[] = {
@@ -107,6 +181,20 @@ static const JNINativeMethod colormatrix_methods[] = {
{"nativeColorMatrixFilter", "([F)J", (void*)ColorFilterGlue::CreateColorMatrixFilter},
{"nativeSetColorMatrix", "(J[F)V", (void*)ColorFilterGlue::SetColorMatrix}};
+static const JNINativeMethod runtime_color_filter_methods[] = {
+ {"nativeCreateRuntimeColorFilter", "(Ljava/lang/String;)J",
+ (void*)ColorFilterGlue::RuntimeColorFilter_createColorFilter},
+ {"nativeUpdateUniforms", "(JLjava/lang/String;[FZ)V",
+ (void*)ColorFilterGlue::RuntimeColorFilter_updateUniformsFloatArray},
+ {"nativeUpdateUniforms", "(JLjava/lang/String;FFFFI)V",
+ (void*)ColorFilterGlue::RuntimeColorFilter_updateUniformsFloats},
+ {"nativeUpdateUniforms", "(JLjava/lang/String;[I)V",
+ (void*)ColorFilterGlue::RuntimeColorFilter_updateUniformsIntArray},
+ {"nativeUpdateUniforms", "(JLjava/lang/String;IIIII)V",
+ (void*)ColorFilterGlue::RuntimeColorFilter_updateUniformsInts},
+ {"nativeUpdateChild", "(JLjava/lang/String;J)V",
+ (void*)ColorFilterGlue::RuntimeColorFilter_updateChild}};
+
int register_android_graphics_ColorFilter(JNIEnv* env) {
android::RegisterMethodsOrDie(env, "android/graphics/ColorFilter", colorfilter_methods,
NELEM(colorfilter_methods));
@@ -118,7 +206,10 @@ int register_android_graphics_ColorFilter(JNIEnv* env) {
NELEM(lighting_methods));
android::RegisterMethodsOrDie(env, "android/graphics/ColorMatrixColorFilter",
colormatrix_methods, NELEM(colormatrix_methods));
-
+ android::RegisterMethodsOrDie(env, "android/graphics/RuntimeColorFilter",
+ runtime_color_filter_methods,
+ NELEM(runtime_color_filter_methods));
+
return 0;
}
diff --git a/libs/hwui/jni/ImageDecoder.cpp b/libs/hwui/jni/ImageDecoder.cpp
index aebc4db37898..90fd3d87cba7 100644
--- a/libs/hwui/jni/ImageDecoder.cpp
+++ b/libs/hwui/jni/ImageDecoder.cpp
@@ -37,6 +37,7 @@
#include <hwui/Bitmap.h>
#include <hwui/ImageDecoder.h>
#include <sys/stat.h>
+#include <utils/StatsUtils.h>
#include "Bitmap.h"
#include "BitmapFactory.h"
@@ -485,6 +486,7 @@ static jobject ImageDecoder_nDecodeBitmap(JNIEnv* env, jobject /*clazz*/, jlong
hwBitmap->setGainmap(std::move(gm));
}
}
+ uirenderer::logBitmapDecode(*hwBitmap);
return bitmap::createBitmap(env, hwBitmap.release(), bitmapCreateFlags,
ninePatchChunk, ninePatchInsets);
}
@@ -498,6 +500,8 @@ static jobject ImageDecoder_nDecodeBitmap(JNIEnv* env, jobject /*clazz*/, jlong
nativeBitmap->setImmutable();
}
+
+ uirenderer::logBitmapDecode(*nativeBitmap);
return bitmap::createBitmap(env, nativeBitmap.release(), bitmapCreateFlags, ninePatchChunk,
ninePatchInsets);
}
diff --git a/libs/hwui/jni/RuntimeEffectUtils.cpp b/libs/hwui/jni/RuntimeEffectUtils.cpp
new file mode 100644
index 000000000000..46db8633c66e
--- /dev/null
+++ b/libs/hwui/jni/RuntimeEffectUtils.cpp
@@ -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.
+ */
+
+#include "RuntimeEffectUtils.h"
+
+#include "include/effects/SkRuntimeEffect.h"
+
+namespace android {
+namespace uirenderer {
+
+static inline int ThrowIAEFmt(JNIEnv* env, const char* fmt, ...) {
+ va_list args;
+ va_start(args, fmt);
+ int ret = jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", fmt, args);
+ va_end(args);
+ return ret;
+}
+
+bool isIntUniformType(const SkRuntimeEffect::Uniform::Type& type) {
+ switch (type) {
+ case SkRuntimeEffect::Uniform::Type::kFloat:
+ case SkRuntimeEffect::Uniform::Type::kFloat2:
+ case SkRuntimeEffect::Uniform::Type::kFloat3:
+ case SkRuntimeEffect::Uniform::Type::kFloat4:
+ case SkRuntimeEffect::Uniform::Type::kFloat2x2:
+ case SkRuntimeEffect::Uniform::Type::kFloat3x3:
+ case SkRuntimeEffect::Uniform::Type::kFloat4x4:
+ return false;
+ case SkRuntimeEffect::Uniform::Type::kInt:
+ case SkRuntimeEffect::Uniform::Type::kInt2:
+ case SkRuntimeEffect::Uniform::Type::kInt3:
+ case SkRuntimeEffect::Uniform::Type::kInt4:
+ return true;
+ }
+}
+
+void UpdateFloatUniforms(JNIEnv* env, SkRuntimeEffectBuilder* builder, const char* uniformName,
+ const float values[], int count, bool isColor) {
+ SkRuntimeEffectBuilder::BuilderUniform uniform = builder->uniform(uniformName);
+ if (uniform.fVar == nullptr) {
+ ThrowIAEFmt(env, "unable to find uniform named %s", uniformName);
+ } else if (isColor != ((uniform.fVar->flags & SkRuntimeEffect::Uniform::kColor_Flag) != 0)) {
+ if (isColor) {
+ jniThrowExceptionFmt(
+ env, "java/lang/IllegalArgumentException",
+ "attempting to set a color uniform using the non-color specific APIs: %s %x",
+ uniformName, uniform.fVar->flags);
+ } else {
+ ThrowIAEFmt(env,
+ "attempting to set a non-color uniform using the setColorUniform APIs: %s",
+ uniformName);
+ }
+ } else if (isIntUniformType(uniform.fVar->type)) {
+ ThrowIAEFmt(env, "attempting to set a int uniform using the setUniform APIs: %s",
+ uniformName);
+ } else if (!uniform.set<float>(values, count)) {
+ ThrowIAEFmt(env, "mismatch in byte size for uniform [expected: %zu actual: %zu]",
+ uniform.fVar->sizeInBytes(), sizeof(float) * count);
+ }
+}
+
+void UpdateIntUniforms(JNIEnv* env, SkRuntimeEffectBuilder* builder, const char* uniformName,
+ const int values[], int count) {
+ SkRuntimeEffectBuilder::BuilderUniform uniform = builder->uniform(uniformName);
+ if (uniform.fVar == nullptr) {
+ ThrowIAEFmt(env, "unable to find uniform named %s", uniformName);
+ } else if (!isIntUniformType(uniform.fVar->type)) {
+ ThrowIAEFmt(env, "attempting to set a non-int uniform using the setIntUniform APIs: %s",
+ uniformName);
+ } else if (!uniform.set<int>(values, count)) {
+ ThrowIAEFmt(env, "mismatch in byte size for uniform [expected: %zu actual: %zu]",
+ uniform.fVar->sizeInBytes(), sizeof(float) * count);
+ }
+}
+
+void UpdateChild(JNIEnv* env, SkRuntimeEffectBuilder* builder, const char* childName,
+ SkFlattenable* childEffect) {
+ SkRuntimeShaderBuilder::BuilderChild builderChild = builder->child(childName);
+ if (builderChild.fChild == nullptr) {
+ ThrowIAEFmt(env, "unable to find shader named %s", childName);
+ return;
+ }
+
+ builderChild = sk_ref_sp(childEffect);
+}
+
+} // namespace uirenderer
+} // namespace android \ No newline at end of file
diff --git a/libs/hwui/jni/RuntimeEffectUtils.h b/libs/hwui/jni/RuntimeEffectUtils.h
new file mode 100644
index 000000000000..75623c0f7ac1
--- /dev/null
+++ b/libs/hwui/jni/RuntimeEffectUtils.h
@@ -0,0 +1,37 @@
+/*
+ * 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 RUNTIMEEFFECTUTILS_H
+#define RUNTIMEEFFECTUTILS_H
+
+#include "GraphicsJNI.h"
+#include "include/effects/SkRuntimeEffect.h"
+
+namespace android {
+namespace uirenderer {
+
+void UpdateFloatUniforms(JNIEnv* env, SkRuntimeEffectBuilder* builder, const char* uniformName,
+ const float values[], int count, bool isColor);
+
+void UpdateIntUniforms(JNIEnv* env, SkRuntimeEffectBuilder* builder, const char* uniformName,
+ const int values[], int count);
+
+void UpdateChild(JNIEnv* env, SkRuntimeEffectBuilder* builder, const char* childName,
+ SkFlattenable* childEffect);
+} // namespace uirenderer
+} // namespace android
+
+#endif // MAIN_RUNTIMEEFFECTUTILS_H
diff --git a/libs/hwui/jni/android_graphics_RenderNode.cpp b/libs/hwui/jni/android_graphics_RenderNode.cpp
index 6e03bbd0fa16..d9dc8eb8c1b1 100644
--- a/libs/hwui/jni/android_graphics_RenderNode.cpp
+++ b/libs/hwui/jni/android_graphics_RenderNode.cpp
@@ -593,9 +593,9 @@ static void android_view_RenderNode_requestPositionUpdates(JNIEnv* env, jobject,
Matrix4 transform;
SkIRect clipBounds;
+ uirenderer::Rect initialClipBounds;
+ const auto clipFlags = props.getClippingFlags();
if (enableClip) {
- uirenderer::Rect initialClipBounds;
- const auto clipFlags = props.getClippingFlags();
if (clipFlags) {
props.getClippingRectForFlags(clipFlags, &initialClipBounds);
} else {
@@ -659,8 +659,8 @@ static void android_view_RenderNode_requestPositionUpdates(JNIEnv* env, jobject,
static_cast<jint>(bounds.left), static_cast<jint>(bounds.top),
static_cast<jint>(bounds.right), static_cast<jint>(bounds.bottom),
static_cast<jint>(clipBounds.fLeft), static_cast<jint>(clipBounds.fTop),
- static_cast<jint>(clipBounds.fRight),
- static_cast<jint>(clipBounds.fBottom));
+ static_cast<jint>(clipBounds.fRight), static_cast<jint>(clipBounds.fBottom),
+ static_cast<jint>(props.getWidth()), static_cast<jint>(props.getHeight()));
}
if (!keepListening) {
env->DeleteGlobalRef(mListener);
@@ -891,7 +891,7 @@ int register_android_view_RenderNode(JNIEnv* env) {
gPositionListener.callPositionChanged = GetStaticMethodIDOrDie(
env, clazz, "callPositionChanged", "(Ljava/lang/ref/WeakReference;JIIII)Z");
gPositionListener.callPositionChanged2 = GetStaticMethodIDOrDie(
- env, clazz, "callPositionChanged2", "(Ljava/lang/ref/WeakReference;JIIIIIIII)Z");
+ env, clazz, "callPositionChanged2", "(Ljava/lang/ref/WeakReference;JIIIIIIIIII)Z");
gPositionListener.callApplyStretch = GetStaticMethodIDOrDie(
env, clazz, "callApplyStretch", "(Ljava/lang/ref/WeakReference;JFFFFFFFFFF)Z");
gPositionListener.callPositionLost = GetStaticMethodIDOrDie(
diff --git a/libs/hwui/libhwui.map.txt b/libs/hwui/libhwui.map.txt
index 2414299321a9..b5591941453d 100644
--- a/libs/hwui/libhwui.map.txt
+++ b/libs/hwui/libhwui.map.txt
@@ -67,6 +67,7 @@ LIBHWUI_PLATFORM {
SkFILEStream::SkFILEStream*;
SkImageInfo::*;
SkMemoryStream::SkMemoryStream*;
+ android::uirenderer::logBitmapDecode*;
};
local:
*;
diff --git a/libs/hwui/utils/StatsUtils.cpp b/libs/hwui/utils/StatsUtils.cpp
new file mode 100644
index 000000000000..5c4027e1a846
--- /dev/null
+++ b/libs/hwui/utils/StatsUtils.cpp
@@ -0,0 +1,102 @@
+/*
+ * Copyright 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.
+ */
+
+#ifdef __ANDROID__
+#include <dlfcn.h>
+#include <log/log.h>
+#include <statslog_hwui.h>
+#include <statssocket_lazy.h>
+#include <utils/Errors.h>
+
+#include <mutex>
+#endif
+
+#include <unistd.h>
+
+#include "StatsUtils.h"
+
+namespace android {
+namespace uirenderer {
+
+#ifdef __ANDROID__
+
+namespace {
+
+int32_t toStatsColorSpaceTransfer(skcms_TFType transferType) {
+ switch (transferType) {
+ case skcms_TFType_sRGBish:
+ return stats::IMAGE_DECODED__COLOR_SPACE_TRANSFER__COLOR_SPACE_TRANSFER_SRGBISH;
+ case skcms_TFType_PQish:
+ return stats::IMAGE_DECODED__COLOR_SPACE_TRANSFER__COLOR_SPACE_TRANSFER_PQISH;
+ case skcms_TFType_HLGish:
+ return stats::IMAGE_DECODED__COLOR_SPACE_TRANSFER__COLOR_SPACE_TRANSFER_HLGISH;
+ default:
+ return stats::IMAGE_DECODED__COLOR_SPACE_TRANSFER__COLOR_SPACE_TRANSFER_UNKNOWN;
+ }
+}
+
+int32_t toStatsBitmapFormat(SkColorType type) {
+ switch (type) {
+ case kAlpha_8_SkColorType:
+ return stats::IMAGE_DECODED__FORMAT__BITMAP_FORMAT_A_8;
+ case kRGB_565_SkColorType:
+ return stats::IMAGE_DECODED__FORMAT__BITMAP_FORMAT_RGB_565;
+ case kN32_SkColorType:
+ return stats::IMAGE_DECODED__FORMAT__BITMAP_FORMAT_ARGB_8888;
+ case kRGBA_F16_SkColorType:
+ return stats::IMAGE_DECODED__FORMAT__BITMAP_FORMAT_RGBA_F16;
+ case kRGBA_1010102_SkColorType:
+ return stats::IMAGE_DECODED__FORMAT__BITMAP_FORMAT_RGBA_1010102;
+ default:
+ return stats::IMAGE_DECODED__FORMAT__BITMAP_FORMAT_UNKNOWN;
+ }
+}
+
+} // namespace
+
+#endif
+
+void logBitmapDecode(const SkImageInfo& info, bool hasGainmap) {
+#ifdef __ANDROID__
+
+ if (!statssocket::lazy::IsAvailable()) {
+ std::once_flag once;
+ std::call_once(once, []() { ALOGD("libstatssocket not available, dropping stats"); });
+ return;
+ }
+
+ skcms_TFType tfnType = skcms_TFType_Invalid;
+
+ if (info.colorSpace()) {
+ skcms_TransferFunction tfn;
+ info.colorSpace()->transferFn(&tfn);
+ tfnType = skcms_TransferFunction_getType(&tfn);
+ }
+
+ auto status =
+ stats::stats_write(uirenderer::stats::IMAGE_DECODED, static_cast<int32_t>(getuid()),
+ uirenderer::toStatsColorSpaceTransfer(tfnType), hasGainmap,
+ uirenderer::toStatsBitmapFormat(info.colorType()));
+ ALOGW_IF(status != OK, "Image decoding logging dropped!");
+#endif
+}
+
+void logBitmapDecode(const Bitmap& bitmap) {
+ logBitmapDecode(bitmap.info(), bitmap.hasGainmap());
+}
+
+} // namespace uirenderer
+} // namespace android
diff --git a/libs/hwui/utils/StatsUtils.h b/libs/hwui/utils/StatsUtils.h
new file mode 100644
index 000000000000..0c247014a8eb
--- /dev/null
+++ b/libs/hwui/utils/StatsUtils.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 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.
+ */
+
+#pragma once
+
+#include <SkBitmap.h>
+#include <SkColorSpace.h>
+#include <SkColorType.h>
+#include <cutils/compiler.h>
+#include <hwui/Bitmap.h>
+
+namespace android {
+namespace uirenderer {
+
+ANDROID_API void logBitmapDecode(const SkImageInfo& info, bool hasGainmap);
+
+ANDROID_API void logBitmapDecode(const Bitmap& bitmap);
+
+} // namespace uirenderer
+} // namespace android
diff --git a/media/java/android/media/AudioAttributes.java b/media/java/android/media/AudioAttributes.java
index 5a8eb3ab17b8..1db719828c76 100644
--- a/media/java/android/media/AudioAttributes.java
+++ b/media/java/android/media/AudioAttributes.java
@@ -16,15 +16,11 @@
package android.media;
-import static android.media.audio.Flags.FLAG_SPEAKER_CLEANUP_USAGE;
-
-import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.TestApi;
-// TODO switch from HIDL imports to AIDL
import android.audio.policy.configuration.V7_0.AudioUsage;
import android.compat.annotation.UnsupportedAppUsage;
import android.media.audiopolicy.AudioProductStrategy;
@@ -251,16 +247,6 @@ public final class AudioAttributes implements Parcelable {
public static final int USAGE_ANNOUNCEMENT = SYSTEM_USAGE_OFFSET + 3;
/**
- * @hide
- * Usage value to use when a system application plays a signal intended to clean up the
- * speaker transducers and free them of deposits of dust or water.
- */
- @FlaggedApi(FLAG_SPEAKER_CLEANUP_USAGE)
- @SystemApi
- @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
- public static final int USAGE_SPEAKER_CLEANUP = SYSTEM_USAGE_OFFSET + 4;
-
- /**
* IMPORTANT: when adding new usage types, add them to SDK_USAGES and update SUPPRESSIBLE_USAGES
* if applicable, as well as audioattributes.proto.
* Also consider adding them to <aaudio/AAudio.h> for the NDK.
@@ -1216,7 +1202,6 @@ public final class AudioAttributes implements Parcelable {
break;
case AudioSystem.STREAM_BLUETOOTH_SCO:
mContentType = CONTENT_TYPE_SPEECH;
- mFlags |= FLAG_SCO;
break;
case AudioSystem.STREAM_DTMF:
mContentType = CONTENT_TYPE_SONIFICATION;
@@ -1536,8 +1521,6 @@ public final class AudioAttributes implements Parcelable {
return "USAGE_VEHICLE_STATUS";
case USAGE_ANNOUNCEMENT:
return "USAGE_ANNOUNCEMENT";
- case USAGE_SPEAKER_CLEANUP:
- return "USAGE_SPEAKER_CLEANUP";
default:
return "unknown usage " + usage;
}
@@ -1678,8 +1661,12 @@ public final class AudioAttributes implements Parcelable {
}
/**
- * Returns whether the given usage can only be used by system-privileged components
- * @param usage one of {@link AttributeSystemUsage}.
+ * @param usage one of {@link AttributeSystemUsage},
+ * {@link AttributeSystemUsage#USAGE_CALL_ASSISTANT},
+ * {@link AttributeSystemUsage#USAGE_EMERGENCY},
+ * {@link AttributeSystemUsage#USAGE_SAFETY},
+ * {@link AttributeSystemUsage#USAGE_VEHICLE_STATUS},
+ * {@link AttributeSystemUsage#USAGE_ANNOUNCEMENT}
* @return boolean indicating if the usage is a system usage or not
* @hide
*/
@@ -1689,8 +1676,7 @@ public final class AudioAttributes implements Parcelable {
|| usage == USAGE_EMERGENCY
|| usage == USAGE_SAFETY
|| usage == USAGE_VEHICLE_STATUS
- || usage == USAGE_ANNOUNCEMENT
- || usage == USAGE_SPEAKER_CLEANUP);
+ || usage == USAGE_ANNOUNCEMENT);
}
/**
@@ -1763,8 +1749,7 @@ public final class AudioAttributes implements Parcelable {
AudioSystem.STREAM_SYSTEM : AudioSystem.STREAM_SYSTEM_ENFORCED;
}
if ((aa.getAllFlags() & FLAG_SCO) == FLAG_SCO) {
- return fromGetVolumeControlStream ?
- AudioSystem.STREAM_VOICE_CALL : AudioSystem.STREAM_BLUETOOTH_SCO;
+ return AudioSystem.STREAM_VOICE_CALL;
}
if ((aa.getAllFlags() & FLAG_BEACON) == FLAG_BEACON) {
return fromGetVolumeControlStream ?
@@ -1805,7 +1790,6 @@ public final class AudioAttributes implements Parcelable {
case USAGE_SAFETY:
case USAGE_VEHICLE_STATUS:
case USAGE_ANNOUNCEMENT:
- case USAGE_SPEAKER_CLEANUP:
case USAGE_UNKNOWN:
return AudioSystem.STREAM_MUSIC;
default:
@@ -1845,8 +1829,7 @@ public final class AudioAttributes implements Parcelable {
USAGE_EMERGENCY,
USAGE_SAFETY,
USAGE_VEHICLE_STATUS,
- USAGE_ANNOUNCEMENT,
- USAGE_SPEAKER_CLEANUP
+ USAGE_ANNOUNCEMENT
})
@Retention(RetentionPolicy.SOURCE)
public @interface AttributeSystemUsage {}
@@ -1896,7 +1879,6 @@ public final class AudioAttributes implements Parcelable {
USAGE_SAFETY,
USAGE_VEHICLE_STATUS,
USAGE_ANNOUNCEMENT,
- USAGE_SPEAKER_CLEANUP,
})
@Retention(RetentionPolicy.SOURCE)
public @interface AttributeUsage {}
diff --git a/media/java/android/media/AudioDeviceInfo.java b/media/java/android/media/AudioDeviceInfo.java
index 39b29d0156d2..2da8eecedc4d 100644
--- a/media/java/android/media/AudioDeviceInfo.java
+++ b/media/java/android/media/AudioDeviceInfo.java
@@ -16,11 +16,15 @@
package android.media;
+import static android.media.audio.Flags.FLAG_ENABLE_MULTICHANNEL_GROUP_DEVICE;
+
import android.Manifest;
+import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.RequiresPermission;
import android.annotation.TestApi;
+import android.media.audio.Flags;
import android.util.SparseIntArray;
import com.android.internal.annotations.VisibleForTesting;
@@ -192,6 +196,15 @@ public final class AudioDeviceInfo {
*/
public static final int TYPE_DOCK_ANALOG = 31;
+ /**
+ * A device type describing a speaker group that supports multichannel contents. The speakers in
+ * the group are connected together using local network based protocols. The speaker group
+ * requires additional input of the physical positions of each individual speaker to provide a
+ * better experience on multichannel contents.
+ */
+ @FlaggedApi(FLAG_ENABLE_MULTICHANNEL_GROUP_DEVICE)
+ public static final int TYPE_MULTICHANNEL_GROUP = 32;
+
/** @hide */
@IntDef(flag = false, prefix = "TYPE", value = {
TYPE_BUILTIN_EARPIECE,
@@ -224,7 +237,8 @@ public final class AudioDeviceInfo {
TYPE_BLE_SPEAKER,
TYPE_ECHO_REFERENCE,
TYPE_BLE_BROADCAST,
- TYPE_DOCK_ANALOG}
+ TYPE_DOCK_ANALOG,
+ TYPE_MULTICHANNEL_GROUP}
)
@Retention(RetentionPolicy.SOURCE)
public @interface AudioDeviceType {}
@@ -285,7 +299,8 @@ public final class AudioDeviceInfo {
TYPE_BLE_HEADSET,
TYPE_BLE_SPEAKER,
TYPE_BLE_BROADCAST,
- TYPE_DOCK_ANALOG}
+ TYPE_DOCK_ANALOG,
+ TYPE_MULTICHANNEL_GROUP}
)
@Retention(RetentionPolicy.SOURCE)
public @interface AudioDeviceTypeOut {}
@@ -321,7 +336,13 @@ public final class AudioDeviceInfo {
case TYPE_BLE_BROADCAST:
case TYPE_DOCK_ANALOG:
return true;
+
default:
+ if (Flags.enableMultichannelGroupDevice()) {
+ if (type == TYPE_MULTICHANNEL_GROUP) {
+ return true;
+ }
+ }
return false;
}
}
@@ -665,6 +686,10 @@ public final class AudioDeviceInfo {
INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_BLE_HEADSET, TYPE_BLE_HEADSET);
INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_BLE_SPEAKER, TYPE_BLE_SPEAKER);
INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_BLE_BROADCAST, TYPE_BLE_BROADCAST);
+ if (Flags.enableMultichannelGroupDevice()) {
+ INT_TO_EXT_DEVICE_MAPPING.put(
+ AudioSystem.DEVICE_OUT_MULTICHANNEL_GROUP, TYPE_MULTICHANNEL_GROUP);
+ }
INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_BUILTIN_MIC, TYPE_BUILTIN_MIC);
INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_BLUETOOTH_SCO_HEADSET, TYPE_BLUETOOTH_SCO);
@@ -721,6 +746,10 @@ public final class AudioDeviceInfo {
EXT_TO_INT_DEVICE_MAPPING.put(TYPE_BLE_HEADSET, AudioSystem.DEVICE_OUT_BLE_HEADSET);
EXT_TO_INT_DEVICE_MAPPING.put(TYPE_BLE_SPEAKER, AudioSystem.DEVICE_OUT_BLE_SPEAKER);
EXT_TO_INT_DEVICE_MAPPING.put(TYPE_BLE_BROADCAST, AudioSystem.DEVICE_OUT_BLE_BROADCAST);
+ if (Flags.enableMultichannelGroupDevice()) {
+ EXT_TO_INT_DEVICE_MAPPING.put(
+ TYPE_MULTICHANNEL_GROUP, AudioSystem.DEVICE_OUT_MULTICHANNEL_GROUP);
+ }
// privileges mapping to input device
EXT_TO_INT_INPUT_DEVICE_MAPPING = new SparseIntArray();
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 8250a536552e..dfe291605522 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -6156,6 +6156,11 @@ public class AudioManager {
*/
public static final int DEVICE_OUT_BLE_BROADCAST = AudioSystem.DEVICE_OUT_BLE_BROADCAST;
/** @hide
+ * The audio output device code for a wireless speaker group supporting multichannel content.
+ */
+ public static final int DEVICE_OUT_MULTICHANNEL_GROUP =
+ AudioSystem.DEVICE_OUT_MULTICHANNEL_GROUP;
+ /** @hide
* This is not used as a returned value from {@link #getDevicesForStream}, but could be
* used in the future in a set method to select whatever default device is chosen by the
* platform-specific implementation.
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index bf09cb07a8ed..0ab94f567506 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -1066,6 +1066,8 @@ public class AudioSystem
/** @hide */
public static final int DEVICE_OUT_IP = 0x800000;
/** @hide */
+ public static final int DEVICE_OUT_MULTICHANNEL_GROUP = 0x800001;
+ /** @hide */
public static final int DEVICE_OUT_BUS = 0x1000000;
/** @hide */
public static final int DEVICE_OUT_PROXY = 0x2000000;
@@ -1134,6 +1136,7 @@ public class AudioSystem
DEVICE_OUT_ALL_SET.add(DEVICE_OUT_AUX_LINE);
DEVICE_OUT_ALL_SET.add(DEVICE_OUT_SPEAKER_SAFE);
DEVICE_OUT_ALL_SET.add(DEVICE_OUT_IP);
+ DEVICE_OUT_ALL_SET.add(DEVICE_OUT_MULTICHANNEL_GROUP);
DEVICE_OUT_ALL_SET.add(DEVICE_OUT_BUS);
DEVICE_OUT_ALL_SET.add(DEVICE_OUT_PROXY);
DEVICE_OUT_ALL_SET.add(DEVICE_OUT_USB_HEADSET);
@@ -1422,6 +1425,8 @@ public class AudioSystem
/** @hide */ public static final String DEVICE_OUT_AUX_LINE_NAME = "aux_line";
/** @hide */ public static final String DEVICE_OUT_SPEAKER_SAFE_NAME = "speaker_safe";
/** @hide */ public static final String DEVICE_OUT_IP_NAME = "ip";
+ /** @hide */
+ public static final String DEVICE_OUT_MULTICHANNEL_GROUP_NAME = "multichannel_group";
/** @hide */ public static final String DEVICE_OUT_BUS_NAME = "bus";
/** @hide */ public static final String DEVICE_OUT_PROXY_NAME = "proxy";
/** @hide */ public static final String DEVICE_OUT_USB_HEADSET_NAME = "usb_headset";
@@ -1515,6 +1520,8 @@ public class AudioSystem
return DEVICE_OUT_SPEAKER_SAFE_NAME;
case DEVICE_OUT_IP:
return DEVICE_OUT_IP_NAME;
+ case DEVICE_OUT_MULTICHANNEL_GROUP:
+ return DEVICE_OUT_MULTICHANNEL_GROUP_NAME;
case DEVICE_OUT_BUS:
return DEVICE_OUT_BUS_NAME;
case DEVICE_OUT_PROXY:
diff --git a/media/java/android/media/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java
index 3a19f466f7c1..96edd63a9b12 100644
--- a/media/java/android/media/MediaCodecInfo.java
+++ b/media/java/android/media/MediaCodecInfo.java
@@ -23,6 +23,7 @@ import static android.media.codec.Flags.FLAG_HLG_EDITING;
import static android.media.codec.Flags.FLAG_IN_PROCESS_SW_AUDIO_CODEC;
import static android.media.codec.Flags.FLAG_NULL_OUTPUT_SURFACE;
import static android.media.codec.Flags.FLAG_REGION_OF_INTEREST;
+import static android.media.codec.Flags.FLAG_APV_SUPPORT;
import static android.media.MediaCodec.GetFlag;
import android.annotation.FlaggedApi;
@@ -4496,6 +4497,265 @@ public final class MediaCodecInfo {
@SuppressLint("AllUpper")
public static final int AC4Level4 = 0x10;
+ // Profiles and levels/bands for APV Codec, corresponding to the definitions in
+ // "Advanced Professional Video", 10.1.3 Profiles, 10.1.4 Levels and Bands
+ // found at https://www.ietf.org/archive/id/draft-lim-apv-02.html
+
+ /**
+ * APV codec profile 422-10 as per IETF lim-apv-02, 10.1.3.1.1
+ */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVProfile422_10 = 0x01;
+
+ /**
+ * APV codec profile 422-10 as per IETF lim-apv-02, 10.1.3.1.1
+ * with HDR10.
+ */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVProfile422_10HDR10 = 0x1000;
+
+ /**
+ * APV codec profile 422-10 as per IETF lim-apv-02, 10.1.3.1.1
+ * with HDR10Plus.
+ */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVProfile422_10HDR10Plus = 0x2000;
+
+ // For APV Levels, the numerical values are constructed as follows:
+ // ((0x100 << (level_num - 1)) | (1 << band))
+ // where:
+ // - "level_num" is the APV Level numbered consecutively
+ // (i.e., Level 1 == 1, Level 1.1 == 2, etc.)
+ // - "band" is the APV Band
+
+ /** APV Codec Level 1, Band 0 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel1Band0 = 0x101;
+ /** APV Codec Level 1, Band 1 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel1Band1 = 0x102;
+ /** APV Codec Level 1, Band 2 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel1Band2 = 0x104;
+ /** APV Codec Level 1, Band 3 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel1Band3 = 0x108;
+ /** APV Codec Level 1.1, Band 0 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel11Band0 = 0x201;
+ /** APV Codec Level 1.1, Band 1 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel11Band1 = 0x202;
+ /** APV Codec Level 1.1, Band 2 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel11Band2 = 0x204;
+ /** APV Codec Level 1.1, Band 3 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel11Band3 = 0x208;
+ /** APV Codec Level 2, Band 0 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel2Band0 = 0x401;
+ /** APV Codec Level 2, Band 1 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel2Band1 = 0x402;
+ /** APV Codec Level 2, Band 2 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel2Band2 = 0x404;
+ /** APV Codec Level 2, Band 3 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel2Band3 = 0x408;
+ /** APV Codec Level 2.1, Band 0 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel21Band0 = 0x801;
+ /** APV Codec Level 2.1, Band 1 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel21Band1 = 0x802;
+ /** APV Codec Level 2.1, Band 2 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel21Band2 = 0x804;
+ /** APV Codec Level 2.1, Band 3 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel21Band3 = 0x808;
+ /** APV Codec Level 3, Band 0 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel3Band0 = 0x1001;
+ /** APV Codec Level 3, Band 1 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel3Band1 = 0x1002;
+ /** APV Codec Level 3, Band 2 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel3Band2 = 0x1004;
+ /** APV Codec Level 3, Band 3 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel3Band3 = 0x1008;
+ /** APV Codec Level 3.1, Band 0 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel31Band0 = 0x2001;
+ /** APV Codec Level 3.1, Band 1 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel31Band1 = 0x2002;
+ /** APV Codec Level 3.1, Band 2 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel31Band2 = 0x2004;
+ /** APV Codec Level 3.1, Band 3 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel31Band3 = 0x2008;
+ /** APV Codec Level 4, Band 0 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel4Band0 = 0x4001;
+ /** APV Codec Level 4, Band 1 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel4Band1 = 0x4002;
+ /** APV Codec Level 4, Band 2 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel4Band2 = 0x4004;
+ /** APV Codec Level 4, Band 3 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel4Band3 = 0x4008;
+ /** APV Codec Level 4.1, Band 0 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel41Band0 = 0x8001;
+ /** APV Codec Level 4.1, Band 1 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel41Band1 = 0x8002;
+ /** APV Codec Level 4.1, Band 2 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel41Band2 = 0x8004;
+ /** APV Codec Level 4.1, Band 3 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel41Band3 = 0x8008;
+ /** APV Codec Level 5, Band 0 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel5Band0 = 0x10001;
+ /** APV Codec Level 5, Band 1 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel5Band1 = 0x10002;
+ /** APV Codec Level 5, Band 2 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel5Band2 = 0x10004;
+ /** APV Codec Level 5, Band 3 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel5Band3 = 0x10008;
+ /** APV Codec Level 5.1, Band 0 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel51Band0 = 0x20001;
+ /** APV Codec Level 5.1, Band 1 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel51Band1 = 0x20002;
+ /** APV Codec Level 5.1, Band 2 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel51Band2 = 0x20004;
+ /** APV Codec Level 5.1, Band 3 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel51Band3 = 0x20008;
+ /** APV Codec Level 6, Band 0 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel6Band0 = 0x40001;
+ /** APV Codec Level 6, Band 1 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel6Band1 = 0x40002;
+ /** APV Codec Level 6, Band 2 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel6Band2 = 0x40004;
+ /** APV Codec Level 6, Band 3 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel6Band3 = 0x40008;
+ /** APV Codec Level 6.1, Band 0 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel61Band0 = 0x80001;
+ /** APV Codec Level 6.1, Band 1 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel61Band1 = 0x80002;
+ /** APV Codec Level 6.1, Band 2 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel61Band2 = 0x80004;
+ /** APV Codec Level 6.1, Band 3 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel61Band3 = 0x80008;
+ /** APV Codec Level 7, Band 0 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel7Band0 = 0x100001;
+ /** APV Codec Level 7, Band 1 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel7Band1 = 0x100002;
+ /** APV Codec Level 7, Band 2 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel7Band2 = 0x100004;
+ /** APV Codec Level 7, Band 3 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel7Band3 = 0x100008;
+ /** APV Codec Level 7.1, Band 0 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel71Band0 = 0x200001;
+ /** APV Codec Level 7.1, Band 1 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel71Band1 = 0x200002;
+ /** APV Codec Level 7.1, Band 2 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel71Band2 = 0x200004;
+ /** APV Codec Level 7.1, Band 3 as per IETF lim-apv-02, 10.1.4 */
+ @SuppressLint("AllUpper")
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final int APVLevel71Band3 = 0x200008;
+
/**
* The profile of the media content. Depending on the type of media this can be
* one of the profile values defined in this class.
diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java
index cd0654ceb348..b08a86ee8f46 100644
--- a/media/java/android/media/MediaFormat.java
+++ b/media/java/android/media/MediaFormat.java
@@ -18,6 +18,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 android.media.codec.Flags.FLAG_APV_SUPPORT;
import static com.android.media.codec.flags.Flags.FLAG_CODEC_IMPORTANCE;
import static com.android.media.codec.flags.Flags.FLAG_LARGE_AUDIO_FRAME;
@@ -157,6 +158,8 @@ import java.util.stream.Collectors;
public final class MediaFormat {
public static final String MIMETYPE_VIDEO_VP8 = "video/x-vnd.on2.vp8";
public static final String MIMETYPE_VIDEO_VP9 = "video/x-vnd.on2.vp9";
+ @FlaggedApi(FLAG_APV_SUPPORT)
+ public static final String MIMETYPE_VIDEO_APV = "video/apv";
public static final String MIMETYPE_VIDEO_AV1 = "video/av01";
public static final String MIMETYPE_VIDEO_AVC = "video/avc";
public static final String MIMETYPE_VIDEO_HEVC = "video/hevc";
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index bdfa63010adc..2d17bf500f12 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -387,13 +387,13 @@ public class MediaRecorder implements AudioRouting,
/**
* Audio source for capturing broadcast radio tuner output.
* Capturing the radio tuner output requires the
- * {@link android.Manifest.permission#CAPTURE_AUDIO_OUTPUT} permission.
+ * {@link android.Manifest.permission#CAPTURE_TUNER_AUDIO_INPUT} permission.
* This permission is reserved for use by system components and is not available to
* third-party applications.
* @hide
*/
@SystemApi
- @RequiresPermission(android.Manifest.permission.CAPTURE_AUDIO_OUTPUT)
+ @RequiresPermission(android.Manifest.permission.CAPTURE_TUNER_AUDIO_INPUT)
public static final int RADIO_TUNER = 1998;
/**
diff --git a/native/graphics/jni/Android.bp b/native/graphics/jni/Android.bp
index 0fb3049f63d8..23dd9b7aee37 100644
--- a/native/graphics/jni/Android.bp
+++ b/native/graphics/jni/Android.bp
@@ -48,7 +48,9 @@ cc_library_shared {
"libhwui_internal_headers",
],
- static_libs: ["libarect"],
+ static_libs: [
+ "libarect",
+ ],
host_supported: true,
target: {
@@ -60,6 +62,11 @@ cc_library_shared {
shared_libs: [
"libandroid",
],
+ static_libs: [
+ "libstatslog_hwui",
+ "libstatspull_lazy",
+ "libstatssocket_lazy",
+ ],
version_script: "libjnigraphics.map.txt",
},
host: {
diff --git a/native/graphics/jni/imagedecoder.cpp b/native/graphics/jni/imagedecoder.cpp
index e18b4a9d2420..cb95bcf5d2b1 100644
--- a/native/graphics/jni/imagedecoder.cpp
+++ b/native/graphics/jni/imagedecoder.cpp
@@ -14,18 +14,9 @@
* limitations under the License.
*/
-#include "aassetstreamadaptor.h"
-
-#include <android/asset_manager.h>
-#include <android/bitmap.h>
-#include <android/data_space.h>
-#include <android/imagedecoder.h>
#include <MimeType.h>
-#include <android/rect.h>
-#include <hwui/ImageDecoder.h>
-#include <log/log.h>
-#include <SkAndroidCodec.h>
#include <SkAlphaType.h>
+#include <SkAndroidCodec.h>
#include <SkCodec.h>
#include <SkCodecAnimation.h>
#include <SkColorSpace.h>
@@ -35,14 +26,24 @@
#include <SkRefCnt.h>
#include <SkSize.h>
#include <SkStream.h>
-#include <utils/Color.h>
-
+#include <android/asset_manager.h>
+#include <android/bitmap.h>
+#include <android/data_space.h>
+#include <android/imagedecoder.h>
+#include <android/rect.h>
#include <fcntl.h>
-#include <limits>
-#include <optional>
+#include <hwui/ImageDecoder.h>
+#include <log/log.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
+#include <utils/Color.h>
+#include <utils/StatsUtils.h>
+
+#include <limits>
+#include <optional>
+
+#include "aassetstreamadaptor.h"
using namespace android;
@@ -400,9 +401,7 @@ size_t AImageDecoder_getMinimumStride(AImageDecoder* decoder) {
return info.minRowBytes();
}
-int AImageDecoder_decodeImage(AImageDecoder* decoder,
- void* pixels, size_t stride,
- size_t size) {
+int AImageDecoder_decodeImage(AImageDecoder* decoder, void* pixels, size_t stride, size_t size) {
if (!decoder || !pixels || !stride) {
return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
}
@@ -419,7 +418,13 @@ int AImageDecoder_decodeImage(AImageDecoder* decoder,
return ANDROID_IMAGE_DECODER_FINISHED;
}
- return ResultToErrorCode(imageDecoder->decode(pixels, stride));
+ const auto result = ResultToErrorCode(imageDecoder->decode(pixels, stride));
+
+ if (result == ANDROID_IMAGE_DECODER_SUCCESS) {
+ uirenderer::logBitmapDecode(imageDecoder->getOutputInfo(), false);
+ }
+
+ return result;
}
void AImageDecoder_delete(AImageDecoder* decoder) {
diff --git a/packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/HandlerExecutor.kt b/packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/HandlerExecutor.kt
index be086061f5cb..99d3c8db7716 100644
--- a/packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/HandlerExecutor.kt
+++ b/packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/HandlerExecutor.kt
@@ -24,7 +24,7 @@ import java.util.concurrent.Executor
* Adapter of [Handler] and [Executor], where the task is executed on handler with given looper.
*
* When current looper is same with the given looper, task passed to [Executor.execute] will be
- * executed immediately to improve better performance.
+ * executed immediately to achieve better performance.
*
* @param looper Looper of the handler.
*/
diff --git a/packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/KeyedObserver.kt b/packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/KeyedObserver.kt
index 9cb0ebb995a8..843d2aadf333 100644
--- a/packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/KeyedObserver.kt
+++ b/packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/KeyedObserver.kt
@@ -114,6 +114,10 @@ interface KeyedObservable<K> {
fun notifyChange(key: K, reason: Int)
}
+/** Delegation of [KeyedObservable]. */
+open class KeyedObservableDelegate<K>(delegate: KeyedObservable<K>) :
+ KeyedObservable<K> by delegate
+
/** A thread safe implementation of [KeyedObservable]. */
open class KeyedDataObservable<K> : KeyedObservable<K> {
// Instead of @GuardedBy("this"), guarded by itself because KeyedDataObservable object could be
diff --git a/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceScreenBindingHelper.kt b/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceScreenBindingHelper.kt
index 7af9c81a61c1..d75f3e84274d 100644
--- a/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceScreenBindingHelper.kt
+++ b/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceScreenBindingHelper.kt
@@ -237,7 +237,8 @@ class PreferenceScreenBindingHelper(
} else {
preferences[preference.key]?.let {
preferenceBindingFactory.bind(preference, it)
- (it as? PersistentPreference<*>)?.storage(context)?.let { storage ->
+ val metadata = it.metadata
+ (metadata as? PersistentPreference<*>)?.storage(context)?.let { storage ->
preference.preferenceDataStore =
storages.getOrPut(storage) { PreferenceDataStoreAdapter(storage) }
}
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index b76b028ac4b9..4d334660895e 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -82,7 +82,7 @@
<string name="speed_label_very_fast" msgid="8215718029533182439">"Veoma brzo"</string>
<string name="wifi_passpoint_expired" msgid="6540867261754427561">"Isteklo"</string>
<string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
- <string name="bluetooth_disconnected" msgid="7739366554710388701">"Isključen"</string>
+ <string name="bluetooth_disconnected" msgid="7739366554710388701">"Nije povezano"</string>
<string name="bluetooth_disconnecting" msgid="7638892134401574338">"Prekidanje veze…"</string>
<string name="bluetooth_connecting" msgid="5871702668260192755">"Povezivanje…"</string>
<string name="bluetooth_connected" msgid="8065345572198502293">"Povezano<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-in/arrays.xml b/packages/SettingsLib/res/values-in/arrays.xml
index 038800cf4bfa..00ea04d68c16 100644
--- a/packages/SettingsLib/res/values-in/arrays.xml
+++ b/packages/SettingsLib/res/values-in/arrays.xml
@@ -29,7 +29,7 @@
<item msgid="4613015005934755724">"Terhubung"</item>
<item msgid="3763530049995655072">"Ditangguhkan"</item>
<item msgid="7852381437933824454">"Memutus sambungan..."</item>
- <item msgid="5046795712175415059">"Sambungan terputus"</item>
+ <item msgid="5046795712175415059">"Tidak terhubung"</item>
<item msgid="2473654476624070462">"Gagal"</item>
<item msgid="9146847076036105115">"Diblokir"</item>
<item msgid="4543924085816294893">"Menghindari sambungan buruk untuk sementara"</item>
@@ -43,7 +43,7 @@
<item msgid="1043944043827424501">"Terhubung ke <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</item>
<item msgid="7445993821842009653">"Ditangguhkan"</item>
<item msgid="1175040558087735707">"Diputus dari <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item>
- <item msgid="699832486578171722">"Sambungan terputus"</item>
+ <item msgid="699832486578171722">"Tidak terhubung"</item>
<item msgid="522383512264986901">"Gagal"</item>
<item msgid="3602596701217484364">"Diblokir"</item>
<item msgid="1999413958589971747">"Menghindari sambungan buruk untuk sementara"</item>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 3b265f8e9d38..bfd8f397be60 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -50,7 +50,7 @@
<string name="wifi_security_owe" msgid="3343421403561657809">"Enhanced Open"</string>
<string name="wifi_security_eap_suiteb" msgid="415842785991698142">"WPA3-Enterprise 192-bit"</string>
<string name="wifi_remembered" msgid="3266709779723179188">"Disimpan"</string>
- <string name="wifi_disconnected" msgid="7054450256284661757">"Terputus"</string>
+ <string name="wifi_disconnected" msgid="7054450256284661757">"Tidak terhubung"</string>
<string name="wifi_disabled_generic" msgid="2651916945380294607">"Nonaktif"</string>
<string name="wifi_disabled_network_failure" msgid="2660396183242399585">"Kegagalan Konfigurasi IP"</string>
<string name="wifi_disabled_password_failure" msgid="6892387079613226738">"Masalah autentikasi"</string>
@@ -82,7 +82,7 @@
<string name="speed_label_very_fast" msgid="8215718029533182439">"Sangat Cepat"</string>
<string name="wifi_passpoint_expired" msgid="6540867261754427561">"Sudah tidak berlaku"</string>
<string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
- <string name="bluetooth_disconnected" msgid="7739366554710388701">"Sambungan terputus"</string>
+ <string name="bluetooth_disconnected" msgid="7739366554710388701">"Tidak terhubung"</string>
<string name="bluetooth_disconnecting" msgid="7638892134401574338">"Memutus sambungan..."</string>
<string name="bluetooth_connecting" msgid="5871702668260192755">"Menghubungkan…"</string>
<string name="bluetooth_connected" msgid="8065345572198502293">"Terhubung<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index 2fb036f8356c..785bf43bb4d1 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -258,7 +258,7 @@
<string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"QR кодунун сканерин колдонуп, жаңы түзмөктөрдү жупташтырыңыз"</string>
<string name="adb_pair_method_code_title" msgid="1122590300445142904">"Түзмөктү атайын код аркылуу жупташтыруу"</string>
<string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Жаңы түзмөктөрдү алты сандан турган код аркылуу жупташтырасыз"</string>
- <string name="adb_paired_devices_title" msgid="5268997341526217362">"Жупташтырылган түзмөктөр"</string>
+ <string name="adb_paired_devices_title" msgid="5268997341526217362">"Байланышкан түзмөктөр"</string>
<string name="adb_wireless_device_connected_summary" msgid="3039660790249148713">"Учурда туташып турган түзмөктөр"</string>
<string name="adb_wireless_device_details_title" msgid="7129369670526565786">"Түзмөктүн чоо-жайы"</string>
<string name="adb_device_forget" msgid="193072400783068417">"Унутулсун"</string>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index f5e84a23aa07..b9d970d8388f 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -85,7 +85,7 @@
<string name="bluetooth_disconnected" msgid="7739366554710388701">"Не е поврзано"</string>
<string name="bluetooth_disconnecting" msgid="7638892134401574338">"Се исклучува..."</string>
<string name="bluetooth_connecting" msgid="5871702668260192755">"Се поврзува..."</string>
- <string name="bluetooth_connected" msgid="8065345572198502293">"Поврзан со <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
+ <string name="bluetooth_connected" msgid="8065345572198502293">"Поврзано<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
<string name="bluetooth_pairing" msgid="4269046942588193600">"Се спарува..."</string>
<string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"Поврзан со <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> (без телефон)"</string>
<string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"Поврзан со <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g> (без аудиовизуелни содржини)"</string>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index 73b099695da8..ae1df210bce3 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -82,7 +82,7 @@
<string name="speed_label_very_fast" msgid="8215718029533182439">"ଅତି ଦ୍ରୁତ"</string>
<string name="wifi_passpoint_expired" msgid="6540867261754427561">"ମିଆଦ ଶେଷ ହୋଇଯାଇଛି"</string>
<string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
- <string name="bluetooth_disconnected" msgid="7739366554710388701">"ବିଛିନ୍ନ ହେଲା"</string>
+ <string name="bluetooth_disconnected" msgid="7739366554710388701">"ଡିସକନେକ୍ଟ ହୋଇଛି"</string>
<string name="bluetooth_disconnecting" msgid="7638892134401574338">"ବିଚ୍ଛିନ୍ନ କରୁଛି…"</string>
<string name="bluetooth_connecting" msgid="5871702668260192755">"କନେକ୍ଟ ହେଉଛି…"</string>
<string name="bluetooth_connected" msgid="8065345572198502293">"ସଂଯୁକ୍ତ ହେଲା<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index 74c294b84db7..4c41b7d4e397 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -82,7 +82,7 @@
<string name="speed_label_very_fast" msgid="8215718029533182439">"Veľmi rýchla"</string>
<string name="wifi_passpoint_expired" msgid="6540867261754427561">"Vypršalo"</string>
<string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
- <string name="bluetooth_disconnected" msgid="7739366554710388701">"Odpojený"</string>
+ <string name="bluetooth_disconnected" msgid="7739366554710388701">"Odpojené"</string>
<string name="bluetooth_disconnecting" msgid="7638892134401574338">"Prebieha odpájanie..."</string>
<string name="bluetooth_connecting" msgid="5871702668260192755">"Prebieha pripájanie…"</string>
<string name="bluetooth_connected" msgid="8065345572198502293">"Pripojené k zariadeniu <xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index 1c1117d39d5b..1d7f62ac6c93 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -82,7 +82,7 @@
<string name="speed_label_very_fast" msgid="8215718029533182439">"Mycket snabb"</string>
<string name="wifi_passpoint_expired" msgid="6540867261754427561">"Har upphört att gälla"</string>
<string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
- <string name="bluetooth_disconnected" msgid="7739366554710388701">"Kopplas ifrån"</string>
+ <string name="bluetooth_disconnected" msgid="7739366554710388701">"Frånkopplad"</string>
<string name="bluetooth_disconnecting" msgid="7638892134401574338">"Kopplar ifrån…"</string>
<string name="bluetooth_connecting" msgid="5871702668260192755">"Ansluter…"</string>
<string name="bluetooth_connected" msgid="8065345572198502293">"Ansluten<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index 57b8f5914e71..060b7b267624 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -82,7 +82,7 @@
<string name="speed_label_very_fast" msgid="8215718029533182439">"เร็วมาก"</string>
<string name="wifi_passpoint_expired" msgid="6540867261754427561">"หมดอายุแล้ว"</string>
<string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
- <string name="bluetooth_disconnected" msgid="7739366554710388701">"ตัดการเชื่อมต่อ"</string>
+ <string name="bluetooth_disconnected" msgid="7739366554710388701">"ยกเลิกการเชื่อมต่อแล้ว"</string>
<string name="bluetooth_disconnecting" msgid="7638892134401574338">"กำลังตัดการเชื่อมต่อ..."</string>
<string name="bluetooth_connecting" msgid="5871702668260192755">"กำลังเชื่อมต่อ…"</string>
<string name="bluetooth_connected" msgid="8065345572198502293">"เชื่อมต่อแล้ว<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig
index a56c2fe7b0f1..83b75664e1a6 100644
--- a/packages/SystemUI/aconfig/systemui.aconfig
+++ b/packages/SystemUI/aconfig/systemui.aconfig
@@ -1154,6 +1154,13 @@ flag {
}
flag {
+ name: "communal_hub_on_mobile"
+ namespace: "systemui"
+ description: "Brings the glanceable hub experience to mobile phones"
+ bug: "375689917"
+}
+
+flag {
name: "dream_overlay_updated_font"
namespace: "systemui"
description: "Flag to enable updated font settings for dream overlay"
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractorTest.kt
index 9ca3ce6929b0..e9e3e1b37776 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractorTest.kt
@@ -81,7 +81,7 @@ class FromDreamingTransitionInteractorTest(flags: FlagsParameterization?) : Sysu
this.fakeKeyguardTransitionRepository =
FakeKeyguardTransitionRepository(
// This test sends transition steps manually in the test cases.
- sendTransitionStepsOnStartTransition = false,
+ initiallySendTransitionStepsOnStartTransition = false,
testScope = testScope,
)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractorTest.kt
index 9c2e6313a1f0..b29a5f4e456f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractorTest.kt
@@ -27,15 +27,13 @@ import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectValues
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
-import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepositorySpy
+import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
import com.android.systemui.keyguard.data.repository.keyguardOcclusionRepository
-import com.android.systemui.keyguard.data.repository.keyguardTransitionRepository
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.StatusBarState
import com.android.systemui.keyguard.shared.model.StatusBarState.KEYGUARD
import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.keyguard.shared.model.TransitionStep
-import com.android.systemui.keyguard.util.KeyguardTransitionRepositorySpySubject.Companion.assertThat as assertThatRepository
import com.android.systemui.kosmos.testScope
import com.android.systemui.shade.data.repository.FlingInfo
import com.android.systemui.shade.data.repository.fakeShadeRepository
@@ -48,6 +46,8 @@ import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito.reset
+import org.mockito.Mockito.spy
+import com.android.systemui.keyguard.util.KeyguardTransitionRepositorySpySubject.Companion.assertThat as assertThatRepository
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@@ -55,7 +55,9 @@ import org.mockito.Mockito.reset
class FromLockscreenTransitionInteractorTest : SysuiTestCase() {
private val kosmos =
testKosmos().apply {
- this.keyguardTransitionRepository = fakeKeyguardTransitionRepositorySpy
+ this.fakeKeyguardTransitionRepository = spy(FakeKeyguardTransitionRepository(
+ testScope = testScope,
+ ))
}
private val testScope = kosmos.testScope
@@ -66,7 +68,7 @@ class FromLockscreenTransitionInteractorTest : SysuiTestCase() {
@Before
fun setup() {
- transitionRepository = kosmos.fakeKeyguardTransitionRepositorySpy
+ transitionRepository = kosmos.fakeKeyguardTransitionRepository
}
@Test
@@ -302,4 +304,74 @@ class FromLockscreenTransitionInteractorTest : SysuiTestCase() {
to = KeyguardState.LOCKSCREEN,
)
}
+
+ /**
+ * External signals can cause us to transition from PRIMARY_BOUNCER -> * while a manual
+ * transition is in progress. This test was added after a bug that caused the manual transition
+ * ID to get stuck in this scenario, preventing subsequent transitions to PRIMARY_BOUNCER.
+ */
+ @Test
+ fun testExternalTransitionAwayFromBouncer_transitionIdNotStuck() =
+ testScope.runTest {
+ underTest.start()
+ keyguardRepository.setStatusBarState(StatusBarState.KEYGUARD)
+ keyguardRepository.setKeyguardDismissible(false)
+ shadeRepository.setLegacyShadeTracking(true)
+ keyguardRepository.setKeyguardOccluded(false)
+ runCurrent()
+
+ reset(transitionRepository)
+
+ // Disable automatic sending of transition steps so we can send steps through RUNNING
+ // to simulate a cancellation.
+ transitionRepository.sendTransitionStepsOnStartTransition = false
+ shadeRepository.setLegacyShadeExpansion(0.5f)
+ runCurrent()
+
+ assertThatRepository(transitionRepository)
+ .startedTransition(
+ from = KeyguardState.LOCKSCREEN,
+ to = KeyguardState.PRIMARY_BOUNCER,
+ )
+
+ // Partially transition to PRIMARY_BOUNCER.
+ transitionRepository.sendTransitionSteps(
+ from = KeyguardState.LOCKSCREEN,
+ to = KeyguardState.PRIMARY_BOUNCER,
+ throughTransitionState = TransitionState.RUNNING,
+ testScope = testScope,
+ )
+
+ // Start a transition to GONE, which will cancel LS -> BOUNCER.
+ transitionRepository.sendTransitionSteps(
+ from = KeyguardState.PRIMARY_BOUNCER,
+ to = KeyguardState.GONE,
+ testScope = testScope,
+ )
+
+ // Go to AOD, then LOCKSCREEN.
+ transitionRepository.sendTransitionSteps(
+ from = KeyguardState.GONE,
+ to = KeyguardState.AOD,
+ testScope = testScope,
+ )
+ transitionRepository.sendTransitionSteps(
+ from = KeyguardState.AOD,
+ to = KeyguardState.LOCKSCREEN,
+ testScope = testScope,
+ )
+
+ reset(transitionRepository)
+
+ // Start a swipe up to the bouncer, and verify that we started a transition to
+ // PRIMARY_BOUNCER, verifying the transition ID did not get stuck.
+ shadeRepository.setLegacyShadeExpansion(0.25f)
+ runCurrent()
+
+ assertThatRepository(transitionRepository)
+ .startedTransition(
+ from = KeyguardState.LOCKSCREEN,
+ to = KeyguardState.PRIMARY_BOUNCER,
+ )
+ }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/composefragment/viewmodel/AbstractQSFragmentComposeViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/composefragment/viewmodel/AbstractQSFragmentComposeViewModelTest.kt
index 2e2894d43b12..b5fc52f7a8d6 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/composefragment/viewmodel/AbstractQSFragmentComposeViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/composefragment/viewmodel/AbstractQSFragmentComposeViewModelTest.kt
@@ -24,12 +24,16 @@ import com.android.systemui.SysuiTestCase
import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.kosmos.testScope
import com.android.systemui.lifecycle.activateIn
+import com.android.systemui.media.controls.domain.pipeline.legacyMediaDataManagerImpl
+import com.android.systemui.media.controls.domain.pipeline.mediaDataManager
+import com.android.systemui.qs.composefragment.dagger.usingMediaInComposeFragment
import com.android.systemui.testKosmos
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.TestResult
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.resetMain
+import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import kotlinx.coroutines.test.setMain
import org.junit.After
@@ -39,7 +43,7 @@ import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
@OptIn(ExperimentalCoroutinesApi::class)
abstract class AbstractQSFragmentComposeViewModelTest : SysuiTestCase() {
- protected val kosmos = testKosmos()
+ protected val kosmos = testKosmos().apply { mediaDataManager = legacyMediaDataManagerImpl }
protected val lifecycleOwner =
TestLifecycleOwner(
@@ -62,11 +66,15 @@ abstract class AbstractQSFragmentComposeViewModelTest : SysuiTestCase() {
}
protected inline fun TestScope.testWithinLifecycle(
- crossinline block: suspend TestScope.() -> TestResult
+ usingMedia: Boolean = true,
+ crossinline block: suspend TestScope.() -> TestResult,
): TestResult {
return runTest {
+ kosmos.usingMediaInComposeFragment = usingMedia
+
lifecycleOwner.setCurrentState(Lifecycle.State.RESUMED)
underTest.activateIn(kosmos.testScope)
+ runCurrent()
block().also { lifecycleOwner.setCurrentState(Lifecycle.State.DESTROYED) }
}
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelTest.kt
index 3b00f86c8f6a..9fe9ed2bf47a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelTest.kt
@@ -25,6 +25,15 @@ import androidx.test.filters.SmallTest
import com.android.systemui.common.ui.data.repository.fakeConfigurationRepository
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.kosmos.testScope
+import com.android.systemui.media.controls.domain.pipeline.legacyMediaDataManagerImpl
+import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager
+import com.android.systemui.media.controls.ui.controller.mediaCarouselController
+import com.android.systemui.media.controls.ui.view.MediaHostState
+import com.android.systemui.media.controls.ui.view.qqsMediaHost
+import com.android.systemui.media.controls.ui.view.qsMediaHost
+import com.android.systemui.qs.composefragment.viewmodel.MediaState.ACTIVE_MEDIA
+import com.android.systemui.qs.composefragment.viewmodel.MediaState.ANY_MEDIA
+import com.android.systemui.qs.composefragment.viewmodel.MediaState.NO_MEDIA
import com.android.systemui.qs.fgsManagerController
import com.android.systemui.qs.panels.domain.interactor.tileSquishinessInteractor
import com.android.systemui.res.R
@@ -35,9 +44,11 @@ import com.android.systemui.statusbar.disableflags.data.repository.fakeDisableFl
import com.android.systemui.statusbar.sysuiStatusBarStateController
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runCurrent
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.kotlin.whenever
@SmallTest
@RunWith(AndroidJUnit4::class)
@@ -185,6 +196,92 @@ class QSFragmentComposeViewModelTest : AbstractQSFragmentComposeViewModelTest()
}
}
+ @Test
+ fun qqsMediaHost_initializedCorrectly() =
+ with(kosmos) {
+ testScope.testWithinLifecycle {
+ assertThat(underTest.qqsMediaHost.location)
+ .isEqualTo(MediaHierarchyManager.LOCATION_QQS)
+ assertThat(underTest.qqsMediaHost.expansion).isEqualTo(MediaHostState.EXPANDED)
+ assertThat(underTest.qqsMediaHost.showsOnlyActiveMedia).isTrue()
+ assertThat(underTest.qqsMediaHost.hostView).isNotNull()
+ }
+ }
+
+ @Test
+ fun qsMediaHost_initializedCorrectly() =
+ with(kosmos) {
+ testScope.testWithinLifecycle {
+ assertThat(underTest.qsMediaHost.location)
+ .isEqualTo(MediaHierarchyManager.LOCATION_QS)
+ assertThat(underTest.qsMediaHost.expansion).isEqualTo(MediaHostState.EXPANDED)
+ assertThat(underTest.qsMediaHost.showsOnlyActiveMedia).isFalse()
+ assertThat(underTest.qsMediaHost.hostView).isNotNull()
+ }
+ }
+
+ @Test
+ fun qqsMediaVisible_onlyWhenActiveMedia() =
+ with(kosmos) {
+ testScope.testWithinLifecycle {
+ whenever(mediaCarouselController.isLockedAndHidden()).thenReturn(false)
+
+ assertThat(underTest.qqsMediaVisible).isEqualTo(underTest.qqsMediaHost.visible)
+
+ setMediaState(NO_MEDIA)
+ assertThat(underTest.qqsMediaVisible).isFalse()
+
+ setMediaState(ANY_MEDIA)
+ assertThat(underTest.qqsMediaVisible).isFalse()
+
+ setMediaState(ACTIVE_MEDIA)
+ assertThat(underTest.qqsMediaVisible).isTrue()
+ }
+ }
+
+ @Test
+ fun qsMediaVisible_onAnyMedia() =
+ with(kosmos) {
+ testScope.testWithinLifecycle {
+ whenever(mediaCarouselController.isLockedAndHidden()).thenReturn(false)
+
+ assertThat(underTest.qsMediaVisible).isEqualTo(underTest.qsMediaHost.visible)
+
+ setMediaState(NO_MEDIA)
+ assertThat(underTest.qsMediaVisible).isFalse()
+
+ setMediaState(ANY_MEDIA)
+ assertThat(underTest.qsMediaVisible).isTrue()
+
+ setMediaState(ACTIVE_MEDIA)
+ assertThat(underTest.qsMediaVisible).isTrue()
+ }
+ }
+
+ @Test
+ fun notUsingMedia_mediaNotVisible() =
+ with(kosmos) {
+ testScope.testWithinLifecycle(usingMedia = false) {
+ setMediaState(ACTIVE_MEDIA)
+
+ assertThat(underTest.qqsMediaVisible).isFalse()
+ assertThat(underTest.qsMediaVisible).isFalse()
+ }
+ }
+
+ private fun TestScope.setMediaState(state: MediaState) {
+ with(kosmos) {
+ val activeMedia = state == ACTIVE_MEDIA
+ val anyMedia = state != NO_MEDIA
+ whenever(legacyMediaDataManagerImpl.hasActiveMediaOrRecommendation())
+ .thenReturn(activeMedia)
+ whenever(legacyMediaDataManagerImpl.hasAnyMediaOrRecommendation()).thenReturn(anyMedia)
+ qqsMediaHost.updateViewVisibility()
+ qsMediaHost.updateViewVisibility()
+ }
+ runCurrent()
+ }
+
companion object {
private const val QS_DISABLE_FLAG = StatusBarManager.DISABLE2_QUICK_SETTINGS
@@ -195,3 +292,9 @@ class QSFragmentComposeViewModelTest : AbstractQSFragmentComposeViewModelTest()
private const val epsilon = 0.001f
}
}
+
+private enum class MediaState {
+ ACTIVE_MEDIA,
+ ANY_MEDIA,
+ NO_MEDIA,
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModelTest.kt
index 2c894f9aa20f..ab5a049c91f1 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModelTest.kt
@@ -20,21 +20,25 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.common.ui.data.repository.fakeConfigurationRepository
-import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.testCase
import com.android.systemui.kosmos.testScope
+import com.android.systemui.lifecycle.activateIn
import com.android.systemui.qs.panels.domain.interactor.qsPreferencesInteractor
import com.android.systemui.qs.pipeline.domain.interactor.currentTilesInteractor
import com.android.systemui.qs.pipeline.shared.TileSpec
import com.android.systemui.res.R
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
+@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@RunWith(AndroidJUnit4::class)
class QuickQuickSettingsViewModelTest : SysuiTestCase() {
@@ -65,7 +69,8 @@ class QuickQuickSettingsViewModelTest : SysuiTestCase() {
fakeConfigurationRepository.onConfigurationChange()
}
- private val underTest = kosmos.quickQuickSettingsViewModel
+ private val underTest =
+ kosmos.quickQuickSettingsViewModelFactory.create().apply { activateIn(kosmos.testScope) }
@Before
fun setUp() {
@@ -77,17 +82,15 @@ class QuickQuickSettingsViewModelTest : SysuiTestCase() {
with(kosmos) {
testScope.runTest {
setRows(2)
- val columns by collectLastValue(underTest.columns)
- val tileViewModels by collectLastValue(underTest.tileViewModels)
- assertThat(columns).isEqualTo(4)
+ assertThat(underTest.columns).isEqualTo(4)
// All tiles in 4 columns
// [1] [2] [3 3]
// [4] [5 5]
// [6 6] [7] [8]
// [9 9]
- assertThat(tileViewModels!!.map { it.tile.spec }).isEqualTo(tiles.take(5))
+ assertThat(underTest.tileViewModels.map { it.tile.spec }).isEqualTo(tiles.take(5))
}
}
@@ -96,10 +99,8 @@ class QuickQuickSettingsViewModelTest : SysuiTestCase() {
with(kosmos) {
testScope.runTest {
setRows(2)
- val columns by collectLastValue(underTest.columns)
- val tileViewModels by collectLastValue(underTest.tileViewModels)
- assertThat(columns).isEqualTo(4)
+ assertThat(underTest.columns).isEqualTo(4)
// All tiles in 4 columns
// [1] [2] [3 3]
// [4] [5 5]
@@ -107,9 +108,9 @@ class QuickQuickSettingsViewModelTest : SysuiTestCase() {
// [9 9]
setRows(3)
- assertThat(tileViewModels!!.map { it.tile.spec }).isEqualTo(tiles.take(8))
+ assertThat(underTest.tileViewModels.map { it.tile.spec }).isEqualTo(tiles.take(8))
setRows(1)
- assertThat(tileViewModels!!.map { it.tile.spec }).isEqualTo(tiles.take(3))
+ assertThat(underTest.tileViewModels.map { it.tile.spec }).isEqualTo(tiles.take(3))
}
}
@@ -118,10 +119,8 @@ class QuickQuickSettingsViewModelTest : SysuiTestCase() {
with(kosmos) {
testScope.runTest {
setRows(2)
- val columns by collectLastValue(underTest.columns)
- val tileViewModels by collectLastValue(underTest.tileViewModels)
- assertThat(columns).isEqualTo(4)
+ assertThat(underTest.columns).isEqualTo(4)
// All tiles in 4 columns
// [1] [2] [3 3]
// [4] [5 5]
@@ -130,8 +129,9 @@ class QuickQuickSettingsViewModelTest : SysuiTestCase() {
// Remove tile small:4
currentTilesInteractor.removeTiles(setOf(tiles[3]))
+ runCurrent()
- assertThat(tileViewModels!!.map { it.tile.spec })
+ assertThat(underTest.tileViewModels.map { it.tile.spec })
.isEqualTo(
listOf(
"$PREFIX_SMALL:1",
@@ -149,12 +149,15 @@ class QuickQuickSettingsViewModelTest : SysuiTestCase() {
currentTilesInteractor.setTiles(tiles)
}
- private fun Kosmos.setRows(rows: Int) {
- testCase.context.orCreateTestableResources.addOverride(
- R.integer.quick_qs_paginated_grid_num_rows,
- rows,
- )
- fakeConfigurationRepository.onConfigurationChange()
+ private fun TestScope.setRows(rows: Int) {
+ with(kosmos) {
+ testCase.context.orCreateTestableResources.addOverride(
+ R.integer.quick_qs_paginated_grid_num_rows,
+ rows,
+ )
+ fakeConfigurationRepository.onConfigurationChange()
+ }
+ runCurrent()
}
private companion object {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowControllerTest.kt
index c0057431f536..657e9df0029b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowControllerTest.kt
@@ -58,6 +58,7 @@ import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.withArgCaptor
import com.android.systemui.util.time.SystemClock
import com.android.systemui.wmshell.BubblesManager
+import com.google.android.msdl.domain.MSDLPlayer
import java.util.Optional
import junit.framework.Assert
import org.junit.After
@@ -110,6 +111,7 @@ class ExpandableNotificationRowControllerTest : SysuiTestCase() {
private val dismissibilityProvider: NotificationDismissibilityProvider = mock()
private val statusBarService: IStatusBarService = mock()
private val uiEventLogger: UiEventLogger = mock()
+ private val msdlPlayer: MSDLPlayer = mock()
private lateinit var controller: ExpandableNotificationRowController
@Before
@@ -150,7 +152,8 @@ class ExpandableNotificationRowControllerTest : SysuiTestCase() {
dragController,
dismissibilityProvider,
statusBarService,
- uiEventLogger
+ uiEventLogger,
+ msdlPlayer,
)
whenever(view.childrenContainer).thenReturn(childrenContainer)
@@ -268,14 +271,14 @@ class ExpandableNotificationRowControllerTest : SysuiTestCase() {
controller.mSettingsListener.onSettingChanged(
BUBBLES_SETTING_URI,
view.entry.sbn.userId,
- "1"
+ "1",
)
verify(childView).setBubblesEnabledForUser(true)
controller.mSettingsListener.onSettingChanged(
BUBBLES_SETTING_URI,
view.entry.sbn.userId,
- "9"
+ "9",
)
verify(childView).setBubblesEnabledForUser(false)
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
index b2794d8f9b56..0eb620343e6a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
@@ -804,6 +804,13 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
}
@Test
+ public void onBackPressedResetsLeaveOnKeyguardHide() {
+ when(mPrimaryBouncerInteractor.isFullyShowing()).thenReturn(true);
+ mStatusBarKeyguardViewManager.onBackPressed();
+ verify(mStatusBarStateController).setLeaveOpenOnKeyguardHide(false);
+ }
+
+ @Test
public void testResetHideBouncerWhenShowingIsFalse_alternateBouncerHides() {
// GIVEN the keyguard is showing
reset(mAlternateBouncerInteractor);
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManagerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManagerTest.kt
index 48c2cc7f11c4..a00858842742 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManagerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManagerTest.kt
@@ -20,6 +20,8 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.compose.animation.scene.ObservableTransitionState
import com.android.systemui.SysuiTestCase
+import com.android.systemui.communal.data.repository.fakeCommunalSceneRepository
+import com.android.systemui.communal.shared.model.CommunalScenes
import com.android.systemui.flags.DisableSceneContainer
import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.kosmos.testScope
@@ -113,4 +115,21 @@ class StatusBarTouchableRegionManagerTest : SysuiTestCase() {
assertThat(underTest.shouldMakeEntireScreenTouchable()).isFalse()
}
+
+ @Test
+ @DisableSceneContainer
+ fun entireScreenTouchable_communalVisible() =
+ testScope.runTest {
+ assertThat(underTest.shouldMakeEntireScreenTouchable()).isFalse()
+
+ kosmos.fakeCommunalSceneRepository.snapToScene(CommunalScenes.Communal)
+ runCurrent()
+
+ assertThat(underTest.shouldMakeEntireScreenTouchable()).isTrue()
+
+ kosmos.fakeCommunalSceneRepository.snapToScene(CommunalScenes.Blank)
+ runCurrent()
+
+ assertThat(underTest.shouldMakeEntireScreenTouchable()).isFalse()
+ }
}
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 9ec61063691a..c091cbf6c062 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Neem jou skerm op?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Neem een app op"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Neem hele skerm op"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Wanneer jy jou hele skerm opneem, word enigiets wat op jou skerm wys, opgeneem. Wees dus versigtig met dinge soos wagwoorde, betalingbesonderhede, boodskappe, foto’s, en oudio en video."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Wanneer jy ’n app opneem, word enigiets wat in daardie app gewys of gespeel word, opgeneem. Wees dus versigtig met dinge soos wagwoorde, betalingbesonderhede, boodskappe, foto’s, en oudio en video."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Neem skerm op"</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Huidige app"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Toeganklikheid"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Kortpadsleutels"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Soekkortpaaie"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Geen soekresultate nie"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Vou ikoon in"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Vou ikoon uit"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"of"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Sleephandvatsel"</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 598e224c6a0e..af2971b2ec81 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"ማያ ገፅዎን ይቀዳሉ?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"አንድ መተግበሪያ ቅዳ"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"መላው ማያ ገፅን ቅረጽ"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"መላው ማያ ገፅዎን በሚቀዱበት ጊዜ፣ በማያ ገፅዎ ላይ የሚታየው ማንኛውም ነገር ይቀዳል። ስለዚህ እንደ የይለፍ ቃላት፣ የክፍያ ዝርዝሮች፣ መልዕክቶች፣ ፎቶዎች እና ኦዲዮ እና ቪድዮ ላሉ ነገሮች ጥንቃቄ ያድርጉ።"</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"መተግበሪያን ሲቀዱ በዚያ መተግበሪያ ውስጥ የሚታይ ወይም የሚጫወት ማንኛውም ነገር ይቀዳል። ስለዚህ እንደ የይለፍ ቃላት፣ የክፍያ ዝርዝሮች፣ መልዕክቶች፣ ፎቶዎች እና ኦዲዮ እና ቪድዮ ላሉ ነገሮች ጥንቃቄ ያድርጉ።"</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"ማያ ገፅን ቅረጽ"</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"የአሁን መተግበሪያ"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ተደራሽነት"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"የቁልፍ ሰሌዳ አቋራጮች"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"የፍለጋ አቋራጮች"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"ምንም የፍለጋ ውጤቶች የሉም"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"መሰብሰቢያ አዶ"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"መዘርጊያ አዶ"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ወይም"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"መያዣ ይጎትቱ"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 342c8c2980d9..4ebac5a86ec1 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"هل تريد تسجيل محتوى الشاشة؟"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"تسجيل محتوى تطبيق واحد"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"تسجيل محتوى الشاشة بالكامل"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"أثناء تسجيل محتوى الشاشة بالكامل، يتم تسجيل كل المحتوى المعروض على شاشتك. لذا يُرجى توخي الحذر بشأن المعلومات، مثل كلمات المرور وتفاصيل الدفع والرسائل والصور وملفات الصوت والفيديو."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"أثناء تسجيل محتوى تطبيق، يتم تسجيل أي محتوى يتم عرضه أو تشغيله في ذلك التطبيق. لذا يُرجى توخي الحذر بشأن المعلومات، مثل كلمات المرور وتفاصيل الدفع والرسائل والصور وملفات الصوت والفيديو."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"تسجيل محتوى الشاشة"</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"التطبيق الحالي"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"تسهيل الاستخدام"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"اختصارات لوحة المفاتيح"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"اختصارات طلبات البحث"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"ما مِن نتائج بحث"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"رمز التصغير"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"رمز التوسيع"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"أو"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"مقبض السحب"</string>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index b71db2e8528c..85517f3865d2 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"আপোনাৰ স্ক্ৰীনখন ৰেকৰ্ড কৰিবনে?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"এটা এপ্ ৰেকৰ্ড কৰক"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"গোটেই স্ক্ৰীনখন ৰেকৰ্ড কৰক"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"আপুনি গোটেই স্ক্ৰীনখন ৰেকৰ্ডিং কৰিলে, আপোনাৰ স্ক্ৰীনখনত দেখুওৱা যিকোনো বস্তু ৰেকৰ্ড কৰা হয়। গতিকে, পাছৱৰ্ড, পৰিশোধৰ সবিশেষ, বাৰ্তা, ফট’ আৰু অডিঅ’ আৰু ভিডিঅ’ৰ ক্ষেত্ৰত সাৱধান হওক।"</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"আপুনি কোনো এপ্ ৰেকৰ্ড কৰিলে, সেই এপত দেখুওৱা বা প্লে’ কৰা যিকোনো বস্তু ৰেকৰ্ড কৰা হয়। গতিকে, পাছৱৰ্ড, পৰিশোধৰ সবিশেষ, বাৰ্তা, ফট’ আৰু অডিঅ’ আৰু ভিডিঅ’ৰ ক্ষেত্ৰত সাৱধান হওক।"</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"স্ক্ৰীনখন ৰেকৰ্ড কৰক"</string>
@@ -581,10 +583,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"আটাইবোৰ মচক"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"পৰিচালনা কৰক"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"ইতিহাস"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"জাননীৰ ছেটিং"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"জাননীৰ ইতিহাস"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"নতুন"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"নীৰৱ"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"জাননীসমূহ"</string>
@@ -1413,9 +1413,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"বৰ্তমানৰ এপ্‌"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"সাধ্য সুবিধা"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"কীব’ৰ্ডৰ শ্বৰ্টকাট"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"সন্ধানৰ শ্বৰ্টকাট"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"সন্ধানৰ কোনো ফলাফল নাই"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"সংকোচন কৰাৰ চিহ্ন"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"বিস্তাৰ কৰাৰ চিহ্ন"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"অথবা"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ড্ৰেগ হেণ্ডেল"</string>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index d51c9aa3af3d..f08724a81449 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Ekran qeydə alınsın?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Bir tətbiqi qeydə alın"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Bütün ekranı qeydə alın"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Bütün ekranı qeydə alarkən ekranda göstərilən bütün kontent qeydə alınır. Parol, ödəniş detalları, mesaj, foto, habelə audio və video kimi məlumatlarla bağlı diqqətli olun."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Tətbiq qeydə aldıqda həmin tətbiqdə göstərilən və ya işə salınan bütün kontent qeydə alınır. Parol, ödəniş detalları, mesaj, foto, habelə audio və video kimi məlumatlarla bağlı diqqətli olun."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Ekranı qeydə alın"</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Cari tətbiq"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Xüsusi imkanlar"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Klaviatura qısayolları"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Axtarış qısayolları"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Axtarış nəticəsi yoxdur"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"İkonanı yığcamlaşdırın"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"İkonanı genişləndirin"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"və ya"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Dəstəyi çəkin"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 881495f0d3fe..f5096915e261 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Želite da snimite ekran?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Snimi jednu aplikaciju"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Snimi ceo ekran"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Kada snimate ceo ekran, snima se sve što je na njemu. Zato pazite na lozinke, informacije o plaćanju, poruke, slike, audio i video sadržaj."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Kada snimate aplikaciju, snima se sav sadržaj koji se prikazuje ili pušta u njoj. Zato pazite na lozinke, informacije o plaćanju, poruke, slike, audio i video sadržaj."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Snimi ekran"</string>
@@ -581,10 +583,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"Obriši sve"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Upravljaj"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Istorija"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"Podešavanja obaveštenja"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"Istorija obaveštenja"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"Novo"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Nečujno"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Obaveštenja"</string>
@@ -1413,9 +1413,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Aktuelna aplikacija"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Pristupačnost"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Tasterske prečice"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Prečice pretrage"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nema rezultata pretrage"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona za skupljanje"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikona za proširivanje"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ili"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Marker za prevlačenje"</string>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 16bb70cf62ca..bc0e2d189c02 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Запісаць экран?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Запісаць адну праграму"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Запісаць змесціва ўсяго экрана"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Пры запісе ўсяго экрана запісваецца ўсё, што паказваецца на экране. Таму прадухіліце паказ пароляў, плацежных рэквізітаў, паведамленняў, фота, відэа і аўдыя."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Пры запісе праграмы запісваецца ўсё, што паказваецца або прайграецца ў гэтай праграме. Таму прадухіліце паказ пароляў, плацежных рэквізітаў, паведамленняў, фота, відэа і аўдыя."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Запісаць экран"</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Бягучая праграма"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Спецыяльныя магчымасці"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Спалучэнні клавіш"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Пошук спалучэнняў клавіш"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Няма вынікаў пошуку"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Значок \"Згарнуць\""</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Значок \"Разгарнуць\""</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"або"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Маркер перацягвання"</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 2b3a0b9383bf..2ee1f5f0f21e 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Да се записва ли екранът?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Записване на едно приложение"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Записване на целия екран"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Когато записвате целия си екран, се записва всичко, което се показва на него. Затова бъдете внимателни с неща като пароли, подробности за начини на плащане, съобщения, снимки, аудио и видео."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Когато записвате приложение, се записва всичко, което се показва или възпроизвежда в него. Затова бъдете внимателни с неща като пароли, подробности за начини на плащане, съобщения, снимки, аудио и видео."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Записване на екрана"</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Текущо приложение"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Достъпност"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Клавишни комбинации"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Търсете клавишни комбинации"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Няма резултати от търсенето"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Икона за свиване"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Икона за разгъване"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"или"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Манипулатор за преместване с плъзгане"</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index f39a644d5e88..c593210c4613 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"আপনার স্ক্রিন রেকর্ড করবেন?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"একটি অ্যাপ রেকর্ড করুন"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"সম্পূর্ণ স্ক্রিন রেকর্ড করুন"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"আপনার সম্পূর্ণ স্ক্রিন রেকর্ড করার সময়, আপনার স্ক্রিনে দেখানো সব কিছু রেকর্ড করা হয়। তাই পাসওয়ার্ড, পেমেন্টের বিবরণ, মেসেজ, ফটো এবং অডিও ও ভিডিওর মতো বিষয়ের ক্ষেত্রে সতর্ক থাকুন।"</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"আপনি কোনও অ্যাপ রেকর্ড করার সময়, সেই অ্যাপে দেখানো বা চালানো সব কিছু রেকর্ড করা হয়। তাই পাসওয়ার্ড, পেমেন্টের বিবরণ, মেসেজ, ফটো এবং অডিও ও ভিডিওর মতো বিষয়ের ক্ষেত্রে সতর্ক থাকুন।"</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"স্ক্রিন রেকর্ড করুন"</string>
@@ -581,10 +583,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"সব মুছে দিন"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"ম্যানেজ করুন"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"ইতিহাস"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"বিজ্ঞপ্তি সেটিংস"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"বিজ্ঞপ্তির ইতিহাস"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"নতুন"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"আওয়াজ করবে না"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"বিজ্ঞপ্তি"</string>
@@ -1413,9 +1413,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"বর্তমান অ্যাপ"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"অ্যাক্সেসিবিলিটি"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"কীবোর্ড শর্টকাট"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"সার্চ শর্টকাট"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"কোনও সার্চ ফলাফল নেই"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"আইকন আড়াল করুন"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"আইকন বড় করুন"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"অথবা"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"টেনে আনার হ্যান্ডেল"</string>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index ec57c6abede1..38f42659245e 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Snimati ekran?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Snimaj jednu aplikaciju"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Snimaj cijeli ekran"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Kada snimate cijeli ekran, snimat će se sve što se prikazuje na ekranu. Stoga budite oprezni s informacijama kao što su lozinke, podaci o plaćanju, poruke, fotografije, zvukovi i videozapisi."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Kada snimate aplikaciju, snimat će se sve što se prikazuje ili reproducira u toj aplikaciji. Stoga budite oprezni s informacijama kao što su lozinke, podaci o plaćanju, poruke, fotografije, zvukovi i videozapisi."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Snimaj ekran"</string>
@@ -581,10 +583,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"Obriši sve"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Upravljajte"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Historija"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"Postavke obavještenja"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"Historija obavještenja"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"Novo"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Nečujno"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Obavještenja"</string>
@@ -1413,9 +1413,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Trenutna aplikacija"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Pristupačnost"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Prečice tastature"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Prečica pretraživanja"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nema rezultata pretraživanja"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona sužavanja"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikona proširivanja"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ili"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Ručica za prevlačenje"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 9c9ba90a225d..bcaca5ae16e9 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Vols gravar la pantalla?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Grava una aplicació"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Grava tota la pantalla"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Quan graves tota la pantalla, es grava tot el que es mostra en pantalla. Per aquest motiu, ves amb compte amb elements com les contrasenyes, les dades de pagament, els missatges, les fotos, i l\'àudio i el vídeo."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Quan graves una aplicació, es grava tot el que es mostra o es reprodueix en aquesta aplicació. Per aquest motiu, ves amb compte amb les contrasenyes, les dades de pagament, els missatges, les fotos, i l\'àudio i el vídeo."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Grava la pantalla"</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Aplicació actual"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibilitat"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Tecles de drecera"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Dreceres de cerca"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"No hi ha cap resultat de la cerca"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Replega la icona"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Desplega la icona"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"o"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Ansa per arrossegar"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 95f369988c1e..76ae86deddd4 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Pořídit nahrávku obrazovky?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Nahrát jednu aplikaci"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Nahrát celou obrazovku"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Při nahrávání celé obrazovky se zaznamenává veškerý obsah na obrazovce. Buďte proto opatrní, když jde o hesla, platební údaje, zprávy, fotografie, zvuk a video."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Při nahrávání aplikace se zaznamenává všechno, co se v dané obrazovce zobrazuje nebo přehrává. Buďte proto opatrní, když jde o hesla, platební údaje, zprávy, fotografie, zvuk a video."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Nahrát obrazovku"</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Aktuální aplikace"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Přístupnost"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Klávesové zkratky"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Vyhledat zkratky"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Žádné výsledky hledání"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona sbalení"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikona rozbalení"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"nebo"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Úchyt pro přetažení"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 8266799a081d..abcd4b8d45ce 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Vil du optage din skærm?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Optag én app"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Optag hele skærmen"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Når du optager hele skærmen, bliver alt det, der vises på skærmen, optaget. Vær derfor forsigtig med ting såsom adgangskoder, betalingsoplysninger, beskeder, billeder, lyd og video."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Når du optager en app, optages alt det, der vises eller afspilles i den pågældende app. Vær derfor forsigtig med ting såsom adgangskoder, betalingsoplysninger, beskeder, billeder, lyd og video."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Optag skærm"</string>
@@ -581,10 +583,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"Ryd alle"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Administrer"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Historik"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"Indstillinger for notifikationer"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"Notifikationshistorik"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"Nye"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Lydløs"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Notifikationer"</string>
@@ -1413,9 +1413,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Aktuel app"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Hjælpefunktioner"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Tastaturgenveje"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Genveje til søgning"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Der er ingen søgeresultater"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikon for Skjul"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikon for Udvid"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"eller"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Håndtag"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index a4bc364be58b..9799a932bcd9 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Bildschirm aufnehmen?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Einzelne App aufnehmen"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Gesamten Bildschirm aufnehmen"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Wenn du den gesamten Bildschirm aufnimmst, ist in der Aufnahme alles zu sehen, was auf dem Bildschirm angezeigt wird. Sei also vorsichtig mit Informationen wie Passwörtern, Zahlungsdetails, Nachrichten, Fotos sowie Audio- und Videoinhalten."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Wenn du eine App aufnimmst, ist in der Aufnahme alles zu sehen, was in dieser App angezeigt oder abgespielt wird. Sei also vorsichtig mit Informationen wie Passwörtern, Zahlungsdetails, Nachrichten, Fotos sowie Audio- und Videoinhalten."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Bildschirm aufnehmen"</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Aktuelle App"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Bedienungshilfen"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Tastenkürzel"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Tastenkürzel suchen"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Keine Suchergebnisse"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Symbol „Minimieren“"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Symbol „Maximieren“"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"oder"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Ziehpunkt"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 278a8ea7cfeb..7200a91b618e 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Να γίνει εγγραφή της οθόνης σας;"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Εγγραφή μίας εφαρμογής"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Εγγραφή ολόκληρης της οθόνης"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Όταν κάνετε εγγραφή ολόκληρης της οθόνη σας, καταγράφεται οτιδήποτε εμφανίζεται σε αυτήν. Επομένως, να είστε προσεκτικοί με τους κωδικούς πρόσβασης, τα στοιχεία πληρωμής, τα μηνύματα, τις φωτογραφίες, τον ήχο και το βίντεο."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Όταν κάνετε εγγραφή μιας εφαρμογής, καταγράφεται οτιδήποτε εμφανίζεται ή αναπαράγεται στη συγκεκριμένη εφαρμογή. Επομένως, να είστε προσεκτικοί με τους κωδικούς πρόσβασης, τα στοιχεία πληρωμής, τα μηνύματα, τις φωτογραφίες, τον ήχο και το βίντεο."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Εγγραφή οθόνης"</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Τρέχουσα εφαρμογή"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Προσβασιμότητα"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Συντομεύσεις πληκτρολογίου"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Συντομεύσεις αναζήτησης"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Κανένα αποτέλεσμα αναζήτησης"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Εικονίδιο σύμπτυξης"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Εικονίδιο ανάπτυξης"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ή"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Λαβή μεταφοράς"</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 2fbd60a11faf..1ecf4f17cac3 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Record your screen?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Record one app"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Record entire screen"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"When you\'re recording your entire screen, anything displayed on your screen is recorded. So, be careful with things like passwords, payment details, messages, photos, audio and video."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"When you\'re recording an app, anything displayed or played in that app is recorded. So, be careful with things like passwords, payment details, messages, photos, audio and video."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Record screen"</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Current app"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibility"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Keyboard shortcuts"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Search shortcuts"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"No search results"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Collapse icon"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Expand icon"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"or"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Drag handle"</string>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index 23475fab120c..f775513ca418 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Record your screen?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Record one app"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Record entire screen"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"When you’re recording your entire screen, anything shown on your screen is recorded. So be careful with things like passwords, payment details, messages, photos, and audio and video."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"When you’re recording an app, anything shown or played in that app is recorded. So be careful with things like passwords, payment details, messages, photos, and audio and video."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Record screen"</string>
@@ -136,17 +138,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"You\'re currently recording <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Stop recording"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Sharing screen"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"Sharing content"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Stop sharing screen?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Stop sharing?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"You\'re currently sharing your entire screen with <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"You\'re currently sharing your entire screen with an app"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"You\'re currently sharing <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"You\'re currently sharing an app"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"You\'re currently sharing with an app"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Stop sharing"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Casting screen"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Stop casting?"</string>
@@ -521,10 +520,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Lock screen widgets"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"Anyone can view widgets on your lock screen, even if your tablet\'s locked."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"unselect widget"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Decrease height"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Increase height"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Lock screen widgets"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"To open an app using a widget, you’ll need to verify it’s you. Also, keep in mind that anyone can view them, even when your tablet’s locked. Some widgets may not have been intended for your lock screen and may be unsafe to add here."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Got it"</string>
@@ -1411,9 +1408,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Current App"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibility"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Keyboard shortcuts"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Search shortcuts"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"No search results"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Collapse icon"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Expand icon"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"or"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Drag handle"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 2fbd60a11faf..1ecf4f17cac3 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Record your screen?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Record one app"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Record entire screen"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"When you\'re recording your entire screen, anything displayed on your screen is recorded. So, be careful with things like passwords, payment details, messages, photos, audio and video."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"When you\'re recording an app, anything displayed or played in that app is recorded. So, be careful with things like passwords, payment details, messages, photos, audio and video."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Record screen"</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Current app"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibility"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Keyboard shortcuts"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Search shortcuts"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"No search results"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Collapse icon"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Expand icon"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"or"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Drag handle"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 2fbd60a11faf..1ecf4f17cac3 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Record your screen?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Record one app"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Record entire screen"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"When you\'re recording your entire screen, anything displayed on your screen is recorded. So, be careful with things like passwords, payment details, messages, photos, audio and video."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"When you\'re recording an app, anything displayed or played in that app is recorded. So, be careful with things like passwords, payment details, messages, photos, audio and video."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Record screen"</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Current app"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibility"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Keyboard shortcuts"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Search shortcuts"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"No search results"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Collapse icon"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Expand icon"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"or"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Drag handle"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 9ea154020d73..77c2a639f903 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"¿Quieres grabar la pantalla?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Grabar una app"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Grabar toda la pantalla"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Cuando grabes toda la pantalla, se grabará todo lo que se muestre en ella. Por lo tanto, debes tener cuidado con contraseñas, detalles de pagos, mensajes, fotos, audios y videos."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Cuando grabes una app, se registrará todo lo que se muestre o reproduzca en ella. Por lo tanto, debes tener cuidado con contraseñas, detalles de pagos, mensajes, fotos, audios y videos."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Grabar pantalla"</string>
@@ -581,10 +583,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"Cerrar todo"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Administrar"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Historial"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"Configuración de notificaciones"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"Historial de notificaciones"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"Nuevo"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Silenciadas"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Notificaciones"</string>
@@ -1413,9 +1413,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"App actual"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accesibilidad"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Combinaciones de teclas"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Buscar combinaciones de teclas"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"La búsqueda no arrojó resultados"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ícono de contraer"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ícono de expandir"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"o"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Controlador de arrastre"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 16ffd44a044c..81b1562ed533 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"¿Grabar la pantalla?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Grabar una aplicación"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Grabar toda la pantalla"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Cuando grabas toda la pantalla, se graba todo lo que se muestre en ella. Debes tener cuidado con elementos como contraseñas, detalles de pagos, mensajes, fotos, audio y vídeo."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Cuando grabas una aplicación, se graba todo lo que se muestre o reproduzca en ella. Debes tener cuidado con elementos como contraseñas, detalles de pagos, mensajes, fotos, audio y vídeo."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Grabar pantalla"</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Aplicación en uso"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accesibilidad"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Combinaciones de teclas"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Atajos de búsqueda"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"No hay resultados de búsqueda"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Icono de contraer"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Icono de desplegar"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"o"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Controlador de arrastre"</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index 5c9664b84d66..56039da5acc8 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Kas salvestada ekraanikuvast video?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Ühe rakenduse salvestamine"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Kogu ekraanikuva salvestamine"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Kui salvestate kogu ekraani, salvestatakse kõik ekraanil kuvatud andmed. Seega olge ettevaatlik selliste andmetega nagu paroolid, makseteave, sõnumid, fotod ning heli ja video."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Kui salvestate rakendust, salvestatakse kõik, mida selles rakenduses näidatakse või esitatakse. Seega olge ettevaatlik selliste andmetega nagu paroolid, makseteave, sõnumid, fotod ning heli ja video."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Ekraanikuva jäädvustamine"</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Praegune rakendus"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Juurdepääsetavus"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Klaviatuuri otseteed"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Otsingu otseteed"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Otsingutulemused puuduvad"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ahendamisikoon"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Laiendamisikoon"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"või"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Lohistamispide"</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 31348b61484f..426d1d754c94 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Pantaila grabatu nahi duzu?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Grabatu aplikazio bat"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Grabatu pantaila osoa"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Pantaila osoa grabatzen ari zarenean, pantailan agertzen den guztia grabatzen da. Beraz, kontuz ibili pasahitzekin, ordainketen xehetasunekin, mezuekin, argazkiekin, audioekin eta bideoekin, besteak beste."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Aplikazio bat grabatzen ari zarenean, aplikazio horretan agertzen den edo bertan erreproduzitzen ari den guztia grabatzen da. Beraz, kontuz ibili pasahitzekin, ordainketen xehetasunekin, mezuekin, argazkiekin, audioekin eta bideoekin, besteak beste."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Grabatu pantaila"</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Oraingo aplikazioa"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Erabilerraztasuna"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Lasterbideak"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Bilatu lasterbideak"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Ez dago bilaketa-emaitzarik"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Tolesteko ikonoa"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Zabaltzeko ikonoa"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"edo"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Arrastatzeko kontrol-puntua"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index bc89200599cb..b0d23aa81898 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"صفحه‌نمایش ضبط شود؟"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"ضبط یک برنامه"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"ضبط کل صفحه‌نمایش"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"وقتی کل صفحه‌نمایش را ضبط می‌کنید، هر چیزی که در صفحه‌نمایش نشان داده شود ضبط خواهد شد. درنتیجه مراقب چیزهایی مثل گذرواژه‌ها، جزئیات پرداخت، پیام‌ها، عکس‌ها، و صدا و تصویر باشید."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"وقتی برنامه‌ای را ضبط می‌کنید، هر چیزی که در آن برنامه نشان داده شود یا پخش شود ضبط خواهد شد. درنتیجه مراقب چیزهایی مثل گذرواژه‌ها، جزئیات پرداخت، پیام‌ها، عکس‌ها، و صدا و تصویر باشید."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"ضبط صفحه‌نمایش"</string>
@@ -581,10 +583,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"پاک کردن همه موارد"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"مدیریت"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"سابقه"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"تنظیمات اعلان"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"سابقه اعلان"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"جدید"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"بی‌صدا"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"اعلان‌ها"</string>
@@ -1413,9 +1413,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"برنامه فعلی"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"دسترس‌پذیری"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"میان‌برهای صفحه‌کلید"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"جستجوی میان‌برها"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"نتیجه‌ای برای جستجو پیدا نشد"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"نماد جمع کردن"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"نماد ازهم بازکردن"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"یا"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"دستگیره کشاندن"</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index a40cbaecfaa5..690228f9d333 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Tallennetaanko näytön toimintaa?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Tallenna yhdestä sovelluksesta"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Tallenna koko näyttö"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Kun tallennat koko näyttöä, kaikki näytöllä näkyvä sisältö tallennetaan. Ole siis varovainen, kun lisäät salasanoja, maksutietoja, viestejä, kuvia, audiota tai videoita."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Kun tallennat sovellusta, kaikki sovelluksessa näkyvä tai toistettu sisältö tallennetaan. Ole siis varovainen, kun lisäät salasanoja, maksutietoja, viestejä, kuvia, audiota tai videoita."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Tallenna näyttö"</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Nykyinen sovellus"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Saavutettavuus"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Pikanäppäimet"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Pikahaut"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Ei hakutuloksia"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Tiivistyskuvake"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Laajennuskuvake"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"tai"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Vetokahva"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 288be348f670..5ea58ce1e574 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Enregistrer votre écran?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Enregistrer une appli"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Enregistrer l\'écran entier"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Lorsque vous enregistrez l\'intégralité de votre écran, tout ce qui s\'affiche sur votre écran est enregistré. Par conséquent, soyez prudent avec les mots de passe, les détails du mode de paiement, les messages, les photos et les contenus audio et vidéo."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Lorsque vous enregistrez une appli, tout ce qui est affiché ou lu dans cette appli est enregistré. Par conséquent, soyez prudent avec les mots de passe, les détails du mode de paiement, les messages, les photos et les contenus audio et vidéo."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Enregistrer l\'écran"</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Appli actuelle"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibilité"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Raccourcis-clavier"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Recherchez des raccourcis"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Aucun résultat de recherche"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Icône Réduire"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Icône Développer"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ou"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Poignée de déplacement"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 9d9f3f99708c..2be31b11c1f5 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Enregistrer l\'écran ?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Enregistrer une appli"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Enregistrer tout l\'écran"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Lorsque vous enregistrez l\'intégralité de votre écran, tout ce qui s\'y affiche est enregistré. Faites donc attention aux éléments tels que les mots de passe, les détails du mode de paiement, les messages, les photos, et les contenus audio et vidéo."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Lorsque vous enregistrez une appli, tout ce qui est affiché ou lu dans celle-ci est enregistré. Faites donc attention aux éléments tels que les mots de passe, détails de mode de paiement, messages, photos et contenus audio et vidéo."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Enregistrer l\'écran"</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Appli actuelle"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibilité"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Raccourcis clavier"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Raccourcis de recherche"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Aucun résultat de recherche"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Icône Réduire"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Icône Développer"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ou"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Poignée de déplacement"</string>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 1430bc2a1131..2bd0b30988e7 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Queres gravar a túa pantalla?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Gravar unha aplicación"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Gravar pantalla completa"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Cando gravas a pantalla completa, recóllese todo o que se mostra nela. Recomendámosche que teñas coidado con determinada información, como os contrasinais, os detalles de pago, as mensaxes e as fotos, así como co contido de audio e de vídeo."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Cando gravas unha aplicación, recóllese todo o que se mostra ou reproduce nela. Recomendámosche que teñas coidado con determinada información, como os contrasinais, os detalles de pago, as mensaxes e as fotos, así como co contido de audio e de vídeo."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Gravar pantalla"</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Aplicación actual"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accesibilidade"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Atallos de teclado"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Atallos de busca"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Non hai resultados de busca"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Icona de contraer"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Icona de despregar"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ou"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Controlador de arrastre"</string>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index bc2739f3a9dc..becca8f8b37f 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"તમારી સ્ક્રીન રેકોર્ડ કરીએ?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"એક ઍપ રેકોર્ડ કરો"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"પૂર્ણ સ્ક્રીન રેકોર્ડ કરો"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"જ્યારે તમે તમારી પૂર્ણ સ્ક્રીન રેકોર્ડ કરી રહ્યાં હો, ત્યારે તમારી સ્ક્રીન પર બતાવવામાં આવતી હોય તેવી બધી વસ્તુ રેકોર્ડ કરવામાં આવે છે. તેથી પાસવર્ડ, ચુકવણીની વિગતો, મેસેજ, ફોટા અને ડિવાઇસ પર વાગી રહેલા ઑડિયો તથા વીડિયો જેવી બાબતોને લઈને સાવચેત રહો."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"જ્યારે તમે કોઈ ઍપને રેકોર્ડ કરી રહ્યાં હો, ત્યારે એ ઍપમાં બતાવવામાં કે ચલાવવામાં આવતી હોય તેવી બધી વસ્તુ રેકોર્ડ કરવામાં આવે છે. તેથી પાસવર્ડ, ચુકવણીની વિગતો, મેસેજ, ફોટા અને ડિવાઇસ પર વાગી રહેલા ઑડિયો તથા વીડિયો જેવી બાબતોને લઈને સાવચેત રહો."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"સ્ક્રીન રેકોર્ડ કરો"</string>
@@ -581,10 +583,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"બધુ સાફ કરો"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"મેનેજ કરો"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"ઇતિહાસ"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"નોટિફિકેશનના સેટિંગ"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"નોટિફિકેશનનો ઇતિહાસ"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"નવા"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"સાઇલન્ટ"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"નોટિફિકેશન"</string>
@@ -1413,9 +1413,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"હાલની ઍપ"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ઍક્સેસિબિલિટી"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"કીબોર્ડ શૉર્ટકટ"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"શૉર્ટકટ શોધો"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"કોઈ શોધ પરિણામો નથી"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"\'નાનું કરો\'નું આઇકન"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"\'મોટું કરો\'નું આઇકન"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"અથવા"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ઑબ્જેક્ટ ખેંચવાનું હૅન્ડલ"</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index f9a1fa5f84ad..a6fc05e2c7e0 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"क्या आपको स्क्रीन रिकॉर्ड करनी है?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"एक ऐप्लिकेशन की रिकॉर्डिंग करें"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"पूरी स्क्रीन रिकॉर्ड करें"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"पूरी स्क्रीन रिकॉर्ड करते समय, स्क्रीन पर दिखने वाली हर चीज़ रिकॉर्ड की जाती है. इसलिए पासवर्ड, पेमेंट के तरीके की जानकारी, मैसेज, डिवाइस पर चल रहे ऑडियो और वीडियो, और फ़ोटो जैसी चीज़ों को लेकर सावधानी बरतें."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"किसी ऐप्लिकेशन को रिकॉर्ड करने के दौरान, उस पर दिख रहा कॉन्टेंट या चल रहा मीडिया दूसरी स्क्रीन पर भी रिकॉर्ड होता है. इसलिए, रिकॉर्ड करते समय पासवर्ड, पेमेंट के तरीके की जानकारी, मैसेज, फ़ोटो, ऑडियो, और वीडियो को लेकर सावधानी बरतें."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"स्क्रीन रिकॉर्ड करें"</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"मौजूदा ऐप्लिकेशन"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"सुलभता"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"कीबोर्ड शॉर्टकट"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"सर्च शॉर्टकट"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"खोज का कोई नतीजा नहीं मिला"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"छोटा करने का आइकॉन"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"बड़ा करने का आइकॉन"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"या"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"खींचकर छोड़ने वाला हैंडल"</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 4a17fdc37b8e..cb7a1931be4d 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Želite li snimati zaslon?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Snimanje jedne aplikacije"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Snimanje cijelog zaslona"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Kad snimate cijeli zaslon, snima se sve što se prikazuje na zaslonu. Stoga pazite na stvari kao što su zaporke, podaci o plaćanju, poruke, fotografije te audio i videozapisi."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Kad snimate aplikaciju, snima se sve što se prikazuje ili reproducira u toj aplikaciji. Stoga pazite na stvari kao što su zaporke, podaci o plaćanju, poruke, fotografije te audio i videozapisi."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Snimanje zaslona"</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Trenutačna aplikacija"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Pristupačnost"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Tipkovni prečaci"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Prečaci za pretraživanje"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nema rezultata pretraživanja"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona za sažimanje"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikona za proširivanje"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ili"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Marker za povlačenje"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index ff5339ff5488..b09947fc2600 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Rögzíti a képernyőt?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Egyetlen alkalmazás rögzítése"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Teljes képernyő rögzítése"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"A teljes képernyő rögzítése esetén a képernyőn megjelenő minden tartalom rögzítésre kerül. Ezért legyen elővigyázatos a jelszavakkal, a fizetési adatokkal, az üzenetekkel, a fotókkal, valamint a hang- és videófelvételekkel."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Alkalmazás rögzítésekor az adott alkalmazásban megjelenített vagy lejátszott minden tartalom rögzítésre kerül. Ezért legyen elővigyázatos a jelszavakkal, a fizetési adatokkal, az üzenetekkel, a fotókkal, valamint a hang- és videófelvételekkel."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Képernyő rögzítése"</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Jelenlegi alkalmazás"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Kisegítő lehetőségek"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Billentyűparancsok"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Billentyűparancsok keresése"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nincsenek keresési találatok"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Összecsukás ikon"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Kibontás ikon"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"vagy"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Fogópont"</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 8fb13478da16..174b52622fd2 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Տեսագրե՞լ ձեր էկրանը"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Տեսագրել մեկ հավելված"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Տեսագրել ամբողջ էկրանը"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Երբ դուք տեսագրում եք ամբողջ էկրանը, էկրանին ցուցադրվող ամեն ինչ տեսագրվում է։ Ուստի ուշադիր եղեք այնպիսի բաների հետ, ինչպիսիք են գաղտնաբառերը, վճարային տվյալները, հաղորդագրությունները, լուսանկարները, աուդիո և վիդեո բովանդակությունը։"</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Երբ դուք որևէ հավելված եք տեսագրում, հավելվածում ցուցադրվող կամ նվագարկվող ամեն ինչ տեսագրվում է։ Ուստի ուշադիր եղեք այնպիսի բաների հետ, ինչպիսիք են գաղտնաբառերը, վճարային տվյալները, հաղորդագրությունները, լուսանկարները, աուդիո և վիդեո բովանդակությունը։"</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Տեսագրել էկրանը"</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Այս հավելվածը"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Հատուկ գործառույթներ"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Ստեղնային դյուրանցումներ"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Դյուրանցումների որոնում"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Որոնման արդյունքներ չկան"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ծալել պատկերակը"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ծավալել պատկերակը"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"կամ"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Տեղափոխման նշիչ"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 0b316befc259..e706b272458a 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Rekam layar Anda?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Rekam satu aplikasi"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Rekam seluruh layar"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Saat Anda merekam seluruh layar, semua hal yang ditampilkan di layar akan direkam. Jadi, berhati-hatilah saat memasukkan sandi, detail pembayaran, pesan, foto, audio, dan video."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Jika Anda merekam aplikasi, semua hal yang ditampilkan atau diputar di aplikasi tersebut akan direkam. Jadi, berhati-hatilah saat memasukkan sandi, detail pembayaran, pesan, foto, audio, dan video."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Rekam layar"</string>
@@ -409,7 +411,7 @@
<string name="quick_settings_onehanded_label" msgid="2416537930246274991">"Mode satu tangan"</string>
<string name="quick_settings_hearing_devices_label" msgid="7277170419679404129">"Alat bantu dengar"</string>
<string name="quick_settings_hearing_devices_connected" msgid="6519069502397037781">"Aktif"</string>
- <string name="quick_settings_hearing_devices_disconnected" msgid="8907061223998176187">"Terputus"</string>
+ <string name="quick_settings_hearing_devices_disconnected" msgid="8907061223998176187">"Tidak terhubung"</string>
<string name="quick_settings_hearing_devices_dialog_title" msgid="9004774017688484981">"Alat bantu dengar"</string>
<string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Sambungkan perangkat baru"</string>
<string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Klik untuk menyambungkan perangkat baru"</string>
@@ -1190,7 +1192,7 @@
<string name="media_output_dialog_group" msgid="5571251347877452212">"Grup"</string>
<string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 perangkat dipilih"</string>
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> perangkat dipilih"</string>
- <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(terputus)"</string>
+ <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(tidak terhubung)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Tidak dapat beralih. Ketuk untuk mencoba lagi."</string>
<string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Hubungkan perangkat"</string>
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Buka aplikasi untuk mentransmisikan sesi ini."</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Aplikasi Saat Ini"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Aksesibilitas"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Pintasan keyboard"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Pintasan penelusuran"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Tidak ada hasil penelusuran"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikon ciutkan"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikon luaskan"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"atau"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Handel geser"</string>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index 700ae589073c..267291069366 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Viltu taka upp skjáinn?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Taka upp eitt forrit"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Taka upp allan skjáinn"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Þegar þú tekur upp allan skjáinn verður allt sem er sýnilegt á skjánum tekið upp. Passaðu því upp á aðgangsorð, greiðsluupplýsingar, skilaboð, myndir, hljóð og vídeó."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Þegar þú tekur upp forrit verður allt sem er sýnilegt eða spilað í forritinu tekið upp. Passaðu því upp á aðgangsorð, greiðsluupplýsingar, skilaboð, myndir, hljóð og vídeó."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Taka upp skjá"</string>
@@ -581,10 +583,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"Hreinsa allt"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Stjórna"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Ferill"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"Tilkynningastillingar"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"Tilkynningaferill"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"Nýtt"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Hljóðlaust"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Tilkynningar"</string>
@@ -1413,9 +1413,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Núverandi forrit"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Aðgengi"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Flýtilyklar"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Leitarflýtileiðir"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Engar leitarniðurstöður"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Minnka tákn"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Stækka tákn"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"eða"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Dragkló"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index e7734fa4a38d..fd56c5b69f5a 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Registrare lo schermo?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Registra un\'app"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Registra l\'intero schermo"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Quando registri l\'intero schermo, tutto ciò che viene mostrato sullo schermo viene registrato. Presta quindi attenzione a password, dati di pagamento, messaggi, foto, audio e video."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Quando registri un\'app, tutto ciò che viene mostrato o riprodotto al suo interno viene registrato. Presta quindi attenzione a password, dati di pagamento, messaggi, foto, audio e video."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Registra lo schermo"</string>
@@ -136,17 +138,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Al momento stai registrando <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Interrompi registrazione"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Condivisione dello schermo in corso"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"Condivisione di contenuti in corso…"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Vuoi interrompere la condivisione dello schermo?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Interrompere la condivisione?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Al momento stai condividendo l\'intero schermo con <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Al momento stai condividendo l\'intero schermo con un\'app"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Al momento stai condividendo <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Al momento stai condividendo un\'app"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"Al momento stai condividendo contenuti con un\'app"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Interrompi condivisione"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"Trasmissione dello schermo in corso…"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Vuoi interrompere la trasmissione?"</string>
@@ -521,10 +520,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Widget della schermata di blocco"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"Chiunque può visualizzare i widget sulla tua schermata di blocco, anche se il tablet è bloccato."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"deseleziona widget"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Riduci altezza"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Aumenta altezza"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widget della schermata di blocco"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Per aprire un\'app utilizzando un widget, dovrai verificare la tua identità. Inoltre tieni presente che chiunque può vederlo, anche quando il tablet è bloccato. Alcuni widget potrebbero non essere stati progettati per la schermata di blocco e potrebbe non essere sicuro aggiungerli qui."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Ok"</string>
@@ -1413,9 +1410,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"App corrente"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibilità"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Scorciatoie da tastiera"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Scorciatoie per la ricerca"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nessun risultato di ricerca"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Icona Comprimi"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Icona Espandi"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"oppure"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Punto di trascinamento"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 553eaae83da9..384c680b116f 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"להקליט את המסך?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"הקלטה של אפליקציה אחת"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"הקלטה של כל המסך"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"כשמקליטים את כל המסך, כל מה שמופיע במסך מוקלט. מומלץ להיזהר עם סיסמאות, פרטי תשלום, הודעות, תמונות, אודיו וסרטונים."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"כשמקליטים אפליקציה, כל מה שרואים או מפעילים בה מוקלט. מומלץ להיזהר עם סיסמאות, פרטי תשלום, הודעות, תמונות, אודיו וסרטונים."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"הקלטת המסך"</string>
@@ -581,10 +583,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"ניקוי הכול"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"ניהול"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"היסטוריה"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"הגדרות של התראות"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"היסטוריית ההתראות"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"התראות חדשות"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"מצב שקט"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"התראות"</string>
@@ -1413,9 +1413,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"האפליקציה הנוכחית"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"נגישות"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"מקשי קיצור"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"קיצורי דרך לחיפוש"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"אין תוצאות חיפוש"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"סמל הכיווץ"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"סמל ההרחבה"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"או"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"נקודת האחיזה לגרירה"</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index a6fffee06695..a0a3b2bdd403 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"画面を録画しますか?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"1 つのアプリを録画"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"画面全体を録画"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"画面全体を録画すると、画面に表示されるものがすべて録画されます。パスワード、お支払いの詳細、メッセージ、写真、音声、動画などの情報にご注意ください。"</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"アプリを録画すると、そのアプリで表示または再生される内容がすべて録画されます。パスワード、お支払いの詳細、メッセージ、写真、音声、動画などの情報にご注意ください。"</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"画面を録画"</string>
@@ -1411,9 +1413,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"現在のアプリ"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ユーザー補助"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"キーボード ショートカット"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"検索ショートカット"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"検索結果がありません"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"閉じるアイコン"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"開くアイコン"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"または"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ドラッグ ハンドル"</string>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index 9608253c1e1e..471957e044cb 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"გსურთ თქვენი ეკრანის ჩაწერა?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"ერთი აპის ჩაწერა"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"მთლიანი ეკრანის ჩაწერა"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"მთლიანი ეკრანის ჩაწერისას ჩაიწერება ყველაფერი, რაც თქვენს ეკრანზე გამოჩნდება. ამიტომ სიფრთხილე გამოიჩინეთ ისეთ ინფორმაციასთან, როგორიცაა პაროლები, გადახდის დეტალები, შეტყობინებები, ფოტოები, აუდიო და ვიდეო."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"აპის ჩაწერისას ჩაიწერება ყველაფერი, რაც ამ აპში გამოჩნდება ან დაიკვრება. ამიტომ სიფრთხილე გამოიჩინეთ ისეთ ინფორმაციასთან, როგორიცაა პაროლები, გადახდის დეტალები, შეტყობინებები, ფოტოები, აუდიო და ვიდეო."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"ეკრანის ჩაწერა"</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"მიმდინარე აპი"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"მისაწვდომობა"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"კლავიატურის მალსახმობები"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ძიების მალსახმობები"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"ძიების შედეგები არ არის"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"ხატულის ჩაკეცვა"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"ხატულის გაფართოება"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ან"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"სახელური ჩავლებისთვის"</string>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 0456fa8164fc..3dbfd86b3f38 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Қолданба экранын жазасыз ба?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Бір қолданба экранын жазу"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Бүкіл экранды жазу"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Бүкіл экранды жазған кезде, онда көрінетін барлық нәрсе жазылады. Сондықтан құпия сөздерді, төлем туралы мәліметті, хабарларды немесе басқа құпия ақпаратты енгізген кезде сақ болыңыз."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Қолданбаны жазған кезде, онда көрінетін не ойнатылатын барлық нәрсе жазылады. Сондықтан құпия сөздерді, төлем туралы мәліметті, хабарларды немесе басқа құпия ақпаратты енгізген кезде сақ болыңыз."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Экранды жазу"</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Қолданыстағы қолданба"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Арнайы мүмкіндіктер"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Перне тіркесімдері"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Іздеу жылдам пәрмендері"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Іздеу нәтижелері жоқ."</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Жию белгішесі"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Жаю белгішесі"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"немесе"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Сүйрейтін тетік"</string>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 3c33531717bc..b2c8977ab7ce 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"ថត​អេក្រង់​របស់អ្នកឬ?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"ថត​កម្មវិធី​ទោល"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"ថតអេក្រង់ទាំងមូល"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"នៅពេល​អ្នកកំពុង​ថតអេក្រង់​ទាំងមូល​របស់អ្នក អ្វីគ្រប់យ៉ាង​ដែលបង្ហាញ​នៅលើ​អេក្រង់​របស់អ្នក​ត្រូវបាន​ថត។ ដូច្នេះ សូមប្រុងប្រយ័ត្នចំពោះអ្វីៗដូចជា ពាក្យសម្ងាត់ ព័ត៌មានលម្អិតអំពីការទូទាត់ប្រាក់ សារ រូបថត ព្រមទាំងសំឡេង និងវីដេអូ។"</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"នៅពេលអ្នក​កំពុង​ថតកម្មវិធី​ណាមួយ អ្វីគ្រប់យ៉ាង​ដែលបង្ហាញ ឬចាក់​នៅក្នុង​កម្មវិធីនោះ​ត្រូវបាន​ថត។ ដូច្នេះ សូមប្រុងប្រយ័ត្នចំពោះអ្វីៗដូចជា ពាក្យសម្ងាត់ ព័ត៌មានលម្អិតអំពីការទូទាត់ប្រាក់ សារ រូបថត ព្រមទាំងសំឡេង និងវីដេអូ។"</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"ថត​អេក្រង់"</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"កម្មវិធីបច្ចុប្បន្ន"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ភាពងាយស្រួល"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"ផ្លូវកាត់​ក្ដារ​ចុច"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ផ្លូវ​កាត់ការស្វែងរក"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"គ្មាន​លទ្ធផល​ស្វែងរក​ទេ"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"រូបតំណាង \"បង្រួម\""</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"រូបតំណាង \"ពង្រីក\""</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ឬ"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ដង​អូស"</string>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index dca2e4b4a59e..20c367696858 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"ನಿಮ್ಮ ಸ್ಕ್ರೀನ್‌ ಅನ್ನು ರೆಕಾರ್ಡ್ ಮಾಡಬೇಕೇ?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"ಒಂದು ಆ್ಯಪ್ ಅನ್ನು ರೆಕಾರ್ಡ್ ಮಾಡಿ"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"ಸಂಪೂರ್ಣ ಸ್ಕ್ರೀನ್ ಅನ್ನು ರೆಕಾರ್ಡ್ ಮಾಡಿ"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"ನಿಮ್ಮ ಸಂಪೂರ್ಣ ಸ್ಕ್ರೀನ್‌ ಅನ್ನು ನೀವು ರೆಕಾರ್ಡ್ ಮಾಡುತ್ತಿರುವಾಗ, ನಿಮ್ಮ ಸ್ಕ್ರೀನ್‌ ಮೇಲೆ ಗೋಚರಿಸುವ ಎಲ್ಲವನ್ನೂ ರೆಕಾರ್ಡ್ ಮಾಡಲಾಗುತ್ತದೆ. ಆದ್ದರಿಂದ ಪಾಸ್‌ವರ್ಡ್‌ಗಳು, ಪಾವತಿ ವಿವರಗಳು, ಸಂದೇಶಗಳು, ಫೋಟೋಗಳು ಮತ್ತು ಆಡಿಯೋ ಮತ್ತು ವೀಡಿಯೊದಂತಹ ವಿಷಯಗಳ ಬಗ್ಗೆ ಜಾಗರೂಕರಾಗಿರಿ."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"ನೀವು ಆ್ಯಪ್ ಅನ್ನು ರೆಕಾರ್ಡ್ ಮಾಡುವಾಗ, ಆ ಆ್ಯಪ್‌ನಲ್ಲಿ ತೋರಿಸಿರುವ ಅಥವಾ ಪ್ಲೇ ಮಾಡಿದ ಎಲ್ಲವನ್ನೂ ರೆಕಾರ್ಡ್ ಮಾಡಲಾಗುತ್ತದೆ. ಆದ್ದರಿಂದ ಪಾಸ್‌ವರ್ಡ್‌ಗಳು, ಪಾವತಿ ವಿವರಗಳು, ಸಂದೇಶಗಳು, ಫೋಟೋಗಳು ಮತ್ತು ಆಡಿಯೋ ಮತ್ತು ವೀಡಿಯೊದಂತಹ ವಿಷಯಗಳ ಬಗ್ಗೆ ಜಾಗರೂಕರಾಗಿರಿ."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡ್ ಮಾಡಿ"</string>
@@ -581,10 +583,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"ಎಲ್ಲವನ್ನೂ ತೆರವುಗೊಳಿಸಿ"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"ನಿರ್ವಹಿಸಿ"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"ಇತಿಹಾಸ"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"ನೋಟಿಫಿಕೇಶನ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"ನೋಟಿಫಿಕೇಶನ್ ಇತಿಹಾಸ"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"ಹೊಸತು"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"ನಿಶ್ಶಬ್ದ"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"ಅಧಿಸೂಚನೆಗಳು"</string>
@@ -1413,9 +1413,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"ಪ್ರಸ್ತುತ ಆ್ಯಪ್"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ಆ್ಯಕ್ಸೆಸಿಬಿಲಿಟಿ"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"ಕೀಬೋರ್ಡ್ ಶಾರ್ಟ್‌ಕಟ್‌ಗಳು"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ಹುಡುಕಾಟದ ಶಾರ್ಟ್‌ಕಟ್‌ಗಳು"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"ಯಾವುದೇ ಹುಡುಕಾಟ ಫಲಿತಾಂಶಗಳಿಲ್ಲ"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"ಕುಗ್ಗಿಸುವ ಐಕಾನ್"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"ವಿಸ್ತೃತಗೊಳಿಸುವ ಐಕಾನ್"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ಅಥವಾ"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ಡ್ರ್ಯಾಗ್‌ ಹ್ಯಾಂಡಲ್‌"</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 8674dc3ad863..35dc245643ae 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"화면을 녹화하시겠습니까?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"단일 앱 녹화"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"전체 화면 녹화"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"전체 화면을 녹화하면 화면에 표시되는 모든 항목이 녹화됩니다. 따라서 비밀번호, 결제 세부정보, 메시지, 사진, 오디오 및 동영상 등이 노출되지 않도록 주의하세요."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"앱을 녹화하면 앱에 표시되거나 앱에서 재생되는 모든 항목이 녹화됩니다. 따라서 비밀번호, 결제 세부정보, 메시지, 사진, 오디오 및 동영상 등이 노출되지 않도록 주의하세요."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"화면 녹화"</string>
@@ -581,10 +583,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"모두 지우기"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"관리"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"기록"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"알림 설정"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"알림 기록"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"새 알림"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"무음"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"알림"</string>
@@ -1413,15 +1413,21 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"현재 앱"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"접근성"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"단축키"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"검색 바로가기"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"검색 결과 없음"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"접기 아이콘"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"확장 아이콘"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"또는"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"드래그 핸들"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"키보드 설정"</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"키보드를 사용하여 이동"</string>
- <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"단축키 알아보기"</string>
+ <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"단축키에 관해 알아보세요."</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"터치패드를 사용하여 이동"</string>
<string name="launch_touchpad_tutorial_notification_content" msgid="7931085031240753226">"터치패드 동작 알아보기"</string>
<string name="launch_keyboard_touchpad_tutorial_notification_title" msgid="1940023776496198762">"키보드와 터치패드를 사용하여 이동"</string>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index 363342a94793..72e86cc4a703 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Экранды жаздырасызбы?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Бир колдонмону жаздыруу"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Бүтүндөй экранды жаздыруу"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Бүтүндөй экранды жаздырганда, андагы нерселердин баары видеого түшүп калат. Андыктан этият болуп, сырсөздөр, төлөм ыкмалары, билдирүүлөр, сүрөттөр, аудио жана видео материалдар сыяктуу купуя нерселерди көрсөтүп албаңыз."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Колдонмону жаздырганда ал колдонмодо көрсөтүлүп же ойнотулуп жаткан нерселер жаздырылат. Андыктан сырсөздөрдү, төлөмдүн чоо-жайын, билдирүүлөрдү, сүрөттөрдү, аудио жана видеону көрсөтүп албаңыз."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Экранды жаздыруу"</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Учурдагы колдонмо"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Атайын мүмкүнчүлүктөр"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Ыкчам баскычтар"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Ыкчам баскычтарды издөө"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Эч нерсе табылган жок"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Жыйыштыруу сүрөтчөсү"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Жайып көрсөтүү сүрөтчөсү"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"же"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Cүйрөө маркери"</string>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 54c2c6baf6a7..f6fe3cce059a 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"ບັນທຶກໜ້າຈໍຂອງທ່ານບໍ?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"ບັນທຶກແອັບດຽວ"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"ບັນທຶກໝົດໜ້າຈໍ"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"ເມື່ອທ່ານບັນທຶກໝົດໜ້າຈໍຂອງທ່ານ, ລະບົບຈະບັນທຶກທຸກສິ່ງທີ່ສະແດງຢູ່ໜ້າຈໍຂອງທ່ານ. ດັ່ງນັ້ນ, ໃຫ້ລະມັດລະວັງສິ່ງຕ່າງໆ ເຊັ່ນ: ລະຫັດຜ່ານ, ລາຍລະອຽດການຈ່າຍເງິນ, ຂໍ້ຄວາມ, ຮູບພາບ, ພ້ອມທັງສຽງ ແລະ ວິດີໂອ."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"ເມື່ອທ່ານບັນທຶກແອັບ, ລະບົບຈະບັນທຶກທຸກສິ່ງທີ່ສະແດງ ຫຼື ຫຼິ້ນຢູ່ໃນແອັບນັ້ນ. ດັ່ງນັ້ນ, ໃຫ້ລະມັດລະວັງສິ່ງຕ່າງໆ ເຊັ່ນ: ລະຫັດຜ່ານ, ລາຍລະອຽດການຈ່າຍເງິນ, ຂໍ້ຄວາມ, ຮູບພາບ, ພ້ອມທັງສຽງ ແລະ ວິດີໂອ."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"ບັນທຶກໜ້າຈໍ"</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"ແອັບປັດຈຸບັນ"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ການຊ່ວຍເຂົ້າເຖິງ"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"ຄີລັດ"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ທາງລັດການຊອກຫາ"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"ບໍ່ມີຜົນການຊອກຫາ"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"ໄອຄອນຫຍໍ້ລົງ"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"ໄອຄອນຂະຫຍາຍ"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ຫຼື"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ບ່ອນຈັບລາກ"</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index dca26a41edbf..70a0063d7627 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Įrašyti ekraną?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Įrašyti vieną programą"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Įrašyti visą ekraną"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Kai įrašote visą ekraną, įrašomas visas ekrane rodomas turinys. Todėl būkite atsargūs naudodami slaptažodžius, išsamią mokėjimo metodo informaciją, pranešimus, nuotraukas ir garso bei vaizdo įrašus."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Kai įrašote programą, įrašomas visas toje programoje rodomas ar leidžiamas turinys. Todėl būkite atsargūs naudodami slaptažodžius, išsamią mokėjimo metodo informaciją, pranešimus, nuotraukas ir garso bei vaizdo įrašus."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Įrašyti ekraną"</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Esama programa"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Pritaikomumas"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Spartieji klavišai"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Paieškos šaukiniai"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nėra jokių paieškos rezultatų"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Sutraukimo piktograma"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Išskleidimo piktograma"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"arba"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Vilkimo rankenėlė"</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index c5ba0ad80493..360afad1c6fa 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Vai ierakstīt ekrānu?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Ierakstīt vienu lietotni"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Ierakstīt visu ekrānu"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Ierakstot visu ekrānu, viss, kas redzams ekrānā, tiek ierakstīts. Tāpēc piesardzīgi apejieties ar parolēm, maksājumu informāciju, ziņojumiem, fotoattēliem un audio un video saturu."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Ierakstot lietotni, tiek ierakstīts viss attiecīgajā lietotnē rādītais vai atskaņotais. Tāpēc piesardzīgi apejieties ar parolēm, maksājumu informāciju, ziņojumiem, fotoattēliem un audio un video saturu."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Ierakstīt ekrānu"</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Pašreizējā lietotne"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Pieejamība"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Īsinājumtaustiņi"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Meklēšanas saīsnes"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nav meklēšanas rezultātu"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Sakļaušanas ikona"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Izvēršanas ikona"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"vai"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Vilkšanas turis"</string>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 65e958e8d765..ebd62a9568e0 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Да се снима екранот?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Снимање на една апликација"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Снимање на целиот екран"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Додека го снимате целиот екран, сѐ што е прикажано на екранот се снима. Затоа, бидете внимателни со лозинките, деталите за плаќање, пораките, фотографиите и аудиото и видеото."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Додека снимате апликација, може да се сними сѐ што се прикажува или пушта во таа апликација. Затоа, бидете внимателни со лозинките, деталите за плаќање, пораките, фотографиите и аудиото и видеото."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Снимај го екранот"</string>
@@ -581,10 +583,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"Избриши сѐ"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Управувајте"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Историја"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"Поставки за известувања"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"Историја на известувања"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"Нов"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Безгласно"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Известувања"</string>
@@ -1413,9 +1413,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Тековна апликација"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Пристапност"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Кратенки од тастатура"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Кратенки за пребарување"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Нема резултати од пребарување"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Икона за собирање"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Икона за проширување"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"или"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Рачка за влечење"</string>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index e10ecff4b318..6152fce2e02b 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"നിങ്ങളുടെ സ്ക്രീൻ റെക്കോർഡ് ചെയ്യണോ?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"ഒരു ആപ്പ് റെക്കോർഡ് ചെയ്യുക"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"സ്ക്രീൻ പൂർണ്ണമായി റെക്കോർഡ് ചെയ്യുക"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"നിങ്ങളുടെ സ്ക്രീൻ പൂർണ്ണമായി റെക്കോർഡ് ചെയ്യുമ്പോൾ, സ്ക്രീനിൽ ദൃശ്യമാകുന്ന എല്ലാം റെക്കോർഡ് ചെയ്യപ്പെടും. അതിനാൽ പാസ്‍വേഡുകൾ, പേയ്‌മെന്റ് വിശദാംശങ്ങൾ, സന്ദേശങ്ങൾ, ഫോട്ടോകൾ, ഓഡിയോ, വീഡിയോ എന്നിവ പോലുള്ള കാര്യങ്ങൾ നൽകുമ്പോൾ സൂക്ഷിക്കുക."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"നിങ്ങളുടെ ആപ്പ് റെക്കോർഡ് ചെയ്യുമ്പോൾ, ആ ആപ്പിൽ കാണിക്കുന്നതോ പ്ലേ ചെയ്യുന്നതോ ആയ എല്ലാ കാര്യങ്ങളും റെക്കോർഡ് ചെയ്യപ്പെടും. അതിനാൽ പാസ്‍വേഡുകൾ, പേയ്‌മെന്റ് വിശദാംശങ്ങൾ, സന്ദേശങ്ങൾ, ഫോട്ടോകൾ, ഓഡിയോ, വീഡിയോ എന്നിവ പോലുള്ള കാര്യങ്ങൾ നൽകുമ്പോൾ സൂക്ഷിക്കുക."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"സ്ക്രീൻ റെക്കോർഡ് ചെയ്യുക"</string>
@@ -581,10 +583,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"എല്ലാം മായ്‌ക്കുക"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"മാനേജ് ചെയ്യുക"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"ചരിത്രം"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"അറിയിപ്പ് ക്രമീകരണം"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"അറിയിപ്പ് ചരിത്രം"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"പുതിയത്"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"നിശബ്‌ദം"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"അറിയിപ്പുകൾ"</string>
@@ -1413,9 +1413,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"നിലവിലെ ആപ്പ്"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ഉപയോഗസഹായി"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"കീബോഡ് കുറുക്കുവഴികൾ"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"തിരയൽ കുറുക്കുവഴികൾ"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"തിരയൽ ഫലങ്ങളൊന്നുമില്ല"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"ചുരുക്കൽ ഐക്കൺ"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"വികസിപ്പിക്കൽ ഐക്കൺ"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"അല്ലെങ്കിൽ"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"വലിച്ചിടുന്നതിനുള്ള ഹാൻഡിൽ"</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index cb5f054cccf5..aafc8c610c55 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Дэлгэцээ бичих үү?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Нэг аппыг бичих"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Бүтэн дэлгэцийг бичих"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Таныг бүтэн дэлгэцээ бичиж байхад дэлгэц дээр тань харуулж буй аливаа зүйлийг бичдэг. Тиймээс нууц үг, төлбөрийн дэлгэрэнгүй, мессеж, зураг, аудио, видео зэрэг зүйлд болгоомжтой хандаарай."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Таныг апп бичиж байхад тухайн аппад харуулж эсвэл тоглуулж буй аливаа зүйлийг бичдэг. Тиймээс нууц үг, төлбөрийн дэлгэрэнгүй, мессеж, зураг, аудио, видео зэрэг зүйлд болгоомжтой хандаарай."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Дэлгэцийг бичих"</string>
@@ -581,10 +583,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"Бүгдийг арилгах"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Удирдах"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Түүх"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"Мэдэгдлийн тохиргоо"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"Мэдэгдлийн түүх"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"Шинэ"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Чимээгүй"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Мэдэгдлүүд"</string>
@@ -1413,9 +1413,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Одоогийн апп"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Хандалт"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Товчлуурын шууд холбоос"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Товчлолууд хайх"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Ямар ч хайлтын илэрц байхгүй"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Хураах дүрс тэмдэг"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Дэлгэх дүрс тэмдэг"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"эсвэл"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Чирэх бариул"</string>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 8aa0afaaa207..fbbb1670b286 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"तुमची स्क्रीन रेकॉर्ड करायची आहे का?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"एक अ‍ॅप रेकॉर्ड करा"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"पूर्ण स्क्रीन रेकॉर्ड करा"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"तुम्ही तुमची पूर्ण स्क्रीन रेकॉर्ड करता, तेव्हा तुमच्या स्क्रीनवर दाखवलेली कोणतीही गोष्टी रेकॉर्ड केली जाते. त्यामुळे पासवर्ड, पेमेंट तपशील, मेसेज, फोटो आणि ऑडिओ व व्हिडिओ यांसारख्या गोष्टींबाबत सावधगिरी बाळगा."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"तुम्ही अ‍ॅप रेकॉर्ड करता, तेव्हा त्या अ‍ॅपमध्ये दाखवलेली किंवा प्ले केलेली कोणतीही गोष्ट रेकॉर्ड केली जाते. त्यामुळे पासवर्ड, पेमेंट तपशील, मेसेज, फोटो आणि ऑडिओ व व्हिडिओ यांसारख्या गोष्टींबाबत सावधगिरी बाळगा."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"स्क्रीन रेकॉर्ड करा"</string>
@@ -581,10 +583,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"सर्व साफ करा"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"व्यवस्थापित करा"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"इतिहास"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"नोटिफिकेशन सेटिंग्ज"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"नोटिफिकेशन इतिहास"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"नवीन"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"सायलंट"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"सूचना"</string>
@@ -1413,9 +1413,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"सध्याचे अ‍ॅप"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"अ‍ॅक्सेसिबिलिटी"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"कीबोर्ड शॉर्टकट"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"शोधण्यासाठी शॉर्टकट"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"कोणतेही शोध परिणाम नाहीत"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"कोलॅप्स करा आयकन"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"विस्तार करा आयकन"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"किंवा"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ड्रॅग हॅंडल"</string>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index d0071f4d73d7..087c8a664076 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Rakam skrin anda?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Rakam satu apl"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Rakam seluruh skrin"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Apabila anda merakam seluruh skrin anda, apa-apa sahaja yang dipaparkan pada skrin anda akan dirakam. Oleh hal yang demikian, berhati-hati dengan perkara seperti kata laluan, butiran pembayaran, mesej, foto dan audio serta video."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Apabila anda merakam apl, apa-apa sahaja yang dipaparkan atau dimainkan dalam apl tersebut akan dirakam. Oleh hal yang demikian, berhati-hati dengan perkara seperti kata laluan, butiran pembayaran, mesej, foto dan audio serta video."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Rakam skrin"</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Apl Semasa"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Kebolehaksesan"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Pintasan papan kekunci"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Pintasan carian"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Tiada hasil carian"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Kuncupkan ikon"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Kembangkan ikon"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"atau"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Pemegang seret"</string>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index fd4c1478f914..d456bcae7085 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"ဖန်သားပြင်ကို ရိုက်ကူးမလား။"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"အက်ပ်တစ်ခုကို ရိုက်ကူးရန်"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"ဖန်သားပြင်တစ်ခုလုံးကို ရိုက်ကူးရန်"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"သင့်ဖန်သားပြင်တစ်ခုလုံး ရိုက်ကူးနေချိန်တွင် ဖန်သားပြင်တွင် ပြထားသည့် အရာအားလုံးကို ရိုက်ကူးသည်။ စကားဝှက်၊ ငွေပေးချေမှု အချက်အလက်၊ မက်ဆေ့ဂျ်၊ ဓာတ်ပုံ၊ အသံနှင့် ဗီဒီယိုကဲ့သို့ အရာများကို ဂရုစိုက်ပါ။"</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"အက်ပ်ကို ရိုက်ကူးနေချိန်တွင် ယင်းအက်ပ်တွင် ပြထားသော (သို့) ဖွင့်ထားသော အရာအားလုံးကို ရိုက်ကူးသည်။ စကားဝှက်၊ ငွေပေးချေမှု အချက်အလက်၊ မက်ဆေ့ဂျ်၊ ဓာတ်ပုံ၊ အသံနှင့် ဗီဒီယိုကဲ့သို့ အရာများကို ဂရုစိုက်ပါ။"</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"ဖန်သားပြင်ကို ရိုက်ကူးရန်"</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"လက်ရှိအက်ပ်"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"အများသုံးနိုင်မှု"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"လက်ကွက်ဖြတ်လမ်းများ"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ရှာဖွေစာလုံး ဖြတ်လမ်း"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"ရှာဖွေမှုရလဒ် မရှိပါ"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"လျှော့ပြရန် သင်္ကေတ"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"ပိုပြရန် သင်္ကေတ"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"သို့မဟုတ်"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ဖိဆွဲအထိန်း"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 1c30ca7a4f4c..1fbb35b0905e 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Vil du ta opp skjermen?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Ta opp én app"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Ta opp hele skjermen"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Når du tar opp hele skjermen, blir alt som vises på skjermen, tatt opp. Derfor bør du være forsiktig med for eksempel passord, betalingsopplysninger, meldinger, bilder, lyd og video."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Når du tar opp en app, blir alt som vises eller spilles av i appen, tatt opp. Derfor bør du være forsiktig med for eksempel passord, betalingsopplysninger, meldinger, bilder, lyd og video."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Ta opp skjermen"</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Aktiv app"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Tilgjengelighet"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Hurtigtaster"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Snarveier til søk"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Ingen søkeresultater"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Skjul-ikon"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Vis-ikon"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"eller"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Håndtak"</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index f7ac880de720..381118ac4d6c 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"तपाईंको स्क्रिन रेकर्ड गर्ने हो?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"एउटा एप रेकर्ड गर्नुहोस्"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"पूरै स्क्रिन रेकर्ड गर्नुहोस्"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"तपाईंले आफ्नो पूरै स्क्रिन रेकर्ड गरिरहेका बेला तपाईंको स्क्रिनमा देखाइने सबै सामग्री रेकर्ड गरिन्छ। त्यसैले पासवर्ड, भुक्तानीसम्बन्धी विवरण, म्यासेज, फोटो र अडियो तथा भिडियो जस्ता कुरा हेर्दा वा प्ले गर्दा सावधानी अपनाउनुहोला।"</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"तपाईंले यो एप रेकर्ड गरिरहेका बेला यो एपमा देखाइने वा प्ले गरिने सबै सामग्री रेकर्ड गरिन्छ। त्यसैले पासवर्ड, भुक्तानीसम्बन्धी विवरण, म्यासेज, फोटो र अडियो तथा भिडियो जस्ता कुरा हेर्दा वा प्ले गर्दा सावधानी अपनाउनुहोला।"</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"स्क्रिन रेकर्ड गर्नुहोस्"</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"हालको एप"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"सर्वसुलभता"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"किबोर्डका सर्टकटहरू"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"खोजका सर्टकटहरू"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"कुनै पनि खोज परिणाम भेटिएन"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"\"कोल्याप्स गर्नुहोस्\" आइकन"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"\"एक्स्पान्ड गर्नुहोस्\" आइकन"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"वा"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ड्र्याग ह्यान्डल"</string>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 4cea60528e2a..8ff59ee93c98 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Je scherm opnemen?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Eén app opnemen"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Hele scherm opnemen"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Als je je hele scherm opneemt, wordt alles opgenomen wat op je scherm wordt getoond. Wees daarom voorzichtig met bijvoorbeeld wachtwoorden, betalingsgegevens, berichten, foto\'s, en audio en video."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Als je een app opneemt, wordt alles opgenomen wat wordt getoond of afgespeeld in die app. Wees daarom voorzichtig met bijvoorbeeld wachtwoorden, betalingsgegevens, berichten, foto\'s, en audio en video."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Scherm opnemen"</string>
@@ -581,10 +583,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"Alles wissen"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Beheren"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Geschiedenis"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"Instellingen voor meldingen"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"Meldings­geschiedenis"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"Nieuw"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Stil"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Meldingen"</string>
@@ -1413,9 +1413,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Huidige app"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Toegankelijkheid"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Sneltoetsen"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Snelkoppelingen voor zoekopdrachten"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Geen zoekresultaten"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Icoon voor samenvouwen"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Icoon voor uitvouwen"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"of"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Handgreep voor slepen"</string>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index bbbea612f7f8..60864409ee7f 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"ଆପଣଙ୍କ ସ୍କ୍ରିନକୁ ରେକର୍ଡ କରିବେ?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"ଗୋଟିଏ ଆପ ରେକର୍ଡ କରନ୍ତୁ"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"ସମ୍ପୂର୍ଣ୍ଣ ସ୍କ୍ରିନ ରେକର୍ଡ କରନ୍ତୁ"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"ଆପଣ ଆପଣଙ୍କର ସମ୍ପୂର୍ଣ୍ଣ ସ୍କ୍ରିନ ରେକର୍ଡ କରିବା ସମୟରେ, ଆପଣଙ୍କ ସ୍କ୍ରିନରେ ଦେଖାଯାଉଥିବା ସବୁକିଛି ରେକର୍ଡ ହୋଇଥାଏ। ତେଣୁ ପାସୱାର୍ଡ, ପେମେଣ୍ଟ ବିବରଣୀ, ମେସେଜ, ଫଟୋ ଏବଂ ଅଡିଓ ଓ ଭିଡିଓ ପରି ବିଷୟଗୁଡ଼ିକ ପ୍ରତି ସତର୍କ ରୁହନ୍ତୁ।"</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"ଆପଣ ଏକ ଆପ ରେକର୍ଡ କରିବା ସମୟରେ, ସେହି ଆପରେ ଦେଖାଯାଉଥିବା କିମ୍ବା ପ୍ଲେ ହେଉଥିବା ସବୁକିଛି ରେକର୍ଡ ହୋଇଥାଏ। ତେଣୁ ପାସୱାର୍ଡ, ପେମେଣ୍ଟ ବିବରଣୀ, ମେସେଜ, ଫଟୋ ଏବଂ ଅଡିଓ ଓ ଭିଡିଓ ପରି ବିଷୟଗୁଡ଼ିକ ପ୍ରତି ସତର୍କ ରୁହନ୍ତୁ।"</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"ସ୍କ୍ରିନ ରେକର୍ଡ କରନ୍ତୁ"</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"ବର୍ତ୍ତମାନର ଆପ"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ଆକ୍ସେସିବିଲିଟୀ"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"କୀବୋର୍ଡ ସର୍ଟକଟ"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ସର୍ଚ୍ଚ ସର୍ଟକଟ"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"କୌଣସି ସର୍ଚ୍ଚ ଫଳାଫଳ ନାହିଁ"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"ଆଇକନକୁ ସଙ୍କୁଚିତ କରନ୍ତୁ"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"ଆଇକନକୁ ବିସ୍ତାର କରନ୍ତୁ"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"କିମ୍ବା"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ଡ୍ରାଗ ହେଣ୍ଡେଲ"</string>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 0170a71db268..b99986a5e955 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"ਕੀ ਤੁਹਾਡੀ ਸਕ੍ਰੀਨ ਨੂੰ ਰਿਕਾਰਡ ਕਰਨਾ ਹੈ?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"ਇੱਕ ਐਪ ਨੂੰ ਰਿਕਾਰਡ ਕਰੋ"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"ਪੂਰੀ ਸਕ੍ਰੀਨ ਨੂੰ ਰਿਕਾਰਡ ਕਰੋ"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"ਜਦੋਂ ਤੁਸੀਂ ਆਪਣੀ ਪੂਰੀ ਸਕ੍ਰੀਨ ਨੂੰ ਰਿਕਾਰਡ ਕਰ ਰਹੇ ਹੁੰਦੇ ਹੋ, ਤਾਂ ਤੁਹਾਡੀ ਸਕ੍ਰੀਨ \'ਤੇ ਦਿਖਾਈ ਜਾ ਰਹੀ ਹਰ ਚੀਜ਼ ਨੂੰ ਰਿਕਾਰਡ ਕੀਤਾ ਜਾਂਦਾ ਹੈ। ਇਸ ਲਈ ਪਾਸਵਰਡਾਂ, ਭੁਗਤਾਨ ਵੇਰਵਿਆਂ, ਸੁਨੇਹਿਆਂ, ਫ਼ੋਟੋਆਂ ਅਤੇ ਨਾਲ ਹੀ ਆਡੀਓ ਅਤੇ ਵੀਡੀਓ ਵਰਗੀਆਂ ਚੀਜ਼ਾਂ ਵਾਸਤੇ ਸਾਵਧਾਨ ਰਹੋ।"</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"ਜਦੋਂ ਤੁਸੀਂ ਕਿਸੇ ਐਪ ਨੂੰ ਰਿਕਾਰਡ ਕਰ ਰਹੇ ਹੁੰਦੇ ਹੋ, ਤਾਂ ਉਸ ਐਪ ਵਿੱਚ ਦਿਖਾਈ ਜਾਂ ਚਲਾਈ ਜਾ ਰਹੀ ਹਰ ਚੀਜ਼ ਨੂੰ ਰਿਕਾਰਡ ਕੀਤਾ ਜਾਂਦਾ ਹੈ। ਇਸ ਲਈ ਪਾਸਵਰਡਾਂ, ਭੁਗਤਾਨ ਵੇਰਵਿਆਂ, ਸੁਨੇਹਿਆਂ, ਫ਼ੋਟੋਆਂ ਅਤੇ ਆਡੀਓ ਅਤੇ ਵੀਡੀਓ ਵਰਗੀਆਂ ਚੀਜ਼ਾਂ ਵਾਸਤੇ ਸਾਵਧਾਨ ਰਹੋ।"</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"ਸਕ੍ਰੀਨ ਰਿਕਾਰਡ ਕਰੋ"</string>
@@ -581,10 +583,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"ਸਭ ਕਲੀਅਰ ਕਰੋ"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"ਪ੍ਰਬੰਧਨ ਕਰੋ"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"ਇਤਿਹਾਸ"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"ਸੂਚਨਾ ਸੈਟਿੰਗਾਂ"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"ਸੂਚਨਾ ਇਤਿਹਾਸ"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"ਨਵੀਆਂ"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"ਸ਼ਾਂਤ"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"ਸੂਚਨਾਵਾਂ"</string>
@@ -1413,9 +1413,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"ਮੌਜੂਦਾ ਐਪ"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ਪਹੁੰਚਯੋਗਤਾ"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"ਕੀ-ਬੋਰਡ ਸ਼ਾਰਟਕੱਟ"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ਖੋਜ ਸੰਬੰਧੀ ਸ਼ਾਰਟਕੱਟ"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"ਕੋਈ ਖੋਜ ਨਤੀਜਾ ਨਹੀਂ ਮਿਲਿਆ"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"ਪ੍ਰਤੀਕ ਨੂੰ ਸਮੇਟੋ"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"ਪ੍ਰਤੀਕ ਦਾ ਵਿਸਤਾਰ ਕਰੋ"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ਜਾਂ"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ਘਸੀਟਣ ਵਾਲਾ ਹੈਂਡਲ"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 33a743f625d3..88177ac56bb7 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Nagrywać ekran?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Nagrywaj jedną aplikację"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Nagrywaj cały ekran"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Kiedy nagrywasz cały ekran, nagrane zostanie wszystko, co jest na nim widoczne. Dlatego uważaj na hasła, dane do płatności, wiadomości, zdjęcia, nagrania audio czy filmy."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Kiedy nagrywasz aplikację, wszystko, co jest w niej wyświetlane lub odtwarzane, zostaje nagrane. Dlatego zachowaj ostrożność w zakresie haseł, danych do płatności, wiadomości, zdjęć, audio i filmów."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Nagrywaj ekran"</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Bieżąca aplikacja"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Ułatwienia dostępu"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Skróty klawiszowe"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Skróty do wyszukiwania"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Brak wyników wyszukiwania"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona zwijania"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikona rozwijania"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"lub"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Uchwyt do przeciągania"</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index 8041760ae14c..e67c16856e58 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Gravar a tela?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Gravar um app"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Gravar a tela toda"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Quando você grava a tela toda, tudo o que aparece nela é registrado. Portanto, tenha cuidado com senhas, detalhes de pagamento, mensagens, fotos, áudios e vídeos."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Quando você grava um app, todas as informações visíveis ou abertas nele ficam registradas. Portanto, tenha cuidado com senhas, detalhes de pagamento, mensagens, fotos, áudios e vídeos."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Gravar a tela"</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"App atual"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Acessibilidade"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Atalhos do teclado"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Atalhos de pesquisa"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nenhum resultado de pesquisa"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ícone \"Fechar\""</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ícone \"Abrir\""</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ou"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Alça de arrastar"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index f0009986b232..30e16f06f00f 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Gravar o ecrã?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Gravar uma app"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Gravar o ecrã inteiro"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Quando está a gravar o ecrã inteiro, tudo o que é apresentado no ecrã é gravado. Por isso, tenha cuidado com, por exemplo, palavras-passe, detalhes de pagamento, mensagens, fotos, áudio e vídeo."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Quando está a gravar uma app, tudo o que é apresentado ou reproduzido nessa app é gravado. Por isso, tenha cuidado com, por exemplo, palavras-passe, detalhes de pagamento, mensagens, fotos, áudio e vídeo."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Gravar ecrã"</string>
@@ -136,17 +138,14 @@
<string name="screenrecord_stop_dialog_message_specific_app" msgid="5995770227684523244">"Neste momento, está a gravar a app <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Parar gravação"</string>
<string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"A partilhar o ecrã"</string>
- <!-- no translation found for share_to_app_chip_accessibility_label_generic (5517431657924536133) -->
- <skip />
+ <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"A partilhar conteúdo"</string>
<string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Parar a partilha do ecrã?"</string>
- <!-- no translation found for share_to_app_stop_dialog_title_generic (9079161538135843648) -->
- <skip />
+ <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Parar a partilha?"</string>
<string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Neste momento, está a partilhar todo o seu ecrã com a app <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Neste momento, está a partilhar todo o seu ecrã com uma app"</string>
<string name="share_to_app_stop_dialog_message_single_app_specific" msgid="5923772039347985172">"Neste momento, está a partilhar a app <xliff:g id="APP_BEING_SHARED_NAME">%1$s</xliff:g>"</string>
<string name="share_to_app_stop_dialog_message_single_app_generic" msgid="6681016774654578261">"Neste momento, está a partilhar uma app"</string>
- <!-- no translation found for share_to_app_stop_dialog_message_generic (7622174291691249392) -->
- <skip />
+ <string name="share_to_app_stop_dialog_message_generic" msgid="7622174291691249392">"Neste momento, está a partilhar com uma app"</string>
<string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Parar partilha"</string>
<string name="cast_screen_to_other_device_chip_accessibility_label" msgid="4687917476203009885">"A transmitir o ecrã"</string>
<string name="cast_to_other_device_stop_dialog_title" msgid="7836517190930357326">"Parar a transmissão?"</string>
@@ -521,10 +520,8 @@
<string name="communal_widget_picker_title" msgid="1953369090475731663">"Widgets do ecrã de bloqueio"</string>
<string name="communal_widget_picker_description" msgid="490515450110487871">"Todos podem pode ver widgets no ecrã de bloqueio, mesmo com o tablet bloqueado."</string>
<string name="accessibility_action_label_unselect_widget" msgid="1041811747619468698">"desmarcar widget"</string>
- <!-- no translation found for accessibility_action_label_shrink_widget (8259511040536438771) -->
- <skip />
- <!-- no translation found for accessibility_action_label_expand_widget (9190524260912211759) -->
- <skip />
+ <string name="accessibility_action_label_shrink_widget" msgid="8259511040536438771">"Diminuir altura"</string>
+ <string name="accessibility_action_label_expand_widget" msgid="9190524260912211759">"Aumentar altura"</string>
<string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Widgets do ecrã de bloqueio"</string>
<string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"Para abrir uma app através de um widget, vai ter de validar a sua identidade. Além disso, tenha em atenção que qualquer pessoa pode ver os widgets, mesmo quando o tablet estiver bloqueado. Alguns widgets podem não se destinar ao ecrã de bloqueio e pode ser inseguro adicioná-los aqui."</string>
<string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"OK"</string>
@@ -1413,9 +1410,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"App atual"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Acessibilidade"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Atalhos de teclado"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Atalhos de pesquisa"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nenhum resultado da pesquisa"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ícone de reduzir"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ícone de expandir"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ou"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Indicador para arrastar"</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 8041760ae14c..e67c16856e58 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Gravar a tela?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Gravar um app"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Gravar a tela toda"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Quando você grava a tela toda, tudo o que aparece nela é registrado. Portanto, tenha cuidado com senhas, detalhes de pagamento, mensagens, fotos, áudios e vídeos."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Quando você grava um app, todas as informações visíveis ou abertas nele ficam registradas. Portanto, tenha cuidado com senhas, detalhes de pagamento, mensagens, fotos, áudios e vídeos."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Gravar a tela"</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"App atual"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Acessibilidade"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Atalhos do teclado"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Atalhos de pesquisa"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Nenhum resultado de pesquisa"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ícone \"Fechar\""</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ícone \"Abrir\""</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ou"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Alça de arrastar"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 57a2a0c2da63..de7f8dac8dd1 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Înregistrezi ecranul?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Înregistrează o aplicație"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Înregistrează tot ecranul"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Când înregistrezi întregul ecran, se înregistrează tot ce apare pe ecran. Prin urmare, ai grijă cu parolele, detaliile de plată, mesajele, fotografiile și conținutul audio și video."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Când înregistrezi o aplicație, se înregistrează tot ce se afișează sau se redă în aplicație. Prin urmare, ai grijă cu parolele, detaliile de plată, mesajele, fotografiile și conținutul audio și video."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Înregistrează ecranul"</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Aplicația actuală"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accesibilitate"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Comenzi rapide de la tastatură"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Comenzi directe de căutare"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Niciun rezultat al căutării"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Pictograma de restrângere"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Pictograma de extindere"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"sau"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Ghidaj de tragere"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 507f70926620..a007685d4af3 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Начать запись экрана?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Записывать одно приложение"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Записывать весь экран"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Во время записи всего экрана все данные и действия, которые на нем показываются, попадают на видео. Поэтому будьте осторожны с паролями, сведениями о способах оплаты, сообщениями, фотографиями, аудио- и видеозаписями."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Во время записи приложения все данные и действия, которые показываются в его окне, попадают на видео. Поэтому будьте осторожны с паролями, сведениями о способах оплаты, сообщениями, фотографиями, аудио- и видеозаписями."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Запись экрана"</string>
@@ -581,10 +583,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"Очистить все"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Настроить"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"История"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"Настройки уведомлений"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"История уведомлений"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"Новое"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Без звука"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Уведомления"</string>
@@ -1413,9 +1413,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Это приложение"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Специальные возможности"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Быстрые клавиши"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Найти быстрые клавиши"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Ничего не найдено"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Значок \"Свернуть\""</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Значок \"Развернуть\""</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"или"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Маркер перемещения"</string>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index fb9be30202db..ae9c4d0cf711 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"ඔබේ තිරය පටිගත කරන්න ද?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"එක් යෙදුමක් පටිගත කරන්න"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"සම්පූර්ණ තිරය පටිගත කරන්න"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"ඔබ ඔබේ සම්පූර්ණ තිරය පටිගත කරන විට, ඔබේ තිරයේ පෙන්වන ඕනෑම දෙයක් වාර්තා වේ. ඒ නිසා මුරපද, ගෙවීම් විස්තර, පණිවුඩ, ඡායාරූප, සහ ශ්‍රව්‍ය සහ දෘශ්‍ය වැනි දේවල් පිළිබඳ ප්‍රවේශම් වන්න."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"ඔබ යෙදුමක් පටිගත කරන විට, එම යෙදුමේ පෙන්වන හෝ වාදනය කරන ඕනෑම දෙයක් වාර්තා වේ. ඒ නිසා මුරපද, ගෙවීම් විස්තර, පණිවුඩ, ඡායාරූප, සහ ශ්‍රව්‍ය සහ දෘශ්‍ය වැනි දේවල් පිළිබඳ ප්‍රවේශම් වන්න."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"තිරය පටිගත කරන්න"</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"වත්මන් යෙදුම"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ප්‍රවේශ්‍යතාව"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"යතුරු පුවරු කෙටි මං"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"කෙටි මං සොයන්න"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"සෙවීම් ප්‍රතිඵල නැත"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"හැකුළුම් නිරූපකය"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"දිගහැරීම් නිරූපකය"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"හෝ"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"ඇදීම් හැඬලය"</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 42a2613cf329..c2235667f08b 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Chcete nahrávať obrazovku?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Nahrávať jednu aplikáciu"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Nahrávať celú obrazovku"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Pri nahrávaní celej obrazovky sa zaznamená všetko, čo sa na nej zobrazuje. Preto venujte pozornosť položkám, ako sú heslá, platobné údaje, správy, fotky a zvuk či video."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Pri nahrávaní aplikácie sa zaznamená všetko, čo sa v nej zobrazuje alebo prehráva. Preto venujte pozornosť položkám, ako sú heslá, platobné údaje, správy, fotky a zvuk či video."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Nahrávať obrazovku"</string>
@@ -581,10 +583,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"Vymazať všetko"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Spravovať"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"História"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"Nastavenia upozornení"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"História upozornení"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"Nové"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Tichý"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Upozornenia"</string>
@@ -1413,9 +1413,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Aktuálna aplikácia"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Dostupnosť"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Klávesové skratky"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Vyhľadávacie odkazy"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Žiadne výsledky vyhľadávania"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona zbalenia"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikona rozbalenia"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"alebo"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Presúvadlo"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 4ca7b244e9a7..15f1b3ccca7d 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Želite posneti zaslon?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Snemanje ene aplikacije"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Snemanje celotnega zaslona"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Pri snemanju celotnega zaslona se posname vse, kar je prikazano na zaslonu. Zato bodite previdni z gesli, podatki za plačilo, sporočili, fotografijami ter z zvokom in videom."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Pri snemanju aplikacije se posname vse, kar je prikazano ali predvajano v tej aplikaciji. Zato bodite previdni z gesli, podatki za plačilo, sporočili, fotografijami ter z zvokom in videom."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Snemanje zaslona"</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Trenutna aplikacija"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Dostopnost"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Bližnjične tipke"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Bližnjice za iskanje"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Ni rezultatov iskanja"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona za strnitev"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikona za razširitev"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ali"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Ročica za vlečenje"</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index ddea921e900d..7f74487ac2b0 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Të regjistrohet ekrani?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Regjistro një aplikacion"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Regjistro të gjithë ekranin"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Kur regjistron të gjithë ekranin, regjistrohet çdo gjë e shfaqur në ekranin tënd. Prandaj, ki kujdes me gjërat si fjalëkalimet, detajet e pagesave, mesazhet, fotografitë, si dhe audion dhe videon."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Kur regjistron një aplikacion, regjistrohet çdo gjë që shfaqet ose luhet në atë aplikacion. Prandaj, ki kujdes me gjërat si fjalëkalimet, detajet e pagesave, mesazhet, fotografitë, si dhe audion dhe videon."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Regjistro ekranin"</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Aplikacioni aktual"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Qasshmëria"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Shkurtoret e tastierës"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Kërko për shkurtoret"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Asnjë rezultat kërkimi"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona e palosjes"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikona e zgjerimit"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"ose"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Doreza e zvarritjes"</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 5936cd780e95..a1952d428f10 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Желите да снимите екран?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Сними једну апликацију"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Сними цео екран"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Када снимате цео екран, снима се све што је на њему. Зато пазите на лозинке, информације о плаћању, поруке, слике, аудио и видео садржај."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Када снимате апликацију, снима се сав садржај који се приказује или пушта у њој. Зато пазите на лозинке, информације о плаћању, поруке, слике, аудио и видео садржај."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Сними екран"</string>
@@ -581,10 +583,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"Обриши све"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Управљај"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Историја"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"Подешавања обавештења"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"Историја обавештења"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"Ново"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Нечујно"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Обавештења"</string>
@@ -1413,9 +1413,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Актуелна апликација"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Приступачност"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Тастерске пречице"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Пречице претраге"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Нема резултата претраге"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Икона за скупљање"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Икона за проширивање"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"или"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Маркер за превлачење"</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 45e150a4574b..b898eafc7f03 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Vill du spela in det som visas på skärmen?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Spela in en app"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Spela in hela skärmen"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"När du spelar in hela skärmen spelas allt som visas på skärmen in. Var försiktig med sådant som lösenord, betalningsuppgifter, meddelanden, foton, ljud och video."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"När du spelar in en app spelas allt som visas eller spelas upp i appen in. Var försiktig med sådant som lösenord, betalningsuppgifter, meddelanden, foton, ljud och video."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Spela in skärmen"</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Aktuell app"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Tillgänglighet"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Kortkommandon"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Sökgenvägar"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Inga sökresultat"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikonen Komprimera"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Ikonen Utöka"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"eller"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Handtag"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 86ea7e492007..8731337c88f0 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Ungependa kurekodi skrini yako?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Rekodi programu moja"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Rekodi skrini nzima"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Unaporekodi skrini yako nzima, chochote kinachoonyeshwa kwenye skrini yako kitarekodiwa. Kwa hivyo kuwa mwangalifu na vitu kama vile manenosiri, maelezo ya malipo, ujumbe, picha, sauti na video."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Unaporekodi programu, chochote kinachoonyeshwa au kuchezwa kwenye programu hiyo kitarekodiwa. Kwa hivyo kuwa mwangalifu na vitu kama vile manenosiri, maelezo ya malipo, ujumbe, picha, sauti na video."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Rekodi skrini"</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Programu Inayotumika Sasa"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Ufikivu"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Mikato ya kibodi"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Njia mkato za kutafutia"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Hamna matokeo ya utafutaji"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Kunja aikoni"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Panua aikoni"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"au"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Aikoni ya buruta"</string>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index 93b18646a831..b75a2186ed64 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"உங்கள் திரையை ரெக்கார்டு செய்யவா?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"ஓர் ஆப்ஸை ரெக்கார்டு செய்தல்"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"முழுத் திரையை ரெக்கார்டு செய்தல்"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"முழுத் திரையை நீங்கள் ரெக்கார்டு செய்யும்போது அதில் காட்டப்படும் அனைத்தும் ரெக்கார்டு செய்யப்படும். எனவே கடவுச்சொற்கள், பேமெண்ட் விவரங்கள், மெசேஜ்கள், படங்கள், ஆடியோ, வீடியோ போன்றவை குறித்துக் கவனத்துடன் இருங்கள்."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"ஓர் ஆப்ஸை ரெக்கார்டு செய்யும்போது அதில் காட்டப்படும் அல்லது பிளே செய்யப்படும் அனைத்தும் ரெக்கார்டு செய்யப்படும். எனவே கடவுச்சொற்கள், பேமெண்ட் விவரங்கள், மெசேஜ்கள், படங்கள், ஆடியோ, வீடியோ போன்றவை குறித்துக் கவனத்துடன் இருங்கள்."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"திரையை ரெக்கார்டு செய்"</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"தற்போதைய ஆப்ஸ்"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"மாற்றுத்திறன் வசதி"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"கீபோர்டு ஷார்ட்கட்கள்"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"தேடல் ஷார்ட்கட்கள்"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"தேடல் முடிவுகள் இல்லை"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"சுருக்குவதற்கான ஐகான்"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"விரிவாக்குவதற்கான ஐகான்"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"அல்லது"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"இழுப்பதற்கான ஹேண்டில்"</string>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 4a976513a8da..d66c6560fd7c 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"మీ స్క్రీన్‌ను రికార్డ్ చేయాలా?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"ఒక యాప్‌ను రికార్డ్ చేయండి"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"ఫుల్ స్క్రీన్‌ను రికార్డ్ చేయండి"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"మీ ఫుల్ స్క్రీన్‌ను మీరు రికార్డ్ చేసేటప్పుడు, మీ స్క్రీన్‌పై కనిపించేవన్నీ రికార్డ్ అవుతాయి. కాబట్టి పాస్‌వర్డ్‌లు, పేమెంట్ వివరాలు, మెసేజ్‌లు, ఫోటోలు, ఆడియో, ఇంకా వీడియో వంటి విషయాల్లో జాగ్రత్త వహించండి."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"మీరు యాప్‌ను రికార్డ్ చేసేటప్పుడు, సంబంధిత యాప్‌లో కనిపించేవన్నీ లేదా ప్లే అయ్యేవన్నీ రికార్డ్ అవుతాయి. కాబట్టి పాస్‌వర్డ్‌లు, పేమెంట్ వివరాలు, మెసేజ్‌లు, ఫోటోలు, ఆడియో, ఇంకా వీడియో వంటి విషయాల్లో జాగ్రత్త వహించండి."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"స్క్రీన్‌ను రికార్డ్ చేయండి"</string>
@@ -581,10 +583,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"అన్నీ క్లియర్ చేయండి"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"మేనేజ్ చేయండి"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"హిస్టరీ"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"నోటిఫికేషన్ సెట్టింగ్‌లు"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"నోటిఫికేషన్ హిస్టరీ"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"కొత్తవి"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"నిశ్శబ్దం"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"నోటిఫికేషన్‌లు"</string>
@@ -1413,9 +1413,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"ప్రస్తుత యాప్"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"యాక్సెసిబిలిటీ"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"కీబోర్డ్ షార్ట్‌కట్‌లు"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"సెర్చ్ షార్ట్‌కట్‌లు"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"సెర్చ్ ఫలితాలు ఏవీ లేవు"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"కుదించండి చిహ్నం"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"విస్తరించండి చిహ్నం"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"లేదా"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"లాగే హ్యాండిల్"</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index ac027c753d12..b7d1a32fdeba 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"บันทึกหน้าจอไหม"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"บันทึกแอปเดียว"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"บันทึกทั้งหน้าจอ"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"ขณะบันทึกทั้งหน้าจอ ระบบจะบันทึกทุกสิ่งที่แสดงอยู่บนหน้าจอ ดังนั้นโปรดระวังสิ่งต่างๆ อย่างเช่นรหัสผ่าน รายละเอียดการชำระเงิน ข้อความ รูปภาพ รวมถึงเสียงและวิดีโอ"</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"ขณะบันทึกแอป ระบบจะบันทึกทุกสิ่งที่แสดงหรือเล่นอยู่ในแอปดังกล่าว ดังนั้นโปรดระวังสิ่งต่างๆ อย่างเช่นรหัสผ่าน รายละเอียดการชำระเงิน ข้อความ รูปภาพ รวมถึงเสียงและวิดีโอ"</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"บันทึกหน้าจอ"</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"แอปปัจจุบัน"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"การช่วยเหลือพิเศษ"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"แป้นพิมพ์ลัด"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"ค้นหาแป้นพิมพ์ลัด"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"ไม่พบผลการค้นหา"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"ไอคอนยุบ"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"ไอคอนขยาย"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"หรือ"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"แฮนเดิลการลาก"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 09a0e0400310..a30a2f2f45f6 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"I-record ang iyong screen?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Mag-record ng isang app"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"I-record ang buong screen"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Kapag nire-record mo ang iyong buong screen, nire-record ang anumang ipinapakita sa screen mo. Kaya mag-ingat sa mga bagay-bagay tulad ng mga password, detalye ng pagbabayad, mensahe, larawan, at audio at video."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Kapag nagre-record ka ng app, nire-record ang anumang ipinapakita o pine-play sa app na iyon. Kaya mag-ingat sa mga bagay-bagay tulad ng mga password, detalye ng pagbabayad, mensahe, larawan, at audio at video."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"I-record ang screen"</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Kasalukuyang App"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibility"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Mga keyboard shortcut"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Mga shortcut ng paghahanap"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Walang resulta ng paghahanap"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"I-collapse ang icon"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"I-expand ang icon"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"o"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Handle sa pag-drag"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index ae9cd186520e..c79dfcf8f162 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Ekranınız kaydedilsin mi?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Bir uygulamayı kaydet"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Tüm ekranı kaydedin"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Tüm ekranınızı kaydettiğinizde ekranınızda gösterilen her şey kaydedilir. Bu nedenle şifre, ödeme ayrıntıları, mesaj, fotoğraf, ses ve video gibi öğeler konusunda dikkatli olun."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Bir uygulamayı kaydettiğinizde o uygulamada gösterilen veya oynatılan her şey kaydedilir. Bu nedenle şifre, ödeme ayrıntıları, mesaj, fotoğraf, ses ve video gibi öğeler konusunda dikkatli olun."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Ekranı kaydet"</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Mevcut Uygulama"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Erişilebilirlik"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Klavye kısayolları"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Arama kısayolları"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Arama sonucu yok"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Daralt simgesi"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Genişlet simgesi"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"veya"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Sürükleme tutamacı"</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 820d072f152e..2808922e166c 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Записати відео з екрана?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Записувати один додаток"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Записувати весь екран"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Коли ви записуєте вміст усього екрана, на відео потрапляє все, що на ньому відображається. Тому будьте уважні з паролями, повідомленнями, фотографіями, аудіо, відео, платіжною інформацією тощо."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Коли ви записуєте додаток, на відео потрапляє все, що відображається або відтворюється в ньому. Тому будьте уважні з паролями, повідомленнями, фотографіями, аудіо, відео, платіжною інформацією тощо."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Записувати вміст екрана"</string>
@@ -1413,15 +1415,21 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Поточний додаток"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Доступність"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Комбінації клавіш"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Комбінації клавіш для пошуку"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Нічого не знайдено"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Значок згортання"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Значок розгортання"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"або"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Маркер переміщення"</string>
<string name="shortcut_helper_keyboard_settings_buttons_label" msgid="6720967595915985259">"Налаштування клавіатури"</string>
<string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Навігація за допомогою клавіатури"</string>
- <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Комбінації клавіш: докладніше"</string>
+ <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Дізнайтеся більше про комбінації клавіш"</string>
<string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Навігація за допомогою сенсорної панелі"</string>
<string name="launch_touchpad_tutorial_notification_content" msgid="7931085031240753226">"Жести для сенсорної панелі: докладніше"</string>
<string name="launch_keyboard_touchpad_tutorial_notification_title" msgid="1940023776496198762">"Навігація за допомогою клавіатури й сенсорної панелі"</string>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index b98abbda3f7b..b72464cad145 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"آپ کی اسکرین ریکارڈ کریں؟"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"ایک ایپ ریکارڈ کریں"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"پوری اسکرین کو ریکارڈ کریں"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"جب آپ اپنی پوری اسکرین کو ریکارڈ کر رہے ہوتے ہیں تو آپ کی اسکرین پر دکھائی گئی ہر چیز ریکارڈ کی جاتی ہے۔ لہذا، پاس ورڈز، ادائیگی کی تفصیلات، پیغامات، تصاویر، ساتھ ہی آڈیو اور ویڈیو جیسی چیزوں کے سلسلے میں محتاط رہیں۔"</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"جب آپ کسی ایپ کو ریکارڈ کر رہے ہوتے ہیں تو اس ایپ میں دکھائی گئی یا چلائی گئی ہر چیز ریکارڈ کی جاتی ہے۔ لہذا، پاس ورڈز، ادائیگی کی تفصیلات، پیغامات، تصاویر، ساتھ ہی آڈیو اور ویڈیو جیسی چیزوں کے سلسلے میں محتاط رہیں۔"</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"اسکرین ریکارڈ کریں"</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"موجودہ ایپ"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ایکسیسبیلٹی"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"کی بورڈ شارٹ کٹس"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"تلاش کے شارٹ کٹس"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"تلاش کا کوئی نتیجہ نہیں ہے"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"آئیکن سکیڑیں"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"آئیکن پھیلائیں"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"یا"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"گھسیٹنے کا ہینڈل"</string>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 3309772d5fc8..7f6275c5a1d2 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Ekran yozib olinsinmi?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Bitta ilovani yozib olish"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Butun ekranni yozib olish"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Butun ekranni yozib olishda ekranda koʻrsatilgan barcha axborotlar yozib olinadi. Shu sababli parollar, toʻlov tafsilotlari, xabarlar, suratlar, audio va video chiqmasligi uchun ehtiyot boʻling."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Ilovani yozib olishda ilova koʻrsatilgan yoki ijro etilgan barcha axborotlar yozib olinadi. Shu sababli parollar, toʻlov tafsilotlari, xabarlar, suratlar, audio va video chiqmasligi uchun ehtiyot boʻling."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Ekranni yozib olish"</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Joriy ilova"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Qulayliklar"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Tezkor tugmalar"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Tezkor tugmalar qidiruvi"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Hech narsa topilmadi"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Yigʻish belgisi"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Yoyish belgisi"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"yoki"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Surish dastagi"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index f404a2bf455b..388ebb804828 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Ghi màn hình?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Ghi một ứng dụng"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Ghi toàn màn hình"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Khi bạn ghi toàn màn hình, mọi nội dung trên màn hình của bạn đều được ghi. Vì vậy, hãy thận trọng để không làm lộ thông tin như mật khẩu, thông tin thanh toán, tin nhắn, ảnh, âm thanh và video."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Khi bạn ghi một ứng dụng, mọi nội dung xuất hiện hoặc phát trong ứng dụng đó sẽ đều được ghi. Vì vậy, hãy thận trọng để không làm lộ thông tin như mật khẩu, thông tin thanh toán, tin nhắn, ảnh, âm thanh và video."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Ghi màn hình"</string>
@@ -581,10 +583,8 @@
<string name="clear_all_notifications_text" msgid="348312370303046130">"Xóa tất cả"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Quản lý"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"Lịch sử"</string>
- <!-- no translation found for notification_settings_button_description (2441994740884163889) -->
- <skip />
- <!-- no translation found for notification_history_button_description (1578657591405033383) -->
- <skip />
+ <string name="notification_settings_button_description" msgid="2441994740884163889">"Cài đặt thông báo"</string>
+ <string name="notification_history_button_description" msgid="1578657591405033383">"Nhật ký thông báo"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"Mới"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"Im lặng"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"Thông báo"</string>
@@ -1413,9 +1413,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Ứng dụng hiện tại"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Hỗ trợ tiếp cận"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Phím tắt"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Lối tắt tìm kiếm"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Không có kết quả tìm kiếm nào"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Biểu tượng Thu gọn"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Biểu tượng Mở rộng"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"hoặc"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Nút kéo"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 24c9f40f05a7..b463900a331d 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"要录制屏幕吗?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"录制单个应用"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"录制整个屏幕"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"录制整个屏幕时,屏幕上显示的所有内容均会被录制。因此,请务必小心操作,谨防泄露密码、付款信息、消息、照片、音频、视频等。"</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"录制单个应用时,该应用中显示或播放的所有内容均会被录制。因此,请务必小心操作,谨防泄露密码、付款信息、消息、照片、音频、视频等。"</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"录制屏幕"</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"当前应用"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"无障碍功能"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"键盘快捷键"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"搜索快捷键"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"无搜索结果"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"收起图标"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"展开图标"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"或"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"拖动手柄"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index e7ebe5ccf697..91185912af9d 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"要錄影螢幕畫面嗎?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"錄影一個應用程式"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"錄影整個螢幕畫面"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"當你錄影整個螢幕畫面時,系統會錄影螢幕畫面上顯示的任何內容。因此,請謹慎處理密碼、付款資料、訊息、相片、音訊和影片等。"</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"當你錄影應用程式時,系統會錄影該應用程式中顯示或播放的任何內容。因此,請謹慎處理密碼、付款資料、訊息、相片、音訊和影片等。"</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"錄影螢幕畫面"</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"目前的應用程式"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"無障礙功能"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"鍵盤快速鍵"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"搜尋快速鍵"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"沒有相符的搜尋結果"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"收合圖示"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"展開圖示"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"或"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"拖曳控點"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 0f298dc314c6..2189cbfdf278 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"要錄製畫面嗎?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"錄製單一應用程式"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"錄製整個畫面"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"錄製整個畫面時,系統會錄下畫面上的所有內容。因此,請謹慎處理密碼、付款資料、訊息、相片和影音內容等資訊。"</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"當你錄製應用程式畫面時,系統會錄下該應用程式顯示或播放的所有內容。因此,請謹慎處理密碼、付款資料、訊息、相片和影音內容等資訊。"</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"錄製畫面"</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"目前的應用程式"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"無障礙"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"鍵盤快速鍵"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"搜尋快速鍵"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"找不到相符的搜尋結果"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"收合圖示"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"展開圖示"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"或"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"拖曳控點"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 444ca041f31b..05b5040faf85 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -112,6 +112,8 @@
<string name="screenrecord_permission_dialog_title" msgid="7415261783188749730">"Rekhoda isikrini sakho?"</string>
<string name="screenrecord_permission_dialog_option_text_single_app" msgid="1996450687814647583">"Rekhoda i-app eyodwa"</string>
<string name="screenrecord_permission_dialog_option_text_entire_screen" msgid="2794896384693120020">"Rekhoda sonke isikrini"</string>
+ <!-- no translation found for screenrecord_permission_dialog_option_text_entire_screen_for_display (3754611651558838691) -->
+ <skip />
<string name="screenrecord_permission_dialog_warning_entire_screen" msgid="1321758636709366068">"Uma urekhoda sonke isikrini sakho, noma yini evela esikrinini iyarekhodwa. Ngakho-ke qaphela ngezinto ezifana namaphasiwedi, imininingwane yenkokhelo, imilayezo, izithombe, nomsindo nevidiyo."</string>
<string name="screenrecord_permission_dialog_warning_single_app" msgid="3738199712880063924">"Uma urekhoda i-app, noma yini evezwa noma edlala kuleyo app iyarekhodwa. Ngakho-ke qaphela ngezinto ezifana namaphasiwedi, imininingwane yenkokhelo, imilayezo, izithombe, nomsindo nevidiyo."</string>
<string name="screenrecord_permission_dialog_continue_entire_screen" msgid="5557974446773486600">"Rekhoda isikrini"</string>
@@ -1413,9 +1415,15 @@
<string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"I-App yamanje"</string>
<string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Ukufinyeleleka"</string>
<string name="shortcut_helper_title" msgid="8567500639300970049">"Izinqamuleli zekhibhodi"</string>
+ <!-- no translation found for shortcut_helper_customize_mode_title (1467657117101096033) -->
+ <skip />
<string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Sesha izinqamuleli"</string>
<string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Ayikho imiphumela yosesho"</string>
<string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Goqa isithonjana"</string>
+ <!-- no translation found for shortcut_helper_customize_button_text (3124983502748069338) -->
+ <skip />
+ <!-- no translation found for shortcut_helper_done_button_text (7249905942125386191) -->
+ <skip />
<string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Nweba isithonjana"</string>
<string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"noma"</string>
<string name="shortcut_helper_content_description_drag_handle" msgid="5092426406009848110">"Hudula isibambi"</string>
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/MultitaskingShortcutsSource.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/MultitaskingShortcutsSource.kt
index eddac4d4ad73..05ff0cc30a44 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/MultitaskingShortcutsSource.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/MultitaskingShortcutsSource.kt
@@ -70,7 +70,7 @@ class MultitaskingShortcutsSource @Inject constructor(@Main private val resource
},
// Change split screen focus to LHS:
// - Meta + Alt + Left arrow
- shortcutInfo(resources.getString(R.string.system_multitasking_splitscreen_focus_rhs)) {
+ shortcutInfo(resources.getString(R.string.system_multitasking_splitscreen_focus_lhs)) {
command(META_META_ON or META_ALT_ON, KEYCODE_DPAD_LEFT)
},
)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt
index f3eeed2682a0..8c6037107c5a 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt
@@ -19,7 +19,6 @@ package com.android.systemui.keyguard.domain.interactor
import android.animation.ValueAnimator
import android.util.MathUtils
import com.android.app.animation.Interpolators
-import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.systemui.Flags.communalSceneKtfRefactor
import com.android.systemui.communal.domain.interactor.CommunalSettingsInteractor
import com.android.systemui.dagger.SysUISingleton
@@ -40,17 +39,19 @@ import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shade.data.repository.ShadeRepository
import com.android.systemui.util.kotlin.sample
-import java.util.UUID
-import javax.inject.Inject
-import kotlin.time.Duration.Companion.milliseconds
-import kotlin.time.Duration.Companion.seconds
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onStart
+import kotlin.time.Duration.Companion.milliseconds
+import kotlin.time.Duration.Companion.seconds
+import java.util.UUID
+import javax.inject.Inject
+import com.android.app.tracing.coroutines.launchTraced as launch
@SysUISingleton
class FromLockscreenTransitionInteractor
@@ -258,6 +259,19 @@ constructor(
}
}
}
+
+ // Ensure that transitionId is nulled out if external signals cause a PRIMARY_BOUNCER
+ // transition to be canceled.
+ scope.launch {
+ transitionInteractor.transitions
+ .filter {
+ it.transitionState == TransitionState.CANCELED &&
+ it.to == KeyguardState.PRIMARY_BOUNCER
+ }
+ .collect {
+ transitionId = null
+ }
+ }
}
fun dismissKeyguard() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSImpl.java
index 0b37b5b7be3d..1ca3927ace33 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSImpl.java
@@ -1146,4 +1146,4 @@ public class QSImpl implements QS, CommandQueue.Callbacks, StatusBarStateControl
updateState();
}
}
-}
+} \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt b/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt
index 9c8e84f280a0..bacff99fe048 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt
@@ -38,12 +38,14 @@ import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.togetherWith
import androidx.compose.foundation.ScrollState
+import androidx.compose.foundation.layout.Arrangement.spacedBy
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.windowInsetsPadding
@@ -73,13 +75,14 @@ import androidx.compose.ui.semantics.CustomAccessibilityAction
import androidx.compose.ui.semantics.customActions
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.IntOffset
+import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.round
import androidx.compose.ui.util.fastRoundToInt
+import androidx.compose.ui.viewinterop.AndroidView
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
-import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.compose.animation.scene.ContentKey
import com.android.compose.animation.scene.ElementKey
import com.android.compose.animation.scene.ElementMatcher
@@ -98,10 +101,7 @@ import com.android.systemui.compose.modifiers.sysuiResTag
import com.android.systemui.dump.DumpManager
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.lifecycle.setSnapshotBinding
-import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager
import com.android.systemui.media.controls.ui.view.MediaHost
-import com.android.systemui.media.dagger.MediaModule.QS_PANEL
-import com.android.systemui.media.dagger.MediaModule.QUICK_QS_PANEL
import com.android.systemui.plugins.qs.QS
import com.android.systemui.plugins.qs.QSContainerController
import com.android.systemui.qs.composefragment.SceneKeys.QuickQuickSettings
@@ -127,7 +127,6 @@ import com.android.systemui.util.println
import java.io.PrintWriter
import java.util.function.Consumer
import javax.inject.Inject
-import javax.inject.Named
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.awaitCancellation
import kotlinx.coroutines.coroutineScope
@@ -135,6 +134,7 @@ import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.launch
@SuppressLint("ValidFragment")
class QSFragmentCompose
@@ -142,11 +142,11 @@ class QSFragmentCompose
constructor(
private val qsFragmentComposeViewModelFactory: QSFragmentComposeViewModel.Factory,
private val dumpManager: DumpManager,
- @Named(QUICK_QS_PANEL) private val qqsMediaHost: MediaHost,
- @Named(QS_PANEL) private val qsMediaHost: MediaHost,
) : LifecycleFragment(), QS, Dumpable {
private val scrollListener = MutableStateFlow<QS.ScrollListener?>(null)
+ private val collapsedMediaVisibilityChangedListener =
+ MutableStateFlow<(Consumer<Boolean>)?>(null)
private val heightListener = MutableStateFlow<QS.HeightListener?>(null)
private val qsContainerController = MutableStateFlow<QSContainerController?>(null)
@@ -183,8 +183,6 @@ constructor(
QSComposeFragment.isUnexpectedlyInLegacyMode()
viewModel = qsFragmentComposeViewModelFactory.create(lifecycleScope)
- qqsMediaHost.init(MediaHierarchyManager.LOCATION_QQS)
- qsMediaHost.init(MediaHierarchyManager.LOCATION_QS)
setListenerCollections()
lifecycleScope.launch { viewModel.activate() }
}
@@ -491,7 +489,7 @@ constructor(
}
override fun setCollapsedMediaVisibilityChangedListener(listener: Consumer<Boolean>?) {
- // TODO (b/353253280)
+ collapsedMediaVisibilityChangedListener.value = listener
}
override fun setScrollListener(scrollListener: QS.ScrollListener?) {
@@ -534,6 +532,7 @@ constructor(
lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
this@QSFragmentCompose.view?.setSnapshotBinding {
scrollListener.value?.onQsPanelScrollChanged(scrollState.value)
+ collapsedMediaVisibilityChangedListener.value?.accept(viewModel.qqsMediaVisible)
}
launch {
setListenerJob(
@@ -569,7 +568,7 @@ constructor(
.squishiness
.collectAsStateWithLifecycle()
- Column(modifier = Modifier.sysuiResTag("quick_qs_panel")) {
+ Column(modifier = Modifier.sysuiResTag(ResIdTags.quickQsPanel)) {
Box(
modifier =
Modifier.fillMaxWidth()
@@ -581,6 +580,9 @@ constructor(
leftFromRoot + coordinates.size.width,
topFromRoot + coordinates.size.height,
)
+ if (squishiness == 1f) {
+ viewModel.qqsHeight = coordinates.size.height
+ }
}
// Use an approach layout to determien the height without squishiness, as
// that's the value that NPVC and QuickSettingsController care about
@@ -595,8 +597,7 @@ constructor(
.padding(top = { qqsPadding }, bottom = { bottomPadding })
) {
if (viewModel.isQsEnabled) {
- QuickQuickSettings(
- viewModel = viewModel.containerViewModel.quickQuickSettingsViewModel,
+ Column(
modifier =
Modifier.collapseExpandSemanticAction(
stringResource(
@@ -608,7 +609,16 @@ constructor(
QuickSettingsShade.Dimensions.Padding.roundToPx()
}
),
- )
+ verticalArrangement =
+ spacedBy(dimensionResource(R.dimen.qs_tile_margin_vertical)),
+ ) {
+ QuickQuickSettings(
+ viewModel = viewModel.containerViewModel.quickQuickSettingsViewModel
+ )
+ if (viewModel.qqsMediaVisible) {
+ MediaObject(mediaHost = viewModel.qqsMediaHost)
+ }
+ }
}
}
Spacer(modifier = Modifier.weight(1f))
@@ -645,14 +655,27 @@ constructor(
}
.onSizeChanged { viewModel.qsScrollHeight = it.height }
.verticalScroll(scrollState)
+ .sysuiResTag(ResIdTags.qsScroll)
) {
Spacer(
modifier = Modifier.height { qqsPadding + qsExtraPadding.roundToPx() }
)
QuickSettingsLayout(
viewModel = viewModel.containerViewModel,
- modifier = Modifier.sysuiResTag("quick_settings_panel"),
+ modifier = Modifier.sysuiResTag(ResIdTags.quickSettingsPanel),
)
+ Spacer(modifier = Modifier.height(8.dp))
+ if (viewModel.qsMediaVisible) {
+ MediaObject(
+ mediaHost = viewModel.qsMediaHost,
+ modifier =
+ Modifier.padding(
+ horizontal = {
+ QuickSettingsShade.Dimensions.Padding.roundToPx()
+ }
+ ),
+ )
+ }
}
}
QuickSettingsTheme {
@@ -660,7 +683,7 @@ constructor(
viewModel = viewModel.footerActionsViewModel,
qsVisibilityLifecycleOwner = this@QSFragmentCompose,
modifier =
- Modifier.sysuiResTag("qs_footer_actions")
+ Modifier.sysuiResTag(ResIdTags.qsFooterActions)
.element(ElementKeys.FooterActions),
)
}
@@ -914,3 +937,29 @@ private fun Modifier.gesturesDisabled(disabled: Boolean) =
} else {
this
}
+
+@Composable
+private fun MediaObject(mediaHost: MediaHost, modifier: Modifier = Modifier) {
+ Box {
+ AndroidView(
+ modifier = modifier,
+ factory = {
+ mediaHost.hostView.apply {
+ layoutParams =
+ FrameLayout.LayoutParams(
+ FrameLayout.LayoutParams.MATCH_PARENT,
+ FrameLayout.LayoutParams.WRAP_CONTENT,
+ )
+ }
+ },
+ onReset = {},
+ )
+ }
+}
+
+private object ResIdTags {
+ const val quickSettingsPanel = "quick_settings_panel"
+ const val quickQsPanel = "quick_qs_panel"
+ const val qsScroll = "expanded_qs_scroll_view"
+ const val qsFooterActions = "qs_footer_actions"
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/composefragment/dagger/QSFragmentComposeModule.kt b/packages/SystemUI/src/com/android/systemui/qs/composefragment/dagger/QSFragmentComposeModule.kt
new file mode 100644
index 000000000000..512732090036
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/composefragment/dagger/QSFragmentComposeModule.kt
@@ -0,0 +1,40 @@
+/*
+ * 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.qs.composefragment.dagger
+
+import android.content.Context
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.util.Utils
+import dagger.Module
+import dagger.Provides
+import javax.inject.Named
+
+@Module
+interface QSFragmentComposeModule {
+
+ companion object {
+ const val QS_USING_MEDIA_PLAYER = "compose_fragment_using_media_player"
+
+ @Provides
+ @SysUISingleton
+ @Named(QS_USING_MEDIA_PLAYER)
+ fun providesUsingMedia(@Application context: Context): Boolean {
+ return Utils.useQsMediaPlayer(context)
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModel.kt
index d30c6bec87dd..0ca621d7d2e2 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModel.kt
@@ -38,11 +38,17 @@ import com.android.systemui.keyguard.shared.model.Edge
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.lifecycle.ExclusiveActivatable
import com.android.systemui.lifecycle.Hydrator
+import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager
+import com.android.systemui.media.controls.ui.view.MediaHost
+import com.android.systemui.media.controls.ui.view.MediaHostState
+import com.android.systemui.media.dagger.MediaModule.QS_PANEL
+import com.android.systemui.media.dagger.MediaModule.QUICK_QS_PANEL
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.qs.FooterActionsController
+import com.android.systemui.qs.composefragment.dagger.QSFragmentComposeModule
import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel
import com.android.systemui.qs.panels.domain.interactor.TileSquishinessInteractor
-import com.android.systemui.qs.panels.ui.viewmodel.PaginatedGridViewModel
+import com.android.systemui.qs.panels.ui.viewmodel.InFirstPageViewModel
import com.android.systemui.qs.ui.viewmodel.QuickSettingsContainerViewModel
import com.android.systemui.res.R
import com.android.systemui.scene.shared.model.Scenes
@@ -60,10 +66,14 @@ import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import java.io.PrintWriter
+import javax.inject.Named
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.awaitCancellation
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.coroutineScope
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.callbackFlow
+import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onStart
@@ -83,7 +93,10 @@ constructor(
configurationInteractor: ConfigurationInteractor,
private val largeScreenHeaderHelper: LargeScreenHeaderHelper,
private val squishinessInteractor: TileSquishinessInteractor,
- private val paginatedGridViewModel: PaginatedGridViewModel,
+ private val inFirstPageViewModel: InFirstPageViewModel,
+ @Named(QUICK_QS_PANEL) val qqsMediaHost: MediaHost,
+ @Named(QS_PANEL) val qsMediaHost: MediaHost,
+ @Named(QSFragmentComposeModule.QS_USING_MEDIA_PLAYER) private val usingMedia: Boolean,
@Assisted private val lifecycleScope: LifecycleCoroutineScope,
) : Dumpable, ExclusiveActivatable() {
@@ -191,7 +204,7 @@ constructor(
var collapseExpandAccessibilityAction: Runnable? = null
val inFirstPage: Boolean
- get() = paginatedGridViewModel.inFirstPage
+ get() = inFirstPageViewModel.inFirstPage
var overScrollAmount by mutableStateOf(0)
@@ -222,6 +235,30 @@ constructor(
}
}
+ val showingMirror: Boolean
+ get() = containerViewModel.brightnessSliderViewModel.showMirror
+
+ // The initial values in these two are not meaningful. The flow will emit on start the correct
+ // values. This is because we need to lazily fetch them after initMediaHosts.
+ val qqsMediaVisible by
+ hydrator.hydratedStateOf(
+ traceName = "qqsMediaVisible",
+ initialValue = usingMedia,
+ source =
+ if (usingMedia) {
+ mediaHostVisible(qqsMediaHost)
+ } else {
+ flowOf(false)
+ },
+ )
+
+ val qsMediaVisible by
+ hydrator.hydratedStateOf(
+ traceName = "qsMediaVisible",
+ initialValue = usingMedia,
+ source = if (usingMedia) mediaHostVisible(qsMediaHost) else flowOf(false),
+ )
+
private var qsBounds by mutableStateOf(Rect())
private val constrainedSquishinessFraction: Float
@@ -259,9 +296,6 @@ constructor(
.onStart { emit(sysuiStatusBarStateController.state) },
)
- val showingMirror: Boolean
- get() = containerViewModel.brightnessSliderViewModel.showMirror
-
private val isKeyguardState: Boolean
get() = statusBarState == StatusBarState.KEYGUARD
@@ -323,6 +357,7 @@ constructor(
)
override suspend fun onActivated(): Nothing {
+ initMediaHosts() // init regardless of using media (same as current QS).
coroutineScope {
launch { hydrateSquishinessInteractor() }
launch { hydrator.activate() }
@@ -331,6 +366,19 @@ constructor(
}
}
+ private fun initMediaHosts() {
+ qqsMediaHost.apply {
+ expansion = MediaHostState.EXPANDED
+ showsOnlyActiveMedia = true
+ init(MediaHierarchyManager.LOCATION_QQS)
+ }
+ qsMediaHost.apply {
+ expansion = MediaHostState.EXPANDED
+ showsOnlyActiveMedia = false
+ init(MediaHierarchyManager.LOCATION_QS)
+ }
+ }
+
private suspend fun hydrateSquishinessInteractor() {
snapshotFlow { constrainedSquishinessFraction }
.collect { squishinessInteractor.setSquishinessValue(it) }
@@ -373,6 +421,10 @@ constructor(
println("qqsHeight", "${qqsHeight}px")
println("qsScrollHeight", "${qsScrollHeight}px")
}
+ printSection("Media") {
+ println("qqsMediaVisible", qqsMediaVisible)
+ println("qsMediaVisible", qsMediaVisible)
+ }
}
}
@@ -390,3 +442,21 @@ private fun Float.constrainSquishiness(): Float {
}
private val SHORT_PARALLAX_AMOUNT = 0.1f
+
+/**
+ * Returns a flow to track the visibility of a [MediaHost]. The flow will emit on start the visible
+ * state of the view.
+ */
+private fun mediaHostVisible(mediaHost: MediaHost): Flow<Boolean> {
+ return callbackFlow {
+ val listener: (Boolean) -> Unit = { visible: Boolean -> trySend(visible) }
+ mediaHost.addVisibilityChangeListener(listener)
+
+ awaitClose { mediaHost.removeVisibilityChangeListener(listener) }
+ }
+ // Need to use this to set initial state because on creation of the media host, the
+ // view visibility is not in sync with [MediaHost.visible], which is what we track with
+ // the listener. The correct state is set as part of init, so we need to get the state
+ // lazily.
+ .onStart { emit(mediaHost.visible) }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java
index 29bcad4e0e0c..94b8a3ac5a3c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java
@@ -19,6 +19,7 @@ package com.android.systemui.qs.dagger;
import com.android.systemui.media.dagger.MediaModule;
import com.android.systemui.qs.ReduceBrightColorsController;
import com.android.systemui.qs.ReduceBrightColorsControllerImpl;
+import com.android.systemui.qs.composefragment.dagger.QSFragmentComposeModule;
import com.android.systemui.qs.external.QSExternalModule;
import com.android.systemui.qs.panels.dagger.PanelsModule;
import com.android.systemui.qs.pipeline.dagger.QSPipelineModule;
@@ -40,6 +41,7 @@ import dagger.multibindings.Multibinds;
includes = {
MediaModule.class,
PanelsModule.class,
+ QSFragmentComposeModule.class,
QSExternalModule.class,
QSFlagsModule.class,
QSHostModule.class,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PaginatedGridLayout.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PaginatedGridLayout.kt
index d55763aaeddb..6cc2cbc63d09 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PaginatedGridLayout.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PaginatedGridLayout.kt
@@ -40,9 +40,9 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
-import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.android.compose.animation.scene.SceneScope
import com.android.systemui.compose.modifiers.sysuiResTag
+import com.android.systemui.lifecycle.rememberViewModel
import com.android.systemui.qs.panels.dagger.PaginatedBaseLayoutType
import com.android.systemui.qs.panels.ui.compose.PaginatedGridLayout.Dimensions.FooterHeight
import com.android.systemui.qs.panels.ui.compose.PaginatedGridLayout.Dimensions.InterPageSpacing
@@ -54,7 +54,7 @@ import javax.inject.Inject
class PaginatedGridLayout
@Inject
constructor(
- private val viewModel: PaginatedGridViewModel,
+ private val viewModelFactory: PaginatedGridViewModel.Factory,
@PaginatedBaseLayoutType private val delegateGridLayout: PaginatableGridLayout,
) : GridLayout by delegateGridLayout {
@Composable
@@ -63,13 +63,18 @@ constructor(
modifier: Modifier,
editModeStart: () -> Unit,
) {
+ val viewModel =
+ rememberViewModel(traceName = "PaginatedGridLayout-TileGrid") {
+ viewModelFactory.create()
+ }
+
DisposableEffect(tiles) {
val token = Any()
tiles.forEach { it.startListening(token) }
onDispose { tiles.forEach { it.stopListening(token) } }
}
- val columns by viewModel.columns.collectAsStateWithLifecycle()
- val rows by viewModel.rows.collectAsStateWithLifecycle()
+ val columns by viewModel.columns
+ val rows = viewModel.rows
val pages =
remember(tiles, columns, rows) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/QuickQuickSettings.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/QuickQuickSettings.kt
index 99a6cda8cbf5..ca28ab3e6ce3 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/QuickQuickSettings.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/QuickQuickSettings.kt
@@ -41,7 +41,8 @@ fun SceneScope.QuickQuickSettings(
viewModel: QuickQuickSettingsViewModel,
modifier: Modifier = Modifier,
) {
- val sizedTiles by viewModel.tileViewModels.collectAsStateWithLifecycle()
+
+ val sizedTiles = viewModel.tileViewModels
val tiles = sizedTiles.fastMap { it.tile }
val bounceables = remember(sizedTiles) { List(sizedTiles.size) { BounceableTileViewModel() } }
val squishiness by viewModel.squishinessViewModel.squishiness.collectAsStateWithLifecycle()
@@ -52,7 +53,7 @@ fun SceneScope.QuickQuickSettings(
tiles.forEach { it.startListening(token) }
onDispose { tiles.forEach { it.stopListening(token) } }
}
- val columns by viewModel.columns.collectAsStateWithLifecycle()
+ val columns = viewModel.columns
var cellIndex = 0
Box(modifier = modifier) {
GridAnchor()
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/InfiniteGridLayout.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/InfiniteGridLayout.kt
index 91f2da2b90f7..19ab29e6c796 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/InfiniteGridLayout.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/InfiniteGridLayout.kt
@@ -72,7 +72,7 @@ constructor(
rememberViewModel(traceName = "InfiniteGridLayout.TileGrid") {
viewModel.dynamicIconTilesViewModelFactory.create()
}
- val columns by viewModel.gridSizeViewModel.columns.collectAsStateWithLifecycle()
+ val columns by viewModel.gridSizeViewModel.columns
val sizedTiles = tiles.map { SizedTileImpl(it, it.spec.width()) }
val bounceables =
remember(sizedTiles) { List(sizedTiles.size) { BounceableTileViewModel() } }
@@ -118,7 +118,7 @@ constructor(
rememberViewModel(traceName = "InfiniteGridLayout.EditTileGrid") {
viewModel.dynamicIconTilesViewModelFactory.create()
}
- val columns by viewModel.gridSizeViewModel.columns.collectAsStateWithLifecycle()
+ val columns by viewModel.gridSizeViewModel.columns
val largeTiles by iconTilesViewModel.largeTiles.collectAsStateWithLifecycle()
// Non-current tiles should always be displayed as icon tiles.
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/InFirstPageViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/InFirstPageViewModel.kt
new file mode 100644
index 000000000000..225f54235d47
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/InFirstPageViewModel.kt
@@ -0,0 +1,29 @@
+/*
+ * 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.qs.panels.ui.viewmodel
+
+import com.android.systemui.dagger.SysUISingleton
+import javax.inject.Inject
+
+/*
+ * Tracks whether the current HorizontalPager (using this viewmodel) is in the first page.
+ * This requires it to be a `@SysUISingleton` to be shared between viewmodels.
+ */
+@SysUISingleton
+class InFirstPageViewModel @Inject constructor() {
+ var inFirstPage = true
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/InfiniteGridViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/InfiniteGridViewModel.kt
index 0d1206768db1..d68710048e13 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/InfiniteGridViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/InfiniteGridViewModel.kt
@@ -16,6 +16,7 @@
package com.android.systemui.qs.panels.ui.viewmodel
+import com.android.systemui.lifecycle.ExclusiveActivatable
import com.android.systemui.qs.panels.ui.dialog.QSResetDialogDelegate
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
@@ -27,12 +28,16 @@ constructor(
val gridSizeViewModel: QSColumnsViewModel,
val squishinessViewModel: TileSquishinessViewModel,
private val resetDialogDelegate: QSResetDialogDelegate,
-) {
+) : ExclusiveActivatable() {
fun showResetDialog() {
resetDialogDelegate.showDialog()
}
+ override suspend fun onActivated(): Nothing {
+ gridSizeViewModel.activate()
+ }
+
@AssistedFactory
interface Factory {
fun create(): InfiniteGridViewModel
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModel.kt
index 0f7dafcd941c..8bd9ed05c12c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModel.kt
@@ -16,33 +16,50 @@
package com.android.systemui.qs.panels.ui.viewmodel
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Application
+import androidx.compose.runtime.State
+import androidx.compose.runtime.getValue
+import com.android.systemui.lifecycle.ExclusiveActivatable
+import com.android.systemui.lifecycle.Hydrator
import com.android.systemui.qs.panels.domain.interactor.PaginatedGridInteractor
-import javax.inject.Inject
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.flow.SharingStarted
-import kotlinx.coroutines.flow.stateIn
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
+import kotlinx.coroutines.awaitCancellation
+import kotlinx.coroutines.coroutineScope
+import kotlinx.coroutines.launch
-@SysUISingleton
class PaginatedGridViewModel
-@Inject
+@AssistedInject
constructor(
iconTilesViewModel: IconTilesViewModel,
- gridSizeViewModel: QSColumnsViewModel,
+ private val gridSizeViewModel: QSColumnsViewModel,
paginatedGridInteractor: PaginatedGridInteractor,
- @Application applicationScope: CoroutineScope,
-) : IconTilesViewModel by iconTilesViewModel, QSColumnsViewModel by gridSizeViewModel {
- val rows =
- paginatedGridInteractor.rows.stateIn(
- applicationScope,
- SharingStarted.WhileSubscribed(),
- paginatedGridInteractor.defaultRows,
+ inFirstPageViewModel: InFirstPageViewModel,
+) : IconTilesViewModel by iconTilesViewModel, ExclusiveActivatable() {
+
+ private val hydrator = Hydrator("PaginatedGridViewModel")
+
+ val rows by
+ hydrator.hydratedStateOf(
+ traceName = "rows",
+ initialValue = paginatedGridInteractor.defaultRows,
+ source = paginatedGridInteractor.rows,
)
- /*
- * Tracks whether the current HorizontalPager (using this viewmodel) is in the first page.
- * This requires it to be a `@SysUISingleton` to be shared between viewmodels.
- */
- var inFirstPage = true
+ var inFirstPage by inFirstPageViewModel::inFirstPage
+
+ val columns: State<Int>
+ get() = gridSizeViewModel.columns
+
+ override suspend fun onActivated(): Nothing {
+ coroutineScope {
+ launch { hydrator.activate() }
+ launch { gridSizeViewModel.activate() }
+ awaitCancellation()
+ }
+ }
+
+ @AssistedFactory
+ interface Factory {
+ fun create(): PaginatedGridViewModel
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/QSColumnsViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/QSColumnsViewModel.kt
index 0f1c77eb4711..8926d2ff107e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/QSColumnsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/QSColumnsViewModel.kt
@@ -16,17 +16,25 @@
package com.android.systemui.qs.panels.ui.viewmodel
-import com.android.systemui.dagger.SysUISingleton
+import androidx.compose.runtime.State
+import com.android.systemui.lifecycle.Activatable
+import com.android.systemui.lifecycle.ExclusiveActivatable
+import com.android.systemui.lifecycle.Hydrator
import com.android.systemui.qs.panels.domain.interactor.QSColumnsInteractor
import javax.inject.Inject
-import kotlinx.coroutines.flow.StateFlow
-interface QSColumnsViewModel {
- val columns: StateFlow<Int>
+interface QSColumnsViewModel : Activatable {
+ val columns: State<Int>
}
-@SysUISingleton
class QSColumnsSizeViewModelImpl @Inject constructor(interactor: QSColumnsInteractor) :
- QSColumnsViewModel {
- override val columns: StateFlow<Int> = interactor.columns
+ QSColumnsViewModel, ExclusiveActivatable() {
+ private val hydrator = Hydrator("QSColumnsSizeViewModelImpl")
+
+ override val columns =
+ hydrator.hydratedStateOf(traceName = "columns", source = interactor.columns)
+
+ override suspend fun onActivated(): Nothing {
+ hydrator.activate()
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModel.kt
index 887a70f39f6a..0859c86d74e1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModel.kt
@@ -16,67 +16,69 @@
package com.android.systemui.qs.panels.ui.viewmodel
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Application
+import androidx.compose.runtime.derivedStateOf
+import androidx.compose.runtime.getValue
import com.android.systemui.haptics.msdl.qs.TileHapticsViewModelFactoryProvider
+import com.android.systemui.lifecycle.ExclusiveActivatable
+import com.android.systemui.lifecycle.Hydrator
import com.android.systemui.qs.panels.domain.interactor.QuickQuickSettingsRowInteractor
-import com.android.systemui.qs.panels.shared.model.SizedTile
import com.android.systemui.qs.panels.shared.model.SizedTileImpl
import com.android.systemui.qs.panels.shared.model.splitInRowsSequence
import com.android.systemui.qs.pipeline.domain.interactor.CurrentTilesInteractor
import com.android.systemui.qs.pipeline.shared.TileSpec
-import javax.inject.Inject
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.flow.SharingStarted
-import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.combine
-import kotlinx.coroutines.flow.flatMapLatest
-import kotlinx.coroutines.flow.mapLatest
-import kotlinx.coroutines.flow.stateIn
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
+import kotlinx.coroutines.awaitCancellation
+import kotlinx.coroutines.coroutineScope
+import kotlinx.coroutines.launch
-@OptIn(ExperimentalCoroutinesApi::class)
-@SysUISingleton
class QuickQuickSettingsViewModel
-@Inject
+@AssistedInject
constructor(
tilesInteractor: CurrentTilesInteractor,
- qsColumnsViewModel: QSColumnsViewModel,
+ private val qsColumnsViewModel: QSColumnsViewModel,
quickQuickSettingsRowInteractor: QuickQuickSettingsRowInteractor,
val squishinessViewModel: TileSquishinessViewModel,
- private val iconTilesViewModel: IconTilesViewModel,
- @Application private val applicationScope: CoroutineScope,
+ iconTilesViewModel: IconTilesViewModel,
val tileHapticsViewModelFactoryProvider: TileHapticsViewModelFactoryProvider,
-) {
+) : ExclusiveActivatable() {
- val columns = qsColumnsViewModel.columns
+ private val hydrator = Hydrator("QuickQuickSettingsViewModel")
- private val rows =
- quickQuickSettingsRowInteractor.rows.stateIn(
- applicationScope,
- SharingStarted.WhileSubscribed(),
- quickQuickSettingsRowInteractor.defaultRows,
+ val columns by qsColumnsViewModel.columns
+
+ private val largeTiles by
+ hydrator.hydratedStateOf(traceName = "largeTiles", source = iconTilesViewModel.largeTiles)
+
+ private val rows by
+ hydrator.hydratedStateOf(
+ traceName = "rows",
+ initialValue = quickQuickSettingsRowInteractor.defaultRows,
+ source = quickQuickSettingsRowInteractor.rows,
)
- val tileViewModels: StateFlow<List<SizedTile<TileViewModel>>> =
- columns
- .flatMapLatest { columns ->
- tilesInteractor.currentTiles.combine(rows, ::Pair).mapLatest { (tiles, rows) ->
- tiles
- .map { SizedTileImpl(TileViewModel(it.tile, it.spec), it.spec.width) }
- .let { splitInRowsSequence(it, columns).take(rows).toList().flatten() }
- }
- }
- .stateIn(
- applicationScope,
- SharingStarted.WhileSubscribed(),
- tilesInteractor.currentTiles.value
- .map { SizedTileImpl(TileViewModel(it.tile, it.spec), it.spec.width) }
- .let {
- splitInRowsSequence(it, columns.value).take(rows.value).toList().flatten()
- },
- )
+ private val currentTiles by
+ hydrator.hydratedStateOf(traceName = "currentTiles", source = tilesInteractor.currentTiles)
+
+ val tileViewModels by derivedStateOf {
+ currentTiles
+ .map { SizedTileImpl(TileViewModel(it.tile, it.spec), it.spec.width) }
+ .let { splitInRowsSequence(it, columns).take(rows).toList().flatten() }
+ }
private val TileSpec.width: Int
- get() = if (iconTilesViewModel.isIconTile(this)) 1 else 2
+ get() = if (largeTiles.contains(this)) 2 else 1
+
+ override suspend fun onActivated(): Nothing {
+ coroutineScope {
+ launch { hydrator.activate() }
+ launch { qsColumnsViewModel.activate() }
+ awaitCancellation()
+ }
+ }
+
+ @AssistedFactory
+ interface Factory {
+ fun create(): QuickQuickSettingsViewModel
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModel.kt
index b1eb3bb38728..da175c9120ba 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModel.kt
@@ -24,22 +24,31 @@ import com.android.systemui.qs.panels.ui.viewmodel.TileGridViewModel
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
+import kotlinx.coroutines.awaitCancellation
+import kotlinx.coroutines.coroutineScope
+import kotlinx.coroutines.launch
class QuickSettingsContainerViewModel
@AssistedInject
constructor(
brightnessSliderViewModelFactory: BrightnessSliderViewModel.Factory,
+ quickQuickSettingsViewModelFactory: QuickQuickSettingsViewModel.Factory,
@Assisted supportsBrightnessMirroring: Boolean,
val tileGridViewModel: TileGridViewModel,
val editModeViewModel: EditModeViewModel,
- val quickQuickSettingsViewModel: QuickQuickSettingsViewModel,
) : ExclusiveActivatable() {
val brightnessSliderViewModel =
brightnessSliderViewModelFactory.create(supportsBrightnessMirroring)
+ val quickQuickSettingsViewModel = quickQuickSettingsViewModelFactory.create()
+
override suspend fun onActivated(): Nothing {
- brightnessSliderViewModel.activate()
+ coroutineScope {
+ launch { brightnessSliderViewModel.activate() }
+ launch { quickQuickSettingsViewModel.activate() }
+ awaitCancellation()
+ }
}
@AssistedFactory
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index aa2a08f980f9..08d177f933c1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -1987,6 +1987,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
mColorUpdateLogger = colorUpdateLogger;
mDismissibilityProvider = dismissibilityProvider;
mFeatureFlags = featureFlags;
+ setHapticFeedbackEnabled(!com.android.systemui.Flags.msdlFeedback());
}
private void initDimens() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
index 23a2facf4c5a..baad616cbf02 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
@@ -64,6 +64,9 @@ import com.android.systemui.statusbar.policy.dagger.RemoteInputViewSubcomponent;
import com.android.systemui.util.time.SystemClock;
import com.android.systemui.wmshell.BubblesManager;
+import com.google.android.msdl.data.model.MSDLToken;
+import com.google.android.msdl.domain.MSDLPlayer;
+
import java.util.List;
import java.util.Optional;
@@ -114,6 +117,7 @@ public class ExpandableNotificationRowController implements NotifViewController
private final NotificationDismissibilityProvider mDismissibilityProvider;
private final IStatusBarService mStatusBarService;
private final UiEventLogger mUiEventLogger;
+ private final MSDLPlayer mMSDLPlayer;
private final NotificationSettingsController mSettingsController;
@@ -273,7 +277,8 @@ public class ExpandableNotificationRowController implements NotifViewController
ExpandableNotificationRowDragController dragController,
NotificationDismissibilityProvider dismissibilityProvider,
IStatusBarService statusBarService,
- UiEventLogger uiEventLogger) {
+ UiEventLogger uiEventLogger,
+ MSDLPlayer msdlPlayer) {
mView = view;
mListContainer = listContainer;
mRemoteInputViewSubcomponentFactory = rivSubcomponentFactory;
@@ -309,6 +314,7 @@ public class ExpandableNotificationRowController implements NotifViewController
mDismissibilityProvider = dismissibilityProvider;
mStatusBarService = statusBarService;
mUiEventLogger = uiEventLogger;
+ mMSDLPlayer = msdlPlayer;
}
/**
@@ -352,6 +358,9 @@ public class ExpandableNotificationRowController implements NotifViewController
}
mView.setLongPressListener((v, x, y, item) -> {
+ if (com.android.systemui.Flags.msdlFeedback()) {
+ mMSDLPlayer.playToken(MSDLToken.LONG_PRESS, null);
+ }
if (mView.isSummaryWithChildren()) {
mView.expandNotification();
return true;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index c1d72e4f7a2a..f02f7f736668 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -678,7 +678,9 @@ public class NotificationStackScrollLayout
mGroupMembershipManager = Dependency.get(GroupMembershipManager.class);
mGroupExpansionManager = Dependency.get(GroupExpansionManager.class);
setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
- setWindowInsetsAnimationCallback(mInsetsCallback);
+ if (!SceneContainerFlag.isEnabled()) {
+ setWindowInsetsAnimationCallback(mInsetsCallback);
+ }
}
/**
@@ -1694,7 +1696,7 @@ public class NotificationStackScrollLayout
} else if (mQsFullScreen) {
int stackStartPosition =
getContentHeight() - getTopPadding() + getIntrinsicPadding();
- int stackEndPosition = mMaxTopPadding + mShelf.getIntrinsicHeight();
+ int stackEndPosition = getMaxTopPadding() + mShelf.getIntrinsicHeight();
if (stackStartPosition <= stackEndPosition) {
stackHeight = stackEndPosition;
} else {
@@ -2086,6 +2088,7 @@ public class NotificationStackScrollLayout
}
private void updateImeInset(WindowInsets windowInsets) {
+ SceneContainerFlag.assertInLegacyMode();
mImeInset = windowInsets.getInsets(WindowInsets.Type.ime()).bottom;
if (mFooterView != null && mFooterView.getViewState() != null) {
@@ -2112,7 +2115,7 @@ public class NotificationStackScrollLayout
if (cutout != null) {
mWaterfallTopInset = cutout.getWaterfallInsets().top;
}
- if (!mIsInsetAnimationRunning) {
+ if (!SceneContainerFlag.isEnabled() && !mIsInsetAnimationRunning) {
// update bottom inset e.g. after rotation
updateImeInset(insets);
}
@@ -2513,6 +2516,7 @@ public class NotificationStackScrollLayout
}
private int getImeInset() {
+ SceneContainerFlag.assertInLegacyMode();
// The NotificationStackScrollLayout does not extend all the way to the bottom of the
// display. Therefore, subtract that space from the mImeInset, in order to only include
// the portion of the bottom inset that actually overlaps the NotificationStackScrollLayout.
@@ -2851,11 +2855,6 @@ public class NotificationStackScrollLayout
setExpandedHeight(mExpandedHeight);
}
- public void setMaxTopPadding(int maxTopPadding) {
- SceneContainerFlag.assertInLegacyMode();
- mMaxTopPadding = maxTopPadding;
- }
-
public int getLayoutMinHeight() {
SceneContainerFlag.assertInLegacyMode();
return getLayoutMinHeightInternal();
@@ -3639,7 +3638,11 @@ public class NotificationStackScrollLayout
* @return Whether a y coordinate is inside the content.
*/
public boolean isInContentBounds(float y) {
- return y < getHeight() - getEmptyBottomMarginInternal();
+ if (SceneContainerFlag.isEnabled()) {
+ return y < mAmbientState.getStackCutoff();
+ } else {
+ return y < getHeight() - getEmptyBottomMarginInternal();
+ }
}
private float getTouchSlop(MotionEvent event) {
@@ -5510,7 +5513,6 @@ public class NotificationStackScrollLayout
println(pw, "alpha", getAlpha());
println(pw, "suppressChildrenMeasureLayout", mSuppressChildrenMeasureAndLayout);
println(pw, "scrollY", mAmbientState.getScrollY());
- println(pw, "maxTopPadding", mMaxTopPadding);
println(pw, "showShelfOnly", mShouldShowShelfOnly);
println(pw, "qsExpandFraction", mQsExpansionFraction);
println(pw, "isCurrentUserSetup", mIsCurrentUserSetup);
@@ -5547,6 +5549,7 @@ public class NotificationStackScrollLayout
println(pw, "intrinsicContentHeight", getIntrinsicContentHeight());
println(pw, "contentHeight", getContentHeight());
println(pw, "topPadding", getTopPadding());
+ println(pw, "maxTopPadding", getMaxTopPadding());
}
});
pw.println();
@@ -6953,10 +6956,12 @@ public class NotificationStackScrollLayout
/** Use {@link ScrollViewFields#intrinsicStackHeight}, when SceneContainerFlag is enabled. */
private int getContentHeight() {
+ SceneContainerFlag.assertInLegacyMode();
return mContentHeight;
}
private void setContentHeight(int contentHeight) {
+ SceneContainerFlag.assertInLegacyMode();
mContentHeight = contentHeight;
}
@@ -6965,10 +6970,23 @@ public class NotificationStackScrollLayout
* @return the height of the content ignoring the footer.
*/
public float getIntrinsicContentHeight() {
+ SceneContainerFlag.assertInLegacyMode();
return mIntrinsicContentHeight;
}
private void setIntrinsicContentHeight(float intrinsicContentHeight) {
+ SceneContainerFlag.assertInLegacyMode();
mIntrinsicContentHeight = intrinsicContentHeight;
}
+
+ private int getMaxTopPadding() {
+ SceneContainerFlag.assertInLegacyMode();
+ return mMaxTopPadding;
+ }
+
+ /** Not used with SceneContainerFlag, because we rely on the placeholder for placement. */
+ public void setMaxTopPadding(int maxTopPadding) {
+ SceneContainerFlag.assertInLegacyMode();
+ mMaxTopPadding = maxTopPadding;
+ }
}
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 9cda199d5279..0c511aeae3e5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -1348,6 +1348,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
if (!canHandleBackPressed()) {
return;
}
+ mStatusBarStateController.setLeaveOpenOnKeyguardHide(false);
boolean hideBouncerOverDream = isBouncerShowing()
&& mDreamOverlayStateController.isOverlayActive();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java
index a6581159d33e..d2c2003112f6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java
@@ -37,6 +37,7 @@ import com.android.systemui.Dumpable;
import com.android.systemui.ScreenDecorations;
import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor;
import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor;
+import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.res.R;
import com.android.systemui.scene.domain.interactor.SceneInteractor;
@@ -78,6 +79,7 @@ public final class StatusBarTouchableRegionManager implements Dumpable {
private View mNotificationShadeWindowView;
private View mNotificationPanelView;
private boolean mForceCollapsedUntilLayout = false;
+ private Boolean mCommunalVisible = false;
private Region mTouchableRegion = new Region();
private int mDisplayCutoutTouchableRegionSize;
@@ -98,7 +100,8 @@ public final class StatusBarTouchableRegionManager implements Dumpable {
JavaAdapter javaAdapter,
UnlockedScreenOffAnimationController unlockedScreenOffAnimationController,
PrimaryBouncerInteractor primaryBouncerInteractor,
- AlternateBouncerInteractor alternateBouncerInteractor
+ AlternateBouncerInteractor alternateBouncerInteractor,
+ CommunalSceneInteractor communalSceneInteractor
) {
mContext = context;
initResources();
@@ -145,6 +148,9 @@ public final class StatusBarTouchableRegionManager implements Dumpable {
javaAdapter.alwaysCollectFlow(
shadeInteractor.isAnyExpanded(),
this::onShadeOrQsExpanded);
+ javaAdapter.alwaysCollectFlow(
+ communalSceneInteractor.isCommunalVisible(),
+ this::onCommunalVisible);
}
mPrimaryBouncerInteractor = primaryBouncerInteractor;
@@ -196,6 +202,10 @@ public final class StatusBarTouchableRegionManager implements Dumpable {
}
}
+ private void onCommunalVisible(Boolean visible) {
+ mCommunalVisible = visible;
+ }
+
/**
* Calculates the touch region needed for heads up notifications, taking into consideration
* any existing display cutouts (notch)
@@ -304,6 +314,9 @@ public final class StatusBarTouchableRegionManager implements Dumpable {
&& (!mIsSceneContainerUiEmpty || mIsRemoteUserInteractionOngoing))
|| mPrimaryBouncerInteractor.isShowing().getValue()
|| mAlternateBouncerInteractor.isVisibleState()
+ // The glanceable hub is a full-screen UI within the notification shade window. When
+ // it's visible, the touchable region should be the full screen.
+ || mCommunalVisible
|| mUnlockedScreenOffAnimationController.isAnimationPlaying();
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
index 06e8b1cf8dab..57fad83da8b9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
@@ -1207,6 +1207,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
}
@Test
+ @DisableSceneContainer
public void testWindowInsetAnimationProgress_updatesBottomInset() {
int imeInset = 100;
WindowInsets windowInsets = new WindowInsets.Builder()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
index c4c2aa7934f2..48106de5225b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
@@ -2533,6 +2533,42 @@ public class BubblesTest extends SysuiTestCase {
verify(mBubbleLogger).log(BubbleLogger.Event.BUBBLE_BAR_DISMISSED_DRAG_BAR);
}
+ @EnableFlags(FLAG_ENABLE_BUBBLE_BAR)
+ @Test
+ public void testEventLogging_bubbleBar_expandAndCollapse() {
+ mBubbleProperties.mIsBubbleBarEnabled = true;
+ mPositioner.setIsLargeScreen(true);
+ FakeBubbleStateListener bubbleStateListener = new FakeBubbleStateListener();
+ mBubbleController.registerBubbleStateListener(bubbleStateListener);
+
+ mEntryListener.onEntryAdded(mRow);
+ mBubbleController.expandStackAndSelectBubbleFromLauncher(mRow.getKey(), 0);
+
+ verify(mBubbleLogger).log(eqBubbleWithKey(mRow.getKey()),
+ eq(BubbleLogger.Event.BUBBLE_BAR_EXPANDED));
+
+ mBubbleController.collapseStack();
+
+ verify(mBubbleLogger).log(eqBubbleWithKey(mRow.getKey()),
+ eq(BubbleLogger.Event.BUBBLE_BAR_COLLAPSED));
+ }
+
+ @EnableFlags(FLAG_ENABLE_BUBBLE_BAR)
+ @Test
+ public void testEventLogging_bubbleBar_autoExpandingBubble() {
+ mBubbleProperties.mIsBubbleBarEnabled = true;
+ mPositioner.setIsLargeScreen(true);
+ FakeBubbleStateListener bubbleStateListener = new FakeBubbleStateListener();
+ mBubbleController.registerBubbleStateListener(bubbleStateListener);
+
+ setMetadataFlags(mRow,
+ Notification.BubbleMetadata.FLAG_AUTO_EXPAND_BUBBLE, true /* enableFlag */);
+ mEntryListener.onEntryAdded(mRow);
+
+ verify(mBubbleLogger).log(eqBubbleWithKey(mRow.getKey()),
+ eq(BubbleLogger.Event.BUBBLE_BAR_EXPANDED));
+ }
+
/** Creates a bubble using the userId and package. */
private Bubble createBubble(int userId, String pkg) {
final UserHandle userHandle = new UserHandle(userId);
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardTransitionRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardTransitionRepository.kt
index 4976cc26068a..19e077c57de0 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardTransitionRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardTransitionRepository.kt
@@ -53,6 +53,15 @@ class FakeKeyguardTransitionRepository(
private val initInLockscreen: Boolean = true,
/**
+ * Initial value for [FakeKeyguardTransitionRepository.sendTransitionStepsOnStartTransition].
+ * This needs to be configurable in the constructor since some transitions are triggered on
+ * init, before a test has the chance to set sendTransitionStepsOnStartTransition to false.
+ */
+ private val initiallySendTransitionStepsOnStartTransition: Boolean = true,
+ private val testScope: TestScope,
+) : KeyguardTransitionRepository {
+
+ /**
* If true, calls to [startTransition] will automatically emit STARTED, RUNNING, and FINISHED
* transition steps from/to the given states.
*
@@ -64,11 +73,9 @@ class FakeKeyguardTransitionRepository(
*
* If your test needs to make assertions at specific points between STARTED/FINISHED, or if it's
* difficult to set up all of the conditions to make the transition interactors actually call
- * startTransition, then construct a FakeKeyguardTransitionRepository with this value false.
+ * startTransition, set this value to false.
*/
- private val sendTransitionStepsOnStartTransition: Boolean = true,
- private val testScope: TestScope,
-) : KeyguardTransitionRepository {
+ var sendTransitionStepsOnStartTransition = initiallySendTransitionStepsOnStartTransition
private val _transitions =
MutableSharedFlow<TransitionStep>(replay = 3, onBufferOverflow = BufferOverflow.DROP_OLDEST)
@@ -77,7 +84,11 @@ class FakeKeyguardTransitionRepository(
@Inject
constructor(
testScope: TestScope
- ) : this(initInLockscreen = true, sendTransitionStepsOnStartTransition = true, testScope)
+ ) : this(
+ initInLockscreen = true,
+ initiallySendTransitionStepsOnStartTransition = true,
+ testScope
+ )
private val _currentTransitionInfo: MutableStateFlow<TransitionInfo> =
MutableStateFlow(
@@ -176,6 +187,20 @@ class FakeKeyguardTransitionRepository(
testScheduler: TestCoroutineScheduler,
throughTransitionState: TransitionState = TransitionState.FINISHED,
) {
+ val lastStep = _transitions.replayCache.lastOrNull()
+ if (lastStep != null && lastStep.transitionState != TransitionState.FINISHED) {
+ sendTransitionStep(
+ step =
+ TransitionStep(
+ transitionState = TransitionState.CANCELED,
+ from = lastStep.from,
+ to = lastStep.to,
+ value = 0f,
+ )
+ )
+ testScheduler.runCurrent()
+ }
+
sendTransitionStep(
step =
TransitionStep(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/domain/pipeline/LegacyMediaDataManagerImplKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/domain/pipeline/LegacyMediaDataManagerImplKosmos.kt
new file mode 100644
index 000000000000..c337298fa8c8
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/domain/pipeline/LegacyMediaDataManagerImplKosmos.kt
@@ -0,0 +1,23 @@
+/*
+ * 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.media.controls.domain.pipeline
+
+import com.android.systemui.kosmos.Kosmos
+import org.mockito.kotlin.mock
+
+/** Empty mock */
+val Kosmos.legacyMediaDataManagerImpl by Kosmos.Fixture { mock<LegacyMediaDataManagerImpl>() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/domain/pipeline/MediaDataManagerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/domain/pipeline/MediaDataManagerKosmos.kt
new file mode 100644
index 000000000000..f733da12a95e
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/domain/pipeline/MediaDataManagerKosmos.kt
@@ -0,0 +1,21 @@
+/*
+ * 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.media.controls.domain.pipeline
+
+import com.android.systemui.kosmos.Kosmos
+
+var Kosmos.mediaDataManager: MediaDataManager by Kosmos.Fixture()
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/controller/MediaCarouselControllerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/controller/MediaCarouselControllerKosmos.kt
new file mode 100644
index 000000000000..3c35ce9bf003
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/controller/MediaCarouselControllerKosmos.kt
@@ -0,0 +1,23 @@
+/*
+ * 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.media.controls.ui.controller
+
+import com.android.systemui.kosmos.Kosmos
+import org.mockito.kotlin.mock
+
+/** Empty mock */
+val Kosmos.mediaCarouselController by Kosmos.Fixture { mock<MediaCarouselController>() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/controller/MediaCarouselControllerLoggerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/controller/MediaCarouselControllerLoggerKosmos.kt
new file mode 100644
index 000000000000..9f5a8328d403
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/controller/MediaCarouselControllerLoggerKosmos.kt
@@ -0,0 +1,23 @@
+/*
+ * 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.media.controls.ui.controller
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.log.core.FakeLogBuffer
+
+val Kosmos.mediaCarouselControllerLogger by
+ Kosmos.Fixture { MediaCarouselControllerLogger(FakeLogBuffer.Factory.create()) }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/controller/MediaHierarchyManagerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/controller/MediaHierarchyManagerKosmos.kt
index 7c24b4cc3d60..624e174321ec 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/controller/MediaHierarchyManagerKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/controller/MediaHierarchyManagerKosmos.kt
@@ -16,8 +16,15 @@
package com.android.systemui.media.controls.ui.controller
+import android.content.testableContext
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
-import com.android.systemui.util.mockito.mock
+import com.android.systemui.util.animation.UniqueObjectHostView
+import org.mockito.kotlin.any
+import org.mockito.kotlin.mock
-var Kosmos.mediaHierarchyManager by Fixture { mock<MediaHierarchyManager>() }
+var Kosmos.mediaHierarchyManager by Fixture {
+ mock<MediaHierarchyManager> {
+ on { register(any()) }.thenAnswer { UniqueObjectHostView(this@Fixture.testableContext) }
+ }
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/controller/MediaHostStatesManagerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/controller/MediaHostStatesManagerKosmos.kt
new file mode 100644
index 000000000000..8b02c579d91d
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/controller/MediaHostStatesManagerKosmos.kt
@@ -0,0 +1,21 @@
+/*
+ * 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.media.controls.ui.controller
+
+import com.android.systemui.kosmos.Kosmos
+
+val Kosmos.mediaHostStatesManager by Kosmos.Fixture { MediaHostStatesManager() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/view/MediaHostKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/view/MediaHostKosmos.kt
new file mode 100644
index 000000000000..9638e117362c
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/view/MediaHostKosmos.kt
@@ -0,0 +1,42 @@
+/*
+ * 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.media.controls.ui.view
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.media.controls.domain.pipeline.mediaDataManager
+import com.android.systemui.media.controls.ui.controller.mediaCarouselController
+import com.android.systemui.media.controls.ui.controller.mediaCarouselControllerLogger
+import com.android.systemui.media.controls.ui.controller.mediaHierarchyManager
+import com.android.systemui.media.controls.ui.controller.mediaHostStatesManager
+import java.util.function.Supplier
+
+private val Kosmos.mediaHostProvider by
+ Kosmos.Fixture {
+ Supplier<MediaHost> {
+ MediaHost(
+ MediaHost.MediaHostStateHolder(),
+ mediaHierarchyManager,
+ mediaDataManager,
+ mediaHostStatesManager,
+ mediaCarouselController,
+ mediaCarouselControllerLogger,
+ )
+ }
+ }
+
+val Kosmos.qqsMediaHost by Kosmos.Fixture { mediaHostProvider.get() }
+val Kosmos.qsMediaHost by Kosmos.Fixture { mediaHostProvider.get() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/composefragment/dagger/QSFragmentComposeModuleKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/composefragment/dagger/QSFragmentComposeModuleKosmos.kt
new file mode 100644
index 000000000000..fb8ffb0c5eb2
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/composefragment/dagger/QSFragmentComposeModuleKosmos.kt
@@ -0,0 +1,21 @@
+/*
+ * 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.qs.composefragment.dagger
+
+import com.android.systemui.kosmos.Kosmos
+
+var Kosmos.usingMediaInComposeFragment by Kosmos.Fixture<Boolean>()
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelKosmos.kt
index 462b4083aa44..bda3192085ed 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelKosmos.kt
@@ -22,10 +22,13 @@ import com.android.systemui.common.ui.domain.interactor.configurationInteractor
import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.media.controls.ui.view.qqsMediaHost
+import com.android.systemui.media.controls.ui.view.qsMediaHost
+import com.android.systemui.qs.composefragment.dagger.usingMediaInComposeFragment
import com.android.systemui.qs.footerActionsController
import com.android.systemui.qs.footerActionsViewModelFactory
import com.android.systemui.qs.panels.domain.interactor.tileSquishinessInteractor
-import com.android.systemui.qs.panels.ui.viewmodel.paginatedGridViewModel
+import com.android.systemui.qs.panels.ui.viewmodel.inFirstPageViewModel
import com.android.systemui.qs.ui.viewmodel.quickSettingsContainerViewModelFactory
import com.android.systemui.shade.largeScreenHeaderHelper
import com.android.systemui.shade.transition.largeScreenShadeInterpolator
@@ -53,7 +56,10 @@ val Kosmos.qsFragmentComposeViewModelFactory by
configurationInteractor,
largeScreenHeaderHelper,
tileSquishinessInteractor,
- paginatedGridViewModel,
+ inFirstPageViewModel,
+ qqsMediaHost,
+ qsMediaHost,
+ usingMediaInComposeFragment,
lifecycleScope,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/InFirstPageViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/InFirstPageViewModelKosmos.kt
new file mode 100644
index 000000000000..1fa74cabcdeb
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/InFirstPageViewModelKosmos.kt
@@ -0,0 +1,21 @@
+/*
+ * 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.qs.panels.ui.viewmodel
+
+import com.android.systemui.kosmos.Kosmos
+
+val Kosmos.inFirstPageViewModel by Kosmos.Fixture { InFirstPageViewModel() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModelKosmos.kt
index 48ef57e9a62c..5c8ca83ff2ae 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModelKosmos.kt
@@ -17,7 +17,6 @@
package com.android.systemui.qs.panels.ui.viewmodel
import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.qs.panels.domain.interactor.paginatedGridInteractor
val Kosmos.paginatedGridViewModel by
@@ -26,6 +25,6 @@ val Kosmos.paginatedGridViewModel by
iconTilesViewModel,
qsColumnsViewModel,
paginatedGridInteractor,
- applicationCoroutineScope,
+ inFirstPageViewModel,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModelKosmos.kt
index 41ee260fd5dd..20be5c675851 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModelKosmos.kt
@@ -18,19 +18,21 @@ package com.android.systemui.qs.panels.ui.viewmodel
import com.android.systemui.haptics.msdl.tileHapticsViewModelFactoryProvider
import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.qs.panels.domain.interactor.quickQuickSettingsRowInteractor
import com.android.systemui.qs.pipeline.domain.interactor.currentTilesInteractor
-val Kosmos.quickQuickSettingsViewModel by
+val Kosmos.quickQuickSettingsViewModelFactory by
Kosmos.Fixture {
- QuickQuickSettingsViewModel(
- currentTilesInteractor,
- qsColumnsViewModel,
- quickQuickSettingsRowInteractor,
- tileSquishinessViewModel,
- iconTilesViewModel,
- applicationCoroutineScope,
- tileHapticsViewModelFactoryProvider,
- )
+ object : QuickQuickSettingsViewModel.Factory {
+ override fun create(): QuickQuickSettingsViewModel {
+ return QuickQuickSettingsViewModel(
+ currentTilesInteractor,
+ qsColumnsViewModel,
+ quickQuickSettingsRowInteractor,
+ tileSquishinessViewModel,
+ iconTilesViewModel,
+ tileHapticsViewModelFactoryProvider,
+ )
+ }
+ }
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModelKosmos.kt
index 6ded7517f1d2..ce103ec57a86 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModelKosmos.kt
@@ -19,7 +19,7 @@ package com.android.systemui.qs.ui.viewmodel
import com.android.systemui.brightness.ui.viewmodel.brightnessSliderViewModelFactory
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.qs.panels.ui.viewmodel.editModeViewModel
-import com.android.systemui.qs.panels.ui.viewmodel.quickQuickSettingsViewModel
+import com.android.systemui.qs.panels.ui.viewmodel.quickQuickSettingsViewModelFactory
import com.android.systemui.qs.panels.ui.viewmodel.tileGridViewModel
val Kosmos.quickSettingsContainerViewModelFactory by
@@ -30,10 +30,10 @@ val Kosmos.quickSettingsContainerViewModelFactory by
): QuickSettingsContainerViewModel {
return QuickSettingsContainerViewModel(
brightnessSliderViewModelFactory,
+ quickQuickSettingsViewModelFactory,
supportsBrightnessMirroring,
tileGridViewModel,
editModeViewModel,
- quickQuickSettingsViewModel,
)
}
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManagerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManagerKosmos.kt
index 8785256de452..87ea1473bba1 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManagerKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManagerKosmos.kt
@@ -19,6 +19,7 @@ package com.android.systemui.statusbar.phone
import android.content.applicationContext
import com.android.systemui.bouncer.domain.interactor.alternateBouncerInteractor
import com.android.systemui.bouncer.domain.interactor.primaryBouncerInteractor
+import com.android.systemui.communal.domain.interactor.communalSceneInteractor
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.testScope
import com.android.systemui.scene.domain.interactor.sceneInteractor
@@ -43,5 +44,6 @@ var Kosmos.statusBarTouchableRegionManager by
mock<UnlockedScreenOffAnimationController>(),
primaryBouncerInteractor,
alternateBouncerInteractor,
+ communalSceneInteractor,
)
}
diff --git a/ravenwood/texts/ravenwood-annotation-allowed-classes.txt b/ravenwood/texts/ravenwood-annotation-allowed-classes.txt
index a26fe66da2ab..70c1d781587f 100644
--- a/ravenwood/texts/ravenwood-annotation-allowed-classes.txt
+++ b/ravenwood/texts/ravenwood-annotation-allowed-classes.txt
@@ -2,6 +2,9 @@
com.android.internal.ravenwood.*
+com.android.server.FgThread
+com.android.server.ServiceThread
+
com.android.internal.display.BrightnessSynchronizer
com.android.internal.util.ArrayUtils
com.android.internal.logging.MetricsLogger
diff --git a/services/Android.bp b/services/Android.bp
index f04c692c12d0..899e224c6fd7 100644
--- a/services/Android.bp
+++ b/services/Android.bp
@@ -188,6 +188,28 @@ art_profile_java_defaults {
},
}
+// Conditionally add crashrecovery stubs library
+soong_config_module_type {
+ name: "crashrecovery_java_defaults",
+ module_type: "java_defaults",
+ config_namespace: "ANDROID",
+ bool_variables: [
+ "release_crashrecovery_module",
+ ],
+ properties: [
+ "libs",
+ ],
+}
+
+crashrecovery_java_defaults {
+ name: "services_crashrecovery_stubs_conditionally",
+ soong_config_variables: {
+ release_crashrecovery_module: {
+ libs: ["service-crashrecovery.stubs.system_server"],
+ },
+ },
+}
+
// merge all required services into one jar
// ============================================================
soong_config_module_type {
@@ -213,6 +235,7 @@ system_java_library {
defaults: [
"services_java_defaults",
"art_profile_java_defaults",
+ "services_crashrecovery_stubs_conditionally",
],
installable: true,
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
index a960015ecba6..51034d24df14 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
@@ -31,13 +31,16 @@ import static android.os.UserHandle.getCallingUserId;
import static com.android.internal.util.CollectionUtils.any;
import static com.android.internal.util.Preconditions.checkState;
+import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
import static com.android.server.companion.utils.PackageUtils.enforceUsesCompanionDeviceFeature;
+import static com.android.server.companion.utils.PackageUtils.getPackageInfo;
import static com.android.server.companion.utils.PackageUtils.isRestrictedSettingsAllowed;
import static com.android.server.companion.utils.PermissionsUtils.enforceCallerCanManageAssociationsForPackage;
import static com.android.server.companion.utils.PermissionsUtils.enforceCallerIsSystemOr;
import static com.android.server.companion.utils.PermissionsUtils.enforceCallerIsSystemOrCanInteractWithUserId;
import static java.util.Objects.requireNonNull;
+import static java.util.concurrent.TimeUnit.MINUTES;
import android.annotation.EnforcePermission;
import android.annotation.NonNull;
@@ -66,22 +69,31 @@ import android.companion.datatransfer.PermissionSyncRequest;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.net.MacAddress;
+import android.net.NetworkPolicyManager;
import android.os.Binder;
+import android.os.Environment;
import android.os.Parcel;
import android.os.ParcelFileDescriptor;
import android.os.PowerExemptionManager;
import android.os.PowerManagerInternal;
import android.os.RemoteException;
+import android.os.ServiceManager;
import android.os.UserHandle;
import android.os.UserManager;
import android.permission.flags.Flags;
+import android.util.ArraySet;
import android.util.ExceptionUtils;
import android.util.Slog;
+import com.android.internal.app.IAppOpsService;
import com.android.internal.content.PackageMonitor;
import com.android.internal.notification.NotificationAccessConfirmationActivityContract;
+import com.android.internal.os.BackgroundThread;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.DumpUtils;
import com.android.server.FgThread;
@@ -102,27 +114,35 @@ import com.android.server.companion.devicepresence.DevicePresenceProcessor;
import com.android.server.companion.devicepresence.ObservableUuid;
import com.android.server.companion.devicepresence.ObservableUuidStore;
import com.android.server.companion.transport.CompanionTransportManager;
+import com.android.server.pm.UserManagerInternal;
import com.android.server.wm.ActivityTaskManagerInternal;
+import java.io.File;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.Collection;
import java.util.List;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
+import java.util.Set;
@SuppressLint("LongLogTag")
public class CompanionDeviceManagerService extends SystemService {
private static final String TAG = "CDM_CompanionDeviceManagerService";
private static final long PAIR_WITHOUT_PROMPT_WINDOW_MS = 10 * 60 * 1000; // 10 min
+
+ private static final String PREF_FILE_NAME = "companion_device_preferences.xml";
+ private static final String PREF_KEY_AUTO_REVOKE_GRANTS_DONE = "auto_revoke_grants_done";
private static final int MAX_CN_LENGTH = 500;
+ private final ActivityTaskManagerInternal mAtmInternal;
+ private final ActivityManagerInternal mAmInternal;
+ private final IAppOpsService mAppOpsManager;
+ private final PowerExemptionManager mPowerExemptionManager;
+ private final PackageManagerInternal mPackageManagerInternal;
+
private final AssociationStore mAssociationStore;
private final SystemDataTransferRequestStore mSystemDataTransferRequestStore;
private final ObservableUuidStore mObservableUuidStore;
-
- private final CompanionExemptionProcessor mCompanionExemptionProcessor;
private final AssociationRequestsProcessor mAssociationRequestsProcessor;
private final SystemDataTransferProcessor mSystemDataTransferProcessor;
private final BackupRestoreProcessor mBackupRestoreProcessor;
@@ -136,15 +156,12 @@ public class CompanionDeviceManagerService extends SystemService {
super(context);
final ActivityManager activityManager = context.getSystemService(ActivityManager.class);
- final PowerExemptionManager powerExemptionManager = context.getSystemService(
- PowerExemptionManager.class);
- final AppOpsManager appOpsManager = context.getSystemService(AppOpsManager.class);
- final ActivityTaskManagerInternal atmInternal = LocalServices.getService(
- ActivityTaskManagerInternal.class);
- final ActivityManagerInternal amInternal = LocalServices.getService(
- ActivityManagerInternal.class);
- final PackageManagerInternal packageManagerInternal = LocalServices.getService(
- PackageManagerInternal.class);
+ mPowerExemptionManager = context.getSystemService(PowerExemptionManager.class);
+ mAppOpsManager = IAppOpsService.Stub.asInterface(
+ ServiceManager.getService(Context.APP_OPS_SERVICE));
+ mAtmInternal = LocalServices.getService(ActivityTaskManagerInternal.class);
+ mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
+ mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
final UserManager userManager = context.getSystemService(UserManager.class);
final PowerManagerInternal powerManagerInternal = LocalServices.getService(
PowerManagerInternal.class);
@@ -156,29 +173,25 @@ public class CompanionDeviceManagerService extends SystemService {
// Init processors
mAssociationRequestsProcessor = new AssociationRequestsProcessor(context,
- packageManagerInternal, mAssociationStore);
- mBackupRestoreProcessor = new BackupRestoreProcessor(context, packageManagerInternal,
+ mPackageManagerInternal, mAssociationStore);
+ mBackupRestoreProcessor = new BackupRestoreProcessor(context, mPackageManagerInternal,
mAssociationStore, associationDiskStore, mSystemDataTransferRequestStore,
mAssociationRequestsProcessor);
mCompanionAppBinder = new CompanionAppBinder(context);
- mCompanionExemptionProcessor = new CompanionExemptionProcessor(context,
- powerExemptionManager, appOpsManager, packageManagerInternal, atmInternal,
- amInternal, mAssociationStore);
-
mDevicePresenceProcessor = new DevicePresenceProcessor(context,
mCompanionAppBinder, userManager, mAssociationStore, mObservableUuidStore,
- powerManagerInternal, mCompanionExemptionProcessor);
+ powerManagerInternal);
mTransportManager = new CompanionTransportManager(context, mAssociationStore);
mDisassociationProcessor = new DisassociationProcessor(context, activityManager,
- mAssociationStore, packageManagerInternal, mDevicePresenceProcessor,
+ mAssociationStore, mPackageManagerInternal, mDevicePresenceProcessor,
mCompanionAppBinder, mSystemDataTransferRequestStore, mTransportManager);
mSystemDataTransferProcessor = new SystemDataTransferProcessor(this,
- packageManagerInternal, mAssociationStore,
+ mPackageManagerInternal, mAssociationStore,
mSystemDataTransferRequestStore, mTransportManager);
// TODO(b/279663946): move context sync to a dedicated system service
@@ -189,6 +202,7 @@ public class CompanionDeviceManagerService extends SystemService {
public void onStart() {
// Init association stores
mAssociationStore.refreshCache();
+ mAssociationStore.registerLocalListener(mAssociationStoreChangeListener);
// Init UUID store
mObservableUuidStore.getObservableUuidsForUser(getContext().getUserId());
@@ -226,11 +240,11 @@ public class CompanionDeviceManagerService extends SystemService {
if (associations.isEmpty()) return;
- mCompanionExemptionProcessor.updateAtm(userId, associations);
+ updateAtm(userId, associations);
- try (ExecutorService executor = Executors.newSingleThreadExecutor()) {
- executor.execute(mCompanionExemptionProcessor::updateAutoRevokeExemptions);
- }
+ BackgroundThread.getHandler().sendMessageDelayed(
+ obtainMessage(CompanionDeviceManagerService::maybeGrantAutoRevokeExemptions, this),
+ MINUTES.toMillis(10));
}
@Override
@@ -248,12 +262,9 @@ public class CompanionDeviceManagerService extends SystemService {
if (!associationsForPackage.isEmpty()) {
Slog.i(TAG, "Package removed or data cleared for user=[" + userId + "], package=["
+ packageName + "]. Cleaning up CDM data...");
-
- for (AssociationInfo association : associationsForPackage) {
- mDisassociationProcessor.disassociate(association.getId());
- }
-
- mCompanionAppBinder.onPackagesChanged(userId, packageName);
+ }
+ for (AssociationInfo association : associationsForPackage) {
+ mDisassociationProcessor.disassociate(association.getId());
}
// Clear observable UUIDs for the package.
@@ -262,16 +273,19 @@ public class CompanionDeviceManagerService extends SystemService {
for (ObservableUuid uuid : uuidsTobeObserved) {
mObservableUuidStore.removeObservableUuid(userId, uuid.getUuid(), packageName);
}
+
+ mCompanionAppBinder.onPackagesChanged(userId);
}
private void onPackageModifiedInternal(@UserIdInt int userId, @NonNull String packageName) {
- final List<AssociationInfo> associations =
+ final List<AssociationInfo> associationsForPackage =
mAssociationStore.getAssociationsByPackage(userId, packageName);
- if (!associations.isEmpty()) {
- mCompanionExemptionProcessor.exemptPackage(userId, packageName, false);
-
- mCompanionAppBinder.onPackagesChanged(userId, packageName);
+ for (AssociationInfo association : associationsForPackage) {
+ updateSpecialAccessPermissionForAssociatedPackage(association.getUserId(),
+ association.getPackageName());
}
+
+ mCompanionAppBinder.onPackagesChanged(userId);
}
private void onPackageAddedInternal(@UserIdInt int userId, @NonNull String packageName) {
@@ -751,6 +765,130 @@ public class CompanionDeviceManagerService extends SystemService {
}
}
+ /**
+ * Update special access for the association's package
+ */
+ public void updateSpecialAccessPermissionForAssociatedPackage(int userId, String packageName) {
+ final PackageInfo packageInfo =
+ getPackageInfo(getContext(), userId, packageName);
+
+ Binder.withCleanCallingIdentity(() -> updateSpecialAccessPermissionAsSystem(packageInfo));
+ }
+
+ private void updateSpecialAccessPermissionAsSystem(PackageInfo packageInfo) {
+ if (packageInfo == null) {
+ return;
+ }
+
+ if (containsEither(packageInfo.requestedPermissions,
+ android.Manifest.permission.RUN_IN_BACKGROUND,
+ android.Manifest.permission.REQUEST_COMPANION_RUN_IN_BACKGROUND)) {
+ mPowerExemptionManager.addToPermanentAllowList(packageInfo.packageName);
+ } else {
+ try {
+ mPowerExemptionManager.removeFromPermanentAllowList(packageInfo.packageName);
+ } catch (UnsupportedOperationException e) {
+ Slog.w(TAG, packageInfo.packageName + " can't be removed from power save"
+ + " whitelist. It might due to the package is whitelisted by the system.");
+ }
+ }
+
+ NetworkPolicyManager networkPolicyManager = NetworkPolicyManager.from(getContext());
+ try {
+ if (containsEither(packageInfo.requestedPermissions,
+ android.Manifest.permission.USE_DATA_IN_BACKGROUND,
+ android.Manifest.permission.REQUEST_COMPANION_USE_DATA_IN_BACKGROUND)) {
+ networkPolicyManager.addUidPolicy(
+ packageInfo.applicationInfo.uid,
+ NetworkPolicyManager.POLICY_ALLOW_METERED_BACKGROUND);
+ } else {
+ networkPolicyManager.removeUidPolicy(
+ packageInfo.applicationInfo.uid,
+ NetworkPolicyManager.POLICY_ALLOW_METERED_BACKGROUND);
+ }
+ } catch (IllegalArgumentException e) {
+ Slog.e(TAG, e.getMessage());
+ }
+
+ exemptFromAutoRevoke(packageInfo.packageName, packageInfo.applicationInfo.uid);
+ }
+
+ private void exemptFromAutoRevoke(String packageName, int uid) {
+ try {
+ mAppOpsManager.setMode(
+ AppOpsManager.OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED,
+ uid,
+ packageName,
+ AppOpsManager.MODE_IGNORED);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Error while granting auto revoke exemption for " + packageName, e);
+ }
+ }
+
+ private void updateAtm(int userId, List<AssociationInfo> associations) {
+ final Set<Integer> companionAppUids = new ArraySet<>();
+ for (AssociationInfo association : associations) {
+ final int uid = mPackageManagerInternal.getPackageUid(association.getPackageName(),
+ 0, userId);
+ if (uid >= 0) {
+ companionAppUids.add(uid);
+ }
+ }
+ if (mAtmInternal != null) {
+ mAtmInternal.setCompanionAppUids(userId, companionAppUids);
+ }
+ if (mAmInternal != null) {
+ // Make a copy of the set and send it to ActivityManager.
+ mAmInternal.setCompanionAppUids(userId, new ArraySet<>(companionAppUids));
+ }
+ }
+
+ private void maybeGrantAutoRevokeExemptions() {
+ Slog.d(TAG, "maybeGrantAutoRevokeExemptions()");
+
+ PackageManager pm = getContext().getPackageManager();
+ for (int userId : LocalServices.getService(UserManagerInternal.class).getUserIds()) {
+ SharedPreferences pref = getContext().getSharedPreferences(
+ new File(Environment.getUserSystemDirectory(userId), PREF_FILE_NAME),
+ Context.MODE_PRIVATE);
+ if (pref.getBoolean(PREF_KEY_AUTO_REVOKE_GRANTS_DONE, false)) {
+ continue;
+ }
+
+ try {
+ final List<AssociationInfo> associations =
+ mAssociationStore.getActiveAssociationsByUser(userId);
+ for (AssociationInfo a : associations) {
+ try {
+ int uid = pm.getPackageUidAsUser(a.getPackageName(), userId);
+ exemptFromAutoRevoke(a.getPackageName(), uid);
+ } catch (PackageManager.NameNotFoundException e) {
+ Slog.w(TAG, "Unknown companion package: " + a.getPackageName(), e);
+ }
+ }
+ } finally {
+ pref.edit().putBoolean(PREF_KEY_AUTO_REVOKE_GRANTS_DONE, true).apply();
+ }
+ }
+ }
+
+ private final AssociationStore.OnChangeListener mAssociationStoreChangeListener =
+ new AssociationStore.OnChangeListener() {
+ @Override
+ public void onAssociationChanged(int changeType, AssociationInfo association) {
+ Slog.d(TAG, "onAssociationChanged changeType=[" + changeType
+ + "], association=[" + association);
+
+ final int userId = association.getUserId();
+ final List<AssociationInfo> updatedAssociations =
+ mAssociationStore.getActiveAssociationsByUser(userId);
+
+ updateAtm(userId, updatedAssociations);
+ updateSpecialAccessPermissionForAssociatedPackage(association.getUserId(),
+ association.getPackageName());
+ }
+ };
+
private final PackageMonitor mPackageMonitor = new PackageMonitor() {
@Override
public void onPackageRemoved(String packageName, int uid) {
@@ -773,6 +911,10 @@ public class CompanionDeviceManagerService extends SystemService {
}
};
+ private static <T> boolean containsEither(T[] array, T a, T b) {
+ return ArrayUtils.contains(array, a) || ArrayUtils.contains(array, b);
+ }
+
private class LocalService implements CompanionDeviceManagerServiceInternal {
@Override
diff --git a/services/companion/java/com/android/server/companion/CompanionExemptionProcessor.java b/services/companion/java/com/android/server/companion/CompanionExemptionProcessor.java
deleted file mode 100644
index 4969ffbfa08a..000000000000
--- a/services/companion/java/com/android/server/companion/CompanionExemptionProcessor.java
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * 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.companion;
-
-import static android.app.AppOpsManager.MODE_ALLOWED;
-import static android.app.AppOpsManager.MODE_IGNORED;
-
-import static com.android.server.companion.utils.PackageUtils.getPackageInfo;
-
-import android.annotation.SuppressLint;
-import android.app.ActivityManagerInternal;
-import android.app.AppOpsManager;
-import android.companion.AssociationInfo;
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManagerInternal;
-import android.net.NetworkPolicyManager;
-import android.os.Binder;
-import android.os.Environment;
-import android.os.PowerExemptionManager;
-import android.util.ArraySet;
-import android.util.Slog;
-
-import com.android.internal.util.ArrayUtils;
-import com.android.server.LocalServices;
-import com.android.server.companion.association.AssociationStore;
-import com.android.server.pm.UserManagerInternal;
-import com.android.server.wm.ActivityTaskManagerInternal;
-
-import java.io.File;
-import java.util.List;
-import java.util.Set;
-
-@SuppressLint("LongLogTag")
-public class CompanionExemptionProcessor {
-
- private static final String TAG = "CDM_CompanionExemptionProcessor";
-
- private static final String PREF_FILE_NAME = "companion_device_preferences.xml";
- private static final String PREF_KEY_AUTO_REVOKE_GRANTS_DONE = "auto_revoke_grants_done";
-
- private final Context mContext;
- private final PowerExemptionManager mPowerExemptionManager;
- private final AppOpsManager mAppOpsManager;
- private final PackageManagerInternal mPackageManager;
- private final ActivityTaskManagerInternal mAtmInternal;
- private final ActivityManagerInternal mAmInternal;
- private final AssociationStore mAssociationStore;
-
- public CompanionExemptionProcessor(Context context, PowerExemptionManager powerExemptionManager,
- AppOpsManager appOpsManager, PackageManagerInternal packageManager,
- ActivityTaskManagerInternal atmInternal, ActivityManagerInternal amInternal,
- AssociationStore associationStore) {
- mContext = context;
- mPowerExemptionManager = powerExemptionManager;
- mAppOpsManager = appOpsManager;
- mPackageManager = packageManager;
- mAtmInternal = atmInternal;
- mAmInternal = amInternal;
- mAssociationStore = associationStore;
-
- mAssociationStore.registerLocalListener(new AssociationStore.OnChangeListener() {
- @Override
- public void onAssociationChanged(int changeType, AssociationInfo association) {
- final int userId = association.getUserId();
- final List<AssociationInfo> updatedAssociations =
- mAssociationStore.getActiveAssociationsByUser(userId);
-
- updateAtm(userId, updatedAssociations);
- }
- });
- }
-
- /**
- * Update ActivityManager and ActivityTaskManager exemptions
- */
- public void updateAtm(int userId, List<AssociationInfo> associations) {
- final Set<Integer> companionAppUids = new ArraySet<>();
- for (AssociationInfo association : associations) {
- int uid = mPackageManager.getPackageUid(association.getPackageName(), 0, userId);
- if (uid >= 0) {
- companionAppUids.add(uid);
- }
- }
- if (mAtmInternal != null) {
- mAtmInternal.setCompanionAppUids(userId, companionAppUids);
- }
- if (mAmInternal != null) {
- // Make a copy of the set and send it to ActivityManager.
- mAmInternal.setCompanionAppUids(userId, new ArraySet<>(companionAppUids));
- }
- }
-
- /**
- * Update special access for the association's package
- */
- public void exemptPackage(int userId, String packageName, boolean hasPresentDevices) {
- Slog.i(TAG, "Exempting package [" + packageName + "]...");
-
- final PackageInfo packageInfo = getPackageInfo(mContext, userId, packageName);
-
- Binder.withCleanCallingIdentity(
- () -> exemptPackageAsSystem(userId, packageInfo, hasPresentDevices));
- }
-
- @SuppressLint("MissingPermission")
- private void exemptPackageAsSystem(int userId, PackageInfo packageInfo,
- boolean hasPresentDevices) {
- if (packageInfo == null) {
- return;
- }
-
- // If the app has run-in-bg permission and present devices, add it to power saver allowlist.
- if (containsEither(packageInfo.requestedPermissions,
- android.Manifest.permission.RUN_IN_BACKGROUND,
- android.Manifest.permission.REQUEST_COMPANION_RUN_IN_BACKGROUND)
- && hasPresentDevices) {
- mPowerExemptionManager.addToPermanentAllowList(packageInfo.packageName);
- } else {
- try {
- mPowerExemptionManager.removeFromPermanentAllowList(packageInfo.packageName);
- } catch (UnsupportedOperationException e) {
- Slog.w(TAG, packageInfo.packageName + " can't be removed from power save"
- + " allowlist. It might be due to the package being allowlisted by the"
- + " system.");
- }
- }
-
- // If the app has run-in-bg permission and present device, allow metered network use.
- NetworkPolicyManager networkPolicyManager = NetworkPolicyManager.from(mContext);
- try {
- if (containsEither(packageInfo.requestedPermissions,
- android.Manifest.permission.USE_DATA_IN_BACKGROUND,
- android.Manifest.permission.REQUEST_COMPANION_USE_DATA_IN_BACKGROUND)
- && hasPresentDevices) {
- networkPolicyManager.addUidPolicy(
- packageInfo.applicationInfo.uid,
- NetworkPolicyManager.POLICY_ALLOW_METERED_BACKGROUND);
- } else {
- networkPolicyManager.removeUidPolicy(
- packageInfo.applicationInfo.uid,
- NetworkPolicyManager.POLICY_ALLOW_METERED_BACKGROUND);
- }
- } catch (IllegalArgumentException e) {
- Slog.e(TAG, e.getMessage());
- }
-
- updateAutoRevokeExemption(packageInfo.packageName, packageInfo.applicationInfo.uid,
- !mAssociationStore.getActiveAssociationsByPackage(userId,
- packageInfo.packageName).isEmpty());
- }
-
- /**
- * Update auto revoke exemptions.
- * If the app has any association, exempt it from permission auto revoke.
- */
- public void updateAutoRevokeExemptions() {
- Slog.d(TAG, "maybeGrantAutoRevokeExemptions()");
-
- PackageManager pm = mContext.getPackageManager();
- for (int userId : LocalServices.getService(UserManagerInternal.class).getUserIds()) {
- SharedPreferences pref = mContext.getSharedPreferences(
- new File(Environment.getUserSystemDirectory(userId), PREF_FILE_NAME),
- Context.MODE_PRIVATE);
- if (pref.getBoolean(PREF_KEY_AUTO_REVOKE_GRANTS_DONE, false)) {
- continue;
- }
-
- try {
- final List<AssociationInfo> associations =
- mAssociationStore.getActiveAssociationsByUser(userId);
- for (AssociationInfo a : associations) {
- try {
- int uid = pm.getPackageUidAsUser(a.getPackageName(), userId);
- updateAutoRevokeExemption(a.getPackageName(), uid, true);
- } catch (PackageManager.NameNotFoundException e) {
- Slog.w(TAG, "Unknown companion package: " + a.getPackageName(), e);
- }
- }
- } finally {
- pref.edit().putBoolean(PREF_KEY_AUTO_REVOKE_GRANTS_DONE, true).apply();
- }
- }
- }
-
- @SuppressLint("MissingPermission")
- private void updateAutoRevokeExemption(String packageName, int uid, boolean hasAssociations) {
- try {
- mAppOpsManager.setMode(
- AppOpsManager.OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED,
- uid,
- packageName,
- hasAssociations ? MODE_IGNORED : MODE_ALLOWED);
- } catch (Exception e) {
- Slog.e(TAG, "Error while granting auto revoke exemption for " + packageName, e);
- }
- }
-
- private <T> boolean containsEither(T[] array, T a, T b) {
- return ArrayUtils.contains(array, a) || ArrayUtils.contains(array, b);
- }
-
-}
diff --git a/services/companion/java/com/android/server/companion/devicepresence/CompanionAppBinder.java b/services/companion/java/com/android/server/companion/devicepresence/CompanionAppBinder.java
index 1eb6d13feeac..60f46887fa5c 100644
--- a/services/companion/java/com/android/server/companion/devicepresence/CompanionAppBinder.java
+++ b/services/companion/java/com/android/server/companion/devicepresence/CompanionAppBinder.java
@@ -95,10 +95,7 @@ public class CompanionAppBinder {
/**
* On package changed.
*/
- public void onPackagesChanged(@UserIdInt int userId, String packageName) {
- // TODO: We shouldn't need to clean up the whole user registry. We only need to remove the
- // package. I will do it in a separate change since it's not appropriate to use
- // PerUser anymore.
+ public void onPackagesChanged(@UserIdInt int userId) {
mCompanionServicesRegister.invalidate(userId);
}
diff --git a/services/companion/java/com/android/server/companion/devicepresence/DevicePresenceProcessor.java b/services/companion/java/com/android/server/companion/devicepresence/DevicePresenceProcessor.java
index 7b4dd7df8be3..a374d279af0b 100644
--- a/services/companion/java/com/android/server/companion/devicepresence/DevicePresenceProcessor.java
+++ b/services/companion/java/com/android/server/companion/devicepresence/DevicePresenceProcessor.java
@@ -57,7 +57,6 @@ import android.util.SparseBooleanArray;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.CollectionUtils;
-import com.android.server.companion.CompanionExemptionProcessor;
import com.android.server.companion.association.AssociationStore;
import java.io.PrintWriter;
@@ -102,8 +101,6 @@ public class DevicePresenceProcessor implements AssociationStore.OnChangeListene
private final PowerManagerInternal mPowerManagerInternal;
@NonNull
private final UserManager mUserManager;
- @NonNull
- private final CompanionExemptionProcessor mCompanionExemptionProcessor;
// NOTE: Same association may appear in more than one of the following sets at the same time.
// (E.g. self-managed devices that have MAC addresses, could be reported as present by their
@@ -114,7 +111,7 @@ public class DevicePresenceProcessor implements AssociationStore.OnChangeListene
@NonNull
private final Set<Integer> mNearbyBleDevices = new HashSet<>();
@NonNull
- private final Set<Integer> mConnectedSelfManagedDevices = new HashSet<>();
+ private final Set<Integer> mReportedSelfManagedDevices = new HashSet<>();
@NonNull
private final Set<ParcelUuid> mConnectedUuidDevices = new HashSet<>();
@NonNull
@@ -149,8 +146,7 @@ public class DevicePresenceProcessor implements AssociationStore.OnChangeListene
@NonNull UserManager userManager,
@NonNull AssociationStore associationStore,
@NonNull ObservableUuidStore observableUuidStore,
- @NonNull PowerManagerInternal powerManagerInternal,
- @NonNull CompanionExemptionProcessor companionExemptionProcessor) {
+ @NonNull PowerManagerInternal powerManagerInternal) {
mContext = context;
mCompanionAppBinder = companionAppBinder;
mAssociationStore = associationStore;
@@ -160,7 +156,6 @@ public class DevicePresenceProcessor implements AssociationStore.OnChangeListene
mObservableUuidStore, this);
mBleDeviceProcessor = new BleDeviceProcessor(associationStore, this);
mPowerManagerInternal = powerManagerInternal;
- mCompanionExemptionProcessor = companionExemptionProcessor;
}
/** Initialize {@link DevicePresenceProcessor} */
@@ -409,7 +404,7 @@ public class DevicePresenceProcessor implements AssociationStore.OnChangeListene
* nearby (for "self-managed" associations).
*/
public boolean isDevicePresent(int associationId) {
- return mConnectedSelfManagedDevices.contains(associationId)
+ return mReportedSelfManagedDevices.contains(associationId)
|| mConnectedBtDevices.contains(associationId)
|| mNearbyBleDevices.contains(associationId)
|| mSimulated.contains(associationId);
@@ -456,7 +451,7 @@ public class DevicePresenceProcessor implements AssociationStore.OnChangeListene
* notifyDeviceAppeared()}
*/
public void onSelfManagedDeviceConnected(int associationId) {
- onDevicePresenceEvent(mConnectedSelfManagedDevices,
+ onDevicePresenceEvent(mReportedSelfManagedDevices,
associationId, EVENT_SELF_MANAGED_APPEARED);
}
@@ -472,7 +467,7 @@ public class DevicePresenceProcessor implements AssociationStore.OnChangeListene
* notifyDeviceDisappeared()}
*/
public void onSelfManagedDeviceDisconnected(int associationId) {
- onDevicePresenceEvent(mConnectedSelfManagedDevices,
+ onDevicePresenceEvent(mReportedSelfManagedDevices,
associationId, EVENT_SELF_MANAGED_DISAPPEARED);
}
@@ -480,7 +475,7 @@ public class DevicePresenceProcessor implements AssociationStore.OnChangeListene
* Marks a "self-managed" device as disconnected when binderDied.
*/
public void onSelfManagedDeviceReporterBinderDied(int associationId) {
- onDevicePresenceEvent(mConnectedSelfManagedDevices,
+ onDevicePresenceEvent(mReportedSelfManagedDevices,
associationId, EVENT_SELF_MANAGED_DISAPPEARED);
}
@@ -688,7 +683,6 @@ public class DevicePresenceProcessor implements AssociationStore.OnChangeListene
if (association.shouldBindWhenPresent()) {
bindApplicationIfNeeded(userId, packageName, association.isSelfManaged());
- mCompanionExemptionProcessor.exemptPackage(userId, packageName, true);
} else {
return;
}
@@ -721,7 +715,6 @@ public class DevicePresenceProcessor implements AssociationStore.OnChangeListene
// Check if there are other devices associated to the app that are present.
if (!shouldBindPackage(userId, packageName)) {
mCompanionAppBinder.unbindCompanionApp(userId, packageName);
- mCompanionExemptionProcessor.exemptPackage(userId, packageName, false);
}
break;
default:
@@ -947,7 +940,7 @@ public class DevicePresenceProcessor implements AssociationStore.OnChangeListene
mConnectedBtDevices.remove(id);
mNearbyBleDevices.remove(id);
- mConnectedSelfManagedDevices.remove(id);
+ mReportedSelfManagedDevices.remove(id);
mSimulated.remove(id);
synchronized (mBtDisconnectedDevices) {
mBtDisconnectedDevices.remove(id);
@@ -1107,7 +1100,7 @@ public class DevicePresenceProcessor implements AssociationStore.OnChangeListene
out.append("Companion Device Present: ");
if (mConnectedBtDevices.isEmpty()
&& mNearbyBleDevices.isEmpty()
- && mConnectedSelfManagedDevices.isEmpty()) {
+ && mReportedSelfManagedDevices.isEmpty()) {
out.append("<empty>\n");
return;
} else {
@@ -1137,11 +1130,11 @@ public class DevicePresenceProcessor implements AssociationStore.OnChangeListene
}
out.append(" Self-Reported Devices: ");
- if (mConnectedSelfManagedDevices.isEmpty()) {
+ if (mReportedSelfManagedDevices.isEmpty()) {
out.append("<empty>\n");
} else {
out.append("\n");
- for (int associationId : mConnectedSelfManagedDevices) {
+ for (int associationId : mReportedSelfManagedDevices) {
AssociationInfo a = mAssociationStore.getAssociationById(associationId);
out.append(" ").append(a.toShortString()).append('\n');
}
diff --git a/services/core/Android.bp b/services/core/Android.bp
index 348d83fea81d..6cfd44bb2d1a 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -126,6 +126,7 @@ java_library_static {
"platform_service_defaults",
"android.hardware.power-java_shared",
"latest_android_hardware_broadcastradio_java_static",
+ "services_crashrecovery_stubs_conditionally",
],
srcs: [
":android.hardware.tv.hdmi.connection-V1-java-source",
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 2a9cb435e01d..1c3569dd52d0 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -60,7 +60,6 @@ import static android.app.ProcessMemoryState.HOSTING_COMPONENT_TYPE_BACKUP;
import static android.app.ProcessMemoryState.HOSTING_COMPONENT_TYPE_INSTRUMENTATION;
import static android.app.ProcessMemoryState.HOSTING_COMPONENT_TYPE_PERSISTENT;
import static android.app.ProcessMemoryState.HOSTING_COMPONENT_TYPE_SYSTEM;
-import static android.content.Intent.isPreventIntentRedirectEnabled;
import static android.content.pm.ApplicationInfo.HIDDEN_API_ENFORCEMENT_DEFAULT;
import static android.content.pm.PackageManager.GET_SHARED_LIBRARY_FILES;
import static android.content.pm.PackageManager.MATCH_ALL;
@@ -131,6 +130,7 @@ import static android.os.Process.setThreadScheduler;
import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
import static android.provider.Settings.Global.DEBUG_APP;
import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
+import static android.security.Flags.preventIntentRedirect;
import static android.util.FeatureFlagUtils.SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS;
import static android.view.Display.INVALID_DISPLAY;
@@ -14301,6 +14301,10 @@ public class ActivityManagerService extends IActivityManager.Stub
mBroadcastController.unregisterReceiver(receiver);
}
+ public List<IntentFilter> getRegisteredIntentFilters(IIntentReceiver receiver) {
+ return mBroadcastController.getRegisteredIntentFilters(receiver);
+ }
+
@GuardedBy("this")
final int broadcastIntentLocked(ProcessRecord callerApp,
String callerPackage, String callerFeatureId, Intent intent, String resolvedType,
@@ -19281,7 +19285,7 @@ public class ActivityManagerService extends IActivityManager.Stub
* @hide
*/
public void addCreatorToken(@Nullable Intent intent, String creatorPackage) {
- if (!isPreventIntentRedirectEnabled()) return;
+ if (!preventIntentRedirect()) return;
if (intent == null || intent.getExtraIntentKeys() == null) return;
for (String key : intent.getExtraIntentKeys()) {
diff --git a/services/core/java/com/android/server/am/BroadcastController.java b/services/core/java/com/android/server/am/BroadcastController.java
index 71ddf05eb692..b0f880710eb6 100644
--- a/services/core/java/com/android/server/am/BroadcastController.java
+++ b/services/core/java/com/android/server/am/BroadcastController.java
@@ -679,6 +679,21 @@ class BroadcastController {
}
}
+ List<IntentFilter> getRegisteredIntentFilters(IIntentReceiver receiver) {
+ synchronized (mService) {
+ final ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
+ if (rl == null) {
+ return null;
+ }
+ final ArrayList<IntentFilter> filters = new ArrayList<>();
+ final int count = rl.size();
+ for (int i = 0; i < count; ++i) {
+ filters.add(rl.get(i));
+ }
+ return filters;
+ }
+ }
+
int broadcastIntentWithFeature(IApplicationThread caller, String callingFeatureId,
Intent intent, String resolvedType, IIntentReceiver resultTo,
int resultCode, String resultData, Bundle resultExtras,
diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
index 7cfe8292d52f..bcde1ffe87d6 100644
--- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
+++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
@@ -209,6 +209,7 @@ public class SettingsToPropertiesMapper {
"pixel_perf",
"pixel_sensors",
"pixel_system_sw_video",
+ "pixel_video_sw",
"pixel_watch",
"platform_compat",
"platform_security",
diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
index 906e584af1ad..a3b20b93ef02 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
@@ -693,6 +693,8 @@ public class AudioDeviceBroker {
elapsed = System.currentTimeMillis() - start;
if (elapsed >= SET_COMMUNICATION_DEVICE_TIMEOUT_MS) {
Log.e(TAG, "Timeout waiting for communication device update.");
+ // reset counter to avoid sticky out of sync condition
+ mCommunicationDeviceUpdateCount = 0;
break;
}
}
@@ -1342,8 +1344,8 @@ public class AudioDeviceBroker {
}
/*package*/ void postSetModeOwner(int mode, int pid, int uid, boolean signal) {
- sendILMsgNoDelay(MSG_IL_SET_MODE_OWNER, SENDMSG_REPLACE,
- signal ? 1 : 0, new AudioModeInfo(mode, pid, uid));
+ sendLMsgNoDelay(signal ? MSG_L_SET_MODE_OWNER_SIGNAL : MSG_L_SET_MODE_OWNER,
+ SENDMSG_REPLACE, new AudioModeInfo(mode, pid, uid));
}
/*package*/ void postBluetoothDeviceConfigChange(@NonNull BtDeviceInfo info) {
@@ -2026,7 +2028,8 @@ public class AudioDeviceBroker {
mBtHelper.setAvrcpAbsoluteVolumeIndex(msg.arg1);
}
break;
- case MSG_IL_SET_MODE_OWNER:
+ case MSG_L_SET_MODE_OWNER:
+ case MSG_L_SET_MODE_OWNER_SIGNAL:
synchronized (mSetModeLock) {
synchronized (mDeviceStateLock) {
mAudioModeOwner = (AudioModeInfo) msg.obj;
@@ -2037,7 +2040,7 @@ public class AudioDeviceBroker {
}
}
}
- if (msg.arg1 == 1 /*signal*/) {
+ if (msg.what == MSG_L_SET_MODE_OWNER_SIGNAL) {
mAudioService.decrementAudioModeResetCount();
}
break;
@@ -2199,7 +2202,8 @@ public class AudioDeviceBroker {
private static final int MSG_REPORT_NEW_ROUTES = 13;
private static final int MSG_II_SET_HEARING_AID_VOLUME = 14;
private static final int MSG_I_SET_AVRCP_ABSOLUTE_VOLUME = 15;
- private static final int MSG_IL_SET_MODE_OWNER = 16;
+ private static final int MSG_L_SET_MODE_OWNER = 16;
+ private static final int MSG_L_SET_MODE_OWNER_SIGNAL = 17;
private static final int MSG_I_BT_SERVICE_DISCONNECTED_PROFILE = 22;
private static final int MSG_IL_BT_SERVICE_CONNECTED_PROFILE = 23;
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 3dbe48a2e540..985155d0d891 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -457,7 +457,7 @@ public class AudioService extends IAudioService.Stub
private static final int MSG_UPDATE_AUDIO_MODE = 36;
private static final int MSG_RECORDING_CONFIG_CHANGE = 37;
private static final int MSG_BT_DEV_CHANGED = 38;
-
+ private static final int MSG_UPDATE_AUDIO_MODE_SIGNAL = 39;
private static final int MSG_DISPATCH_AUDIO_MODE = 40;
private static final int MSG_ROUTING_UPDATED = 41;
private static final int MSG_INIT_HEADTRACKING_SENSORS = 42;
@@ -4804,16 +4804,14 @@ public class AudioService extends IAudioService.Stub
}
static class UpdateAudioModeInfo {
- UpdateAudioModeInfo(int mode, int pid, String packageName, boolean signal) {
+ UpdateAudioModeInfo(int mode, int pid, String packageName) {
mMode = mode;
mPid = pid;
mPackageName = packageName;
- mSignal = signal;
}
private final int mMode;
private final int mPid;
private final String mPackageName;
- private final boolean mSignal;
int getMode() {
return mMode;
@@ -4824,9 +4822,6 @@ public class AudioService extends IAudioService.Stub
String getPackageName() {
return mPackageName;
}
- boolean getSignal() {
- return mSignal;
- }
}
void postUpdateAudioMode(int msgPolicy, int mode, int pid, String packageName,
@@ -4835,8 +4830,8 @@ public class AudioService extends IAudioService.Stub
if (signal) {
mAudioModeResetCount++;
}
- sendMsg(mAudioHandler, MSG_UPDATE_AUDIO_MODE, msgPolicy, 0, 0,
- new UpdateAudioModeInfo(mode, pid, packageName, signal), delay);
+ sendMsg(mAudioHandler, signal ? MSG_UPDATE_AUDIO_MODE_SIGNAL : MSG_UPDATE_AUDIO_MODE,
+ msgPolicy, 0, 0, new UpdateAudioModeInfo(mode, pid, packageName), delay);
}
}
@@ -6654,6 +6649,9 @@ public class AudioService extends IAudioService.Stub
// connections not started by the application changing the mode when pid changes
mDeviceBroker.postSetModeOwner(mode, pid, uid, signal);
} else {
+ // reset here to avoid sticky out of sync condition (would have been reset
+ // by AudioDeviceBroker processing MSG_L_SET_MODE_OWNER_SIGNAL message)
+ resetAudioModeResetCount();
Log.w(TAG, "onUpdateAudioMode: failed to set audio mode to: " + mode);
}
}
@@ -10420,10 +10418,11 @@ public class AudioService extends IAudioService.Stub
break;
case MSG_UPDATE_AUDIO_MODE:
+ case MSG_UPDATE_AUDIO_MODE_SIGNAL:
synchronized (mDeviceBroker.mSetModeLock) {
UpdateAudioModeInfo info = (UpdateAudioModeInfo) msg.obj;
onUpdateAudioMode(info.getMode(), info.getPid(), info.getPackageName(),
- false /*force*/, info.getSignal());
+ false /*force*/, msg.what == MSG_UPDATE_AUDIO_MODE_SIGNAL);
}
break;
@@ -11164,6 +11163,8 @@ public class AudioService extends IAudioService.Stub
elapsed = java.lang.System.currentTimeMillis() - start;
if (elapsed >= AUDIO_MODE_RESET_TIMEOUT_MS) {
Log.e(TAG, "Timeout waiting for audio mode reset");
+ // reset count to avoid sticky out of sync state.
+ resetAudioModeResetCount();
break;
}
}
@@ -11175,7 +11176,7 @@ public class AudioService extends IAudioService.Stub
return mMediaFocusControl.abandonAudioFocus(fd, clientId, aa, callingPackageName);
}
- /** synchronization between setMode(NORMAL) and abandonAudioFocus() frmo Telecom */
+ /** synchronization between setMode(NORMAL) and abandonAudioFocus() from Telecom */
private static final long AUDIO_MODE_RESET_TIMEOUT_MS = 3000;
private final Object mAudioModeResetLock = new Object();
@@ -11194,6 +11195,13 @@ public class AudioService extends IAudioService.Stub
}
}
+ private void resetAudioModeResetCount() {
+ synchronized (mAudioModeResetLock) {
+ mAudioModeResetCount = 0;
+ mAudioModeResetLock.notify();
+ }
+ }
+
/** see {@link AudioManager#abandonAudioFocusForTest(AudioFocusRequest, String)} */
public int abandonAudioFocusForTest(IAudioFocusDispatcher fd, String clientId,
AudioAttributes aa, String callingPackageName) {
diff --git a/services/core/java/com/android/server/audio/MediaFocusControl.java b/services/core/java/com/android/server/audio/MediaFocusControl.java
index 1604e94e5a6d..1da62d74f0df 100644
--- a/services/core/java/com/android/server/audio/MediaFocusControl.java
+++ b/services/core/java/com/android/server/audio/MediaFocusControl.java
@@ -1068,7 +1068,6 @@ public class MediaFocusControl implements PlayerFocusEnforcer {
switch (attr.getUsage()) {
case AudioAttributes.USAGE_MEDIA:
case AudioAttributes.USAGE_GAME:
- case AudioAttributes.USAGE_SPEAKER_CLEANUP:
return 1000;
case AudioAttributes.USAGE_ALARM:
case AudioAttributes.USAGE_NOTIFICATION_RINGTONE:
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 3603cdbd775f..f5a75c7d1c38 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -25,7 +25,7 @@ import static android.Manifest.permission.MANAGE_DISPLAYS;
import static android.Manifest.permission.RESTRICT_DISPLAY_MODES;
import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_CACHED;
import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE;
-import static android.hardware.display.DisplayManager.EventsMask;
+import static android.hardware.display.DisplayManager.EventFlag;
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_ALWAYS_UNLOCKED;
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR;
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD;
@@ -1390,16 +1390,16 @@ public final class DisplayManagerService extends SystemService {
}
private void registerCallbackInternal(IDisplayManagerCallback callback, int callingPid,
- int callingUid, @EventsMask long eventsMask) {
+ int callingUid, @EventFlag long eventFlagsMask) {
synchronized (mSyncRoot) {
CallbackRecord record = mCallbacks.get(callingPid);
if (record != null) {
- record.updateEventsMask(eventsMask);
+ record.updateEventFlagsMask(eventFlagsMask);
return;
}
- record = new CallbackRecord(callingPid, callingUid, callback, eventsMask);
+ record = new CallbackRecord(callingPid, callingUid, callback, eventFlagsMask);
try {
IBinder binder = callback.asBinder();
binder.linkToDeath(record, 0);
@@ -1889,6 +1889,7 @@ public final class DisplayManagerService extends SystemService {
final String displayUniqueId = VirtualDisplayAdapter.generateDisplayUniqueId(
packageName, callingUid, virtualDisplayConfig);
+ boolean shouldClearDisplayWindowSettings = false;
if (virtualDisplayConfig.isHomeSupported()) {
if ((flags & VIRTUAL_DISPLAY_FLAG_TRUSTED) == 0) {
Slog.w(TAG, "Display created with home support but lacks "
@@ -1900,6 +1901,18 @@ public final class DisplayManagerService extends SystemService {
} else {
mWindowManagerInternal.setHomeSupportedOnDisplay(displayUniqueId,
Display.TYPE_VIRTUAL, true);
+ shouldClearDisplayWindowSettings = true;
+ }
+ }
+
+ if (virtualDisplayConfig.isIgnoreActivitySizeRestrictions()) {
+ if ((flags & VIRTUAL_DISPLAY_FLAG_TRUSTED) == 0) {
+ Slog.w(TAG, "Display created to ignore activity size restrictions, "
+ + "but lacks VIRTUAL_DISPLAY_FLAG_TRUSTED, ignoring the request.");
+ } else {
+ mWindowManagerInternal.setIgnoreActivitySizeRestrictionsOnDisplay(
+ displayUniqueId, Display.TYPE_VIRTUAL, true);
+ shouldClearDisplayWindowSettings = true;
}
}
@@ -1922,8 +1935,7 @@ public final class DisplayManagerService extends SystemService {
}
}
- if (displayId == Display.INVALID_DISPLAY && virtualDisplayConfig.isHomeSupported()
- && (flags & VIRTUAL_DISPLAY_FLAG_TRUSTED) != 0) {
+ if (displayId == Display.INVALID_DISPLAY && shouldClearDisplayWindowSettings) {
// Failed to create the virtual display, so we should clean up the WM settings
// because it won't receive the onDisplayRemoved callback.
mWindowManagerInternal.clearDisplaySettings(displayUniqueId, Display.TYPE_VIRTUAL);
@@ -3997,7 +4009,7 @@ public final class DisplayManagerService extends SystemService {
public final int mPid;
public final int mUid;
private final IDisplayManagerCallback mCallback;
- private @EventsMask AtomicLong mEventsMask;
+ private @DisplayManager.EventFlag AtomicLong mEventFlagsMask;
private final String mPackageName;
public boolean mWifiDisplayScanRequested;
@@ -4018,11 +4030,11 @@ public final class DisplayManagerService extends SystemService {
private boolean mFrozen;
CallbackRecord(int pid, int uid, @NonNull IDisplayManagerCallback callback,
- @EventsMask long eventsMask) {
+ @EventFlag long eventFlagsMask) {
mPid = pid;
mUid = uid;
mCallback = callback;
- mEventsMask = new AtomicLong(eventsMask);
+ mEventFlagsMask = new AtomicLong(eventFlagsMask);
mCached = false;
mFrozen = false;
@@ -4044,8 +4056,8 @@ public final class DisplayManagerService extends SystemService {
mPackageName = packageNames == null ? null : packageNames[0];
}
- public void updateEventsMask(@EventsMask long eventsMask) {
- mEventsMask.set(eventsMask);
+ public void updateEventFlagsMask(@EventFlag long eventFlag) {
+ mEventFlagsMask.set(eventFlag);
}
/**
@@ -4109,12 +4121,13 @@ public final class DisplayManagerService extends SystemService {
if (!shouldSendEvent(event)) {
if (extraLogging(mPackageName)) {
Slog.i(TAG,
- "Not sending displayEvent: " + event + " due to mask:" + mEventsMask);
+ "Not sending displayEvent: " + event + " due to flag:"
+ + mEventFlagsMask);
}
if (Trace.isTagEnabled(Trace.TRACE_TAG_POWER)) {
Trace.instant(Trace.TRACE_TAG_POWER,
- "notifyDisplayEventAsync#notSendingEvent=" + event + ",mEventsMask="
- + mEventsMask);
+ "notifyDisplayEventAsync#notSendingEvent=" + event + ",mEventsFlag="
+ + mEventFlagsMask);
}
// The client is not interested in this event, so do nothing.
return true;
@@ -4160,22 +4173,22 @@ public final class DisplayManagerService extends SystemService {
* Return true if the client is interested in this event.
*/
private boolean shouldSendEvent(@DisplayEvent int event) {
- final long mask = mEventsMask.get();
+ final long flag = mEventFlagsMask.get();
switch (event) {
case DisplayManagerGlobal.EVENT_DISPLAY_ADDED:
- return (mask & DisplayManager.EVENT_FLAG_DISPLAY_ADDED) != 0;
+ return (flag & DisplayManager.EVENT_FLAG_DISPLAY_ADDED) != 0;
case DisplayManagerGlobal.EVENT_DISPLAY_CHANGED:
- return (mask & DisplayManager.EVENT_FLAG_DISPLAY_CHANGED) != 0;
+ return (flag & DisplayManager.EVENT_FLAG_DISPLAY_CHANGED) != 0;
case DisplayManagerGlobal.EVENT_DISPLAY_BRIGHTNESS_CHANGED:
- return (mask & DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS) != 0;
+ return (flag & DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS) != 0;
case DisplayManagerGlobal.EVENT_DISPLAY_REMOVED:
- return (mask & DisplayManager.EVENT_FLAG_DISPLAY_REMOVED) != 0;
+ return (flag & DisplayManager.EVENT_FLAG_DISPLAY_REMOVED) != 0;
case DisplayManagerGlobal.EVENT_DISPLAY_HDR_SDR_RATIO_CHANGED:
- return (mask & DisplayManager.EVENT_FLAG_HDR_SDR_RATIO_CHANGED) != 0;
+ return (flag & DisplayManager.EVENT_FLAG_HDR_SDR_RATIO_CHANGED) != 0;
case DisplayManagerGlobal.EVENT_DISPLAY_CONNECTED:
// fallthrough
case DisplayManagerGlobal.EVENT_DISPLAY_DISCONNECTED:
- return (mask & DisplayManager.EVENT_FLAG_DISPLAY_CONNECTION_CHANGED) != 0;
+ return (flag & DisplayManager.EVENT_FLAG_DISPLAY_CONNECTION_CHANGED) != 0;
default:
// This should never happen.
Slog.e(TAG, "Unknown display event " + event);
@@ -4369,7 +4382,7 @@ public final class DisplayManagerService extends SystemService {
@Override // Binder call
@SuppressLint("AndroidFrameworkRequiresPermission") // Permission only required sometimes
public void registerCallbackWithEventMask(IDisplayManagerCallback callback,
- @EventsMask long eventsMask) {
+ @EventFlag long eventFlagsMask) {
if (callback == null) {
throw new IllegalArgumentException("listener must not be null");
}
@@ -4378,7 +4391,7 @@ public final class DisplayManagerService extends SystemService {
final int callingUid = Binder.getCallingUid();
if (mFlags.isConnectedDisplayManagementEnabled()) {
- if ((eventsMask & DisplayManager.EVENT_FLAG_DISPLAY_CONNECTION_CHANGED) != 0) {
+ if ((eventFlagsMask & DisplayManager.EVENT_FLAG_DISPLAY_CONNECTION_CHANGED) != 0) {
mContext.enforceCallingOrSelfPermission(MANAGE_DISPLAYS,
"Permission required to get signals about connection events.");
}
@@ -4386,7 +4399,7 @@ public final class DisplayManagerService extends SystemService {
final long token = Binder.clearCallingIdentity();
try {
- registerCallbackInternal(callback, callingPid, callingUid, eventsMask);
+ registerCallbackInternal(callback, callingPid, callingUid, eventFlagsMask);
} finally {
Binder.restoreCallingIdentity(token);
}
diff --git a/services/core/java/com/android/server/input/KeyGestureController.java b/services/core/java/com/android/server/input/KeyGestureController.java
index 68eaf7242d04..e665f96ab282 100644
--- a/services/core/java/com/android/server/input/KeyGestureController.java
+++ b/services/core/java/com/android/server/input/KeyGestureController.java
@@ -25,6 +25,7 @@ import static com.android.hardware.input.Flags.useKeyGestureEventHandler;
import static com.android.hardware.input.Flags.useKeyGestureEventHandlerMultiPressGestures;
import static com.android.server.flags.Flags.newBugreportKeyboardShortcut;
import static com.android.window.flags.Flags.enableMoveToNextDisplayShortcut;
+import static com.android.window.flags.Flags.enableTaskResizingKeyboardShortcuts;
import android.annotation.BinderThread;
import android.annotation.MainThread;
@@ -734,6 +735,54 @@ final class KeyGestureController {
}
}
break;
+ case KeyEvent.KEYCODE_LEFT_BRACKET:
+ if (enableTaskResizingKeyboardShortcuts()) {
+ if (firstDown && event.isAltPressed()) {
+ return handleKeyGesture(deviceId, new int[]{keyCode},
+ KeyEvent.META_ALT_ON,
+ KeyGestureEvent.KEY_GESTURE_TYPE_SNAP_LEFT_FREEFORM_WINDOW,
+ KeyGestureEvent.ACTION_GESTURE_COMPLETE,
+ displayId,
+ focusedToken, /* flags = */0);
+ }
+ }
+ break;
+ case KeyEvent.KEYCODE_RIGHT_BRACKET:
+ if (enableTaskResizingKeyboardShortcuts()) {
+ if (firstDown && event.isAltPressed()) {
+ return handleKeyGesture(deviceId, new int[]{keyCode},
+ KeyEvent.META_ALT_ON,
+ KeyGestureEvent.KEY_GESTURE_TYPE_SNAP_RIGHT_FREEFORM_WINDOW,
+ KeyGestureEvent.ACTION_GESTURE_COMPLETE,
+ displayId,
+ focusedToken, /* flags = */0);
+ }
+ }
+ break;
+ case KeyEvent.KEYCODE_EQUALS:
+ if (enableTaskResizingKeyboardShortcuts()) {
+ if (firstDown && event.isAltPressed()) {
+ return handleKeyGesture(deviceId, new int[]{keyCode},
+ KeyEvent.META_ALT_ON,
+ KeyGestureEvent.KEY_GESTURE_TYPE_MAXIMIZE_FREEFORM_WINDOW,
+ KeyGestureEvent.ACTION_GESTURE_COMPLETE,
+ displayId,
+ focusedToken, /* flags = */0);
+ }
+ }
+ break;
+ case KeyEvent.KEYCODE_MINUS:
+ if (enableTaskResizingKeyboardShortcuts()) {
+ if (firstDown && event.isAltPressed()) {
+ return handleKeyGesture(deviceId, new int[]{keyCode},
+ KeyEvent.META_ALT_ON,
+ KeyGestureEvent.KEY_GESTURE_TYPE_RESTORE_FREEFORM_WINDOW_SIZE,
+ KeyGestureEvent.ACTION_GESTURE_COMPLETE,
+ displayId,
+ focusedToken, /* flags = */0);
+ }
+ }
+ break;
case KeyEvent.KEYCODE_SLASH:
if (firstDown && event.isMetaPressed()) {
return handleKeyGesture(deviceId, new int[]{keyCode}, KeyEvent.META_META_ON,
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index 8798a64ec479..45885f0399c4 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -253,10 +253,10 @@ public class LockSettingsService extends ILockSettings.Stub {
private static final String MIGRATED_FRP2 = "migrated_frp2";
private static final String MIGRATED_KEYSTORE_NS = "migrated_keystore_namespace";
- private static final String MIGRATED_SP_CE_ONLY = "migrated_all_users_to_sp_and_bound_ce";
private static final String MIGRATED_SP_FULL = "migrated_all_users_to_sp_and_bound_keys";
private static final String MIGRATED_WEAVER_DISABLED_ON_UNSECURED_USERS =
"migrated_weaver_disabled_on_unsecured_users";
+ // Note: some other migrated_* strings used to be used and may exist in the database already.
// Duration that LockSettingsService will store the gatekeeper password for. This allows
// multiple biometric enrollments without prompting the user to enter their password via
@@ -1219,21 +1219,16 @@ public class LockSettingsService extends ILockSettings.Stub {
Slog.i(TAG, "Synthetic password is already not protected by Weaver");
}
} else if (sp == null) {
- Slogf.wtf(TAG, "Failed to unwrap synthetic password for unsecured user %d", userId);
- return;
+ throw new IllegalStateException(
+ "Failed to unwrap synthetic password for unsecured user " + userId);
}
// Call setCeStorageProtection(), to re-encrypt the CE key with the SP if it's currently
- // encrypted by an empty secret. Skip this if it was definitely already done as part of the
- // upgrade to Android 14, since while setCeStorageProtection() is idempotent it does log
- // some error messages when called again. Do not skip this if
- // config_disableWeaverOnUnsecuredUsers=true, since in that case we'd like to recover from
- // the case where an earlier upgrade to Android 14 incorrectly skipped this step.
- if (getString(MIGRATED_SP_CE_ONLY, null, 0) == null
- || isWeaverDisabledOnUnsecuredUsers()) {
- Slogf.i(TAG, "Encrypting CE key of user %d with synthetic password", userId);
- setCeStorageProtection(userId, sp);
- }
+ // encrypted by an empty secret. If the CE key is already encrypted by the SP, then this is
+ // a no-op except for some log messages.
+ Slogf.i(TAG, "Encrypting CE key of user %d with synthetic password", userId);
+ setCeStorageProtection(userId, sp);
+
Slogf.i(TAG, "Initializing Keystore super keys for user %d", userId);
initKeystoreSuperKeys(userId, sp, /* allowExisting= */ true);
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 62df825617cd..849f236916a6 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -105,6 +105,7 @@ import static android.os.UserHandle.USER_SYSTEM;
import static android.service.notification.Adjustment.KEY_TYPE;
import static android.service.notification.Adjustment.TYPE_CONTENT_RECOMMENDATION;
import static android.service.notification.Adjustment.TYPE_PROMOTION;
+import static android.service.notification.Flags.FLAG_NOTIFICATION_CONVERSATION_CHANNEL_MANAGEMENT;
import static android.service.notification.Flags.callstyleCallbackApi;
import static android.service.notification.Flags.notificationClassification;
import static android.service.notification.Flags.notificationForceGrouping;
@@ -6681,6 +6682,33 @@ public class NotificationManagerService extends SystemService {
}
@Override
+ @FlaggedApi(FLAG_NOTIFICATION_CONVERSATION_CHANNEL_MANAGEMENT)
+ public NotificationChannel createConversationNotificationChannelForPackageFromPrivilegedListener(
+ INotificationListener token, String pkg, UserHandle user,
+ String parentId, String conversationId) throws RemoteException {
+ Objects.requireNonNull(pkg);
+ Objects.requireNonNull(user);
+ Objects.requireNonNull(parentId);
+ Objects.requireNonNull(conversationId);
+
+ verifyPrivilegedListener(token, user, true);
+
+ int uid = getUidForPackageAndUser(pkg, user);
+ NotificationChannel conversationChannel =
+ mPreferencesHelper.getNotificationChannel(pkg, uid, parentId, false).copy();
+ String conversationChannelId = String.format(
+ CONVERSATION_CHANNEL_ID_FORMAT, parentId, conversationId);
+ conversationChannel.setId(conversationChannelId);
+ conversationChannel.setConversationId(parentId, conversationId);
+ createNotificationChannelsImpl(
+ pkg, uid, new ParceledListSlice(Arrays.asList(conversationChannel)));
+ handleSavePolicyFile();
+
+ return mPreferencesHelper.getConversationNotificationChannel(
+ pkg, uid, parentId, conversationId, false, false).copy();
+ }
+
+ @Override
public void updateNotificationChannelGroupFromPrivilegedListener(
INotificationListener token, String pkg, UserHandle user,
NotificationChannelGroup group) throws RemoteException {
@@ -6698,7 +6726,7 @@ public class NotificationManagerService extends SystemService {
Objects.requireNonNull(pkg);
Objects.requireNonNull(user);
- verifyPrivilegedListener(token, user, false);
+ verifyPrivilegedListener(token, user, true);
final NotificationChannel originalChannel = mPreferencesHelper.getNotificationChannel(
pkg, getUidForPackageAndUser(pkg, user), channel.getId(), true);
diff --git a/services/core/java/com/android/server/pm/BroadcastHelper.java b/services/core/java/com/android/server/pm/BroadcastHelper.java
index 84a5f2b0e8bc..9f4b9f1c1f24 100644
--- a/services/core/java/com/android/server/pm/BroadcastHelper.java
+++ b/services/core/java/com/android/server/pm/BroadcastHelper.java
@@ -64,6 +64,9 @@ import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
+import com.android.internal.pm.pkg.component.ParsedActivity;
+import com.android.internal.pm.pkg.component.ParsedProvider;
+import com.android.internal.pm.pkg.component.ParsedService;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FrameworkStatsLog;
import com.android.server.pm.pkg.AndroidPackage;
@@ -80,6 +83,8 @@ import java.util.function.BiFunction;
*/
public final class BroadcastHelper {
private static final boolean DEBUG_BROADCASTS = false;
+ private static final String PERMISSION_PACKAGE_CHANGED_BROADCAST_ON_COMPONENT_STATE_CHANGED =
+ "android.permission.INTERNAL_RECEIVE_PACKAGE_CHANGED_BROADCAST_ON_COMPONENT_STATE_CHANGED";
private final UserManagerInternal mUmInternal;
private final ActivityManagerInternal mAmInternal;
@@ -291,6 +296,57 @@ public final class BroadcastHelper {
return bOptions;
}
+ private ArrayList<String> getAllNotExportedComponents(@NonNull AndroidPackage pkg,
+ @NonNull ArrayList<String> inputComponentNames) {
+ final ArrayList<String> outputNotExportedComponentNames = new ArrayList<>();
+ int remainingComponentCount = inputComponentNames.size();
+ for (ParsedActivity component : pkg.getReceivers()) {
+ if (inputComponentNames.contains(component.getClassName())) {
+ if (!component.isExported()) {
+ outputNotExportedComponentNames.add(component.getClassName());
+ }
+ remainingComponentCount--;
+ if (remainingComponentCount <= 0) {
+ return outputNotExportedComponentNames;
+ }
+ }
+ }
+ for (ParsedProvider component : pkg.getProviders()) {
+ if (inputComponentNames.contains(component.getClassName())) {
+ if (!component.isExported()) {
+ outputNotExportedComponentNames.add(component.getClassName());
+ }
+ remainingComponentCount--;
+ if (remainingComponentCount <= 0) {
+ return outputNotExportedComponentNames;
+ }
+ }
+ }
+ for (ParsedService component : pkg.getServices()) {
+ if (inputComponentNames.contains(component.getClassName())) {
+ if (!component.isExported()) {
+ outputNotExportedComponentNames.add(component.getClassName());
+ }
+ remainingComponentCount--;
+ if (remainingComponentCount <= 0) {
+ return outputNotExportedComponentNames;
+ }
+ }
+ }
+ for (ParsedActivity component : pkg.getActivities()) {
+ if (inputComponentNames.contains(component.getClassName())) {
+ if (!component.isExported()) {
+ outputNotExportedComponentNames.add(component.getClassName());
+ }
+ remainingComponentCount--;
+ if (remainingComponentCount <= 0) {
+ return outputNotExportedComponentNames;
+ }
+ }
+ }
+ return outputNotExportedComponentNames;
+ }
+
private void sendPackageChangedBroadcastInternal(@NonNull String packageName,
boolean dontKillApp,
@NonNull ArrayList<String> componentNames,
@@ -298,10 +354,48 @@ public final class BroadcastHelper {
@Nullable String reason,
@Nullable int[] userIds,
@Nullable int[] instantUserIds,
- @Nullable SparseArray<int[]> broadcastAllowList) {
- sendPackageChangedBroadcastWithPermissions(packageName, dontKillApp, componentNames,
- packageUid, reason, userIds, instantUserIds, broadcastAllowList,
- null /* targetPackageName */, null /* requiredPermissions */);
+ @Nullable SparseArray<int[]> broadcastAllowList,
+ @NonNull AndroidPackage pkg) {
+ final boolean isForWholeApp = componentNames.contains(packageName);
+ if (isForWholeApp || !android.content.pm.Flags.reduceBroadcastsForComponentStateChanges()) {
+ sendPackageChangedBroadcastWithPermissions(packageName, dontKillApp, componentNames,
+ packageUid, reason, userIds, instantUserIds, broadcastAllowList,
+ null /* targetPackageName */, null /* requiredPermissions */);
+ return;
+ }
+ // Currently only these four components of activity, receiver, provider and service are
+ // considered to send only the broadcast to the system and the application itself when the
+ // component is not exported. In order to avoid losing to send the broadcast for other
+ // components, it gets the not exported components for these four components of activity,
+ // receiver, provider and service and the others are considered the exported components.
+ final ArrayList<String> notExportedComponentNames = getAllNotExportedComponents(pkg,
+ componentNames);
+ final ArrayList<String> exportedComponentNames = (ArrayList<String>) componentNames.clone();
+ exportedComponentNames.removeAll(notExportedComponentNames);
+
+ if (!notExportedComponentNames.isEmpty()) {
+ // Limit sending of the PACKAGE_CHANGED broadcast to only the system and the
+ // application itself when the component is not exported.
+
+ // First, send the PACKAGE_CHANGED broadcast to the system.
+ sendPackageChangedBroadcastWithPermissions(packageName, dontKillApp,
+ notExportedComponentNames, packageUid, reason, userIds, instantUserIds,
+ broadcastAllowList, "android" /* targetPackageName */,
+ new String[]{PERMISSION_PACKAGE_CHANGED_BROADCAST_ON_COMPONENT_STATE_CHANGED});
+
+ // Second, send the PACKAGE_CHANGED broadcast to the application itself.
+ sendPackageChangedBroadcastWithPermissions(packageName, dontKillApp,
+ notExportedComponentNames, packageUid, reason, userIds, instantUserIds,
+ broadcastAllowList, packageName /* targetPackageName */,
+ null /* requiredPermissions */);
+ }
+
+ if (!exportedComponentNames.isEmpty()) {
+ sendPackageChangedBroadcastWithPermissions(packageName, dontKillApp,
+ exportedComponentNames, packageUid, reason, userIds, instantUserIds,
+ broadcastAllowList, null /* targetPackageName */,
+ null /* requiredPermissions */);
+ }
}
private void sendPackageChangedBroadcastWithPermissions(@NonNull String packageName,
@@ -830,7 +924,7 @@ public final class BroadcastHelper {
@NonNull String reason) {
PackageStateInternal setting = snapshot.getPackageStateInternal(packageName,
Process.SYSTEM_UID);
- if (setting == null) {
+ if (setting == null || setting.getPkg() == null) {
return;
}
final int userId = UserHandle.getUserId(packageUid);
@@ -842,7 +936,7 @@ public final class BroadcastHelper {
isInstantApp ? null : snapshot.getVisibilityAllowLists(packageName, userIds);
mHandler.post(() -> sendPackageChangedBroadcastInternal(
packageName, dontKillApp, componentNames, packageUid, reason, userIds,
- instantUserIds, broadcastAllowList));
+ instantUserIds, broadcastAllowList, setting.getPkg()));
mPackageMonitorCallbackHelper.notifyPackageChanged(packageName, dontKillApp, componentNames,
packageUid, reason, userIds, instantUserIds, broadcastAllowList, mHandler);
}
diff --git a/services/core/java/com/android/server/security/advancedprotection/AdvancedProtectionService.java b/services/core/java/com/android/server/security/advancedprotection/AdvancedProtectionService.java
index c33ed555a7f9..1260eeec098f 100644
--- a/services/core/java/com/android/server/security/advancedprotection/AdvancedProtectionService.java
+++ b/services/core/java/com/android/server/security/advancedprotection/AdvancedProtectionService.java
@@ -33,6 +33,7 @@ import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.ShellCallback;
import android.provider.Settings;
+import android.security.advancedprotection.AdvancedProtectionFeature;
import android.security.advancedprotection.IAdvancedProtectionCallback;
import android.security.advancedprotection.IAdvancedProtectionService;
import android.util.ArrayMap;
@@ -44,9 +45,11 @@ import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.pm.UserManagerInternal;
import com.android.server.security.advancedprotection.features.AdvancedProtectionHook;
+import com.android.server.security.advancedprotection.features.AdvancedProtectionProvider;
import java.io.FileDescriptor;
import java.util.ArrayList;
+import java.util.List;
/** @hide */
public class AdvancedProtectionService extends IAdvancedProtectionService.Stub {
@@ -58,10 +61,12 @@ public class AdvancedProtectionService extends IAdvancedProtectionService.Stub
private final Handler mHandler;
private final AdvancedProtectionStore mStore;
- // Features owned by the service - their code will be executed when state changes
+ // Features living with the service - their code will be executed when state changes
private final ArrayList<AdvancedProtectionHook> mHooks = new ArrayList<>();
// External features - they will be called on state change
private final ArrayMap<IBinder, IAdvancedProtectionCallback> mCallbacks = new ArrayMap<>();
+ // For tracking only - not called on state change
+ private final ArrayList<AdvancedProtectionProvider> mProviders = new ArrayList<>();
private AdvancedProtectionService(@NonNull Context context) {
super(PermissionEnforcer.fromContext(context));
@@ -71,13 +76,17 @@ public class AdvancedProtectionService extends IAdvancedProtectionService.Stub
}
private void initFeatures(boolean enabled) {
+ // Empty until features are added.
+ // Examples:
+ // mHooks.add(new SideloadingAdvancedProtectionHook(mContext, enabled));
+ // mProviders.add(new WifiAdvancedProtectionProvider());
}
// Only for tests
@VisibleForTesting
AdvancedProtectionService(@NonNull Context context, @NonNull AdvancedProtectionStore store,
@NonNull Looper looper, @NonNull PermissionEnforcer permissionEnforcer,
- @Nullable AdvancedProtectionHook hook) {
+ @Nullable AdvancedProtectionHook hook, @Nullable AdvancedProtectionProvider provider) {
super(permissionEnforcer);
mContext = context;
mStore = store;
@@ -85,6 +94,10 @@ public class AdvancedProtectionService extends IAdvancedProtectionService.Stub
if (hook != null) {
mHooks.add(hook);
}
+
+ if (provider != null) {
+ mProviders.add(provider);
+ }
}
@Override
@@ -146,6 +159,25 @@ public class AdvancedProtectionService extends IAdvancedProtectionService.Stub
}
@Override
+ @EnforcePermission(Manifest.permission.SET_ADVANCED_PROTECTION_MODE)
+ public List<AdvancedProtectionFeature> getAdvancedProtectionFeatures() {
+ getAdvancedProtectionFeatures_enforcePermission();
+ List<AdvancedProtectionFeature> features = new ArrayList<>();
+ for (int i = 0; i < mProviders.size(); i++) {
+ features.addAll(mProviders.get(i).getFeatures());
+ }
+
+ for (int i = 0; i < mHooks.size(); i++) {
+ AdvancedProtectionHook hook = mHooks.get(i);
+ if (hook.isAvailable()) {
+ features.add(hook.getFeature());
+ }
+ }
+
+ return features;
+ }
+
+ @Override
public void onShellCommand(FileDescriptor in, FileDescriptor out,
FileDescriptor err, @NonNull String[] args, ShellCallback callback,
@NonNull ResultReceiver resultReceiver) {
diff --git a/services/core/java/com/android/server/security/advancedprotection/features/AdvancedProtectionHook.java b/services/core/java/com/android/server/security/advancedprotection/features/AdvancedProtectionHook.java
index b2acc511950b..f82db9676c2c 100644
--- a/services/core/java/com/android/server/security/advancedprotection/features/AdvancedProtectionHook.java
+++ b/services/core/java/com/android/server/security/advancedprotection/features/AdvancedProtectionHook.java
@@ -18,11 +18,15 @@ package com.android.server.security.advancedprotection.features;
import android.annotation.NonNull;
import android.content.Context;
+import android.security.advancedprotection.AdvancedProtectionFeature;
/** @hide */
public abstract class AdvancedProtectionHook {
/** Called on boot phase PHASE_SYSTEM_SERVICES_READY */
public AdvancedProtectionHook(@NonNull Context context, boolean enabled) {}
+ /** The feature this hook provides */
+ @NonNull
+ public abstract AdvancedProtectionFeature getFeature();
/** Whether this feature is relevant on this device. If false, onAdvancedProtectionChanged will
* not be called, and the feature will not be displayed in the onboarding UX. */
public abstract boolean isAvailable();
diff --git a/services/core/java/com/android/server/security/advancedprotection/features/AdvancedProtectionProvider.java b/services/core/java/com/android/server/security/advancedprotection/features/AdvancedProtectionProvider.java
new file mode 100644
index 000000000000..ed451f1e2257
--- /dev/null
+++ b/services/core/java/com/android/server/security/advancedprotection/features/AdvancedProtectionProvider.java
@@ -0,0 +1,27 @@
+/*
+ * 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.security.advancedprotection.features;
+
+import android.security.advancedprotection.AdvancedProtectionFeature;
+
+import java.util.List;
+
+/** @hide */
+public abstract class AdvancedProtectionProvider {
+ /** The list of features provided */
+ public abstract List<AdvancedProtectionFeature> getFeatures();
+}
diff --git a/services/core/java/com/android/server/stats/pull/netstats/NetworkStatsAccumulator.java b/services/core/java/com/android/server/stats/pull/netstats/NetworkStatsAccumulator.java
index e798bc487031..3f7fcee5bb9a 100644
--- a/services/core/java/com/android/server/stats/pull/netstats/NetworkStatsAccumulator.java
+++ b/services/core/java/com/android/server/stats/pull/netstats/NetworkStatsAccumulator.java
@@ -19,6 +19,7 @@ package com.android.server.stats.pull.netstats;
import android.annotation.NonNull;
import android.net.NetworkStats;
import android.net.NetworkTemplate;
+import android.util.Log;
import java.util.Objects;
@@ -33,6 +34,7 @@ import java.util.Objects;
*/
public class NetworkStatsAccumulator {
+ private static final String TAG = "NetworkStatsAccumulator";
private final NetworkTemplate mTemplate;
private final boolean mWithTags;
private final long mBucketDurationMillis;
@@ -57,8 +59,9 @@ public class NetworkStatsAccumulator {
@NonNull
public NetworkStats queryStats(long currentTimeMillis,
@NonNull StatsQueryFunction queryFunction) {
- maybeExpandSnapshot(currentTimeMillis, queryFunction);
- return snapshotPlusFollowingStats(currentTimeMillis, queryFunction);
+ NetworkStats completeStats = snapshotPlusFollowingStats(currentTimeMillis, queryFunction);
+ maybeExpandSnapshot(currentTimeMillis, completeStats, queryFunction);
+ return completeStats;
}
/**
@@ -72,15 +75,28 @@ public class NetworkStatsAccumulator {
* Expands the internal cumulative stats snapshot, if possible, by querying NetworkStats.
*/
private void maybeExpandSnapshot(long currentTimeMillis,
+ NetworkStats completeStatsUntilCurrentTime,
@NonNull StatsQueryFunction queryFunction) {
// Update snapshot only if it is possible to expand it by at least one full bucket, and only
// if the new snapshot's end is not in the active bucket.
long newEndTimeMillis = currentTimeMillis - mBucketDurationMillis;
if (newEndTimeMillis - mSnapshotEndTimeMillis > mBucketDurationMillis) {
- NetworkStats extraStats = queryFunction.queryNetworkStats(mTemplate, mWithTags,
- mSnapshotEndTimeMillis, newEndTimeMillis);
+ Log.v(TAG,
+ "Expanding snapshot (mTemplate=" + mTemplate + ", mWithTags=" + mWithTags
+ + ") from " + mSnapshotEndTimeMillis + " to " + newEndTimeMillis
+ + " at " + currentTimeMillis);
+ NetworkStats extraStats = queryFunction.queryNetworkStats(
+ mTemplate, mWithTags, mSnapshotEndTimeMillis, newEndTimeMillis);
mSnapshot = mSnapshot.add(extraStats);
mSnapshotEndTimeMillis = newEndTimeMillis;
+
+ // NetworkStats queries interpolate historical data using integers maths, which makes
+ // queries non-transitive: Query(t0, t1) + Query(t1, t2) <= Query(t0, t2).
+ // Compute interpolation data loss from moving the snapshot's end-point, and add it to
+ // the snapshot to avoid under-counting.
+ NetworkStats newStats = snapshotPlusFollowingStats(currentTimeMillis, queryFunction);
+ NetworkStats interpolationLoss = completeStatsUntilCurrentTime.subtract(newStats);
+ mSnapshot = mSnapshot.add(interpolationLoss);
}
}
diff --git a/services/core/java/com/android/server/wm/ActivityRecordInputSink.java b/services/core/java/com/android/server/wm/ActivityRecordInputSink.java
index fa5beca31ec1..ea6506a03a80 100644
--- a/services/core/java/com/android/server/wm/ActivityRecordInputSink.java
+++ b/services/core/java/com/android/server/wm/ActivityRecordInputSink.java
@@ -40,7 +40,6 @@ class ActivityRecordInputSink {
@ChangeId
static final long ENABLE_TOUCH_OPAQUE_ACTIVITIES = 194480991L;
- // TODO(b/369605358) Update EnabledSince when SDK 36 version code is available.
/**
* If the app's target SDK is 36+, pass-through touches from a cross-uid overlaying activity is
* blocked by default. The activity may opt in to receive pass-through touches using
@@ -52,7 +51,7 @@ class ActivityRecordInputSink {
* @see ActivityOptions#setAllowPassThroughOnTouchOutside
*/
@ChangeId
- @EnabledSince(targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT)
+ @EnabledSince(targetSdkVersion = Build.VERSION_CODES.BAKLAVA)
static final long ENABLE_OVERLAY_TOUCH_PASS_THROUGH_OPT_IN_ENFORCEMENT = 358129114L;
private final ActivityRecord mActivityRecord;
diff --git a/services/core/java/com/android/server/wm/ActivityStartController.java b/services/core/java/com/android/server/wm/ActivityStartController.java
index 6e97f8a943dd..3f24da9d89f2 100644
--- a/services/core/java/com/android/server/wm/ActivityStartController.java
+++ b/services/core/java/com/android/server/wm/ActivityStartController.java
@@ -478,7 +478,7 @@ public class ActivityStartController {
intentGrants.merge(creatorIntentGrants);
}
} catch (SecurityException securityException) {
- ActivityStarter.logAndThrowExceptionForIntentRedirect(
+ ActivityStarter.logAndThrowExceptionForIntentRedirect(mService.mContext,
"Creator URI Grant Caused Exception.", intent, creatorUid,
creatorPackage, filterCallingUid, callingPackage,
securityException);
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index e15968db9b3d..05a96d9fcf5e 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -55,6 +55,7 @@ import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TOP;
import static android.content.pm.ActivityInfo.launchModeToString;
import static android.os.Process.INVALID_UID;
import static android.security.Flags.preventIntentRedirectAbortOrThrowException;
+import static android.security.Flags.preventIntentRedirectShowToast;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.TRANSIT_NONE;
import static android.view.WindowManager.TRANSIT_OPEN;
@@ -105,6 +106,7 @@ import android.compat.annotation.ChangeId;
import android.compat.annotation.Disabled;
import android.compat.annotation.EnabledSince;
import android.compat.annotation.Overridable;
+import android.content.Context;
import android.content.IIntentSender;
import android.content.Intent;
import android.content.IntentSender;
@@ -128,12 +130,14 @@ import android.service.voice.IVoiceInteractionSession;
import android.text.TextUtils;
import android.util.Pools.SynchronizedPool;
import android.util.Slog;
+import android.widget.Toast;
import android.window.RemoteTransition;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.HeavyWeightSwitcherActivity;
import com.android.internal.app.IVoiceInteractor;
import com.android.internal.protolog.ProtoLog;
+import com.android.server.UiThread;
import com.android.server.am.ActivityManagerService.IntentCreatorToken;
import com.android.server.am.PendingIntentRecord;
import com.android.server.pm.InstantAppResolver;
@@ -614,7 +618,7 @@ class ActivityStarter {
// Check if the Intent was redirected
if ((intent.getExtendedFlags() & Intent.EXTENDED_FLAG_MISSING_CREATOR_OR_INVALID_TOKEN)
!= 0) {
- ActivityStarter.logAndThrowExceptionForIntentRedirect(
+ logAndThrowExceptionForIntentRedirect(supervisor.mService.mContext,
"Unparceled intent does not have a creator token set.", intent,
intentCreatorUid, intentCreatorPackage, resolvedCallingUid,
resolvedCallingPackage, null);
@@ -650,7 +654,7 @@ class ActivityStarter {
intentGrants.merge(creatorIntentGrants);
}
} catch (SecurityException securityException) {
- ActivityStarter.logAndThrowExceptionForIntentRedirect(
+ logAndThrowExceptionForIntentRedirect(supervisor.mService.mContext,
"Creator URI Grant Caused Exception.", intent, intentCreatorUid,
intentCreatorPackage, resolvedCallingUid,
resolvedCallingPackage, securityException);
@@ -674,7 +678,7 @@ class ActivityStarter {
intentGrants.merge(creatorIntentGrants);
}
} catch (SecurityException securityException) {
- ActivityStarter.logAndThrowExceptionForIntentRedirect(
+ logAndThrowExceptionForIntentRedirect(supervisor.mService.mContext,
"Creator URI Grant Caused Exception.", intent, intentCreatorUid,
intentCreatorPackage, resolvedCallingUid,
resolvedCallingPackage, securityException);
@@ -1250,27 +1254,27 @@ class ActivityStarter {
requestCode, 0, intentCreatorUid, intentCreatorPackage, "",
request.ignoreTargetSecurity, inTask != null, null, resultRecord,
resultRootTask)) {
- abort = logAndAbortForIntentRedirect(
+ abort = logAndAbortForIntentRedirect(mService.mContext,
"Creator checkStartAnyActivityPermission Caused abortion.",
intent, intentCreatorUid, intentCreatorPackage, callingUid,
callingPackage);
}
} catch (SecurityException e) {
- logAndThrowExceptionForIntentRedirect(
+ logAndThrowExceptionForIntentRedirect(mService.mContext,
"Creator checkStartAnyActivityPermission Caused Exception.",
intent, intentCreatorUid, intentCreatorPackage, callingUid, callingPackage,
e);
}
if (!mService.mIntentFirewall.checkStartActivity(intent, intentCreatorUid,
0, resolvedType, aInfo.applicationInfo)) {
- abort = logAndAbortForIntentRedirect(
+ abort = logAndAbortForIntentRedirect(mService.mContext,
"Creator IntentFirewall.checkStartActivity Caused abortion.",
intent, intentCreatorUid, intentCreatorPackage, callingUid, callingPackage);
}
if (!mService.getPermissionPolicyInternal().checkStartActivity(intent,
intentCreatorUid, intentCreatorPackage)) {
- abort = logAndAbortForIntentRedirect(
+ abort = logAndAbortForIntentRedirect(mService.mContext,
"Creator PermissionPolicyService.checkStartActivity Caused abortion.",
intent, intentCreatorUid, intentCreatorPackage, callingUid, callingPackage);
}
@@ -3596,25 +3600,38 @@ class ActivityStarter {
pw.println(mInTaskFragment);
}
- static void logAndThrowExceptionForIntentRedirect(@NonNull String message,
- @NonNull Intent intent, int intentCreatorUid, @Nullable String intentCreatorPackage,
- int callingUid, @Nullable String callingPackage,
+ static void logAndThrowExceptionForIntentRedirect(@NonNull Context context,
+ @NonNull String message, @NonNull Intent intent, int intentCreatorUid,
+ @Nullable String intentCreatorPackage, int callingUid, @Nullable String callingPackage,
@Nullable SecurityException originalException) {
String msg = getIntentRedirectPreventedLogMessage(message, intent, intentCreatorUid,
intentCreatorPackage, callingUid, callingPackage);
Slog.wtf(TAG, msg);
+ if (preventIntentRedirectShowToast()) {
+ UiThread.getHandler().post(
+ () -> Toast.makeText(context,
+ "Activity launch blocked. go/report-bug-intentRedir to report a bug",
+ Toast.LENGTH_LONG).show());
+ }
if (preventIntentRedirectAbortOrThrowException() && CompatChanges.isChangeEnabled(
ENABLE_PREVENT_INTENT_REDIRECT_TAKE_ACTION, callingUid)) {
throw new SecurityException(msg, originalException);
}
}
- private static boolean logAndAbortForIntentRedirect(@NonNull String message,
- @NonNull Intent intent, int intentCreatorUid, @Nullable String intentCreatorPackage,
- int callingUid, @Nullable String callingPackage) {
+ private static boolean logAndAbortForIntentRedirect(@NonNull Context context,
+ @NonNull String message, @NonNull Intent intent, int intentCreatorUid,
+ @Nullable String intentCreatorPackage, int callingUid,
+ @Nullable String callingPackage) {
String msg = getIntentRedirectPreventedLogMessage(message, intent, intentCreatorUid,
intentCreatorPackage, callingUid, callingPackage);
Slog.wtf(TAG, msg);
+ if (preventIntentRedirectShowToast()) {
+ UiThread.getHandler().post(
+ () -> Toast.makeText(context,
+ "Activity launch blocked. go/report-bug-intentRedir to report a bug",
+ Toast.LENGTH_LONG).show());
+ }
return preventIntentRedirectAbortOrThrowException() && CompatChanges.isChangeEnabled(
ENABLE_PREVENT_INTENT_REDIRECT_TAKE_ACTION, callingUid);
}
diff --git a/services/core/java/com/android/server/wm/AppCompatAspectRatioOverrides.java b/services/core/java/com/android/server/wm/AppCompatAspectRatioOverrides.java
index f1dd41e7d74a..90c0866d7dff 100644
--- a/services/core/java/com/android/server/wm/AppCompatAspectRatioOverrides.java
+++ b/services/core/java/com/android/server/wm/AppCompatAspectRatioOverrides.java
@@ -37,6 +37,7 @@ import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLAS
import static com.android.server.wm.AppCompatConfiguration.LETTERBOX_POSITION_MULTIPLIER_CENTER;
import static com.android.server.wm.AppCompatConfiguration.MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO;
import static com.android.server.wm.AppCompatUtils.isChangeEnabled;
+import static com.android.server.wm.AppCompatUtils.isDisplayIgnoreActivitySizeRestrictions;
import android.annotation.NonNull;
import android.content.pm.IPackageManager;
@@ -175,8 +176,17 @@ class AppCompatAspectRatioOverrides {
&& mActivityRecord.mDisplayContent.getIgnoreOrientationRequest();
}
+ /**
+ * Whether to ignore fixed orientation, aspect ratio and resizability of activity.
+ */
boolean hasFullscreenOverride() {
- return shouldApplyUserFullscreenOverride() || isSystemOverrideToFullscreenEnabled();
+ return shouldApplyUserFullscreenOverride() || isSystemOverrideToFullscreenEnabled()
+ || shouldIgnoreActivitySizeRestrictionsForDisplay();
+ }
+
+ boolean shouldIgnoreActivitySizeRestrictionsForDisplay() {
+ return isDisplayIgnoreActivitySizeRestrictions(mActivityRecord)
+ && !mAllowOrientationOverrideOptProp.isFalse();
}
float getUserMinAspectRatio() {
diff --git a/services/core/java/com/android/server/wm/AppCompatOrientationPolicy.java b/services/core/java/com/android/server/wm/AppCompatOrientationPolicy.java
index e3a9d672c17f..7aed33d94223 100644
--- a/services/core/java/com/android/server/wm/AppCompatOrientationPolicy.java
+++ b/services/core/java/com/android/server/wm/AppCompatOrientationPolicy.java
@@ -53,11 +53,16 @@ class AppCompatOrientationPolicy {
@ActivityInfo.ScreenOrientation
int overrideOrientationIfNeeded(@ActivityInfo.ScreenOrientation int candidate) {
+ final AppCompatAspectRatioOverrides aspectRatioOverrides =
+ mAppCompatOverrides.getAppCompatAspectRatioOverrides();
+ // Ignore all orientation requests of activities for eligible virtual displays.
+ if (aspectRatioOverrides.shouldIgnoreActivitySizeRestrictionsForDisplay()) {
+ return SCREEN_ORIENTATION_USER;
+ }
final DisplayContent displayContent = mActivityRecord.mDisplayContent;
final boolean isIgnoreOrientationRequestEnabled = displayContent != null
&& displayContent.getIgnoreOrientationRequest();
- final boolean hasFullscreenOverride = mAppCompatOverrides
- .getAppCompatAspectRatioOverrides().hasFullscreenOverride();
+ final boolean hasFullscreenOverride = aspectRatioOverrides.hasFullscreenOverride();
final boolean shouldCameraCompatControlOrientation =
AppCompatCameraPolicy.shouldCameraCompatControlOrientation(mActivityRecord);
if (hasFullscreenOverride && isIgnoreOrientationRequestEnabled
@@ -76,8 +81,8 @@ class AppCompatOrientationPolicy {
// In some cases (e.g. Kids app) we need to map the candidate orientation to some other
// orientation.
candidate = mActivityRecord.mWmService.mapOrientationRequest(candidate);
- final boolean shouldApplyUserMinAspectRatioOverride = mAppCompatOverrides
- .getAppCompatAspectRatioOverrides().shouldApplyUserMinAspectRatioOverride();
+ final boolean shouldApplyUserMinAspectRatioOverride = aspectRatioOverrides
+ .shouldApplyUserMinAspectRatioOverride();
if (shouldApplyUserMinAspectRatioOverride && (!isFixedOrientation(candidate)
|| candidate == SCREEN_ORIENTATION_LOCKED)) {
Slog.v(TAG, "Requested orientation " + screenOrientationToString(candidate)
diff --git a/services/core/java/com/android/server/wm/AppCompatSizeCompatModePolicy.java b/services/core/java/com/android/server/wm/AppCompatSizeCompatModePolicy.java
index f069dcdbc86b..d0d3d4321a0a 100644
--- a/services/core/java/com/android/server/wm/AppCompatSizeCompatModePolicy.java
+++ b/services/core/java/com/android/server/wm/AppCompatSizeCompatModePolicy.java
@@ -149,7 +149,7 @@ class AppCompatSizeCompatModePolicy {
@NonNull Configuration newParentConfig) {
mSizeCompatScale = mActivityRecord.mAppCompatController.getTransparentPolicy()
.findOpaqueNotFinishingActivityBelow()
- .map(activityRecord -> mSizeCompatScale)
+ .map(ar -> Math.min(1.0f, ar.getCompatScale()))
.orElseGet(() -> calculateSizeCompatScale(
resolvedAppBounds, containerAppBounds, newParentConfig));
}
diff --git a/services/core/java/com/android/server/wm/AppCompatUtils.java b/services/core/java/com/android/server/wm/AppCompatUtils.java
index 8d8424820990..db76eb9ac5d9 100644
--- a/services/core/java/com/android/server/wm/AppCompatUtils.java
+++ b/services/core/java/com/android/server/wm/AppCompatUtils.java
@@ -32,6 +32,8 @@ import android.view.InsetsSource;
import android.view.InsetsState;
import android.view.WindowInsets;
+import com.android.window.flags.Flags;
+
import java.util.function.BooleanSupplier;
/**
@@ -86,10 +88,22 @@ final class AppCompatUtils {
/**
* @param activityRecord The {@link ActivityRecord} for the app package.
* @param overrideChangeId The per-app override identifier.
- * @return {@code true} if the per-app override is enable for the given activity.
+ * @return {@code true} if the per-app override is enable for the given activity and the
+ * display does not ignore fixed orientation, aspect ratio and resizability of activity.
*/
static boolean isChangeEnabled(@NonNull ActivityRecord activityRecord, long overrideChangeId) {
- return activityRecord.info.isChangeEnabled(overrideChangeId);
+ return activityRecord.info.isChangeEnabled(overrideChangeId)
+ && !isDisplayIgnoreActivitySizeRestrictions(activityRecord);
+ }
+
+ /**
+ * Whether the display ignores fixed orientation, aspect ratio and resizability of activities.
+ */
+ static boolean isDisplayIgnoreActivitySizeRestrictions(
+ @NonNull ActivityRecord activityRecord) {
+ final DisplayContent dc = activityRecord.mDisplayContent;
+ return Flags.vdmForceAppUniversalResizableApi() && dc != null
+ && dc.isDisplayIgnoreActivitySizeRestrictions();
}
/**
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index aac756f4e559..e827f44cb2a2 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -5789,6 +5789,17 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
}
/**
+ * Checks if this display is allowed to ignore fixed orientation, aspect ratio,
+ * and resizability of apps.
+ *
+ * <p>This can be set via
+ * {@link VirtualDisplayConfig.Builder#setIgnoreActivitySizeRestrictions}.</p>
+ */
+ boolean isDisplayIgnoreActivitySizeRestrictions() {
+ return mWmService.mDisplayWindowSettings.isIgnoreActivitySizeRestrictionsLocked(this);
+ }
+
+ /**
* The direct child layer of the display to put all non-overlay windows. This is also used for
* screen rotation animation so that there is a parent layer to put the animation leash.
*/
diff --git a/services/core/java/com/android/server/wm/DisplayWindowSettings.java b/services/core/java/com/android/server/wm/DisplayWindowSettings.java
index e585efa8a3cc..c87b811b4231 100644
--- a/services/core/java/com/android/server/wm/DisplayWindowSettings.java
+++ b/services/core/java/com/android/server/wm/DisplayWindowSettings.java
@@ -275,6 +275,24 @@ class DisplayWindowSettings {
mSettingsProvider.updateOverrideSettings(displayInfo, overrideSettings);
}
+ boolean isIgnoreActivitySizeRestrictionsLocked(@NonNull DisplayContent dc) {
+ final DisplayInfo displayInfo = dc.getDisplayInfo();
+ final SettingsProvider.SettingsEntry settings = mSettingsProvider.getSettings(displayInfo);
+ return settings.mIgnoreActivitySizeRestrictions != null
+ && settings.mIgnoreActivitySizeRestrictions;
+ }
+
+ void setIgnoreActivitySizeRestrictionsOnDisplayLocked(@NonNull String displayUniqueId,
+ int displayType, boolean enabled) {
+ final DisplayInfo displayInfo = new DisplayInfo();
+ displayInfo.uniqueId = displayUniqueId;
+ displayInfo.type = displayType;
+ final SettingsProvider.SettingsEntry overrideSettings =
+ mSettingsProvider.getOverrideSettings(displayInfo);
+ overrideSettings.mIgnoreActivitySizeRestrictions = enabled;
+ mSettingsProvider.updateOverrideSettings(displayInfo, overrideSettings);
+ }
+
void clearDisplaySettings(@NonNull String displayUniqueId, int displayType) {
final DisplayInfo displayInfo = new DisplayInfo();
displayInfo.uniqueId = displayUniqueId;
@@ -474,6 +492,8 @@ class DisplayWindowSettings {
Boolean mIgnoreDisplayCutout;
@Nullable
Boolean mDontMoveToTop;
+ @Nullable
+ Boolean mIgnoreActivitySizeRestrictions;
SettingsEntry() {}
@@ -557,6 +577,11 @@ class DisplayWindowSettings {
mDontMoveToTop = other.mDontMoveToTop;
changed = true;
}
+ if (!Objects.equals(other.mIgnoreActivitySizeRestrictions,
+ mIgnoreActivitySizeRestrictions)) {
+ mIgnoreActivitySizeRestrictions = other.mIgnoreActivitySizeRestrictions;
+ changed = true;
+ }
return changed;
}
@@ -649,6 +674,11 @@ class DisplayWindowSettings {
mDontMoveToTop = delta.mDontMoveToTop;
changed = true;
}
+ if (delta.mIgnoreActivitySizeRestrictions != null && !Objects.equals(
+ delta.mIgnoreActivitySizeRestrictions, mIgnoreActivitySizeRestrictions)) {
+ mIgnoreActivitySizeRestrictions = delta.mIgnoreActivitySizeRestrictions;
+ changed = true;
+ }
return changed;
}
@@ -667,7 +697,8 @@ class DisplayWindowSettings {
&& mFixedToUserRotation == null
&& mIgnoreOrientationRequest == null
&& mIgnoreDisplayCutout == null
- && mDontMoveToTop == null;
+ && mDontMoveToTop == null
+ && mIgnoreActivitySizeRestrictions == null;
}
@Override
@@ -691,7 +722,9 @@ class DisplayWindowSettings {
&& Objects.equals(mFixedToUserRotation, that.mFixedToUserRotation)
&& Objects.equals(mIgnoreOrientationRequest, that.mIgnoreOrientationRequest)
&& Objects.equals(mIgnoreDisplayCutout, that.mIgnoreDisplayCutout)
- && Objects.equals(mDontMoveToTop, that.mDontMoveToTop);
+ && Objects.equals(mDontMoveToTop, that.mDontMoveToTop)
+ && Objects.equals(mIgnoreActivitySizeRestrictions,
+ that.mIgnoreActivitySizeRestrictions);
}
@Override
@@ -700,7 +733,7 @@ class DisplayWindowSettings {
mForcedHeight, mForcedDensity, mForcedScalingMode, mRemoveContentMode,
mShouldShowWithInsecureKeyguard, mShouldShowSystemDecors, mIsHomeSupported,
mImePolicy, mFixedToUserRotation, mIgnoreOrientationRequest,
- mIgnoreDisplayCutout, mDontMoveToTop);
+ mIgnoreDisplayCutout, mDontMoveToTop, mIgnoreActivitySizeRestrictions);
}
@Override
@@ -722,6 +755,7 @@ class DisplayWindowSettings {
+ ", mIgnoreOrientationRequest=" + mIgnoreOrientationRequest
+ ", mIgnoreDisplayCutout=" + mIgnoreDisplayCutout
+ ", mDontMoveToTop=" + mDontMoveToTop
+ + ", mForceAppsUniversalResizable=" + mIgnoreActivitySizeRestrictions
+ '}';
}
}
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index b14dd3f7f17c..8aa0530d3bc1 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -3464,7 +3464,8 @@ class Task extends TaskFragment {
return null;
}
final Rect windowFrame = mainWindow.getFrame();
- if (top.getBounds().equals(windowFrame)) {
+ final Rect parentFrame = mainWindow.getParentFrame();
+ if (parentFrame.equals(windowFrame)) {
return null;
}
return windowFrame;
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 6c92ae6bb3e7..552584222711 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -1117,7 +1117,9 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
*/
void onDisplayChanged(DisplayContent dc) {
if (mDisplayContent != null && mDisplayContent != dc) {
- mTransitionController.collect(this);
+ if (asWindowState() == null) {
+ mTransitionController.collect(this);
+ }
// Cancel any change transition queued-up for this container on the old display when
// this container is moved from the old display.
mDisplayContent.mClosingChangingContainers.remove(this);
diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java
index 82d39a39d188..ce032b4f7f9a 100644
--- a/services/core/java/com/android/server/wm/WindowManagerInternal.java
+++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java
@@ -859,6 +859,18 @@ public abstract class WindowManagerInternal {
public abstract boolean isHomeSupportedOnDisplay(int displayId);
/**
+ * Sets whether the relevant display content ignores fixed orientation, aspect ratio
+ * and resizability of apps.
+ *
+ * @param displayUniqueId The unique ID of the display. Note that the display may not yet be
+ * created, but whenever it is, this property will be applied.
+ * @param displayType The type of the display, e.g. {@link Display#TYPE_VIRTUAL}.
+ * @param enabled Whether app is universal resizable on this display.
+ */
+ public abstract void setIgnoreActivitySizeRestrictionsOnDisplay(
+ @NonNull String displayUniqueId, int displayType, boolean enabled);
+
+ /**
* Removes any settings relevant to the given display.
*
* <p>This may be used when a property is set for a display unique ID before the display
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 97bf587cd10f..88b2d229e083 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -8384,6 +8384,20 @@ public class WindowManagerService extends IWindowManager.Stub
}
@Override
+ public void setIgnoreActivitySizeRestrictionsOnDisplay(@NonNull String displayUniqueId,
+ int displayType, boolean enabled) {
+ final long origId = Binder.clearCallingIdentity();
+ try {
+ synchronized (mGlobalLock) {
+ mDisplayWindowSettings.setIgnoreActivitySizeRestrictionsOnDisplayLocked(
+ displayUniqueId, displayType, enabled);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(origId);
+ }
+ }
+
+ @Override
public void clearDisplaySettings(String displayUniqueId, int displayType) {
final long origId = Binder.clearCallingIdentity();
try {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 585e61795e7d..d01e29b2fd5e 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -258,6 +258,7 @@ import com.android.server.policy.WindowManagerPolicy;
import com.android.server.wm.LocalAnimationAdapter.AnimationSpec;
import com.android.server.wm.RefreshRatePolicy.FrameRateVote;
import com.android.server.wm.SurfaceAnimator.AnimationType;
+import com.android.server.wm.utils.RegionUtils;
import com.android.window.flags.Flags;
import dalvik.annotation.optimization.NeverCompile;
@@ -2327,7 +2328,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
if (mStartingData != null && mStartingData.mAssociatedTask == null
&& mTempConfiguration.windowConfiguration.getRotation()
== selfConfiguration.windowConfiguration.getRotation()
- && !mTempConfiguration.windowConfiguration.getBounds().equals(getBounds())) {
+ && !RegionUtils.sizeEquals(
+ mTempConfiguration.windowConfiguration.getBounds(), getBounds())) {
mStartingData.mResizedFromTransfer = true;
// Lock the starting window to task, so it won't resize from transfer anymore.
mActivityRecord.associateStartingWindowWithTaskIfNeeded();
diff --git a/services/core/java/com/android/server/wm/utils/RegionUtils.java b/services/core/java/com/android/server/wm/utils/RegionUtils.java
index ff23145fc6b9..6c5da175644b 100644
--- a/services/core/java/com/android/server/wm/utils/RegionUtils.java
+++ b/services/core/java/com/android/server/wm/utils/RegionUtils.java
@@ -92,4 +92,9 @@ public class RegionUtils {
}
return area;
}
+
+ /** Returns whether the sizes between the two Rects are equal. */
+ public static boolean sizeEquals(Rect a, Rect b) {
+ return a.width() == b.width() && a.height() == b.height();
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/security/advancedprotection/AdvancedProtectionServiceTest.java b/services/tests/servicestests/src/com/android/server/security/advancedprotection/AdvancedProtectionServiceTest.java
index e97b48cb3489..24bf6ca507e6 100644
--- a/services/tests/servicestests/src/com/android/server/security/advancedprotection/AdvancedProtectionServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/security/advancedprotection/AdvancedProtectionServiceTest.java
@@ -16,6 +16,8 @@
package com.android.server.security.advancedprotection;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.collection.IsIterableContainingInAnyOrder.containsInAnyOrder;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
@@ -28,15 +30,20 @@ import android.os.RemoteException;
import android.os.test.FakePermissionEnforcer;
import android.os.test.TestLooper;
import android.provider.Settings;
+import android.security.advancedprotection.AdvancedProtectionFeature;
import android.security.advancedprotection.IAdvancedProtectionCallback;
+import androidx.annotation.NonNull;
+
import com.android.server.security.advancedprotection.features.AdvancedProtectionHook;
+import com.android.server.security.advancedprotection.features.AdvancedProtectionProvider;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
+import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
@SuppressLint("VisibleForTests")
@@ -47,6 +54,7 @@ public class AdvancedProtectionServiceTest {
private Context mContext;
private AdvancedProtectionService.AdvancedProtectionStore mStore;
private TestLooper mLooper;
+ AdvancedProtectionFeature mFeature = new AdvancedProtectionFeature("test-id");
@Before
public void setup() throws Settings.SettingNotFoundException {
@@ -70,8 +78,9 @@ public class AdvancedProtectionServiceTest {
};
mLooper = new TestLooper();
+
mService = new AdvancedProtectionService(mContext, mStore, mLooper.getLooper(),
- mPermissionEnforcer, null);
+ mPermissionEnforcer, null, null);
}
@Test
@@ -93,6 +102,12 @@ public class AdvancedProtectionServiceTest {
AtomicBoolean callbackCaptor = new AtomicBoolean(false);
AdvancedProtectionHook hook =
new AdvancedProtectionHook(mContext, true) {
+ @NonNull
+ @Override
+ public AdvancedProtectionFeature getFeature() {
+ return mFeature;
+ }
+
@Override
public boolean isAvailable() {
return true;
@@ -105,7 +120,7 @@ public class AdvancedProtectionServiceTest {
};
mService = new AdvancedProtectionService(mContext, mStore, mLooper.getLooper(),
- mPermissionEnforcer, hook);
+ mPermissionEnforcer, hook, null);
mService.setAdvancedProtectionEnabled(true);
mLooper.dispatchNext();
@@ -117,6 +132,12 @@ public class AdvancedProtectionServiceTest {
AtomicBoolean callbackCalledCaptor = new AtomicBoolean(false);
AdvancedProtectionHook hook =
new AdvancedProtectionHook(mContext, true) {
+ @NonNull
+ @Override
+ public AdvancedProtectionFeature getFeature() {
+ return mFeature;
+ }
+
@Override
public boolean isAvailable() {
return false;
@@ -129,7 +150,8 @@ public class AdvancedProtectionServiceTest {
};
mService = new AdvancedProtectionService(mContext, mStore, mLooper.getLooper(),
- mPermissionEnforcer, hook);
+ mPermissionEnforcer, hook, null);
+
mService.setAdvancedProtectionEnabled(true);
mLooper.dispatchNext();
assertFalse(callbackCalledCaptor.get());
@@ -140,6 +162,12 @@ public class AdvancedProtectionServiceTest {
AtomicBoolean callbackCalledCaptor = new AtomicBoolean(false);
AdvancedProtectionHook hook =
new AdvancedProtectionHook(mContext, true) {
+ @NonNull
+ @Override
+ public AdvancedProtectionFeature getFeature() {
+ return mFeature;
+ }
+
@Override
public boolean isAvailable() {
return true;
@@ -152,7 +180,7 @@ public class AdvancedProtectionServiceTest {
};
mService = new AdvancedProtectionService(mContext, mStore, mLooper.getLooper(),
- mPermissionEnforcer, hook);
+ mPermissionEnforcer, hook, null);
mService.setAdvancedProtectionEnabled(true);
mLooper.dispatchNext();
assertTrue(callbackCalledCaptor.get());
@@ -208,6 +236,66 @@ public class AdvancedProtectionServiceTest {
assertFalse(callbackCalledCaptor.get());
}
+ @Test
+ public void testGetFeatures() {
+ AdvancedProtectionFeature feature1 = new AdvancedProtectionFeature("id-1");
+ AdvancedProtectionFeature feature2 = new AdvancedProtectionFeature("id-2");
+ AdvancedProtectionHook hook = new AdvancedProtectionHook(mContext, true) {
+ @NonNull
+ @Override
+ public AdvancedProtectionFeature getFeature() {
+ return feature1;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return true;
+ }
+ };
+
+ AdvancedProtectionProvider provider = new AdvancedProtectionProvider() {
+ @Override
+ public List<AdvancedProtectionFeature> getFeatures() {
+ return List.of(feature2);
+ }
+ };
+
+ mService = new AdvancedProtectionService(mContext, mStore, mLooper.getLooper(),
+ mPermissionEnforcer, hook, provider);
+ List<AdvancedProtectionFeature> features = mService.getAdvancedProtectionFeatures();
+ assertThat(features, containsInAnyOrder(feature1, feature2));
+ }
+
+ @Test
+ public void testGetFeatures_featureNotAvailable() {
+ AdvancedProtectionFeature feature1 = new AdvancedProtectionFeature("id-1");
+ AdvancedProtectionFeature feature2 = new AdvancedProtectionFeature("id-2");
+ AdvancedProtectionHook hook = new AdvancedProtectionHook(mContext, true) {
+ @NonNull
+ @Override
+ public AdvancedProtectionFeature getFeature() {
+ return feature1;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return false;
+ }
+ };
+
+ AdvancedProtectionProvider provider = new AdvancedProtectionProvider() {
+ @Override
+ public List<AdvancedProtectionFeature> getFeatures() {
+ return List.of(feature2);
+ }
+ };
+
+ mService = new AdvancedProtectionService(mContext, mStore, mLooper.getLooper(),
+ mPermissionEnforcer, hook, provider);
+ List<AdvancedProtectionFeature> features = mService.getAdvancedProtectionFeatures();
+ assertThat(features, containsInAnyOrder(feature2));
+ }
+
@Test
public void testSetProtection_withoutPermission() {
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index b99ab0595c9d..ac021e122998 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -112,6 +112,7 @@ import static android.service.notification.Condition.SOURCE_CONTEXT;
import static android.service.notification.Condition.SOURCE_USER_ACTION;
import static android.service.notification.Condition.STATE_TRUE;
import static android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION;
+import static android.service.notification.Flags.FLAG_NOTIFICATION_CONVERSATION_CHANNEL_MANAGEMENT;
import static android.service.notification.Flags.FLAG_NOTIFICATION_FORCE_GROUPING;
import static android.service.notification.Flags.FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS;
import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_ALERTING;
@@ -265,6 +266,7 @@ import android.os.WorkSource;
import android.permission.PermissionManager;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
+import android.platform.test.annotations.RequiresFlagsEnabled;
import android.platform.test.flag.junit.FlagsParameterization;
import android.platform.test.flag.junit.SetFlagsRule;
import android.platform.test.rule.LimitDevicesRule;
@@ -485,6 +487,15 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
NotificationChannel mMinChannel = new NotificationChannel("min", "min", IMPORTANCE_MIN);
+ private final NotificationChannel mParentChannel =
+ new NotificationChannel(PARENT_CHANNEL_ID, "parentName", IMPORTANCE_DEFAULT);
+ private final NotificationChannel mConversationChannel =
+ new NotificationChannel(CONVERSATION_CHANNEL_ID, "conversationName", IMPORTANCE_DEFAULT);
+
+ private static final String PARENT_CHANNEL_ID = "parentChannelId";
+ private static final String CONVERSATION_CHANNEL_ID = "conversationChannelId";
+ private static final String CONVERSATION_ID = "conversationId";
+
private static final int NOTIFICATION_LOCATION_UNKNOWN = 0;
private static final String VALID_CONVO_SHORTCUT_ID = "shortcut";
@@ -4672,8 +4683,161 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
verify(mAmi).hasForegroundServiceNotification(anyString(), anyInt(), anyString());
}
+ private void setUpChannelsForConversationChannelTest() throws RemoteException {
+ when(mPreferencesHelper.getNotificationChannel(
+ eq(mPkg), eq(mUid), eq(PARENT_CHANNEL_ID), eq(false)))
+ .thenReturn(mParentChannel);
+ when(mPreferencesHelper.getConversationNotificationChannel(
+ eq(mPkg), eq(mUid), eq(PARENT_CHANNEL_ID), eq(CONVERSATION_ID), eq(false), eq(false)))
+ .thenReturn(mConversationChannel);
+ when(mPackageManager.getPackageUid(mPkg, 0, mUserId)).thenReturn(mUid);
+ }
+
+ @Test
+ @RequiresFlagsEnabled(FLAG_NOTIFICATION_CONVERSATION_CHANNEL_MANAGEMENT)
+ public void createConversationChannelForPkgFromPrivilegedListener_cdm_success() throws Exception {
+ // Set up cdm
+ mService.setPreferencesHelper(mPreferencesHelper);
+ when(mCompanionMgr.getAssociations(mPkg, mUserId))
+ .thenReturn(singletonList(mock(AssociationInfo.class)));
+
+ // Set up parent channel
+ setUpChannelsForConversationChannelTest();
+ final NotificationChannel parentChannelCopy = mParentChannel.copy();
+
+ NotificationChannel createdChannel =
+ mBinderService.createConversationNotificationChannelForPackageFromPrivilegedListener(
+ null, mPkg, mUser, PARENT_CHANNEL_ID, CONVERSATION_ID);
+
+ // Verify that a channel is created and a copied channel is returned.
+ verify(mPreferencesHelper, times(1)).createNotificationChannel(
+ eq(mPkg), eq(mUid), any(), anyBoolean(), anyBoolean(),
+ eq(mUid), anyBoolean());
+ assertThat(createdChannel).isNotSameInstanceAs(mConversationChannel);
+ assertThat(createdChannel).isEqualTo(mConversationChannel);
+
+ // Verify that the channel creation is not directly use the parent channel.
+ verify(mPreferencesHelper, never()).createNotificationChannel(
+ anyString(), anyInt(), eq(mParentChannel), anyBoolean(), anyBoolean(),
+ anyInt(), anyBoolean());
+
+ // Verify that the content of parent channel is not changed.
+ assertThat(parentChannelCopy).isEqualTo(mParentChannel);
+ }
+
+ @Test
+ @RequiresFlagsEnabled(FLAG_NOTIFICATION_CONVERSATION_CHANNEL_MANAGEMENT)
+ public void createConversationChannelForPkgFromPrivilegedListener_cdm_noAccess() throws Exception {
+ // Set up cdm without access
+ mService.setPreferencesHelper(mPreferencesHelper);
+ when(mCompanionMgr.getAssociations(mPkg, mUserId))
+ .thenReturn(emptyList());
+
+ // Set up parent channel
+ setUpChannelsForConversationChannelTest();
+
+ try {
+ mBinderService.createConversationNotificationChannelForPackageFromPrivilegedListener(
+ null, mPkg, mUser, "parentId", "conversationId");
+ fail("listeners that don't have a companion device shouldn't be able to call this");
+ } catch (SecurityException e) {
+ // pass
+ }
+
+ verify(mPreferencesHelper, never()).createNotificationChannel(
+ anyString(), anyInt(), any(), anyBoolean(), anyBoolean(),
+ anyInt(), anyBoolean());
+ }
+
+ @Test
+ @RequiresFlagsEnabled(FLAG_NOTIFICATION_CONVERSATION_CHANNEL_MANAGEMENT)
+ public void createConversationChannelForPkgFromPrivilegedListener_assistant_success() throws Exception {
+ // Set up assistant
+ mService.setPreferencesHelper(mPreferencesHelper);
+ when(mCompanionMgr.getAssociations(mPkg, mUserId))
+ .thenReturn(emptyList());
+ when(mAssistants.isServiceTokenValidLocked(any())).thenReturn(true);
+
+ // Set up parent channel
+ setUpChannelsForConversationChannelTest();
+ final NotificationChannel parentChannelCopy = mParentChannel.copy();
+
+ NotificationChannel createdChannel =
+ mBinderService.createConversationNotificationChannelForPackageFromPrivilegedListener(
+ null, mPkg, mUser, PARENT_CHANNEL_ID, CONVERSATION_ID);
+
+ // Verify that a channel is created and a copied channel is returned.
+ verify(mPreferencesHelper, times(1)).createNotificationChannel(
+ eq(mPkg), eq(mUid), any(), anyBoolean(), anyBoolean(),
+ eq(mUid), anyBoolean());
+ assertThat(createdChannel).isNotSameInstanceAs(mConversationChannel);
+ assertThat(createdChannel).isEqualTo(mConversationChannel);
+
+ // Verify that the channel creation is not directly use the parent channel.
+ verify(mPreferencesHelper, never()).createNotificationChannel(
+ anyString(), anyInt(), eq(mParentChannel), anyBoolean(), anyBoolean(),
+ anyInt(), anyBoolean());
+
+ // Verify that the content of parent channel is not changed.
+ assertThat(parentChannelCopy).isEqualTo(mParentChannel);
+ }
+
+ @Test
+ @RequiresFlagsEnabled(FLAG_NOTIFICATION_CONVERSATION_CHANNEL_MANAGEMENT)
+ public void createConversationChannelForPkgFromPrivilegedListener_assistant_noAccess() throws Exception {
+ // Set up assistant without access
+ mService.setPreferencesHelper(mPreferencesHelper);
+ when(mCompanionMgr.getAssociations(mPkg, mUserId))
+ .thenReturn(emptyList());
+ when(mAssistants.isServiceTokenValidLocked(any())).thenReturn(false);
+
+ // Set up parent channel
+ setUpChannelsForConversationChannelTest();
+
+ try {
+ mBinderService.createConversationNotificationChannelForPackageFromPrivilegedListener(
+ null, mPkg, mUser, "parentId", "conversationId");
+ fail("listeners that don't have a companion device shouldn't be able to call this");
+ } catch (SecurityException e) {
+ // pass
+ }
+
+ verify(mPreferencesHelper, never()).createNotificationChannel(
+ anyString(), anyInt(), any(), anyBoolean(), anyBoolean(),
+ anyInt(), anyBoolean());
+ }
+
+ @Test
+ @RequiresFlagsEnabled(FLAG_NOTIFICATION_CONVERSATION_CHANNEL_MANAGEMENT)
+ public void createConversationChannelForPkgFromPrivilegedListener_badUser() throws Exception {
+ // Set up bad user
+ mService.setPreferencesHelper(mPreferencesHelper);
+ when(mCompanionMgr.getAssociations(mPkg, mUserId))
+ .thenReturn(singletonList(mock(AssociationInfo.class)));
+ mListener = mock(ManagedServices.ManagedServiceInfo.class);
+ mListener.component = new ComponentName(mPkg, mPkg);
+ when(mListener.enabledAndUserMatches(anyInt())).thenReturn(false);
+ when(mListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
+
+ // Set up parent channel
+ setUpChannelsForConversationChannelTest();
+
+ try {
+ mBinderService.createConversationNotificationChannelForPackageFromPrivilegedListener(
+ null, mPkg, mUser, "parentId", "conversationId");
+ fail("listener getting channels from a user they cannot see");
+ } catch (SecurityException e) {
+ // pass
+ }
+
+ verify(mPreferencesHelper, never()).createNotificationChannel(
+ anyString(), anyInt(), any(), anyBoolean(), anyBoolean(),
+ anyInt(), anyBoolean());
+ }
+
@Test
- public void testUpdateNotificationChannelFromPrivilegedListener_success() throws Exception {
+ public void updateNotificationChannelFromPrivilegedListener_cdm_success() throws Exception {
+
mService.setPreferencesHelper(mPreferencesHelper);
when(mCompanionMgr.getAssociations(mPkg, mUserId))
.thenReturn(singletonList(mock(AssociationInfo.class)));
@@ -4693,7 +4857,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
}
@Test
- public void testUpdateNotificationChannelFromPrivilegedListener_noAccess() throws Exception {
+ public void updateNotificationChannelFromPrivilegedListener_cdm_noAccess() throws Exception {
mService.setPreferencesHelper(mPreferencesHelper);
when(mCompanionMgr.getAssociations(mPkg, mUserId))
.thenReturn(emptyList());
@@ -4715,7 +4879,51 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
}
@Test
- public void testUpdateNotificationChannelFromPrivilegedListener_badUser() throws Exception {
+ public void updateNotificationChannelFromPrivilegedListener_assistant_success() throws Exception {
+ mService.setPreferencesHelper(mPreferencesHelper);
+ when(mCompanionMgr.getAssociations(mPkg, mUserId))
+ .thenReturn(emptyList());
+ when(mAssistants.isServiceTokenValidLocked(any())).thenReturn(true);
+ when(mPreferencesHelper.getNotificationChannel(eq(mPkg), anyInt(),
+ eq(mTestNotificationChannel.getId()), anyBoolean()))
+ .thenReturn(mTestNotificationChannel);
+
+ mBinderService.updateNotificationChannelFromPrivilegedListener(
+ null, mPkg, Process.myUserHandle(), mTestNotificationChannel);
+
+ verify(mPreferencesHelper, times(1)).updateNotificationChannel(
+ anyString(), anyInt(), any(), anyBoolean(), anyInt(), anyBoolean());
+
+ verify(mListeners, never()).notifyNotificationChannelChanged(eq(mPkg),
+ eq(Process.myUserHandle()), eq(mTestNotificationChannel),
+ eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED));
+ }
+
+ @Test
+ public void updateNotificationChannelFromPrivilegedListener_assistant_noAccess() throws Exception {
+ mService.setPreferencesHelper(mPreferencesHelper);
+ when(mCompanionMgr.getAssociations(mPkg, mUserId))
+ .thenReturn(emptyList());
+ when(mAssistants.isServiceTokenValidLocked(any())).thenReturn(false);
+
+ try {
+ mBinderService.updateNotificationChannelFromPrivilegedListener(
+ null, mPkg, Process.myUserHandle(), mTestNotificationChannel);
+ fail("listeners that don't have a companion device shouldn't be able to call this");
+ } catch (SecurityException e) {
+ // pass
+ }
+
+ verify(mPreferencesHelper, never()).updateNotificationChannel(
+ anyString(), anyInt(), any(), anyBoolean(), anyInt(), anyBoolean());
+
+ verify(mListeners, never()).notifyNotificationChannelChanged(eq(mPkg),
+ eq(Process.myUserHandle()), eq(mTestNotificationChannel),
+ eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED));
+ }
+
+ @Test
+ public void updateNotificationChannelFromPrivilegedListener_badUser() throws Exception {
mService.setPreferencesHelper(mPreferencesHelper);
when(mCompanionMgr.getAssociations(mPkg, mUserId))
.thenReturn(singletonList(mock(AssociationInfo.class)));
@@ -4741,7 +4949,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
}
@Test
- public void testUpdateNotificationChannelFromPrivilegedListener_noSoundUriPermission()
+ public void updateNotificationChannelFromPrivilegedListener_noSoundUriPermission()
throws Exception {
mService.setPreferencesHelper(mPreferencesHelper);
when(mCompanionMgr.getAssociations(mPkg, mUserId))
@@ -4773,7 +4981,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
}
@Test
- public void testUpdateNotificationChannelFromPrivilegedListener_noSoundUriPermission_sameSound()
+ public void updateNotificationChannelFromPrivilegedListener_noSoundUriPermission_sameSound()
throws Exception {
mService.setPreferencesHelper(mPreferencesHelper);
when(mCompanionMgr.getAssociations(mPkg, mUserId))
@@ -4805,7 +5013,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
@Test
public void
- testUpdateNotificationChannelFromPrivilegedListener_oldSoundNoUriPerm_newSoundHasUriPerm()
+ updateNotificationChannelFromPrivilegedListener_oldSoundNoUriPerm_newSoundHasUriPerm()
throws Exception {
mService.setPreferencesHelper(mPreferencesHelper);
when(mCompanionMgr.getAssociations(mPkg, mUserId))
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java
index bdf146fa94a8..3236f9501324 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java
@@ -528,8 +528,8 @@ public class ZenModeConfigTest extends UiServiceTestCase {
String xml = "<zen version=\"12\">\n"
+ "<allow calls=\"true\" repeatCallers=\"true\" messages=\"true\""
+ " reminders=\"false\" events=\"false\" callsFrom=\"2\" messagesFrom=\"2\""
- + " alarms=\"true\" media=\"true\" system=\"false\" convos=\"true\" convosFrom=\"2\""
- + " priorityChannelsAllowed=\"true\" />\n"
+ + " alarms=\"true\" media=\"true\" system=\"false\" convos=\"true\""
+ + " convosFrom=\"2\" priorityChannelsAllowed=\"true\" />\n"
+ "<disallow visualEffects=\"157\" />\n"
+ "<manual enabled=\"true\" zen=\"1\" creationTime=\"0\" modified=\"false\" />\n"
+ "<state areChannelsBypassingDnd=\"true\" />\n"
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppCompatActivityRobot.java b/services/tests/wmtests/src/com/android/server/wm/AppCompatActivityRobot.java
index 3742249bdffe..b8cfa7c39464 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppCompatActivityRobot.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppCompatActivityRobot.java
@@ -143,6 +143,10 @@ class AppCompatActivityRobot {
doReturn(naturalOrientation).when(mDisplayContent).getNaturalOrientation();
}
+ void setDisplayIgnoreActivitySizeRestrictions(boolean enabled) {
+ doReturn(enabled).when(mDisplayContent).isDisplayIgnoreActivitySizeRestrictions();
+ }
+
void configureTaskBounds(@NonNull Rect taskBounds) {
doReturn(taskBounds).when(mTaskStack.top()).getBounds();
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppCompatAspectRatioOverridesTest.java b/services/tests/wmtests/src/com/android/server/wm/AppCompatAspectRatioOverridesTest.java
index b83911337c5c..14ef913e28db 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppCompatAspectRatioOverridesTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppCompatAspectRatioOverridesTest.java
@@ -17,9 +17,12 @@
package com.android.server.wm;
import static android.content.pm.ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_3_2;
import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_FULLSCREEN;
+import static android.view.Surface.ROTATION_90;
import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE;
+import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE;
import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_FULLSCREEN_OVERRIDE;
import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE;
@@ -29,10 +32,13 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import android.compat.testing.PlatformCompatChangeRule;
+import android.platform.test.annotations.EnableFlags;
import android.platform.test.annotations.Presubmit;
import androidx.annotation.NonNull;
+import com.android.window.flags.Flags;
+
import libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges;
import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
@@ -288,6 +294,93 @@ public class AppCompatAspectRatioOverridesTest extends WindowTestsBase {
});
}
+ @Test
+ @EnableFlags(Flags.FLAG_VDM_FORCE_APP_UNIVERSAL_RESIZABLE_API)
+ public void testHasFullscreenOverride_displayIgnoreActivitySizeRestrictionsTrue() {
+ runTestScenario((robot) -> {
+ robot.applyOnActivity((a) -> {
+ a.setDisplayIgnoreActivitySizeRestrictions(true);
+ a.createActivityWithComponent();
+ });
+
+ robot.checkHasFullscreenOverride(true);
+ });
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_VDM_FORCE_APP_UNIVERSAL_RESIZABLE_API)
+ public void testHasFullscreenOverride_displayIgnoreActivitySizeRestrictionsFalse() {
+ runTestScenario((robot) -> {
+ robot.applyOnActivity((a) -> {
+ a.setDisplayIgnoreActivitySizeRestrictions(false);
+ a.createActivityWithComponent();
+ });
+
+ robot.checkHasFullscreenOverride(false);
+ });
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_VDM_FORCE_APP_UNIVERSAL_RESIZABLE_API)
+ public void testPropFalse_displayIgnoreActivitySizeRestrictionsTrue_notOverridden() {
+ runTestScenario((robot) -> {
+ robot.prop().disable(PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE);
+ robot.applyOnActivity((a) -> {
+ a.setDisplayIgnoreActivitySizeRestrictions(true);
+ a.createActivityWithComponent();
+ });
+
+ robot.checkHasFullscreenOverride(false);
+ });
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_VDM_FORCE_APP_UNIVERSAL_RESIZABLE_API)
+ public void testPropTrue_displayIgnoreActivitySizeRestrictionsFalse_notOverridden() {
+ runTestScenario((robot) -> {
+ robot.prop().enable(PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE);
+ robot.applyOnActivity((a) -> {
+ a.setDisplayIgnoreActivitySizeRestrictions(false);
+ a.createActivityWithComponent();
+ });
+
+ robot.checkHasFullscreenOverride(false);
+ });
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_VDM_FORCE_APP_UNIVERSAL_RESIZABLE_API)
+ public void testNotInSizeCompatMode_displayIgnoreActivitySizeRestrictionsTrue() {
+ runTestScenario((robot) -> {
+ robot.applyOnActivity((a) -> {
+ a.createActivityWithComponent();
+ a.setDisplayIgnoreActivitySizeRestrictions(true);
+ a.configureTopActivity(/* minAspect */ -1f, /* maxAspect */-1f,
+ SCREEN_ORIENTATION_LANDSCAPE, true);
+ a.rotateDisplayForTopActivity(ROTATION_90);
+
+ a.checkTopActivityInSizeCompatMode(false);
+ });
+ });
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_VDM_FORCE_APP_UNIVERSAL_RESIZABLE_API)
+ public void testInSizeCompatMode_displayIgnoreActivitySizeRestrictionsFalse() {
+ runTestScenario((robot) -> {
+ robot.applyOnActivity((a) -> {
+ a.createActivityWithComponent();
+ a.setIgnoreOrientationRequest(true);
+ a.setDisplayIgnoreActivitySizeRestrictions(false);
+ a.configureTopActivity(/* minAspect */ -1f, /* maxAspect */-1f,
+ SCREEN_ORIENTATION_LANDSCAPE, true);
+ a.rotateDisplayForTopActivity(ROTATION_90);
+
+ a.checkTopActivityInSizeCompatMode(true);
+ });
+ });
+ }
+
/**
* Runs a test scenario providing a Robot.
*/
@@ -366,6 +459,11 @@ public class AppCompatAspectRatioOverridesTest extends WindowTestsBase {
}
}
+ void checkHasFullscreenOverride(boolean expected) {
+ assertEquals(expected,
+ getTopActivityAppCompatAspectRatioOverrides().hasFullscreenOverride());
+ }
+
private AppCompatAspectRatioOverrides getTopActivityAppCompatAspectRatioOverrides() {
return activity().top().mAppCompatController.getAppCompatAspectRatioOverrides();
}
diff --git a/test-mock/src/android/test/mock/MockContext.java b/test-mock/src/android/test/mock/MockContext.java
index 6bf7ff501217..3247d1fe5222 100644
--- a/test-mock/src/android/test/mock/MockContext.java
+++ b/test-mock/src/android/test/mock/MockContext.java
@@ -53,6 +53,7 @@ import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.util.List;
import java.util.concurrent.Executor;
/**
@@ -607,6 +608,12 @@ public class MockContext extends Context {
throw new UnsupportedOperationException();
}
+ /** @hide */
+ @Override
+ public List<IntentFilter> getRegisteredIntentFilters(BroadcastReceiver receiver) {
+ throw new UnsupportedOperationException();
+ }
+
@Override
public ComponentName startService(Intent service) {
throw new UnsupportedOperationException();
diff --git a/tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt b/tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt
index 19dea0c5e74a..a7e22141e56f 100644
--- a/tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt
+++ b/tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt
@@ -884,6 +884,86 @@ class KeyGestureControllerTests {
}
@Test
+ @EnableFlags(com.android.window.flags.Flags.FLAG_ENABLE_TASK_RESIZING_KEYBOARD_SHORTCUTS)
+ fun testSnapLeftFreeformTask() {
+ val keyGestureController = KeyGestureController(context, testLooper.looper)
+ testKeyGestureInternal(
+ keyGestureController,
+ TestData(
+ "ALT + [ -> Resizes a task to fit the left half of the screen",
+ intArrayOf(
+ KeyEvent.KEYCODE_ALT_LEFT,
+ KeyEvent.KEYCODE_LEFT_BRACKET
+ ),
+ KeyGestureEvent.KEY_GESTURE_TYPE_SNAP_LEFT_FREEFORM_WINDOW,
+ intArrayOf(KeyEvent.KEYCODE_LEFT_BRACKET),
+ KeyEvent.META_ALT_ON,
+ intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE)
+ )
+ )
+ }
+
+ @Test
+ @EnableFlags(com.android.window.flags.Flags.FLAG_ENABLE_TASK_RESIZING_KEYBOARD_SHORTCUTS)
+ fun testSnapRightFreeformTask() {
+ val keyGestureController = KeyGestureController(context, testLooper.looper)
+ testKeyGestureInternal(
+ keyGestureController,
+ TestData(
+ "ALT + ] -> Resizes a task to fit the right half of the screen",
+ intArrayOf(
+ KeyEvent.KEYCODE_ALT_LEFT,
+ KeyEvent.KEYCODE_RIGHT_BRACKET
+ ),
+ KeyGestureEvent.KEY_GESTURE_TYPE_SNAP_RIGHT_FREEFORM_WINDOW,
+ intArrayOf(KeyEvent.KEYCODE_RIGHT_BRACKET),
+ KeyEvent.META_ALT_ON,
+ intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE)
+ )
+ )
+ }
+
+ @Test
+ @EnableFlags(com.android.window.flags.Flags.FLAG_ENABLE_TASK_RESIZING_KEYBOARD_SHORTCUTS)
+ fun testMaximizeFreeformTask() {
+ val keyGestureController = KeyGestureController(context, testLooper.looper)
+ testKeyGestureInternal(
+ keyGestureController,
+ TestData(
+ "ALT + '=' -> Maximizes a task to fit the screen",
+ intArrayOf(
+ KeyEvent.KEYCODE_ALT_LEFT,
+ KeyEvent.KEYCODE_EQUALS
+ ),
+ KeyGestureEvent.KEY_GESTURE_TYPE_MAXIMIZE_FREEFORM_WINDOW,
+ intArrayOf(KeyEvent.KEYCODE_EQUALS),
+ KeyEvent.META_ALT_ON,
+ intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE)
+ )
+ )
+ }
+
+ @Test
+ @EnableFlags(com.android.window.flags.Flags.FLAG_ENABLE_TASK_RESIZING_KEYBOARD_SHORTCUTS)
+ fun testRestoreFreeformTask() {
+ val keyGestureController = KeyGestureController(context, testLooper.looper)
+ testKeyGestureInternal(
+ keyGestureController,
+ TestData(
+ "ALT + '-' -> Restores a task size to its previous bounds",
+ intArrayOf(
+ KeyEvent.KEYCODE_ALT_LEFT,
+ KeyEvent.KEYCODE_MINUS
+ ),
+ KeyGestureEvent.KEY_GESTURE_TYPE_RESTORE_FREEFORM_WINDOW_SIZE,
+ intArrayOf(KeyEvent.KEYCODE_MINUS),
+ KeyEvent.META_ALT_ON,
+ intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE)
+ )
+ )
+ }
+
+ @Test
fun testCapsLockPressNotified() {
val keyGestureController = KeyGestureController(context, testLooper.looper)
val listener = KeyGestureEventListener()
diff --git a/tests/graphics/HwAccelerationTest/AndroidManifest.xml b/tests/graphics/HwAccelerationTest/AndroidManifest.xml
index db3a992b9c7b..05b2f4c53b15 100644
--- a/tests/graphics/HwAccelerationTest/AndroidManifest.xml
+++ b/tests/graphics/HwAccelerationTest/AndroidManifest.xml
@@ -24,7 +24,7 @@
<uses-feature android:name="android.hardware.camera"/>
<uses-feature android:name="android.hardware.camera.autofocus"/>
- <uses-sdk android:minSdkVersion="21"/>
+ <uses-sdk android:minSdkVersion="21" />
<application android:label="HwUi"
android:theme="@android:style/Theme.Material.Light">
@@ -409,6 +409,24 @@
</intent-filter>
</activity>
+ <activity android:name="ScrollingZAboveSurfaceView"
+ android:label="SurfaceView/Z-Above scrolling"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="com.android.test.hwui.TEST"/>
+ </intent-filter>
+ </activity>
+
+ <activity android:name="ScrollingZAboveScaledSurfaceView"
+ android:label="SurfaceView/Z-Above scrolling, scaled surface"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="com.android.test.hwui.TEST"/>
+ </intent-filter>
+ </activity>
+
<activity android:name="StretchySurfaceViewActivity"
android:label="SurfaceView/Stretchy Movement"
android:exported="true">
diff --git a/tests/graphics/HwAccelerationTest/res/layout/scrolling_zabove_surfaceview.xml b/tests/graphics/HwAccelerationTest/res/layout/scrolling_zabove_surfaceview.xml
new file mode 100644
index 000000000000..31e5774dd1ad
--- /dev/null
+++ b/tests/graphics/HwAccelerationTest/res/layout/scrolling_zabove_surfaceview.xml
@@ -0,0 +1,131 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ 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.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ tools:context=".MainActivity">
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="Above the ScrollView"
+ android:textColor="#FFFFFFFF"
+ android:background="#FF444444"
+ android:padding="32dp" />
+
+ <ScrollView
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="Scrolling Header"
+ android:background="#FFCCCCCC"
+ android:padding="32dp" />
+
+ <SurfaceView
+ android:layout_width="match_parent"
+ android:layout_height="500dp"
+ android:id="@+id/surfaceview" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="Scrolling Item"
+ android:background="#FFCCCCCC"
+ android:padding="32dp" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="Scrolling Item"
+ android:background="#FFCCCCCC"
+ android:padding="32dp" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="Scrolling Item"
+ android:background="#FFCCCCCC"
+ android:padding="32dp" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="Scrolling Item"
+ android:background="#FFCCCCCC"
+ android:padding="32dp" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="Scrolling Item"
+ android:background="#FFCCCCCC"
+ android:padding="32dp" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="Scrolling Item"
+ android:background="#FFCCCCCC"
+ android:padding="32dp" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="Scrolling Item"
+ android:background="#FFCCCCCC"
+ android:padding="32dp" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="Scrolling Item"
+ android:background="#FFCCCCCC"
+ android:padding="32dp" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="Scrolling Item"
+ android:background="#FFCCCCCC"
+ android:padding="32dp" />
+
+ </LinearLayout>
+
+ </ScrollView>
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="Below the ScrollView"
+ android:textColor="#FFFFFFFF"
+ android:background="#FF444444"
+ android:padding="32dp" />
+
+</LinearLayout> \ No newline at end of file
diff --git a/tests/graphics/HwAccelerationTest/src/com/android/test/hwui/ScrollingZAboveScaledSurfaceView.kt b/tests/graphics/HwAccelerationTest/src/com/android/test/hwui/ScrollingZAboveScaledSurfaceView.kt
new file mode 100644
index 000000000000..59ae885664db
--- /dev/null
+++ b/tests/graphics/HwAccelerationTest/src/com/android/test/hwui/ScrollingZAboveScaledSurfaceView.kt
@@ -0,0 +1,58 @@
+/*
+ * 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.test.hwui
+
+import android.app.Activity
+import android.graphics.Color
+import android.graphics.Paint
+import android.os.Bundle
+import android.view.SurfaceHolder
+import android.view.SurfaceView
+
+class ScrollingZAboveScaledSurfaceView : Activity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.scrolling_zabove_surfaceview)
+
+ findViewById<SurfaceView>(R.id.surfaceview).apply {
+ setZOrderOnTop(true)
+ holder.setFixedSize(1000, 2000)
+ holder.addCallback(object : SurfaceHolder.Callback {
+ override fun surfaceCreated(p0: SurfaceHolder) {
+
+ }
+
+ override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) {
+ holder.unlockCanvasAndPost(holder.lockCanvas().apply {
+ drawColor(Color.BLUE)
+ val paint = Paint()
+ paint.textSize = 16 * resources.displayMetrics.density
+ paint.textAlign = Paint.Align.CENTER
+ paint.color = Color.WHITE
+ drawText("I'm a setZOrderOnTop(true) SurfaceView!",
+ (width / 2).toFloat(), (height / 2).toFloat(), paint)
+ })
+ }
+
+ override fun surfaceDestroyed(p0: SurfaceHolder) {
+
+ }
+
+ })
+ }
+ }
+} \ No newline at end of file
diff --git a/tests/graphics/HwAccelerationTest/src/com/android/test/hwui/ScrollingZAboveSurfaceView.kt b/tests/graphics/HwAccelerationTest/src/com/android/test/hwui/ScrollingZAboveSurfaceView.kt
new file mode 100644
index 000000000000..ccb71ec0ff2a
--- /dev/null
+++ b/tests/graphics/HwAccelerationTest/src/com/android/test/hwui/ScrollingZAboveSurfaceView.kt
@@ -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.
+ */
+
+package com.android.test.hwui
+
+import android.app.Activity
+import android.graphics.Color
+import android.graphics.Paint
+import android.os.Bundle
+import android.view.SurfaceHolder
+import android.view.SurfaceView
+
+class ScrollingZAboveSurfaceView : Activity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.scrolling_zabove_surfaceview)
+
+ findViewById<SurfaceView>(R.id.surfaceview).apply {
+ setZOrderOnTop(true)
+ holder.addCallback(object : SurfaceHolder.Callback {
+ override fun surfaceCreated(p0: SurfaceHolder) {
+
+ }
+
+ override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) {
+ holder.unlockCanvasAndPost(holder.lockCanvas().apply {
+ drawColor(Color.BLUE)
+ val paint = Paint()
+ paint.textSize = 16 * resources.displayMetrics.density
+ paint.textAlign = Paint.Align.CENTER
+ paint.color = Color.WHITE
+ drawText("I'm a setZOrderOnTop(true) SurfaceView!",
+ (width / 2).toFloat(), (height / 2).toFloat(), paint)
+ })
+ }
+
+ override fun surfaceDestroyed(p0: SurfaceHolder) {
+
+ }
+
+ })
+ }
+ }
+} \ No newline at end of file