summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AconfigFlags.bp10
-rw-r--r--Android.bp74
-rw-r--r--BAL_OWNERS5
-rw-r--r--apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java7
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java12
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java33
-rw-r--r--apex/jobscheduler/service/java/com/android/server/tare/InternalResourceService.java8
-rw-r--r--core/api/current.txt64
-rw-r--r--core/api/system-current.txt5
-rw-r--r--core/java/android/app/AppOpsManager.java68
-rw-r--r--core/java/android/app/AppOpsManagerInternal.java51
-rw-r--r--core/java/android/app/ApplicationPackageManager.java6
-rw-r--r--core/java/android/app/OWNERS1
-rw-r--r--core/java/android/app/notification.aconfig8
-rw-r--r--core/java/android/appwidget/AppWidgetManager.java89
-rw-r--r--core/java/android/companion/virtual/VirtualDeviceManager.java3
-rw-r--r--core/java/android/companion/virtual/flags.aconfig7
-rw-r--r--core/java/android/content/AttributionSource.java6
-rw-r--r--core/java/android/content/Intent.java5
-rw-r--r--core/java/android/content/pm/ArchivedActivityInfo.java (renamed from core/java/android/content/pm/ArchivedActivity.java)26
-rw-r--r--core/java/android/content/pm/ArchivedPackageInfo.java (renamed from core/java/android/content/pm/ArchivedPackage.java)44
-rw-r--r--core/java/android/content/pm/PackageInstaller.java11
-rw-r--r--core/java/android/content/pm/PackageManager.java2
-rw-r--r--core/java/android/content/res/StringBlock.java55
-rw-r--r--core/java/android/credentials/CredentialManager.java9
-rw-r--r--core/java/android/os/BatteryManager.java2
-rw-r--r--core/java/android/text/TextUtils.java9
-rw-r--r--core/java/android/text/style/LineBreakConfigSpan.java96
-rw-r--r--core/java/android/view/AttachedSurfaceControl.java19
-rw-r--r--core/java/android/view/SurfaceControlRegistry.java4
-rw-r--r--core/java/android/view/ViewRootImpl.java52
-rw-r--r--core/java/android/view/accessibility/flags/accessibility_flags.aconfig7
-rw-r--r--core/java/android/view/contentcapture/ContentCaptureManager.java6
-rw-r--r--core/java/android/view/contentcapture/MainContentCaptureSession.java15
-rw-r--r--core/java/android/view/contentprotection/flags/content_protection_flags.aconfig7
-rw-r--r--core/java/android/widget/RemoteViews.java220
-rw-r--r--core/java/android/window/ITaskFragmentOrganizerController.aidl6
-rw-r--r--core/java/android/window/TaskFragmentOrganizer.java26
-rw-r--r--core/java/android/window/WindowTokenClient.java5
-rw-r--r--core/java/android/window/flags/responsible_apis.aconfig22
-rw-r--r--core/java/android/window/flags/wallpaper_manager.aconfig8
-rw-r--r--core/java/android/window/flags/window_surfaces.aconfig8
-rw-r--r--core/java/com/android/internal/accessibility/AccessibilityShortcutController.java24
-rw-r--r--core/java/com/android/internal/accessibility/common/ShortcutConstants.java11
-rw-r--r--core/java/com/android/internal/accessibility/dialog/InvisibleToggleAccessibilityServiceTarget.java26
-rw-r--r--core/java/com/android/internal/accessibility/util/ShortcutUtils.java97
-rw-r--r--core/java/com/android/internal/app/IAppOpsService.aidl39
-rw-r--r--core/java/com/android/internal/config/sysui/SystemUiSystemPropertiesFlags.java4
-rw-r--r--core/java/com/android/internal/content/PackageMonitor.java6
-rw-r--r--core/res/AndroidManifest.xml1
-rw-r--r--core/res/res/drawable/archived_app_cloud_overlay.xml15
-rw-r--r--core/res/res/values/symbols.xml1
-rw-r--r--core/tests/coretests/src/android/app/OWNERS4
-rw-r--r--core/tests/coretests/src/android/os/PowerManagerTest.java34
-rw-r--r--core/tests/coretests/src/android/view/ViewRootImplTest.java20
-rw-r--r--core/tests/coretests/src/android/view/contentcapture/ContentCaptureManagerTest.java47
-rw-r--r--core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java66
-rw-r--r--core/tests/coretests/src/com/android/internal/accessibility/TestUtils.java39
-rw-r--r--core/tests/coretests/src/com/android/internal/accessibility/dialog/InvisibleToggleAccessibilityServiceTargetTest.java182
-rw-r--r--core/tests/coretests/src/com/android/internal/accessibility/util/AccessibilityUtilsTest.java (renamed from core/tests/coretests/src/com/android/internal/accessibility/AccessibilityUtilsTest.java)6
-rw-r--r--core/tests/coretests/src/com/android/internal/accessibility/util/ShortcutUtilsTest.java358
-rw-r--r--core/tests/packagemonitortests/src/com/android/internal/content/PackageMonitorTest.java37
-rw-r--r--data/etc/services.core.protolog.json6
-rw-r--r--graphics/java/android/graphics/text/LineBreakConfig.java42
-rw-r--r--libs/WindowManager/Shell/res/layout/bubble_manage_menu.xml9
-rw-r--r--libs/WindowManager/Shell/tests/flicker/Android.bp270
-rw-r--r--libs/WindowManager/Shell/tests/flicker/appcompat/Android.bp41
-rw-r--r--libs/WindowManager/Shell/tests/flicker/appcompat/AndroidManifest.xml (renamed from libs/WindowManager/Shell/tests/flicker/manifests/AndroidManifest.xml)35
-rw-r--r--libs/WindowManager/Shell/tests/flicker/appcompat/AndroidTestTemplate.xml109
-rw-r--r--libs/WindowManager/Shell/tests/flicker/appcompat/res/xml/network_security_config.xml (renamed from libs/WindowManager/Shell/tests/flicker/res/xml/network_security_config.xml)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/appcompat/src/com/android/wm/shell/flicker/appcompat/BaseAppCompat.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/BaseAppCompat.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/appcompat/src/com/android/wm/shell/flicker/appcompat/LetterboxRule.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/LetterboxRule.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/appcompat/src/com/android/wm/shell/flicker/appcompat/OpenAppInSizeCompatModeTest.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/OpenAppInSizeCompatModeTest.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/appcompat/src/com/android/wm/shell/flicker/appcompat/OpenTransparentActivityTest.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/OpenTransparentActivityTest.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/appcompat/src/com/android/wm/shell/flicker/appcompat/QuickSwitchLauncherToLetterboxAppTest.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/QuickSwitchLauncherToLetterboxAppTest.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/appcompat/src/com/android/wm/shell/flicker/appcompat/RepositionFixedPortraitAppTest.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/RepositionFixedPortraitAppTest.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/appcompat/src/com/android/wm/shell/flicker/appcompat/RestartAppInSizeCompatModeTest.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/RestartAppInSizeCompatModeTest.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/appcompat/src/com/android/wm/shell/flicker/appcompat/RotateImmersiveAppInFullscreenTest.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/RotateImmersiveAppInFullscreenTest.kt)61
-rw-r--r--libs/WindowManager/Shell/tests/flicker/appcompat/src/com/android/wm/shell/flicker/appcompat/TransparentBaseAppCompat.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/TransparentBaseAppCompat.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/appcompat/trace_config/trace_config.textproto75
-rw-r--r--libs/WindowManager/Shell/tests/flicker/bubble/Android.bp34
-rw-r--r--libs/WindowManager/Shell/tests/flicker/bubble/AndroidManifest.xml77
-rw-r--r--libs/WindowManager/Shell/tests/flicker/bubble/AndroidTestTemplate.xml109
-rw-r--r--libs/WindowManager/Shell/tests/flicker/bubble/OWNERS (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/OWNERS)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/bubble/res/xml/network_security_config.xml (renamed from libs/WindowManager/Shell/tests/flicker/manifests/AndroidManifestOther.xml)14
-rw-r--r--libs/WindowManager/Shell/tests/flicker/bubble/src/com/android/wm/shell/flicker/bubble/BaseBubbleScreen.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/BaseBubbleScreen.kt)10
-rw-r--r--libs/WindowManager/Shell/tests/flicker/bubble/src/com/android/wm/shell/flicker/bubble/ChangeActiveActivityFromBubbleTest.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/ChangeActiveActivityFromBubbleTest.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/bubble/src/com/android/wm/shell/flicker/bubble/DragToDismissBubbleScreenTest.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/DragToDismissBubbleScreenTest.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/bubble/src/com/android/wm/shell/flicker/bubble/OpenActivityFromBubbleOnLocksreenTest.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/OpenActivityFromBubbleOnLocksreenTest.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/bubble/src/com/android/wm/shell/flicker/bubble/OpenActivityFromBubbleTest.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/OpenActivityFromBubbleTest.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/bubble/src/com/android/wm/shell/flicker/bubble/SendBubbleNotificationTest.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/SendBubbleNotificationTest.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/bubble/trace_config/trace_config.textproto75
-rw-r--r--libs/WindowManager/Shell/tests/flicker/manifests/AndroidManifestPip.xml27
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/Android.bp136
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/AndroidManifest.xml80
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/AndroidTestTemplate.xml109
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/OWNERS (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/OWNERS)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/csuiteDefaultTemplate.xml (renamed from libs/WindowManager/Shell/tests/flicker/csuiteDefaultTemplate.xml)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/res/xml/network_security_config.xml (renamed from libs/WindowManager/Shell/tests/flicker/manifests/AndroidManifestBubbles.xml)14
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/AutoEnterPipFromSplitScreenOnGoToHomeTest.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/AutoEnterPipFromSplitScreenOnGoToHomeTest.kt)13
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/AutoEnterPipOnGoToHomeTest.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/AutoEnterPipOnGoToHomeTest.kt)9
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ClosePipBySwipingDownTest.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipBySwipingDownTest.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ClosePipWithDismissButtonTest.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipWithDismissButtonTest.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTest.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTest.kt)6
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipViaAppUiButtonTest.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipViaAppUiButtonTest.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaExpandButtonTest.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaExpandButtonTest.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaIntentTest.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaIntentTest.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ExpandPipOnPinchOpenTest.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnPinchOpenTest.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/MovePipDownOnShelfHeightChange.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipDownOnShelfHeightChange.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/MovePipOnImeVisibilityChangeTest.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipOnImeVisibilityChangeTest.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/MovePipUpOnShelfHeightChangeTest.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipUpOnShelfHeightChangeTest.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/PipAspectRatioChangeTest.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipAspectRatioChangeTest.kt)4
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/PipDragTest.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipDragTest.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/PipDragThenSnapTest.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipDragThenSnapTest.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/PipPinchInTest.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipPinchInTest.kt)4
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinned.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinned.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ShowPipAndRotateDisplay.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ShowPipAndRotateDisplay.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/AppsEnterPipTransition.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/apps/AppsEnterPipTransition.kt)12
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/MapsEnterPipTest.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/apps/MapsEnterPipTest.kt)31
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/NetflixEnterPipTest.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/apps/NetflixEnterPipTest.kt)16
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/YouTubeEnterPipTest.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/apps/YouTubeEnterPipTest.kt)8
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/common/ClosePipTransition.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/common/ClosePipTransition.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/common/EnterPipTransition.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/common/EnterPipTransition.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/common/ExitPipToAppTransition.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/common/ExitPipToAppTransition.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/common/MovePipShelfHeightTransition.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/common/MovePipShelfHeightTransition.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/common/PipTransition.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/common/PipTransition.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/tv/PipAppHelperTv.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/PipAppHelperTv.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/tv/PipTestBase.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/PipTestBase.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/tv/TvPipBasicTest.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvPipBasicTest.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/tv/TvPipMenuTests.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvPipMenuTests.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/tv/TvPipNotificationTests.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvPipNotificationTests.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/tv/TvPipTestBase.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvPipTestBase.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/tv/TvUtils.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvUtils.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/trace_config/trace_config.textproto75
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/Android.bp67
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/AndroidManifest.xml77
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/AndroidTestTemplate.xml109
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/res/xml/network_security_config.xml (renamed from libs/WindowManager/Shell/tests/flicker/manifests/AndroidManifestSplitScreen.xml)14
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/common/Utils.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/common/Utils.kt)4
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/OWNERS (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/OWNERS)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/CopyContentInSplitGesturalNavLandscape.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/CopyContentInSplitGesturalNavLandscape.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/CopyContentInSplitGesturalNavPortrait.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/CopyContentInSplitGesturalNavPortrait.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByDividerGesturalNavLandscape.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByDividerGesturalNavLandscape.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByDividerGesturalNavPortrait.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByDividerGesturalNavPortrait.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByGoHomeGesturalNavLandscape.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByGoHomeGesturalNavLandscape.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByGoHomeGesturalNavPortrait.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByGoHomeGesturalNavPortrait.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DragDividerToResizeGesturalNavLandscape.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DragDividerToResizeGesturalNavLandscape.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DragDividerToResizeGesturalNavPortrait.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DragDividerToResizeGesturalNavPortrait.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromAllAppsGesturalNavLandscape.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromAllAppsGesturalNavLandscape.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromAllAppsGesturalNavPortrait.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromAllAppsGesturalNavPortrait.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromNotificationGesturalNavLandscape.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromNotificationGesturalNavLandscape.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromNotificationGesturalNavPortrait.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromNotificationGesturalNavPortrait.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromShortcutGesturalNavLandscape.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromShortcutGesturalNavLandscape.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromShortcutGesturalNavPortrait.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromShortcutGesturalNavPortrait.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromTaskbarGesturalNavLandscape.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromTaskbarGesturalNavLandscape.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromTaskbarGesturalNavPortrait.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromTaskbarGesturalNavPortrait.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenFromOverviewGesturalNavLandscape.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenFromOverviewGesturalNavLandscape.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenFromOverviewGesturalNavPortrait.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenFromOverviewGesturalNavPortrait.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchAppByDoubleTapDividerGesturalNavLandscape.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchAppByDoubleTapDividerGesturalNavLandscape.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchAppByDoubleTapDividerGesturalNavPortrait.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchAppByDoubleTapDividerGesturalNavPortrait.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromAnotherAppGesturalNavLandscape.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromAnotherAppGesturalNavLandscape.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromAnotherAppGesturalNavPortrait.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromAnotherAppGesturalNavPortrait.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromHomeGesturalNavLandscape.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromHomeGesturalNavLandscape.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromHomeGesturalNavPortrait.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromHomeGesturalNavPortrait.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromRecentGesturalNavLandscape.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromRecentGesturalNavLandscape.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromRecentGesturalNavPortrait.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromRecentGesturalNavPortrait.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBetweenSplitPairsGesturalNavLandscape.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBetweenSplitPairsGesturalNavLandscape.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBetweenSplitPairsGesturalNavPortrait.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBetweenSplitPairsGesturalNavPortrait.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/UnlockKeyguardToSplitScreenGesturalNavLandscape.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/UnlockKeyguardToSplitScreenGesturalNavLandscape.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/UnlockKeyguardToSplitScreenGesturalNavPortrait.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/UnlockKeyguardToSplitScreenGesturalNavPortrait.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/CopyContentInSplitGesturalNavLandscape.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/CopyContentInSplitGesturalNavLandscape.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/CopyContentInSplitGesturalNavPortrait.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/CopyContentInSplitGesturalNavPortrait.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByDividerGesturalNavLandscape.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByDividerGesturalNavLandscape.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByDividerGesturalNavPortrait.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByDividerGesturalNavPortrait.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByGoHomeGesturalNavLandscape.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByGoHomeGesturalNavLandscape.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByGoHomeGesturalNavPortrait.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByGoHomeGesturalNavPortrait.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DragDividerToResizeGesturalNavLandscape.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DragDividerToResizeGesturalNavLandscape.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DragDividerToResizeGesturalNavPortrait.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DragDividerToResizeGesturalNavPortrait.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromAllAppsGesturalNavLandscape.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromAllAppsGesturalNavLandscape.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromAllAppsGesturalNavPortrait.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromAllAppsGesturalNavPortrait.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromNotificationGesturalNavLandscape.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromNotificationGesturalNavLandscape.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromNotificationGesturalNavPortrait.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromNotificationGesturalNavPortrait.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromShortcutGesturalNavLandscape.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromShortcutGesturalNavLandscape.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromShortcutGesturalNavPortrait.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromShortcutGesturalNavPortrait.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromTaskbarGesturalNavLandscape.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromTaskbarGesturalNavLandscape.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromTaskbarGesturalNavPortrait.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromTaskbarGesturalNavPortrait.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenFromOverviewGesturalNavLandscape.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenFromOverviewGesturalNavLandscape.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenFromOverviewGesturalNavPortrait.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenFromOverviewGesturalNavPortrait.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchAppByDoubleTapDividerGesturalNavLandscape.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchAppByDoubleTapDividerGesturalNavLandscape.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchAppByDoubleTapDividerGesturalNavPortrait.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchAppByDoubleTapDividerGesturalNavPortrait.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromAnotherAppGesturalNavLandscape.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromAnotherAppGesturalNavLandscape.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromAnotherAppGesturalNavPortrait.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromAnotherAppGesturalNavPortrait.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromHomeGesturalNavLandscape.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromHomeGesturalNavLandscape.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromHomeGesturalNavPortrait.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromHomeGesturalNavPortrait.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromRecentGesturalNavLandscape.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromRecentGesturalNavLandscape.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromRecentGesturalNavPortrait.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromRecentGesturalNavPortrait.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBetweenSplitPairsGesturalNavLandscape.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBetweenSplitPairsGesturalNavLandscape.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBetweenSplitPairsGesturalNavPortrait.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBetweenSplitPairsGesturalNavPortrait.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/UnlockKeyguardToSplitScreenGesturalNavLandscape.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/UnlockKeyguardToSplitScreenGesturalNavLandscape.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/UnlockKeyguardToSplitScreenGesturalNavPortrait.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/UnlockKeyguardToSplitScreenGesturalNavPortrait.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/CopyContentInSplit.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/CopyContentInSplit.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DismissSplitScreenByDivider.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DismissSplitScreenByDivider.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DismissSplitScreenByGoHome.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DismissSplitScreenByGoHome.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DragDividerToResize.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DragDividerToResize.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromAllApps.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromAllApps.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromNotification.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromNotification.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromShortcut.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromShortcut.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromTaskbar.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromTaskbar.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenFromOverview.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenFromOverview.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchAppByDoubleTapDivider.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchAppByDoubleTapDivider.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromAnotherApp.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromAnotherApp.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromHome.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromHome.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromRecent.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromRecent.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBetweenSplitPairs.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBetweenSplitPairs.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/UnlockKeyguardToSplitScreen.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/UnlockKeyguardToSplitScreen.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/service/trace_config/trace_config.textproto75
-rw-r--r--libs/WindowManager/Shell/tests/flicker/splitscreen/Android.bp77
-rw-r--r--libs/WindowManager/Shell/tests/flicker/splitscreen/AndroidManifest.xml77
-rw-r--r--libs/WindowManager/Shell/tests/flicker/splitscreen/AndroidTestTemplate.xml109
-rw-r--r--libs/WindowManager/Shell/tests/flicker/splitscreen/OWNERS (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/OWNERS)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/splitscreen/res/xml/network_security_config.xml (renamed from libs/WindowManager/Shell/tests/flicker/manifests/AndroidManifestService.xml)14
-rw-r--r--libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/CopyContentInSplit.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/CopyContentInSplit.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByDivider.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByDivider.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/DragDividerToResize.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DragDividerToResize.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromAllApps.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromAllApps.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromNotification.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromNotification.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromShortcut.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromShortcut.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromTaskbar.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromTaskbar.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenFromOverview.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenFromOverview.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/SwitchAppByDoubleTapDivider.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchAppByDoubleTapDivider.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromAnotherApp.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromAnotherApp.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromHome.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromHome.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromRecent.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromRecent.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairs.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairs.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairsNoPip.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairsNoPip.kt)20
-rw-r--r--libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/UnlockKeyguardToSplitScreen.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/UnlockKeyguardToSplitScreen.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/CopyContentInSplitBenchmark.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/CopyContentInSplitBenchmark.kt)12
-rw-r--r--libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByDividerBenchmark.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByDividerBenchmark.kt)12
-rw-r--r--libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByGoHomeBenchmark.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByGoHomeBenchmark.kt)10
-rw-r--r--libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/DragDividerToResizeBenchmark.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DragDividerToResizeBenchmark.kt)12
-rw-r--r--libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromAllAppsBenchmark.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromAllAppsBenchmark.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromNotificationBenchmark.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromNotificationBenchmark.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromShortcutBenchmark.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromShortcutBenchmark.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromTaskbarBenchmark.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromTaskbarBenchmark.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenFromOverviewBenchmark.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenFromOverviewBenchmark.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/SplitScreenBase.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SplitScreenBase.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchAppByDoubleTapDividerBenchmark.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchAppByDoubleTapDividerBenchmark.kt)12
-rw-r--r--libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromAnotherAppBenchmark.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromAnotherAppBenchmark.kt)10
-rw-r--r--libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromHomeBenchmark.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromHomeBenchmark.kt)10
-rw-r--r--libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromRecentBenchmark.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromRecentBenchmark.kt)10
-rw-r--r--libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBetweenSplitPairsBenchmark.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBetweenSplitPairsBenchmark.kt)20
-rw-r--r--libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/UnlockKeyguardToSplitScreenBenchmark.kt (renamed from libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/UnlockKeyguardToSplitScreenBenchmark.kt)0
-rw-r--r--libs/WindowManager/Shell/tests/flicker/splitscreen/trace_config/trace_config.textproto75
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/BaseTest.kt2
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/SplitScreenUtils.kt11
-rw-r--r--libs/hwui/tests/common/TestUtils.cpp10
-rw-r--r--libs/hwui/tests/common/TestUtils.h3
-rw-r--r--libs/hwui/tests/common/scenes/ListViewAnimation.cpp2
-rw-r--r--libs/hwui/tests/common/scenes/StretchyListViewAnimation.cpp2
-rw-r--r--location/api/system-lint-baseline.txt6
-rw-r--r--media/java/android/media/projection/IMediaProjectionManager.aidl5
-rw-r--r--packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java9
-rw-r--r--packages/SettingsLib/res/values/strings.xml15
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java128
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaDevice.java7
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java11
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/qrcode/QrCamera.java9
-rw-r--r--packages/SettingsLib/tests/robotests/Android.bp2
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java572
-rw-r--r--packages/SettingsProvider/Android.bp1
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java101
-rw-r--r--packages/SystemUI/Android.bp1
-rw-r--r--packages/SystemUI/aconfig/accessibility.aconfig2
-rw-r--r--packages/SystemUI/aconfig/systemui.aconfig8
-rw-r--r--packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt61
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt147
-rw-r--r--packages/SystemUI/res/layout/volume_dnd_icon.xml31
-rw-r--r--packages/SystemUI/src/com/android/keyguard/LockIconViewController.java30
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt15
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt27
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/FalsingCollector.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorFake.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java18
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorNoOp.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/FalsingCoreStartable.kt29
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/FalsingModule.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/FalsingStartModule.kt31
-rw-r--r--packages/SystemUI/src/com/android/systemui/common/shared/model/SharedNotificationContainerPosition.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalContentSize.kt15
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/ui/model/CommunalContentUiModel.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt15
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/flags/Flags.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt15
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt12
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTileNewImpl.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/NotificationsQSContainerController.kt23
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java35
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/ShadeExpansionStateManager.kt20
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeRepository.kt20
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractor.kt25
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt19
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt24
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java40
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProvider.kt1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionRefactor.kt46
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionSuppressor.kt1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt12
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerTest.java46
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java1
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt47
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingCollectorImplTest.java21
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java16
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java1
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt33
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java10
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java1
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQSContainerControllerLegacyTest.kt15
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQSContainerControllerTest.kt16
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeRepositoryImplTest.kt9
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/PulseExpansionHandlerTest.kt14
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java20
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderWrapperTest.kt59
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestBase.kt410
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt32
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java29
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java14
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableNotificationInterruptStateProviderImpl.java14
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/shade/data/repository/FakeShadeRepository.kt8
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/FakeStatusBarStateController.kt2
-rw-r--r--packages/SystemUI/tools/lint/baseline.xml33
-rw-r--r--services/Android.bp12
-rw-r--r--services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java8
-rw-r--r--services/core/java/com/android/server/StorageManagerService.java24
-rw-r--r--services/core/java/com/android/server/am/ActiveServices.java60
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java85
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerShellCommand.java2
-rw-r--r--services/core/java/com/android/server/am/AppPermissionTracker.java13
-rw-r--r--services/core/java/com/android/server/appop/AppOpsService.java271
-rw-r--r--services/core/java/com/android/server/display/feature/DisplayManagerFlags.java4
-rw-r--r--services/core/java/com/android/server/display/feature/display_flags.aconfig9
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java50
-rw-r--r--services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java47
-rw-r--r--services/core/java/com/android/server/media/MediaRouterService.java2
-rw-r--r--services/core/java/com/android/server/media/projection/FrameworkStatsLogWrapper.java21
-rw-r--r--services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java26
-rw-r--r--services/core/java/com/android/server/media/projection/MediaProjectionMetricsLogger.java114
-rwxr-xr-xservices/core/java/com/android/server/notification/NotificationManagerService.java21
-rw-r--r--services/core/java/com/android/server/notification/flags.aconfig7
-rw-r--r--services/core/java/com/android/server/pm/PackageArchiver.java41
-rw-r--r--services/core/java/com/android/server/policy/AppOpsPolicy.java72
-rw-r--r--services/core/java/com/android/server/policy/PhoneWindowManager.java8
-rw-r--r--services/core/java/com/android/server/tv/TvInputManagerService.java6
-rw-r--r--services/core/java/com/android/server/wm/ContentRecorder.java47
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java3
-rw-r--r--services/core/java/com/android/server/wm/OWNERS7
-rw-r--r--services/core/java/com/android/server/wm/Session.java5
-rw-r--r--services/core/java/com/android/server/wm/SynchedDeviceConfig.java20
-rw-r--r--services/core/java/com/android/server/wm/Task.java8
-rw-r--r--services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java10
-rw-r--r--services/core/java/com/android/server/wm/WindowOrganizerController.java13
-rw-r--r--services/credentials/java/com/android/server/credentials/CredentialManagerService.java56
-rw-r--r--services/proguard.flags8
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/AppStateTrackerTest.java21
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerServiceTest.java19
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/am/BackgroundRestrictionTest.java7
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java63
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/pm/PackageArchiverTest.java4
-rw-r--r--services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java44
-rw-r--r--services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionMetricsLoggerTest.java203
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/SuspendPackagesTest.java9
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java71
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/InputMethodDialogWindowContextTest.java3
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java35
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java6
-rw-r--r--telecomm/java/android/telecom/TelecomManager.java15
-rw-r--r--telephony/java/android/telephony/CarrierConfigManager.java1
-rw-r--r--telephony/java/android/telephony/IBooleanConsumer.aidl25
-rw-r--r--telephony/java/android/telephony/IIntegerConsumer.aidl25
-rw-r--r--telephony/java/android/telephony/SubscriptionManager.java22
-rw-r--r--telephony/java/android/telephony/TelephonyManager.java3
-rw-r--r--telephony/java/android/telephony/satellite/stub/ISatellite.aidl6
-rw-r--r--telephony/java/android/telephony/satellite/stub/SatelliteImplBase.java4
-rw-r--r--telephony/java/com/android/internal/telephony/ISub.aidl3
-rw-r--r--tests/FlickerTests/Android.bp16
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/open/OpenActivityEmbeddingPlaceholderSplitTest.kt10
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/common/OpenTransferSplashscreenAppFromLauncherTransition.kt9
397 files changed, 6838 insertions, 1896 deletions
diff --git a/AconfigFlags.bp b/AconfigFlags.bp
index 2e7d0ec9c89a..372ae6da4959 100644
--- a/AconfigFlags.bp
+++ b/AconfigFlags.bp
@@ -58,6 +58,7 @@ aconfig_srcjars = [
":android.service.autofill.flags-aconfig-java{.generated_srcjars}",
":com.android.net.flags-aconfig-java{.generated_srcjars}",
":device_policy_aconfig_flags_lib{.generated_srcjars}",
+ ":surfaceflinger_flags_java_lib{.generated_srcjars}",
]
filegroup {
@@ -482,7 +483,7 @@ java_aconfig_library {
defaults: ["framework-minus-apex-aconfig-java-defaults"],
}
-// Activity Manager
+// android.app
aconfig_declarations {
name: "android.app.flags-aconfig",
package: "android.app",
@@ -641,3 +642,10 @@ java_aconfig_library {
aconfig_declarations: "android.app.smartspace.flags-aconfig",
defaults: ["framework-minus-apex-aconfig-java-defaults"],
}
+
+// SurfaceFlinger
+java_aconfig_library {
+ name: "surfaceflinger_flags_java_lib",
+ aconfig_declarations: "surfaceflinger_flags",
+ defaults: ["framework-minus-apex-aconfig-java-defaults"],
+}
diff --git a/Android.bp b/Android.bp
index 49256ddb5cd4..8c4d76919568 100644
--- a/Android.bp
+++ b/Android.bp
@@ -745,90 +745,36 @@ stubs_defaults {
// non_updatable_modules list in frameworks/base/api/api.go
java_defaults {
name: "framework-non-updatable-unbundled-defaults",
- defaults: ["framework-non-updatable-lint-defaults"],
-
- sdk_version: "core_platform",
-
- // Api scope settings
+ defaults: [
+ "framework-non-updatable-lint-defaults",
+ "non-updatable-framework-module-defaults",
+ ],
public: {
- enabled: true,
- sdk_version: "module_current",
libs: ["android_module_lib_stubs_current"],
},
system: {
- enabled: true,
- sdk_version: "module_current",
libs: ["android_module_lib_stubs_current"],
},
module_lib: {
- enabled: true,
- sdk_version: "module_current",
libs: ["android_module_lib_stubs_current"],
},
test: {
- enabled: true,
- sdk_version: "test_frameworks_core_current",
libs: ["android_test_frameworks_core_stubs_current"],
},
-
- stub_only_libs: [
- "framework-protos",
- ],
- impl_only_libs: [
- "framework-minus-apex-headers", // full access to framework-minus-apex including hidden API
- "framework-annotations-lib",
- ],
- visibility: ["//visibility:public"],
- stubs_library_visibility: ["//visibility:public"],
- stubs_source_visibility: ["//visibility:private"],
- impl_library_visibility: [
- ":__pkg__",
- "//frameworks/base",
- "//frameworks/base/api", // For framework-all
- ],
- defaults_visibility: [
- "//frameworks/base/location",
- ],
- plugins: [
- "error_prone_android_framework",
- ],
+ sdk_version: "core_platform",
+ stub_only_libs: ["framework-protos"],
+ impl_only_libs: ["framework-minus-apex-headers"], // the framework, including hidden API
+ impl_library_visibility: ["//frameworks/base"],
+ defaults_visibility: ["//frameworks/base/location"],
+ plugins: ["error_prone_android_framework"],
errorprone: {
javacflags: [
"-Xep:AndroidFrameworkCompatChange:ERROR",
"-Xep:AndroidFrameworkUid:ERROR",
],
},
-
// Include manual annotations in API txt files
merge_annotations_dirs: ["metalava-manual"],
-
- // Use the source of annotations that affect metalava doc generation, since
- // the relevant generation instructions are themselves in javadoc, which is
- // not present in class files.
- api_srcs: [":framework-metalava-annotations"],
-
- // Framework modules are not generally shared libraries, i.e. they are not
- // intended, and must not be allowed, to be used in a <uses-library> manifest
- // entry.
- shared_library: false,
-
- // Prevent dependencies that do not specify an sdk_version from accessing the
- // implementation library by default and force them to use stubs instead.
- default_to_stubs: true,
-
- // Subdirectory for the artifacts that are copied to the dist directory
- dist_group: "android",
-
- droiddoc_options: [
- "--error UnhiddenSystemApi " +
- "--hide CallbackInterface " +
- "--hide HiddenTypedefConstant " +
- "--hide RequiresPermission " +
- "--enhance-documentation " +
- "--hide-package com.android.server ",
- ],
-
- annotations_enabled: true,
}
build = [
diff --git a/BAL_OWNERS b/BAL_OWNERS
new file mode 100644
index 000000000000..d56a1d4634df
--- /dev/null
+++ b/BAL_OWNERS
@@ -0,0 +1,5 @@
+brufino@google.com
+achim@google.com
+topjohnwu@google.com
+lus@google.com
+
diff --git a/apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java b/apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java
index e08200b055d8..5fc77451e832 100644
--- a/apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java
+++ b/apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java
@@ -23,6 +23,7 @@ import android.app.AppOpsManager;
import android.app.AppOpsManager.PackageOps;
import android.app.IActivityManager;
import android.app.usage.UsageStatsManager;
+import android.content.AttributionSource;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -746,8 +747,10 @@ public class AppStateTrackerImpl implements AppStateTracker {
public void opChanged(int op, int uid, String packageName) throws RemoteException {
boolean restricted = false;
try {
- restricted = mAppOpsService.checkOperation(TARGET_OP,
- uid, packageName) != AppOpsManager.MODE_ALLOWED;
+ final AttributionSource attributionSource =
+ new AttributionSource.Builder(uid).setPackageName(packageName).build();
+ restricted = mAppOpsService.checkOperationWithState(TARGET_OP,
+ attributionSource.asState()) != AppOpsManager.MODE_ALLOWED;
} catch (RemoteException e) {
// Shouldn't happen
}
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
index 1287cb4bb952..23b36e20b174 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
@@ -1820,7 +1820,11 @@ public class JobSchedulerService extends com.android.server.SystemService
jobStatus.getEstimatedNetworkUploadBytes(),
jobStatus.getWorkCount(),
ActivityManager.processStateAmToProto(mUidProcStates.get(jobStatus.getUid())),
- jobStatus.getNamespaceHash());
+ jobStatus.getNamespaceHash(),
+ /* system_measured_source_download_bytes */0,
+ /* system_measured_source_upload_bytes */ 0,
+ /* system_measured_calling_download_bytes */0,
+ /* system_measured_calling_upload_bytes */ 0);
// If the job is immediately ready to run, then we can just immediately
// put it in the pending list and try to schedule it. This is especially
@@ -2257,7 +2261,11 @@ public class JobSchedulerService extends com.android.server.SystemService
cancelled.getEstimatedNetworkUploadBytes(),
cancelled.getWorkCount(),
ActivityManager.processStateAmToProto(mUidProcStates.get(cancelled.getUid())),
- cancelled.getNamespaceHash());
+ cancelled.getNamespaceHash(),
+ /* system_measured_source_download_bytes */ 0,
+ /* system_measured_source_upload_bytes */ 0,
+ /* system_measured_calling_download_bytes */0,
+ /* system_measured_calling_upload_bytes */ 0);
}
// If this is a replacement, bring in the new version of the job
if (incomingJob != null) {
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java b/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
index 79653f0e0a91..2d49cfb3b171 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
@@ -45,6 +45,7 @@ import android.content.Intent;
import android.content.PermissionChecker;
import android.content.ServiceConnection;
import android.net.Network;
+import android.net.TrafficStats;
import android.net.Uri;
import android.os.Binder;
import android.os.Build;
@@ -241,6 +242,14 @@ public final class JobServiceContext implements ServiceConnection {
private int mDeathMarkInternalStopReason;
private String mDeathMarkDebugReason;
+ private long mInitialDownloadedBytesFromSource;
+
+ private long mInitialUploadedBytesFromSource;
+
+ private long mInitialDownloadedBytesFromCalling;
+
+ private long mInitialUploadedBytesFromCalling;
+
// Debugging: reason this job was last stopped.
public String mStoppedReason;
@@ -472,6 +481,14 @@ public final class JobServiceContext implements ServiceConnection {
}
mJobPackageTracker.noteActive(job);
final int sourceUid = job.getSourceUid();
+
+ // Measure UID baseline traffic for deltas
+ mInitialDownloadedBytesFromSource = TrafficStats.getUidRxBytes(sourceUid);
+ mInitialUploadedBytesFromSource = TrafficStats.getUidTxBytes(sourceUid);
+
+ mInitialDownloadedBytesFromCalling = TrafficStats.getUidRxBytes(job.getUid());
+ mInitialUploadedBytesFromCalling = TrafficStats.getUidTxBytes(job.getUid());
+
FrameworkStatsLog.write(FrameworkStatsLog.SCHEDULED_JOB_STATE_CHANGED,
job.isProxyJob() ? new int[]{sourceUid, job.getUid()} : new int[]{sourceUid},
// Given that the source tag is set by the calling app, it should be connected
@@ -517,7 +534,11 @@ public final class JobServiceContext implements ServiceConnection {
job.getEstimatedNetworkUploadBytes(),
job.getWorkCount(),
ActivityManager.processStateAmToProto(mService.getUidProcState(job.getUid())),
- job.getNamespaceHash());
+ job.getNamespaceHash(),
+ /* system_measured_source_download_bytes */ 0,
+ /* system_measured_source_upload_bytes */ 0,
+ /* system_measured_calling_download_bytes */ 0,
+ /* system_measured_calling_upload_bytes */ 0);
sEnqueuedJwiAtJobStart.logSampleWithUid(job.getUid(), job.getWorkCount());
final String sourcePackage = job.getSourcePackageName();
if (Trace.isTagEnabled(Trace.TRACE_TAG_SYSTEM_SERVER)) {
@@ -1586,7 +1607,15 @@ public final class JobServiceContext implements ServiceConnection {
completedJob.getWorkCount(),
ActivityManager
.processStateAmToProto(mService.getUidProcState(completedJob.getUid())),
- completedJob.getNamespaceHash());
+ completedJob.getNamespaceHash(),
+ TrafficStats.getUidRxBytes(completedJob.getSourceUid())
+ - mInitialDownloadedBytesFromSource,
+ TrafficStats.getUidTxBytes(completedJob.getSourceUid())
+ - mInitialUploadedBytesFromSource,
+ TrafficStats.getUidRxBytes(completedJob.getUid())
+ - mInitialDownloadedBytesFromCalling,
+ TrafficStats.getUidTxBytes(completedJob.getUid())
+ - mInitialUploadedBytesFromCalling);
if (Trace.isTagEnabled(Trace.TRACE_TAG_SYSTEM_SERVER)) {
Trace.asyncTraceForTrackEnd(Trace.TRACE_TAG_SYSTEM_SERVER, "JobScheduler",
getId());
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/InternalResourceService.java b/apex/jobscheduler/service/java/com/android/server/tare/InternalResourceService.java
index b8397d2cd1b4..95f901c4a365 100644
--- a/apex/jobscheduler/service/java/com/android/server/tare/InternalResourceService.java
+++ b/apex/jobscheduler/service/java/com/android/server/tare/InternalResourceService.java
@@ -38,6 +38,7 @@ import android.app.tare.EconomyManager;
import android.app.tare.IEconomyManager;
import android.app.usage.UsageEvents;
import android.app.usage.UsageStatsManagerInternal;
+import android.content.AttributionSource;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
@@ -230,8 +231,11 @@ public class InternalResourceService extends SystemService {
public void opChanged(int op, int uid, String packageName) {
boolean restricted = false;
try {
- restricted = mAppOpsService.checkOperation(
- AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, uid, packageName)
+ final AttributionSource attributionSource = new AttributionSource.Builder(uid)
+ .setPackageName(packageName)
+ .build();
+ restricted = mAppOpsService.checkOperationWithState(
+ AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, attributionSource.asState())
!= AppOpsManager.MODE_ALLOWED;
} catch (RemoteException e) {
// Shouldn't happen
diff --git a/core/api/current.txt b/core/api/current.txt
index fdb4133743cb..7e3da2279311 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -11989,22 +11989,22 @@ package android.content.pm {
method public final int compare(android.content.pm.ApplicationInfo, android.content.pm.ApplicationInfo);
}
- @FlaggedApi("android.content.pm.archiving") public final class ArchivedActivity {
- ctor public ArchivedActivity(@NonNull CharSequence, @NonNull android.content.ComponentName);
+ @FlaggedApi("android.content.pm.archiving") public final class ArchivedActivityInfo {
+ ctor public ArchivedActivityInfo(@NonNull CharSequence, @NonNull android.content.ComponentName);
method @NonNull public android.content.ComponentName getComponentName();
method @Nullable public android.graphics.drawable.Drawable getIcon();
method @NonNull public CharSequence getLabel();
method @Nullable public android.graphics.drawable.Drawable getMonochromeIcon();
- method @NonNull public android.content.pm.ArchivedActivity setComponentName(@NonNull android.content.ComponentName);
- method @NonNull public android.content.pm.ArchivedActivity setIcon(@NonNull android.graphics.drawable.Drawable);
- method @NonNull public android.content.pm.ArchivedActivity setLabel(@NonNull CharSequence);
- method @NonNull public android.content.pm.ArchivedActivity setMonochromeIcon(@NonNull android.graphics.drawable.Drawable);
+ method @NonNull public android.content.pm.ArchivedActivityInfo setComponentName(@NonNull android.content.ComponentName);
+ method @NonNull public android.content.pm.ArchivedActivityInfo setIcon(@NonNull android.graphics.drawable.Drawable);
+ method @NonNull public android.content.pm.ArchivedActivityInfo setLabel(@NonNull CharSequence);
+ method @NonNull public android.content.pm.ArchivedActivityInfo setMonochromeIcon(@NonNull android.graphics.drawable.Drawable);
}
- @FlaggedApi("android.content.pm.archiving") public final class ArchivedPackage {
- ctor public ArchivedPackage(@NonNull String, @NonNull android.content.pm.SigningInfo, @NonNull java.util.List<android.content.pm.ArchivedActivity>);
+ @FlaggedApi("android.content.pm.archiving") public final class ArchivedPackageInfo {
+ ctor public ArchivedPackageInfo(@NonNull String, @NonNull android.content.pm.SigningInfo, @NonNull java.util.List<android.content.pm.ArchivedActivityInfo>);
method @Nullable public String getDefaultToDeviceProtectedStorage();
- method @NonNull public java.util.List<android.content.pm.ArchivedActivity> getLauncherActivities();
+ method @NonNull public java.util.List<android.content.pm.ArchivedActivityInfo> getLauncherActivities();
method @NonNull public String getPackageName();
method @Nullable public String getRequestLegacyExternalStorage();
method @NonNull public android.content.pm.SigningInfo getSigningInfo();
@@ -12012,15 +12012,15 @@ package android.content.pm {
method @Nullable public String getUserDataFragile();
method public int getVersionCode();
method public int getVersionCodeMajor();
- method @NonNull public android.content.pm.ArchivedPackage setDefaultToDeviceProtectedStorage(@NonNull String);
- method @NonNull public android.content.pm.ArchivedPackage setLauncherActivities(@NonNull java.util.List<android.content.pm.ArchivedActivity>);
- method @NonNull public android.content.pm.ArchivedPackage setPackageName(@NonNull String);
- method @NonNull public android.content.pm.ArchivedPackage setRequestLegacyExternalStorage(@NonNull String);
- method @NonNull public android.content.pm.ArchivedPackage setSigningInfo(@NonNull android.content.pm.SigningInfo);
- method @NonNull public android.content.pm.ArchivedPackage setTargetSdkVersion(int);
- method @NonNull public android.content.pm.ArchivedPackage setUserDataFragile(@NonNull String);
- method @NonNull public android.content.pm.ArchivedPackage setVersionCode(int);
- method @NonNull public android.content.pm.ArchivedPackage setVersionCodeMajor(int);
+ method @NonNull public android.content.pm.ArchivedPackageInfo setDefaultToDeviceProtectedStorage(@NonNull String);
+ method @NonNull public android.content.pm.ArchivedPackageInfo setLauncherActivities(@NonNull java.util.List<android.content.pm.ArchivedActivityInfo>);
+ method @NonNull public android.content.pm.ArchivedPackageInfo setPackageName(@NonNull String);
+ method @NonNull public android.content.pm.ArchivedPackageInfo setRequestLegacyExternalStorage(@NonNull String);
+ method @NonNull public android.content.pm.ArchivedPackageInfo setSigningInfo(@NonNull android.content.pm.SigningInfo);
+ method @NonNull public android.content.pm.ArchivedPackageInfo setTargetSdkVersion(int);
+ method @NonNull public android.content.pm.ArchivedPackageInfo setUserDataFragile(@NonNull String);
+ method @NonNull public android.content.pm.ArchivedPackageInfo setVersionCode(int);
+ method @NonNull public android.content.pm.ArchivedPackageInfo setVersionCodeMajor(int);
}
public final class Attribution implements android.os.Parcelable {
@@ -12355,7 +12355,7 @@ package android.content.pm {
method @Nullable public android.content.pm.PackageInstaller.SessionInfo getSessionInfo(int);
method @NonNull public java.util.List<android.content.pm.PackageInstaller.SessionInfo> getStagedSessions();
method @RequiresPermission(allOf={android.Manifest.permission.INSTALL_PACKAGES, "com.android.permission.INSTALL_EXISTING_PACKAGES"}) public void installExistingPackage(@NonNull String, int, @Nullable android.content.IntentSender);
- method @FlaggedApi("android.content.pm.archiving") @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void installPackageArchived(@NonNull android.content.pm.ArchivedPackage, @NonNull android.content.pm.PackageInstaller.SessionParams, @NonNull android.content.IntentSender);
+ method @FlaggedApi("android.content.pm.archiving") @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void installPackageArchived(@NonNull android.content.pm.ArchivedPackageInfo, @NonNull android.content.pm.PackageInstaller.SessionParams, @NonNull android.content.IntentSender);
method @NonNull public android.content.pm.PackageInstaller.Session openSession(int) throws java.io.IOException;
method public void registerSessionCallback(@NonNull android.content.pm.PackageInstaller.SessionCallback);
method public void registerSessionCallback(@NonNull android.content.pm.PackageInstaller.SessionCallback, @NonNull android.os.Handler);
@@ -12637,7 +12637,7 @@ package android.content.pm {
method @NonNull public abstract CharSequence getApplicationLabel(@NonNull android.content.pm.ApplicationInfo);
method @Nullable public abstract android.graphics.drawable.Drawable getApplicationLogo(@NonNull android.content.pm.ApplicationInfo);
method @Nullable public abstract android.graphics.drawable.Drawable getApplicationLogo(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException;
- method @FlaggedApi("android.content.pm.archiving") @Nullable public android.content.pm.ArchivedPackage getArchivedPackage(@NonNull String);
+ method @FlaggedApi("android.content.pm.archiving") @Nullable public android.content.pm.ArchivedPackageInfo getArchivedPackage(@NonNull String);
method @NonNull public CharSequence getBackgroundPermissionOptionLabel();
method @Nullable public abstract android.content.pm.ChangedPackages getChangedPackages(@IntRange(from=0) int);
method public abstract int getComponentEnabledSetting(@NonNull android.content.ComponentName);
@@ -17708,11 +17708,14 @@ package android.graphics.pdf {
package android.graphics.text {
- public final class LineBreakConfig {
+ public final class LineBreakConfig implements android.os.Parcelable {
+ method @FlaggedApi("com.android.text.flags.no_break_no_hyphenation_span") public int describeContents();
method @FlaggedApi("com.android.text.flags.no_break_no_hyphenation_span") public int getHyphenation();
method public int getLineBreakStyle();
method public int getLineBreakWordStyle();
method @FlaggedApi("com.android.text.flags.no_break_no_hyphenation_span") @NonNull public android.graphics.text.LineBreakConfig merge(@NonNull android.graphics.text.LineBreakConfig);
+ method @FlaggedApi("com.android.text.flags.no_break_no_hyphenation_span") public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @FlaggedApi("com.android.text.flags.no_break_no_hyphenation_span") @NonNull public static final android.os.Parcelable.Creator<android.graphics.text.LineBreakConfig> CREATOR;
field @FlaggedApi("com.android.text.flags.no_break_no_hyphenation_span") public static final int HYPHENATION_DISABLED = 0; // 0x0
field @FlaggedApi("com.android.text.flags.no_break_no_hyphenation_span") public static final int HYPHENATION_ENABLED = 1; // 0x1
field @FlaggedApi("com.android.text.flags.no_break_no_hyphenation_span") public static final int HYPHENATION_UNSPECIFIED = -1; // 0xffffffff
@@ -42596,6 +42599,7 @@ package android.telecom {
field public static final String EXTRA_CALL_DISCONNECT_CAUSE = "android.telecom.extra.CALL_DISCONNECT_CAUSE";
field public static final String EXTRA_CALL_DISCONNECT_MESSAGE = "android.telecom.extra.CALL_DISCONNECT_MESSAGE";
field public static final String EXTRA_CALL_DURATION = "android.telecom.extra.CALL_DURATION";
+ field @FlaggedApi("com.android.server.telecom.flags.add_call_uri_for_missed_calls") public static final String EXTRA_CALL_LOG_URI = "android.telecom.extra.CALL_LOG_URI";
field public static final String EXTRA_CALL_NETWORK_TYPE = "android.telecom.extra.CALL_NETWORK_TYPE";
field public static final String EXTRA_CALL_SUBJECT = "android.telecom.extra.CALL_SUBJECT";
field public static final String EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME = "android.telecom.extra.CHANGE_DEFAULT_DIALER_PACKAGE_NAME";
@@ -45534,6 +45538,7 @@ package android.telephony {
field public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_THROTTLED = 2; // 0x2
field public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_TIMEOUT = 9; // 0x9
field public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_USER_CANCELED = 6; // 0x6
+ field @FlaggedApi("com.android.internal.telephony.flags.slicing_additional_error_codes") public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_USER_DISABLED = 16; // 0x10
field public static final int SET_OPPORTUNISTIC_SUB_INACTIVE_SUBSCRIPTION = 2; // 0x2
field public static final int SET_OPPORTUNISTIC_SUB_NO_OPPORTUNISTIC_SUB_AVAILABLE = 3; // 0x3
field public static final int SET_OPPORTUNISTIC_SUB_REMOTE_SERVICE_EXCEPTION = 4; // 0x4
@@ -48011,17 +48016,15 @@ package android.text.style {
method public void writeToParcel(@NonNull android.os.Parcel, int);
}
- @FlaggedApi("com.android.text.flags.no_break_no_hyphenation_span") public class LineBreakConfigSpan {
+ @FlaggedApi("com.android.text.flags.no_break_no_hyphenation_span") public final class LineBreakConfigSpan implements android.text.ParcelableSpan {
ctor @FlaggedApi("com.android.text.flags.no_break_no_hyphenation_span") public LineBreakConfigSpan(@NonNull android.graphics.text.LineBreakConfig);
+ method @FlaggedApi("com.android.text.flags.no_break_no_hyphenation_span") @NonNull public static android.text.style.LineBreakConfigSpan createNoBreakSpan();
+ method @FlaggedApi("com.android.text.flags.no_break_no_hyphenation_span") @NonNull public static android.text.style.LineBreakConfigSpan createNoHyphenationSpan();
+ method public int describeContents();
method @FlaggedApi("com.android.text.flags.no_break_no_hyphenation_span") @NonNull public android.graphics.text.LineBreakConfig getLineBreakConfig();
- }
-
- @FlaggedApi("com.android.text.flags.no_break_no_hyphenation_span") public static final class LineBreakConfigSpan.NoBreakSpan extends android.text.style.LineBreakConfigSpan {
- ctor @FlaggedApi("com.android.text.flags.no_break_no_hyphenation_span") public LineBreakConfigSpan.NoBreakSpan();
- }
-
- @FlaggedApi("com.android.text.flags.no_break_no_hyphenation_span") public static final class LineBreakConfigSpan.NoHyphenationSpan extends android.text.style.LineBreakConfigSpan {
- ctor @FlaggedApi("com.android.text.flags.no_break_no_hyphenation_span") public LineBreakConfigSpan.NoHyphenationSpan();
+ method public int getSpanTypeId();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.text.style.LineBreakConfigSpan> CREATOR;
}
public interface LineHeightSpan extends android.text.style.ParagraphStyle android.text.style.WrapTogetherSpan {
@@ -49803,6 +49806,7 @@ package android.view {
method public boolean applyTransactionOnDraw(@NonNull android.view.SurfaceControl.Transaction);
method @Nullable public android.view.SurfaceControl.Transaction buildReparentTransaction(@NonNull android.view.SurfaceControl);
method public default int getBufferTransformHint();
+ method @FlaggedApi("com.android.window.flags.get_host_token_api") @Nullable public default android.os.IBinder getHostToken();
method public default void removeOnBufferTransformHintChangedListener(@NonNull android.view.AttachedSurfaceControl.OnBufferTransformHintChangedListener);
method public default void setChildBoundingInsets(@NonNull android.graphics.Rect);
method public default void setTouchableRegion(@Nullable android.graphics.Region);
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 0ad73af28a2c..183b925cefd5 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -37,7 +37,7 @@ package android {
field public static final String ALLOW_ANY_CODEC_FOR_PLAYBACK = "android.permission.ALLOW_ANY_CODEC_FOR_PLAYBACK";
field public static final String ALLOW_PLACE_IN_MULTI_PANE_SETTINGS = "android.permission.ALLOW_PLACE_IN_MULTI_PANE_SETTINGS";
field public static final String ALLOW_SLIPPERY_TOUCHES = "android.permission.ALLOW_SLIPPERY_TOUCHES";
- field public static final String ALWAYS_UPDATE_WALLPAPER = "android.permission.ALWAYS_UPDATE_WALLPAPER";
+ field @FlaggedApi("com.android.window.flags.always_update_wallpaper_permission") public static final String ALWAYS_UPDATE_WALLPAPER = "android.permission.ALWAYS_UPDATE_WALLPAPER";
field public static final String AMBIENT_WALLPAPER = "android.permission.AMBIENT_WALLPAPER";
field public static final String APPROVE_INCIDENT_REPORTS = "android.permission.APPROVE_INCIDENT_REPORTS";
field public static final String ASSOCIATE_COMPANION_DEVICES = "android.permission.ASSOCIATE_COMPANION_DEVICES";
@@ -627,6 +627,7 @@ package android.app {
field public static final String OPSTR_BIND_ACCESSIBILITY_SERVICE = "android:bind_accessibility_service";
field public static final String OPSTR_CAPTURE_CONSENTLESS_BUGREPORT_ON_USERDEBUG_BUILD = "android:capture_consentless_bugreport_on_userdebug_build";
field public static final String OPSTR_CHANGE_WIFI_STATE = "android:change_wifi_state";
+ field @FlaggedApi("android.view.contentprotection.flags.create_accessibility_overlay_app_op_enabled") public static final String OPSTR_CREATE_ACCESSIBILITY_OVERLAY = "android:create_accessibility_overlay";
field public static final String OPSTR_ESTABLISH_VPN_MANAGER = "android:establish_vpn_manager";
field public static final String OPSTR_ESTABLISH_VPN_SERVICE = "android:establish_vpn_service";
field public static final String OPSTR_GET_ACCOUNTS = "android:get_accounts";
@@ -3819,7 +3820,7 @@ package android.content.pm {
field public static final String EXTRA_CALLBACK = "android.content.pm.extra.CALLBACK";
field public static final String EXTRA_DATA_LOADER_TYPE = "android.content.pm.extra.DATA_LOADER_TYPE";
field public static final String EXTRA_LEGACY_STATUS = "android.content.pm.extra.LEGACY_STATUS";
- field public static final String EXTRA_RESOLVED_BASE_PATH = "android.content.pm.extra.RESOLVED_BASE_PATH";
+ field @Deprecated public static final String EXTRA_RESOLVED_BASE_PATH = "android.content.pm.extra.RESOLVED_BASE_PATH";
field @FlaggedApi("android.content.pm.archiving") public static final String EXTRA_UNARCHIVE_ALL_USERS = "android.content.pm.extra.UNARCHIVE_ALL_USERS";
field @FlaggedApi("android.content.pm.archiving") public static final String EXTRA_UNARCHIVE_PACKAGE_NAME = "android.content.pm.extra.UNARCHIVE_PACKAGE_NAME";
field public static final int LOCATION_DATA_APP = 0; // 0x0
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 9a19d8edf8a8..b03bd59c305e 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -16,10 +16,13 @@
package android.app;
+import static android.view.contentprotection.flags.Flags.FLAG_CREATE_ACCESSIBILITY_OVERLAY_APP_OP_ENABLED;
+
import static java.lang.Long.max;
import android.Manifest;
import android.annotation.CallbackExecutor;
+import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.NonNull;
@@ -1495,9 +1498,17 @@ public class AppOpsManager {
public static final int OP_RECEIVE_SANDBOXED_DETECTION_TRAINING_DATA =
AppProtoEnums.APP_OP_RECEIVE_SANDBOXED_DETECTION_TRAINING_DATA;
+ /**
+ * Creation of an overlay using accessibility services
+ *
+ * @hide
+ */
+ public static final int OP_CREATE_ACCESSIBILITY_OVERLAY =
+ AppProtoEnums.APP_OP_CREATE_ACCESSIBILITY_OVERLAY;
+
/** @hide */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public static final int _NUM_OP = 138;
+ public static final int _NUM_OP = 139;
/**
* All app ops represented as strings.
@@ -1641,7 +1652,8 @@ public class AppOpsManager {
OPSTR_CAMERA_SANDBOXED,
OPSTR_RECORD_AUDIO_SANDBOXED,
OPSTR_RECEIVE_SANDBOX_TRIGGER_AUDIO,
- OPSTR_RECEIVE_SANDBOXED_DETECTION_TRAINING_DATA
+ OPSTR_RECEIVE_SANDBOXED_DETECTION_TRAINING_DATA,
+ OPSTR_CREATE_ACCESSIBILITY_OVERLAY,
})
public @interface AppOpString {}
@@ -2270,6 +2282,16 @@ public class AppOpsManager {
public static final String OPSTR_RECEIVE_SANDBOXED_DETECTION_TRAINING_DATA =
"android:RECEIVE_SANDBOXED_DETECTION_TRAINING_DATA";
+ /**
+ * Creation of an overlay using accessibility services
+ *
+ * @hide
+ */
+ @SystemApi
+ @FlaggedApi(FLAG_CREATE_ACCESSIBILITY_OVERLAY_APP_OP_ENABLED)
+ public static final String OPSTR_CREATE_ACCESSIBILITY_OVERLAY =
+ "android:create_accessibility_overlay";
+
/** {@link #sAppOpsToNote} not initialized yet for this op */
private static final byte SHOULD_COLLECT_NOTE_OP_NOT_INITIALIZED = 0;
/** Should not collect noting of this app-op in {@link #sAppOpsToNote} */
@@ -2819,7 +2841,11 @@ public class AppOpsManager {
OPSTR_RECEIVE_SANDBOXED_DETECTION_TRAINING_DATA,
"RECEIVE_SANDBOXED_DETECTION_TRAINING_DATA")
.setPermission(Manifest.permission.RECEIVE_SANDBOXED_DETECTION_TRAINING_DATA)
- .setDefaultMode(AppOpsManager.MODE_DEFAULT).build()
+ .setDefaultMode(AppOpsManager.MODE_DEFAULT).build(),
+ new AppOpInfo.Builder(OP_CREATE_ACCESSIBILITY_OVERLAY,
+ OPSTR_CREATE_ACCESSIBILITY_OVERLAY,
+ "CREATE_ACCESSIBILITY_OVERLAY")
+ .setDefaultMode(AppOpsManager.MODE_ALLOWED).build(),
};
// The number of longs needed to form a full bitmask of app ops
@@ -8305,7 +8331,9 @@ public class AppOpsManager {
*/
public int unsafeCheckOpRawNoThrow(int op, int uid, @NonNull String packageName) {
try {
- return mService.checkOperationRaw(op, uid, packageName, null);
+ final AttributionSource attributionSource =
+ new AttributionSource.Builder(uid).setPackageName(packageName).build();
+ return mService.checkOperationWithStateRaw(op, attributionSource.asState());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -8468,7 +8496,12 @@ public class AppOpsManager {
}
}
- SyncNotedAppOp syncOp = mService.noteOperation(op, uid, packageName, attributionTag,
+ final AttributionSource attributionSource =
+ new AttributionSource.Builder(uid)
+ .setPackageName(packageName)
+ .setAttributionTag(attributionTag)
+ .build();
+ SyncNotedAppOp syncOp = mService.noteOperationWithState(op, attributionSource.asState(),
collectionMode == COLLECT_ASYNC, message, shouldCollectMessage);
if (syncOp.getOpMode() == MODE_ALLOWED) {
@@ -8708,7 +8741,9 @@ public class AppOpsManager {
@UnsupportedAppUsage
public int checkOp(int op, int uid, String packageName) {
try {
- int mode = mService.checkOperation(op, uid, packageName);
+ final AttributionSource attributionSource =
+ new AttributionSource.Builder(uid).setPackageName(packageName).build();
+ int mode = mService.checkOperationWithState(op, attributionSource.asState());
if (mode == MODE_ERRORED) {
throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
}
@@ -8729,7 +8764,9 @@ public class AppOpsManager {
@UnsupportedAppUsage
public int checkOpNoThrow(int op, int uid, String packageName) {
try {
- int mode = mService.checkOperation(op, uid, packageName);
+ final AttributionSource attributionSource =
+ new AttributionSource.Builder(uid).setPackageName(packageName).build();
+ int mode = mService.checkOperationWithState(op, attributionSource.asState());
return mode == AppOpsManager.MODE_FOREGROUND ? AppOpsManager.MODE_ALLOWED : mode;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
@@ -8974,8 +9011,14 @@ public class AppOpsManager {
}
}
- SyncNotedAppOp syncOp = mService.startOperation(token, op, uid, packageName,
- attributionTag, startIfModeDefault, collectionMode == COLLECT_ASYNC, message,
+ final AttributionSource attributionSource =
+ new AttributionSource.Builder(uid)
+ .setPackageName(packageName)
+ .setAttributionTag(attributionTag)
+ .build();
+ SyncNotedAppOp syncOp = mService.startOperationWithState(token, op,
+ attributionSource.asState(), startIfModeDefault,
+ collectionMode == COLLECT_ASYNC, message,
shouldCollectMessage, attributionFlags, attributionChainId);
if (syncOp.getOpMode() == MODE_ALLOWED) {
@@ -9188,7 +9231,12 @@ public class AppOpsManager {
public void finishOp(IBinder token, int op, int uid, @NonNull String packageName,
@Nullable String attributionTag) {
try {
- mService.finishOperation(token, op, uid, packageName, attributionTag);
+ final AttributionSource attributionSource =
+ new AttributionSource.Builder(uid)
+ .setPackageName(packageName)
+ .setAttributionTag(attributionTag)
+ .build();
+ mService.finishOperationWithState(token, op, attributionSource.asState());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/app/AppOpsManagerInternal.java b/core/java/android/app/AppOpsManagerInternal.java
index 43023fe9c2ab..a3de8faa1273 100644
--- a/core/java/android/app/AppOpsManagerInternal.java
+++ b/core/java/android/app/AppOpsManagerInternal.java
@@ -26,11 +26,12 @@ import android.util.SparseArray;
import android.util.SparseIntArray;
import com.android.internal.app.IAppOpsCallback;
-import com.android.internal.util.function.HeptFunction;
import com.android.internal.util.function.HexFunction;
+import com.android.internal.util.function.NonaFunction;
import com.android.internal.util.function.QuadFunction;
-import com.android.internal.util.function.QuintConsumer;
import com.android.internal.util.function.QuintFunction;
+import com.android.internal.util.function.TriConsumer;
+import com.android.internal.util.function.TriFunction;
import com.android.internal.util.function.UndecFunction;
/**
@@ -45,15 +46,13 @@ public abstract class AppOpsManagerInternal {
* Allows overriding check operation behavior.
*
* @param code The op code to check.
- * @param uid The UID for which to check.
- * @param packageName The package for which to check.
- * @param attributionTag The attribution tag for which to check.
+ * @param attributionSource the {@link AttributionSource} responsible for data access
* @param raw Whether to check the raw op i.e. not interpret the mode based on UID state.
* @param superImpl The super implementation.
* @return The app op check result.
*/
- int checkOperation(int code, int uid, String packageName, @Nullable String attributionTag,
- boolean raw, QuintFunction<Integer, Integer, String, String, Boolean, Integer>
+ int checkOperation(int code, AttributionSource attributionSource,
+ boolean raw, TriFunction<Integer, AttributionSource, Boolean, Integer>
superImpl);
/**
@@ -73,25 +72,23 @@ public abstract class AppOpsManagerInternal {
* Allows overriding note operation behavior.
*
* @param code The op code to note.
- * @param uid The UID for which to note.
- * @param packageName The package for which to note. {@code null} for system package.
- * @param featureId Id of the feature in the package
+ * @param attributionSource the {@link AttributionSource} responsible for data access
* @param shouldCollectAsyncNotedOp If an {@link AsyncNotedAppOp} should be collected
* @param message The message in the async noted op
* @param superImpl The super implementation.
* @return The app op note result.
*/
- SyncNotedAppOp noteOperation(int code, int uid, @Nullable String packageName,
- @Nullable String featureId, boolean shouldCollectAsyncNotedOp,
+ SyncNotedAppOp noteOperation(int code, AttributionSource attributionSource,
+ boolean shouldCollectAsyncNotedOp,
@Nullable String message, boolean shouldCollectMessage,
- @NonNull HeptFunction<Integer, Integer, String, String, Boolean, String, Boolean,
+ @NonNull QuintFunction<Integer, AttributionSource, Boolean, String, Boolean,
SyncNotedAppOp> superImpl);
/**
* Allows overriding note proxy operation behavior.
*
* @param code The op code to note.
- * @param attributionSource The permission identity of the caller.
+ * @param attributionSource the {@link AttributionSource} responsible for data access
* @param shouldCollectAsyncNotedOp If an {@link AsyncNotedAppOp} should be collected
* @param message The message in the async noted op
* @param shouldCollectMessage whether to collect messages
@@ -110,9 +107,7 @@ public abstract class AppOpsManagerInternal {
*
* @param token The client state.
* @param code The op code to start.
- * @param uid The UID for which to note.
- * @param packageName The package for which to note. {@code null} for system package.
- * @param attributionTag the attribution tag.
+ * @param attributionSource the {@link AttributionSource} responsible for data access
* @param startIfModeDefault Whether to start the op of the mode is default.
* @param shouldCollectAsyncNotedOp If an {@link AsyncNotedAppOp} should be collected
* @param message The message in the async noted op
@@ -122,12 +117,12 @@ public abstract class AppOpsManagerInternal {
* @param superImpl The super implementation.
* @return The app op note result.
*/
- SyncNotedAppOp startOperation(IBinder token, int code, int uid,
- @Nullable String packageName, @Nullable String attributionTag,
+ SyncNotedAppOp startOperation(IBinder token, int code,
+ AttributionSource attributionSource,
boolean startIfModeDefault, boolean shouldCollectAsyncNotedOp,
@Nullable String message, boolean shouldCollectMessage,
@AttributionFlags int attributionFlags, int attributionChainId,
- @NonNull UndecFunction<IBinder, Integer, Integer, String, String, Boolean,
+ @NonNull NonaFunction<IBinder, Integer, AttributionSource, Boolean,
Boolean, String, Boolean, Integer, Integer, SyncNotedAppOp> superImpl);
/**
@@ -135,7 +130,7 @@ public abstract class AppOpsManagerInternal {
*
* @param clientId The client calling start, represented by an IBinder
* @param code The op code to start.
- * @param attributionSource The permission identity of the caller.
+ * @param attributionSource the {@link AttributionSource} responsible for data access
* @param startIfModeDefault Whether to start the op of the mode is default.
* @param shouldCollectAsyncNotedOp If an {@link AsyncNotedAppOp} should be collected
* @param message The message in the async noted op
@@ -161,21 +156,19 @@ public abstract class AppOpsManagerInternal {
*
* @param clientId The client state.
* @param code The op code to finish.
- * @param uid The UID for which the op was noted.
- * @param packageName The package for which it was noted. {@code null} for system package.
- * @param attributionTag the attribution tag.
+ * @param attributionSource the {@link AttributionSource} responsible for data access
*/
- default void finishOperation(IBinder clientId, int code, int uid, String packageName,
- String attributionTag,
- @NonNull QuintConsumer<IBinder, Integer, Integer, String, String> superImpl) {
- superImpl.accept(clientId, code, uid, packageName, attributionTag);
+ default void finishOperation(IBinder clientId, int code,
+ AttributionSource attributionSource,
+ @NonNull TriConsumer<IBinder, Integer, AttributionSource> superImpl) {
+ superImpl.accept(clientId, code, attributionSource);
}
/**
* Allows overriding finish proxy op.
*
* @param code The op code to finish.
- * @param attributionSource The permission identity of the caller.
+ * @param attributionSource the {@link AttributionSource} responsible for data access
* @param skipProxyOperation Whether to skip the proxy in the proxy/proxied operation
* @param clientId The client calling finishProxyOperation
* @param superImpl The "standard" implementation to potentially call
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index fd308ce2e85a..367e92b9d960 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -48,7 +48,7 @@ import android.content.IntentSender;
import android.content.pm.ActivityInfo;
import android.content.pm.ApkChecksum;
import android.content.pm.ApplicationInfo;
-import android.content.pm.ArchivedPackage;
+import android.content.pm.ArchivedPackageInfo;
import android.content.pm.ChangedPackages;
import android.content.pm.Checksum;
import android.content.pm.ComponentInfo;
@@ -3937,13 +3937,13 @@ public class ApplicationPackageManager extends PackageManager {
}
@Override
- public @Nullable ArchivedPackage getArchivedPackage(@NonNull String packageName) {
+ public @Nullable ArchivedPackageInfo getArchivedPackage(@NonNull String packageName) {
try {
var parcel = mPM.getArchivedPackage(packageName, mContext.getUserId());
if (parcel == null) {
return null;
}
- return new ArchivedPackage(parcel);
+ return new ArchivedPackageInfo(parcel);
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
diff --git a/core/java/android/app/OWNERS b/core/java/android/app/OWNERS
index 9cf54e3b9063..cc56a1cee7a2 100644
--- a/core/java/android/app/OWNERS
+++ b/core/java/android/app/OWNERS
@@ -36,6 +36,7 @@ per-file GameMode* = file:/GAME_MANAGER_OWNERS
per-file GameState* = file:/GAME_MANAGER_OWNERS
per-file IGameManager* = file:/GAME_MANAGER_OWNERS
per-file IGameMode* = file:/GAME_MANAGER_OWNERS
+per-file BackgroundStartPrivileges.java = file:/BAL_OWNERS
# ActivityThread
per-file ActivityThread.java = file:/services/core/java/com/android/server/am/OWNERS
diff --git a/core/java/android/app/notification.aconfig b/core/java/android/app/notification.aconfig
new file mode 100644
index 000000000000..cd1d8ce66cb5
--- /dev/null
+++ b/core/java/android/app/notification.aconfig
@@ -0,0 +1,8 @@
+package: "android.app"
+
+flag {
+ name: "modes_api"
+ namespace: "systemui"
+ description: "This flag controls new and updated DND apis"
+ bug: "300477976"
+} \ No newline at end of file
diff --git a/core/java/android/appwidget/AppWidgetManager.java b/core/java/android/appwidget/AppWidgetManager.java
index 3abe1d9494f0..c6012bbc7292 100644
--- a/core/java/android/appwidget/AppWidgetManager.java
+++ b/core/java/android/appwidget/AppWidgetManager.java
@@ -562,13 +562,6 @@ public class AppWidgetManager {
});
}
- private boolean isPostingTaskToBackground(@Nullable RemoteViews views) {
- return Looper.myLooper() == Looper.getMainLooper()
- && RemoteViews.isAdapterConversionEnabled()
- && (mHasPostedLegacyLists = mHasPostedLegacyLists
- || (views != null && views.hasLegacyLists()));
- }
-
/**
* Set the RemoteViews to use for the specified appWidgetIds.
* <p>
@@ -593,16 +586,25 @@ public class AppWidgetManager {
return;
}
- if (isPostingTaskToBackground(views)) {
- createUpdateExecutorIfNull().execute(() -> {
- try {
- mService.updateAppWidgetIds(mPackageName, appWidgetIds, views);
- } catch (RemoteException e) {
- Log.e(TAG, "Error updating app widget views in background", e);
- }
- });
+ final boolean isConvertingAdapter = RemoteViews.isAdapterConversionEnabled()
+ && (mHasPostedLegacyLists = mHasPostedLegacyLists
+ || (views != null && views.hasLegacyLists()));
- return;
+ if (isConvertingAdapter) {
+ views.collectAllIntents();
+
+ if (Looper.getMainLooper() == Looper.myLooper()) {
+ RemoteViews viewsCopy = new RemoteViews(views);
+ createUpdateExecutorIfNull().execute(() -> {
+ try {
+ mService.updateAppWidgetIds(mPackageName, appWidgetIds, viewsCopy);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error updating app widget views in background", e);
+ }
+ });
+
+ return;
+ }
}
try {
@@ -714,16 +716,25 @@ public class AppWidgetManager {
return;
}
- if (isPostingTaskToBackground(views)) {
- createUpdateExecutorIfNull().execute(() -> {
- try {
- mService.partiallyUpdateAppWidgetIds(mPackageName, appWidgetIds, views);
- } catch (RemoteException e) {
- Log.e(TAG, "Error partially updating app widget views in background", e);
- }
- });
+ final boolean isConvertingAdapter = RemoteViews.isAdapterConversionEnabled()
+ && (mHasPostedLegacyLists = mHasPostedLegacyLists
+ || (views != null && views.hasLegacyLists()));
+
+ if (isConvertingAdapter) {
+ views.collectAllIntents();
- return;
+ if (Looper.getMainLooper() == Looper.myLooper()) {
+ RemoteViews viewsCopy = new RemoteViews(views);
+ createUpdateExecutorIfNull().execute(() -> {
+ try {
+ mService.partiallyUpdateAppWidgetIds(mPackageName, appWidgetIds, viewsCopy);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error partially updating app widget views in background", e);
+ }
+ });
+
+ return;
+ }
}
try {
@@ -782,16 +793,26 @@ public class AppWidgetManager {
return;
}
- if (isPostingTaskToBackground(views)) {
- createUpdateExecutorIfNull().execute(() -> {
- try {
- mService.updateAppWidgetProvider(provider, views);
- } catch (RemoteException e) {
- Log.e(TAG, "Error updating app widget view using provider in background", e);
- }
- });
+ final boolean isConvertingAdapter = RemoteViews.isAdapterConversionEnabled()
+ && (mHasPostedLegacyLists = mHasPostedLegacyLists
+ || (views != null && views.hasLegacyLists()));
+
+ if (isConvertingAdapter) {
+ views.collectAllIntents();
- return;
+ if (Looper.getMainLooper() == Looper.myLooper()) {
+ RemoteViews viewsCopy = new RemoteViews(views);
+ createUpdateExecutorIfNull().execute(() -> {
+ try {
+ mService.updateAppWidgetProvider(provider, viewsCopy);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error updating app widget view using provider in background",
+ e);
+ }
+ });
+
+ return;
+ }
}
try {
diff --git a/core/java/android/companion/virtual/VirtualDeviceManager.java b/core/java/android/companion/virtual/VirtualDeviceManager.java
index d40a5911d8f4..b3ea93bb8a85 100644
--- a/core/java/android/companion/virtual/VirtualDeviceManager.java
+++ b/core/java/android/companion/virtual/VirtualDeviceManager.java
@@ -185,9 +185,6 @@ public final class VirtualDeviceManager {
int associationId,
@NonNull VirtualDeviceParams params) {
Objects.requireNonNull(params, "params must not be null");
- if (Flags.moreLogs()) {
- Log.i(TAG, "Creating VirtualDevice");
- }
try {
return new VirtualDevice(mService, mContext, associationId, params);
} catch (RemoteException e) {
diff --git a/core/java/android/companion/virtual/flags.aconfig b/core/java/android/companion/virtual/flags.aconfig
index f380963fbcab..3cadb7c09d54 100644
--- a/core/java/android/companion/virtual/flags.aconfig
+++ b/core/java/android/companion/virtual/flags.aconfig
@@ -1,13 +1,6 @@
package: "android.companion.virtual.flags"
flag {
- name: "more_logs"
- namespace: "virtual_devices"
- description: "More logs to test flags with"
- bug: "291725823"
-}
-
-flag {
name: "enable_native_vdm"
namespace: "virtual_devices"
description: "Enable native VDM service"
diff --git a/core/java/android/content/AttributionSource.java b/core/java/android/content/AttributionSource.java
index 4b2cee698df2..c2bc974a42ae 100644
--- a/core/java/android/content/AttributionSource.java
+++ b/core/java/android/content/AttributionSource.java
@@ -235,6 +235,12 @@ public final class AttributionSource implements Parcelable {
}
/** @hide */
+ public AttributionSource withUid(int uid) {
+ return new AttributionSource(uid, getPid(), getPackageName(), getAttributionTag(),
+ getToken(), mAttributionSourceState.renouncedPermissions, getDeviceId(), getNext());
+ }
+
+ /** @hide */
public AttributionSource withPid(int pid) {
return new AttributionSource(getUid(), pid, getPackageName(), getAttributionTag(),
getToken(), mAttributionSourceState.renouncedPermissions, getDeviceId(), getNext());
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index ffc4805df264..ea54c912d4b9 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1164,6 +1164,11 @@ public class Intent implements Parcelable, Cloneable {
* numbers. Applications can <strong>dial</strong> emergency numbers using
* {@link #ACTION_DIAL}, however.
*
+ * <p>Note: This Intent can only be used to dial call forwarding MMI codes if the application
+ * using this intent is set as the default or system dialer. The system will treat any other
+ * application using this Intent for the purpose of dialing call forwarding MMI codes as if the
+ * {@link #ACTION_DIAL} Intent was used instead.
+ *
* <p>Note: An app filling the {@link android.app.role.RoleManager#ROLE_DIALER} role should use
* {@link android.telecom.TelecomManager#placeCall(Uri, Bundle)} to place calls rather than
* relying on this intent.
diff --git a/core/java/android/content/pm/ArchivedActivity.java b/core/java/android/content/pm/ArchivedActivityInfo.java
index 9e49c9e52878..1faa4373d88f 100644
--- a/core/java/android/content/pm/ArchivedActivity.java
+++ b/core/java/android/content/pm/ArchivedActivityInfo.java
@@ -32,9 +32,13 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Objects;
+/**
+ * Contains fields required to show archived package in Launcher.
+ * @see ArchivedPackageInfo
+ */
@DataClass(genBuilder = false, genConstructor = false, genSetters = true)
@FlaggedApi(Flags.FLAG_ARCHIVING)
-public final class ArchivedActivity {
+public final class ArchivedActivityInfo {
/** The label for the activity. */
private @NonNull CharSequence mLabel;
/** The component name of this activity. */
@@ -47,7 +51,7 @@ public final class ArchivedActivity {
/** Monochrome icon, if defined, of the activity. */
private @Nullable Drawable mMonochromeIcon;
- public ArchivedActivity(@NonNull CharSequence label, @NonNull ComponentName componentName) {
+ public ArchivedActivityInfo(@NonNull CharSequence label, @NonNull ComponentName componentName) {
Objects.requireNonNull(label);
Objects.requireNonNull(componentName);
mLabel = label;
@@ -55,7 +59,7 @@ public final class ArchivedActivity {
}
/* @hide */
- ArchivedActivity(@NonNull ArchivedActivityParcel parcel) {
+ ArchivedActivityInfo(@NonNull ArchivedActivityParcel parcel) {
mLabel = parcel.title;
mComponentName = parcel.originalComponentName;
mIcon = drawableFromCompressedBitmap(parcel.iconBitmap);
@@ -149,7 +153,7 @@ public final class ArchivedActivity {
// CHECKSTYLE:OFF Generated code
//
// To regenerate run:
- // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/content/pm/ArchivedActivity.java
+ // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/content/pm/ArchivedActivityInfo.java
//
// To exclude the generated code from IntelliJ auto-formatting enable (one-time):
// Settings > Editor > Code Style > Formatter Control
@@ -193,7 +197,7 @@ public final class ArchivedActivity {
* The label for the activity.
*/
@DataClass.Generated.Member
- public @NonNull ArchivedActivity setLabel(@NonNull CharSequence value) {
+ public @NonNull ArchivedActivityInfo setLabel(@NonNull CharSequence value) {
mLabel = value;
com.android.internal.util.AnnotationValidations.validate(
NonNull.class, null, mLabel);
@@ -204,7 +208,7 @@ public final class ArchivedActivity {
* The component name of this activity.
*/
@DataClass.Generated.Member
- public @NonNull ArchivedActivity setComponentName(@NonNull ComponentName value) {
+ public @NonNull ArchivedActivityInfo setComponentName(@NonNull ComponentName value) {
mComponentName = value;
com.android.internal.util.AnnotationValidations.validate(
NonNull.class, null, mComponentName);
@@ -216,7 +220,7 @@ public final class ArchivedActivity {
* launcher.
*/
@DataClass.Generated.Member
- public @NonNull ArchivedActivity setIcon(@NonNull Drawable value) {
+ public @NonNull ArchivedActivityInfo setIcon(@NonNull Drawable value) {
mIcon = value;
return this;
}
@@ -225,16 +229,16 @@ public final class ArchivedActivity {
* Monochrome icon, if defined, of the activity.
*/
@DataClass.Generated.Member
- public @NonNull ArchivedActivity setMonochromeIcon(@NonNull Drawable value) {
+ public @NonNull ArchivedActivityInfo setMonochromeIcon(@NonNull Drawable value) {
mMonochromeIcon = value;
return this;
}
@DataClass.Generated(
- time = 1698173429911L,
+ time = 1698789991876L,
codegenVersion = "1.0.23",
- sourceFile = "frameworks/base/core/java/android/content/pm/ArchivedActivity.java",
- inputSignatures = "private @android.annotation.NonNull java.lang.CharSequence mLabel\nprivate @android.annotation.NonNull android.content.ComponentName mComponentName\nprivate @android.annotation.Nullable android.graphics.drawable.Drawable mIcon\nprivate @android.annotation.Nullable android.graphics.drawable.Drawable mMonochromeIcon\n @android.annotation.NonNull android.content.pm.ArchivedActivityParcel getParcel()\npublic static android.graphics.Bitmap drawableToBitmap(android.graphics.drawable.Drawable)\npublic static android.graphics.Bitmap drawableToBitmap(android.graphics.drawable.Drawable,int)\npublic static byte[] bytesFromBitmap(android.graphics.Bitmap)\nprivate static android.graphics.drawable.Drawable drawableFromCompressedBitmap(byte[])\nclass ArchivedActivity extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genBuilder=false, genConstructor=false, genSetters=true)")
+ sourceFile = "frameworks/base/core/java/android/content/pm/ArchivedActivityInfo.java",
+ inputSignatures = "private @android.annotation.NonNull java.lang.CharSequence mLabel\nprivate @android.annotation.NonNull android.content.ComponentName mComponentName\nprivate @android.annotation.Nullable android.graphics.drawable.Drawable mIcon\nprivate @android.annotation.Nullable android.graphics.drawable.Drawable mMonochromeIcon\n @android.annotation.NonNull android.content.pm.ArchivedActivityParcel getParcel()\npublic static android.graphics.Bitmap drawableToBitmap(android.graphics.drawable.Drawable)\npublic static android.graphics.Bitmap drawableToBitmap(android.graphics.drawable.Drawable,int)\npublic static byte[] bytesFromBitmap(android.graphics.Bitmap)\nprivate static android.graphics.drawable.Drawable drawableFromCompressedBitmap(byte[])\nclass ArchivedActivityInfo extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genBuilder=false, genConstructor=false, genSetters=true)")
@Deprecated
private void __metadata() {}
diff --git a/core/java/android/content/pm/ArchivedPackage.java b/core/java/android/content/pm/ArchivedPackageInfo.java
index 42795db35684..f432598ef887 100644
--- a/core/java/android/content/pm/ArchivedPackage.java
+++ b/core/java/android/content/pm/ArchivedPackageInfo.java
@@ -27,9 +27,13 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
+/**
+ * Contains fields required for archived package installation,
+ * i.e. installation without an APK.
+ */
@DataClass(genBuilder = false, genConstructor = false, genSetters = true)
@FlaggedApi(Flags.FLAG_ARCHIVING)
-public final class ArchivedPackage {
+public final class ArchivedPackageInfo {
/** Name of the package as used to identify it in the system */
private @NonNull String mPackageName;
/** Signing certificates used to sign the package. */
@@ -74,10 +78,10 @@ public final class ArchivedPackage {
* {@link Intent#CATEGORY_LAUNCHER}.
* @see LauncherApps#getActivityList
*/
- private @NonNull List<ArchivedActivity> mLauncherActivities;
+ private @NonNull List<ArchivedActivityInfo> mLauncherActivities;
- public ArchivedPackage(@NonNull String packageName, @NonNull SigningInfo signingInfo,
- @NonNull List<ArchivedActivity> launcherActivities) {
+ public ArchivedPackageInfo(@NonNull String packageName, @NonNull SigningInfo signingInfo,
+ @NonNull List<ArchivedActivityInfo> launcherActivities) {
Objects.requireNonNull(packageName);
Objects.requireNonNull(signingInfo);
Objects.requireNonNull(launcherActivities);
@@ -90,7 +94,7 @@ public final class ArchivedPackage {
* Constructs the archived package from parcel.
* @hide
*/
- public ArchivedPackage(@NonNull ArchivedPackageParcel parcel) {
+ public ArchivedPackageInfo(@NonNull ArchivedPackageParcel parcel) {
mPackageName = parcel.packageName;
mSigningInfo = new SigningInfo(parcel.signingDetails);
mVersionCode = parcel.versionCode;
@@ -102,7 +106,7 @@ public final class ArchivedPackage {
mLauncherActivities = new ArrayList<>();
if (parcel.archivedActivities != null) {
for (var activityParcel : parcel.archivedActivities) {
- mLauncherActivities.add(new ArchivedActivity(activityParcel));
+ mLauncherActivities.add(new ArchivedActivityInfo(activityParcel));
}
}
}
@@ -135,7 +139,7 @@ public final class ArchivedPackage {
// CHECKSTYLE:OFF Generated code
//
// To regenerate run:
- // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/content/pm/ArchivedPackage.java
+ // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/content/pm/ArchivedPackageInfo.java
//
// To exclude the generated code from IntelliJ auto-formatting enable (one-time):
// Settings > Editor > Code Style > Formatter Control
@@ -224,7 +228,7 @@ public final class ArchivedPackage {
* @see LauncherApps#getActivityList
*/
@DataClass.Generated.Member
- public @NonNull List<ArchivedActivity> getLauncherActivities() {
+ public @NonNull List<ArchivedActivityInfo> getLauncherActivities() {
return mLauncherActivities;
}
@@ -232,7 +236,7 @@ public final class ArchivedPackage {
* Name of the package as used to identify it in the system
*/
@DataClass.Generated.Member
- public @NonNull ArchivedPackage setPackageName(@NonNull String value) {
+ public @NonNull ArchivedPackageInfo setPackageName(@NonNull String value) {
mPackageName = value;
com.android.internal.util.AnnotationValidations.validate(
NonNull.class, null, mPackageName);
@@ -243,7 +247,7 @@ public final class ArchivedPackage {
* Signing certificates used to sign the package.
*/
@DataClass.Generated.Member
- public @NonNull ArchivedPackage setSigningInfo(@NonNull SigningInfo value) {
+ public @NonNull ArchivedPackageInfo setSigningInfo(@NonNull SigningInfo value) {
mSigningInfo = value;
com.android.internal.util.AnnotationValidations.validate(
NonNull.class, null, mSigningInfo);
@@ -255,7 +259,7 @@ public final class ArchivedPackage {
* {@link android.R.styleable#AndroidManifest_versionCode versionCode} attribute.
*/
@DataClass.Generated.Member
- public @NonNull ArchivedPackage setVersionCode( int value) {
+ public @NonNull ArchivedPackageInfo setVersionCode( int value) {
mVersionCode = value;
return this;
}
@@ -265,7 +269,7 @@ public final class ArchivedPackage {
* {@link android.R.styleable#AndroidManifest_versionCode versionCodeMajor} attribute.
*/
@DataClass.Generated.Member
- public @NonNull ArchivedPackage setVersionCodeMajor( int value) {
+ public @NonNull ArchivedPackageInfo setVersionCodeMajor( int value) {
mVersionCodeMajor = value;
return this;
}
@@ -276,7 +280,7 @@ public final class ArchivedPackage {
* attribute.
*/
@DataClass.Generated.Member
- public @NonNull ArchivedPackage setTargetSdkVersion( int value) {
+ public @NonNull ArchivedPackageInfo setTargetSdkVersion( int value) {
mTargetSdkVersion = value;
return this;
}
@@ -287,7 +291,7 @@ public final class ArchivedPackage {
* attribute.
*/
@DataClass.Generated.Member
- public @NonNull ArchivedPackage setDefaultToDeviceProtectedStorage(@NonNull String value) {
+ public @NonNull ArchivedPackageInfo setDefaultToDeviceProtectedStorage(@NonNull String value) {
mDefaultToDeviceProtectedStorage = value;
return this;
}
@@ -299,7 +303,7 @@ public final class ArchivedPackage {
* attribute.
*/
@DataClass.Generated.Member
- public @NonNull ArchivedPackage setRequestLegacyExternalStorage(@NonNull String value) {
+ public @NonNull ArchivedPackageInfo setRequestLegacyExternalStorage(@NonNull String value) {
mRequestLegacyExternalStorage = value;
return this;
}
@@ -310,7 +314,7 @@ public final class ArchivedPackage {
* {@link android.R.styleable#AndroidManifestApplication_hasFragileUserData} attribute.
*/
@DataClass.Generated.Member
- public @NonNull ArchivedPackage setUserDataFragile(@NonNull String value) {
+ public @NonNull ArchivedPackageInfo setUserDataFragile(@NonNull String value) {
mUserDataFragile = value;
return this;
}
@@ -322,7 +326,7 @@ public final class ArchivedPackage {
* @see LauncherApps#getActivityList
*/
@DataClass.Generated.Member
- public @NonNull ArchivedPackage setLauncherActivities(@NonNull List<ArchivedActivity> value) {
+ public @NonNull ArchivedPackageInfo setLauncherActivities(@NonNull List<ArchivedActivityInfo> value) {
mLauncherActivities = value;
com.android.internal.util.AnnotationValidations.validate(
NonNull.class, null, mLauncherActivities);
@@ -330,10 +334,10 @@ public final class ArchivedPackage {
}
@DataClass.Generated(
- time = 1697824890503L,
+ time = 1698789995536L,
codegenVersion = "1.0.23",
- sourceFile = "frameworks/base/core/java/android/content/pm/ArchivedPackage.java",
- inputSignatures = "private @android.annotation.NonNull java.lang.String mPackageName\nprivate @android.annotation.NonNull android.content.pm.SigningInfo mSigningInfo\nprivate int mVersionCode\nprivate int mVersionCodeMajor\nprivate int mTargetSdkVersion\nprivate @android.annotation.Nullable java.lang.String mDefaultToDeviceProtectedStorage\nprivate @android.annotation.Nullable java.lang.String mRequestLegacyExternalStorage\nprivate @android.annotation.Nullable java.lang.String mUserDataFragile\nprivate @android.annotation.NonNull java.util.List<android.content.pm.ArchivedActivity> mLauncherActivities\n android.content.pm.ArchivedPackageParcel getParcel()\nclass ArchivedPackage extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genBuilder=false, genConstructor=false, genSetters=true)")
+ sourceFile = "frameworks/base/core/java/android/content/pm/ArchivedPackageInfo.java",
+ inputSignatures = "private @android.annotation.NonNull java.lang.String mPackageName\nprivate @android.annotation.NonNull android.content.pm.SigningInfo mSigningInfo\nprivate int mVersionCode\nprivate int mVersionCodeMajor\nprivate int mTargetSdkVersion\nprivate @android.annotation.Nullable java.lang.String mDefaultToDeviceProtectedStorage\nprivate @android.annotation.Nullable java.lang.String mRequestLegacyExternalStorage\nprivate @android.annotation.Nullable java.lang.String mUserDataFragile\nprivate @android.annotation.NonNull java.util.List<android.content.pm.ArchivedActivityInfo> mLauncherActivities\n android.content.pm.ArchivedPackageParcel getParcel()\nclass ArchivedPackageInfo extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genBuilder=false, genConstructor=false, genSetters=true)")
@Deprecated
private void __metadata() {}
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index cbb20e08f368..1114b358e08a 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -343,7 +343,10 @@ public class PackageInstaller {
* point at the existing base APK (when adding splits to an existing app).
*
* @hide
+ * @deprecated Resolved base path of an install session should not be available to unauthorized
+ * callers. Use {@link SessionInfo#getResolvedBaseApkPath()} instead.
*/
+ @Deprecated
@SystemApi
public static final String EXTRA_RESOLVED_BASE_PATH =
"android.content.pm.extra.RESOLVED_BASE_PATH";
@@ -1003,7 +1006,7 @@ public class PackageInstaller {
/**
* Install package in an archived state.
*
- * @param archivedPackage archived package data such as package name, signature etc.
+ * @param archivedPackageInfo archived package data such as package name, signature etc.
* @param sessionParams used to create an underlying installation session
* @param statusReceiver Called when the state of the session changes. Intents
* sent to this receiver contain {@link #EXTRA_STATUS}. Refer to the
@@ -1013,15 +1016,15 @@ public class PackageInstaller {
*/
@RequiresPermission(Manifest.permission.INSTALL_PACKAGES)
@FlaggedApi(Flags.FLAG_ARCHIVING)
- public void installPackageArchived(@NonNull ArchivedPackage archivedPackage,
+ public void installPackageArchived(@NonNull ArchivedPackageInfo archivedPackageInfo,
@NonNull SessionParams sessionParams,
@NonNull IntentSender statusReceiver) {
- Objects.requireNonNull(archivedPackage, "archivedPackage cannot be null");
+ Objects.requireNonNull(archivedPackageInfo, "archivedPackageInfo cannot be null");
Objects.requireNonNull(sessionParams, "sessionParams cannot be null");
Objects.requireNonNull(statusReceiver, "statusReceiver cannot be null");
try {
mInstaller.installPackageArchived(
- archivedPackage.getParcel(),
+ archivedPackageInfo.getParcel(),
sessionParams,
statusReceiver,
mInstallerPackageName,
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index ad7dd513b382..dea4a12541e5 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -11032,7 +11032,7 @@ public abstract class PackageManager {
* @see PackageInstaller#installPackageArchived
*/
@FlaggedApi(android.content.pm.Flags.FLAG_ARCHIVING)
- public @Nullable ArchivedPackage getArchivedPackage(@NonNull String packageName) {
+ public @Nullable ArchivedPackageInfo getArchivedPackage(@NonNull String packageName) {
throw new UnsupportedOperationException(
"getArchivedPackage not implemented in subclass");
}
diff --git a/core/java/android/content/res/StringBlock.java b/core/java/android/content/res/StringBlock.java
index c143acb34c5f..0070a6f920db 100644
--- a/core/java/android/content/res/StringBlock.java
+++ b/core/java/android/content/res/StringBlock.java
@@ -24,6 +24,7 @@ import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Typeface;
+import android.graphics.text.LineBreakConfig;
import android.text.Annotation;
import android.text.Spannable;
import android.text.SpannableString;
@@ -35,6 +36,7 @@ import android.text.style.BackgroundColorSpan;
import android.text.style.BulletSpan;
import android.text.style.CharacterStyle;
import android.text.style.ForegroundColorSpan;
+import android.text.style.LineBreakConfigSpan;
import android.text.style.LineHeightSpan;
import android.text.style.RelativeSizeSpan;
import android.text.style.StrikethroughSpan;
@@ -176,6 +178,10 @@ public final class StringBlock implements Closeable {
mStyleIDs.listItemId = styleId;
} else if (styleTag.equals("marquee")) {
mStyleIDs.marqueeId = styleId;
+ } else if (styleTag.equals("nobreak")) {
+ mStyleIDs.mNoBreakId = styleId;
+ } else if (styleTag.equals("nohyphen")) {
+ mStyleIDs.mNoHyphenId = styleId;
}
}
@@ -224,6 +230,8 @@ public final class StringBlock implements Closeable {
private int strikeId = -1;
private int listItemId = -1;
private int marqueeId = -1;
+ private int mNoBreakId = -1;
+ private int mNoHyphenId = -1;
}
@Nullable
@@ -285,12 +293,19 @@ public final class StringBlock implements Closeable {
buffer.setSpan(TextUtils.TruncateAt.MARQUEE,
style[i+1], style[i+2]+1,
Spannable.SPAN_INCLUSIVE_INCLUSIVE);
+ } else if (type == ids.mNoBreakId) {
+ buffer.setSpan(LineBreakConfigSpan.createNoBreakSpan(),
+ style[i + 1], style[i + 2] + 1,
+ Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
+ } else if (type == ids.mNoHyphenId) {
+ buffer.setSpan(LineBreakConfigSpan.createNoHyphenationSpan(),
+ style[i + 1], style[i + 2] + 1,
+ Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
} else {
String tag = nativeGetString(mNative, type);
if (tag == null) {
return null;
}
-
if (tag.startsWith("font;")) {
String sub;
@@ -367,6 +382,44 @@ public final class StringBlock implements Closeable {
style[i+1], style[i+2]+1,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
+ } else if (tag.startsWith("lineBreakConfig;")) {
+ String lbStyleStr = subtag(tag, ";style=");
+ int lbStyle = LineBreakConfig.LINE_BREAK_STYLE_UNSPECIFIED;
+ if (lbStyleStr != null) {
+ if (lbStyleStr.equals("none")) {
+ lbStyle = LineBreakConfig.LINE_BREAK_STYLE_NONE;
+ } else if (lbStyleStr.equals("normal")) {
+ lbStyle = LineBreakConfig.LINE_BREAK_STYLE_NORMAL;
+ } else if (lbStyleStr.equals("loose")) {
+ lbStyle = LineBreakConfig.LINE_BREAK_STYLE_LOOSE;
+ } else if (lbStyleStr.equals("strict")) {
+ lbStyle = LineBreakConfig.LINE_BREAK_STYLE_STRICT;
+ } else {
+ Log.w(TAG, "Unknown LineBreakConfig style: " + lbStyleStr);
+ }
+ }
+
+ String lbWordStyleStr = subtag(tag, ";wordStyle=");
+ int lbWordStyle = LineBreakConfig.LINE_BREAK_STYLE_UNSPECIFIED;
+ if (lbWordStyleStr != null) {
+ if (lbWordStyleStr.equals("none")) {
+ lbWordStyle = LineBreakConfig.LINE_BREAK_WORD_STYLE_NONE;
+ } else if (lbWordStyleStr.equals("phrase")) {
+ lbWordStyle = LineBreakConfig.LINE_BREAK_WORD_STYLE_PHRASE;
+ } else {
+ Log.w(TAG, "Unknown LineBreakConfig word style: " + lbWordStyleStr);
+ }
+ }
+
+ // Attach span only when the both lbStyle and lbWordStyle are valid.
+ if (lbStyle != LineBreakConfig.LINE_BREAK_STYLE_UNSPECIFIED
+ || lbWordStyle != LineBreakConfig.LINE_BREAK_WORD_STYLE_UNSPECIFIED) {
+ buffer.setSpan(new LineBreakConfigSpan(
+ new LineBreakConfig(lbStyle, lbWordStyle,
+ LineBreakConfig.HYPHENATION_UNSPECIFIED)),
+ style[i + 1], style[i + 2] + 1,
+ Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ }
}
}
diff --git a/core/java/android/credentials/CredentialManager.java b/core/java/android/credentials/CredentialManager.java
index 524afe975d73..ad3ccc41cf6d 100644
--- a/core/java/android/credentials/CredentialManager.java
+++ b/core/java/android/credentials/CredentialManager.java
@@ -437,7 +437,14 @@ public final class CredentialManager {
* Returns {@code true} if the calling application provides a CredentialProviderService that is
* enabled for the current user, or {@code false} otherwise. CredentialProviderServices are
* enabled on a per-service basis so the individual component name of the service should be
- * passed in here.
+ * passed in here. <strong>Usage of this API is discouraged as it is not fully functional, and
+ * may throw a NullPointerException on certain devices and/or API versions.</strong>
+ *
+ * @throws IllegalArgumentException if the componentName package does not match the calling
+ * package name this call will throw an exception
+ *
+ * @throws NullPointerException Usage of this API is discouraged as it is not fully
+ * functional, and may throw a NullPointerException on certain devices and/or API versions
*
* @param componentName the component name to check is enabled
*/
diff --git a/core/java/android/os/BatteryManager.java b/core/java/android/os/BatteryManager.java
index 6a4ec9b7605a..25fba60b9bb5 100644
--- a/core/java/android/os/BatteryManager.java
+++ b/core/java/android/os/BatteryManager.java
@@ -21,6 +21,7 @@ import static android.os.Flags.FLAG_STATE_OF_HEALTH_PUBLIC;
import android.Manifest.permission;
import android.annotation.FlaggedApi;
import android.annotation.RequiresPermission;
+import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.annotation.TestApi;
@@ -236,6 +237,7 @@ public class BatteryManager {
OsProtoEnums.CHARGING_POLICY_ADAPTIVE_LONGLIFE; // = 4
/** @hide */
+ @SuppressLint("UnflaggedApi") // TestApi without associated feature.
@TestApi
public static final int BATTERY_PLUGGED_ANY =
BATTERY_PLUGGED_AC | BATTERY_PLUGGED_USB | BATTERY_PLUGGED_WIRELESS
diff --git a/core/java/android/text/TextUtils.java b/core/java/android/text/TextUtils.java
index 4e3deb61761e..c0a5629f9220 100644
--- a/core/java/android/text/TextUtils.java
+++ b/core/java/android/text/TextUtils.java
@@ -47,6 +47,7 @@ import android.text.style.EasyEditSpan;
import android.text.style.ForegroundColorSpan;
import android.text.style.LeadingMarginSpan;
import android.text.style.LineBackgroundSpan;
+import android.text.style.LineBreakConfigSpan;
import android.text.style.LineHeightSpan;
import android.text.style.LocaleSpan;
import android.text.style.ParagraphStyle;
@@ -787,7 +788,9 @@ public class TextUtils {
/** @hide */
public static final int ACCESSIBILITY_REPLACEMENT_SPAN = 29;
/** @hide */
- public static final int LAST_SPAN = ACCESSIBILITY_REPLACEMENT_SPAN;
+ public static final int LINE_BREAK_CONFIG_SPAN = 30;
+ /** @hide */
+ public static final int LAST_SPAN = LINE_BREAK_CONFIG_SPAN;
/**
* Flatten a CharSequence and whatever styles can be copied across processes
@@ -991,6 +994,10 @@ public class TextUtils {
span = new AccessibilityReplacementSpan(p);
break;
+ case LINE_BREAK_CONFIG_SPAN:
+ span = LineBreakConfigSpan.CREATOR.createFromParcel(p);
+ break;
+
default:
throw new RuntimeException("bogus span encoding " + kind);
}
diff --git a/core/java/android/text/style/LineBreakConfigSpan.java b/core/java/android/text/style/LineBreakConfigSpan.java
index 682ffa180c0b..eeb638389271 100644
--- a/core/java/android/text/style/LineBreakConfigSpan.java
+++ b/core/java/android/text/style/LineBreakConfigSpan.java
@@ -21,6 +21,9 @@ import static com.android.text.flags.Flags.FLAG_NO_BREAK_NO_HYPHENATION_SPAN;
import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.graphics.text.LineBreakConfig;
+import android.os.Parcel;
+import android.text.ParcelableSpan;
+import android.text.TextUtils;
import java.util.Objects;
@@ -28,7 +31,7 @@ import java.util.Objects;
* LineBreakSpan for changing line break style of the specific region of the text.
*/
@FlaggedApi(FLAG_NO_BREAK_NO_HYPHENATION_SPAN)
-public class LineBreakConfigSpan {
+public final class LineBreakConfigSpan implements ParcelableSpan {
private final LineBreakConfig mLineBreakConfig;
/**
@@ -49,6 +52,28 @@ public class LineBreakConfigSpan {
return mLineBreakConfig;
}
+ /**
+ * A specialized {@link LineBreakConfigSpan} that used for preventing line break.
+ *
+ * This is useful when you want to preserve some words in the same line.
+ * Note that even if this style is specified, the grapheme based line break is still performed
+ * for preventing clipping text.
+ *
+ * @see LineBreakConfigSpan
+ */
+ @FlaggedApi(FLAG_NO_BREAK_NO_HYPHENATION_SPAN)
+ public static @NonNull LineBreakConfigSpan createNoBreakSpan() {
+ return new LineBreakConfigSpan(sNoBreakConfig);
+ }
+
+ /**
+ * A specialized {@link LineBreakConfigSpan} that used for preventing hyphenation.
+ */
+ @FlaggedApi(FLAG_NO_BREAK_NO_HYPHENATION_SPAN)
+ public static @NonNull LineBreakConfigSpan createNoHyphenationSpan() {
+ return new LineBreakConfigSpan(sNoHyphenationConfig);
+ }
+
@Override
public boolean equals(Object o) {
if (this == o) return true;
@@ -75,37 +100,46 @@ public class LineBreakConfigSpan {
.setLineBreakStyle(LineBreakConfig.LINE_BREAK_STYLE_NO_BREAK)
.build();
- /**
- * A specialized {@link LineBreakConfigSpan} that used for preventing hyphenation.
- */
- @FlaggedApi(FLAG_NO_BREAK_NO_HYPHENATION_SPAN)
- public static final class NoHyphenationSpan extends LineBreakConfigSpan {
- /**
- * Construct a new {@link NoHyphenationSpan}.
- */
- @FlaggedApi(FLAG_NO_BREAK_NO_HYPHENATION_SPAN)
- public NoHyphenationSpan() {
- super(sNoHyphenationConfig);
- }
+ @Override
+ public int describeContents() {
+ return 0;
}
- /**
- * A specialized {@link LineBreakConfigSpan} that used for preventing line break.
- *
- * This is useful when you want to preserve some words in the same line.
- * Note that even if this style is specified, the grapheme based line break is still performed
- * for preventing clipping text.
- *
- * @see LineBreakConfigSpan
- */
- @FlaggedApi(FLAG_NO_BREAK_NO_HYPHENATION_SPAN)
- public static final class NoBreakSpan extends LineBreakConfigSpan {
- /**
- * Construct a new {@link NoBreakSpan}.
- */
- @FlaggedApi(FLAG_NO_BREAK_NO_HYPHENATION_SPAN)
- public NoBreakSpan() {
- super(sNoBreakConfig);
- }
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ writeToParcelInternal(dest, flags);
}
+
+ @Override
+ public int getSpanTypeId() {
+ return getSpanTypeIdInternal();
+ }
+
+ /** @hide */
+ @Override
+ public int getSpanTypeIdInternal() {
+ return TextUtils.LINE_BREAK_CONFIG_SPAN;
+ }
+
+ /** @hide */
+ @Override
+ public void writeToParcelInternal(@NonNull Parcel dest, int flags) {
+ dest.writeParcelable(mLineBreakConfig, flags);
+ }
+
+ @NonNull
+ public static final Creator<LineBreakConfigSpan> CREATOR = new Creator<>() {
+
+ @Override
+ public LineBreakConfigSpan createFromParcel(Parcel source) {
+ LineBreakConfig lbc = source.readParcelable(
+ LineBreakConfig.class.getClassLoader(), LineBreakConfig.class);
+ return new LineBreakConfigSpan(lbc);
+ }
+
+ @Override
+ public LineBreakConfigSpan[] newArray(int size) {
+ return new LineBreakConfigSpan[size];
+ }
+ };
}
diff --git a/core/java/android/view/AttachedSurfaceControl.java b/core/java/android/view/AttachedSurfaceControl.java
index 71d382e19e2b..d5457511876b 100644
--- a/core/java/android/view/AttachedSurfaceControl.java
+++ b/core/java/android/view/AttachedSurfaceControl.java
@@ -15,14 +15,18 @@
*/
package android.view;
+import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UiThread;
import android.graphics.Rect;
import android.graphics.Region;
import android.hardware.HardwareBuffer;
+import android.os.IBinder;
import android.window.SurfaceSyncGroup;
+import com.android.window.flags.Flags;
+
import java.util.concurrent.Executor;
import java.util.function.Consumer;
@@ -178,6 +182,21 @@ public interface AttachedSurfaceControl {
}
/**
+ * Gets the token used for associating this {@link AttachedSurfaceControl} with
+ * {@link SurfaceControlViewHost} instances.
+ *
+ * <p>This token should be passed to {@link SurfaceControlViewHost}'s constructor.
+ *
+ * @return The SurfaceControlViewHost link token.
+ */
+ @Nullable
+ @FlaggedApi(Flags.FLAG_GET_HOST_TOKEN_API)
+ default IBinder getHostToken() {
+ throw new UnsupportedOperationException("The getHostToken needs to be "
+ + "implemented before making this call.");
+ }
+
+ /**
* Add a trusted presentation listener on the SurfaceControl associated with this window.
*
* @param t Transaction that the trusted presentation listener is added on. This should
diff --git a/core/java/android/view/SurfaceControlRegistry.java b/core/java/android/view/SurfaceControlRegistry.java
index 52be8f6a76fd..127d4a70a564 100644
--- a/core/java/android/view/SurfaceControlRegistry.java
+++ b/core/java/android/view/SurfaceControlRegistry.java
@@ -337,13 +337,13 @@ public class SurfaceControlRegistry {
@VisibleForTesting
public final boolean matchesForCallStackDebugging(@Nullable String name, @NonNull String call) {
final boolean matchCall = !sCallStackDebuggingMatchCall.isEmpty();
- if (matchCall && !call.toLowerCase().contains(sCallStackDebuggingMatchCall)) {
+ if (matchCall && !sCallStackDebuggingMatchCall.contains(call.toLowerCase())) {
// Skip if target call doesn't match requested caller
return false;
}
final boolean matchName = !sCallStackDebuggingMatchName.isEmpty();
if (matchName && (name == null
- || !name.toLowerCase().contains(sCallStackDebuggingMatchName))) {
+ || !sCallStackDebuggingMatchName.contains(name.toLowerCase()))) {
// Skip if target surface doesn't match requested surface
return false;
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 4da02f902e60..24223694e421 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -93,6 +93,7 @@ import android.accessibilityservice.AccessibilityService;
import android.animation.AnimationHandler;
import android.animation.LayoutTransition;
import android.annotation.AnyThread;
+import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Size;
@@ -227,6 +228,7 @@ import com.android.internal.policy.PhoneFallbackEventHandler;
import com.android.internal.view.BaseSurfaceHolder;
import com.android.internal.view.RootViewSurfaceTaker;
import com.android.internal.view.SurfaceCallbackHelper;
+import com.android.window.flags.Flags;
import java.io.IOException;
import java.io.OutputStream;
@@ -3962,9 +3964,15 @@ public final class ViewRootImpl implements ViewParent,
// on a different thread. However, when the current process is system, the finishDraw in
// system server will be run on the current thread, which could result in a deadlock.
if (mWindowSession instanceof Binder) {
- reportDrawFinished(t, seqId);
+ // The transaction should be copied to a local reference when posting onto a new
+ // thread because up until now the SSG is holding a lock on the transaction. Once
+ // the call jumps onto a new thread, the lock is no longer held and the transaction
+ // send back may be modified or used again.
+ Transaction transactionCopy = new Transaction();
+ transactionCopy.merge(t);
+ mHandler.postAtFrontOfQueue(() -> reportDrawFinished(transactionCopy, seqId));
} else {
- mHandler.postAtFrontOfQueue(() -> reportDrawFinished(t, seqId));
+ reportDrawFinished(t, seqId);
}
});
if (DEBUG_BLAST) {
@@ -3975,8 +3983,17 @@ public final class ViewRootImpl implements ViewParent,
}
private void notifyContentCaptureEvents() {
- Trace.traceBegin(Trace.TRACE_TAG_VIEW, "notifyContentCaptureEvents");
try {
+ if (!isContentCaptureEnabled()) {
+ if (DEBUG_CONTENT_CAPTURE) {
+ Log.d(mTag, "notifyContentCaptureEvents while disabled");
+ }
+ mAttachInfo.mContentCaptureEvents = null;
+ return;
+ }
+ if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
+ Trace.traceBegin(Trace.TRACE_TAG_VIEW, "notifyContentCaptureEvents");
+ }
MainContentCaptureSession mainSession = mAttachInfo.mContentCaptureManager
.getMainContentCaptureSession();
for (int i = 0; i < mAttachInfo.mContentCaptureEvents.size(); i++) {
@@ -4890,13 +4907,14 @@ public final class ViewRootImpl implements ViewParent,
if (DEBUG_CONTENT_CAPTURE) {
Log.v(mTag, "performContentCaptureInitialReport() on " + rootView);
}
- if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
- Trace.traceBegin(Trace.TRACE_TAG_VIEW, "dispatchContentCapture() for "
- + getClass().getSimpleName());
- }
try {
if (!isContentCaptureEnabled()) return;
+ if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
+ Trace.traceBegin(Trace.TRACE_TAG_VIEW, "dispatchContentCapture() for "
+ + getClass().getSimpleName());
+ }
+
// Initial dispatch of window bounds to content capture
if (mAttachInfo.mContentCaptureManager != null) {
MainContentCaptureSession session =
@@ -4916,13 +4934,14 @@ public final class ViewRootImpl implements ViewParent,
if (DEBUG_CONTENT_CAPTURE) {
Log.v(mTag, "handleContentCaptureFlush()");
}
- if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
- Trace.traceBegin(Trace.TRACE_TAG_VIEW, "flushContentCapture for "
- + getClass().getSimpleName());
- }
try {
if (!isContentCaptureEnabled()) return;
+ if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
+ Trace.traceBegin(Trace.TRACE_TAG_VIEW, "flushContentCapture for "
+ + getClass().getSimpleName());
+ }
+
final ContentCaptureManager ccm = mAttachInfo.mContentCaptureManager;
if (ccm == null) {
Log.w(TAG, "No ContentCapture on AttachInfo");
@@ -10858,6 +10877,17 @@ public final class ViewRootImpl implements ViewParent,
return mInputEventReceiver.getToken();
}
+ /**
+ * @return Returns a token used for associating the root surface
+ * to {@link SurfaceControlViewHost}.
+ */
+ @Nullable
+ @Override
+ @FlaggedApi(Flags.FLAG_GET_HOST_TOKEN_API)
+ public IBinder getHostToken() {
+ return getInputToken();
+ }
+
@NonNull
public IBinder getWindowToken() {
return mAttachInfo.mWindowToken;
diff --git a/core/java/android/view/accessibility/flags/accessibility_flags.aconfig b/core/java/android/view/accessibility/flags/accessibility_flags.aconfig
index 6888b50bb744..ab9566e1ece0 100644
--- a/core/java/android/view/accessibility/flags/accessibility_flags.aconfig
+++ b/core/java/android/view/accessibility/flags/accessibility_flags.aconfig
@@ -22,3 +22,10 @@ flag {
description: "Enable force force-dark for smart inversion and dark theme everywhere"
bug: "282821643"
}
+
+flag {
+ namespace: "accessibility"
+ name: "update_always_on_a11y_service"
+ description: "Updates the Always-On A11yService state when the user changes the enablement of the shortcut."
+ bug: "298869916"
+}
diff --git a/core/java/android/view/contentcapture/ContentCaptureManager.java b/core/java/android/view/contentcapture/ContentCaptureManager.java
index 970baf2ce264..5a058ff3de99 100644
--- a/core/java/android/view/contentcapture/ContentCaptureManager.java
+++ b/core/java/android/view/contentcapture/ContentCaptureManager.java
@@ -794,7 +794,9 @@ public final class ContentCaptureManager {
(params.flags & WindowManager.LayoutParams.FLAG_SECURE) != 0;
MainContentCaptureSession mainSession;
+ boolean alreadyDisabledByApp;
synchronized (mLock) {
+ alreadyDisabledByApp = (mFlags & ContentCaptureContext.FLAG_DISABLED_BY_APP) != 0;
if (flagSecureEnabled) {
mFlags |= ContentCaptureContext.FLAG_DISABLED_BY_FLAG_SECURE;
} else {
@@ -802,7 +804,9 @@ public final class ContentCaptureManager {
}
mainSession = mMainSession;
}
- if (mainSession != null) {
+
+ // Prevent overriding the status of disabling by app
+ if (mainSession != null && !alreadyDisabledByApp) {
mainSession.setDisabled(flagSecureEnabled);
}
}
diff --git a/core/java/android/view/contentcapture/MainContentCaptureSession.java b/core/java/android/view/contentcapture/MainContentCaptureSession.java
index b44d6a496058..d9b0f8035a6d 100644
--- a/core/java/android/view/contentcapture/MainContentCaptureSession.java
+++ b/core/java/android/view/contentcapture/MainContentCaptureSession.java
@@ -44,6 +44,7 @@ import android.os.Handler;
import android.os.IBinder;
import android.os.IBinder.DeathRecipient;
import android.os.RemoteException;
+import android.os.Trace;
import android.text.Selection;
import android.text.Spannable;
import android.text.TextUtils;
@@ -373,12 +374,26 @@ public final class MainContentCaptureSession extends ContentCaptureSession {
return;
}
+ if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
+ if (eventType == TYPE_VIEW_TREE_APPEARING) {
+ Trace.asyncTraceBegin(
+ Trace.TRACE_TAG_VIEW, /* methodName= */ "sendEventAsync", /* cookie= */ 0);
+ }
+ }
+
if (isContentProtectionReceiverEnabled()) {
sendContentProtectionEvent(event);
}
if (isContentCaptureReceiverEnabled()) {
sendContentCaptureEvent(event, forceFlush);
}
+
+ if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
+ if (eventType == TYPE_VIEW_TREE_APPEARED) {
+ Trace.asyncTraceEnd(
+ Trace.TRACE_TAG_VIEW, /* methodName= */ "sendEventAsync", /* cookie= */ 0);
+ }
+ }
}
@UiThread
diff --git a/core/java/android/view/contentprotection/flags/content_protection_flags.aconfig b/core/java/android/view/contentprotection/flags/content_protection_flags.aconfig
index f6ee061fdd89..f3dc33cd2cc9 100644
--- a/core/java/android/view/contentprotection/flags/content_protection_flags.aconfig
+++ b/core/java/android/view/contentprotection/flags/content_protection_flags.aconfig
@@ -20,3 +20,10 @@ flag {
description: "If true, content protection setting ui is displayed in Settings > Privacy & Security > More security & privacy."
bug: "305792348"
}
+
+flag {
+ name: "create_accessibility_overlay_app_op_enabled"
+ namespace: "content_protection"
+ description: "If true, an appop is logged on creation of accessibility overlays."
+ bug: "289081465"
+}
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 30788014ff92..403b403be961 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -85,6 +85,7 @@ import android.util.Log;
import android.util.LongArray;
import android.util.Pair;
import android.util.SizeF;
+import android.util.SparseArray;
import android.util.SparseIntArray;
import android.util.TypedValue;
import android.util.TypedValue.ComplexDimensionUnit;
@@ -367,6 +368,11 @@ public class RemoteViews implements Parcelable, Filter {
@UnsupportedAppUsage
private BitmapCache mBitmapCache = new BitmapCache();
+ /**
+ * Maps Intent ID to RemoteCollectionItems to avoid duplicate items
+ */
+ private RemoteCollectionCache mCollectionCache = new RemoteCollectionCache();
+
/** Cache of ApplicationInfos used by collection items. */
private ApplicationInfoCache mApplicationInfoCache = new ApplicationInfoCache();
@@ -784,9 +790,12 @@ public class RemoteViews implements Parcelable, Filter {
if (action instanceof SetRemoteCollectionItemListAdapterAction itemsAction
&& itemsAction.mViewId == viewId
&& itemsAction.mServiceIntent != null) {
- mActions.set(i,
- new SetRemoteCollectionItemListAdapterAction(itemsAction.mViewId,
- itemsAction.mServiceIntent));
+ SetRemoteCollectionItemListAdapterAction newCollectionAction =
+ new SetRemoteCollectionItemListAdapterAction(
+ itemsAction.mViewId, itemsAction.mServiceIntent);
+ newCollectionAction.mIntentId = itemsAction.mIntentId;
+ newCollectionAction.mIsReplacedIntoAction = true;
+ mActions.set(i, newCollectionAction);
isActionReplaced = true;
} else if (action instanceof SetRemoteViewsAdapterIntent intentAction
&& intentAction.mViewId == viewId) {
@@ -1048,6 +1057,8 @@ public class RemoteViews implements Parcelable, Filter {
@NonNull
private CompletableFuture<RemoteCollectionItems> mItemsFuture;
final Intent mServiceIntent;
+ int mIntentId = -1;
+ boolean mIsReplacedIntoAction = false;
SetRemoteCollectionItemListAdapterAction(@IdRes int id,
@NonNull RemoteCollectionItems items) {
@@ -1108,38 +1119,36 @@ public class RemoteViews implements Parcelable, Filter {
SetRemoteCollectionItemListAdapterAction(Parcel parcel) {
mViewId = parcel.readInt();
- mItemsFuture = CompletableFuture.completedFuture(
- new RemoteCollectionItems(parcel, getHierarchyRootData()));
+ mIntentId = parcel.readInt();
+ mItemsFuture = CompletableFuture.completedFuture(mIntentId != -1
+ ? null
+ : new RemoteCollectionItems(parcel, getHierarchyRootData()));
mServiceIntent = parcel.readTypedObject(Intent.CREATOR);
}
@Override
public void setHierarchyRootData(HierarchyRootData rootData) {
- mItemsFuture = mItemsFuture
- .thenApply(rc -> {
- rc.setHierarchyRootData(rootData);
- return rc;
- });
- }
-
- private static RemoteCollectionItems getCollectionItemsFromFuture(
- CompletableFuture<RemoteCollectionItems> itemsFuture) {
- RemoteCollectionItems items;
- try {
- items = itemsFuture.get();
- } catch (Exception e) {
- Log.e(LOG_TAG, "Error getting collection items from future", e);
- items = new RemoteCollectionItems.Builder().build();
+ if (mIntentId == -1) {
+ mItemsFuture = mItemsFuture
+ .thenApply(rc -> {
+ rc.setHierarchyRootData(rootData);
+ return rc;
+ });
+ return;
}
- return items;
+ // Set the root data for items in the cache instead
+ mCollectionCache.setHierarchyDataForId(mIntentId, rootData);
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mViewId);
- RemoteCollectionItems items = getCollectionItemsFromFuture(mItemsFuture);
- items.writeToParcel(dest, flags, /* attached= */ true);
+ dest.writeInt(mIntentId);
+ if (mIntentId == -1) {
+ RemoteCollectionItems items = getCollectionItemsFromFuture(mItemsFuture);
+ items.writeToParcel(dest, flags, /* attached= */ true);
+ }
dest.writeTypedObject(mServiceIntent, flags);
}
@@ -1149,7 +1158,9 @@ public class RemoteViews implements Parcelable, Filter {
View target = root.findViewById(mViewId);
if (target == null) return;
- RemoteCollectionItems items = getCollectionItemsFromFuture(mItemsFuture);
+ RemoteCollectionItems items = mIntentId == -1
+ ? getCollectionItemsFromFuture(mItemsFuture)
+ : mCollectionCache.getItemsForId(mIntentId);
// Ensure that we are applying to an AppWidget root
if (!(rootParent instanceof AppWidgetHostView)) {
@@ -1210,6 +1221,153 @@ public class RemoteViews implements Parcelable, Filter {
}
}
+ private static RemoteCollectionItems getCollectionItemsFromFuture(
+ CompletableFuture<RemoteCollectionItems> itemsFuture) {
+ RemoteCollectionItems items;
+ try {
+ items = itemsFuture.get();
+ } catch (Exception e) {
+ Log.e(LOG_TAG, "Error getting collection items from future", e);
+ items = new RemoteCollectionItems.Builder().build();
+ }
+
+ return items;
+ }
+
+ /**
+ * @hide
+ */
+ public void collectAllIntents() {
+ mCollectionCache.collectAllIntentsNoComplete(this);
+ }
+
+ private class RemoteCollectionCache {
+ private SparseArray<String> mIdToUriMapping = new SparseArray<>();
+ private HashMap<String, RemoteCollectionItems> mUriToCollectionMapping = new HashMap<>();
+
+ // We don't put this into the parcel
+ private HashMap<String, CompletableFuture<RemoteCollectionItems>> mTempUriToFutureMapping =
+ new HashMap<>();
+
+ RemoteCollectionCache() { }
+
+ RemoteCollectionCache(RemoteCollectionCache src) {
+ boolean isWaitingCache = src.mTempUriToFutureMapping.size() != 0;
+ for (int i = 0; i < src.mIdToUriMapping.size(); i++) {
+ String uri = src.mIdToUriMapping.valueAt(i);
+ mIdToUriMapping.put(src.mIdToUriMapping.keyAt(i), uri);
+ if (isWaitingCache) {
+ mTempUriToFutureMapping.put(uri, src.mTempUriToFutureMapping.get(uri));
+ } else {
+ mUriToCollectionMapping.put(uri, src.mUriToCollectionMapping.get(uri));
+ }
+ }
+ }
+
+ RemoteCollectionCache(Parcel in) {
+ int cacheSize = in.readInt();
+ HierarchyRootData currentRootData = new HierarchyRootData(mBitmapCache,
+ this,
+ mApplicationInfoCache,
+ mClassCookies);
+ for (int i = 0; i < cacheSize; i++) {
+ int intentId = in.readInt();
+ String intentUri = in.readString8();
+ RemoteCollectionItems items = new RemoteCollectionItems(in, currentRootData);
+ mIdToUriMapping.put(intentId, intentUri);
+ mUriToCollectionMapping.put(intentUri, items);
+ }
+ }
+
+ void setHierarchyDataForId(int intentId, HierarchyRootData data) {
+ String uri = mIdToUriMapping.get(intentId);
+ if (mTempUriToFutureMapping.get(uri) != null) {
+ CompletableFuture<RemoteCollectionItems> itemsFuture =
+ mTempUriToFutureMapping.get(uri);
+ mTempUriToFutureMapping.put(uri, itemsFuture.thenApply(rc -> {
+ rc.setHierarchyRootData(data);
+ return rc;
+ }));
+
+ return;
+ }
+
+ RemoteCollectionItems items = mUriToCollectionMapping.get(uri);
+ items.setHierarchyRootData(data);
+ }
+
+ RemoteCollectionItems getItemsForId(int intentId) {
+ String uri = mIdToUriMapping.get(intentId);
+ return mUriToCollectionMapping.get(uri);
+ }
+
+ void collectAllIntentsNoComplete(@NonNull RemoteViews inViews) {
+ if (inViews.hasSizedRemoteViews()) {
+ for (RemoteViews remoteViews : inViews.mSizedRemoteViews) {
+ remoteViews.collectAllIntents();
+ }
+ } else if (inViews.hasLandscapeAndPortraitLayouts()) {
+ inViews.mLandscape.collectAllIntents();
+ inViews.mPortrait.collectAllIntents();
+ } else if (inViews.mActions != null) {
+ for (Action action : inViews.mActions) {
+ if (action instanceof SetRemoteCollectionItemListAdapterAction rca) {
+ // Deal with the case where the intent is replaced into the action list
+ if (rca.mIntentId != -1 && !rca.mIsReplacedIntoAction) {
+ continue;
+ }
+
+ if (rca.mIntentId != -1 && rca.mIsReplacedIntoAction) {
+ String uri = mIdToUriMapping.get(rca.mIntentId);
+ mTempUriToFutureMapping.put(uri, rca.mItemsFuture);
+ rca.mItemsFuture = CompletableFuture.completedFuture(null);
+ continue;
+ }
+
+ // Differentiate between the normal collection actions and the ones with
+ // intents.
+ if (rca.mServiceIntent != null) {
+ String uri = rca.mServiceIntent.toUri(0);
+ int index = mIdToUriMapping.indexOfValue(uri);
+ if (index == -1) {
+ int newIntentId = mIdToUriMapping.size();
+ rca.mIntentId = newIntentId;
+ mIdToUriMapping.put(newIntentId, uri);
+ // mUriToIntentMapping.put(uri, mServiceIntent);
+ mTempUriToFutureMapping.put(uri, rca.mItemsFuture);
+ } else {
+ rca.mIntentId = mIdToUriMapping.keyAt(index);
+ }
+ rca.mItemsFuture = CompletableFuture.completedFuture(null);
+ } else {
+ RemoteCollectionItems items = getCollectionItemsFromFuture(
+ rca.mItemsFuture);
+ for (RemoteViews views : items.mViews) {
+ views.collectAllIntents();
+ }
+ }
+ } else if (action instanceof ViewGroupActionAdd vgaa
+ && vgaa.mNestedViews != null) {
+ vgaa.mNestedViews.collectAllIntents();
+ }
+ }
+ }
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeInt(mIdToUriMapping.size());
+ for (int i = 0; i < mIdToUriMapping.size(); i++) {
+ out.writeInt(mIdToUriMapping.keyAt(i));
+ String intentUri = mIdToUriMapping.valueAt(i);
+ out.writeString8(intentUri);
+ RemoteCollectionItems items = mTempUriToFutureMapping.get(intentUri) != null
+ ? getCollectionItemsFromFuture(mTempUriToFutureMapping.get(intentUri))
+ : mUriToCollectionMapping.get(intentUri);
+ items.writeToParcel(out, flags, true);
+ }
+ }
+ }
+
private class SetRemoteViewsAdapterIntent extends Action {
Intent mIntent;
boolean mIsAsync = false;
@@ -3850,9 +4008,12 @@ public class RemoteViews implements Parcelable, Filter {
private void initializeFrom(@NonNull RemoteViews src, @Nullable RemoteViews hierarchyRoot) {
if (hierarchyRoot == null) {
mBitmapCache = src.mBitmapCache;
+ // We need to create a new instance because we don't reconstruct collection cache
+ mCollectionCache = new RemoteCollectionCache(src.mCollectionCache);
mApplicationInfoCache = src.mApplicationInfoCache;
} else {
mBitmapCache = hierarchyRoot.mBitmapCache;
+ mCollectionCache = hierarchyRoot.mCollectionCache;
mApplicationInfoCache = hierarchyRoot.mApplicationInfoCache;
}
if (hierarchyRoot == null || src.mIsRoot) {
@@ -3926,6 +4087,7 @@ public class RemoteViews implements Parcelable, Filter {
mBitmapCache = new BitmapCache(parcel);
// Store the class cookies such that they are available when we clone this RemoteView.
mClassCookies = parcel.copyClassCookies();
+ mCollectionCache = new RemoteCollectionCache(parcel);
} else {
configureAsChild(rootData);
}
@@ -4087,6 +4249,7 @@ public class RemoteViews implements Parcelable, Filter {
private void configureAsChild(@NonNull HierarchyRootData rootData) {
mIsRoot = false;
mBitmapCache = rootData.mBitmapCache;
+ mCollectionCache = rootData.mRemoteCollectionCache;
mApplicationInfoCache = rootData.mApplicationInfoCache;
mClassCookies = rootData.mClassCookies;
configureDescendantsAsChildren();
@@ -6357,6 +6520,7 @@ public class RemoteViews implements Parcelable, Filter {
// is shared by all children.
if (mIsRoot) {
mBitmapCache.writeBitmapsToParcel(dest, flags);
+ mCollectionCache.writeToParcel(dest, flags);
}
mApplication.writeToParcel(dest, flags);
if (mIsRoot || mIdealSize == null) {
@@ -6373,6 +6537,7 @@ public class RemoteViews implements Parcelable, Filter {
dest.writeInt(MODE_HAS_SIZED_REMOTEVIEWS);
if (mIsRoot) {
mBitmapCache.writeBitmapsToParcel(dest, flags);
+ mCollectionCache.writeToParcel(dest, flags);
}
dest.writeInt(mSizedRemoteViews.size());
for (RemoteViews view : mSizedRemoteViews) {
@@ -6384,6 +6549,7 @@ public class RemoteViews implements Parcelable, Filter {
// is shared by all children.
if (mIsRoot) {
mBitmapCache.writeBitmapsToParcel(dest, flags);
+ mCollectionCache.writeToParcel(dest, flags);
}
mLandscape.writeToParcel(dest, flags);
// Both RemoteViews already share the same package and user
@@ -7262,19 +7428,23 @@ public class RemoteViews implements Parcelable, Filter {
}
private HierarchyRootData getHierarchyRootData() {
- return new HierarchyRootData(mBitmapCache, mApplicationInfoCache, mClassCookies);
+ return new HierarchyRootData(mBitmapCache, mCollectionCache,
+ mApplicationInfoCache, mClassCookies);
}
private static final class HierarchyRootData {
final BitmapCache mBitmapCache;
+ final RemoteCollectionCache mRemoteCollectionCache;
final ApplicationInfoCache mApplicationInfoCache;
final Map<Class, Object> mClassCookies;
HierarchyRootData(
BitmapCache bitmapCache,
+ RemoteCollectionCache remoteCollectionCache,
ApplicationInfoCache applicationInfoCache,
Map<Class, Object> classCookies) {
mBitmapCache = bitmapCache;
+ mRemoteCollectionCache = remoteCollectionCache;
mApplicationInfoCache = applicationInfoCache;
mClassCookies = classCookies;
}
diff --git a/core/java/android/window/ITaskFragmentOrganizerController.aidl b/core/java/android/window/ITaskFragmentOrganizerController.aidl
index 7b7e34172fed..4706dfd1a76c 100644
--- a/core/java/android/window/ITaskFragmentOrganizerController.aidl
+++ b/core/java/android/window/ITaskFragmentOrganizerController.aidl
@@ -19,6 +19,7 @@ package android.window;
import android.os.IBinder;
import android.view.RemoteAnimationDefinition;
import android.window.ITaskFragmentOrganizer;
+import android.window.RemoteTransition;
import android.window.WindowContainerTransaction;
/** @hide */
@@ -65,7 +66,10 @@ interface ITaskFragmentOrganizerController {
/**
* Requests the server to apply the given {@link WindowContainerTransaction}.
+ *
+ * {@link RemoteTransition} can only be used by a system organizer and
+ * {@code shouldApplyIndependently} must be {@code true}. See {@link registerOrganizer}.
*/
void applyTransaction(in WindowContainerTransaction wct, int transitionType,
- boolean shouldApplyIndependently);
+ boolean shouldApplyIndependently, in RemoteTransition remoteTransition);
}
diff --git a/core/java/android/window/TaskFragmentOrganizer.java b/core/java/android/window/TaskFragmentOrganizer.java
index a6c9cecb508f..5c113f865d45 100644
--- a/core/java/android/window/TaskFragmentOrganizer.java
+++ b/core/java/android/window/TaskFragmentOrganizer.java
@@ -275,7 +275,31 @@ public class TaskFragmentOrganizer extends WindowOrganizer {
}
wct.setTaskFragmentOrganizer(mInterface);
try {
- getController().applyTransaction(wct, transitionType, shouldApplyIndependently);
+ getController().applyTransaction(
+ wct, transitionType, shouldApplyIndependently, null /* remoteTransition */);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Applies a transaction with a {@link RemoteTransition}. Only a system organizer is allowed to
+ * use {@link RemoteTransition}. See {@link TaskFragmentOrganizer#registerOrganizer(boolean)}.
+ *
+ * @hide
+ */
+ @FlaggedApi(Flags.FLAG_TASK_FRAGMENT_SYSTEM_ORGANIZER_FLAG)
+ public void applySystemTransaction(@NonNull WindowContainerTransaction wct,
+ @TaskFragmentTransitionType int transitionType,
+ @Nullable RemoteTransition remoteTransition) {
+ if (wct.isEmpty()) {
+ return;
+ }
+ wct.setTaskFragmentOrganizer(mInterface);
+ try {
+ getController().applyTransaction(
+ wct, transitionType, remoteTransition != null /* shouldApplyIndependently */,
+ remoteTransition);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/window/WindowTokenClient.java b/core/java/android/window/WindowTokenClient.java
index f4f1b3b9b27b..c20b278f7eaa 100644
--- a/core/java/android/window/WindowTokenClient.java
+++ b/core/java/android/window/WindowTokenClient.java
@@ -31,10 +31,8 @@ import android.content.res.Configuration;
import android.inputmethodservice.AbstractInputMethodService;
import android.os.Binder;
import android.os.Build;
-import android.os.Bundle;
import android.os.Debug;
import android.os.Handler;
-import android.os.IBinder;
import android.util.Log;
import com.android.internal.annotations.GuardedBy;
@@ -76,8 +74,7 @@ public class WindowTokenClient extends Binder {
* Attaches {@code context} to this {@link WindowTokenClient}. Each {@link WindowTokenClient}
* can only attach one {@link Context}.
* <p>This method must be called before invoking
- * {@link android.view.IWindowManager#attachWindowContextToDisplayArea(IBinder, int, int,
- * Bundle)}.<p/>
+ * {@link android.view.IWindowManager#attachWindowContextToDisplayArea}.<p/>
*
* @param context context to be attached
* @throws IllegalStateException if attached context has already existed.
diff --git a/core/java/android/window/flags/responsible_apis.aconfig b/core/java/android/window/flags/responsible_apis.aconfig
new file mode 100644
index 000000000000..4bfb17700a76
--- /dev/null
+++ b/core/java/android/window/flags/responsible_apis.aconfig
@@ -0,0 +1,22 @@
+package: "com.android.window.flags"
+
+flag {
+ name: "bal_require_opt_in_by_pending_intent_creator"
+ namespace: "responsible_apis"
+ description: "Require the PendingIntent creator to opt in starting with Android 15"
+ bug: "296478951"
+}
+
+flag {
+ name: "bal_dont_bring_existing_background_task_stack_to_fg"
+ namespace: "responsible_apis"
+ description: "When starting a PendingIntent with ONLY creator privileges, don't bring the existing task stack to foreground"
+ bug: "296478675"
+}
+
+flag {
+ name: "bal_show_toasts"
+ namespace: "responsible_apis"
+ description: "Enable toasts to indicate (potential) BAL blocking."
+ bug: "308059069"
+} \ No newline at end of file
diff --git a/core/java/android/window/flags/wallpaper_manager.aconfig b/core/java/android/window/flags/wallpaper_manager.aconfig
new file mode 100644
index 000000000000..09be0cfc5fb0
--- /dev/null
+++ b/core/java/android/window/flags/wallpaper_manager.aconfig
@@ -0,0 +1,8 @@
+package: "com.android.window.flags"
+
+flag {
+ name: "always_update_wallpaper_permission"
+ namespace: "wear_frameworks"
+ description: "Allow out of focus process to update wallpaper complications"
+ bug: "271132915"
+} \ No newline at end of file
diff --git a/core/java/android/window/flags/window_surfaces.aconfig b/core/java/android/window/flags/window_surfaces.aconfig
index ccbf4a9b3d21..5ad5c79f2d42 100644
--- a/core/java/android/window/flags/window_surfaces.aconfig
+++ b/core/java/android/window/flags/window_surfaces.aconfig
@@ -17,3 +17,11 @@ flag {
is_fixed_read_only: true
bug: "300019131"
}
+
+flag {
+ namespace: "window_surfaces"
+ name: "get_host_token_api"
+ description: "Feature flag to associate the host and embedded windows"
+ is_fixed_read_only: true
+ bug: "304508760"
+}
diff --git a/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java b/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java
index 2efe44544f37..de0f070b01a3 100644
--- a/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java
+++ b/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java
@@ -53,10 +53,13 @@ import android.util.Slog;
import android.view.Window;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.Flags;
import android.widget.Toast;
import com.android.internal.R;
+import com.android.internal.accessibility.common.ShortcutConstants;
import com.android.internal.accessibility.dialog.AccessibilityTarget;
+import com.android.internal.accessibility.util.ShortcutUtils;
import com.android.internal.util.function.pooled.PooledLambda;
import java.lang.annotation.Retention;
@@ -66,6 +69,7 @@ import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Map;
+import java.util.Set;
/**
* Class to help manage the accessibility shortcut key
@@ -364,9 +368,23 @@ public class AccessibilityShortcutController {
})
.setPositiveButton(R.string.accessibility_shortcut_off,
(DialogInterface d, int which) -> {
- Settings.Secure.putStringForUser(mContext.getContentResolver(),
- Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, "",
- userId);
+ if (Flags.updateAlwaysOnA11yService()) {
+ Set<String> targetServices =
+ ShortcutUtils.getShortcutTargetsFromSettings(
+ mContext,
+ ShortcutConstants.UserShortcutType.HARDWARE,
+ userId);
+
+ Settings.Secure.putStringForUser(mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, "",
+ userId);
+ ShortcutUtils.updateInvisibleToggleAccessibilityServiceEnableState(
+ mContext, targetServices, userId);
+ } else {
+ Settings.Secure.putStringForUser(mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, "",
+ userId);
+ }
// If canceled, treat as if the dialog has never been shown
Settings.Secure.putIntForUser(mContext.getContentResolver(),
diff --git a/core/java/com/android/internal/accessibility/common/ShortcutConstants.java b/core/java/com/android/internal/accessibility/common/ShortcutConstants.java
index e6360048706b..7ec8838699b3 100644
--- a/core/java/com/android/internal/accessibility/common/ShortcutConstants.java
+++ b/core/java/com/android/internal/accessibility/common/ShortcutConstants.java
@@ -60,6 +60,17 @@ public final class ShortcutConstants {
}
/**
+ * A list of possible {@link UserShortcutType}. Should stay in sync with the
+ * non-default IntDef types.
+ */
+ public static final int[] USER_SHORTCUT_TYPES = {
+ UserShortcutType.SOFTWARE,
+ UserShortcutType.HARDWARE,
+ UserShortcutType.TRIPLETAP
+ };
+
+
+ /**
* Annotation for the different accessibility fragment type.
*
* {@code VOLUME_SHORTCUT_TOGGLE} for displaying appearance with switch bar and only one
diff --git a/core/java/com/android/internal/accessibility/dialog/InvisibleToggleAccessibilityServiceTarget.java b/core/java/com/android/internal/accessibility/dialog/InvisibleToggleAccessibilityServiceTarget.java
index 9d5c374e98f5..1bc8b84e6869 100644
--- a/core/java/com/android/internal/accessibility/dialog/InvisibleToggleAccessibilityServiceTarget.java
+++ b/core/java/com/android/internal/accessibility/dialog/InvisibleToggleAccessibilityServiceTarget.java
@@ -27,17 +27,25 @@ import android.accessibilityservice.AccessibilityServiceInfo;
import android.annotation.NonNull;
import android.content.ComponentName;
import android.content.Context;
+import android.os.UserHandle;
import android.view.accessibility.AccessibilityManager.ShortcutType;
+import android.view.accessibility.Flags;
import com.android.internal.accessibility.common.ShortcutConstants.AccessibilityFragmentType;
+import com.android.internal.accessibility.util.ShortcutUtils;
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.Set;
/**
* Extension for {@link AccessibilityServiceTarget} with
* {@link AccessibilityFragmentType#INVISIBLE_TOGGLE} type.
*/
-class InvisibleToggleAccessibilityServiceTarget extends AccessibilityServiceTarget {
+@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+public class InvisibleToggleAccessibilityServiceTarget extends AccessibilityServiceTarget {
- InvisibleToggleAccessibilityServiceTarget(Context context, @ShortcutType int shortcutType,
+ public InvisibleToggleAccessibilityServiceTarget(
+ Context context, @ShortcutType int shortcutType,
@NonNull AccessibilityServiceInfo serviceInfo) {
super(context,
shortcutType,
@@ -49,11 +57,17 @@ class InvisibleToggleAccessibilityServiceTarget extends AccessibilityServiceTarg
public void onCheckedChanged(boolean isChecked) {
final ComponentName componentName = ComponentName.unflattenFromString(getId());
- if (!isComponentIdExistingInOtherShortcut()) {
- setAccessibilityServiceState(getContext(), componentName, isChecked);
- }
+ if (Flags.updateAlwaysOnA11yService()) {
+ super.onCheckedChanged(isChecked);
+ ShortcutUtils.updateInvisibleToggleAccessibilityServiceEnableState(
+ getContext(), Set.of(componentName.flattenToString()), UserHandle.myUserId());
+ } else {
+ if (!isComponentIdExistingInOtherShortcut()) {
+ setAccessibilityServiceState(getContext(), componentName, isChecked);
+ }
- super.onCheckedChanged(isChecked);
+ super.onCheckedChanged(isChecked);
+ }
}
private boolean isComponentIdExistingInOtherShortcut() {
diff --git a/core/java/com/android/internal/accessibility/util/ShortcutUtils.java b/core/java/com/android/internal/accessibility/util/ShortcutUtils.java
index 31ccb6c32bab..3fd303038c57 100644
--- a/core/java/com/android/internal/accessibility/util/ShortcutUtils.java
+++ b/core/java/com/android/internal/accessibility/util/ShortcutUtils.java
@@ -15,20 +15,29 @@
*/
package com.android.internal.accessibility.util;
+
import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_BUTTON;
import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_SHORTCUT_KEY;
+import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME;
+import static com.android.internal.accessibility.common.ShortcutConstants.AccessibilityFragmentType.INVISIBLE_TOGGLE;
import static com.android.internal.accessibility.common.ShortcutConstants.SERVICES_SEPARATOR;
+import static com.android.internal.accessibility.common.ShortcutConstants.USER_SHORTCUT_TYPES;
import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType;
+import android.accessibilityservice.AccessibilityServiceInfo;
import android.annotation.NonNull;
+import android.content.ComponentName;
import android.content.Context;
import android.provider.Settings;
import android.text.TextUtils;
+import android.util.ArraySet;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityManager.ShortcutType;
+import java.util.Collections;
import java.util.List;
+import java.util.Set;
import java.util.StringJoiner;
/**
@@ -180,4 +189,92 @@ public final class ShortcutUtils {
"Unsupported shortcut type:" + type);
}
}
+
+ /**
+ * Updates an accessibility state if the accessibility service is a Always-On a11y service,
+ * a.k.a. AccessibilityServices that has FLAG_REQUEST_ACCESSIBILITY_BUTTON
+ * <p>
+ * Turn on the accessibility service when there is any shortcut associated to it.
+ * <p>
+ * Turn off the accessibility service when there is no shortcut associated to it.
+ *
+ * @param componentNames the a11y shortcut target's component names
+ */
+ public static void updateInvisibleToggleAccessibilityServiceEnableState(
+ Context context, Set<String> componentNames, int userId) {
+ final AccessibilityManager am = (AccessibilityManager) context.getSystemService(
+ Context.ACCESSIBILITY_SERVICE);
+ if (am == null) return;
+
+ final List<AccessibilityServiceInfo> installedServices =
+ am.getInstalledAccessibilityServiceList();
+
+ final Set<String> invisibleToggleServices = new ArraySet<>();
+ for (AccessibilityServiceInfo serviceInfo : installedServices) {
+ if (AccessibilityUtils.getAccessibilityServiceFragmentType(serviceInfo)
+ == INVISIBLE_TOGGLE) {
+ invisibleToggleServices.add(serviceInfo.getComponentName().flattenToString());
+ }
+ }
+
+ final Set<String> servicesWithShortcuts = new ArraySet<>();
+ for (int shortcutType: USER_SHORTCUT_TYPES) {
+ // The call to update always-on service might modify the shortcut setting right before
+ // calling #updateAccessibilityServiceStateIfNeeded in the same call.
+ // To avoid getting the shortcut target from out-dated value, use values from Settings
+ // instead.
+ servicesWithShortcuts.addAll(
+ getShortcutTargetsFromSettings(context, shortcutType, userId));
+ }
+
+ for (String componentName : componentNames) {
+ // Only needs to update the Always-On A11yService's state when the shortcut changes.
+ if (invisibleToggleServices.contains(componentName)) {
+
+ boolean enableA11yService = servicesWithShortcuts.contains(componentName);
+ AccessibilityUtils.setAccessibilityServiceState(
+ context,
+ ComponentName.unflattenFromString(componentName), enableA11yService);
+ }
+ }
+ }
+
+ /**
+ * Returns the target component names of a given user shortcut type from Settings.
+ *
+ * <p>
+ * Note: grab shortcut targets from Settings is only needed
+ * if you depends on a value being set in the same call.
+ * For example, you disable a single shortcut,
+ * and you're checking if there is any shortcut remaining.
+ *
+ * <p>
+ * If you just want to know the current state, you can use
+ * {@link AccessibilityManager#getAccessibilityShortcutTargets(int)}
+ */
+ public static Set<String> getShortcutTargetsFromSettings(
+ Context context, @UserShortcutType int shortcutType, int userId) {
+ final String targetKey = convertToKey(shortcutType);
+ if (Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED.equals(targetKey)) {
+ boolean magnificationEnabled = Settings.Secure.getIntForUser(
+ context.getContentResolver(), targetKey, /* def= */ 0, userId) == 1;
+ return magnificationEnabled ? Set.of(MAGNIFICATION_CONTROLLER_NAME)
+ : Collections.emptySet();
+
+ } else {
+ final String targetString = Settings.Secure.getStringForUser(
+ context.getContentResolver(), targetKey, userId);
+
+ if (TextUtils.isEmpty(targetString)) {
+ return Collections.emptySet();
+ }
+
+ Set<String> targets = new ArraySet<>();
+ sStringColonSplitter.setString(targetString);
+ while (sStringColonSplitter.hasNext()) {
+ targets.add(sStringColonSplitter.next());
+ }
+ return Collections.unmodifiableSet(targets);
+ }
+ }
}
diff --git a/core/java/com/android/internal/app/IAppOpsService.aidl b/core/java/com/android/internal/app/IAppOpsService.aidl
index 492e2ac7cc28..1b05982a7569 100644
--- a/core/java/com/android/internal/app/IAppOpsService.aidl
+++ b/core/java/com/android/internal/app/IAppOpsService.aidl
@@ -42,18 +42,22 @@ import com.android.internal.app.MessageSamplingConfig;
// frameworks/native/libs/permission/include/binder/IAppOpsService.h must match the order here.
// Please be careful to respect both these issues when modifying this file.
interface IAppOpsService {
- // These methods are also called by native code, so please be careful that the number in
- // frameworks/native/libs/permission/include/binder/IAppOpsService.h matches the ordering here.
+ // Deprecated, use checkOperationWithState instead.
int checkOperation(int code, int uid, String packageName);
+ // Deprecated, use noteOperationWithState instead.
SyncNotedAppOp noteOperation(int code, int uid, String packageName, @nullable String attributionTag,
boolean shouldCollectAsyncNotedOp, String message, boolean shouldCollectMessage);
+ // Deprecated, use startOperationWithState instead.
SyncNotedAppOp startOperation(IBinder clientId, int code, int uid, String packageName,
@nullable String attributionTag, boolean startIfModeDefault,
boolean shouldCollectAsyncNotedOp, String message, boolean shouldCollectMessage,
int attributionFlags, int attributionChainId);
+ // Deprecated, use finishOperationWithState instead.
@UnsupportedAppUsage
void finishOperation(IBinder clientId, int code, int uid, String packageName,
@nullable String attributionTag);
+ // These methods are also called by native code, so please be careful that the number in
+ // frameworks/native/libs/permission/include/binder/IAppOpsService.h matches the ordering here.
void startWatchingMode(int op, String packageName, IAppOpsCallback callback);
void stopWatchingMode(IAppOpsCallback callback);
int permissionToOpCode(String permission);
@@ -134,20 +138,33 @@ interface IAppOpsService {
void stopWatchingAsyncNoted(String packageName, IAppOpsAsyncNotedCallback callback);
List<AsyncNotedAppOp> extractAsyncOps(String packageName);
+ // Deprecated, use checkOperationWithStateRaw instead.
int checkOperationRaw(int code, int uid, String packageName, @nullable String attributionTag);
void reloadNonHistoricalState();
void collectNoteOpCallsForValidation(String stackTrace, int op, String packageName, long version);
-
+ // These methods are also called by native code, so please be careful that the number in
+ // frameworks/native/libs/permission/include/binder/IAppOpsService.h matches the ordering here.
+ int checkOperationWithState(int code, in AttributionSourceState attributionSourceState);
+ int checkOperationWithStateRaw(int code, in AttributionSourceState attributionSourceState);
+ SyncNotedAppOp noteOperationWithState(int code, in AttributionSourceState attributionSourceState,
+ boolean shouldCollectAsyncNotedOp, String message, boolean shouldCollectMessage);
+ SyncNotedAppOp startOperationWithState(IBinder clientId, int code,
+ in AttributionSourceState attributionSourceState, boolean startIfModeDefault,
+ boolean shouldCollectAsyncNotedOp, String message, boolean shouldCollectMessage,
+ int attributionFlags, int attributionChainId);
+ void finishOperationWithState(IBinder clientId, int code, in AttributionSourceState attributionSourceState);
+ // End of methods also called by native code (there may be more blocks like this of native
+ // methods later in this file).
SyncNotedAppOp noteProxyOperationWithState(int code,
- in AttributionSourceState attributionSourceStateState,
- boolean shouldCollectAsyncNotedOp, String message, boolean shouldCollectMessage,
- boolean skipProxyOperation);
+ in AttributionSourceState attributionSourceStateState,
+ boolean shouldCollectAsyncNotedOp, String message, boolean shouldCollectMessage,
+ boolean skipProxyOperation);
SyncNotedAppOp startProxyOperationWithState(IBinder clientId, int code,
- in AttributionSourceState attributionSourceStateState, boolean startIfModeDefault,
- boolean shouldCollectAsyncNotedOp, String message, boolean shouldCollectMessage,
- boolean skipProxyOperation, int proxyAttributionFlags, int proxiedAttributionFlags,
- int attributionChainId);
+ in AttributionSourceState attributionSourceStateState, boolean startIfModeDefault,
+ boolean shouldCollectAsyncNotedOp, String message, boolean shouldCollectMessage,
+ boolean skipProxyOperation, int proxyAttributionFlags, int proxiedAttributionFlags,
+ int attributionChainId);
void finishProxyOperationWithState(IBinder clientId, int code,
- in AttributionSourceState attributionSourceStateState, boolean skipProxyOperation);
+ in AttributionSourceState attributionSourceStateState, boolean skipProxyOperation);
}
diff --git a/core/java/com/android/internal/config/sysui/SystemUiSystemPropertiesFlags.java b/core/java/com/android/internal/config/sysui/SystemUiSystemPropertiesFlags.java
index 77e150239803..df6c1538fc6d 100644
--- a/core/java/com/android/internal/config/sysui/SystemUiSystemPropertiesFlags.java
+++ b/core/java/com/android/internal/config/sysui/SystemUiSystemPropertiesFlags.java
@@ -106,6 +106,10 @@ public class SystemUiSystemPropertiesFlags {
/** b/301242692: Visit extra URIs used in notifications to prevent security issues. */
public static final Flag VISIT_RISKY_URIS = devFlag(
"persist.sysui.notification.visit_risky_uris");
+
+ /** b/303716154: For debugging only: use short bitmap duration. */
+ public static final Flag DEBUG_SHORT_BITMAP_DURATION = devFlag(
+ "persist.sysui.notification.debug_short_bitmap_duration");
}
//// == End of flags. Everything below this line is the implementation. == ////
diff --git a/core/java/com/android/internal/content/PackageMonitor.java b/core/java/com/android/internal/content/PackageMonitor.java
index 0b69030d384f..9d88a2341fad 100644
--- a/core/java/com/android/internal/content/PackageMonitor.java
+++ b/core/java/com/android/internal/content/PackageMonitor.java
@@ -401,6 +401,12 @@ public abstract class PackageMonitor extends android.content.BroadcastReceiver {
if (intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
mChangeType = PACKAGE_UPDATING;
onPackageUpdateStarted(pkg, uid);
+ if (intent.getBooleanExtra(Intent.EXTRA_ARCHIVAL, false)) {
+ // In case it is a removal event due to archiving, we trigger package
+ // update event to refresh details like icons, title etc. corresponding to
+ // the archived app.
+ onPackageModified(pkg);
+ }
} else {
mChangeType = PACKAGE_PERMANENT_CHANGE;
// We only consider something to have changed if this is
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 8c91be8b21c0..c75f99616f5b 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -4065,6 +4065,7 @@
<!-- Allow apps to always update wallpaper by sending data.
@SystemApi
@hide
+ @FlaggedApi("com.android.window.flags.always_update_wallpaper_permission")
-->
<permission android:name="android.permission.ALWAYS_UPDATE_WALLPAPER"
android:protectionLevel="internal|role" />
diff --git a/core/res/res/drawable/archived_app_cloud_overlay.xml b/core/res/res/drawable/archived_app_cloud_overlay.xml
new file mode 100644
index 000000000000..611e0f39bb5c
--- /dev/null
+++ b/core/res/res/drawable/archived_app_cloud_overlay.xml
@@ -0,0 +1,15 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="20dp"
+ android:height="20dp"
+ android:viewportWidth="60"
+ android:viewportHeight="60">
+ <group
+ android:scaleX="1.2"
+ android:scaleY="1.2"
+ android:translateX="15"
+ android:translateY="14">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M19.35,10.04C18.67,6.59 15.64,4 12,4 9.11,4 6.6,5.64 5.35,8.04 2.34,8.36 0,10.91 0,14c0,3.31 2.69,6 6,6h13c2.76,0 5,-2.24 5,-5 0,-2.64 -2.05,-4.78 -4.65,-4.96zM19,18L6,18c-2.21,0 -4,-1.79 -4,-4 0,-2.05 1.53,-3.76 3.56,-3.97l1.07,-0.11 0.5,-0.95C8.08,7.14 9.94,6 12,6c2.62,0 4.88,1.86 5.39,4.43l0.3,1.5 1.53,0.11c1.56,0.1 2.78,1.41 2.78,2.96 0,1.65 -1.35,3 -3,3zM13.45,10h-2.9v3L8,13l4,4 4,-4h-2.55z"/>
+ </group>
+</vector> \ No newline at end of file
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 14bbb966f750..1aa1fea95049 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1405,6 +1405,7 @@
<java-symbol type="drawable" name="ic_test_badge_no_background" />
<java-symbol type="drawable" name="ic_test_icon_badge_experiment" />
<java-symbol type="drawable" name="ic_instant_icon_badge_bolt" />
+ <java-symbol type="drawable" name="archived_app_cloud_overlay" />
<java-symbol type="drawable" name="emulator_circular_window_overlay" />
<java-symbol type="drawable" name="ic_qs_battery_saver" />
<java-symbol type="drawable" name="ic_qs_bluetooth" />
diff --git a/core/tests/coretests/src/android/app/OWNERS b/core/tests/coretests/src/android/app/OWNERS
index 64f5e6c68a95..5636f9bc436c 100644
--- a/core/tests/coretests/src/android/app/OWNERS
+++ b/core/tests/coretests/src/android/app/OWNERS
@@ -10,3 +10,7 @@ per-file *UiAutomation* = file:/services/accessibility/OWNERS
# KeyguardManagerTest
per-file KeyguardManagerTest.java = file:/services/core/java/com/android/server/locksettings/OWNERS
+
+# Files related to background activity launches
+per-file Background*Start* = file:/BAL_OWNERS
+
diff --git a/core/tests/coretests/src/android/os/PowerManagerTest.java b/core/tests/coretests/src/android/os/PowerManagerTest.java
index 21d1dbb04519..5d213caf61e6 100644
--- a/core/tests/coretests/src/android/os/PowerManagerTest.java
+++ b/core/tests/coretests/src/android/os/PowerManagerTest.java
@@ -19,11 +19,17 @@ package android.os;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import android.content.Context;
+import android.os.Flags;
+import android.platform.test.annotations.RequiresFlagsEnabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.test.AndroidTestCase;
import androidx.test.InstrumentationRegistry;
@@ -31,6 +37,7 @@ import androidx.test.filters.SmallTest;
import androidx.test.uiautomator.UiDevice;
import org.junit.After;
+import org.junit.Rule;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -64,6 +71,10 @@ public class PowerManagerTest extends AndroidTestCase {
System.loadLibrary("powermanagertest_jni");
}
+ // Required for RequiresFlagsEnabled and RequiresFlagsDisabled annotations to take effect.
+ @Rule
+ public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
+
/**
* Setup any common data for the upcoming tests.
*/
@@ -454,4 +465,27 @@ public class PowerManagerTest extends AndroidTestCase {
parcelBatterySaverPolicyConfigToNativeAndVerify(bs2);
}
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_BATTERY_SAVER_SUPPORTED_CHECK_API)
+ public void testBatterySaverSupported_isSupported() throws RemoteException {
+ IPowerManager powerManager = mock(IPowerManager.class);
+ PowerManager pm = new PowerManager(mContext, powerManager,
+ mock(IThermalService.class),
+ Handler.createAsync(Looper.getMainLooper()));
+ when(powerManager.isBatterySaverSupported()).thenReturn(true);
+
+ assertTrue(pm.isBatterySaverSupported());
+ }
+
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_BATTERY_SAVER_SUPPORTED_CHECK_API)
+ public void testBatterySaverSupported_isNotSupported() throws RemoteException {
+ IPowerManager powerManager = mock(IPowerManager.class);
+ PowerManager pm = new PowerManager(mContext, powerManager,
+ mock(IThermalService.class),
+ Handler.createAsync(Looper.getMainLooper()));
+ when(powerManager.isBatterySaverSupported()).thenReturn(false);
+
+ assertFalse(pm.isBatterySaverSupported());
+ }
}
diff --git a/core/tests/coretests/src/android/view/ViewRootImplTest.java b/core/tests/coretests/src/android/view/ViewRootImplTest.java
index 6a9fc04230f8..40fd34e7d072 100644
--- a/core/tests/coretests/src/android/view/ViewRootImplTest.java
+++ b/core/tests/coretests/src/android/view/ViewRootImplTest.java
@@ -48,6 +48,9 @@ import android.hardware.display.DisplayManagerGlobal;
import android.os.Binder;
import android.os.SystemProperties;
import android.platform.test.annotations.Presubmit;
+import android.platform.test.annotations.RequiresFlagsEnabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.Settings;
import android.util.Log;
@@ -60,6 +63,7 @@ import androidx.test.filters.SmallTest;
import androidx.test.platform.app.InstrumentationRegistry;
import com.android.compatibility.common.util.ShellIdentityUtils;
+import com.android.window.flags.Flags;
import org.junit.After;
import org.junit.AfterClass;
@@ -97,6 +101,9 @@ public class ViewRootImplTest {
// state after the test completes.
private static boolean sOriginalTouchMode;
+ @Rule
+ public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
+
@BeforeClass
public static void setUpClass() {
sContext = sInstrumentation.getTargetContext();
@@ -338,6 +345,19 @@ public class ViewRootImplTest {
assertThat(view.hasWindowFocus()).isFalse();
}
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_GET_HOST_TOKEN_API)
+ public void whenViewIsAttachedToWindow_getHostToken() {
+ View view = new View(sContext);
+ attachViewToWindow(view);
+
+ mViewRootImpl = view.getViewRootImpl();
+
+ assertThat(mViewRootImpl.getHostToken()).isNotEqualTo(null);
+ assertThat(mViewRootImpl.getHostToken())
+ .isEqualTo(mViewRootImpl.getInputToken());
+ }
+
/**
* When window doesn't have focus, keys should be dropped.
*/
diff --git a/core/tests/coretests/src/android/view/contentcapture/ContentCaptureManagerTest.java b/core/tests/coretests/src/android/view/contentcapture/ContentCaptureManagerTest.java
index 5c411d5335a7..35ddfdb3723b 100644
--- a/core/tests/coretests/src/android/view/contentcapture/ContentCaptureManagerTest.java
+++ b/core/tests/coretests/src/android/view/contentcapture/ContentCaptureManagerTest.java
@@ -23,6 +23,7 @@ import static org.testng.Assert.assertThrows;
import android.content.ContentCaptureOptions;
import android.content.Context;
+import android.view.WindowManager;
import com.android.internal.util.RingBuffer;
@@ -147,6 +148,52 @@ public class ContentCaptureManagerTest {
assertThat(manager.getFlushViewTreeAppearingEventDisabled()).isFalse();
}
+ @Test
+ public void testUpdateWindowAttribute_setFlagSecure() {
+ final ContentCaptureManager manager =
+ new ContentCaptureManager(mMockContext, mMockContentCaptureManager, EMPTY_OPTIONS);
+ // Ensure main session is created.
+ final MainContentCaptureSession unused = manager.getMainContentCaptureSession();
+ final WindowManager.LayoutParams initialParam = new WindowManager.LayoutParams();
+ initialParam.flags |= WindowManager.LayoutParams.FLAG_SECURE;
+
+ manager.updateWindowAttributes(initialParam);
+
+ assertThat(manager.isContentCaptureEnabled()).isFalse();
+ }
+
+ @Test
+ public void testUpdateWindowAttribute_clearFlagSecure() {
+ final ContentCaptureManager manager =
+ new ContentCaptureManager(mMockContext, mMockContentCaptureManager, EMPTY_OPTIONS);
+ // Ensure main session is created.
+ final MainContentCaptureSession unused = manager.getMainContentCaptureSession();
+ final WindowManager.LayoutParams initialParam = new WindowManager.LayoutParams();
+ initialParam.flags |= WindowManager.LayoutParams.FLAG_SECURE;
+ // Default param does not have FLAG_SECURE set.
+ final WindowManager.LayoutParams resetParam = new WindowManager.LayoutParams();
+
+ manager.updateWindowAttributes(initialParam);
+ manager.updateWindowAttributes(resetParam);
+
+ assertThat(manager.isContentCaptureEnabled()).isTrue();
+ }
+
+ @Test
+ public void testUpdateWindowAttribute_clearFlagSecureAfterDisabledByApp() {
+ final ContentCaptureManager manager =
+ new ContentCaptureManager(mMockContext, mMockContentCaptureManager, EMPTY_OPTIONS);
+ // Ensure main session is created.
+ final MainContentCaptureSession unused = manager.getMainContentCaptureSession();
+ // Default param does not have FLAG_SECURE set.
+ final WindowManager.LayoutParams resetParam = new WindowManager.LayoutParams();
+
+ manager.setContentCaptureEnabled(false);
+ manager.updateWindowAttributes(resetParam);
+
+ assertThat(manager.isContentCaptureEnabled()).isFalse();
+ }
+
private ContentCaptureOptions createOptions(
ContentCaptureOptions.ContentProtectionOptions contentProtectionOptions) {
return new ContentCaptureOptions(
diff --git a/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java b/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java
index cd5ec851e9eb..75b0d4a159d9 100644
--- a/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java
+++ b/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java
@@ -16,9 +16,11 @@
package com.android.internal.accessibility;
+import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS;
import static android.provider.Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN;
import static android.provider.Settings.Secure.ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN;
import static android.provider.Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE;
+import static android.provider.Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES;
import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_SHORTCUT_KEY;
import static com.android.internal.accessibility.AccessibilityShortcutController.ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME;
@@ -62,6 +64,9 @@ import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.os.Vibrator;
+import android.platform.test.annotations.RequiresFlagsEnabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.provider.Settings;
import android.speech.tts.TextToSpeech;
import android.speech.tts.Voice;
@@ -69,6 +74,7 @@ import android.test.mock.MockContentResolver;
import android.view.Window;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.Flags;
import android.view.accessibility.IAccessibilityManager;
import android.widget.Toast;
@@ -81,6 +87,7 @@ import com.android.internal.util.test.FakeSettingsProvider;
import org.junit.AfterClass;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
@@ -96,6 +103,9 @@ import java.util.Set;
@RunWith(AndroidJUnit4.class)
public class AccessibilityShortcutControllerTest {
+ @Rule
+ public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
+
private static final String SERVICE_NAME_STRING = "fake.package/fake.service.name";
private static final CharSequence PACKAGE_NAME_STRING = "Service name";
private static final String SERVICE_NAME_SUMMARY = "Summary";
@@ -430,6 +440,43 @@ public class AccessibilityShortcutControllerTest {
}
@Test
+ @RequiresFlagsEnabled(Flags.FLAG_UPDATE_ALWAYS_ON_A11Y_SERVICE)
+ public void turnOffVolumeShortcutForAlwaysOnA11yService_shouldTurnOffA11yService()
+ throws Exception {
+ configureApplicationTargetSdkVersion(Build.VERSION_CODES.R);
+ turnOffVolumeKeyShortcutForA11yService(/* alwaysOnService= */ true);
+
+ assertThat(
+ Settings.Secure.getString(mContentResolver, ENABLED_ACCESSIBILITY_SERVICES)
+ ).isEmpty();
+ }
+
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_UPDATE_ALWAYS_ON_A11Y_SERVICE)
+ public void turnOffVolumeShortcutForAlwaysOnA11yService_hasOtherTypesShortcut_shouldNotTurnOffA11yService()
+ throws Exception {
+ configureApplicationTargetSdkVersion(Build.VERSION_CODES.R);
+ Settings.Secure.putString(
+ mContentResolver, ACCESSIBILITY_BUTTON_TARGETS, SERVICE_NAME_STRING);
+
+ turnOffVolumeKeyShortcutForA11yService(/* alwaysOnService= */ true);
+
+ assertThat(
+ Settings.Secure.getString(mContentResolver, ENABLED_ACCESSIBILITY_SERVICES)
+ ).isEqualTo(SERVICE_NAME_STRING);
+ }
+
+ @Test
+ public void turnOffVolumeShortcutForStandardA11yService_shouldNotTurnOffA11yService()
+ throws Exception {
+ turnOffVolumeKeyShortcutForA11yService(/* alwaysOnService= */ false);
+
+ assertThat(
+ Settings.Secure.getString(mContentResolver, ENABLED_ACCESSIBILITY_SERVICES)
+ ).isEqualTo(SERVICE_NAME_STRING);
+ }
+
+ @Test
public void testClickingTurnOnButtonInDialog_shouldLeaveShortcutReady() throws Exception {
configureShortcutEnabled(ENABLED_EXCEPT_LOCK_SCREEN);
configureValidShortcutService();
@@ -746,6 +793,8 @@ public class AccessibilityShortcutControllerTest {
private void configureEnabledService() throws Exception {
when(mAccessibilityManagerService.getEnabledAccessibilityServiceList(anyInt(), anyInt()))
.thenReturn(Collections.singletonList(mServiceInfo));
+ Settings.Secure.putString(
+ mContentResolver, ENABLED_ACCESSIBILITY_SERVICES, SERVICE_NAME_STRING);
}
private AccessibilityShortcutController getController() {
@@ -763,4 +812,21 @@ public class AccessibilityShortcutControllerTest {
when(mResources.getString(R.string.config_defaultAccessibilityService)).thenReturn(
SERVICE_NAME_STRING);
}
+
+ private void turnOffVolumeKeyShortcutForA11yService(boolean alwaysOnService) throws Exception {
+ configureValidShortcutService();
+ Settings.Secure.putInt(mContentResolver, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN,
+ AccessibilityShortcutController.DialogStatus.NOT_SHOWN);
+ if (alwaysOnService) {
+ configureRequestAccessibilityButton();
+ }
+ configureEnabledService();
+ getController().performAccessibilityShortcut();
+
+ ArgumentCaptor<DialogInterface.OnClickListener> captor =
+ ArgumentCaptor.forClass(DialogInterface.OnClickListener.class);
+ verify(mAlertDialogBuilder).setPositiveButton(eq(R.string.accessibility_shortcut_off),
+ captor.capture());
+ captor.getValue().onClick(null, DialogInterface.BUTTON_POSITIVE);
+ }
}
diff --git a/core/tests/coretests/src/com/android/internal/accessibility/TestUtils.java b/core/tests/coretests/src/com/android/internal/accessibility/TestUtils.java
index ff014add793a..1bb03fcc99e5 100644
--- a/core/tests/coretests/src/com/android/internal/accessibility/TestUtils.java
+++ b/core/tests/coretests/src/com/android/internal/accessibility/TestUtils.java
@@ -16,6 +16,17 @@
package com.android.internal.accessibility;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import android.accessibilityservice.AccessibilityServiceInfo;
+import android.content.ComponentName;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.os.Build;
+
import com.android.internal.os.RoSystemProperties;
import java.lang.reflect.Field;
@@ -38,4 +49,32 @@ public class TestUtils {
throw new RuntimeException(e);
}
}
+
+ /**
+ * Creates fake accessibility service info.
+ */
+ public static AccessibilityServiceInfo createFakeServiceInfo(
+ String packageLabel, String serviceComponent,
+ String serviceSummary, boolean isAlwaysOnService) {
+ ApplicationInfo applicationInfo = mock(ApplicationInfo.class);
+ applicationInfo.targetSdkVersion = Build.VERSION_CODES.R;
+ ServiceInfo serviceInfo = mock(ServiceInfo.class);
+ ResolveInfo resolveInfo = mock(ResolveInfo.class);
+ resolveInfo.serviceInfo = serviceInfo;
+ resolveInfo.serviceInfo.applicationInfo = applicationInfo;
+ when(resolveInfo.loadLabel(any())).thenReturn(packageLabel);
+
+ AccessibilityServiceInfo a11yServiceInfo = mock(AccessibilityServiceInfo.class);
+ when(a11yServiceInfo.getResolveInfo()).thenReturn(resolveInfo);
+ when(a11yServiceInfo.getComponentName())
+ .thenReturn(ComponentName.unflattenFromString(serviceComponent));
+ when(a11yServiceInfo.loadSummary(any())).thenReturn(serviceSummary);
+
+ if (isAlwaysOnService) {
+ a11yServiceInfo.flags |= AccessibilityServiceInfo
+ .FLAG_REQUEST_ACCESSIBILITY_BUTTON;
+ }
+
+ return a11yServiceInfo;
+ }
}
diff --git a/core/tests/coretests/src/com/android/internal/accessibility/dialog/InvisibleToggleAccessibilityServiceTargetTest.java b/core/tests/coretests/src/com/android/internal/accessibility/dialog/InvisibleToggleAccessibilityServiceTargetTest.java
new file mode 100644
index 000000000000..69b6a9b7aa87
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/accessibility/dialog/InvisibleToggleAccessibilityServiceTargetTest.java
@@ -0,0 +1,182 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.accessibility.dialog;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.accessibilityservice.AccessibilityServiceInfo;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.content.pm.ParceledListSlice;
+import android.os.Handler;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.IAccessibilityManager;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.internal.accessibility.TestUtils;
+import com.android.internal.util.test.FakeSettingsProvider;
+import com.android.internal.util.test.FakeSettingsProviderRule;
+
+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.Collections;
+
+/**
+ * Unit Tests for
+ * {@link com.android.internal.accessibility.dialog.InvisibleToggleAccessibilityServiceTarget}
+ */
+@RunWith(AndroidJUnit4.class)
+public class InvisibleToggleAccessibilityServiceTargetTest {
+ @Rule
+ public FakeSettingsProviderRule mSettingsProviderRule = FakeSettingsProvider.rule();
+ @Mock
+ private IAccessibilityManager mAccessibilityManagerService;
+
+ private static final String ALWAYS_ON_SERVICE_PACKAGE_LABEL = "always on a11y service";
+ private static final String ALWAYS_ON_SERVICE_COMPONENT_NAME =
+ "fake.package/fake.alwayson.service.name";
+ private static final String FAKE_A11Y_SERVICE_SUMMARY = "A11yService summary";
+
+ private ContextWrapper mContextSpy;
+ private InvisibleToggleAccessibilityServiceTarget mSut;
+
+ @Before
+ public void setUp() throws RemoteException {
+ MockitoAnnotations.initMocks(this);
+ mContextSpy = spy(
+ new ContextWrapper(InstrumentationRegistry.getInstrumentation().getContext()));
+
+ ContentResolver contentResolver = mSettingsProviderRule.mockContentResolver(mContextSpy);
+ when(mContextSpy.getContentResolver()).thenReturn(contentResolver);
+
+ AccessibilityManager accessibilityManager =
+ new AccessibilityManager(
+ mContextSpy, mock(Handler.class),
+ mAccessibilityManagerService, UserHandle.myUserId(),
+ /* serviceConnect= */ true);
+ when(mContextSpy.getSystemService(Context.ACCESSIBILITY_SERVICE))
+ .thenReturn(accessibilityManager);
+
+ AccessibilityServiceInfo accessibilityServiceInfo = TestUtils.createFakeServiceInfo(
+ ALWAYS_ON_SERVICE_PACKAGE_LABEL,
+ ALWAYS_ON_SERVICE_COMPONENT_NAME,
+ FAKE_A11Y_SERVICE_SUMMARY,
+ /* isAlwaysOnService*/ true);
+ when(mAccessibilityManagerService.getInstalledAccessibilityServiceList(anyInt()))
+ .thenReturn(
+ new ParceledListSlice<>(
+ Collections.singletonList(accessibilityServiceInfo)));
+
+ mSut = new InvisibleToggleAccessibilityServiceTarget(
+ mContextSpy,
+ AccessibilityManager.ACCESSIBILITY_SHORTCUT_KEY, accessibilityServiceInfo);
+ }
+
+ @Test
+ public void onCheckedChanged_turnOnShortcut_hasOtherShortcut_serviceKeepsOn() {
+ enableA11yService(/* enable= */ true);
+ addShortcutForA11yService(
+ Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, /* add= */ false);
+ addShortcutForA11yService(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, /* add= */ true);
+
+ mSut.onCheckedChanged(/* isChecked= */ true);
+
+ assertA11yServiceState(/* enabled= */ true);
+ }
+
+ @Test
+ public void onCheckedChanged_turnOnShortcut_noOtherShortcut_shouldTurnOnService() {
+ enableA11yService(/* enable= */ false);
+ addShortcutForA11yService(
+ Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, /* add= */ false);
+ addShortcutForA11yService(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, /* add= */ false);
+
+ mSut.onCheckedChanged(/* isChecked= */ true);
+
+ assertA11yServiceState(/* enabled= */ true);
+ }
+
+ @Test
+ public void onCheckedChanged_turnOffShortcut_hasOtherShortcut_serviceKeepsOn() {
+ enableA11yService(/* enable= */ true);
+ addShortcutForA11yService(
+ Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, /* add= */ true);
+ addShortcutForA11yService(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, /* add= */ true);
+
+ mSut.onCheckedChanged(/* isChecked= */ false);
+
+ assertA11yServiceState(/* enabled= */ true);
+ }
+
+ @Test
+ public void onCheckedChanged_turnOffShortcut_noOtherShortcut_shouldTurnOffService() {
+ enableA11yService(/* enable= */ true);
+ addShortcutForA11yService(
+ Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, /* add= */ true);
+ addShortcutForA11yService(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, /* add= */ false);
+
+ mSut.onCheckedChanged(/* isChecked= */ false);
+
+ assertA11yServiceState(/* enabled= */ false);
+ }
+
+ private void enableA11yService(boolean enable) {
+ Settings.Secure.putString(
+ mContextSpy.getContentResolver(),
+ Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
+ enable ? ALWAYS_ON_SERVICE_COMPONENT_NAME : "");
+ }
+
+ private void addShortcutForA11yService(String shortcutKey, boolean add) {
+ Settings.Secure.putString(
+ mContextSpy.getContentResolver(),
+ shortcutKey,
+ add ? ALWAYS_ON_SERVICE_COMPONENT_NAME : "");
+ }
+
+ private void assertA11yServiceState(boolean enabled) {
+ if (enabled) {
+ assertThat(
+ Settings.Secure.getString(
+ mContextSpy.getContentResolver(),
+ Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES)
+ ).contains(ALWAYS_ON_SERVICE_COMPONENT_NAME);
+ } else {
+ assertThat(
+ Settings.Secure.getString(
+ mContextSpy.getContentResolver(),
+ Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES)
+ ).doesNotContain(ALWAYS_ON_SERVICE_COMPONENT_NAME);
+ }
+ }
+}
diff --git a/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityUtilsTest.java b/core/tests/coretests/src/com/android/internal/accessibility/util/AccessibilityUtilsTest.java
index 3ea7f471e4bd..58ab92af7dbd 100644
--- a/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityUtilsTest.java
+++ b/core/tests/coretests/src/com/android/internal/accessibility/util/AccessibilityUtilsTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.accessibility;
+package com.android.internal.accessibility.util;
import static com.android.internal.accessibility.util.AccessibilityUtils.ACCESSIBILITY_MENU_IN_SYSTEM;
import static com.android.internal.accessibility.util.AccessibilityUtils.MENU_SERVICE_RELATIVE_CLASS_NAME;
@@ -35,8 +35,6 @@ import android.text.style.LocaleSpan;
import androidx.test.runner.AndroidJUnit4;
-import com.android.internal.accessibility.util.AccessibilityUtils;
-
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
diff --git a/core/tests/coretests/src/com/android/internal/accessibility/util/ShortcutUtilsTest.java b/core/tests/coretests/src/com/android/internal/accessibility/util/ShortcutUtilsTest.java
new file mode 100644
index 000000000000..708f246fea75
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/accessibility/util/ShortcutUtilsTest.java
@@ -0,0 +1,358 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.accessibility.util;
+
+import static android.provider.Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED;
+import static android.provider.Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_MAGNIFICATION_CONTROLLER;
+
+import static com.android.internal.accessibility.common.ShortcutConstants.SERVICES_SEPARATOR;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.accessibilityservice.AccessibilityServiceInfo;
+import android.content.ComponentName;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.content.pm.ParceledListSlice;
+import android.os.Handler;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.IAccessibilityManager;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.internal.accessibility.AccessibilityShortcutController;
+import com.android.internal.accessibility.TestUtils;
+import com.android.internal.accessibility.common.ShortcutConstants;
+import com.android.internal.util.test.FakeSettingsProvider;
+import com.android.internal.util.test.FakeSettingsProviderRule;
+
+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.List;
+import java.util.Set;
+import java.util.StringJoiner;
+
+/**
+ * Unit Tests for {@link com.android.internal.accessibility.util.ShortcutUtils}
+ */
+@RunWith(AndroidJUnit4.class)
+public class ShortcutUtilsTest {
+ private static final Set<String> ONE_COMPONENT = Set.of(
+ new ComponentName("pkg", "serv").flattenToString());
+ private static final Set<String> TWO_COMPONENTS = Set.of(
+ new ComponentName("pkg", "serv").flattenToString(),
+ AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME);
+ private static final String ALWAYS_ON_SERVICE_PACKAGE_LABEL = "always on a11y service";
+ private static final String ALWAYS_ON_SERVICE_COMPONENT_NAME =
+ "fake.package/fake.alwayson.service.name";
+
+ private static final String STANDARD_SERVICE_PACKAGE_LABEL = "standard a11y service";
+ private static final String STANDARD_SERVICE_COMPONENT_NAME =
+ "fake.package/fake.standard.service.name";
+ private static final String SERVICE_NAME_SUMMARY = "Summary";
+
+ @Rule
+ public FakeSettingsProviderRule mSettingsProviderRule = FakeSettingsProvider.rule();
+ @Mock
+ private IAccessibilityManager mAccessibilityManagerService;
+ private ContextWrapper mContextSpy;
+
+ @Before
+ public void setUp() throws RemoteException {
+ MockitoAnnotations.initMocks(this);
+ mContextSpy = spy(
+ new ContextWrapper(InstrumentationRegistry.getInstrumentation().getContext()));
+
+ ContentResolver contentResolver = mSettingsProviderRule.mockContentResolver(mContextSpy);
+ when(mContextSpy.getContentResolver()).thenReturn(contentResolver);
+
+ AccessibilityManager accessibilityManager =
+ new AccessibilityManager(
+ mContextSpy, mock(Handler.class),
+ mAccessibilityManagerService, UserHandle.myUserId(),
+ /* serviceConnect= */ true);
+ when(mContextSpy.getSystemService(Context.ACCESSIBILITY_SERVICE))
+ .thenReturn(accessibilityManager);
+
+ setupFakeA11yServiceInfos();
+ }
+
+ @Test
+ public void getShortcutTargets_softwareShortcutNoService_emptyResult() {
+ assertThat(
+ ShortcutUtils.getShortcutTargetsFromSettings(
+ mContextSpy,
+ ShortcutConstants.UserShortcutType.SOFTWARE, UserHandle.myUserId())
+ ).isEmpty();
+ }
+
+ @Test
+ public void getShortcutTargets_volumeKeyShortcutNoService_emptyResult() {
+ assertThat(
+ ShortcutUtils.getShortcutTargetsFromSettings(
+ mContextSpy, ShortcutConstants.UserShortcutType.HARDWARE,
+ UserHandle.myUserId())
+ ).isEmpty();
+ }
+
+ @Test
+ public void getShortcutTargets_softwareShortcut1Service_return1Service() {
+ setupShortcutTargets(ONE_COMPONENT, Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS);
+ setupShortcutTargets(TWO_COMPONENTS, Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE);
+
+ assertThat(
+ ShortcutUtils.getShortcutTargetsFromSettings(
+ mContextSpy, ShortcutConstants.UserShortcutType.SOFTWARE,
+ UserHandle.myUserId())
+ ).containsExactlyElementsIn(ONE_COMPONENT);
+ }
+
+ @Test
+ public void getShortcutTargets_volumeShortcut2Service_return2Service() {
+ setupShortcutTargets(ONE_COMPONENT, Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS);
+ setupShortcutTargets(TWO_COMPONENTS, Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE);
+
+ assertThat(
+ ShortcutUtils.getShortcutTargetsFromSettings(
+ mContextSpy, ShortcutConstants.UserShortcutType.HARDWARE,
+ UserHandle.myUserId())
+ ).containsExactlyElementsIn(TWO_COMPONENTS);
+ }
+
+ @Test
+ public void getShortcutTargets_tripleTapShortcut_magnificationDisabled_emptyResult() {
+ enableTripleTapShortcutForMagnification(/* enable= */ false);
+ setupShortcutTargets(ONE_COMPONENT, Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS);
+ setupShortcutTargets(TWO_COMPONENTS, Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE);
+
+ assertThat(
+ ShortcutUtils.getShortcutTargetsFromSettings(
+ mContextSpy, ShortcutConstants.UserShortcutType.TRIPLETAP,
+ UserHandle.myUserId())
+ ).isEmpty();
+ }
+
+ @Test
+ public void getShortcutTargets_tripleTapShortcut_magnificationEnabled_returnMagnification() {
+ setupShortcutTargets(ONE_COMPONENT, Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS);
+ setupShortcutTargets(TWO_COMPONENTS, Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE);
+ enableTripleTapShortcutForMagnification(/* enable= */ true);
+
+ assertThat(
+ ShortcutUtils.getShortcutTargetsFromSettings(
+ mContextSpy, ShortcutConstants.UserShortcutType.TRIPLETAP,
+ UserHandle.myUserId())
+ ).containsExactly(ACCESSIBILITY_SHORTCUT_TARGET_MAGNIFICATION_CONTROLLER);
+ }
+
+ @Test
+ public void updateAccessibilityServiceStateIfNeeded_alwaysOnServiceOn_noShortcuts_serviceTurnedOff() {
+ setupA11yServiceAndShortcutState(
+ ALWAYS_ON_SERVICE_COMPONENT_NAME, /* serviceOn= */ true, /* shortcutOn= */ false);
+
+ ShortcutUtils.updateInvisibleToggleAccessibilityServiceEnableState(
+ mContextSpy,
+ Set.of(ALWAYS_ON_SERVICE_COMPONENT_NAME),
+ UserHandle.myUserId()
+ );
+
+ assertA11yServiceState(ALWAYS_ON_SERVICE_COMPONENT_NAME, /* enabled= */ false);
+ }
+
+ @Test
+ public void updateAccessibilityServiceStateIfNeeded_alwaysOnServiceOn_hasShortcut_serviceKeepsOn() {
+ setupA11yServiceAndShortcutState(
+ ALWAYS_ON_SERVICE_COMPONENT_NAME, /* serviceOn= */ true, /* shortcutOn= */ true);
+
+ ShortcutUtils.updateInvisibleToggleAccessibilityServiceEnableState(
+ mContextSpy,
+ Set.of(ALWAYS_ON_SERVICE_COMPONENT_NAME),
+ UserHandle.myUserId()
+ );
+
+ assertA11yServiceState(ALWAYS_ON_SERVICE_COMPONENT_NAME, /* enabled= */ true);
+ }
+
+ @Test
+ public void updateAccessibilityServiceStateIfNeeded_alwaysOnServiceOff_noShortcuts_serviceKeepsOff() {
+ setupA11yServiceAndShortcutState(
+ ALWAYS_ON_SERVICE_COMPONENT_NAME, /* serviceOn= */ false, /* shortcutOn= */ false);
+
+ ShortcutUtils.updateInvisibleToggleAccessibilityServiceEnableState(
+ mContextSpy,
+ Set.of(ALWAYS_ON_SERVICE_COMPONENT_NAME),
+ UserHandle.myUserId()
+ );
+
+ assertA11yServiceState(ALWAYS_ON_SERVICE_COMPONENT_NAME, /* enabled= */ false);
+ }
+
+ @Test
+ public void updateAccessibilityServiceStateIfNeeded_alwaysOnServiceOff_hasShortcuts_serviceTurnsOn() {
+ setupA11yServiceAndShortcutState(
+ ALWAYS_ON_SERVICE_COMPONENT_NAME, /* serviceOn= */ false, /* shortcutOn= */ true);
+
+ ShortcutUtils.updateInvisibleToggleAccessibilityServiceEnableState(
+ mContextSpy,
+ Set.of(ALWAYS_ON_SERVICE_COMPONENT_NAME),
+ UserHandle.myUserId()
+ );
+
+ assertA11yServiceState(ALWAYS_ON_SERVICE_COMPONENT_NAME, /* enabled= */ true);
+ }
+
+ @Test
+ public void updateAccessibilityServiceStateIfNeeded_standardA11yServiceOn_noShortcuts_serviceKeepsOn() {
+ setupA11yServiceAndShortcutState(
+ STANDARD_SERVICE_COMPONENT_NAME, /* serviceOn= */ true, /* shortcutOn= */ false);
+
+ ShortcutUtils.updateInvisibleToggleAccessibilityServiceEnableState(
+ mContextSpy,
+ Set.of(STANDARD_SERVICE_COMPONENT_NAME),
+ UserHandle.myUserId()
+ );
+
+ assertA11yServiceState(STANDARD_SERVICE_COMPONENT_NAME, /* enabled= */ true);
+ }
+
+ @Test
+ public void updateAccessibilityServiceStateIfNeeded_standardA11yServiceOn_hasShortcuts_serviceKeepsOn() {
+ setupA11yServiceAndShortcutState(
+ STANDARD_SERVICE_COMPONENT_NAME, /* serviceOn= */ true, /* shortcutOn= */ true);
+
+ ShortcutUtils.updateInvisibleToggleAccessibilityServiceEnableState(
+ mContextSpy,
+ Set.of(STANDARD_SERVICE_COMPONENT_NAME),
+ UserHandle.myUserId()
+ );
+
+ assertA11yServiceState(STANDARD_SERVICE_COMPONENT_NAME, /* enabled= */ true);
+ }
+
+ @Test
+ public void updateAccessibilityServiceStateIfNeeded_standardA11yServiceOff_noShortcuts_serviceKeepsOff() {
+ setupA11yServiceAndShortcutState(
+ STANDARD_SERVICE_COMPONENT_NAME, /* serviceOn= */ false, /* shortcutOn= */ false);
+
+ ShortcutUtils.updateInvisibleToggleAccessibilityServiceEnableState(
+ mContextSpy,
+ Set.of(STANDARD_SERVICE_COMPONENT_NAME),
+ UserHandle.myUserId()
+ );
+
+ assertA11yServiceState(STANDARD_SERVICE_COMPONENT_NAME, /* enabled= */ false);
+ }
+
+ @Test
+ public void updateAccessibilityServiceStateIfNeeded_standardA11yServiceOff_hasShortcuts_serviceKeepsOff() {
+ setupA11yServiceAndShortcutState(
+ STANDARD_SERVICE_COMPONENT_NAME, /* serviceOn= */ false, /* shortcutOn= */ true);
+
+ ShortcutUtils.updateInvisibleToggleAccessibilityServiceEnableState(
+ mContextSpy,
+ Set.of(STANDARD_SERVICE_COMPONENT_NAME),
+ UserHandle.myUserId()
+ );
+
+ assertA11yServiceState(STANDARD_SERVICE_COMPONENT_NAME, /* enabled= */ false);
+ }
+
+ private void setupShortcutTargets(Set<String> components, String shortcutSettingsKey) {
+ final StringJoiner stringJoiner = new StringJoiner(String.valueOf(SERVICES_SEPARATOR));
+ for (String target : components) {
+ stringJoiner.add(target);
+ }
+ Settings.Secure.putStringForUser(
+ mContextSpy.getContentResolver(), shortcutSettingsKey,
+ stringJoiner.toString(),
+ UserHandle.myUserId());
+ }
+
+ private void enableTripleTapShortcutForMagnification(boolean enable) {
+ Settings.Secure.putInt(
+ mContextSpy.getContentResolver(),
+ ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, enable ? 1 : 0);
+ }
+
+ private void setupFakeA11yServiceInfos() throws RemoteException {
+ List<AccessibilityServiceInfo> serviceInfos = List.of(
+ TestUtils.createFakeServiceInfo(
+ ALWAYS_ON_SERVICE_PACKAGE_LABEL,
+ ALWAYS_ON_SERVICE_COMPONENT_NAME,
+ SERVICE_NAME_SUMMARY,
+ /* isAlwaysOnService*/ true),
+ TestUtils.createFakeServiceInfo(
+ STANDARD_SERVICE_PACKAGE_LABEL,
+ STANDARD_SERVICE_COMPONENT_NAME,
+ SERVICE_NAME_SUMMARY,
+ /* isAlwaysOnService*/ false)
+ );
+ when(mAccessibilityManagerService.getInstalledAccessibilityServiceList(anyInt()))
+ .thenReturn(new ParceledListSlice<>(serviceInfos));
+ }
+
+ private void setupA11yServiceAndShortcutState(
+ String a11yServiceComponentName, boolean serviceOn, boolean shortcutOn) {
+ enableA11yService(a11yServiceComponentName, serviceOn);
+ addShortcutForA11yService(a11yServiceComponentName, shortcutOn);
+ }
+
+ private void assertA11yServiceState(String a11yServiceComponentName, boolean enabled) {
+ if (enabled) {
+ assertThat(
+ Settings.Secure.getString(
+ mContextSpy.getContentResolver(),
+ Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES)
+ ).contains(a11yServiceComponentName);
+ } else {
+ assertThat(
+ Settings.Secure.getString(
+ mContextSpy.getContentResolver(),
+ Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES)
+ ).doesNotContain(a11yServiceComponentName);
+ }
+ }
+
+ private void enableA11yService(String a11yServiceComponentName, boolean enable) {
+ Settings.Secure.putString(
+ mContextSpy.getContentResolver(),
+ Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
+ enable ? a11yServiceComponentName : "");
+ }
+
+ private void addShortcutForA11yService(String a11yServiceComponentName, boolean add) {
+ Settings.Secure.putString(
+ mContextSpy.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE,
+ add ? a11yServiceComponentName : "");
+ }
+}
diff --git a/core/tests/packagemonitortests/src/com/android/internal/content/PackageMonitorTest.java b/core/tests/packagemonitortests/src/com/android/internal/content/PackageMonitorTest.java
index a3399070ebcd..8e653f5e828f 100644
--- a/core/tests/packagemonitortests/src/com/android/internal/content/PackageMonitorTest.java
+++ b/core/tests/packagemonitortests/src/com/android/internal/content/PackageMonitorTest.java
@@ -298,6 +298,43 @@ public class PackageMonitorTest {
}
@Test
+ public void testPackageMonitorDoHandlePackageEventPackageRemovedReplacingArchived() {
+ PackageMonitor spyPackageMonitor = spy(new TestPackageMonitor());
+
+ Intent intent = new Intent(Intent.ACTION_PACKAGE_REMOVED);
+ intent.setData(Uri.fromParts("package", FAKE_PACKAGE_NAME, null));
+ intent.putExtra(Intent.EXTRA_USER_HANDLE, FAKE_USER_ID);
+ intent.putExtra(Intent.EXTRA_UID, FAKE_PACKAGE_UID);
+ intent.putExtra(Intent.EXTRA_REPLACING, true);
+ intent.putExtra(Intent.EXTRA_ARCHIVAL, true);
+ intent.putExtra(Intent.EXTRA_REMOVED_FOR_ALL_USERS, true);
+ spyPackageMonitor.doHandlePackageEvent(intent);
+
+ verify(spyPackageMonitor, times(1)).onBeginPackageChanges();
+ verify(spyPackageMonitor, times(1))
+ .onPackageUpdateStarted(eq(FAKE_PACKAGE_NAME), eq(FAKE_PACKAGE_UID));
+ verify(spyPackageMonitor, times(1)).onPackageModified(eq(FAKE_PACKAGE_NAME));
+
+ ArgumentCaptor<Bundle> argumentCaptor = ArgumentCaptor.forClass(Bundle.class);
+ verify(spyPackageMonitor, times(1))
+ .onPackageDisappearedWithExtras(eq(FAKE_PACKAGE_NAME), argumentCaptor.capture());
+ Bundle capturedExtras = argumentCaptor.getValue();
+ Bundle expectedExtras = intent.getExtras();
+ assertThat(capturedExtras.getInt(Intent.EXTRA_USER_HANDLE))
+ .isEqualTo(expectedExtras.getInt(Intent.EXTRA_USER_HANDLE));
+ assertThat(capturedExtras.getInt(Intent.EXTRA_UID))
+ .isEqualTo(expectedExtras.getInt(Intent.EXTRA_UID));
+ assertThat(capturedExtras.getInt(Intent.EXTRA_REPLACING))
+ .isEqualTo(expectedExtras.getInt(Intent.EXTRA_REPLACING));
+ assertThat(capturedExtras.getInt(Intent.EXTRA_REMOVED_FOR_ALL_USERS))
+ .isEqualTo(expectedExtras.getInt(Intent.EXTRA_REMOVED_FOR_ALL_USERS));
+
+ verify(spyPackageMonitor, times(1))
+ .onPackageDisappeared(eq(FAKE_PACKAGE_NAME), eq(PackageMonitor.PACKAGE_UPDATING));
+ verify(spyPackageMonitor, times(1)).onFinishPackageChanges();
+ }
+
+ @Test
public void testPackageMonitorDoHandlePackageEventPackageRemovedNotReplacing()
throws Exception {
PackageMonitor spyPackageMonitor = spy(new TestPackageMonitor());
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index 87be13ab4a93..dc2b0561957d 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -2653,6 +2653,12 @@
"group": "WM_DEBUG_WINDOW_TRANSITIONS",
"at": "com\/android\/server\/wm\/TransitionController.java"
},
+ "261227010": {
+ "message": "Content Recording: Unable to tell log windowing mode change: %s",
+ "level": "ERROR",
+ "group": "WM_DEBUG_CONTENT_RECORDING",
+ "at": "com\/android\/server\/wm\/ContentRecorder.java"
+ },
"269576220": {
"message": "Resuming rotation after drag",
"level": "DEBUG",
diff --git a/graphics/java/android/graphics/text/LineBreakConfig.java b/graphics/java/android/graphics/text/LineBreakConfig.java
index 621958562b94..c5e451a5ec3a 100644
--- a/graphics/java/android/graphics/text/LineBreakConfig.java
+++ b/graphics/java/android/graphics/text/LineBreakConfig.java
@@ -28,6 +28,8 @@ import android.compat.annotation.ChangeId;
import android.compat.annotation.EnabledSince;
import android.os.Build;
import android.os.LocaleList;
+import android.os.Parcel;
+import android.os.Parcelable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -40,7 +42,7 @@ import java.util.Objects;
* <a href="https://www.w3.org/TR/css-text-3/#line-break-property" class="external">
* line-break property</a> for more information.
*/
-public final class LineBreakConfig {
+public final class LineBreakConfig implements Parcelable {
/**
* A feature ID for automatic line break word style.
@@ -161,12 +163,12 @@ public final class LineBreakConfig {
*
* This is useful when you want to preserve some words in the same line by using
* {@link android.text.style.LineBreakConfigSpan} or
- * {@link android.text.style.LineBreakConfigSpan.NoBreakSpan} as a shorthand.
+ * {@link android.text.style.LineBreakConfigSpan#createNoBreakSpan()} as a shorthand.
* Note that even if this style is specified, the grapheme based line break is still performed
* for preventing clipping text.
*
* @see android.text.style.LineBreakConfigSpan
- * @see android.text.style.LineBreakConfigSpan.NoBreakSpan
+ * @see android.text.style.LineBreakConfigSpan#createNoBreakSpan()
*/
@FlaggedApi(FLAG_NO_BREAK_NO_HYPHENATION_SPAN)
public static final int LINE_BREAK_STYLE_NO_BREAK = 4;
@@ -457,8 +459,9 @@ public final class LineBreakConfig {
*
* <p>Use {@link LineBreakConfig.Builder} to create the
* {@code LineBreakConfig} instance.
+ * @hide
*/
- private LineBreakConfig(@LineBreakStyle int lineBreakStyle,
+ public LineBreakConfig(@LineBreakStyle int lineBreakStyle,
@LineBreakWordStyle int lineBreakWordStyle,
@Hyphenation int hyphenation) {
mLineBreakStyle = lineBreakStyle;
@@ -606,4 +609,35 @@ public final class LineBreakConfig {
+ ", mHyphenation= " + mHyphenation
+ '}';
}
+
+ @FlaggedApi(FLAG_NO_BREAK_NO_HYPHENATION_SPAN)
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @FlaggedApi(FLAG_NO_BREAK_NO_HYPHENATION_SPAN)
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeInt(mLineBreakStyle);
+ dest.writeInt(mLineBreakWordStyle);
+ dest.writeInt(mHyphenation);
+ }
+
+ @FlaggedApi(FLAG_NO_BREAK_NO_HYPHENATION_SPAN)
+ public static final @NonNull Creator<LineBreakConfig> CREATOR = new Creator<>() {
+
+ @Override
+ public LineBreakConfig createFromParcel(Parcel source) {
+ final int lineBreakStyle = source.readInt();
+ final int lineBreakWordStyle = source.readInt();
+ final int hyphenation = source.readInt();
+ return new LineBreakConfig(lineBreakStyle, lineBreakWordStyle, hyphenation);
+ }
+
+ @Override
+ public LineBreakConfig[] newArray(int size) {
+ return new LineBreakConfig[size];
+ }
+ };
}
diff --git a/libs/WindowManager/Shell/res/layout/bubble_manage_menu.xml b/libs/WindowManager/Shell/res/layout/bubble_manage_menu.xml
index 10c9562cf651..d8ae9c8c64a6 100644
--- a/libs/WindowManager/Shell/res/layout/bubble_manage_menu.xml
+++ b/libs/WindowManager/Shell/res/layout/bubble_manage_menu.xml
@@ -26,7 +26,8 @@
android:id="@+id/bubble_manage_menu_dismiss_container"
android:background="@drawable/bubble_manage_menu_row"
android:layout_width="match_parent"
- android:layout_height="@dimen/bubble_menu_item_height"
+ android:layout_height="wrap_content"
+ android:minHeight="@dimen/bubble_menu_item_height"
android:gravity="center_vertical"
android:paddingStart="@dimen/bubble_menu_padding"
android:paddingEnd="@dimen/bubble_menu_padding"
@@ -52,7 +53,8 @@
android:id="@+id/bubble_manage_menu_dont_bubble_container"
android:background="@drawable/bubble_manage_menu_row"
android:layout_width="match_parent"
- android:layout_height="@dimen/bubble_menu_item_height"
+ android:layout_height="wrap_content"
+ android:minHeight="@dimen/bubble_menu_item_height"
android:gravity="center_vertical"
android:paddingStart="@dimen/bubble_menu_padding"
android:paddingEnd="@dimen/bubble_menu_padding"
@@ -78,7 +80,8 @@
android:id="@+id/bubble_manage_menu_settings_container"
android:background="@drawable/bubble_manage_menu_row"
android:layout_width="match_parent"
- android:layout_height="@dimen/bubble_menu_item_height"
+ android:layout_height="wrap_content"
+ android:minHeight="@dimen/bubble_menu_item_height"
android:gravity="center_vertical"
android:paddingStart="@dimen/bubble_menu_padding"
android:paddingEnd="@dimen/bubble_menu_padding"
diff --git a/libs/WindowManager/Shell/tests/flicker/Android.bp b/libs/WindowManager/Shell/tests/flicker/Android.bp
index bd2eb5b4a8ae..366f7b1e678f 100644
--- a/libs/WindowManager/Shell/tests/flicker/Android.bp
+++ b/libs/WindowManager/Shell/tests/flicker/Android.bp
@@ -28,93 +28,6 @@ filegroup {
srcs: ["src/com/android/wm/shell/flicker/utils/*.kt"],
}
-filegroup {
- name: "WMShellFlickerTestsBase-src",
- srcs: ["src/com/android/wm/shell/flicker/*.kt"],
-}
-
-filegroup {
- name: "WMShellFlickerTestsBubbles-src",
- srcs: ["src/com/android/wm/shell/flicker/bubble/*.kt"],
-}
-
-filegroup {
- name: "WMShellFlickerTestsPip1-src",
- srcs: [
- "src/com/android/wm/shell/flicker/pip/A*.kt",
- "src/com/android/wm/shell/flicker/pip/B*.kt",
- "src/com/android/wm/shell/flicker/pip/C*.kt",
- "src/com/android/wm/shell/flicker/pip/D*.kt",
- "src/com/android/wm/shell/flicker/pip/S*.kt",
- ],
-}
-
-filegroup {
- name: "WMShellFlickerTestsPip2-src",
- srcs: [
- "src/com/android/wm/shell/flicker/pip/E*.kt",
- ],
-}
-
-filegroup {
- name: "WMShellFlickerTestsPip3-src",
- srcs: ["src/com/android/wm/shell/flicker/pip/*.kt"],
-}
-
-filegroup {
- name: "WMShellFlickerTestsPipCommon-src",
- srcs: ["src/com/android/wm/shell/flicker/pip/common/*.kt"],
-}
-
-filegroup {
- name: "WMShellFlickerTestsPipApps-src",
- srcs: ["src/com/android/wm/shell/flicker/pip/apps/*.kt"],
-}
-
-filegroup {
- name: "WMShellFlickerTestsSplitScreenBase-src",
- srcs: [
- "src/com/android/wm/shell/flicker/splitscreen/benchmark/*.kt",
- ],
-}
-
-filegroup {
- name: "WMShellFlickerTestsSplitScreenGroup1-src",
- srcs: [
- "src/com/android/wm/shell/flicker/splitscreen/A*.kt",
- "src/com/android/wm/shell/flicker/splitscreen/B*.kt",
- "src/com/android/wm/shell/flicker/splitscreen/C*.kt",
- "src/com/android/wm/shell/flicker/splitscreen/D*.kt",
- "src/com/android/wm/shell/flicker/splitscreen/E*.kt",
- ],
-}
-
-filegroup {
- name: "WMShellFlickerTestsSplitScreenGroup2-src",
- srcs: [
- "src/com/android/wm/shell/flicker/splitscreen/*.kt",
- ],
-}
-
-filegroup {
- name: "WMShellFlickerServicePlatinumTests-src",
- srcs: [
- "src/com/android/wm/shell/flicker/service/*/platinum/**/*.kt",
- "src/com/android/wm/shell/flicker/service/*/scenarios/**/*.kt",
- "src/com/android/wm/shell/flicker/service/common/**/*.kt",
- ],
-}
-
-filegroup {
- name: "WMShellFlickerServiceTests-src",
- srcs: [
- "src/com/android/wm/shell/flicker/service/**/*.kt",
- ],
- exclude_srcs: [
- "src/com/android/wm/shell/flicker/service/*/platinum/**/*.kt",
- ],
-}
-
java_library {
name: "wm-shell-flicker-utils",
platform_apis: true,
@@ -138,23 +51,8 @@ java_library {
],
}
-java_library {
- name: "wm-shell-flicker-platinum-tests",
- platform_apis: true,
- optimize: {
- enabled: false,
- },
- srcs: [
- ":WMShellFlickerServicePlatinumTests-src",
- ],
- static_libs: [
- "wm-shell-flicker-utils",
- ],
-}
-
java_defaults {
name: "WMShellFlickerTestsDefaultWithoutTemplate",
- manifest: "manifests/AndroidManifest.xml",
platform_apis: true,
certificate: "platform",
optimize: {
@@ -187,170 +85,8 @@ java_defaults {
test_config_template: "AndroidTestTemplate.xml",
}
-android_test {
- name: "WMShellFlickerTestsOther",
- defaults: ["WMShellFlickerTestsDefault"],
- additional_manifests: ["manifests/AndroidManifestOther.xml"],
- package_name: "com.android.wm.shell.flicker",
- instrumentation_target_package: "com.android.wm.shell.flicker",
- srcs: [
- "src/**/*.java",
- "src/**/*.kt",
- ],
- exclude_srcs: [
- ":WMShellFlickerTestsBubbles-src",
- ":WMShellFlickerTestsPip1-src",
- ":WMShellFlickerTestsPip2-src",
- ":WMShellFlickerTestsPip3-src",
- ":WMShellFlickerTestsPipCommon-src",
- ":WMShellFlickerTestsPipApps-src",
- ":WMShellFlickerTestsSplitScreenGroup1-src",
- ":WMShellFlickerTestsSplitScreenGroup2-src",
- ":WMShellFlickerTestsSplitScreenBase-src",
- ":WMShellFlickerServiceTests-src",
- ":WMShellFlickerServicePlatinumTests-src",
- ],
-}
-
-android_test {
- name: "WMShellFlickerTestsBubbles",
- defaults: ["WMShellFlickerTestsDefault"],
- additional_manifests: ["manifests/AndroidManifestBubbles.xml"],
- package_name: "com.android.wm.shell.flicker.bubbles",
- instrumentation_target_package: "com.android.wm.shell.flicker.bubbles",
- srcs: [
- ":WMShellFlickerTestsBase-src",
- ":WMShellFlickerTestsBubbles-src",
- ],
-}
-
-android_test {
- name: "WMShellFlickerTestsPip1",
- defaults: ["WMShellFlickerTestsDefault"],
- additional_manifests: ["manifests/AndroidManifestPip.xml"],
- package_name: "com.android.wm.shell.flicker.pip",
- instrumentation_target_package: "com.android.wm.shell.flicker.pip",
- srcs: [
- ":WMShellFlickerTestsBase-src",
- ":WMShellFlickerTestsPip1-src",
- ":WMShellFlickerTestsPipCommon-src",
- ],
-}
-
-android_test {
- name: "WMShellFlickerTestsPip2",
- defaults: ["WMShellFlickerTestsDefault"],
- additional_manifests: ["manifests/AndroidManifestPip.xml"],
- package_name: "com.android.wm.shell.flicker.pip",
- instrumentation_target_package: "com.android.wm.shell.flicker.pip",
- srcs: [
- ":WMShellFlickerTestsBase-src",
- ":WMShellFlickerTestsPip2-src",
- ":WMShellFlickerTestsPipCommon-src",
- ],
-}
-
-android_test {
- name: "WMShellFlickerTestsPip3",
- defaults: ["WMShellFlickerTestsDefault"],
- additional_manifests: ["manifests/AndroidManifestPip.xml"],
- package_name: "com.android.wm.shell.flicker.pip",
- instrumentation_target_package: "com.android.wm.shell.flicker.pip",
- srcs: [
- ":WMShellFlickerTestsBase-src",
- ":WMShellFlickerTestsPip3-src",
- ":WMShellFlickerTestsPipCommon-src",
- ],
- exclude_srcs: [
- ":WMShellFlickerTestsPip1-src",
- ":WMShellFlickerTestsPip2-src",
- ],
-}
-
-android_test {
- name: "WMShellFlickerTestsPipApps",
- defaults: ["WMShellFlickerTestsDefault"],
- additional_manifests: ["manifests/AndroidManifestPip.xml"],
- package_name: "com.android.wm.shell.flicker.pip.apps",
- instrumentation_target_package: "com.android.wm.shell.flicker.pip.apps",
- srcs: [
- ":WMShellFlickerTestsBase-src",
- ":WMShellFlickerTestsPipApps-src",
- ":WMShellFlickerTestsPipCommon-src",
- ],
-}
-
-android_test {
- name: "WMShellFlickerTestsPipAppsCSuite",
- defaults: ["WMShellFlickerTestsDefaultWithoutTemplate"],
- additional_manifests: ["manifests/AndroidManifestPip.xml"],
- package_name: "com.android.wm.shell.flicker.pip.apps",
- instrumentation_target_package: "com.android.wm.shell.flicker.pip.apps",
- srcs: [
- ":WMShellFlickerTestsBase-src",
- ":WMShellFlickerTestsPipApps-src",
- ":WMShellFlickerTestsPipCommon-src",
- ],
- test_suites: [
- "device-tests",
- "csuite",
- ],
-}
-
-android_test {
- name: "WMShellFlickerTestsSplitScreenGroup1",
- defaults: ["WMShellFlickerTestsDefault"],
- additional_manifests: ["manifests/AndroidManifestSplitScreen.xml"],
- package_name: "com.android.wm.shell.flicker.splitscreen",
- instrumentation_target_package: "com.android.wm.shell.flicker.splitscreen",
- srcs: [
- ":WMShellFlickerTestsBase-src",
- ":WMShellFlickerTestsSplitScreenBase-src",
- ":WMShellFlickerTestsSplitScreenGroup1-src",
- ],
-}
-
-android_test {
- name: "WMShellFlickerTestsSplitScreenGroup2",
- defaults: ["WMShellFlickerTestsDefault"],
- additional_manifests: ["manifests/AndroidManifestSplitScreen.xml"],
- package_name: "com.android.wm.shell.flicker.splitscreen",
- instrumentation_target_package: "com.android.wm.shell.flicker.splitscreen",
- srcs: [
- ":WMShellFlickerTestsBase-src",
- ":WMShellFlickerTestsSplitScreenBase-src",
- ":WMShellFlickerTestsSplitScreenGroup2-src",
- ],
- exclude_srcs: [
- ":WMShellFlickerTestsSplitScreenGroup1-src",
- ],
-}
-
-android_test {
- name: "WMShellFlickerServiceTests",
- defaults: ["WMShellFlickerTestsDefault"],
- additional_manifests: ["manifests/AndroidManifestService.xml"],
- package_name: "com.android.wm.shell.flicker.service",
- instrumentation_target_package: "com.android.wm.shell.flicker.service",
- srcs: [
- ":WMShellFlickerTestsBase-src",
- ":WMShellFlickerServiceTests-src",
- ],
-}
-
-android_test {
- name: "WMShellFlickerServicePlatinumTests",
+java_library {
+ name: "WMShellFlickerTestsBase",
defaults: ["WMShellFlickerTestsDefault"],
- additional_manifests: ["manifests/AndroidManifestService.xml"],
- package_name: "com.android.wm.shell.flicker.service",
- instrumentation_target_package: "com.android.wm.shell.flicker.service",
- srcs: [
- ":WMShellFlickerTestsBase-src",
- ":WMShellFlickerServicePlatinumTests-src",
- ],
-}
-
-csuite_test {
- name: "csuite-1p3p-pip-flickers",
- test_config_template: "csuiteDefaultTemplate.xml",
+ srcs: ["src/com/android/wm/shell/flicker/*.kt"],
}
diff --git a/libs/WindowManager/Shell/tests/flicker/appcompat/Android.bp b/libs/WindowManager/Shell/tests/flicker/appcompat/Android.bp
new file mode 100644
index 000000000000..bae701f2cbeb
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/appcompat/Android.bp
@@ -0,0 +1,41 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "frameworks_base_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["frameworks_base_license"],
+}
+
+filegroup {
+ name: "WMShellFlickerTestsAppCompat-src",
+ srcs: [
+ "src/**/*.kt",
+ ],
+}
+
+android_test {
+ name: "WMShellFlickerTestsOther",
+ defaults: ["WMShellFlickerTestsDefault"],
+ manifest: "AndroidManifest.xml",
+ package_name: "com.android.wm.shell.flicker",
+ instrumentation_target_package: "com.android.wm.shell.flicker",
+ srcs: [":WMShellFlickerTestsAppCompat-src"],
+ static_libs: ["WMShellFlickerTestsBase"],
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/manifests/AndroidManifest.xml b/libs/WindowManager/Shell/tests/flicker/appcompat/AndroidManifest.xml
index ae130b8f6f7d..2af1e74fb3d5 100644
--- a/libs/WindowManager/Shell/tests/flicker/manifests/AndroidManifest.xml
+++ b/libs/WindowManager/Shell/tests/flicker/appcompat/AndroidManifest.xml
@@ -1,18 +1,18 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2020 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
+<!--
+ ~ Copyright (C) 2023 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
@@ -69,4 +69,9 @@
android:authorities="${applicationId}.androidx-startup"
tools:node="remove" />
</application>
+
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="com.android.wm.shell.flicker"
+ android:label="WindowManager Flicker Tests">
+ </instrumentation>
</manifest>
diff --git a/libs/WindowManager/Shell/tests/flicker/appcompat/AndroidTestTemplate.xml b/libs/WindowManager/Shell/tests/flicker/appcompat/AndroidTestTemplate.xml
new file mode 100644
index 000000000000..1df11369a049
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/appcompat/AndroidTestTemplate.xml
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2023 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<configuration description="Runs WindowManager Shell Flicker Tests {MODULE}">
+ <option name="test-tag" value="FlickerTests"/>
+ <!-- Needed for storing the perfetto trace files in the sdcard/test_results-->
+ <option name="isolated-storage" value="false"/>
+
+ <target_preparer class="com.android.tradefed.targetprep.DeviceSetup">
+ <!-- keeps the screen on during tests -->
+ <option name="screen-always-on" value="on"/>
+ <!-- prevents the phone from restarting -->
+ <option name="force-skip-system-props" value="true"/>
+ <!-- set WM tracing verbose level to all -->
+ <option name="run-command" value="cmd window tracing level all"/>
+ <!-- set WM tracing to frame (avoid incomplete states) -->
+ <option name="run-command" value="cmd window tracing frame"/>
+ <!-- disable betterbug as it's log collection dialogues cause flakes in e2e tests -->
+ <option name="run-command" value="pm disable com.google.android.internal.betterbug"/>
+ <!-- ensure lock screen mode is swipe -->
+ <option name="run-command" value="locksettings set-disabled false"/>
+ <!-- restart launcher to activate TAPL -->
+ <option name="run-command"
+ value="setprop ro.test_harness 1 ; am force-stop com.google.android.apps.nexuslauncher"/>
+ <!-- Increase trace size: 20mb for WM and 80mb for SF -->
+ <option name="run-command" value="cmd window tracing size 20480"/>
+ <option name="run-command" value="su root service call SurfaceFlinger 1029 i32 81920"/>
+ </target_preparer>
+ <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+ <option name="test-user-token" value="%TEST_USER%"/>
+ <option name="run-command" value="rm -rf /data/user/%TEST_USER%/files/*"/>
+ <option name="run-command" value="settings put secure show_ime_with_hard_keyboard 1"/>
+ <option name="run-command" value="settings put system show_touches 1"/>
+ <option name="run-command" value="settings put system pointer_location 1"/>
+ <option name="teardown-command"
+ value="settings delete secure show_ime_with_hard_keyboard"/>
+ <option name="teardown-command" value="settings delete system show_touches"/>
+ <option name="teardown-command" value="settings delete system pointer_location"/>
+ <option name="teardown-command"
+ value="cmd overlay enable com.android.internal.systemui.navbar.gestural"/>
+ </target_preparer>
+ <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+ <option name="cleanup-apks" value="true"/>
+ <option name="test-file-name" value="{MODULE}.apk"/>
+ <option name="test-file-name" value="FlickerTestApp.apk"/>
+ </target_preparer>
+ <!-- Enable mocking GPS location by the test app -->
+ <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+ <option name="run-command"
+ value="appops set com.android.wm.shell.flicker.pip.apps android:mock_location allow"/>
+ <option name="teardown-command"
+ value="appops set com.android.wm.shell.flicker.pip.apps android:mock_location deny"/>
+ </target_preparer>
+
+ <!-- Needed for pushing the trace config file -->
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="push-file"
+ key="trace_config.textproto"
+ value="/data/misc/perfetto-traces/trace_config.textproto"
+ />
+ <!--Install the content provider automatically when we push some file in sdcard folder.-->
+ <!--Needed to avoid the installation during the test suite.-->
+ <option name="push-file" key="trace_config.textproto" value="/sdcard/sample.textproto"/>
+ </target_preparer>
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest">
+ <option name="package" value="{PACKAGE}"/>
+ <option name="shell-timeout" value="6600s"/>
+ <option name="test-timeout" value="6000s"/>
+ <option name="hidden-api-checks" value="false"/>
+ <option name="device-listeners" value="android.device.collectors.PerfettoListener"/>
+ <!-- PerfettoListener related arguments -->
+ <option name="instrumentation-arg" key="perfetto_config_text_proto" value="true"/>
+ <option name="instrumentation-arg"
+ key="perfetto_config_file"
+ value="trace_config.textproto"
+ />
+ <option name="instrumentation-arg" key="per_run" value="true"/>
+ </test>
+ <!-- Needed for pulling the collected trace config on to the host -->
+ <metrics_collector class="com.android.tradefed.device.metric.FilePullerLogCollector">
+ <option name="pull-pattern-keys" value="perfetto_file_path"/>
+ <option name="directory-keys"
+ value="/data/user/0/com.android.wm.shell.flicker/files"/>
+ <option name="directory-keys"
+ value="/data/user/0/com.android.wm.shell.flicker.bubbles/files"/>
+ <option name="directory-keys"
+ value="/data/user/0/com.android.wm.shell.flicker.pip/files"/>
+ <option name="directory-keys"
+ value="/data/user/0/com.android.wm.shell.flicker.splitscreen/files"/>
+ <option name="directory-keys"
+ value="/data/user/0/com.android.wm.shell.flicker.service/files"/>
+ <option name="collect-on-run-ended-only" value="true"/>
+ <option name="clean-up" value="true"/>
+ </metrics_collector>
+</configuration>
diff --git a/libs/WindowManager/Shell/tests/flicker/res/xml/network_security_config.xml b/libs/WindowManager/Shell/tests/flicker/appcompat/res/xml/network_security_config.xml
index 4bd9ca049f55..4bd9ca049f55 100644
--- a/libs/WindowManager/Shell/tests/flicker/res/xml/network_security_config.xml
+++ b/libs/WindowManager/Shell/tests/flicker/appcompat/res/xml/network_security_config.xml
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/BaseAppCompat.kt b/libs/WindowManager/Shell/tests/flicker/appcompat/src/com/android/wm/shell/flicker/appcompat/BaseAppCompat.kt
index adf92d8854ff..adf92d8854ff 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/BaseAppCompat.kt
+++ b/libs/WindowManager/Shell/tests/flicker/appcompat/src/com/android/wm/shell/flicker/appcompat/BaseAppCompat.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/LetterboxRule.kt b/libs/WindowManager/Shell/tests/flicker/appcompat/src/com/android/wm/shell/flicker/appcompat/LetterboxRule.kt
index 744e8c2eb06f..744e8c2eb06f 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/LetterboxRule.kt
+++ b/libs/WindowManager/Shell/tests/flicker/appcompat/src/com/android/wm/shell/flicker/appcompat/LetterboxRule.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/OpenAppInSizeCompatModeTest.kt b/libs/WindowManager/Shell/tests/flicker/appcompat/src/com/android/wm/shell/flicker/appcompat/OpenAppInSizeCompatModeTest.kt
index 1e5e42fb077e..1e5e42fb077e 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/OpenAppInSizeCompatModeTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/appcompat/src/com/android/wm/shell/flicker/appcompat/OpenAppInSizeCompatModeTest.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/OpenTransparentActivityTest.kt b/libs/WindowManager/Shell/tests/flicker/appcompat/src/com/android/wm/shell/flicker/appcompat/OpenTransparentActivityTest.kt
index 2fa1ec386781..2fa1ec386781 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/OpenTransparentActivityTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/appcompat/src/com/android/wm/shell/flicker/appcompat/OpenTransparentActivityTest.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/QuickSwitchLauncherToLetterboxAppTest.kt b/libs/WindowManager/Shell/tests/flicker/appcompat/src/com/android/wm/shell/flicker/appcompat/QuickSwitchLauncherToLetterboxAppTest.kt
index b74aa1d7bf73..b74aa1d7bf73 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/QuickSwitchLauncherToLetterboxAppTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/appcompat/src/com/android/wm/shell/flicker/appcompat/QuickSwitchLauncherToLetterboxAppTest.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/RepositionFixedPortraitAppTest.kt b/libs/WindowManager/Shell/tests/flicker/appcompat/src/com/android/wm/shell/flicker/appcompat/RepositionFixedPortraitAppTest.kt
index 68fa8d2fc2e8..68fa8d2fc2e8 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/RepositionFixedPortraitAppTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/appcompat/src/com/android/wm/shell/flicker/appcompat/RepositionFixedPortraitAppTest.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/RestartAppInSizeCompatModeTest.kt b/libs/WindowManager/Shell/tests/flicker/appcompat/src/com/android/wm/shell/flicker/appcompat/RestartAppInSizeCompatModeTest.kt
index fcb6931af9a2..fcb6931af9a2 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/RestartAppInSizeCompatModeTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/appcompat/src/com/android/wm/shell/flicker/appcompat/RestartAppInSizeCompatModeTest.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/RotateImmersiveAppInFullscreenTest.kt b/libs/WindowManager/Shell/tests/flicker/appcompat/src/com/android/wm/shell/flicker/appcompat/RotateImmersiveAppInFullscreenTest.kt
index ba2b3e7e2781..446aad8a8936 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/RotateImmersiveAppInFullscreenTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/appcompat/src/com/android/wm/shell/flicker/appcompat/RotateImmersiveAppInFullscreenTest.kt
@@ -17,11 +17,11 @@
package com.android.wm.shell.flicker.appcompat
import android.os.Build
-import android.tools.common.datatypes.Rect
import android.platform.test.annotations.Postsubmit
import android.system.helpers.CommandsHelper
import android.tools.common.NavBar
import android.tools.common.Rotation
+import android.tools.common.datatypes.Rect
import android.tools.common.flicker.assertions.FlickerTest
import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
@@ -65,10 +65,12 @@ import org.junit.runners.Parameterized
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
class RotateImmersiveAppInFullscreenTest(flicker: LegacyFlickerTest) : BaseAppCompat(flicker) {
- private val immersiveApp = LetterboxAppHelper(instrumentation,
+ private val immersiveApp =
+ LetterboxAppHelper(
+ instrumentation,
launcherName = ActivityOptions.PortraitImmersiveActivity.LABEL,
- component =
- ActivityOptions.PortraitImmersiveActivity.COMPONENT.toFlickerComponent())
+ component = ActivityOptions.PortraitImmersiveActivity.COMPONENT.toFlickerComponent()
+ )
private val cmdHelper: CommandsHelper = CommandsHelper.getInstance(instrumentation)
private val execAdb: (String) -> String = { cmd -> cmdHelper.executeShellCommand(cmd) }
@@ -84,8 +86,8 @@ class RotateImmersiveAppInFullscreenTest(flicker: LegacyFlickerTest) : BaseAppCo
setStartRotation()
immersiveApp.launchViaIntent(wmHelper)
startDisplayBounds =
- wmHelper.currentState.layerState.physicalDisplayBounds
- ?: error("Display not found")
+ wmHelper.currentState.layerState.physicalDisplayBounds
+ ?: error("Display not found")
}
transitions {
if (isCuttlefishDevice) {
@@ -96,12 +98,10 @@ class RotateImmersiveAppInFullscreenTest(flicker: LegacyFlickerTest) : BaseAppCo
val rotationButtonSelector = By.res(LAUNCHER_PACKAGE, "rotate_suggestion")
uiDevice.wait(Until.hasObject(rotationButtonSelector), FIND_TIMEOUT)
uiDevice.findObject(rotationButtonSelector)
- ?: error("rotation button not found")
+ ?: error("rotation button not found")
}
}
- teardown {
- immersiveApp.exit(wmHelper)
- }
+ teardown { immersiveApp.exit(wmHelper) }
}
@Before
@@ -112,48 +112,40 @@ class RotateImmersiveAppInFullscreenTest(flicker: LegacyFlickerTest) : BaseAppCo
/** {@inheritDoc} */
@Test
@Ignore("Not applicable to this CUJ. App is in immersive mode.")
- override fun taskBarLayerIsVisibleAtStartAndEnd() {
- }
+ override fun taskBarLayerIsVisibleAtStartAndEnd() {}
/** {@inheritDoc} */
@Test
@Ignore("Not applicable to this CUJ. App is in immersive mode.")
- override fun navBarLayerIsVisibleAtStartAndEnd() {
- }
+ override fun navBarLayerIsVisibleAtStartAndEnd() {}
/** {@inheritDoc} */
@Test
@Ignore("Not applicable to this CUJ. App is in immersive mode.")
- override fun statusBarLayerIsVisibleAtStartAndEnd() {
- }
+ override fun statusBarLayerIsVisibleAtStartAndEnd() {}
/** {@inheritDoc} */
@Test
@Ignore("Not applicable to this CUJ. App is in immersive mode.")
- override fun taskBarWindowIsAlwaysVisible() {
- }
+ override fun taskBarWindowIsAlwaysVisible() {}
/** {@inheritDoc} */
@Test
@Ignore("Not applicable to this CUJ. App is in immersive mode.")
- override fun navBarWindowIsAlwaysVisible() {
- }
+ override fun navBarWindowIsAlwaysVisible() {}
/** {@inheritDoc} */
@Test
@Ignore("Not applicable to this CUJ. App is in immersive mode.")
- override fun statusBarWindowIsAlwaysVisible() {
- }
+ override fun statusBarWindowIsAlwaysVisible() {}
@Test
@Ignore("Not applicable to this CUJ. App is in immersive mode.")
- override fun statusBarLayerPositionAtStartAndEnd() {
- }
+ override fun statusBarLayerPositionAtStartAndEnd() {}
@Test
@Ignore("Not applicable to this CUJ. App is in immersive mode.")
- override fun visibleWindowsShownMoreThanOneConsecutiveEntry() {
- }
+ override fun visibleWindowsShownMoreThanOneConsecutiveEntry() {}
/** Test that app is fullscreen by checking status bar and task bar visibility. */
@Postsubmit
@@ -161,8 +153,9 @@ class RotateImmersiveAppInFullscreenTest(flicker: LegacyFlickerTest) : BaseAppCo
fun appWindowFullScreen() {
flicker.assertWmEnd {
this.isAppWindowInvisible(ComponentNameMatcher.STATUS_BAR)
- .isAppWindowInvisible(ComponentNameMatcher.TASK_BAR)
- .visibleRegion(immersiveApp).coversExactly(startDisplayBounds)
+ .isAppWindowInvisible(ComponentNameMatcher.TASK_BAR)
+ .visibleRegion(immersiveApp)
+ .coversExactly(startDisplayBounds)
}
}
@@ -170,9 +163,7 @@ class RotateImmersiveAppInFullscreenTest(flicker: LegacyFlickerTest) : BaseAppCo
@Postsubmit
@Test
fun appInOriginalRotation() {
- flicker.assertWmEnd {
- this.hasRotation(Rotation.ROTATION_90)
- }
+ flicker.assertWmEnd { this.hasRotation(Rotation.ROTATION_90) }
}
companion object {
@@ -189,10 +180,10 @@ class RotateImmersiveAppInFullscreenTest(flicker: LegacyFlickerTest) : BaseAppCo
@JvmStatic
fun getParams(): Collection<FlickerTest> {
return LegacyFlickerTestFactory.nonRotationTests(
- supportedRotations = listOf(Rotation.ROTATION_90),
- // TODO(b/292403378): 3 button mode not added as rotation button is hidden in taskbar
- supportedNavigationModes = listOf(NavBar.MODE_GESTURAL)
-
+ supportedRotations = listOf(Rotation.ROTATION_90),
+ // TODO(b/292403378): 3 button mode not added as rotation button is hidden in
+ // taskbar
+ supportedNavigationModes = listOf(NavBar.MODE_GESTURAL)
)
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/TransparentBaseAppCompat.kt b/libs/WindowManager/Shell/tests/flicker/appcompat/src/com/android/wm/shell/flicker/appcompat/TransparentBaseAppCompat.kt
index 9792c859cced..9792c859cced 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/TransparentBaseAppCompat.kt
+++ b/libs/WindowManager/Shell/tests/flicker/appcompat/src/com/android/wm/shell/flicker/appcompat/TransparentBaseAppCompat.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/appcompat/trace_config/trace_config.textproto b/libs/WindowManager/Shell/tests/flicker/appcompat/trace_config/trace_config.textproto
new file mode 100644
index 000000000000..406ada97a07d
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/appcompat/trace_config/trace_config.textproto
@@ -0,0 +1,75 @@
+# Copyright (C) 2023 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# proto-message: TraceConfig
+
+# Enable periodic flushing of the trace buffer into the output file.
+write_into_file: true
+
+# Writes the userspace buffer into the file every 1s.
+file_write_period_ms: 2500
+
+# See b/126487238 - we need to guarantee ordering of events.
+flush_period_ms: 30000
+
+# The trace buffers needs to be big enough to hold |file_write_period_ms| of
+# trace data. The trace buffer sizing depends on the number of trace categories
+# enabled and the device activity.
+
+# RSS events
+buffers: {
+ size_kb: 63488
+ fill_policy: RING_BUFFER
+}
+
+data_sources {
+ config {
+ name: "linux.process_stats"
+ target_buffer: 0
+ # polled per-process memory counters and process/thread names.
+ # If you don't want the polled counters, remove the "process_stats_config"
+ # section, but keep the data source itself as it still provides on-demand
+ # thread/process naming for ftrace data below.
+ process_stats_config {
+ scan_all_processes_on_start: true
+ }
+ }
+}
+
+data_sources: {
+ config {
+ name: "linux.ftrace"
+ ftrace_config {
+ ftrace_events: "ftrace/print"
+ ftrace_events: "task/task_newtask"
+ ftrace_events: "task/task_rename"
+ atrace_categories: "ss"
+ atrace_categories: "wm"
+ atrace_categories: "am"
+ atrace_categories: "aidl"
+ atrace_categories: "input"
+ atrace_categories: "binder_driver"
+ atrace_categories: "sched_process_exit"
+ atrace_apps: "com.android.server.wm.flicker.testapp"
+ atrace_apps: "com.android.systemui"
+ atrace_apps: "com.android.wm.shell.flicker"
+ atrace_apps: "com.android.wm.shell.flicker.other"
+ atrace_apps: "com.android.wm.shell.flicker.bubbles"
+ atrace_apps: "com.android.wm.shell.flicker.pip"
+ atrace_apps: "com.android.wm.shell.flicker.splitscreen"
+ atrace_apps: "com.google.android.apps.nexuslauncher"
+ }
+ }
+}
+
diff --git a/libs/WindowManager/Shell/tests/flicker/bubble/Android.bp b/libs/WindowManager/Shell/tests/flicker/bubble/Android.bp
new file mode 100644
index 000000000000..c4e9a8479563
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/bubble/Android.bp
@@ -0,0 +1,34 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "frameworks_base_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["frameworks_base_license"],
+}
+
+android_test {
+ name: "WMShellFlickerTestsBubbles",
+ defaults: ["WMShellFlickerTestsDefault"],
+ manifest: "AndroidManifest.xml",
+ package_name: "com.android.wm.shell.flicker.bubbles",
+ instrumentation_target_package: "com.android.wm.shell.flicker.bubbles",
+ srcs: ["src/**/*.kt"],
+ static_libs: ["WMShellFlickerTestsBase"],
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/bubble/AndroidManifest.xml b/libs/WindowManager/Shell/tests/flicker/bubble/AndroidManifest.xml
new file mode 100644
index 000000000000..e6e6f1b21bc3
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/bubble/AndroidManifest.xml
@@ -0,0 +1,77 @@
+<!--
+ ~ Copyright (C) 2023 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ package="com.android.wm.shell.flicker.bubble">
+
+ <uses-sdk android:minSdkVersion="29" android:targetSdkVersion="29"/>
+ <!-- Read and write traces from external storage -->
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+ <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+ <!-- Allow the test to write directly to /sdcard/ -->
+ <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
+ <!-- Write secure settings -->
+ <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
+ <!-- Capture screen contents -->
+ <uses-permission android:name="android.permission.ACCESS_SURFACE_FLINGER" />
+ <!-- Enable / Disable tracing !-->
+ <uses-permission android:name="android.permission.DUMP" />
+ <!-- Run layers trace -->
+ <uses-permission android:name="android.permission.HARDWARE_TEST"/>
+ <!-- Capture screen recording -->
+ <uses-permission android:name="android.permission.CAPTURE_VIDEO_OUTPUT"/>
+ <!-- Workaround grant runtime permission exception from b/152733071 -->
+ <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"/>
+ <uses-permission android:name="android.permission.READ_LOGS"/>
+ <!-- Force-stop test apps -->
+ <uses-permission android:name="android.permission.FORCE_STOP_PACKAGES"/>
+ <!-- Control test app's media session -->
+ <uses-permission android:name="android.permission.MEDIA_CONTENT_CONTROL"/>
+ <!-- ATM.removeRootTasksWithActivityTypes() -->
+ <uses-permission android:name="android.permission.MANAGE_ACTIVITY_TASKS" />
+ <!-- Enable bubble notification-->
+ <uses-permission android:name="android.permission.STATUS_BAR_SERVICE" />
+ <!-- Allow the test to connect to perfetto trace processor -->
+ <uses-permission android:name="android.permission.INTERNET"/>
+
+ <!-- Allow the test to write directly to /sdcard/ and connect to trace processor -->
+ <application android:requestLegacyExternalStorage="true"
+ android:networkSecurityConfig="@xml/network_security_config"
+ android:largeHeap="true">
+ <uses-library android:name="android.test.runner"/>
+
+ <service android:name=".NotificationListener"
+ android:exported="true"
+ android:label="WMShellTestsNotificationListenerService"
+ android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
+ <intent-filter>
+ <action android:name="android.service.notification.NotificationListenerService" />
+ </intent-filter>
+ </service>
+
+ <!-- (b/197936012) Remove startup provider due to test timeout issue -->
+ <provider
+ android:name="androidx.startup.InitializationProvider"
+ android:authorities="${applicationId}.androidx-startup"
+ tools:node="remove" />
+ </application>
+
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="com.android.wm.shell.flicker.bubble"
+ android:label="WindowManager Flicker Tests">
+ </instrumentation>
+</manifest>
diff --git a/libs/WindowManager/Shell/tests/flicker/bubble/AndroidTestTemplate.xml b/libs/WindowManager/Shell/tests/flicker/bubble/AndroidTestTemplate.xml
new file mode 100644
index 000000000000..1df11369a049
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/bubble/AndroidTestTemplate.xml
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2023 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<configuration description="Runs WindowManager Shell Flicker Tests {MODULE}">
+ <option name="test-tag" value="FlickerTests"/>
+ <!-- Needed for storing the perfetto trace files in the sdcard/test_results-->
+ <option name="isolated-storage" value="false"/>
+
+ <target_preparer class="com.android.tradefed.targetprep.DeviceSetup">
+ <!-- keeps the screen on during tests -->
+ <option name="screen-always-on" value="on"/>
+ <!-- prevents the phone from restarting -->
+ <option name="force-skip-system-props" value="true"/>
+ <!-- set WM tracing verbose level to all -->
+ <option name="run-command" value="cmd window tracing level all"/>
+ <!-- set WM tracing to frame (avoid incomplete states) -->
+ <option name="run-command" value="cmd window tracing frame"/>
+ <!-- disable betterbug as it's log collection dialogues cause flakes in e2e tests -->
+ <option name="run-command" value="pm disable com.google.android.internal.betterbug"/>
+ <!-- ensure lock screen mode is swipe -->
+ <option name="run-command" value="locksettings set-disabled false"/>
+ <!-- restart launcher to activate TAPL -->
+ <option name="run-command"
+ value="setprop ro.test_harness 1 ; am force-stop com.google.android.apps.nexuslauncher"/>
+ <!-- Increase trace size: 20mb for WM and 80mb for SF -->
+ <option name="run-command" value="cmd window tracing size 20480"/>
+ <option name="run-command" value="su root service call SurfaceFlinger 1029 i32 81920"/>
+ </target_preparer>
+ <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+ <option name="test-user-token" value="%TEST_USER%"/>
+ <option name="run-command" value="rm -rf /data/user/%TEST_USER%/files/*"/>
+ <option name="run-command" value="settings put secure show_ime_with_hard_keyboard 1"/>
+ <option name="run-command" value="settings put system show_touches 1"/>
+ <option name="run-command" value="settings put system pointer_location 1"/>
+ <option name="teardown-command"
+ value="settings delete secure show_ime_with_hard_keyboard"/>
+ <option name="teardown-command" value="settings delete system show_touches"/>
+ <option name="teardown-command" value="settings delete system pointer_location"/>
+ <option name="teardown-command"
+ value="cmd overlay enable com.android.internal.systemui.navbar.gestural"/>
+ </target_preparer>
+ <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+ <option name="cleanup-apks" value="true"/>
+ <option name="test-file-name" value="{MODULE}.apk"/>
+ <option name="test-file-name" value="FlickerTestApp.apk"/>
+ </target_preparer>
+ <!-- Enable mocking GPS location by the test app -->
+ <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+ <option name="run-command"
+ value="appops set com.android.wm.shell.flicker.pip.apps android:mock_location allow"/>
+ <option name="teardown-command"
+ value="appops set com.android.wm.shell.flicker.pip.apps android:mock_location deny"/>
+ </target_preparer>
+
+ <!-- Needed for pushing the trace config file -->
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="push-file"
+ key="trace_config.textproto"
+ value="/data/misc/perfetto-traces/trace_config.textproto"
+ />
+ <!--Install the content provider automatically when we push some file in sdcard folder.-->
+ <!--Needed to avoid the installation during the test suite.-->
+ <option name="push-file" key="trace_config.textproto" value="/sdcard/sample.textproto"/>
+ </target_preparer>
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest">
+ <option name="package" value="{PACKAGE}"/>
+ <option name="shell-timeout" value="6600s"/>
+ <option name="test-timeout" value="6000s"/>
+ <option name="hidden-api-checks" value="false"/>
+ <option name="device-listeners" value="android.device.collectors.PerfettoListener"/>
+ <!-- PerfettoListener related arguments -->
+ <option name="instrumentation-arg" key="perfetto_config_text_proto" value="true"/>
+ <option name="instrumentation-arg"
+ key="perfetto_config_file"
+ value="trace_config.textproto"
+ />
+ <option name="instrumentation-arg" key="per_run" value="true"/>
+ </test>
+ <!-- Needed for pulling the collected trace config on to the host -->
+ <metrics_collector class="com.android.tradefed.device.metric.FilePullerLogCollector">
+ <option name="pull-pattern-keys" value="perfetto_file_path"/>
+ <option name="directory-keys"
+ value="/data/user/0/com.android.wm.shell.flicker/files"/>
+ <option name="directory-keys"
+ value="/data/user/0/com.android.wm.shell.flicker.bubbles/files"/>
+ <option name="directory-keys"
+ value="/data/user/0/com.android.wm.shell.flicker.pip/files"/>
+ <option name="directory-keys"
+ value="/data/user/0/com.android.wm.shell.flicker.splitscreen/files"/>
+ <option name="directory-keys"
+ value="/data/user/0/com.android.wm.shell.flicker.service/files"/>
+ <option name="collect-on-run-ended-only" value="true"/>
+ <option name="clean-up" value="true"/>
+ </metrics_collector>
+</configuration>
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/OWNERS b/libs/WindowManager/Shell/tests/flicker/bubble/OWNERS
index 566acc87e42d..566acc87e42d 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/OWNERS
+++ b/libs/WindowManager/Shell/tests/flicker/bubble/OWNERS
diff --git a/libs/WindowManager/Shell/tests/flicker/manifests/AndroidManifestOther.xml b/libs/WindowManager/Shell/tests/flicker/bubble/res/xml/network_security_config.xml
index cf642f63a41d..4bd9ca049f55 100644
--- a/libs/WindowManager/Shell/tests/flicker/manifests/AndroidManifestOther.xml
+++ b/libs/WindowManager/Shell/tests/flicker/bubble/res/xml/network_security_config.xml
@@ -1,3 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2023 The Android Open Source Project
~
@@ -14,11 +15,8 @@
~ limitations under the License.
-->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.wm.shell.flicker">
-
- <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
- android:targetPackage="com.android.wm.shell.flicker"
- android:label="WindowManager Flicker Tests">
- </instrumentation>
-</manifest>
+<network-security-config>
+ <domain-config cleartextTrafficPermitted="true">
+ <domain includeSubdomains="true">localhost</domain>
+ </domain-config>
+</network-security-config>
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/BaseBubbleScreen.kt b/libs/WindowManager/Shell/tests/flicker/bubble/src/com/android/wm/shell/flicker/bubble/BaseBubbleScreen.kt
index bc095bbacc5a..0c36e29a8315 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/BaseBubbleScreen.kt
+++ b/libs/WindowManager/Shell/tests/flicker/bubble/src/com/android/wm/shell/flicker/bubble/BaseBubbleScreen.kt
@@ -58,8 +58,9 @@ abstract class BaseBubbleScreen(flicker: LegacyFlickerTest) : BaseTest(flicker)
return {
setup {
MultiWindowUtils.executeShellCommand(
- instrumentation,
- "settings put secure force_hide_bubbles_user_education 1")
+ instrumentation,
+ "settings put secure force_hide_bubbles_user_education 1"
+ )
notifyManager.setBubblesAllowed(
testApp.packageName,
uid,
@@ -72,8 +73,9 @@ abstract class BaseBubbleScreen(flicker: LegacyFlickerTest) : BaseTest(flicker)
teardown {
MultiWindowUtils.executeShellCommand(
- instrumentation,
- "settings put secure force_hide_bubbles_user_education 0")
+ instrumentation,
+ "settings put secure force_hide_bubbles_user_education 0"
+ )
notifyManager.setBubblesAllowed(
testApp.packageName,
uid,
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/ChangeActiveActivityFromBubbleTest.kt b/libs/WindowManager/Shell/tests/flicker/bubble/src/com/android/wm/shell/flicker/bubble/ChangeActiveActivityFromBubbleTest.kt
index 55039f59190b..55039f59190b 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/ChangeActiveActivityFromBubbleTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/bubble/src/com/android/wm/shell/flicker/bubble/ChangeActiveActivityFromBubbleTest.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/DragToDismissBubbleScreenTest.kt b/libs/WindowManager/Shell/tests/flicker/bubble/src/com/android/wm/shell/flicker/bubble/DragToDismissBubbleScreenTest.kt
index 9ca7bf113589..9ca7bf113589 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/DragToDismissBubbleScreenTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/bubble/src/com/android/wm/shell/flicker/bubble/DragToDismissBubbleScreenTest.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/OpenActivityFromBubbleOnLocksreenTest.kt b/libs/WindowManager/Shell/tests/flicker/bubble/src/com/android/wm/shell/flicker/bubble/OpenActivityFromBubbleOnLocksreenTest.kt
index b007e6b3535c..b007e6b3535c 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/OpenActivityFromBubbleOnLocksreenTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/bubble/src/com/android/wm/shell/flicker/bubble/OpenActivityFromBubbleOnLocksreenTest.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/OpenActivityFromBubbleTest.kt b/libs/WindowManager/Shell/tests/flicker/bubble/src/com/android/wm/shell/flicker/bubble/OpenActivityFromBubbleTest.kt
index 4959672d865b..4959672d865b 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/OpenActivityFromBubbleTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/bubble/src/com/android/wm/shell/flicker/bubble/OpenActivityFromBubbleTest.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/SendBubbleNotificationTest.kt b/libs/WindowManager/Shell/tests/flicker/bubble/src/com/android/wm/shell/flicker/bubble/SendBubbleNotificationTest.kt
index 0d95574aca06..0d95574aca06 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/SendBubbleNotificationTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/bubble/src/com/android/wm/shell/flicker/bubble/SendBubbleNotificationTest.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/bubble/trace_config/trace_config.textproto b/libs/WindowManager/Shell/tests/flicker/bubble/trace_config/trace_config.textproto
new file mode 100644
index 000000000000..406ada97a07d
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/bubble/trace_config/trace_config.textproto
@@ -0,0 +1,75 @@
+# Copyright (C) 2023 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# proto-message: TraceConfig
+
+# Enable periodic flushing of the trace buffer into the output file.
+write_into_file: true
+
+# Writes the userspace buffer into the file every 1s.
+file_write_period_ms: 2500
+
+# See b/126487238 - we need to guarantee ordering of events.
+flush_period_ms: 30000
+
+# The trace buffers needs to be big enough to hold |file_write_period_ms| of
+# trace data. The trace buffer sizing depends on the number of trace categories
+# enabled and the device activity.
+
+# RSS events
+buffers: {
+ size_kb: 63488
+ fill_policy: RING_BUFFER
+}
+
+data_sources {
+ config {
+ name: "linux.process_stats"
+ target_buffer: 0
+ # polled per-process memory counters and process/thread names.
+ # If you don't want the polled counters, remove the "process_stats_config"
+ # section, but keep the data source itself as it still provides on-demand
+ # thread/process naming for ftrace data below.
+ process_stats_config {
+ scan_all_processes_on_start: true
+ }
+ }
+}
+
+data_sources: {
+ config {
+ name: "linux.ftrace"
+ ftrace_config {
+ ftrace_events: "ftrace/print"
+ ftrace_events: "task/task_newtask"
+ ftrace_events: "task/task_rename"
+ atrace_categories: "ss"
+ atrace_categories: "wm"
+ atrace_categories: "am"
+ atrace_categories: "aidl"
+ atrace_categories: "input"
+ atrace_categories: "binder_driver"
+ atrace_categories: "sched_process_exit"
+ atrace_apps: "com.android.server.wm.flicker.testapp"
+ atrace_apps: "com.android.systemui"
+ atrace_apps: "com.android.wm.shell.flicker"
+ atrace_apps: "com.android.wm.shell.flicker.other"
+ atrace_apps: "com.android.wm.shell.flicker.bubbles"
+ atrace_apps: "com.android.wm.shell.flicker.pip"
+ atrace_apps: "com.android.wm.shell.flicker.splitscreen"
+ atrace_apps: "com.google.android.apps.nexuslauncher"
+ }
+ }
+}
+
diff --git a/libs/WindowManager/Shell/tests/flicker/manifests/AndroidManifestPip.xml b/libs/WindowManager/Shell/tests/flicker/manifests/AndroidManifestPip.xml
deleted file mode 100644
index fa42a4570b7d..000000000000
--- a/libs/WindowManager/Shell/tests/flicker/manifests/AndroidManifestPip.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<!--
- ~ Copyright (C) 2023 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.wm.shell.flicker.pip">
-
- <!-- Enable mocking GPS location -->
- <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"/>
-
- <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
- android:targetPackage="com.android.wm.shell.flicker.pip"
- android:label="WindowManager Flicker Tests">
- </instrumentation>
-</manifest>
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/Android.bp b/libs/WindowManager/Shell/tests/flicker/pip/Android.bp
new file mode 100644
index 000000000000..386983ce6aae
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/pip/Android.bp
@@ -0,0 +1,136 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "frameworks_base_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["frameworks_base_license"],
+}
+
+filegroup {
+ name: "WMShellFlickerTestsPip1-src",
+ srcs: [
+ "src/**/A*.kt",
+ "src/**/B*.kt",
+ "src/**/C*.kt",
+ "src/**/D*.kt",
+ "src/**/S*.kt",
+ ],
+}
+
+filegroup {
+ name: "WMShellFlickerTestsPip2-src",
+ srcs: [
+ "src/**/E*.kt",
+ ],
+}
+
+filegroup {
+ name: "WMShellFlickerTestsPip3-src",
+ srcs: ["src/**/*.kt"],
+}
+
+filegroup {
+ name: "WMShellFlickerTestsPipCommon-src",
+ srcs: ["src/**/common/*.kt"],
+}
+
+filegroup {
+ name: "WMShellFlickerTestsPipApps-src",
+ srcs: ["src/**/apps/*.kt"],
+}
+
+android_test {
+ name: "WMShellFlickerTestsPip1",
+ defaults: ["WMShellFlickerTestsDefault"],
+ manifest: "AndroidManifest.xml",
+ package_name: "com.android.wm.shell.flicker.pip",
+ instrumentation_target_package: "com.android.wm.shell.flicker.pip",
+ srcs: [
+ ":WMShellFlickerTestsPip1-src",
+ ":WMShellFlickerTestsPipCommon-src",
+ ],
+ static_libs: ["WMShellFlickerTestsBase"],
+}
+
+android_test {
+ name: "WMShellFlickerTestsPip2",
+ defaults: ["WMShellFlickerTestsDefault"],
+ manifest: "AndroidManifest.xml",
+ package_name: "com.android.wm.shell.flicker.pip",
+ instrumentation_target_package: "com.android.wm.shell.flicker.pip",
+ srcs: [
+ ":WMShellFlickerTestsPip2-src",
+ ":WMShellFlickerTestsPipCommon-src",
+ ],
+ static_libs: ["WMShellFlickerTestsBase"],
+}
+
+android_test {
+ name: "WMShellFlickerTestsPip3",
+ defaults: ["WMShellFlickerTestsDefault"],
+ manifest: "AndroidManifest.xml",
+ package_name: "com.android.wm.shell.flicker.pip",
+ instrumentation_target_package: "com.android.wm.shell.flicker.pip",
+ srcs: [
+ ":WMShellFlickerTestsPip3-src",
+ ":WMShellFlickerTestsPipCommon-src",
+ ],
+ exclude_srcs: [
+ ":WMShellFlickerTestsPip1-src",
+ ":WMShellFlickerTestsPip2-src",
+ ":WMShellFlickerTestsPipApps-src",
+ ],
+ static_libs: ["WMShellFlickerTestsBase"],
+}
+
+android_test {
+ name: "WMShellFlickerTestsPipApps",
+ defaults: ["WMShellFlickerTestsDefault"],
+ manifest: "AndroidManifest.xml",
+ package_name: "com.android.wm.shell.flicker.pip.apps",
+ instrumentation_target_package: "com.android.wm.shell.flicker.pip.apps",
+ srcs: [
+ ":WMShellFlickerTestsPipApps-src",
+ ":WMShellFlickerTestsPipCommon-src",
+ ],
+ static_libs: ["WMShellFlickerTestsBase"],
+}
+
+android_test {
+ name: "WMShellFlickerTestsPipAppsCSuite",
+ defaults: ["WMShellFlickerTestsDefaultWithoutTemplate"],
+ additional_manifests: ["AndroidManifest.xml"],
+ package_name: "com.android.wm.shell.flicker.pip.apps",
+ instrumentation_target_package: "com.android.wm.shell.flicker.pip.apps",
+ srcs: [
+ ":WMShellFlickerTestsPipApps-src",
+ ":WMShellFlickerTestsPipCommon-src",
+ ],
+ static_libs: ["WMShellFlickerTestsBase"],
+ test_suites: [
+ "device-tests",
+ "csuite",
+ ],
+}
+
+csuite_test {
+ name: "csuite-1p3p-pip-flickers",
+ test_config_template: "csuiteDefaultTemplate.xml",
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/AndroidManifest.xml b/libs/WindowManager/Shell/tests/flicker/pip/AndroidManifest.xml
new file mode 100644
index 000000000000..6d5423b28f39
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/pip/AndroidManifest.xml
@@ -0,0 +1,80 @@
+<!--
+ ~ Copyright (C) 2023 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ package="com.android.wm.shell.flicker.pip">
+
+ <uses-sdk android:minSdkVersion="29" android:targetSdkVersion="29"/>
+ <!-- Read and write traces from external storage -->
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+ <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+ <!-- Allow the test to write directly to /sdcard/ -->
+ <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
+ <!-- Write secure settings -->
+ <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
+ <!-- Capture screen contents -->
+ <uses-permission android:name="android.permission.ACCESS_SURFACE_FLINGER" />
+ <!-- Enable / Disable tracing !-->
+ <uses-permission android:name="android.permission.DUMP" />
+ <!-- Run layers trace -->
+ <uses-permission android:name="android.permission.HARDWARE_TEST"/>
+ <!-- Capture screen recording -->
+ <uses-permission android:name="android.permission.CAPTURE_VIDEO_OUTPUT"/>
+ <!-- Workaround grant runtime permission exception from b/152733071 -->
+ <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"/>
+ <uses-permission android:name="android.permission.READ_LOGS"/>
+ <!-- Force-stop test apps -->
+ <uses-permission android:name="android.permission.FORCE_STOP_PACKAGES"/>
+ <!-- Control test app's media session -->
+ <uses-permission android:name="android.permission.MEDIA_CONTENT_CONTROL"/>
+ <!-- ATM.removeRootTasksWithActivityTypes() -->
+ <uses-permission android:name="android.permission.MANAGE_ACTIVITY_TASKS" />
+ <!-- Enable bubble notification-->
+ <uses-permission android:name="android.permission.STATUS_BAR_SERVICE" />
+ <!-- Allow the test to connect to perfetto trace processor -->
+ <uses-permission android:name="android.permission.INTERNET"/>
+
+ <!-- Allow the test to write directly to /sdcard/ and connect to trace processor -->
+ <application android:requestLegacyExternalStorage="true"
+ android:networkSecurityConfig="@xml/network_security_config"
+ android:largeHeap="true">
+ <uses-library android:name="android.test.runner"/>
+
+ <service android:name=".NotificationListener"
+ android:exported="true"
+ android:label="WMShellTestsNotificationListenerService"
+ android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
+ <intent-filter>
+ <action android:name="android.service.notification.NotificationListenerService" />
+ </intent-filter>
+ </service>
+
+ <!-- (b/197936012) Remove startup provider due to test timeout issue -->
+ <provider
+ android:name="androidx.startup.InitializationProvider"
+ android:authorities="${applicationId}.androidx-startup"
+ tools:node="remove" />
+ </application>
+
+ <!-- Enable mocking GPS location -->
+ <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"/>
+
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="com.android.wm.shell.flicker.pip"
+ android:label="WindowManager Flicker Tests">
+ </instrumentation>
+</manifest>
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/AndroidTestTemplate.xml b/libs/WindowManager/Shell/tests/flicker/pip/AndroidTestTemplate.xml
new file mode 100644
index 000000000000..1df11369a049
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/pip/AndroidTestTemplate.xml
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2023 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<configuration description="Runs WindowManager Shell Flicker Tests {MODULE}">
+ <option name="test-tag" value="FlickerTests"/>
+ <!-- Needed for storing the perfetto trace files in the sdcard/test_results-->
+ <option name="isolated-storage" value="false"/>
+
+ <target_preparer class="com.android.tradefed.targetprep.DeviceSetup">
+ <!-- keeps the screen on during tests -->
+ <option name="screen-always-on" value="on"/>
+ <!-- prevents the phone from restarting -->
+ <option name="force-skip-system-props" value="true"/>
+ <!-- set WM tracing verbose level to all -->
+ <option name="run-command" value="cmd window tracing level all"/>
+ <!-- set WM tracing to frame (avoid incomplete states) -->
+ <option name="run-command" value="cmd window tracing frame"/>
+ <!-- disable betterbug as it's log collection dialogues cause flakes in e2e tests -->
+ <option name="run-command" value="pm disable com.google.android.internal.betterbug"/>
+ <!-- ensure lock screen mode is swipe -->
+ <option name="run-command" value="locksettings set-disabled false"/>
+ <!-- restart launcher to activate TAPL -->
+ <option name="run-command"
+ value="setprop ro.test_harness 1 ; am force-stop com.google.android.apps.nexuslauncher"/>
+ <!-- Increase trace size: 20mb for WM and 80mb for SF -->
+ <option name="run-command" value="cmd window tracing size 20480"/>
+ <option name="run-command" value="su root service call SurfaceFlinger 1029 i32 81920"/>
+ </target_preparer>
+ <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+ <option name="test-user-token" value="%TEST_USER%"/>
+ <option name="run-command" value="rm -rf /data/user/%TEST_USER%/files/*"/>
+ <option name="run-command" value="settings put secure show_ime_with_hard_keyboard 1"/>
+ <option name="run-command" value="settings put system show_touches 1"/>
+ <option name="run-command" value="settings put system pointer_location 1"/>
+ <option name="teardown-command"
+ value="settings delete secure show_ime_with_hard_keyboard"/>
+ <option name="teardown-command" value="settings delete system show_touches"/>
+ <option name="teardown-command" value="settings delete system pointer_location"/>
+ <option name="teardown-command"
+ value="cmd overlay enable com.android.internal.systemui.navbar.gestural"/>
+ </target_preparer>
+ <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+ <option name="cleanup-apks" value="true"/>
+ <option name="test-file-name" value="{MODULE}.apk"/>
+ <option name="test-file-name" value="FlickerTestApp.apk"/>
+ </target_preparer>
+ <!-- Enable mocking GPS location by the test app -->
+ <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+ <option name="run-command"
+ value="appops set com.android.wm.shell.flicker.pip.apps android:mock_location allow"/>
+ <option name="teardown-command"
+ value="appops set com.android.wm.shell.flicker.pip.apps android:mock_location deny"/>
+ </target_preparer>
+
+ <!-- Needed for pushing the trace config file -->
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="push-file"
+ key="trace_config.textproto"
+ value="/data/misc/perfetto-traces/trace_config.textproto"
+ />
+ <!--Install the content provider automatically when we push some file in sdcard folder.-->
+ <!--Needed to avoid the installation during the test suite.-->
+ <option name="push-file" key="trace_config.textproto" value="/sdcard/sample.textproto"/>
+ </target_preparer>
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest">
+ <option name="package" value="{PACKAGE}"/>
+ <option name="shell-timeout" value="6600s"/>
+ <option name="test-timeout" value="6000s"/>
+ <option name="hidden-api-checks" value="false"/>
+ <option name="device-listeners" value="android.device.collectors.PerfettoListener"/>
+ <!-- PerfettoListener related arguments -->
+ <option name="instrumentation-arg" key="perfetto_config_text_proto" value="true"/>
+ <option name="instrumentation-arg"
+ key="perfetto_config_file"
+ value="trace_config.textproto"
+ />
+ <option name="instrumentation-arg" key="per_run" value="true"/>
+ </test>
+ <!-- Needed for pulling the collected trace config on to the host -->
+ <metrics_collector class="com.android.tradefed.device.metric.FilePullerLogCollector">
+ <option name="pull-pattern-keys" value="perfetto_file_path"/>
+ <option name="directory-keys"
+ value="/data/user/0/com.android.wm.shell.flicker/files"/>
+ <option name="directory-keys"
+ value="/data/user/0/com.android.wm.shell.flicker.bubbles/files"/>
+ <option name="directory-keys"
+ value="/data/user/0/com.android.wm.shell.flicker.pip/files"/>
+ <option name="directory-keys"
+ value="/data/user/0/com.android.wm.shell.flicker.splitscreen/files"/>
+ <option name="directory-keys"
+ value="/data/user/0/com.android.wm.shell.flicker.service/files"/>
+ <option name="collect-on-run-ended-only" value="true"/>
+ <option name="clean-up" value="true"/>
+ </metrics_collector>
+</configuration>
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/OWNERS b/libs/WindowManager/Shell/tests/flicker/pip/OWNERS
index 172e24bf4574..172e24bf4574 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/OWNERS
+++ b/libs/WindowManager/Shell/tests/flicker/pip/OWNERS
diff --git a/libs/WindowManager/Shell/tests/flicker/csuiteDefaultTemplate.xml b/libs/WindowManager/Shell/tests/flicker/pip/csuiteDefaultTemplate.xml
index ca182fa5a266..ca182fa5a266 100644
--- a/libs/WindowManager/Shell/tests/flicker/csuiteDefaultTemplate.xml
+++ b/libs/WindowManager/Shell/tests/flicker/pip/csuiteDefaultTemplate.xml
diff --git a/libs/WindowManager/Shell/tests/flicker/manifests/AndroidManifestBubbles.xml b/libs/WindowManager/Shell/tests/flicker/pip/res/xml/network_security_config.xml
index 437871f1bb8f..4bd9ca049f55 100644
--- a/libs/WindowManager/Shell/tests/flicker/manifests/AndroidManifestBubbles.xml
+++ b/libs/WindowManager/Shell/tests/flicker/pip/res/xml/network_security_config.xml
@@ -1,3 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2023 The Android Open Source Project
~
@@ -14,11 +15,8 @@
~ limitations under the License.
-->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.wm.shell.flicker.bubble">
-
- <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
- android:targetPackage="com.android.wm.shell.flicker.bubble"
- android:label="WindowManager Flicker Tests">
- </instrumentation>
-</manifest>
+<network-security-config>
+ <domain-config cleartextTrafficPermitted="true">
+ <domain includeSubdomains="true">localhost</domain>
+ </domain-config>
+</network-security-config>
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/AutoEnterPipFromSplitScreenOnGoToHomeTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/AutoEnterPipFromSplitScreenOnGoToHomeTest.kt
index 943b16c33a98..a5c2c8988e70 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/AutoEnterPipFromSplitScreenOnGoToHomeTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/AutoEnterPipFromSplitScreenOnGoToHomeTest.kt
@@ -81,8 +81,13 @@ class AutoEnterPipFromSplitScreenOnGoToHomeTest(flicker: LegacyFlickerTest) :
pipApp.launchViaIntent(wmHelper)
tapl.goHome()
SplitScreenUtils.enterSplit(
- wmHelper, tapl, device, pipApp, secondAppForSplitScreen,
- flicker.scenario.startRotation)
+ wmHelper,
+ tapl,
+ device,
+ pipApp,
+ secondAppForSplitScreen,
+ flicker.scenario.startRotation
+ )
pipApp.enableAutoEnterForPipActivity()
}
teardown {
@@ -132,9 +137,7 @@ class AutoEnterPipFromSplitScreenOnGoToHomeTest(flicker: LegacyFlickerTest) :
if (flicker.scenario.isLandscapeOrSeascapeAtStart) {
flicker.assertWmVisibleRegion(pipApp) {
// first check against landscape bounds then against portrait bounds
- coversAtMost(displayBounds).then().coversAtMost(
- portraitDisplayBounds
- )
+ coversAtMost(displayBounds).then().coversAtMost(portraitDisplayBounds)
}
} else {
// always check against the display bounds which do not change during transition
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/AutoEnterPipOnGoToHomeTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/AutoEnterPipOnGoToHomeTest.kt
index 94e3959782ed..af2db12faf3a 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/AutoEnterPipOnGoToHomeTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/AutoEnterPipOnGoToHomeTest.kt
@@ -55,8 +55,7 @@ import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class AutoEnterPipOnGoToHomeTest(flicker: LegacyFlickerTest) :
- EnterPipTransition(flicker) {
+open class AutoEnterPipOnGoToHomeTest(flicker: LegacyFlickerTest) : EnterPipTransition(flicker) {
override val thisTransition: FlickerBuilder.() -> Unit = { transitions { tapl.goHome() } }
override val defaultEnterPip: FlickerBuilder.() -> Unit = {
@@ -66,11 +65,7 @@ open class AutoEnterPipOnGoToHomeTest(flicker: LegacyFlickerTest) :
}
}
- override val defaultTeardown: FlickerBuilder.() -> Unit = {
- teardown {
- pipApp.exit(wmHelper)
- }
- }
+ override val defaultTeardown: FlickerBuilder.() -> Unit = { teardown { pipApp.exit(wmHelper) } }
@FlakyTest(bugId = 293133362)
@Test
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipBySwipingDownTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ClosePipBySwipingDownTest.kt
index 9256725c6180..9256725c6180 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipBySwipingDownTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ClosePipBySwipingDownTest.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipWithDismissButtonTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ClosePipWithDismissButtonTest.kt
index 002c019eff93..002c019eff93 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipWithDismissButtonTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ClosePipWithDismissButtonTest.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTest.kt
index 820af9316aae..4cc9547ba2e3 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTest.kt
@@ -53,11 +53,7 @@ class EnterPipOnUserLeaveHintTest(flicker: LegacyFlickerTest) : EnterPipTransiti
}
}
- override val defaultTeardown: FlickerBuilder.() -> Unit = {
- teardown {
- pipApp.exit(wmHelper)
- }
- }
+ override val defaultTeardown: FlickerBuilder.() -> Unit = { teardown { pipApp.exit(wmHelper) } }
@Presubmit
@Test
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt
index 8207b85c3e0c..8207b85c3e0c 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipViaAppUiButtonTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipViaAppUiButtonTest.kt
index cc943678d492..cc943678d492 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipViaAppUiButtonTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipViaAppUiButtonTest.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaExpandButtonTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaExpandButtonTest.kt
index 7da442901e40..7da442901e40 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaExpandButtonTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaExpandButtonTest.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaIntentTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaIntentTest.kt
index 0ad9e4c61d83..0ad9e4c61d83 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaIntentTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaIntentTest.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt
index 89a6c93e478c..89a6c93e478c 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnPinchOpenTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ExpandPipOnPinchOpenTest.kt
index 8978af0088b8..8978af0088b8 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnPinchOpenTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ExpandPipOnPinchOpenTest.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipDownOnShelfHeightChange.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/MovePipDownOnShelfHeightChange.kt
index 4776206724cc..4776206724cc 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipDownOnShelfHeightChange.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/MovePipDownOnShelfHeightChange.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipOnImeVisibilityChangeTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/MovePipOnImeVisibilityChangeTest.kt
index 425cbfaffedd..425cbfaffedd 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipOnImeVisibilityChangeTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/MovePipOnImeVisibilityChangeTest.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipUpOnShelfHeightChangeTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/MovePipUpOnShelfHeightChangeTest.kt
index 18f30d96938b..18f30d96938b 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipUpOnShelfHeightChangeTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/MovePipUpOnShelfHeightChangeTest.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipAspectRatioChangeTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/PipAspectRatioChangeTest.kt
index 4f27ceddd705..36047cca55ea 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipAspectRatioChangeTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/PipAspectRatioChangeTest.kt
@@ -35,9 +35,7 @@ import org.junit.runners.Parameterized
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
class PipAspectRatioChangeTest(flicker: LegacyFlickerTest) : PipTransition(flicker) {
override val thisTransition: FlickerBuilder.() -> Unit = {
- transitions {
- pipApp.changeAspectRatio()
- }
+ transitions { pipApp.changeAspectRatio() }
}
@Presubmit
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipDragTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/PipDragTest.kt
index c7f2786debd0..c7f2786debd0 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipDragTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/PipDragTest.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipDragThenSnapTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/PipDragThenSnapTest.kt
index cabc1cc0b023..cabc1cc0b023 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipDragThenSnapTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/PipDragThenSnapTest.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipPinchInTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/PipPinchInTest.kt
index 0fd1b2c3f0de..381f947cbc84 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipPinchInTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/PipPinchInTest.kt
@@ -42,8 +42,8 @@ class PipPinchInTest(flicker: LegacyFlickerTest) : PipTransition(flicker) {
}
/**
- * Checks that the visible region area of [pipApp] decreases
- * and then increases during the animation.
+ * Checks that the visible region area of [pipApp] decreases and then increases during the
+ * animation.
*/
@Presubmit
@Test
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinned.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinned.kt
index 1f69847e5481..1f69847e5481 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinned.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinned.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ShowPipAndRotateDisplay.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ShowPipAndRotateDisplay.kt
index 308ece40402f..308ece40402f 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ShowPipAndRotateDisplay.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/ShowPipAndRotateDisplay.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/apps/AppsEnterPipTransition.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/AppsEnterPipTransition.kt
index c9a98c73e5e5..be5a27ac7dcc 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/apps/AppsEnterPipTransition.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/AppsEnterPipTransition.kt
@@ -81,9 +81,8 @@ abstract class AppsEnterPipTransition(flicker: LegacyFlickerTest) : EnterPipTran
@Test
override fun pipLayerReduces() {
flicker.assertLayers {
- val pipLayerList = this.layers {
- standardAppHelper.layerMatchesAnyOf(it) && it.isVisible
- }
+ val pipLayerList =
+ this.layers { standardAppHelper.layerMatchesAnyOf(it) && it.isVisible }
pipLayerList.zipWithNext { previous, current ->
current.visibleRegion.notBiggerThan(previous.visibleRegion.region)
}
@@ -194,7 +193,8 @@ abstract class AppsEnterPipTransition(flicker: LegacyFlickerTest) : EnterPipTran
* transition
*/
@Postsubmit
- @Test override fun statusBarWindowIsAlwaysVisible() = super.statusBarWindowIsAlwaysVisible()
+ @Test
+ override fun statusBarWindowIsAlwaysVisible() = super.statusBarWindowIsAlwaysVisible()
/**
* Checks that all layers that are visible on the trace, are visible for at least 2 consecutive
@@ -215,9 +215,7 @@ abstract class AppsEnterPipTransition(flicker: LegacyFlickerTest) : EnterPipTran
super.visibleWindowsShownMoreThanOneConsecutiveEntry()
/** Checks that all parts of the screen are covered during the transition */
- @Postsubmit
- @Test
- override fun entireScreenCovered() = super.entireScreenCovered()
+ @Postsubmit @Test override fun entireScreenCovered() = super.entireScreenCovered()
companion object {
/**
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/apps/MapsEnterPipTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/MapsEnterPipTest.kt
index d7ba3d57b548..4da52ef1272c 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/apps/MapsEnterPipTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/MapsEnterPipTest.kt
@@ -69,20 +69,21 @@ open class MapsEnterPipTest(flicker: LegacyFlickerTest) : AppsEnterPipTransition
val mainHandler = Handler(Looper.getMainLooper())
var mockLocationEnabled = false
- val updateLocation = object : Runnable {
- override fun run() {
- // early bail out if mocking location is not enabled
- if (!mockLocationEnabled) return
- val location = Location("Googleplex")
- location.latitude = 37.42243438411294
- location.longitude = -122.08426281892311
- location.time = System.currentTimeMillis()
- location.elapsedRealtimeNanos = SystemClock.elapsedRealtimeNanos()
- location.accuracy = 100f
- locationManager.setTestProviderLocation(LocationManager.GPS_PROVIDER, location)
- mainHandler.postDelayed(this, 5)
+ val updateLocation =
+ object : Runnable {
+ override fun run() {
+ // early bail out if mocking location is not enabled
+ if (!mockLocationEnabled) return
+ val location = Location("Googleplex")
+ location.latitude = 37.42243438411294
+ location.longitude = -122.08426281892311
+ location.time = System.currentTimeMillis()
+ location.elapsedRealtimeNanos = SystemClock.elapsedRealtimeNanos()
+ location.accuracy = 100f
+ locationManager.setTestProviderLocation(LocationManager.GPS_PROVIDER, location)
+ mainHandler.postDelayed(this, 5)
+ }
}
- }
override val defaultEnterPip: FlickerBuilder.() -> Unit = {
setup {
@@ -129,9 +130,7 @@ open class MapsEnterPipTest(flicker: LegacyFlickerTest) : AppsEnterPipTransition
}
}
- override val thisTransition: FlickerBuilder.() -> Unit = {
- transitions { tapl.goHome() }
- }
+ override val thisTransition: FlickerBuilder.() -> Unit = { transitions { tapl.goHome() } }
@Postsubmit
@Test
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/apps/NetflixEnterPipTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/NetflixEnterPipTest.kt
index 596580547d59..5498e8c4f970 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/apps/NetflixEnterPipTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/NetflixEnterPipTest.kt
@@ -67,25 +67,18 @@ open class NetflixEnterPipTest(flicker: LegacyFlickerTest) : AppsEnterPipTransit
standardAppHelper.launchViaIntent(
wmHelper,
NetflixAppHelper.getNetflixWatchVideoIntent("70184207"),
- ComponentNameMatcher(
- NetflixAppHelper.PACKAGE_NAME,
- NetflixAppHelper.WATCH_ACTIVITY
- )
+ ComponentNameMatcher(NetflixAppHelper.PACKAGE_NAME, NetflixAppHelper.WATCH_ACTIVITY)
)
standardAppHelper.waitForVideoPlaying()
}
}
override val defaultTeardown: FlickerBuilder.() -> Unit = {
- teardown {
- standardAppHelper.exit(wmHelper)
- }
+ teardown { standardAppHelper.exit(wmHelper) }
}
override val thisTransition: FlickerBuilder.() -> Unit = {
- transitions {
- tapl.goHomeFromImmersiveFullscreenApp()
- }
+ transitions { tapl.goHomeFromImmersiveFullscreenApp() }
}
@Postsubmit
@@ -133,7 +126,8 @@ open class NetflixEnterPipTest(flicker: LegacyFlickerTest) : AppsEnterPipTransit
}
@Postsubmit
- @Test override fun statusBarWindowIsAlwaysVisible() {
+ @Test
+ override fun statusBarWindowIsAlwaysVisible() {
// Netflix plays in immersive fullscreen mode, so taskbar will be gone at some point
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/apps/YouTubeEnterPipTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/YouTubeEnterPipTest.kt
index c370d91034fd..d8afc25caf71 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/apps/YouTubeEnterPipTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/YouTubeEnterPipTest.kt
@@ -70,14 +70,10 @@ open class YouTubeEnterPipTest(flicker: LegacyFlickerTest) : AppsEnterPipTransit
}
override val defaultTeardown: FlickerBuilder.() -> Unit = {
- teardown {
- standardAppHelper.exit(wmHelper)
- }
+ teardown { standardAppHelper.exit(wmHelper) }
}
- override val thisTransition: FlickerBuilder.() -> Unit = {
- transitions { tapl.goHome() }
- }
+ override val thisTransition: FlickerBuilder.() -> Unit = { transitions { tapl.goHome() } }
@Postsubmit
@Test
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/common/ClosePipTransition.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/common/ClosePipTransition.kt
index 751f2bc0807f..751f2bc0807f 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/common/ClosePipTransition.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/common/ClosePipTransition.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/common/EnterPipTransition.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/common/EnterPipTransition.kt
index 9c129e47efba..9c129e47efba 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/common/EnterPipTransition.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/common/EnterPipTransition.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/common/ExitPipToAppTransition.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/common/ExitPipToAppTransition.kt
index 9450bdd2d894..9450bdd2d894 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/common/ExitPipToAppTransition.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/common/ExitPipToAppTransition.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/common/MovePipShelfHeightTransition.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/common/MovePipShelfHeightTransition.kt
index 7e42bc11a9c1..7e42bc11a9c1 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/common/MovePipShelfHeightTransition.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/common/MovePipShelfHeightTransition.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/common/PipTransition.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/common/PipTransition.kt
index 7b7f1d7b5a82..7b7f1d7b5a82 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/common/PipTransition.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/common/PipTransition.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/PipAppHelperTv.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/tv/PipAppHelperTv.kt
index c6cbcd052fe0..c6cbcd052fe0 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/PipAppHelperTv.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/tv/PipAppHelperTv.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/PipTestBase.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/tv/PipTestBase.kt
index 2cb18f948f0e..2cb18f948f0e 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/PipTestBase.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/tv/PipTestBase.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvPipBasicTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/tv/TvPipBasicTest.kt
index 8a073abf032c..8a073abf032c 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvPipBasicTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/tv/TvPipBasicTest.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvPipMenuTests.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/tv/TvPipMenuTests.kt
index d4cd6da4acb1..d4cd6da4acb1 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvPipMenuTests.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/tv/TvPipMenuTests.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvPipNotificationTests.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/tv/TvPipNotificationTests.kt
index 4402e2153e9b..4402e2153e9b 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvPipNotificationTests.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/tv/TvPipNotificationTests.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvPipTestBase.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/tv/TvPipTestBase.kt
index 47bff8de377e..47bff8de377e 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvPipTestBase.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/tv/TvPipTestBase.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvUtils.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/tv/TvUtils.kt
index 4aee61ade10e..4aee61ade10e 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvUtils.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/tv/TvUtils.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/trace_config/trace_config.textproto b/libs/WindowManager/Shell/tests/flicker/pip/trace_config/trace_config.textproto
new file mode 100644
index 000000000000..406ada97a07d
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/pip/trace_config/trace_config.textproto
@@ -0,0 +1,75 @@
+# Copyright (C) 2023 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# proto-message: TraceConfig
+
+# Enable periodic flushing of the trace buffer into the output file.
+write_into_file: true
+
+# Writes the userspace buffer into the file every 1s.
+file_write_period_ms: 2500
+
+# See b/126487238 - we need to guarantee ordering of events.
+flush_period_ms: 30000
+
+# The trace buffers needs to be big enough to hold |file_write_period_ms| of
+# trace data. The trace buffer sizing depends on the number of trace categories
+# enabled and the device activity.
+
+# RSS events
+buffers: {
+ size_kb: 63488
+ fill_policy: RING_BUFFER
+}
+
+data_sources {
+ config {
+ name: "linux.process_stats"
+ target_buffer: 0
+ # polled per-process memory counters and process/thread names.
+ # If you don't want the polled counters, remove the "process_stats_config"
+ # section, but keep the data source itself as it still provides on-demand
+ # thread/process naming for ftrace data below.
+ process_stats_config {
+ scan_all_processes_on_start: true
+ }
+ }
+}
+
+data_sources: {
+ config {
+ name: "linux.ftrace"
+ ftrace_config {
+ ftrace_events: "ftrace/print"
+ ftrace_events: "task/task_newtask"
+ ftrace_events: "task/task_rename"
+ atrace_categories: "ss"
+ atrace_categories: "wm"
+ atrace_categories: "am"
+ atrace_categories: "aidl"
+ atrace_categories: "input"
+ atrace_categories: "binder_driver"
+ atrace_categories: "sched_process_exit"
+ atrace_apps: "com.android.server.wm.flicker.testapp"
+ atrace_apps: "com.android.systemui"
+ atrace_apps: "com.android.wm.shell.flicker"
+ atrace_apps: "com.android.wm.shell.flicker.other"
+ atrace_apps: "com.android.wm.shell.flicker.bubbles"
+ atrace_apps: "com.android.wm.shell.flicker.pip"
+ atrace_apps: "com.android.wm.shell.flicker.splitscreen"
+ atrace_apps: "com.google.android.apps.nexuslauncher"
+ }
+ }
+}
+
diff --git a/libs/WindowManager/Shell/tests/flicker/service/Android.bp b/libs/WindowManager/Shell/tests/flicker/service/Android.bp
new file mode 100644
index 000000000000..9b8cd94d56b2
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/service/Android.bp
@@ -0,0 +1,67 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "frameworks_base_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["frameworks_base_license"],
+}
+
+filegroup {
+ name: "WMShellFlickerServicePlatinumTests-src",
+ srcs: [
+ "src/**/platinum/*.kt",
+ "src/**/scenarios/*.kt",
+ "src/**/common/*.kt",
+ ],
+}
+
+java_library {
+ name: "wm-shell-flicker-platinum-tests",
+ platform_apis: true,
+ optimize: {
+ enabled: false,
+ },
+ srcs: [
+ ":WMShellFlickerServicePlatinumTests-src",
+ ],
+ static_libs: [
+ "wm-shell-flicker-utils",
+ ],
+}
+
+android_test {
+ name: "WMShellFlickerServiceTests",
+ defaults: ["WMShellFlickerTestsDefault"],
+ manifest: "AndroidManifest.xml",
+ package_name: "com.android.wm.shell.flicker.service",
+ instrumentation_target_package: "com.android.wm.shell.flicker.service",
+ srcs: ["src/**/*.kt"],
+ static_libs: ["WMShellFlickerTestsBase"],
+}
+
+android_test {
+ name: "WMShellFlickerServicePlatinumTests",
+ defaults: ["WMShellFlickerTestsDefault"],
+ manifest: "AndroidManifest.xml",
+ package_name: "com.android.wm.shell.flicker.service",
+ instrumentation_target_package: "com.android.wm.shell.flicker.service",
+ srcs: [":WMShellFlickerServicePlatinumTests-src"],
+ static_libs: ["WMShellFlickerTestsBase"],
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/service/AndroidManifest.xml b/libs/WindowManager/Shell/tests/flicker/service/AndroidManifest.xml
new file mode 100644
index 000000000000..d54b6941d975
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/service/AndroidManifest.xml
@@ -0,0 +1,77 @@
+<!--
+ ~ Copyright (C) 2023 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ package="com.android.wm.shell.flicker.service">
+
+ <uses-sdk android:minSdkVersion="29" android:targetSdkVersion="29"/>
+ <!-- Read and write traces from external storage -->
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+ <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+ <!-- Allow the test to write directly to /sdcard/ -->
+ <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
+ <!-- Write secure settings -->
+ <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
+ <!-- Capture screen contents -->
+ <uses-permission android:name="android.permission.ACCESS_SURFACE_FLINGER" />
+ <!-- Enable / Disable tracing !-->
+ <uses-permission android:name="android.permission.DUMP" />
+ <!-- Run layers trace -->
+ <uses-permission android:name="android.permission.HARDWARE_TEST"/>
+ <!-- Capture screen recording -->
+ <uses-permission android:name="android.permission.CAPTURE_VIDEO_OUTPUT"/>
+ <!-- Workaround grant runtime permission exception from b/152733071 -->
+ <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"/>
+ <uses-permission android:name="android.permission.READ_LOGS"/>
+ <!-- Force-stop test apps -->
+ <uses-permission android:name="android.permission.FORCE_STOP_PACKAGES"/>
+ <!-- Control test app's media session -->
+ <uses-permission android:name="android.permission.MEDIA_CONTENT_CONTROL"/>
+ <!-- ATM.removeRootTasksWithActivityTypes() -->
+ <uses-permission android:name="android.permission.MANAGE_ACTIVITY_TASKS" />
+ <!-- Enable bubble notification-->
+ <uses-permission android:name="android.permission.STATUS_BAR_SERVICE" />
+ <!-- Allow the test to connect to perfetto trace processor -->
+ <uses-permission android:name="android.permission.INTERNET"/>
+
+ <!-- Allow the test to write directly to /sdcard/ and connect to trace processor -->
+ <application android:requestLegacyExternalStorage="true"
+ android:networkSecurityConfig="@xml/network_security_config"
+ android:largeHeap="true">
+ <uses-library android:name="android.test.runner"/>
+
+ <service android:name=".NotificationListener"
+ android:exported="true"
+ android:label="WMShellTestsNotificationListenerService"
+ android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
+ <intent-filter>
+ <action android:name="android.service.notification.NotificationListenerService" />
+ </intent-filter>
+ </service>
+
+ <!-- (b/197936012) Remove startup provider due to test timeout issue -->
+ <provider
+ android:name="androidx.startup.InitializationProvider"
+ android:authorities="${applicationId}.androidx-startup"
+ tools:node="remove" />
+ </application>
+
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="com.android.wm.shell.flicker.service"
+ android:label="WindowManager Flicker Service Tests">
+ </instrumentation>
+</manifest>
diff --git a/libs/WindowManager/Shell/tests/flicker/service/AndroidTestTemplate.xml b/libs/WindowManager/Shell/tests/flicker/service/AndroidTestTemplate.xml
new file mode 100644
index 000000000000..1df11369a049
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/service/AndroidTestTemplate.xml
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2023 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<configuration description="Runs WindowManager Shell Flicker Tests {MODULE}">
+ <option name="test-tag" value="FlickerTests"/>
+ <!-- Needed for storing the perfetto trace files in the sdcard/test_results-->
+ <option name="isolated-storage" value="false"/>
+
+ <target_preparer class="com.android.tradefed.targetprep.DeviceSetup">
+ <!-- keeps the screen on during tests -->
+ <option name="screen-always-on" value="on"/>
+ <!-- prevents the phone from restarting -->
+ <option name="force-skip-system-props" value="true"/>
+ <!-- set WM tracing verbose level to all -->
+ <option name="run-command" value="cmd window tracing level all"/>
+ <!-- set WM tracing to frame (avoid incomplete states) -->
+ <option name="run-command" value="cmd window tracing frame"/>
+ <!-- disable betterbug as it's log collection dialogues cause flakes in e2e tests -->
+ <option name="run-command" value="pm disable com.google.android.internal.betterbug"/>
+ <!-- ensure lock screen mode is swipe -->
+ <option name="run-command" value="locksettings set-disabled false"/>
+ <!-- restart launcher to activate TAPL -->
+ <option name="run-command"
+ value="setprop ro.test_harness 1 ; am force-stop com.google.android.apps.nexuslauncher"/>
+ <!-- Increase trace size: 20mb for WM and 80mb for SF -->
+ <option name="run-command" value="cmd window tracing size 20480"/>
+ <option name="run-command" value="su root service call SurfaceFlinger 1029 i32 81920"/>
+ </target_preparer>
+ <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+ <option name="test-user-token" value="%TEST_USER%"/>
+ <option name="run-command" value="rm -rf /data/user/%TEST_USER%/files/*"/>
+ <option name="run-command" value="settings put secure show_ime_with_hard_keyboard 1"/>
+ <option name="run-command" value="settings put system show_touches 1"/>
+ <option name="run-command" value="settings put system pointer_location 1"/>
+ <option name="teardown-command"
+ value="settings delete secure show_ime_with_hard_keyboard"/>
+ <option name="teardown-command" value="settings delete system show_touches"/>
+ <option name="teardown-command" value="settings delete system pointer_location"/>
+ <option name="teardown-command"
+ value="cmd overlay enable com.android.internal.systemui.navbar.gestural"/>
+ </target_preparer>
+ <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+ <option name="cleanup-apks" value="true"/>
+ <option name="test-file-name" value="{MODULE}.apk"/>
+ <option name="test-file-name" value="FlickerTestApp.apk"/>
+ </target_preparer>
+ <!-- Enable mocking GPS location by the test app -->
+ <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+ <option name="run-command"
+ value="appops set com.android.wm.shell.flicker.pip.apps android:mock_location allow"/>
+ <option name="teardown-command"
+ value="appops set com.android.wm.shell.flicker.pip.apps android:mock_location deny"/>
+ </target_preparer>
+
+ <!-- Needed for pushing the trace config file -->
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="push-file"
+ key="trace_config.textproto"
+ value="/data/misc/perfetto-traces/trace_config.textproto"
+ />
+ <!--Install the content provider automatically when we push some file in sdcard folder.-->
+ <!--Needed to avoid the installation during the test suite.-->
+ <option name="push-file" key="trace_config.textproto" value="/sdcard/sample.textproto"/>
+ </target_preparer>
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest">
+ <option name="package" value="{PACKAGE}"/>
+ <option name="shell-timeout" value="6600s"/>
+ <option name="test-timeout" value="6000s"/>
+ <option name="hidden-api-checks" value="false"/>
+ <option name="device-listeners" value="android.device.collectors.PerfettoListener"/>
+ <!-- PerfettoListener related arguments -->
+ <option name="instrumentation-arg" key="perfetto_config_text_proto" value="true"/>
+ <option name="instrumentation-arg"
+ key="perfetto_config_file"
+ value="trace_config.textproto"
+ />
+ <option name="instrumentation-arg" key="per_run" value="true"/>
+ </test>
+ <!-- Needed for pulling the collected trace config on to the host -->
+ <metrics_collector class="com.android.tradefed.device.metric.FilePullerLogCollector">
+ <option name="pull-pattern-keys" value="perfetto_file_path"/>
+ <option name="directory-keys"
+ value="/data/user/0/com.android.wm.shell.flicker/files"/>
+ <option name="directory-keys"
+ value="/data/user/0/com.android.wm.shell.flicker.bubbles/files"/>
+ <option name="directory-keys"
+ value="/data/user/0/com.android.wm.shell.flicker.pip/files"/>
+ <option name="directory-keys"
+ value="/data/user/0/com.android.wm.shell.flicker.splitscreen/files"/>
+ <option name="directory-keys"
+ value="/data/user/0/com.android.wm.shell.flicker.service/files"/>
+ <option name="collect-on-run-ended-only" value="true"/>
+ <option name="clean-up" value="true"/>
+ </metrics_collector>
+</configuration>
diff --git a/libs/WindowManager/Shell/tests/flicker/manifests/AndroidManifestSplitScreen.xml b/libs/WindowManager/Shell/tests/flicker/service/res/xml/network_security_config.xml
index 887d8db3042f..4bd9ca049f55 100644
--- a/libs/WindowManager/Shell/tests/flicker/manifests/AndroidManifestSplitScreen.xml
+++ b/libs/WindowManager/Shell/tests/flicker/service/res/xml/network_security_config.xml
@@ -1,3 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2023 The Android Open Source Project
~
@@ -14,11 +15,8 @@
~ limitations under the License.
-->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.wm.shell.flicker.splitscreen">
-
- <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
- android:targetPackage="com.android.wm.shell.flicker.splitscreen"
- android:label="WindowManager Flicker Tests">
- </instrumentation>
-</manifest>
+<network-security-config>
+ <domain-config cleartextTrafficPermitted="true">
+ <domain includeSubdomains="true">localhost</domain>
+ </domain-config>
+</network-security-config>
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/common/Utils.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/common/Utils.kt
index 5f157856aa36..4bd79546b96d 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/common/Utils.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/common/Utils.kt
@@ -36,9 +36,7 @@ object Utils {
fun testSetupRule(navigationMode: NavBar, rotation: Rotation): RuleChain {
return RuleChain.outerRule(ArtifactSaverRule())
.around(UnlockScreenRule())
- .around(
- NavigationModeRule(navigationMode.value, false)
- )
+ .around(NavigationModeRule(navigationMode.value, false))
.around(
LaunchAppRule(MessagingAppHelper(instrumentation), clearCacheAfterParsing = false)
)
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/OWNERS b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/OWNERS
index 3ab6a1ee061d..3ab6a1ee061d 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/OWNERS
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/OWNERS
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/CopyContentInSplitGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/CopyContentInSplitGesturalNavLandscape.kt
index a5c512267508..a5c512267508 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/CopyContentInSplitGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/CopyContentInSplitGesturalNavLandscape.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/CopyContentInSplitGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/CopyContentInSplitGesturalNavPortrait.kt
index 092fb6720e57..092fb6720e57 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/CopyContentInSplitGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/CopyContentInSplitGesturalNavPortrait.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByDividerGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByDividerGesturalNavLandscape.kt
index 69499b9b488b..69499b9b488b 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByDividerGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByDividerGesturalNavLandscape.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByDividerGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByDividerGesturalNavPortrait.kt
index bd627f4babaa..bd627f4babaa 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByDividerGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByDividerGesturalNavPortrait.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByGoHomeGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByGoHomeGesturalNavLandscape.kt
index a8f4d0a24c7e..a8f4d0a24c7e 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByGoHomeGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByGoHomeGesturalNavLandscape.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByGoHomeGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByGoHomeGesturalNavPortrait.kt
index cee9bbfb4aa4..cee9bbfb4aa4 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByGoHomeGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByGoHomeGesturalNavPortrait.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DragDividerToResizeGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DragDividerToResizeGesturalNavLandscape.kt
index c1b3aade11cd..c1b3aade11cd 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DragDividerToResizeGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DragDividerToResizeGesturalNavLandscape.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DragDividerToResizeGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DragDividerToResizeGesturalNavPortrait.kt
index c6e2e854ab89..c6e2e854ab89 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DragDividerToResizeGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DragDividerToResizeGesturalNavPortrait.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromAllAppsGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromAllAppsGesturalNavLandscape.kt
index 169b5cfa3462..169b5cfa3462 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromAllAppsGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromAllAppsGesturalNavLandscape.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromAllAppsGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromAllAppsGesturalNavPortrait.kt
index 412c011a3f17..412c011a3f17 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromAllAppsGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromAllAppsGesturalNavPortrait.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromNotificationGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromNotificationGesturalNavLandscape.kt
index 6e4cf9f55cfd..6e4cf9f55cfd 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromNotificationGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromNotificationGesturalNavLandscape.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromNotificationGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromNotificationGesturalNavPortrait.kt
index cc2870213e8d..cc2870213e8d 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromNotificationGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromNotificationGesturalNavPortrait.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromShortcutGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromShortcutGesturalNavLandscape.kt
index 736604f02377..736604f02377 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromShortcutGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromShortcutGesturalNavLandscape.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromShortcutGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromShortcutGesturalNavPortrait.kt
index 8df8dfaab071..8df8dfaab071 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromShortcutGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromShortcutGesturalNavPortrait.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromTaskbarGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromTaskbarGesturalNavLandscape.kt
index 378f055ef830..378f055ef830 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromTaskbarGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromTaskbarGesturalNavLandscape.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromTaskbarGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromTaskbarGesturalNavPortrait.kt
index b33d26288d33..b33d26288d33 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromTaskbarGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromTaskbarGesturalNavPortrait.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenFromOverviewGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenFromOverviewGesturalNavLandscape.kt
index b1d3858b9dbb..b1d3858b9dbb 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenFromOverviewGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenFromOverviewGesturalNavLandscape.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenFromOverviewGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenFromOverviewGesturalNavPortrait.kt
index 6d824c74c1fe..6d824c74c1fe 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenFromOverviewGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenFromOverviewGesturalNavPortrait.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchAppByDoubleTapDividerGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchAppByDoubleTapDividerGesturalNavLandscape.kt
index f1d3d0cf2716..f1d3d0cf2716 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchAppByDoubleTapDividerGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchAppByDoubleTapDividerGesturalNavLandscape.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchAppByDoubleTapDividerGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchAppByDoubleTapDividerGesturalNavPortrait.kt
index a867bac8c0eb..a867bac8c0eb 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchAppByDoubleTapDividerGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchAppByDoubleTapDividerGesturalNavPortrait.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromAnotherAppGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromAnotherAppGesturalNavLandscape.kt
index 76247ba10037..76247ba10037 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromAnotherAppGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromAnotherAppGesturalNavLandscape.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromAnotherAppGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromAnotherAppGesturalNavPortrait.kt
index e179da81e4db..e179da81e4db 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromAnotherAppGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromAnotherAppGesturalNavPortrait.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromHomeGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromHomeGesturalNavLandscape.kt
index 20f554f7d154..20f554f7d154 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromHomeGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromHomeGesturalNavLandscape.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromHomeGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromHomeGesturalNavPortrait.kt
index f7776ee3244a..f7776ee3244a 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromHomeGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromHomeGesturalNavPortrait.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromRecentGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromRecentGesturalNavLandscape.kt
index 4ff0b4362e60..4ff0b4362e60 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromRecentGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromRecentGesturalNavLandscape.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromRecentGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromRecentGesturalNavPortrait.kt
index 930f31d1f348..930f31d1f348 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromRecentGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromRecentGesturalNavPortrait.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBetweenSplitPairsGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBetweenSplitPairsGesturalNavLandscape.kt
index 3da61e5e310c..3da61e5e310c 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBetweenSplitPairsGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBetweenSplitPairsGesturalNavLandscape.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBetweenSplitPairsGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBetweenSplitPairsGesturalNavPortrait.kt
index 627ae1843314..627ae1843314 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBetweenSplitPairsGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBetweenSplitPairsGesturalNavPortrait.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/UnlockKeyguardToSplitScreenGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/UnlockKeyguardToSplitScreenGesturalNavLandscape.kt
index c744103d49ba..c744103d49ba 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/UnlockKeyguardToSplitScreenGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/UnlockKeyguardToSplitScreenGesturalNavLandscape.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/UnlockKeyguardToSplitScreenGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/UnlockKeyguardToSplitScreenGesturalNavPortrait.kt
index 11a4e02c5e37..11a4e02c5e37 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/UnlockKeyguardToSplitScreenGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/flicker/UnlockKeyguardToSplitScreenGesturalNavPortrait.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/CopyContentInSplitGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/CopyContentInSplitGesturalNavLandscape.kt
index e37d806c7a14..e37d806c7a14 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/CopyContentInSplitGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/CopyContentInSplitGesturalNavLandscape.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/CopyContentInSplitGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/CopyContentInSplitGesturalNavPortrait.kt
index 2a50912e0a5c..2a50912e0a5c 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/CopyContentInSplitGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/CopyContentInSplitGesturalNavPortrait.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByDividerGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByDividerGesturalNavLandscape.kt
index d5da1a8b558c..d5da1a8b558c 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByDividerGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByDividerGesturalNavLandscape.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByDividerGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByDividerGesturalNavPortrait.kt
index 7fdcb9be62ee..7fdcb9be62ee 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByDividerGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByDividerGesturalNavPortrait.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByGoHomeGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByGoHomeGesturalNavLandscape.kt
index 308e954b86c1..308e954b86c1 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByGoHomeGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByGoHomeGesturalNavLandscape.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByGoHomeGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByGoHomeGesturalNavPortrait.kt
index 39e75bd25a71..39e75bd25a71 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByGoHomeGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByGoHomeGesturalNavPortrait.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DragDividerToResizeGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DragDividerToResizeGesturalNavLandscape.kt
index e18da17175c0..e18da17175c0 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DragDividerToResizeGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DragDividerToResizeGesturalNavLandscape.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DragDividerToResizeGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DragDividerToResizeGesturalNavPortrait.kt
index 00d60e756ffa..00d60e756ffa 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DragDividerToResizeGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DragDividerToResizeGesturalNavPortrait.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromAllAppsGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromAllAppsGesturalNavLandscape.kt
index d7efbc8c0fd4..d7efbc8c0fd4 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromAllAppsGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromAllAppsGesturalNavLandscape.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromAllAppsGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromAllAppsGesturalNavPortrait.kt
index 4eece3f62d10..4eece3f62d10 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromAllAppsGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromAllAppsGesturalNavPortrait.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromNotificationGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromNotificationGesturalNavLandscape.kt
index d96b056d8753..d96b056d8753 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromNotificationGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromNotificationGesturalNavLandscape.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromNotificationGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromNotificationGesturalNavPortrait.kt
index 809b690e0861..809b690e0861 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromNotificationGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromNotificationGesturalNavPortrait.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromShortcutGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromShortcutGesturalNavLandscape.kt
index bbdf2d728494..bbdf2d728494 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromShortcutGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromShortcutGesturalNavLandscape.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromShortcutGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromShortcutGesturalNavPortrait.kt
index 5c29fd8fe57e..5c29fd8fe57e 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromShortcutGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromShortcutGesturalNavPortrait.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromTaskbarGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromTaskbarGesturalNavLandscape.kt
index a7398ebf56e8..a7398ebf56e8 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromTaskbarGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromTaskbarGesturalNavLandscape.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromTaskbarGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromTaskbarGesturalNavPortrait.kt
index eae88ad4ad09..eae88ad4ad09 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromTaskbarGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromTaskbarGesturalNavPortrait.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenFromOverviewGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenFromOverviewGesturalNavLandscape.kt
index 7e8ee04a28fa..7e8ee04a28fa 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenFromOverviewGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenFromOverviewGesturalNavLandscape.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenFromOverviewGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenFromOverviewGesturalNavPortrait.kt
index 9295c330b879..9295c330b879 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenFromOverviewGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenFromOverviewGesturalNavPortrait.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchAppByDoubleTapDividerGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchAppByDoubleTapDividerGesturalNavLandscape.kt
index 4b59e9fbd866..4b59e9fbd866 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchAppByDoubleTapDividerGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchAppByDoubleTapDividerGesturalNavLandscape.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchAppByDoubleTapDividerGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchAppByDoubleTapDividerGesturalNavPortrait.kt
index 5ff36d4aabbb..5ff36d4aabbb 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchAppByDoubleTapDividerGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchAppByDoubleTapDividerGesturalNavPortrait.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromAnotherAppGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromAnotherAppGesturalNavLandscape.kt
index c0cb7219437b..c0cb7219437b 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromAnotherAppGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromAnotherAppGesturalNavLandscape.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromAnotherAppGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromAnotherAppGesturalNavPortrait.kt
index 8c140884aa50..8c140884aa50 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromAnotherAppGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromAnotherAppGesturalNavPortrait.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromHomeGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromHomeGesturalNavLandscape.kt
index 7b6614b81c11..7b6614b81c11 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromHomeGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromHomeGesturalNavLandscape.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromHomeGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromHomeGesturalNavPortrait.kt
index 5df5be9daa8b..5df5be9daa8b 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromHomeGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromHomeGesturalNavPortrait.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromRecentGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromRecentGesturalNavLandscape.kt
index 9d63003bf2a1..9d63003bf2a1 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromRecentGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromRecentGesturalNavLandscape.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromRecentGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromRecentGesturalNavPortrait.kt
index 9fa04b208ad1..9fa04b208ad1 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromRecentGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromRecentGesturalNavPortrait.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBetweenSplitPairsGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBetweenSplitPairsGesturalNavLandscape.kt
index 9386aa2b2cf0..9386aa2b2cf0 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBetweenSplitPairsGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBetweenSplitPairsGesturalNavLandscape.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBetweenSplitPairsGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBetweenSplitPairsGesturalNavPortrait.kt
index 5ef21672bfe0..5ef21672bfe0 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBetweenSplitPairsGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBetweenSplitPairsGesturalNavPortrait.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/UnlockKeyguardToSplitScreenGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/UnlockKeyguardToSplitScreenGesturalNavLandscape.kt
index 9caab9b5182a..9caab9b5182a 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/UnlockKeyguardToSplitScreenGesturalNavLandscape.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/UnlockKeyguardToSplitScreenGesturalNavLandscape.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/UnlockKeyguardToSplitScreenGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/UnlockKeyguardToSplitScreenGesturalNavPortrait.kt
index bf484e5cef98..bf484e5cef98 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/UnlockKeyguardToSplitScreenGesturalNavPortrait.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/platinum/UnlockKeyguardToSplitScreenGesturalNavPortrait.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/CopyContentInSplit.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/CopyContentInSplit.kt
index 80ab24ddf9ef..80ab24ddf9ef 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/CopyContentInSplit.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/CopyContentInSplit.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DismissSplitScreenByDivider.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DismissSplitScreenByDivider.kt
index 4c391047e853..4c391047e853 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DismissSplitScreenByDivider.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DismissSplitScreenByDivider.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DismissSplitScreenByGoHome.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DismissSplitScreenByGoHome.kt
index f6d1afc05a5a..f6d1afc05a5a 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DismissSplitScreenByGoHome.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DismissSplitScreenByGoHome.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DragDividerToResize.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DragDividerToResize.kt
index db5a32a382fb..db5a32a382fb 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DragDividerToResize.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DragDividerToResize.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromAllApps.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromAllApps.kt
index d7b306c3be23..d7b306c3be23 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromAllApps.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromAllApps.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromNotification.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromNotification.kt
index cc982d1ba860..cc982d1ba860 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromNotification.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromNotification.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromShortcut.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromShortcut.kt
index fa12bb869467..fa12bb869467 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromShortcut.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromShortcut.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromTaskbar.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromTaskbar.kt
index 2592fd40d902..2592fd40d902 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromTaskbar.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromTaskbar.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenFromOverview.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenFromOverview.kt
index 983653b9b5ca..983653b9b5ca 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenFromOverview.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenFromOverview.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchAppByDoubleTapDivider.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchAppByDoubleTapDivider.kt
index 068171d2e129..068171d2e129 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchAppByDoubleTapDivider.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchAppByDoubleTapDivider.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromAnotherApp.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromAnotherApp.kt
index 64b75c5fd967..64b75c5fd967 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromAnotherApp.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromAnotherApp.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromHome.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromHome.kt
index 179501089168..179501089168 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromHome.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromHome.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromRecent.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromRecent.kt
index 7065846dc653..7065846dc653 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromRecent.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromRecent.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBetweenSplitPairs.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBetweenSplitPairs.kt
index 251cb50de017..251cb50de017 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBetweenSplitPairs.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBetweenSplitPairs.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/UnlockKeyguardToSplitScreen.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/UnlockKeyguardToSplitScreen.kt
index a9933bbe09fc..a9933bbe09fc 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/UnlockKeyguardToSplitScreen.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/UnlockKeyguardToSplitScreen.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/service/trace_config/trace_config.textproto b/libs/WindowManager/Shell/tests/flicker/service/trace_config/trace_config.textproto
new file mode 100644
index 000000000000..406ada97a07d
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/service/trace_config/trace_config.textproto
@@ -0,0 +1,75 @@
+# Copyright (C) 2023 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# proto-message: TraceConfig
+
+# Enable periodic flushing of the trace buffer into the output file.
+write_into_file: true
+
+# Writes the userspace buffer into the file every 1s.
+file_write_period_ms: 2500
+
+# See b/126487238 - we need to guarantee ordering of events.
+flush_period_ms: 30000
+
+# The trace buffers needs to be big enough to hold |file_write_period_ms| of
+# trace data. The trace buffer sizing depends on the number of trace categories
+# enabled and the device activity.
+
+# RSS events
+buffers: {
+ size_kb: 63488
+ fill_policy: RING_BUFFER
+}
+
+data_sources {
+ config {
+ name: "linux.process_stats"
+ target_buffer: 0
+ # polled per-process memory counters and process/thread names.
+ # If you don't want the polled counters, remove the "process_stats_config"
+ # section, but keep the data source itself as it still provides on-demand
+ # thread/process naming for ftrace data below.
+ process_stats_config {
+ scan_all_processes_on_start: true
+ }
+ }
+}
+
+data_sources: {
+ config {
+ name: "linux.ftrace"
+ ftrace_config {
+ ftrace_events: "ftrace/print"
+ ftrace_events: "task/task_newtask"
+ ftrace_events: "task/task_rename"
+ atrace_categories: "ss"
+ atrace_categories: "wm"
+ atrace_categories: "am"
+ atrace_categories: "aidl"
+ atrace_categories: "input"
+ atrace_categories: "binder_driver"
+ atrace_categories: "sched_process_exit"
+ atrace_apps: "com.android.server.wm.flicker.testapp"
+ atrace_apps: "com.android.systemui"
+ atrace_apps: "com.android.wm.shell.flicker"
+ atrace_apps: "com.android.wm.shell.flicker.other"
+ atrace_apps: "com.android.wm.shell.flicker.bubbles"
+ atrace_apps: "com.android.wm.shell.flicker.pip"
+ atrace_apps: "com.android.wm.shell.flicker.splitscreen"
+ atrace_apps: "com.google.android.apps.nexuslauncher"
+ }
+ }
+}
+
diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/Android.bp b/libs/WindowManager/Shell/tests/flicker/splitscreen/Android.bp
new file mode 100644
index 000000000000..4629c5318366
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/splitscreen/Android.bp
@@ -0,0 +1,77 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "frameworks_base_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["frameworks_base_license"],
+}
+
+filegroup {
+ name: "WMShellFlickerTestsSplitScreenBase-src",
+ srcs: [
+ "src/**/benchmark/*.kt",
+ ],
+}
+
+filegroup {
+ name: "WMShellFlickerTestsSplitScreenGroup1-src",
+ srcs: [
+ "src/**/A*.kt",
+ "src/**/B*.kt",
+ "src/**/C*.kt",
+ "src/**/D*.kt",
+ "src/**/E*.kt",
+ ],
+}
+
+filegroup {
+ name: "WMShellFlickerTestsSplitScreenGroup2-src",
+ srcs: [
+ "src/**/*.kt",
+ ],
+}
+
+android_test {
+ name: "WMShellFlickerTestsSplitScreenGroup1",
+ defaults: ["WMShellFlickerTestsDefault"],
+ manifest: "AndroidManifest.xml",
+ package_name: "com.android.wm.shell.flicker.splitscreen",
+ instrumentation_target_package: "com.android.wm.shell.flicker.splitscreen",
+ srcs: [
+ ":WMShellFlickerTestsSplitScreenBase-src",
+ ":WMShellFlickerTestsSplitScreenGroup1-src",
+ ],
+ static_libs: ["WMShellFlickerTestsBase"],
+}
+
+android_test {
+ name: "WMShellFlickerTestsSplitScreenGroup2",
+ manifest: "AndroidManifest.xml",
+ package_name: "com.android.wm.shell.flicker.splitscreen",
+ instrumentation_target_package: "com.android.wm.shell.flicker.splitscreen",
+ srcs: [
+ ":WMShellFlickerTestsSplitScreenBase-src",
+ ":WMShellFlickerTestsSplitScreenGroup2-src",
+ ],
+ exclude_srcs: [
+ ":WMShellFlickerTestsSplitScreenGroup1-src",
+ ],
+ static_libs: ["WMShellFlickerTestsBase"],
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/AndroidManifest.xml b/libs/WindowManager/Shell/tests/flicker/splitscreen/AndroidManifest.xml
new file mode 100644
index 000000000000..9ff2161daa51
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/splitscreen/AndroidManifest.xml
@@ -0,0 +1,77 @@
+<!--
+ ~ Copyright (C) 2023 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ package="com.android.wm.shell.flicker.splitscreen">
+
+ <uses-sdk android:minSdkVersion="29" android:targetSdkVersion="29"/>
+ <!-- Read and write traces from external storage -->
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+ <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+ <!-- Allow the test to write directly to /sdcard/ -->
+ <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
+ <!-- Write secure settings -->
+ <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
+ <!-- Capture screen contents -->
+ <uses-permission android:name="android.permission.ACCESS_SURFACE_FLINGER" />
+ <!-- Enable / Disable tracing !-->
+ <uses-permission android:name="android.permission.DUMP" />
+ <!-- Run layers trace -->
+ <uses-permission android:name="android.permission.HARDWARE_TEST"/>
+ <!-- Capture screen recording -->
+ <uses-permission android:name="android.permission.CAPTURE_VIDEO_OUTPUT"/>
+ <!-- Workaround grant runtime permission exception from b/152733071 -->
+ <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"/>
+ <uses-permission android:name="android.permission.READ_LOGS"/>
+ <!-- Force-stop test apps -->
+ <uses-permission android:name="android.permission.FORCE_STOP_PACKAGES"/>
+ <!-- Control test app's media session -->
+ <uses-permission android:name="android.permission.MEDIA_CONTENT_CONTROL"/>
+ <!-- ATM.removeRootTasksWithActivityTypes() -->
+ <uses-permission android:name="android.permission.MANAGE_ACTIVITY_TASKS" />
+ <!-- Enable bubble notification-->
+ <uses-permission android:name="android.permission.STATUS_BAR_SERVICE" />
+ <!-- Allow the test to connect to perfetto trace processor -->
+ <uses-permission android:name="android.permission.INTERNET"/>
+
+ <!-- Allow the test to write directly to /sdcard/ and connect to trace processor -->
+ <application android:requestLegacyExternalStorage="true"
+ android:networkSecurityConfig="@xml/network_security_config"
+ android:largeHeap="true">
+ <uses-library android:name="android.test.runner"/>
+
+ <service android:name=".NotificationListener"
+ android:exported="true"
+ android:label="WMShellTestsNotificationListenerService"
+ android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
+ <intent-filter>
+ <action android:name="android.service.notification.NotificationListenerService" />
+ </intent-filter>
+ </service>
+
+ <!-- (b/197936012) Remove startup provider due to test timeout issue -->
+ <provider
+ android:name="androidx.startup.InitializationProvider"
+ android:authorities="${applicationId}.androidx-startup"
+ tools:node="remove" />
+ </application>
+
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="com.android.wm.shell.flicker.splitscreen"
+ android:label="WindowManager Flicker Tests">
+ </instrumentation>
+</manifest>
diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/AndroidTestTemplate.xml b/libs/WindowManager/Shell/tests/flicker/splitscreen/AndroidTestTemplate.xml
new file mode 100644
index 000000000000..1df11369a049
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/splitscreen/AndroidTestTemplate.xml
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2023 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<configuration description="Runs WindowManager Shell Flicker Tests {MODULE}">
+ <option name="test-tag" value="FlickerTests"/>
+ <!-- Needed for storing the perfetto trace files in the sdcard/test_results-->
+ <option name="isolated-storage" value="false"/>
+
+ <target_preparer class="com.android.tradefed.targetprep.DeviceSetup">
+ <!-- keeps the screen on during tests -->
+ <option name="screen-always-on" value="on"/>
+ <!-- prevents the phone from restarting -->
+ <option name="force-skip-system-props" value="true"/>
+ <!-- set WM tracing verbose level to all -->
+ <option name="run-command" value="cmd window tracing level all"/>
+ <!-- set WM tracing to frame (avoid incomplete states) -->
+ <option name="run-command" value="cmd window tracing frame"/>
+ <!-- disable betterbug as it's log collection dialogues cause flakes in e2e tests -->
+ <option name="run-command" value="pm disable com.google.android.internal.betterbug"/>
+ <!-- ensure lock screen mode is swipe -->
+ <option name="run-command" value="locksettings set-disabled false"/>
+ <!-- restart launcher to activate TAPL -->
+ <option name="run-command"
+ value="setprop ro.test_harness 1 ; am force-stop com.google.android.apps.nexuslauncher"/>
+ <!-- Increase trace size: 20mb for WM and 80mb for SF -->
+ <option name="run-command" value="cmd window tracing size 20480"/>
+ <option name="run-command" value="su root service call SurfaceFlinger 1029 i32 81920"/>
+ </target_preparer>
+ <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+ <option name="test-user-token" value="%TEST_USER%"/>
+ <option name="run-command" value="rm -rf /data/user/%TEST_USER%/files/*"/>
+ <option name="run-command" value="settings put secure show_ime_with_hard_keyboard 1"/>
+ <option name="run-command" value="settings put system show_touches 1"/>
+ <option name="run-command" value="settings put system pointer_location 1"/>
+ <option name="teardown-command"
+ value="settings delete secure show_ime_with_hard_keyboard"/>
+ <option name="teardown-command" value="settings delete system show_touches"/>
+ <option name="teardown-command" value="settings delete system pointer_location"/>
+ <option name="teardown-command"
+ value="cmd overlay enable com.android.internal.systemui.navbar.gestural"/>
+ </target_preparer>
+ <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+ <option name="cleanup-apks" value="true"/>
+ <option name="test-file-name" value="{MODULE}.apk"/>
+ <option name="test-file-name" value="FlickerTestApp.apk"/>
+ </target_preparer>
+ <!-- Enable mocking GPS location by the test app -->
+ <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+ <option name="run-command"
+ value="appops set com.android.wm.shell.flicker.pip.apps android:mock_location allow"/>
+ <option name="teardown-command"
+ value="appops set com.android.wm.shell.flicker.pip.apps android:mock_location deny"/>
+ </target_preparer>
+
+ <!-- Needed for pushing the trace config file -->
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="push-file"
+ key="trace_config.textproto"
+ value="/data/misc/perfetto-traces/trace_config.textproto"
+ />
+ <!--Install the content provider automatically when we push some file in sdcard folder.-->
+ <!--Needed to avoid the installation during the test suite.-->
+ <option name="push-file" key="trace_config.textproto" value="/sdcard/sample.textproto"/>
+ </target_preparer>
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest">
+ <option name="package" value="{PACKAGE}"/>
+ <option name="shell-timeout" value="6600s"/>
+ <option name="test-timeout" value="6000s"/>
+ <option name="hidden-api-checks" value="false"/>
+ <option name="device-listeners" value="android.device.collectors.PerfettoListener"/>
+ <!-- PerfettoListener related arguments -->
+ <option name="instrumentation-arg" key="perfetto_config_text_proto" value="true"/>
+ <option name="instrumentation-arg"
+ key="perfetto_config_file"
+ value="trace_config.textproto"
+ />
+ <option name="instrumentation-arg" key="per_run" value="true"/>
+ </test>
+ <!-- Needed for pulling the collected trace config on to the host -->
+ <metrics_collector class="com.android.tradefed.device.metric.FilePullerLogCollector">
+ <option name="pull-pattern-keys" value="perfetto_file_path"/>
+ <option name="directory-keys"
+ value="/data/user/0/com.android.wm.shell.flicker/files"/>
+ <option name="directory-keys"
+ value="/data/user/0/com.android.wm.shell.flicker.bubbles/files"/>
+ <option name="directory-keys"
+ value="/data/user/0/com.android.wm.shell.flicker.pip/files"/>
+ <option name="directory-keys"
+ value="/data/user/0/com.android.wm.shell.flicker.splitscreen/files"/>
+ <option name="directory-keys"
+ value="/data/user/0/com.android.wm.shell.flicker.service/files"/>
+ <option name="collect-on-run-ended-only" value="true"/>
+ <option name="clean-up" value="true"/>
+ </metrics_collector>
+</configuration>
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/OWNERS b/libs/WindowManager/Shell/tests/flicker/splitscreen/OWNERS
index 3ab6a1ee061d..3ab6a1ee061d 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/OWNERS
+++ b/libs/WindowManager/Shell/tests/flicker/splitscreen/OWNERS
diff --git a/libs/WindowManager/Shell/tests/flicker/manifests/AndroidManifestService.xml b/libs/WindowManager/Shell/tests/flicker/splitscreen/res/xml/network_security_config.xml
index c7aca1a72696..4bd9ca049f55 100644
--- a/libs/WindowManager/Shell/tests/flicker/manifests/AndroidManifestService.xml
+++ b/libs/WindowManager/Shell/tests/flicker/splitscreen/res/xml/network_security_config.xml
@@ -1,3 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2023 The Android Open Source Project
~
@@ -14,11 +15,8 @@
~ limitations under the License.
-->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.wm.shell.flicker.service">
-
- <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
- android:targetPackage="com.android.wm.shell.flicker.service"
- android:label="WindowManager Flicker Service Tests">
- </instrumentation>
-</manifest>
+<network-security-config>
+ <domain-config cleartextTrafficPermitted="true">
+ <domain includeSubdomains="true">localhost</domain>
+ </domain-config>
+</network-security-config>
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/CopyContentInSplit.kt b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/CopyContentInSplit.kt
index 6b971699d212..6b971699d212 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/CopyContentInSplit.kt
+++ b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/CopyContentInSplit.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByDivider.kt b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByDivider.kt
index 51588569a8aa..51588569a8aa 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByDivider.kt
+++ b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByDivider.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt
index fc6c2b3d7ce7..fc6c2b3d7ce7 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt
+++ b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DragDividerToResize.kt b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/DragDividerToResize.kt
index 8b1689a9d816..8b1689a9d816 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DragDividerToResize.kt
+++ b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/DragDividerToResize.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromAllApps.kt b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromAllApps.kt
index 99613f39060d..99613f39060d 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromAllApps.kt
+++ b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromAllApps.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromNotification.kt b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromNotification.kt
index 756a7fa4ba98..756a7fa4ba98 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromNotification.kt
+++ b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromNotification.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromShortcut.kt b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromShortcut.kt
index 121b46acdb66..121b46acdb66 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromShortcut.kt
+++ b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromShortcut.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromTaskbar.kt b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromTaskbar.kt
index 99deb9279271..99deb9279271 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromTaskbar.kt
+++ b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromTaskbar.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenFromOverview.kt b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenFromOverview.kt
index 212a4e3649dc..212a4e3649dc 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenFromOverview.kt
+++ b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenFromOverview.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchAppByDoubleTapDivider.kt b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/SwitchAppByDoubleTapDivider.kt
index fac97c8cc8c4..fac97c8cc8c4 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchAppByDoubleTapDivider.kt
+++ b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/SwitchAppByDoubleTapDivider.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromAnotherApp.kt b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromAnotherApp.kt
index 284c32ea110d..284c32ea110d 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromAnotherApp.kt
+++ b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromAnotherApp.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromHome.kt b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromHome.kt
index 9e6448f0bec9..9e6448f0bec9 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromHome.kt
+++ b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromHome.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromRecent.kt b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromRecent.kt
index 8e28712cd993..8e28712cd993 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromRecent.kt
+++ b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromRecent.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairs.kt b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairs.kt
index fb0193b1830d..fb0193b1830d 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairs.kt
+++ b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairs.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairsNoPip.kt b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairsNoPip.kt
index 13875362a1c8..715a533a7bab 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairsNoPip.kt
+++ b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairsNoPip.kt
@@ -62,10 +62,22 @@ class SwitchBetweenSplitPairsNoPip(override val flicker: LegacyFlickerTest) :
get() = {
setup {
tapl.goHome()
- SplitScreenUtils.enterSplit(wmHelper, tapl, device, primaryApp,
- secondaryApp, flicker.scenario.startRotation)
- SplitScreenUtils.enterSplit(wmHelper, tapl, device, thirdApp, pipApp,
- flicker.scenario.startRotation)
+ SplitScreenUtils.enterSplit(
+ wmHelper,
+ tapl,
+ device,
+ primaryApp,
+ secondaryApp,
+ flicker.scenario.startRotation
+ )
+ SplitScreenUtils.enterSplit(
+ wmHelper,
+ tapl,
+ device,
+ thirdApp,
+ pipApp,
+ flicker.scenario.startRotation
+ )
pipApp.enableAutoEnterForPipActivity()
SplitScreenUtils.waitForSplitComplete(wmHelper, thirdApp, pipApp)
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/UnlockKeyguardToSplitScreen.kt b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/UnlockKeyguardToSplitScreen.kt
index f3145c97a6f1..f3145c97a6f1 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/UnlockKeyguardToSplitScreen.kt
+++ b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/UnlockKeyguardToSplitScreen.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/CopyContentInSplitBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/CopyContentInSplitBenchmark.kt
index 3b9e53f9ce04..df1c9a2ec089 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/CopyContentInSplitBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/CopyContentInSplitBenchmark.kt
@@ -39,8 +39,16 @@ abstract class CopyContentInSplitBenchmark(override val flicker: LegacyFlickerTe
protected val popupWindowLayer = ComponentNameMatcher("", "PopupWindow:")
protected val thisTransition: FlickerBuilder.() -> Unit
get() = {
- setup { SplitScreenUtils.enterSplit(wmHelper, tapl, device, primaryApp,
- textEditApp, flicker.scenario.startRotation) }
+ setup {
+ SplitScreenUtils.enterSplit(
+ wmHelper,
+ tapl,
+ device,
+ primaryApp,
+ textEditApp,
+ flicker.scenario.startRotation
+ )
+ }
transitions {
SplitScreenUtils.copyContentInSplit(
instrumentation,
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByDividerBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByDividerBenchmark.kt
index 5fdde3ad23d2..d01eab060263 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByDividerBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByDividerBenchmark.kt
@@ -35,8 +35,16 @@ abstract class DismissSplitScreenByDividerBenchmark(override val flicker: Legacy
SplitScreenBase(flicker) {
protected val thisTransition: FlickerBuilder.() -> Unit
get() = {
- setup { SplitScreenUtils.enterSplit(wmHelper, tapl, device, primaryApp,
- secondaryApp, flicker.scenario.startRotation) }
+ setup {
+ SplitScreenUtils.enterSplit(
+ wmHelper,
+ tapl,
+ device,
+ primaryApp,
+ secondaryApp,
+ flicker.scenario.startRotation
+ )
+ }
transitions {
if (tapl.isTablet) {
SplitScreenUtils.dragDividerToDismissSplit(
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByGoHomeBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByGoHomeBenchmark.kt
index b7f6bfe7efd6..e36bd33bd1fd 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByGoHomeBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByGoHomeBenchmark.kt
@@ -36,8 +36,14 @@ abstract class DismissSplitScreenByGoHomeBenchmark(override val flicker: LegacyF
protected val thisTransition: FlickerBuilder.() -> Unit
get() = {
setup {
- SplitScreenUtils.enterSplit(wmHelper, tapl, device, primaryApp, secondaryApp,
- flicker.scenario.startRotation)
+ SplitScreenUtils.enterSplit(
+ wmHelper,
+ tapl,
+ device,
+ primaryApp,
+ secondaryApp,
+ flicker.scenario.startRotation
+ )
}
transitions {
tapl.goHome()
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DragDividerToResizeBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/DragDividerToResizeBenchmark.kt
index bb2a7aabed1b..050d389e978c 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DragDividerToResizeBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/DragDividerToResizeBenchmark.kt
@@ -37,8 +37,16 @@ abstract class DragDividerToResizeBenchmark(override val flicker: LegacyFlickerT
SplitScreenBase(flicker) {
protected val thisTransition: FlickerBuilder.() -> Unit
get() = {
- setup { SplitScreenUtils.enterSplit(wmHelper, tapl, device, primaryApp,
- secondaryApp, flicker.scenario.startRotation) }
+ setup {
+ SplitScreenUtils.enterSplit(
+ wmHelper,
+ tapl,
+ device,
+ primaryApp,
+ secondaryApp,
+ flicker.scenario.startRotation
+ )
+ }
transitions { SplitScreenUtils.dragDividerToResizeAndWait(device, wmHelper) }
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromAllAppsBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromAllAppsBenchmark.kt
index 394864ad9d4d..394864ad9d4d 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromAllAppsBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromAllAppsBenchmark.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromNotificationBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromNotificationBenchmark.kt
index cd3fbab1497b..cd3fbab1497b 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromNotificationBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromNotificationBenchmark.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromShortcutBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromShortcutBenchmark.kt
index 3b3be84f9841..3b3be84f9841 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromShortcutBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromShortcutBenchmark.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromTaskbarBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromTaskbarBenchmark.kt
index eff355987cc0..eff355987cc0 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromTaskbarBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromTaskbarBenchmark.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenFromOverviewBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenFromOverviewBenchmark.kt
index 5e5e7d7fc3c9..5e5e7d7fc3c9 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenFromOverviewBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenFromOverviewBenchmark.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SplitScreenBase.kt b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/SplitScreenBase.kt
index a0e437c25aa7..a0e437c25aa7 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SplitScreenBase.kt
+++ b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/SplitScreenBase.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchAppByDoubleTapDividerBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchAppByDoubleTapDividerBenchmark.kt
index 46b0bd226daf..e39c3c93d79a 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchAppByDoubleTapDividerBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchAppByDoubleTapDividerBenchmark.kt
@@ -39,8 +39,16 @@ abstract class SwitchAppByDoubleTapDividerBenchmark(override val flicker: Legacy
SplitScreenBase(flicker) {
protected val thisTransition: FlickerBuilder.() -> Unit
get() = {
- setup { SplitScreenUtils.enterSplit(wmHelper, tapl, device, primaryApp,
- secondaryApp, flicker.scenario.startRotation) }
+ setup {
+ SplitScreenUtils.enterSplit(
+ wmHelper,
+ tapl,
+ device,
+ primaryApp,
+ secondaryApp,
+ flicker.scenario.startRotation
+ )
+ }
transitions {
SplitScreenUtils.doubleTapDividerToSwitch(device)
wmHelper.StateSyncBuilder().withAppTransitionIdle().waitForAndVerify()
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromAnotherAppBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromAnotherAppBenchmark.kt
index baf76932c7ac..32284ba41aee 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromAnotherAppBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromAnotherAppBenchmark.kt
@@ -39,8 +39,14 @@ abstract class SwitchBackToSplitFromAnotherAppBenchmark(override val flicker: Le
protected val thisTransition: FlickerBuilder.() -> Unit
get() = {
setup {
- SplitScreenUtils.enterSplit(wmHelper, tapl, device, primaryApp,
- secondaryApp, flicker.scenario.startRotation)
+ SplitScreenUtils.enterSplit(
+ wmHelper,
+ tapl,
+ device,
+ primaryApp,
+ secondaryApp,
+ flicker.scenario.startRotation
+ )
thirdApp.launchViaIntent(wmHelper)
wmHelper.StateSyncBuilder().withWindowSurfaceAppeared(thirdApp).waitForAndVerify()
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromHomeBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromHomeBenchmark.kt
index 33b55f1a57d8..a926ec903f58 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromHomeBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromHomeBenchmark.kt
@@ -37,8 +37,14 @@ abstract class SwitchBackToSplitFromHomeBenchmark(override val flicker: LegacyFl
protected val thisTransition: FlickerBuilder.() -> Unit
get() = {
setup {
- SplitScreenUtils.enterSplit(wmHelper, tapl, device, primaryApp,
- secondaryApp, flicker.scenario.startRotation)
+ SplitScreenUtils.enterSplit(
+ wmHelper,
+ tapl,
+ device,
+ primaryApp,
+ secondaryApp,
+ flicker.scenario.startRotation
+ )
tapl.goHome()
wmHelper.StateSyncBuilder().withHomeActivityVisible().waitForAndVerify()
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromRecentBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromRecentBenchmark.kt
index b79dfb5f0665..d2e1d5294aa1 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromRecentBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromRecentBenchmark.kt
@@ -37,8 +37,14 @@ abstract class SwitchBackToSplitFromRecentBenchmark(override val flicker: Legacy
protected val thisTransition: FlickerBuilder.() -> Unit
get() = {
setup {
- SplitScreenUtils.enterSplit(wmHelper, tapl, device, primaryApp,
- secondaryApp, flicker.scenario.startRotation)
+ SplitScreenUtils.enterSplit(
+ wmHelper,
+ tapl,
+ device,
+ primaryApp,
+ secondaryApp,
+ flicker.scenario.startRotation
+ )
tapl.goHome()
wmHelper.StateSyncBuilder().withHomeActivityVisible().waitForAndVerify()
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBetweenSplitPairsBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBetweenSplitPairsBenchmark.kt
index 0204d754585a..9d6b25174c13 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBetweenSplitPairsBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBetweenSplitPairsBenchmark.kt
@@ -39,10 +39,22 @@ abstract class SwitchBetweenSplitPairsBenchmark(override val flicker: LegacyFlic
protected val thisTransition: FlickerBuilder.() -> Unit
get() = {
setup {
- SplitScreenUtils.enterSplit(wmHelper, tapl, device, primaryApp,
- secondaryApp, flicker.scenario.startRotation)
- SplitScreenUtils.enterSplit(wmHelper, tapl, device, thirdApp, fourthApp,
- flicker.scenario.startRotation)
+ SplitScreenUtils.enterSplit(
+ wmHelper,
+ tapl,
+ device,
+ primaryApp,
+ secondaryApp,
+ flicker.scenario.startRotation
+ )
+ SplitScreenUtils.enterSplit(
+ wmHelper,
+ tapl,
+ device,
+ thirdApp,
+ fourthApp,
+ flicker.scenario.startRotation
+ )
SplitScreenUtils.waitForSplitComplete(wmHelper, thirdApp, fourthApp)
}
transitions {
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/UnlockKeyguardToSplitScreenBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/UnlockKeyguardToSplitScreenBenchmark.kt
index e71834de7123..e71834de7123 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/UnlockKeyguardToSplitScreenBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/splitscreen/src/com/android/wm/shell/flicker/splitscreen/benchmark/UnlockKeyguardToSplitScreenBenchmark.kt
diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/trace_config/trace_config.textproto b/libs/WindowManager/Shell/tests/flicker/splitscreen/trace_config/trace_config.textproto
new file mode 100644
index 000000000000..406ada97a07d
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/splitscreen/trace_config/trace_config.textproto
@@ -0,0 +1,75 @@
+# Copyright (C) 2023 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# proto-message: TraceConfig
+
+# Enable periodic flushing of the trace buffer into the output file.
+write_into_file: true
+
+# Writes the userspace buffer into the file every 1s.
+file_write_period_ms: 2500
+
+# See b/126487238 - we need to guarantee ordering of events.
+flush_period_ms: 30000
+
+# The trace buffers needs to be big enough to hold |file_write_period_ms| of
+# trace data. The trace buffer sizing depends on the number of trace categories
+# enabled and the device activity.
+
+# RSS events
+buffers: {
+ size_kb: 63488
+ fill_policy: RING_BUFFER
+}
+
+data_sources {
+ config {
+ name: "linux.process_stats"
+ target_buffer: 0
+ # polled per-process memory counters and process/thread names.
+ # If you don't want the polled counters, remove the "process_stats_config"
+ # section, but keep the data source itself as it still provides on-demand
+ # thread/process naming for ftrace data below.
+ process_stats_config {
+ scan_all_processes_on_start: true
+ }
+ }
+}
+
+data_sources: {
+ config {
+ name: "linux.ftrace"
+ ftrace_config {
+ ftrace_events: "ftrace/print"
+ ftrace_events: "task/task_newtask"
+ ftrace_events: "task/task_rename"
+ atrace_categories: "ss"
+ atrace_categories: "wm"
+ atrace_categories: "am"
+ atrace_categories: "aidl"
+ atrace_categories: "input"
+ atrace_categories: "binder_driver"
+ atrace_categories: "sched_process_exit"
+ atrace_apps: "com.android.server.wm.flicker.testapp"
+ atrace_apps: "com.android.systemui"
+ atrace_apps: "com.android.wm.shell.flicker"
+ atrace_apps: "com.android.wm.shell.flicker.other"
+ atrace_apps: "com.android.wm.shell.flicker.bubbles"
+ atrace_apps: "com.android.wm.shell.flicker.pip"
+ atrace_apps: "com.android.wm.shell.flicker.splitscreen"
+ atrace_apps: "com.google.android.apps.nexuslauncher"
+ }
+ }
+}
+
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/BaseTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/BaseTest.kt
index 735fbfb341f5..568650d71872 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/BaseTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/BaseTest.kt
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/SplitScreenUtils.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/SplitScreenUtils.kt
index 6b3cfaf33c05..c31b9e2c22c7 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/SplitScreenUtils.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/SplitScreenUtils.kt
@@ -24,6 +24,7 @@ import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.common.traces.component.IComponentMatcher
import android.tools.common.traces.component.IComponentNameMatcher
import android.tools.device.apphelpers.StandardAppHelper
+import android.tools.device.flicker.rules.ChangeDisplayOrientationRule
import android.tools.device.traces.parsers.WindowManagerStateHelper
import android.tools.device.traces.parsers.toFlickerComponent
import android.view.InputDevice
@@ -42,7 +43,6 @@ import com.android.server.wm.flicker.helpers.SimpleAppHelper
import com.android.server.wm.flicker.testapp.ActivityOptions
import com.android.server.wm.flicker.testapp.ActivityOptions.SplitScreen.Primary
import org.junit.Assert.assertNotNull
-import android.tools.device.flicker.rules.ChangeDisplayOrientationRule
object SplitScreenUtils {
private const val TIMEOUT_MS = 3_000L
@@ -153,15 +153,10 @@ object SplitScreenUtils {
} else {
val rotationCheckEnabled = tapl.getExpectedRotationCheckEnabled()
tapl.setExpectedRotationCheckEnabled(false) // disable rotation check to enter overview
- val home = tapl.workspace
- .switchToOverview()
+ val home = tapl.workspace.switchToOverview()
tapl.setExpectedRotationCheckEnabled(rotationCheckEnabled) // restore rotation checks
ChangeDisplayOrientationRule.setRotation(rotation)
- home.currentTask
- .tapMenu()
- .tapSplitMenuItem()
- .currentTask
- .open()
+ home.currentTask.tapMenu().tapSplitMenuItem().currentTask.open()
}
SystemClock.sleep(TIMEOUT_MS)
}
diff --git a/libs/hwui/tests/common/TestUtils.cpp b/libs/hwui/tests/common/TestUtils.cpp
index a4890ede8faa..ad963dd913cf 100644
--- a/libs/hwui/tests/common/TestUtils.cpp
+++ b/libs/hwui/tests/common/TestUtils.cpp
@@ -19,6 +19,8 @@
#include "DeferredLayerUpdater.h"
#include "hwui/Paint.h"
+#include <hwui/MinikinSkia.h>
+#include <hwui/Typeface.h>
#include <minikin/Layout.h>
#include <pipeline/skia/SkiaOpenGLPipeline.h>
#include <pipeline/skia/SkiaVulkanPipeline.h>
@@ -179,5 +181,13 @@ SkRect TestUtils::getLocalClipBounds(const SkCanvas* canvas) {
return outlineInLocalCoord;
}
+SkFont TestUtils::defaultFont() {
+ const std::shared_ptr<minikin::MinikinFont>& minikinFont =
+ Typeface::resolveDefault(nullptr)->fFontCollection->getFamilyAt(0)->getFont(0)->baseTypeface();
+ SkTypeface* skTypeface = reinterpret_cast<const MinikinFontSkia*>(minikinFont.get())->GetSkTypeface();
+ LOG_ALWAYS_FATAL_IF(skTypeface == nullptr);
+ return SkFont(sk_ref_sp(skTypeface));
+}
+
} /* namespace uirenderer */
} /* namespace android */
diff --git a/libs/hwui/tests/common/TestUtils.h b/libs/hwui/tests/common/TestUtils.h
index ffc664c2e1bc..0ede902b1b95 100644
--- a/libs/hwui/tests/common/TestUtils.h
+++ b/libs/hwui/tests/common/TestUtils.h
@@ -30,6 +30,7 @@
#include <SkBitmap.h>
#include <SkColor.h>
+#include <SkFont.h>
#include <SkImageInfo.h>
#include <SkRefCnt.h>
@@ -353,6 +354,8 @@ public:
static CallCounts& countsForFunctor(int functor) { return sMockFunctorCounts[functor]; }
+ static SkFont defaultFont();
+
private:
static std::unordered_map<int, CallCounts> sMockFunctorCounts;
diff --git a/libs/hwui/tests/common/scenes/ListViewAnimation.cpp b/libs/hwui/tests/common/scenes/ListViewAnimation.cpp
index 4a5d9468cd88..97d4c8214cde 100644
--- a/libs/hwui/tests/common/scenes/ListViewAnimation.cpp
+++ b/libs/hwui/tests/common/scenes/ListViewAnimation.cpp
@@ -57,7 +57,7 @@ class ListViewAnimation : public TestListViewSceneBase {
128 * 3;
paint.setColor(bgDark ? Color::White : Color::Grey_700);
- SkFont font;
+ SkFont font = TestUtils::defaultFont();
font.setSize(size / 2);
char charToShow = 'A' + (rand() % 26);
const SkPoint pos = {SkIntToScalar(size / 2),
diff --git a/libs/hwui/tests/common/scenes/StretchyListViewAnimation.cpp b/libs/hwui/tests/common/scenes/StretchyListViewAnimation.cpp
index bb95490c1d39..159541c11c64 100644
--- a/libs/hwui/tests/common/scenes/StretchyListViewAnimation.cpp
+++ b/libs/hwui/tests/common/scenes/StretchyListViewAnimation.cpp
@@ -102,7 +102,7 @@ private:
128 * 3;
paint.setColor(bgDark ? Color::White : Color::Grey_700);
- SkFont font;
+ SkFont font = TestUtils::defaultFont();
font.setSize(size / 2);
char charToShow = 'A' + (rand() % 26);
const SkPoint pos = {SkIntToScalar(size / 2),
diff --git a/location/api/system-lint-baseline.txt b/location/api/system-lint-baseline.txt
index a5e5752d7cf5..043a082409ac 100644
--- a/location/api/system-lint-baseline.txt
+++ b/location/api/system-lint-baseline.txt
@@ -9,3 +9,9 @@ SamShouldBeLast: android.location.LocationManager#requestSingleUpdate(String, an
SAM-compatible parameters (such as parameter 2, "listener", in android.location.LocationManager.requestSingleUpdate) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
SamShouldBeLast: android.location.LocationManager#requestSingleUpdate(android.location.Criteria, android.location.LocationListener, android.os.Looper):
SAM-compatible parameters (such as parameter 2, "listener", in android.location.LocationManager.requestSingleUpdate) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
+
+
+UnflaggedApi: android.location.GnssMeasurementRequest#getWorkSource():
+ New API must be flagged with @FlaggedApi: method android.location.GnssMeasurementRequest.getWorkSource()
+UnflaggedApi: android.location.GnssMeasurementRequest.Builder#setWorkSource(android.os.WorkSource):
+ New API must be flagged with @FlaggedApi: method android.location.GnssMeasurementRequest.Builder.setWorkSource(android.os.WorkSource)
diff --git a/media/java/android/media/projection/IMediaProjectionManager.aidl b/media/java/android/media/projection/IMediaProjectionManager.aidl
index 24efbd14bc02..a7ec6c692416 100644
--- a/media/java/android/media/projection/IMediaProjectionManager.aidl
+++ b/media/java/android/media/projection/IMediaProjectionManager.aidl
@@ -212,4 +212,9 @@ interface IMediaProjectionManager {
@JavaPassthrough(annotation = "@android.annotation.RequiresPermission(android.Manifest"
+ ".permission.MANAGE_MEDIA_PROJECTION)")
oneway void notifyAppSelectorDisplayed(int hostUid);
+
+ @EnforcePermission("MANAGE_MEDIA_PROJECTION")
+ @JavaPassthrough(annotation = "@android.annotation.RequiresPermission(android.Manifest"
+ + ".permission.MANAGE_MEDIA_PROJECTION)")
+ void notifyWindowingModeChanged(int contentToRecord, int targetUid, int windowingMode);
}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java b/packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java
index 1088acef0fb0..4992ef1e1c00 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java
@@ -290,7 +290,14 @@ public class InstallInstalling extends AlertActivity {
broadcastIntent,
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);
- session.commit(pendingIntent.getIntentSender());
+ try {
+ session.commit(pendingIntent.getIntentSender());
+ } catch (Exception e) {
+ Log.e(LOG_TAG, "Cannot install package: ", e);
+ launchFailure(PackageInstaller.STATUS_FAILURE,
+ PackageManager.INSTALL_FAILED_INTERNAL_ERROR, null);
+ return;
+ }
mCancelButton.setEnabled(false);
setFinishOnTouchOutside(false);
} else {
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 6eaabbb389c2..96029c813528 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -202,10 +202,18 @@
<string name="bluetooth_active_battery_level_untethered">Active, L: <xliff:g id="battery_level_as_percentage" example="25%">%1$s</xliff:g> battery, R: <xliff:g id="battery_level_as_percentage" example="25%">%2$s</xliff:g> battery</string>
<!-- Connected devices settings. Message when Bluetooth is connected but not in use, showing remote device battery level. [CHAR LIMIT=NONE] -->
<string name="bluetooth_battery_level"><xliff:g id="battery_level_as_percentage">%1$s</xliff:g> battery</string>
+ <!-- Connected devices settings. Message on TV when Bluetooth is connected but not in use, showing remote device battery level. [CHAR LIMIT=NONE] -->
+ <string name="tv_bluetooth_battery_level">Battery <xliff:g id="battery_level_as_percentage">%1$s</xliff:g></string>
<!-- Connected devices settings. Message when Bluetooth is connected but not in use, showing remote device battery level for untethered headset. [CHAR LIMIT=NONE] -->
<string name="bluetooth_battery_level_untethered">L: <xliff:g id="battery_level_as_percentage" example="25%">%1$s</xliff:g> battery, R: <xliff:g id="battery_level_as_percentage" example="25%">%2$s</xliff:g> battery</string>
+ <!-- Connected devices settings. Message when Bluetooth is connected but not in use, showing remote device battery level for the left part of the untethered headset. [CHAR LIMIT=NONE] -->
+ <string name="bluetooth_battery_level_untethered_left">Left <xliff:g id="battery_level_as_percentage" example="25%">%1$s</xliff:g></string>
+ <!-- Connected devices settings. Message when Bluetooth is connected but not in use, showing remote device battery level for the right part of the untethered headset. [CHAR LIMIT=NONE] -->
+ <string name="bluetooth_battery_level_untethered_right">Right <xliff:g id="battery_level_as_percentage" example="25%">%1$s</xliff:g></string>
<!-- Connected devices settings. Message when Bluetooth is connected and active but no battery information, showing remote device status. [CHAR LIMIT=NONE] -->
<string name="bluetooth_active_no_battery_level">Active</string>
+ <!-- Connected devices settings. Message shown when bluetooth device is disconnected but is a known, previously connected device [CHAR LIMIT=NONE] -->
+ <string name="bluetooth_saved_device">Saved</string>
<!-- Connected device settings. Message when the left-side hearing aid device is active. [CHAR LIMIT=NONE] -->
<string name="bluetooth_hearing_aid_left_active">Active, left only</string>
@@ -1019,6 +1027,13 @@
<!-- Settings item title to select whether to disable cache for transcoding. [CHAR LIMIT=85] -->
<string name="transcode_disable_cache">Disable transcoding cache</string>
+ <!-- Developer settings title: widevine settings screen. [CHAR LIMIT=50] -->
+ <string name="widevine_settings_title">Widevine settings</string>
+ <!-- Developer settings title: select whether to enable Force L3 fallback. [CHAR LIMIT=50] -->
+ <string name="force_l3_fallback_title">Force L3 fallback</string>
+ <!-- Developer settings summary: select whether to enable Force L3 fallback.[CHAR LIMIT=NONE] -->
+ <string name="force_l3_fallback_summary">Select to force L3 fallback</string>
+
<!-- Services settings screen, setting option name for the user to go to the screen to view running services -->
<string name="runningservices_settings_title">Running services</string>
<!-- Services settings screen, setting option summary for the user to go to the screen to view running services -->
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index 66efb1ceaf19..24083b682397 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -35,7 +35,9 @@ import android.os.Looper;
import android.os.Message;
import android.os.ParcelUuid;
import android.os.SystemClock;
+import android.text.SpannableStringBuilder;
import android.text.TextUtils;
+import android.text.style.ForegroundColorSpan;
import android.util.Log;
import android.util.LruCache;
import android.util.Pair;
@@ -46,6 +48,7 @@ import androidx.annotation.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
import com.android.settingslib.R;
import com.android.settingslib.Utils;
+import com.android.settingslib.media.flags.Flags;
import com.android.settingslib.utils.ThreadUtils;
import com.android.settingslib.widget.AdaptiveOutlineDrawable;
@@ -83,6 +86,12 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
private static final long MAX_LEAUDIO_DELAY_FOR_AUTO_CONNECT = 30000;
private static final long MAX_MEDIA_PROFILE_CONNECT_DELAY = 60000;
+ private static final int DEFAULT_LOW_BATTERY_THRESHOLD = 20;
+
+ // To be used instead of a resource id to indicate that low battery states should not be
+ // changed to a different color.
+ private static final int SUMMARY_NO_COLOR_FOR_LOW_BATTERY = 0;
+
private final Context mContext;
private final BluetoothAdapter mLocalAdapter;
private final LocalBluetoothProfileManager mProfileManager;
@@ -1189,6 +1198,46 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
* @param shortSummary {@code true} if need to return short version summary
*/
public String getConnectionSummary(boolean shortSummary) {
+ CharSequence summary = getConnectionSummary(shortSummary, false /* isTvSummary */,
+ SUMMARY_NO_COLOR_FOR_LOW_BATTERY);
+ if (summary != null) {
+ return summary.toString();
+ }
+ return null;
+ }
+
+ /**
+ * Returns android tv string that describes the connection state of this device.
+ */
+ public CharSequence getTvConnectionSummary() {
+ return getTvConnectionSummary(SUMMARY_NO_COLOR_FOR_LOW_BATTERY);
+ }
+
+ /**
+ * Returns android tv string that describes the connection state of this device, with low
+ * battery states highlighted in color.
+ *
+ * @param lowBatteryColorRes - resource id for the color that should be used for the part of the
+ * CharSequence that contains low battery information.
+ */
+ public CharSequence getTvConnectionSummary(int lowBatteryColorRes) {
+ return getConnectionSummary(false /* shortSummary */, true /* isTvSummary */,
+ lowBatteryColorRes);
+ }
+
+ /**
+ * Return summary that describes connection state of this device. Summary depends on:
+ * 1. Whether device has battery info
+ * 2. Whether device is in active usage(or in phone call)
+ *
+ * @param shortSummary {@code true} if need to return short version summary
+ * @param isTvSummary {@code true} if the summary should be TV specific
+ * @param lowBatteryColorRes Resource id of the color to be used for low battery strings. Use
+ * {@link SUMMARY_NO_COLOR_FOR_LOW_BATTERY} if no separate color
+ * should be used.
+ */
+ private CharSequence getConnectionSummary(boolean shortSummary, boolean isTvSummary,
+ int lowBatteryColorRes) {
boolean profileConnected = false; // Updated as long as BluetoothProfile is connected
boolean a2dpConnected = true; // A2DP is connected
boolean hfpConnected = true; // HFP is connected
@@ -1315,17 +1364,82 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
}
}
- if (stringRes != R.string.bluetooth_pairing
- || getBondState() == BluetoothDevice.BOND_BONDING) {
- if (isTwsBatteryAvailable(leftBattery, rightBattery)) {
- return mContext.getString(stringRes, Utils.formatPercentage(leftBattery),
+ if (stringRes == R.string.bluetooth_pairing
+ && getBondState() != BluetoothDevice.BOND_BONDING) {
+ return null;
+ }
+
+ boolean summaryIncludesBatteryLevel = stringRes == R.string.bluetooth_battery_level
+ || stringRes == R.string.bluetooth_active_battery_level
+ || stringRes == R.string.bluetooth_active_battery_level_untethered
+ || stringRes == R.string.bluetooth_battery_level_untethered;
+ if (isTvSummary && summaryIncludesBatteryLevel && Flags.enableTvMediaOutputDialog()) {
+ return getTvBatterySummary(batteryLevel, leftBattery, rightBattery, lowBatteryColorRes);
+ }
+
+ if (isTwsBatteryAvailable(leftBattery, rightBattery)) {
+ return mContext.getString(stringRes, Utils.formatPercentage(leftBattery),
+ Utils.formatPercentage(rightBattery));
+ } else {
+ return mContext.getString(stringRes, batteryLevelPercentageString);
+ }
+ }
+
+ private CharSequence getTvBatterySummary(int mainBattery, int leftBattery, int rightBattery,
+ int lowBatteryColorRes) {
+ // Since there doesn't seem to be a way to use format strings to add the
+ // percentages and also mark which part of the string is left and right to color
+ // them, we are using one string resource per battery.
+ Resources res = mContext.getResources();
+ SpannableStringBuilder spannableBuilder = new SpannableStringBuilder();
+ if (leftBattery >= 0 || rightBattery >= 0) {
+ // Not switching the left and right for RTL to keep the left earbud always on
+ // the left.
+ if (leftBattery >= 0) {
+ String left = res.getString(
+ R.string.bluetooth_battery_level_untethered_left,
+ Utils.formatPercentage(leftBattery));
+ addBatterySpan(spannableBuilder, left, isBatteryLow(leftBattery,
+ BluetoothDevice.METADATA_UNTETHERED_LEFT_LOW_BATTERY_THRESHOLD),
+ lowBatteryColorRes);
+ }
+ if (rightBattery >= 0) {
+ if (!spannableBuilder.isEmpty()) {
+ spannableBuilder.append(" ");
+ }
+ String right = res.getString(
+ R.string.bluetooth_battery_level_untethered_right,
Utils.formatPercentage(rightBattery));
- } else {
- return mContext.getString(stringRes, batteryLevelPercentageString);
+ addBatterySpan(spannableBuilder, right, isBatteryLow(rightBattery,
+ BluetoothDevice.METADATA_UNTETHERED_RIGHT_LOW_BATTERY_THRESHOLD),
+ lowBatteryColorRes);
}
} else {
- return null;
+ addBatterySpan(spannableBuilder, res.getString(R.string.tv_bluetooth_battery_level,
+ Utils.formatPercentage(mainBattery)),
+ isBatteryLow(mainBattery, BluetoothDevice.METADATA_MAIN_LOW_BATTERY_THRESHOLD),
+ lowBatteryColorRes);
+ }
+ return spannableBuilder;
+ }
+
+ private void addBatterySpan(SpannableStringBuilder builder,
+ String batteryString, boolean lowBattery, int lowBatteryColorRes) {
+ if (lowBattery && lowBatteryColorRes != SUMMARY_NO_COLOR_FOR_LOW_BATTERY) {
+ builder.append(batteryString,
+ new ForegroundColorSpan(mContext.getResources().getColor(lowBatteryColorRes)),
+ 0 /* flags */);
+ } else {
+ builder.append(batteryString);
+ }
+ }
+
+ private boolean isBatteryLow(int batteryLevel, int metadataKey) {
+ int lowBatteryThreshold = BluetoothUtils.getIntMetaData(mDevice, metadataKey);
+ if (lowBatteryThreshold <= 0) {
+ lowBatteryThreshold = DEFAULT_LOW_BATTERY_THRESHOLD;
}
+ return batteryLevel <= lowBatteryThreshold;
}
private boolean isTwsBatteryAvailable(int leftBattery, int rightBattery) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaDevice.java
index ed518f79156b..9560b8dc802e 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaDevice.java
@@ -72,6 +72,13 @@ public class BluetoothMediaDevice extends MediaDevice {
}
@Override
+ public CharSequence getSummaryForTv(int lowBatteryColorRes) {
+ return isConnected() || mCachedDevice.isBusy()
+ ? mCachedDevice.getTvConnectionSummary(lowBatteryColorRes)
+ : mContext.getString(R.string.bluetooth_saved_device);
+ }
+
+ @Override
public int getSelectionBehavior() {
// We don't allow apps to override the selection behavior of system routes.
return SELECTION_BEHAVIOR_TRANSFER;
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java
index 8085c998abea..c8e4c0c93789 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java
@@ -208,6 +208,17 @@ public abstract class MediaDevice implements Comparable<MediaDevice> {
public abstract String getSummary();
/**
+ * Get summary from MediaDevice for TV with low batter states in a different color if
+ * applicable.
+ *
+ * @param lowBatteryColorRes Color resource for the part of the CharSequence that describes a
+ * low battery state.
+ */
+ public CharSequence getSummaryForTv(int lowBatteryColorRes) {
+ return getSummary();
+ }
+
+ /**
* Get icon of MediaDevice.
*
* @return drawable of icon.
diff --git a/packages/SettingsLib/src/com/android/settingslib/qrcode/QrCamera.java b/packages/SettingsLib/src/com/android/settingslib/qrcode/QrCamera.java
index e65109003856..ae17acb5104b 100644
--- a/packages/SettingsLib/src/com/android/settingslib/qrcode/QrCamera.java
+++ b/packages/SettingsLib/src/com/android/settingslib/qrcode/QrCamera.java
@@ -116,8 +116,13 @@ public class QrCamera extends Handler {
mDecodeTask = null;
}
if (mCamera != null) {
- mCamera.stopPreview();
- releaseCamera();
+ try {
+ mCamera.stopPreview();
+ releaseCamera();
+ } catch (RuntimeException e) {
+ Log.e(TAG, "Stop previewing camera failed:" + e);
+ mCamera = null;
+ }
}
}
diff --git a/packages/SettingsLib/tests/robotests/Android.bp b/packages/SettingsLib/tests/robotests/Android.bp
index 2d875cf7244d..732c33615dd0 100644
--- a/packages/SettingsLib/tests/robotests/Android.bp
+++ b/packages/SettingsLib/tests/robotests/Android.bp
@@ -49,6 +49,8 @@ android_robolectric_test {
"androidx.fragment_fragment",
"androidx.test.core",
"androidx.core_core",
+ "flag-junit",
+ "settingslib_flags_lib",
"testng", // TODO: remove once JUnit on Android provides assertThrows
],
java_resource_dirs: ["config"],
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
index 85efe69529b4..ed545ab5c81d 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
@@ -35,13 +35,18 @@ import android.bluetooth.BluetoothStatusCodes;
import android.content.Context;
import android.graphics.drawable.BitmapDrawable;
import android.media.AudioManager;
+import android.platform.test.flag.junit.SetFlagsRule;
+import android.text.Spannable;
+import android.text.style.ForegroundColorSpan;
import android.util.LruCache;
import com.android.settingslib.R;
+import com.android.settingslib.media.flags.Flags;
import com.android.settingslib.testutils.shadow.ShadowBluetoothAdapter;
import com.android.settingslib.widget.AdaptiveOutlineDrawable;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -60,10 +65,13 @@ public class CachedBluetoothDeviceTest {
private static final String DEVICE_ALIAS_NEW = "TestAliasNew";
private static final String TWS_BATTERY_LEFT = "15";
private static final String TWS_BATTERY_RIGHT = "25";
+ private static final String TWS_LOW_BATTERY_THRESHOLD_LOW = "10";
+ private static final String TWS_LOW_BATTERY_THRESHOLD_HIGH = "25";
private static final short RSSI_1 = 10;
private static final short RSSI_2 = 11;
private static final boolean JUSTDISCOVERED_1 = true;
private static final boolean JUSTDISCOVERED_2 = false;
+ private static final int LOW_BATTERY_COLOR = android.R.color.holo_red_dark;
@Mock
private LocalBluetoothProfileManager mProfileManager;
@Mock
@@ -89,9 +97,13 @@ public class CachedBluetoothDeviceTest {
private int mBatteryLevel = BluetoothDevice.BATTERY_LEVEL_UNKNOWN;
private ShadowBluetoothAdapter mShadowBluetoothAdapter;
+ @Rule
+ public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
+ mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_TV_MEDIA_OUTPUT_DIALOG);
mContext = RuntimeEnvironment.application;
mAudioManager = mContext.getSystemService(AudioManager.class);
mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter());
@@ -179,6 +191,17 @@ public class CachedBluetoothDeviceTest {
}
@Test
+ public void getTvConnectionSummary_testProfilesInactive_returnPairing() {
+ // Arrange:
+ // Bond State: Bonding
+ when(mDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDING);
+
+ // Act & Assert:
+ // Get "Pairing…" result without Battery Level.
+ assertThat(mCachedDevice.getTvConnectionSummary().toString()).isEqualTo("Pairing…");
+ }
+
+ @Test
public void getConnectionSummary_testSingleProfileConnectDisconnect() {
// Test without battery level
// Set PAN profile to be connected and test connection state summary
@@ -212,6 +235,39 @@ public class CachedBluetoothDeviceTest {
}
@Test
+ public void getTvConnectionSummary_testSingleProfileConnectDisconnect() {
+ // Test without battery level
+ // Set PAN profile to be connected and test connection state summary
+ updateProfileStatus(mPanProfile, BluetoothProfile.STATE_CONNECTED);
+ assertThat(mCachedDevice.getTvConnectionSummary()).isNull();
+
+ // Set PAN profile to be disconnected and test connection state summary
+ updateProfileStatus(mPanProfile, BluetoothProfile.STATE_DISCONNECTED);
+ assertThat(mCachedDevice.getTvConnectionSummary()).isNull();
+
+ // Test with battery level
+ mBatteryLevel = 10;
+ // Set PAN profile to be connected and test connection state summary
+ updateProfileStatus(mPanProfile, BluetoothProfile.STATE_CONNECTED);
+ assertThat(mCachedDevice.getTvConnectionSummary().toString()).isEqualTo("Battery 10%");
+
+ // Set PAN profile to be disconnected and test connection state summary
+ updateProfileStatus(mPanProfile, BluetoothProfile.STATE_DISCONNECTED);
+ assertThat(mCachedDevice.getTvConnectionSummary()).isNull();
+
+ // Test with BluetoothDevice.BATTERY_LEVEL_UNKNOWN battery level
+ mBatteryLevel = BluetoothDevice.BATTERY_LEVEL_UNKNOWN;
+
+ // Set PAN profile to be connected and test connection state summary
+ updateProfileStatus(mPanProfile, BluetoothProfile.STATE_CONNECTED);
+ assertThat(mCachedDevice.getTvConnectionSummary()).isNull();
+
+ // Set PAN profile to be disconnected and test connection state summary
+ updateProfileStatus(mPanProfile, BluetoothProfile.STATE_DISCONNECTED);
+ assertThat(mCachedDevice.getTvConnectionSummary()).isNull();
+ }
+
+ @Test
public void getConnectionSummary_testMultipleProfileConnectDisconnect() {
mBatteryLevel = 10;
@@ -243,6 +299,37 @@ public class CachedBluetoothDeviceTest {
}
@Test
+ public void getTvConnectionSummary_testMultipleProfileConnectDisconnect() {
+ mBatteryLevel = 10;
+
+ // Set HFP, A2DP and PAN profile to be connected and test connection state summary
+ updateProfileStatus(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
+ updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
+ updateProfileStatus(mPanProfile, BluetoothProfile.STATE_CONNECTED);
+ assertThat(mCachedDevice.getTvConnectionSummary().toString()).isEqualTo("Battery 10%");
+
+ // Disconnect HFP only and test connection state summary
+ updateProfileStatus(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
+ assertThat(mCachedDevice.getTvConnectionSummary().toString()).isEqualTo(
+ "Battery 10%");
+
+ // Disconnect A2DP only and test connection state summary
+ updateProfileStatus(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
+ updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED);
+ assertThat(mCachedDevice.getTvConnectionSummary().toString()).isEqualTo(
+ "Battery 10%");
+
+ // Disconnect both HFP and A2DP and test connection state summary
+ updateProfileStatus(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
+ assertThat(mCachedDevice.getTvConnectionSummary().toString()).isEqualTo(
+ "Battery 10%");
+
+ // Disconnect all profiles and test connection state summary
+ updateProfileStatus(mPanProfile, BluetoothProfile.STATE_DISCONNECTED);
+ assertThat(mCachedDevice.getTvConnectionSummary()).isNull();
+ }
+
+ @Test
public void getConnectionSummary_testSingleProfileActiveDeviceA2dp() {
// Test without battery level
// Set A2DP profile to be connected and test connection state summary
@@ -275,6 +362,37 @@ public class CachedBluetoothDeviceTest {
}
@Test
+ public void getTvConnectionSummary_testSingleProfileActiveDeviceA2dp() {
+ // Test without battery level
+ // Set A2DP profile to be connected and test connection state summary
+ updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
+ assertThat(mCachedDevice.getTvConnectionSummary()).isNull();
+
+ // Set device as Active for A2DP and test connection state summary
+ mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP);
+ assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Active");
+
+ // Test with battery level
+ mBatteryLevel = 10;
+ assertThat(mCachedDevice.getTvConnectionSummary().toString()).isEqualTo("Battery 10%");
+
+ // Set A2DP profile to be disconnected and test connection state summary
+ updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED);
+ assertThat(mCachedDevice.getTvConnectionSummary()).isNull();
+
+ // Test with BluetoothDevice.BATTERY_LEVEL_UNKNOWN battery level
+ mBatteryLevel = BluetoothDevice.BATTERY_LEVEL_UNKNOWN;
+ // Set A2DP profile to be connected, Active and test connection state summary
+ updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
+ mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP);
+ assertThat(mCachedDevice.getTvConnectionSummary().toString()).isEqualTo("Active");
+
+ // Set A2DP profile to be disconnected and test connection state summary
+ updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED);
+ assertThat(mCachedDevice.getTvConnectionSummary()).isNull();
+ }
+
+ @Test
public void getConnectionSummary_shortSummary_returnShortSummary() {
// Test without battery level
// Set A2DP profile to be connected and test connection state summary
@@ -309,6 +427,18 @@ public class CachedBluetoothDeviceTest {
}
@Test
+ public void getTvConnectionSummary_testA2dpBatteryInactive_returnBattery() {
+ // Arrange:
+ // 1. Profile: {A2DP, CONNECTED, Inactive}
+ // 2. Battery Level: 10
+ updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
+ mBatteryLevel = 10;
+
+ // Act & Assert:
+ assertThat(mCachedDevice.getTvConnectionSummary().toString()).isEqualTo("Battery 10%");
+ }
+
+ @Test
public void getConnectionSummary_testA2dpInCall_returnNull() {
// Arrange:
// 1. Profile: {A2DP, Connected, Active}
@@ -323,6 +453,20 @@ public class CachedBluetoothDeviceTest {
}
@Test
+ public void getTvConnectionSummary_testA2dpInCall_returnNull() {
+ // Arrange:
+ // 1. Profile: {A2DP, Connected, Active}
+ // 2. Audio Manager: In Call
+ updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
+ mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP);
+ mAudioManager.setMode(AudioManager.MODE_IN_CALL);
+
+ // Act & Assert:
+ // Get null result without Battery Level.
+ assertThat(mCachedDevice.getTvConnectionSummary()).isNull();
+ }
+
+ @Test
public void getConnectionSummary_testA2dpBatteryInCall_returnBattery() {
// Arrange:
// 1. Profile: {A2DP, Connected, Active}
@@ -339,6 +483,22 @@ public class CachedBluetoothDeviceTest {
}
@Test
+ public void getTvConnectionSummary_testA2dpBatteryInCall_returnBattery() {
+ // Arrange:
+ // 1. Profile: {A2DP, Connected, Active}
+ // 3. Battery Level: 10
+ // 2. Audio Manager: In Call
+ updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
+ mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP);
+ mBatteryLevel = 10;
+ mAudioManager.setMode(AudioManager.MODE_IN_CALL);
+
+ // Act & Assert:
+ // Get "10% battery" result with Battery Level 10.
+ assertThat(mCachedDevice.getTvConnectionSummary().toString()).isEqualTo("Battery 10%");
+ }
+
+ @Test
public void getConnectionSummary_testSingleProfileActiveDeviceHfp() {
// Test without battery level
// Set HFP profile to be connected and test connection state summary
@@ -372,6 +532,39 @@ public class CachedBluetoothDeviceTest {
}
@Test
+ public void getTvConnectionSummary_testSingleProfileActiveDeviceHfp() {
+ // Test without battery level
+ // Set HFP profile to be connected and test connection state summary
+ updateProfileStatus(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
+ assertThat(mCachedDevice.getTvConnectionSummary()).isNull();
+
+ // Set device as Active for HFP and test connection state summary
+ mCachedDevice.onAudioModeChanged();
+ mAudioManager.setMode(AudioManager.MODE_IN_CALL);
+ mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEADSET);
+ assertThat(mCachedDevice.getTvConnectionSummary().toString()).isEqualTo("Active");
+
+ // Test with battery level
+ mBatteryLevel = 10;
+ assertThat(mCachedDevice.getTvConnectionSummary().toString()).isEqualTo("Battery 10%");
+
+ // Set HFP profile to be disconnected and test connection state summary
+ updateProfileStatus(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
+ assertThat(mCachedDevice.getTvConnectionSummary()).isNull();
+
+ // Test with BluetoothDevice.BATTERY_LEVEL_UNKNOWN battery level
+ mBatteryLevel = BluetoothDevice.BATTERY_LEVEL_UNKNOWN;
+ // Set HFP profile to be connected, Active and test connection state summary
+ updateProfileStatus(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
+ mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEADSET);
+ assertThat(mCachedDevice.getTvConnectionSummary().toString()).isEqualTo("Active");
+
+ // Set HFP profile to be disconnected and test connection state summary
+ updateProfileStatus(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
+ assertThat(mCachedDevice.getTvConnectionSummary()).isNull();
+ }
+
+ @Test
public void getConnectionSummary_testHeadsetBatteryInactive_returnBattery() {
// Arrange:
// 1. Profile: {HEADSET, CONNECTED, Inactive}
@@ -385,6 +578,19 @@ public class CachedBluetoothDeviceTest {
}
@Test
+ public void getTvConnectionSummary_testHeadsetBatteryInactive_returnBattery() {
+ // Arrange:
+ // 1. Profile: {HEADSET, CONNECTED, Inactive}
+ // 2. Battery Level: 10
+ updateProfileStatus(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
+ mBatteryLevel = 10;
+
+ // Act & Assert:
+ // Get "10% battery" result without Battery Level.
+ assertThat(mCachedDevice.getTvConnectionSummary().toString()).isEqualTo("Battery 10%");
+ }
+
+ @Test
public void getConnectionSummary_testHeadsetWithoutInCall_returnNull() {
// Arrange:
// 1. Profile: {HEADSET, Connected, Active}
@@ -398,6 +604,19 @@ public class CachedBluetoothDeviceTest {
}
@Test
+ public void getTvConnectionSummary_testHeadsetWithoutInCall_returnNull() {
+ // Arrange:
+ // 1. Profile: {HEADSET, Connected, Active}
+ // 2. Audio Manager: Normal (Without In Call)
+ updateProfileStatus(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
+ mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEADSET);
+
+ // Act & Assert:
+ // Get null result without Battery Level.
+ assertThat(mCachedDevice.getTvConnectionSummary()).isNull();
+ }
+
+ @Test
public void getConnectionSummary_testHeadsetBatteryWithoutInCall_returnBattery() {
// Arrange:
// 1. Profile: {HEADSET, Connected, Active}
@@ -413,6 +632,22 @@ public class CachedBluetoothDeviceTest {
}
@Test
+ public void getTvConnectionSummary_testHeadsetBatteryWithoutInCall_returnBattery() {
+ // Arrange:
+ // 1. Profile: {HEADSET, Connected, Active}
+ // 2. Battery Level: 10
+ // 3. Audio Manager: Normal (Without In Call)
+ updateProfileStatus(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
+ mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEADSET);
+ mBatteryLevel = 10;
+
+ // Act & Assert:
+ // Get "10% battery" result with Battery Level 10.
+ assertThat(mCachedDevice.getTvConnectionSummary().toString()).isEqualTo("Battery 10%");
+ }
+
+
+ @Test
public void getConnectionSummary_testSingleProfileActiveDeviceHearingAid() {
// Test without battery level
// Set Hearing Aid profile to be connected and test connection state summary
@@ -432,6 +667,26 @@ public class CachedBluetoothDeviceTest {
}
@Test
+ public void getTvConnectionSummary_testSingleProfileActiveDeviceHearingAid() {
+ // Test without battery level
+ // Set Hearing Aid profile to be connected and test connection state summary
+ updateProfileStatus(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED);
+ assertThat(mCachedDevice.getTvConnectionSummary()).isNull();
+
+ // Set device as Active for Hearing Aid and test connection state summary
+ mCachedDevice.setHearingAidInfo(getLeftAshaHearingAidInfo());
+ mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEARING_AID);
+ assertThat(mCachedDevice.getTvConnectionSummary().toString()).isEqualTo(
+ "Active, left only");
+
+ // Set Hearing Aid profile to be disconnected and test connection state summary
+ mCachedDevice.onActiveDeviceChanged(false, BluetoothProfile.HEARING_AID);
+ mCachedDevice.onProfileStateChanged(mHearingAidProfile,
+ BluetoothProfile.STATE_DISCONNECTED);
+ assertThat(mCachedDevice.getTvConnectionSummary()).isNull();
+ }
+
+ @Test
public void getConnectionSummary_testHearingAidBatteryInactive_returnBattery() {
// Arrange:
// 1. Profile: {HEARING_AID, CONNECTED, Inactive}
@@ -445,6 +700,19 @@ public class CachedBluetoothDeviceTest {
}
@Test
+ public void getTvConnectionSummary_testHearingAidBatteryInactive_returnBattery() {
+ // Arrange:
+ // 1. Profile: {HEARING_AID, CONNECTED, Inactive}
+ // 2. Battery Level: 10
+ updateProfileStatus(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED);
+ mBatteryLevel = 10;
+
+ // Act & Assert:
+ // Get "10% battery" result without Battery Level.
+ assertThat(mCachedDevice.getTvConnectionSummary().toString()).isEqualTo("Battery 10%");
+ }
+
+ @Test
public void getConnectionSummary_testHearingAidBatteryWithoutInCall_returnActiveBattery() {
// Arrange:
// 1. Profile: {HEARING_AID, Connected, Active}
@@ -460,6 +728,21 @@ public class CachedBluetoothDeviceTest {
}
@Test
+ public void getTvConnectionSummary_testHearingAidBatteryWithoutInCall_returnBattery() {
+ // Arrange:
+ // 1. Profile: {HEARING_AID, Connected, Active}
+ // 2. Battery Level: 10
+ // 3. Audio Manager: Normal (Without In Call)
+ updateProfileStatus(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED);
+ mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEARING_AID);
+ mBatteryLevel = 10;
+
+ // Act & Assert:
+ // Get "Active, 10% battery" result with Battery Level 10.
+ assertThat(mCachedDevice.getTvConnectionSummary().toString()).isEqualTo("Battery 10%");
+ }
+
+ @Test
public void getConnectionSummary_testHearingAidRightEarInCall_returnActiveRightEar() {
// Arrange:
// 1. Profile: {HEARING_AID, Connected, Active, Right ear}
@@ -475,6 +758,22 @@ public class CachedBluetoothDeviceTest {
}
@Test
+ public void getTvConnectionSummary_testHearingAidRightEarInCall_returnActiveRightEar() {
+ // Arrange:
+ // 1. Profile: {HEARING_AID, Connected, Active, Right ear}
+ // 2. Audio Manager: In Call
+ updateProfileStatus(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED);
+ mCachedDevice.setHearingAidInfo(getRightAshaHearingAidInfo());
+ mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEARING_AID);
+ mAudioManager.setMode(AudioManager.MODE_IN_CALL);
+
+ // Act & Assert:
+ // Get "Active" result without Battery Level.
+ assertThat(mCachedDevice.getTvConnectionSummary().toString()).isEqualTo(
+ "Active, right only");
+ }
+
+ @Test
public void getConnectionSummary_testHearingAidBothEarInCall_returnActiveBothEar() {
// Arrange:
// 1. Profile: {HEARING_AID, Connected, Active, Both ear}
@@ -493,6 +792,25 @@ public class CachedBluetoothDeviceTest {
}
@Test
+ public void getTvConnectionSummary_testHearingAidBothEarInCall_returnActiveBothEar() {
+ // Arrange:
+ // 1. Profile: {HEARING_AID, Connected, Active, Both ear}
+ // 2. Audio Manager: In Call
+ mCachedDevice.setHearingAidInfo(getRightAshaHearingAidInfo());
+ updateProfileStatus(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED);
+ mSubCachedDevice.setHearingAidInfo(getLeftAshaHearingAidInfo());
+ updateSubDeviceProfileStatus(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED);
+ mCachedDevice.setSubDevice(mSubCachedDevice);
+ mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEARING_AID);
+ mAudioManager.setMode(AudioManager.MODE_IN_CALL);
+
+ // Act & Assert:
+ // Get "Active" result without Battery Level.
+ assertThat(mCachedDevice.getTvConnectionSummary().toString())
+ .isEqualTo("Active, left and right");
+ }
+
+ @Test
public void getConnectionSummary_testHearingAidBatteryInCall_returnActiveBattery() {
// Arrange:
// 1. Profile: {HEARING_AID, Connected, Active}
@@ -509,6 +827,22 @@ public class CachedBluetoothDeviceTest {
}
@Test
+ public void getTvConnectionSummary_testHearingAidBatteryInCall_returnBattery() {
+ // Arrange:
+ // 1. Profile: {HEARING_AID, Connected, Active}
+ // 2. Battery Level: 10
+ // 3. Audio Manager: In Call
+ updateProfileStatus(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED);
+ mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEARING_AID);
+ mAudioManager.setMode(AudioManager.MODE_IN_CALL);
+ mBatteryLevel = 10;
+
+ // Act & Assert:
+ // Get "Active, 10% battery" result with Battery Level 10.
+ assertThat(mCachedDevice.getTvConnectionSummary().toString()).isEqualTo("Battery 10%");
+ }
+
+ @Test
public void getConnectionSummary_testActiveDeviceLeAudioHearingAid() {
// Test without battery level
// Set HAP Client and LE Audio profile to be connected and test connection state summary
@@ -529,6 +863,27 @@ public class CachedBluetoothDeviceTest {
}
@Test
+ public void getTvConnectionSummary_testActiveDeviceLeAudioHearingAid() {
+ // Test without battery level
+ // Set HAP Client and LE Audio profile to be connected and test connection state summary
+ when(mProfileManager.getHapClientProfile()).thenReturn(mHapClientProfile);
+ updateProfileStatus(mHapClientProfile, BluetoothProfile.STATE_CONNECTED);
+ updateProfileStatus(mLeAudioProfile, BluetoothProfile.STATE_CONNECTED);
+ assertThat(mCachedDevice.getTvConnectionSummary()).isNull();
+
+ // Set device as Active for LE Audio and test connection state summary
+ mCachedDevice.setHearingAidInfo(getLeftLeAudioHearingAidInfo());
+ mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.LE_AUDIO);
+ assertThat(mCachedDevice.getTvConnectionSummary().toString()).isEqualTo(
+ "Active, left only");
+
+ // Set LE Audio profile to be disconnected and test connection state summary
+ mCachedDevice.onActiveDeviceChanged(false, BluetoothProfile.LE_AUDIO);
+ mCachedDevice.onProfileStateChanged(mLeAudioProfile, BluetoothProfile.STATE_DISCONNECTED);
+ assertThat(mCachedDevice.getTvConnectionSummary()).isNull();
+ }
+
+ @Test
public void getConnectionSummary_testMemberDevicesExist_returnMinBattery() {
// One device is active with battery level 70.
mBatteryLevel = 70;
@@ -545,6 +900,22 @@ public class CachedBluetoothDeviceTest {
}
@Test
+ public void getTvConnectionSummary_testMemberDevicesExist_returnMinBattery() {
+ // One device is active with battery level 70.
+ mBatteryLevel = 70;
+ updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
+ mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP);
+
+
+ // Add a member device with battery level 30.
+ int lowerBatteryLevel = 30;
+ mCachedDevice.addMemberDevice(mSubCachedDevice);
+ doAnswer((invocation) -> lowerBatteryLevel).when(mSubCachedDevice).getBatteryLevel();
+
+ assertThat(mCachedDevice.getTvConnectionSummary().toString()).isEqualTo("Battery 30%");
+ }
+
+ @Test
public void getConnectionSummary_testMemberDevicesBatteryUnknown_returnMinBattery() {
// One device is active with battery level 70.
mBatteryLevel = 70;
@@ -560,6 +931,21 @@ public class CachedBluetoothDeviceTest {
}
@Test
+ public void getTvConnectionSummary_testMemberDevicesBatteryUnknown_returnMinBattery() {
+ // One device is active with battery level 70.
+ mBatteryLevel = 70;
+ updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
+ mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP);
+
+ // Add a member device with battery level unknown.
+ mCachedDevice.addMemberDevice(mSubCachedDevice);
+ doAnswer((invocation) -> BluetoothDevice.BATTERY_LEVEL_UNKNOWN).when(
+ mSubCachedDevice).getBatteryLevel();
+
+ assertThat(mCachedDevice.getTvConnectionSummary().toString()).isEqualTo("Battery 70%");
+ }
+
+ @Test
public void getConnectionSummary_testAllDevicesBatteryUnknown_returnNoBattery() {
// One device is active with battery level unknown.
updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
@@ -574,6 +960,20 @@ public class CachedBluetoothDeviceTest {
}
@Test
+ public void getTvConnectionSummary_testAllDevicesBatteryUnknown_returnNoBattery() {
+ // One device is active with battery level unknown.
+ updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
+ mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP);
+
+ // Add a member device with battery level unknown.
+ mCachedDevice.addMemberDevice(mSubCachedDevice);
+ doAnswer((invocation) -> BluetoothDevice.BATTERY_LEVEL_UNKNOWN).when(
+ mSubCachedDevice).getBatteryLevel();
+
+ assertThat(mCachedDevice.getTvConnectionSummary().toString()).isEqualTo("Active");
+ }
+
+ @Test
public void getConnectionSummary_testMultipleProfilesActiveDevice() {
// Test without battery level
// Set A2DP and HFP profiles to be connected and test connection state summary
@@ -621,6 +1021,53 @@ public class CachedBluetoothDeviceTest {
}
@Test
+ public void getTvConnectionSummary_testMultipleProfilesActiveDevice() {
+ // Test without battery level
+ // Set A2DP and HFP profiles to be connected and test connection state summary
+ updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
+ updateProfileStatus(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
+ assertThat(mCachedDevice.getTvConnectionSummary()).isNull();
+
+ // Set device as Active for A2DP and HFP and test connection state summary
+ mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP);
+ mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEADSET);
+ assertThat(mCachedDevice.getTvConnectionSummary().toString()).isEqualTo("Active");
+
+ // Test with battery level
+ mBatteryLevel = 10;
+ assertThat(mCachedDevice.getTvConnectionSummary().toString()).isEqualTo(
+ "Battery 10%");
+
+ // Disconnect A2DP only and test connection state summary
+ mCachedDevice.onActiveDeviceChanged(false, BluetoothProfile.A2DP);
+ updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED);
+ assertThat(mCachedDevice.getTvConnectionSummary().toString()).isEqualTo(
+ "Battery 10%");
+
+ // Disconnect HFP only and test connection state summary
+ mCachedDevice.onActiveDeviceChanged(false, BluetoothProfile.HEADSET);
+ updateProfileStatus(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
+ updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
+ mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP);
+ assertThat(mCachedDevice.getTvConnectionSummary().toString()).isEqualTo(
+ "Battery 10%");
+
+ // Test with BluetoothDevice.BATTERY_LEVEL_UNKNOWN battery level
+ mBatteryLevel = BluetoothDevice.BATTERY_LEVEL_UNKNOWN;
+ // Set A2DP and HFP profiles to be connected, Active and test connection state summary
+ updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
+ updateProfileStatus(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
+ mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP);
+ mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEADSET);
+ assertThat(mCachedDevice.getTvConnectionSummary().toString()).isEqualTo("Active");
+
+ // Set A2DP and HFP profiles to be disconnected and test connection state summary
+ updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED);
+ updateProfileStatus(mHfpProfile, BluetoothProfile.STATE_DISCONNECTED);
+ assertThat(mCachedDevice.getTvConnectionSummary()).isNull();
+ }
+
+ @Test
public void getConnectionSummary_testMultipleProfilesInactive_returnPairing() {
// Arrange:
// 1. Profile 1: {A2DP, CONNECTED, Inactive}
@@ -638,6 +1085,23 @@ public class CachedBluetoothDeviceTest {
}
@Test
+ public void getTvConnectionSummary_testMultipleProfilesInactive_returnPairing() {
+ // Arrange:
+ // 1. Profile 1: {A2DP, CONNECTED, Inactive}
+ // 2. Profile 2: {HEADSET, CONNECTED, Inactive}
+ // 3. Profile 3: {HEARING_AID, CONNECTED, Inactive}
+ // 4. Bond State: Bonding
+ updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
+ updateProfileStatus(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
+ updateProfileStatus(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED);
+ when(mDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDING);
+
+ // Act & Assert:
+ // Get "Pairing…" result without Battery Level.
+ assertThat(mCachedDevice.getTvConnectionSummary().toString()).isEqualTo("Pairing…");
+ }
+
+ @Test
public void getConnectionSummary_trueWirelessActiveDeviceWithBattery_returnActiveWithBattery() {
updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
updateProfileStatus(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
@@ -656,6 +1120,24 @@ public class CachedBluetoothDeviceTest {
}
@Test
+ public void getTvConnectionSummary_trueWirelessActiveDeviceWithBattery_returnBattery() {
+ updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
+ updateProfileStatus(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
+ updateProfileStatus(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED);
+ when(mDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
+ mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEARING_AID);
+ when(mDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET)).thenReturn(
+ "true".getBytes());
+ when(mDevice.getMetadata(BluetoothDevice.METADATA_UNTETHERED_LEFT_BATTERY)).thenReturn(
+ TWS_BATTERY_LEFT.getBytes());
+ when(mDevice.getMetadata(BluetoothDevice.METADATA_UNTETHERED_RIGHT_BATTERY)).thenReturn(
+ TWS_BATTERY_RIGHT.getBytes());
+
+ assertThat(mCachedDevice.getTvConnectionSummary().toString()).isEqualTo(
+ "Left 15% Right 25%");
+ }
+
+ @Test
public void getConnectionSummary_trueWirelessDeviceWithBattery_returnActiveWithBattery() {
updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
updateProfileStatus(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
@@ -673,6 +1155,84 @@ public class CachedBluetoothDeviceTest {
}
@Test
+ public void getTvConnectionSummary_trueWirelessDeviceWithBattery_returnBattery() {
+ updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
+ updateProfileStatus(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
+ updateProfileStatus(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED);
+ when(mDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
+ when(mDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET)).thenReturn(
+ "true".getBytes());
+ when(mDevice.getMetadata(BluetoothDevice.METADATA_UNTETHERED_LEFT_BATTERY)).thenReturn(
+ TWS_BATTERY_LEFT.getBytes());
+ when(mDevice.getMetadata(BluetoothDevice.METADATA_UNTETHERED_RIGHT_BATTERY)).thenReturn(
+ TWS_BATTERY_RIGHT.getBytes());
+
+ assertThat(mCachedDevice.getTvConnectionSummary().toString()).isEqualTo(
+ "Left 15% Right 25%");
+ }
+
+ @Test
+ public void getTvConnectionSummary_trueWirelessDeviceWithLowBattery() {
+ updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
+ updateProfileStatus(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
+ updateProfileStatus(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED);
+ when(mDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
+ when(mDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET)).thenReturn(
+ "true".getBytes());
+ when(mDevice.getMetadata(BluetoothDevice.METADATA_UNTETHERED_LEFT_BATTERY)).thenReturn(
+ TWS_BATTERY_LEFT.getBytes());
+ when(mDevice.getMetadata(BluetoothDevice.METADATA_UNTETHERED_RIGHT_BATTERY)).thenReturn(
+ TWS_BATTERY_RIGHT.getBytes());
+
+ int lowBatteryColor = mContext.getColor(LOW_BATTERY_COLOR);
+
+ // Default low battery threshold, only left battery is low
+ CharSequence summary = mCachedDevice.getTvConnectionSummary(LOW_BATTERY_COLOR);
+ assertForegroundColorSpan(summary, 0, 0, 8, lowBatteryColor);
+ assertThat(summary.toString()).isEqualTo("Left 15% Right 25%");
+
+ // Lower threshold, neither battery should be low
+ when(mDevice.getMetadata(BluetoothDevice.METADATA_UNTETHERED_LEFT_LOW_BATTERY_THRESHOLD))
+ .thenReturn(TWS_LOW_BATTERY_THRESHOLD_LOW.getBytes());
+ when(mDevice.getMetadata(BluetoothDevice.METADATA_UNTETHERED_RIGHT_LOW_BATTERY_THRESHOLD))
+ .thenReturn(TWS_LOW_BATTERY_THRESHOLD_LOW.getBytes());
+ summary = mCachedDevice.getTvConnectionSummary(LOW_BATTERY_COLOR);
+ assertNoForegroundColorSpans(summary);
+ assertThat(summary.toString()).isEqualTo("Left 15% Right 25%");
+
+
+ // Higher Threshold, both batteries are low
+ when(mDevice.getMetadata(BluetoothDevice.METADATA_UNTETHERED_LEFT_LOW_BATTERY_THRESHOLD))
+ .thenReturn(TWS_LOW_BATTERY_THRESHOLD_HIGH.getBytes());
+ when(mDevice.getMetadata(BluetoothDevice.METADATA_UNTETHERED_RIGHT_LOW_BATTERY_THRESHOLD))
+ .thenReturn(TWS_LOW_BATTERY_THRESHOLD_HIGH.getBytes());
+ summary = mCachedDevice.getTvConnectionSummary(LOW_BATTERY_COLOR);
+ assertForegroundColorSpan(summary, 0, 0, 8, lowBatteryColor);
+ assertForegroundColorSpan(summary, 1, 9, 18, lowBatteryColor);
+ assertThat(summary.toString()).isEqualTo("Left 15% Right 25%");
+ }
+
+ private void assertNoForegroundColorSpans(CharSequence charSequence) {
+ if (charSequence instanceof Spannable) {
+ Spannable summarySpan = (Spannable) charSequence;
+ ForegroundColorSpan[] spans = summarySpan.getSpans(0, summarySpan.length(),
+ ForegroundColorSpan.class);
+ assertThat(spans).isEmpty();
+ }
+ }
+
+ private void assertForegroundColorSpan(CharSequence charSequence, int indexInSpannable,
+ int start, int end, int color) {
+ assertThat(charSequence).isInstanceOf(Spannable.class);
+ Spannable summarySpan = (Spannable) charSequence;
+ ForegroundColorSpan[] spans = summarySpan.getSpans(0, summarySpan.length(),
+ ForegroundColorSpan.class);
+ assertThat(spans[indexInSpannable].getForegroundColor()).isEqualTo(color);
+ assertThat(summarySpan.getSpanStart(spans[indexInSpannable])).isEqualTo(start);
+ assertThat(summarySpan.getSpanEnd(spans[indexInSpannable])).isEqualTo(end);
+ }
+
+ @Test
public void getCarConnectionSummary_singleProfileConnectDisconnect() {
// Test without battery level
// Set PAN profile to be connected and test connection state summary
@@ -1136,6 +1696,18 @@ public class CachedBluetoothDeviceTest {
}
@Test
+ public void getTvConnectionSummary_profileConnectedFail_showErrorMessage() {
+ final A2dpProfile profile = mock(A2dpProfile.class);
+ mCachedDevice.onProfileStateChanged(profile, BluetoothProfile.STATE_CONNECTED);
+ mCachedDevice.setProfileConnectedStatus(BluetoothProfile.A2DP, true);
+
+ when(profile.getConnectionStatus(mDevice)).thenReturn(BluetoothProfile.STATE_CONNECTED);
+
+ assertThat(mCachedDevice.getTvConnectionSummary().toString()).isEqualTo(
+ mContext.getString(R.string.profile_connect_timeout_subtext));
+ }
+
+ @Test
public void onUuidChanged_bluetoothClassIsNull_shouldNotCrash() {
mShadowBluetoothAdapter.setUuids(PbapServerProfile.PBAB_CLIENT_UUIDS);
when(mDevice.getUuids()).thenReturn(PbapServerProfile.PBAB_CLIENT_UUIDS);
diff --git a/packages/SettingsProvider/Android.bp b/packages/SettingsProvider/Android.bp
index a4a9290b16ab..adebdcdcf26a 100644
--- a/packages/SettingsProvider/Android.bp
+++ b/packages/SettingsProvider/Android.bp
@@ -33,6 +33,7 @@ android_library {
],
static_libs: [
"device_config_service_flags_java",
+ "libaconfig_java_proto_lite",
"SettingsLibDeviceStateRotationLock",
"SettingsLibDisplayUtils",
],
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java b/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java
index 969f1fde604e..976ba215d349 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java
@@ -22,6 +22,8 @@ import static android.provider.Settings.Config.SYNC_DISABLED_MODE_UNTIL_REBOOT;
import static com.android.providers.settings.Flags.supportOverrides;
+import android.aconfig.Aconfig.parsed_flag;
+import android.aconfig.Aconfig.parsed_flags;
import android.annotation.SuppressLint;
import android.app.ActivityManager;
import android.content.AttributionSource;
@@ -39,12 +41,13 @@ import android.provider.DeviceConfigShellCommandHandler;
import android.provider.Settings;
import android.provider.Settings.Config.SyncDisabledMode;
import android.provider.UpdatableDeviceConfigServiceReadiness;
+import android.util.Slog;
import com.android.internal.util.FastPrintWriter;
import java.io.File;
import java.io.FileDescriptor;
-import java.io.FileNotFoundException;
+import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
@@ -56,18 +59,17 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
-import java.util.Scanner;
/**
* Receives shell commands from the command line related to device config flags, and dispatches them
* to the SettingsProvider.
*/
public final class DeviceConfigService extends Binder {
- private static final List<String> aconfigTextProtoFilesOnDevice = List.of(
- "/system/etc/aconfig_flags.textproto",
- "/system_ext/etc/aconfig_flags.textproto",
- "/system_ext/etc/aconfig_flags.textproto",
- "/vendor/etc/aconfig_flags.textproto");
+ private static final List<String> sAconfigTextProtoFilesOnDevice = List.of(
+ "/system/etc/aconfig_flags.pb",
+ "/system_ext/etc/aconfig_flags.pb",
+ "/system_ext/etc/aconfig_flags.pb",
+ "/vendor/etc/aconfig_flags.pb");
private static final List<String> PRIVATE_NAMESPACES = List.of(
"device_config_overrides",
@@ -76,6 +78,8 @@ public final class DeviceConfigService extends Binder {
final SettingsProvider mProvider;
+ private static final String TAG = "DeviceConfigService";
+
public DeviceConfigService(SettingsProvider provider) {
mProvider = provider;
}
@@ -94,62 +98,55 @@ public final class DeviceConfigService extends Binder {
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- final IContentProvider iprovider = mProvider.getIContentProvider();
- pw.println("DeviceConfig flags:");
- for (String line : MyShellCommand.listAll(iprovider)) {
- pw.println(line);
- }
-
- ArrayList<String> missingFiles = new ArrayList<String>();
- for (String fileName : aconfigTextProtoFilesOnDevice) {
- File aconfigFile = new File(fileName);
- if (!aconfigFile.exists()) {
- missingFiles.add(fileName);
+ final IContentProvider iprovider = mProvider.getIContentProvider();
+ pw.println("DeviceConfig flags:");
+ for (String line : MyShellCommand.listAll(iprovider)) {
+ pw.println(line);
}
- }
- if (missingFiles.isEmpty()) {
- pw.println("\nAconfig flags:");
- for (String name : MyShellCommand.listAllAconfigFlags(iprovider)) {
- pw.println(name);
+ ArrayList<String> missingFiles = new ArrayList<String>();
+ for (String fileName : sAconfigTextProtoFilesOnDevice) {
+ File aconfigFile = new File(fileName);
+ if (!aconfigFile.exists()) {
+ missingFiles.add(fileName);
+ }
}
- } else {
- pw.println("\nFailed to dump aconfig flags due to missing files:");
- for (String fileName : missingFiles) {
- pw.println(fileName);
+
+ if (missingFiles.isEmpty()) {
+ pw.println("\nAconfig flags:");
+ for (String name : MyShellCommand.listAllAconfigFlags(iprovider)) {
+ pw.println(name);
+ }
+ } else {
+ pw.println("\nFailed to dump aconfig flags due to missing files:");
+ for (String fileName : missingFiles) {
+ pw.println(fileName);
+ }
}
- }
}
private static HashSet<String> getAconfigFlagNamesInDeviceConfig() {
HashSet<String> nameSet = new HashSet<String>();
- for (String fileName : aconfigTextProtoFilesOnDevice) {
- try{
- File aconfigFile = new File(fileName);
- String packageName = "";
- String namespace = "";
- String name = "";
-
- try (Scanner scanner = new Scanner(aconfigFile)) {
- while (scanner.hasNextLine()) {
- String data = scanner.nextLine().replaceAll("\\s+","");
- if (data.startsWith("package:\"")) {
- packageName = data.substring(9, data.length()-1);
- } else if (data.startsWith("name:\"")) {
- name = data.substring(6, data.length()-1);
- } else if (data.startsWith("namespace:\"")) {
- namespace = data.substring(11, data.length()-1);
- nameSet.add(namespace + "/" + packageName + "." + name);
+ try {
+ for (String fileName : sAconfigTextProtoFilesOnDevice) {
+ byte[] contents = (new FileInputStream(fileName)).readAllBytes();
+ parsed_flags parsedFlags = parsed_flags.parseFrom(contents);
+ if (parsedFlags == null) {
+ Slog.e(TAG, "failed to parse aconfig protobuf from " + fileName);
+ continue;
}
- }
- }
- } catch (FileNotFoundException e) {
- continue;
- }
+ for (parsed_flag flag : parsedFlags.getParsedFlagList()) {
+ String namespace = flag.getNamespace();
+ String packageName = flag.getPackage();
+ String name = flag.getName();
+ nameSet.add(namespace + "/" + packageName + "." + name);
+ }
+ }
+ } catch (IOException e) {
+ Slog.e(TAG, "failed to read aconfig protobuf", e);
}
-
- return nameSet;
+ return nameSet;
}
private void callUpdableDeviceConfigShellCommandHandler(FileDescriptor in, FileDescriptor out,
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index 17cc9f8135f4..f78811f5bb14 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -60,7 +60,6 @@ systemui_compose_java_defaults {
// except for SystemUI-core.
// Copied from compose/features/Android.bp.
static_libs: [
- "CommunalLayoutLib",
"PlatformComposeCore",
"PlatformComposeSceneTransitionLayout",
diff --git a/packages/SystemUI/aconfig/accessibility.aconfig b/packages/SystemUI/aconfig/accessibility.aconfig
index 9e06872797dc..21263a92ae26 100644
--- a/packages/SystemUI/aconfig/accessibility.aconfig
+++ b/packages/SystemUI/aconfig/accessibility.aconfig
@@ -6,7 +6,7 @@ flag {
name: "floating_menu_animated_tuck"
namespace: "accessibility"
description: "Sets up animations for tucking/untucking and adjusts clipbounds."
- bug: "24592044"
+ bug: "297556899"
}
flag {
diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig
index c26d5f53dee9..8eff9bfcf099 100644
--- a/packages/SystemUI/aconfig/systemui.aconfig
+++ b/packages/SystemUI/aconfig/systemui.aconfig
@@ -51,3 +51,11 @@ flag {
description: "Enables the scene container framework go/flexiglass."
bug: "283121968"
}
+
+flag {
+ name: "visual_interruptions_refactor"
+ namespace: "systemui"
+ description: "Enables the refactored version of the code to decide when notifications "
+ "HUN, bubble, pulse, or FSI."
+ bug: "261728888"
+}
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
index ab4db451406d..f7d9056c33dc 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
@@ -114,7 +114,13 @@ class ActivityLaunchAnimator(
private val NAV_FADE_OUT_INTERPOLATOR = PathInterpolator(0.2f, 0f, 1f, 1f)
/** The time we wait before timing out the remote animation after starting the intent. */
- private const val LAUNCH_TIMEOUT = 1000L
+ private const val LAUNCH_TIMEOUT = 1_000L
+
+ /**
+ * The time we wait before we Log.wtf because the remote animation was neither started or
+ * cancelled by WM.
+ */
+ private const val LONG_LAUNCH_TIMEOUT = 5_000L
private fun createPositionXInterpolator(): Interpolator {
val path =
@@ -247,7 +253,7 @@ class ActivityLaunchAnimator(
// If we expect an animation, post a timeout to cancel it in case the remote animation is
// never started.
if (willAnimate) {
- runnerDelegate.postTimeout()
+ runnerDelegate.postTimeouts()
// Hide the keyguard using the launch animation instead of the default unlock animation.
if (hideKeyguardWithAnimation) {
@@ -578,21 +584,41 @@ class ActivityLaunchAnimator(
private var cancelled = false
private var animation: LaunchAnimator.Animation? = null
- // A timeout to cancel the remote animation if it is not started within X milliseconds after
- // the intent was started.
- //
- // Note that this is important to keep this a Runnable (and not a Kotlin lambda), otherwise
- // it will be automatically converted when posted and we wouldn't be able to remove it after
- // posting it.
+ /**
+ * A timeout to cancel the launch animation if the remote animation is not started or
+ * cancelled within [LAUNCH_TIMEOUT] milliseconds after the intent was started.
+ *
+ * Note that this is important to keep this a Runnable (and not a Kotlin lambda), otherwise
+ * it will be automatically converted when posted and we wouldn't be able to remove it after
+ * posting it.
+ */
private var onTimeout = Runnable { onAnimationTimedOut() }
+ /**
+ * A long timeout to Log.wtf (signaling a bug in WM) when the remote animation wasn't
+ * started or cancelled within [LONG_LAUNCH_TIMEOUT] milliseconds after the intent was
+ * started.
+ */
+ private var onLongTimeout = Runnable {
+ Log.wtf(
+ TAG,
+ "The remote animation was neither cancelled or started within $LONG_LAUNCH_TIMEOUT"
+ )
+ }
+
@UiThread
- internal fun postTimeout() {
- timeoutHandler?.postDelayed(onTimeout, LAUNCH_TIMEOUT)
+ internal fun postTimeouts() {
+ if (timeoutHandler != null) {
+ timeoutHandler.postDelayed(onTimeout, LAUNCH_TIMEOUT)
+ timeoutHandler.postDelayed(onLongTimeout, LONG_LAUNCH_TIMEOUT)
+ }
}
- private fun removeTimeout() {
- timeoutHandler?.removeCallbacks(onTimeout)
+ private fun removeTimeouts() {
+ if (timeoutHandler != null) {
+ timeoutHandler.removeCallbacks(onTimeout)
+ timeoutHandler.removeCallbacks(onLongTimeout)
+ }
}
@UiThread
@@ -603,7 +629,7 @@ class ActivityLaunchAnimator(
nonApps: Array<out RemoteAnimationTarget>?,
callback: IRemoteAnimationFinishedCallback?
) {
- removeTimeout()
+ removeTimeouts()
// The animation was started too late and we already notified the controller that it
// timed out.
@@ -653,7 +679,6 @@ class ActivityLaunchAnimator(
val window = findRootTaskIfPossible(apps)
if (window == null) {
Log.i(TAG, "Aborting the animation as no window is opening")
- removeTimeout()
iCallback?.invoke()
if (DEBUG_LAUNCH_ANIMATION) {
@@ -890,11 +915,13 @@ class ActivityLaunchAnimator(
}
private fun onAnimationTimedOut() {
+ // The remote animation was cancelled by WM, so we already cancelled the launch
+ // animation.
if (cancelled) {
return
}
- Log.wtf(TAG, "Remote animation timed out")
+ Log.w(TAG, "Remote animation timed out")
timedOut = true
if (DEBUG_LAUNCH_ANIMATION) {
@@ -906,13 +933,15 @@ class ActivityLaunchAnimator(
@UiThread
override fun onAnimationCancelled() {
+ removeTimeouts()
+
+ // The short timeout happened, so we already cancelled the launch animation.
if (timedOut) {
return
}
Log.i(TAG, "Remote animation was cancelled")
cancelled = true
- removeTimeout()
animation?.cancel()
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt
index b8fb26406801..87a8c35388fa 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt
@@ -4,8 +4,14 @@ import android.appwidget.AppWidgetHostView
import android.os.Bundle
import android.util.SizeF
import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.lazy.grid.GridCells
+import androidx.compose.foundation.lazy.grid.GridItemSpan
+import androidx.compose.foundation.lazy.grid.LazyHorizontalGrid
import androidx.compose.material3.Card
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
@@ -13,16 +19,12 @@ import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.res.dimensionResource
-import androidx.compose.ui.res.integerResource
+import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
-import com.android.systemui.communal.layout.ui.compose.CommunalGridLayout
-import com.android.systemui.communal.layout.ui.compose.config.CommunalGridLayoutCard
-import com.android.systemui.communal.layout.ui.compose.config.CommunalGridLayoutConfig
import com.android.systemui.communal.shared.model.CommunalContentSize
import com.android.systemui.communal.ui.model.CommunalContentUiModel
import com.android.systemui.communal.ui.viewmodel.CommunalViewModel
-import com.android.systemui.res.R
@Composable
fun CommunalHub(
@@ -34,68 +36,91 @@ fun CommunalHub(
Box(
modifier = modifier.fillMaxSize().background(Color.White),
) {
- CommunalGridLayout(
- modifier = Modifier.align(Alignment.CenterStart),
- layoutConfig =
- CommunalGridLayoutConfig(
- gridColumnSize = dimensionResource(R.dimen.communal_grid_column_size),
- gridGutter = dimensionResource(R.dimen.communal_grid_gutter_size),
- gridHeight = dimensionResource(R.dimen.communal_grid_height),
- gridColumnsPerCard = integerResource(R.integer.communal_grid_columns_per_card),
- ),
- communalCards = if (showTutorial) tutorialContent else widgetContent.map(::contentCard),
- )
+ LazyHorizontalGrid(
+ modifier = modifier.height(Dimensions.GridHeight).align(Alignment.CenterStart),
+ rows = GridCells.Fixed(CommunalContentSize.FULL.span),
+ horizontalArrangement = Arrangement.spacedBy(Dimensions.Spacing),
+ verticalArrangement = Arrangement.spacedBy(Dimensions.Spacing),
+ ) {
+ if (showTutorial) {
+ items(
+ count = tutorialContentSizes.size,
+ // TODO(b/308148193): a more scalable solution for unique ids.
+ key = { index -> "tutorial_$index" },
+ span = { index -> GridItemSpan(tutorialContentSizes[index].span) },
+ ) { index ->
+ TutorialCard(
+ modifier =
+ Modifier.size(Dimensions.CardWidth, tutorialContentSizes[index].dp()),
+ )
+ }
+ } else {
+ items(
+ count = widgetContent.size,
+ key = { index -> widgetContent[index].id },
+ span = { index -> GridItemSpan(widgetContent[index].size.span) },
+ ) { index ->
+ val widget = widgetContent[index]
+ ContentCard(
+ modifier = Modifier.size(Dimensions.CardWidth, widget.size.dp()),
+ model = widget,
+ )
+ }
+ }
+ }
}
}
-private val tutorialContent =
- listOf(
- tutorialCard(CommunalGridLayoutCard.Size.FULL),
- tutorialCard(CommunalGridLayoutCard.Size.THIRD),
- tutorialCard(CommunalGridLayoutCard.Size.THIRD),
- tutorialCard(CommunalGridLayoutCard.Size.THIRD),
- tutorialCard(CommunalGridLayoutCard.Size.HALF),
- tutorialCard(CommunalGridLayoutCard.Size.HALF),
- tutorialCard(CommunalGridLayoutCard.Size.HALF),
- tutorialCard(CommunalGridLayoutCard.Size.HALF),
- )
-
-private fun tutorialCard(size: CommunalGridLayoutCard.Size): CommunalGridLayoutCard {
- return object : CommunalGridLayoutCard() {
- override val supportedSizes = listOf(size)
-
- @Composable
- override fun Content(modifier: Modifier, size: SizeF) {
- Card(modifier = modifier, content = {})
- }
- }
+// A placeholder for tutorial content.
+@Composable
+private fun TutorialCard(modifier: Modifier = Modifier) {
+ Card(modifier = modifier, content = {})
}
-private fun contentCard(model: CommunalContentUiModel): CommunalGridLayoutCard {
- return object : CommunalGridLayoutCard() {
- override val supportedSizes = listOf(convertToCardSize(model.size))
- override val priority = model.priority
+@Composable
+private fun ContentCard(
+ model: CommunalContentUiModel,
+ modifier: Modifier = Modifier,
+) {
+ AndroidView(
+ modifier = modifier,
+ factory = {
+ model.view.apply {
+ if (this is AppWidgetHostView) {
+ val size = SizeF(Dimensions.CardWidth.value, model.size.dp().value)
+ updateAppWidgetSize(Bundle.EMPTY, listOf(size))
+ }
+ }
+ },
+ )
+}
- @Composable
- override fun Content(modifier: Modifier, size: SizeF) {
- AndroidView(
- modifier = modifier,
- factory = {
- model.view.apply {
- if (this is AppWidgetHostView) {
- updateAppWidgetSize(Bundle(), listOf(size))
- }
- }
- },
- )
- }
+private fun CommunalContentSize.dp(): Dp {
+ return when (this) {
+ CommunalContentSize.FULL -> Dimensions.CardHeightFull
+ CommunalContentSize.HALF -> Dimensions.CardHeightHalf
+ CommunalContentSize.THIRD -> Dimensions.CardHeightThird
}
}
-private fun convertToCardSize(size: CommunalContentSize): CommunalGridLayoutCard.Size {
- return when (size) {
- CommunalContentSize.FULL -> CommunalGridLayoutCard.Size.FULL
- CommunalContentSize.HALF -> CommunalGridLayoutCard.Size.HALF
- CommunalContentSize.THIRD -> CommunalGridLayoutCard.Size.THIRD
- }
+// Sizes for the tutorial placeholders.
+private val tutorialContentSizes =
+ listOf(
+ CommunalContentSize.FULL,
+ CommunalContentSize.THIRD,
+ CommunalContentSize.THIRD,
+ CommunalContentSize.THIRD,
+ CommunalContentSize.HALF,
+ CommunalContentSize.HALF,
+ CommunalContentSize.HALF,
+ CommunalContentSize.HALF,
+ )
+
+private object Dimensions {
+ val CardWidth = 464.dp
+ val CardHeightFull = 630.dp
+ val CardHeightHalf = 307.dp
+ val CardHeightThird = 199.dp
+ val GridHeight = CardHeightFull
+ val Spacing = 16.dp
}
diff --git a/packages/SystemUI/res/layout/volume_dnd_icon.xml b/packages/SystemUI/res/layout/volume_dnd_icon.xml
deleted file mode 100644
index 56587b99b80b..000000000000
--- a/packages/SystemUI/res/layout/volume_dnd_icon.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<!--
- Copyright (C) 2018 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<FrameLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/dnd_icon"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="bottom"
- android:layout_marginTop="6dp"
- android:layout_marginBottom="6dp">
-
- <ImageView
- android:layout_width="14dp"
- android:layout_height="14dp"
- android:layout_gravity="center"
- android:src="@*android:drawable/ic_qs_dnd"
- android:tint="?android:attr/textColorTertiary"/>
-</FrameLayout> \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
index 611283f12984..181aa5c1e648 100644
--- a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
@@ -26,7 +26,6 @@ import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInOffset;
import static com.android.systemui.flags.Flags.DOZING_MIGRATION_1;
import static com.android.systemui.flags.Flags.LOCKSCREEN_WALLPAPER_DREAM_ENABLED;
import static com.android.systemui.flags.Flags.NEW_AOD_TRANSITION;
-import static com.android.systemui.flags.Flags.ONE_WAY_HAPTICS_API_MIGRATION;
import static com.android.systemui.util.kotlin.JavaAdapterKt.collectFlow;
import android.annotation.SuppressLint;
@@ -37,7 +36,6 @@ import android.graphics.Point;
import android.graphics.Rect;
import android.hardware.biometrics.BiometricAuthenticator;
import android.hardware.biometrics.BiometricSourceType;
-import android.os.Process;
import android.os.VibrationAttributes;
import android.util.DisplayMetrics;
import android.util.Log;
@@ -793,33 +791,15 @@ public class LockIconViewController implements Dumpable {
@VisibleForTesting
void vibrateOnTouchExploration() {
- if (mFeatureFlags.isEnabled(ONE_WAY_HAPTICS_API_MIGRATION)) {
- mVibrator.performHapticFeedback(
- mView,
- HapticFeedbackConstants.CONTEXT_CLICK
- );
- } else {
- mVibrator.vibrate(
- Process.myUid(),
- mContext.getOpPackageName(),
- UdfpsController.EFFECT_CLICK,
- "lock-icon-down",
- TOUCH_VIBRATION_ATTRIBUTES);
- }
+ mVibrator.performHapticFeedback(
+ mView,
+ HapticFeedbackConstants.CONTEXT_CLICK
+ );
}
@VisibleForTesting
void vibrateOnLongPress() {
- if (mFeatureFlags.isEnabled(ONE_WAY_HAPTICS_API_MIGRATION)) {
- mVibrator.performHapticFeedback(mView, UdfpsController.LONG_PRESS);
- } else {
- mVibrator.vibrate(
- Process.myUid(),
- mContext.getOpPackageName(),
- UdfpsController.EFFECT_CLICK,
- "lock-screen-lock-icon-longpress",
- TOUCH_VIBRATION_ATTRIBUTES);
- }
+ mVibrator.performHapticFeedback(mView, UdfpsController.LONG_PRESS);
}
private final AuthController.Callback mAuthControllerCallback = new AuthController.Callback() {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
index 85122baa3fec..e69eced0de45 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
@@ -18,6 +18,7 @@ package com.android.systemui.biometrics;
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+
import static com.android.internal.jank.InteractionJankMonitor.CUJ_BIOMETRIC_PROMPT_TRANSITION;
import android.animation.Animator;
@@ -63,7 +64,6 @@ import com.android.app.animation.Interpolators;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.jank.InteractionJankMonitor;
import com.android.internal.widget.LockPatternUtils;
-import com.android.systemui.res.R;
import com.android.systemui.biometrics.AuthController.ScaleFactorProvider;
import com.android.systemui.biometrics.domain.interactor.PromptCredentialInteractor;
import com.android.systemui.biometrics.domain.interactor.PromptSelectorInteractor;
@@ -76,8 +76,8 @@ import com.android.systemui.biometrics.ui.binder.Spaghetti;
import com.android.systemui.biometrics.ui.viewmodel.CredentialViewModel;
import com.android.systemui.biometrics.ui.viewmodel.PromptViewModel;
import com.android.systemui.dagger.qualifiers.Background;
-import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.keyguard.WakefulnessLifecycle;
+import com.android.systemui.res.R;
import com.android.systemui.statusbar.VibratorHelper;
import com.android.systemui.util.concurrency.DelayableExecutor;
@@ -280,7 +280,6 @@ public class AuthContainerView extends LinearLayout
// TODO(b/251476085): remove Config and further decompose these properties out of view classes
AuthContainerView(@NonNull Config config,
- @NonNull FeatureFlags featureFlags,
@NonNull CoroutineScope applicationCoroutineScope,
@Nullable List<FingerprintSensorPropertiesInternal> fpProps,
@Nullable List<FaceSensorPropertiesInternal> faceProps,
@@ -295,7 +294,7 @@ public class AuthContainerView extends LinearLayout
@NonNull Provider<CredentialViewModel> credentialViewModelProvider,
@NonNull @Background DelayableExecutor bgExecutor,
@NonNull VibratorHelper vibratorHelper) {
- this(config, featureFlags, applicationCoroutineScope, fpProps, faceProps,
+ this(config, applicationCoroutineScope, fpProps, faceProps,
wakefulnessLifecycle, panelInteractionDetector, userManager, lockPatternUtils,
jankMonitor, promptSelectorInteractor, promptCredentialInteractor, promptViewModel,
credentialViewModelProvider, new Handler(Looper.getMainLooper()), bgExecutor,
@@ -304,7 +303,6 @@ public class AuthContainerView extends LinearLayout
@VisibleForTesting
AuthContainerView(@NonNull Config config,
- @NonNull FeatureFlags featureFlags,
@NonNull CoroutineScope applicationCoroutineScope,
@Nullable List<FingerprintSensorPropertiesInternal> fpProps,
@Nullable List<FaceSensorPropertiesInternal> faceProps,
@@ -368,7 +366,7 @@ public class AuthContainerView extends LinearLayout
showPrompt(config, layoutInflater, promptViewModel,
Utils.findFirstSensorProperties(fpProps, mConfig.mSensorIds),
Utils.findFirstSensorProperties(faceProps, mConfig.mSensorIds),
- vibratorHelper, featureFlags);
+ vibratorHelper);
// TODO: De-dupe the logic with AuthCredentialPasswordView
setOnKeyListener((v, keyCode, event) -> {
@@ -390,8 +388,7 @@ public class AuthContainerView extends LinearLayout
@NonNull PromptViewModel viewModel,
@Nullable FingerprintSensorPropertiesInternal fpProps,
@Nullable FaceSensorPropertiesInternal faceProps,
- @NonNull VibratorHelper vibratorHelper,
- @NonNull FeatureFlags featureFlags
+ @NonNull VibratorHelper vibratorHelper
) {
if (Utils.isBiometricAllowed(config.mPromptInfo)) {
mPromptSelectorInteractorProvider.get().useBiometricsForAuthentication(
@@ -407,7 +404,7 @@ public class AuthContainerView extends LinearLayout
getJankListener(view, TRANSIT,
BiometricViewSizeBinder.ANIMATE_MEDIUM_TO_LARGE_DURATION_MS),
mBackgroundView, mBiometricCallback, mApplicationCoroutineScope,
- vibratorHelper, featureFlags);
+ vibratorHelper);
// TODO(b/251476085): migrate these dependencies
if (fpProps != null && fpProps.isAnyUdfpsType()) {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
index a64e862000fc..05db56f9eafb 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
@@ -78,7 +78,6 @@ import com.android.systemui.dagger.qualifiers.Application;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.doze.DozeReceiver;
-import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.keyguard.data.repository.BiometricType;
import com.android.systemui.statusbar.CommandQueue;
@@ -120,7 +119,6 @@ public class AuthController implements CoreStartable, CommandQueue.Callbacks,
private final Handler mHandler;
private final Context mContext;
- private final FeatureFlags mFeatureFlags;
private final Execution mExecution;
private final CommandQueue mCommandQueue;
private final ActivityTaskManager mActivityTaskManager;
@@ -743,7 +741,6 @@ public class AuthController implements CoreStartable, CommandQueue.Callbacks,
}
@Inject
public AuthController(Context context,
- @NonNull FeatureFlags featureFlags,
@Application CoroutineScope applicationCoroutineScope,
Execution execution,
CommandQueue commandQueue,
@@ -770,7 +767,6 @@ public class AuthController implements CoreStartable, CommandQueue.Callbacks,
@NonNull UdfpsUtils udfpsUtils,
@NonNull VibratorHelper vibratorHelper) {
mContext = context;
- mFeatureFlags = featureFlags;
mExecution = execution;
mUserManager = userManager;
mLockPatternUtils = lockPatternUtils;
@@ -1316,7 +1312,7 @@ public class AuthController implements CoreStartable, CommandQueue.Callbacks,
config.mRequestId = requestId;
config.mSensorIds = sensorIds;
config.mScaleProvider = this::getScaleFactor;
- return new AuthContainerView(config, mFeatureFlags, mApplicationCoroutineScope, mFpProps, mFaceProps,
+ return new AuthContainerView(config, mApplicationCoroutineScope, mFpProps, mFaceProps,
wakefulnessLifecycle, panelInteractionDetector, userManager, lockPatternUtils,
mInteractionJankMonitor, mPromptCredentialInteractor, mPromptSelectorInteractor,
viewModel, mCredentialViewModelProvider, bgExecutor, mVibratorHelper);
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt
index ac48b6a2b11e..32d9067bd9e4 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt
@@ -49,8 +49,6 @@ import com.android.systemui.biometrics.ui.viewmodel.FingerprintStartMode
import com.android.systemui.biometrics.ui.viewmodel.PromptMessage
import com.android.systemui.biometrics.ui.viewmodel.PromptSize
import com.android.systemui.biometrics.ui.viewmodel.PromptViewModel
-import com.android.systemui.flags.FeatureFlags
-import com.android.systemui.flags.Flags.ONE_WAY_HAPTICS_API_MIGRATION
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.res.R
import com.android.systemui.statusbar.VibratorHelper
@@ -78,7 +76,6 @@ object BiometricViewBinder {
legacyCallback: Spaghetti.Callback,
applicationScope: CoroutineScope,
vibratorHelper: VibratorHelper,
- featureFlags: FeatureFlags,
): Spaghetti {
val accessibilityManager = view.context.getSystemService(AccessibilityManager::class.java)!!
@@ -380,13 +377,11 @@ object BiometricViewBinder {
}
// Play haptics
- if (featureFlags.isEnabled(ONE_WAY_HAPTICS_API_MIGRATION)) {
- launch {
- viewModel.hapticsToPlay.collect { hapticFeedbackConstant ->
- if (hapticFeedbackConstant != HapticFeedbackConstants.NO_HAPTICS) {
- vibratorHelper.performHapticFeedback(view, hapticFeedbackConstant)
- viewModel.clearHaptics()
- }
+ launch {
+ viewModel.hapticsToPlay.collect { hapticFeedbackConstant ->
+ if (hapticFeedbackConstant != HapticFeedbackConstants.NO_HAPTICS) {
+ vibratorHelper.performHapticFeedback(view, hapticFeedbackConstant)
+ viewModel.clearHaptics()
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt
index e49b4a7bbce9..647aaf392ed8 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt
@@ -29,10 +29,7 @@ import com.android.systemui.biometrics.shared.model.BiometricModality
import com.android.systemui.biometrics.shared.model.DisplayRotation
import com.android.systemui.biometrics.shared.model.PromptKind
import com.android.systemui.dagger.qualifiers.Application
-import com.android.systemui.flags.FeatureFlags
-import com.android.systemui.flags.Flags.ONE_WAY_HAPTICS_API_MIGRATION
import com.android.systemui.res.R
-import com.android.systemui.statusbar.VibratorHelper
import javax.inject.Inject
import kotlinx.coroutines.Job
import kotlinx.coroutines.coroutineScope
@@ -52,9 +49,7 @@ class PromptViewModel
constructor(
displayStateInteractor: DisplayStateInteractor,
promptSelectorInteractor: PromptSelectorInteractor,
- private val vibrator: VibratorHelper,
@Application context: Context,
- private val featureFlags: FeatureFlags,
) {
/** The set of modalities available for this prompt */
val modalities: Flow<BiometricModalities> =
@@ -339,7 +334,7 @@ constructor(
_message.value = PromptMessage.Error(message)
if (hapticFeedback) {
- vibrator.error(failedModality)
+ vibrateOnError()
}
messageJob?.cancel()
@@ -457,7 +452,7 @@ constructor(
_message.value = PromptMessage.Empty
if (!needsUserConfirmation) {
- vibrator.success(modality)
+ vibrateOnSuccess()
}
messageJob?.cancel()
@@ -495,7 +490,7 @@ constructor(
_isAuthenticated.value = authState.asExplicitlyConfirmed()
_message.value = PromptMessage.Empty
- vibrator.success(authState.authenticatedModality)
+ vibrateOnSuccess()
messageJob?.cancel()
messageJob = null
@@ -530,20 +525,12 @@ constructor(
_forceLargeSize.value = true
}
- private fun VibratorHelper.success(modality: BiometricModality) {
- if (featureFlags.isEnabled(ONE_WAY_HAPTICS_API_MIGRATION)) {
- _hapticsToPlay.value = HapticFeedbackConstants.CONFIRM
- } else {
- vibrateAuthSuccess("$TAG, modality = $modality BP::success")
- }
+ private fun vibrateOnSuccess() {
+ _hapticsToPlay.value = HapticFeedbackConstants.CONFIRM
}
- private fun VibratorHelper.error(modality: BiometricModality = BiometricModality.None) {
- if (featureFlags.isEnabled(ONE_WAY_HAPTICS_API_MIGRATION)) {
- _hapticsToPlay.value = HapticFeedbackConstants.REJECT
- } else {
- vibrateAuthError("$TAG, modality = $modality BP::error")
- }
+ private fun vibrateOnError() {
+ _hapticsToPlay.value = HapticFeedbackConstants.REJECT
}
/** Clears the [hapticsToPlay] variable by setting it to the NO_HAPTICS default. */
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollector.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollector.java
index f77f98956cbf..a79a654aedc2 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollector.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollector.java
@@ -75,5 +75,8 @@ public interface FalsingCollector {
/** Indicates an a11y action was made. */
void onA11yAction();
+
+ /** Initialize the class. */
+ void init();
}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorFake.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorFake.java
index 0dfaf0f4318d..d6b9a119e31c 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorFake.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorFake.java
@@ -23,6 +23,10 @@ import javax.inject.Inject;
/** */
public class FalsingCollectorFake implements FalsingCollector {
+ @Override
+ public void init() {
+ }
+
@Inject
public FalsingCollectorFake() {
}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java
index a6b073da2530..12df96e41b2c 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java
@@ -32,13 +32,14 @@ import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dock.DockManager;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.shade.ShadeExpansionStateManager;
+import com.android.systemui.shade.domain.interactor.ShadeInteractor;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.user.domain.interactor.SelectedUserInteractor;
import com.android.systemui.util.concurrency.DelayableExecutor;
+import com.android.systemui.util.kotlin.JavaAdapter;
import com.android.systemui.util.sensors.ProximitySensor;
import com.android.systemui.util.sensors.ThresholdSensor;
import com.android.systemui.util.sensors.ThresholdSensorEvent;
@@ -65,9 +66,11 @@ class FalsingCollectorImpl implements FalsingCollector {
private final ProximitySensor mProximitySensor;
private final StatusBarStateController mStatusBarStateController;
private final KeyguardStateController mKeyguardStateController;
+ private final Lazy<ShadeInteractor> mShadeInteractorLazy;
private final BatteryController mBatteryController;
private final DockManager mDockManager;
private final DelayableExecutor mMainExecutor;
+ private final JavaAdapter mJavaAdapter;
private final SystemClock mSystemClock;
private final Lazy<SelectedUserInteractor> mUserInteractor;
@@ -136,10 +139,11 @@ class FalsingCollectorImpl implements FalsingCollector {
ProximitySensor proximitySensor,
StatusBarStateController statusBarStateController,
KeyguardStateController keyguardStateController,
- ShadeExpansionStateManager shadeExpansionStateManager,
+ Lazy<ShadeInteractor> shadeInteractorLazy,
BatteryController batteryController,
DockManager dockManager,
@Main DelayableExecutor mainExecutor,
+ JavaAdapter javaAdapter,
SystemClock systemClock,
Lazy<SelectedUserInteractor> userInteractor) {
mFalsingDataProvider = falsingDataProvider;
@@ -149,12 +153,17 @@ class FalsingCollectorImpl implements FalsingCollector {
mProximitySensor = proximitySensor;
mStatusBarStateController = statusBarStateController;
mKeyguardStateController = keyguardStateController;
+ mShadeInteractorLazy = shadeInteractorLazy;
mBatteryController = batteryController;
mDockManager = dockManager;
mMainExecutor = mainExecutor;
+ mJavaAdapter = javaAdapter;
mSystemClock = systemClock;
mUserInteractor = userInteractor;
+ }
+ @Override
+ public void init() {
mProximitySensor.setTag(PROXIMITY_SENSOR_TAG);
mProximitySensor.setDelay(SensorManager.SENSOR_DELAY_GAME);
@@ -163,7 +172,10 @@ class FalsingCollectorImpl implements FalsingCollector {
mKeyguardUpdateMonitor.registerCallback(mKeyguardUpdateCallback);
- shadeExpansionStateManager.addQsExpansionListener(this::onQsExpansionChanged);
+ mJavaAdapter.alwaysCollectFlow(
+ mShadeInteractorLazy.get().isQsExpanded(),
+ this::onQsExpansionChanged
+ );
mBatteryController.addCallback(mBatteryListener);
mDockManager.addListener(mDockEventListener);
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorNoOp.kt b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorNoOp.kt
index e5b404f30889..c5d8c795853d 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorNoOp.kt
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorNoOp.kt
@@ -23,6 +23,10 @@ import javax.inject.Inject
@SysUISingleton
class FalsingCollectorNoOp @Inject constructor() : FalsingCollector {
+ override fun init() {
+ logDebug("NOOP: init")
+ }
+
override fun onSuccessfulUnlock() {
logDebug("NOOP: onSuccessfulUnlock")
}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingCoreStartable.kt b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCoreStartable.kt
new file mode 100644
index 000000000000..b79538aac3e6
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCoreStartable.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.classifier
+
+import com.android.systemui.CoreStartable
+import com.android.systemui.dagger.SysUISingleton
+import javax.inject.Inject
+
+/** Initializes classes related to falsing. */
+@SysUISingleton
+class FalsingCoreStartable @Inject constructor(val falsingCollector: FalsingCollector) :
+ CoreStartable {
+ override fun start() {
+ falsingCollector.init()
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingModule.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingModule.java
index 2729b7b0a4fd..af467ef1319b 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingModule.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingModule.java
@@ -19,9 +19,9 @@ package com.android.systemui.classifier;
import android.content.res.Resources;
import android.view.ViewConfiguration;
-import com.android.systemui.res.R;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.res.R;
import com.android.systemui.scene.shared.flag.SceneContainerFlags;
import com.android.systemui.statusbar.phone.NotificationTapHelper;
@@ -37,7 +37,7 @@ import java.util.Set;
import javax.inject.Named;
/** Dagger Module for Falsing. */
-@Module
+@Module(includes = {FalsingStartModule.class})
public interface FalsingModule {
String BRIGHT_LINE_GESTURE_CLASSIFERS = "bright_line_gesture_classifiers";
String SINGLE_TAP_TOUCH_SLOP = "falsing_single_tap_touch_slop";
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingStartModule.kt b/packages/SystemUI/src/com/android/systemui/classifier/FalsingStartModule.kt
new file mode 100644
index 000000000000..a9f8f37fffa9
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingStartModule.kt
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.classifier
+
+import com.android.systemui.CoreStartable
+import dagger.Binds
+import dagger.Module
+import dagger.multibindings.ClassKey
+import dagger.multibindings.IntoMap
+
+@Module
+interface FalsingStartModule {
+ /** */
+ @Binds
+ @IntoMap
+ @ClassKey(FalsingCoreStartable::class)
+ fun bindFalsingCoreStartable(falsingCoreStartable: FalsingCoreStartable?): CoreStartable?
+}
diff --git a/packages/SystemUI/src/com/android/systemui/common/shared/model/SharedNotificationContainerPosition.kt b/packages/SystemUI/src/com/android/systemui/common/shared/model/SharedNotificationContainerPosition.kt
index b2bc06f0ae29..48d374207388 100644
--- a/packages/SystemUI/src/com/android/systemui/common/shared/model/SharedNotificationContainerPosition.kt
+++ b/packages/SystemUI/src/com/android/systemui/common/shared/model/SharedNotificationContainerPosition.kt
@@ -20,4 +20,7 @@ package com.android.systemui.common.shared.model
data class SharedNotificationContainerPosition(
val top: Float = 0f,
val bottom: Float = 0f,
+
+ /** Whether any modifications to top/bottom are smoothly animated */
+ val animate: Boolean = false,
)
diff --git a/packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalContentSize.kt b/packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalContentSize.kt
index 39a6476929ed..c903709aa2ee 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalContentSize.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalContentSize.kt
@@ -16,14 +16,19 @@
package com.android.systemui.communal.shared.model
-/** Supported sizes for communal content in the layout grid. */
-enum class CommunalContentSize {
+/**
+ * Supported sizes for communal content in the layout grid.
+ *
+ * @param span The span of the content in a column. For example, if FULL is 6, then 3 represents
+ * HALF, 2 represents THIRD, and 1 represents SIXTH.
+ */
+enum class CommunalContentSize(val span: Int) {
/** Content takes the full height of the column. */
- FULL,
+ FULL(6),
/** Content takes half of the height of the column. */
- HALF,
+ HALF(3),
/** Content takes a third of the height of the column. */
- THIRD,
+ THIRD(2),
}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/model/CommunalContentUiModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/model/CommunalContentUiModel.kt
index 98060dc1dceb..b60dc2a21699 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/ui/model/CommunalContentUiModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/ui/model/CommunalContentUiModel.kt
@@ -9,7 +9,7 @@ import com.android.systemui.communal.shared.model.CommunalContentSize
* This model stays in the UI layer.
*/
data class CommunalContentUiModel(
+ val id: String,
val view: View,
- val size: CommunalContentSize,
- val priority: Int,
+ val size: CommunalContentSize = CommunalContentSize.HALF,
)
diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt
index 25c64eafe255..390b580bad28 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt
@@ -20,7 +20,6 @@ import android.appwidget.AppWidgetHost
import android.content.Context
import com.android.systemui.communal.domain.interactor.CommunalInteractor
import com.android.systemui.communal.domain.interactor.CommunalTutorialInteractor
-import com.android.systemui.communal.shared.model.CommunalContentSize
import com.android.systemui.communal.ui.model.CommunalContentUiModel
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
@@ -42,16 +41,16 @@ constructor(
/** List of widgets to be displayed in the communal hub. */
val widgetContent: Flow<List<CommunalContentUiModel>> =
- communalInteractor.widgetContent.map {
- it.map {
+ communalInteractor.widgetContent.map { widgets ->
+ widgets.map Widget@{ widget ->
// TODO(b/306406256): As adding and removing widgets functionalities are
// supported, cache the host views so they're not recreated each time.
- val hostView = appWidgetHost.createView(context, it.appWidgetId, it.providerInfo)
- return@map CommunalContentUiModel(
+ val hostView =
+ appWidgetHost.createView(context, widget.appWidgetId, widget.providerInfo)
+ return@Widget CommunalContentUiModel(
+ // TODO(b/308148193): a more scalable solution for unique ids.
+ id = "widget_${widget.appWidgetId}",
view = hostView,
- priority = it.priority,
- // All widgets have HALF size.
- size = CommunalContentSize.HALF,
)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java
index 4cade77c8312..323ed9871dc3 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java
@@ -261,6 +261,13 @@ public class DozeScreenBrightness extends BroadcastReceiver implements DozeMachi
}
//TODO: brightnessfloat change usages to float.
private int clampToUserSetting(int brightness) {
+ int screenBrightnessModeSetting = mSystemSettings.getIntForUser(
+ Settings.System.SCREEN_BRIGHTNESS_MODE,
+ Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL, UserHandle.USER_CURRENT);
+ if (screenBrightnessModeSetting == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC) {
+ return brightness;
+ }
+
int userSetting = mSystemSettings.getIntForUser(
Settings.System.SCREEN_BRIGHTNESS, Integer.MAX_VALUE,
UserHandle.USER_CURRENT);
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index f4a9f739d187..0c364e1e710d 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
@@ -400,8 +400,7 @@ object Flags {
// 600- status bar
// TODO(b/291315866): Tracking Bug
- @JvmField val SIGNAL_CALLBACK_DEPRECATION =
- unreleasedFlag("signal_callback_deprecation", teamfood = true)
+ @JvmField val SIGNAL_CALLBACK_DEPRECATION = releasedFlag("signal_callback_deprecation")
// TODO(b/301610137): Tracking bug
@JvmField val NEW_NETWORK_SLICE_UI = unreleasedFlag("new_network_slice_ui", teamfood = true)
@@ -414,15 +413,14 @@ object Flags {
val PLUG_IN_STATUS_BAR_CHIP = releasedFlag("plug_in_status_bar_chip")
// TODO(b/292533677): Tracking Bug
- val WIFI_TRACKER_LIB_FOR_WIFI_ICON =
- unreleasedFlag("wifi_tracker_lib_for_wifi_icon", teamfood = true)
+ val WIFI_TRACKER_LIB_FOR_WIFI_ICON = releasedFlag("wifi_tracker_lib_for_wifi_icon")
// TODO(b/293863612): Tracking Bug
@JvmField val INCOMPATIBLE_CHARGING_BATTERY_ICON =
releasedFlag("incompatible_charging_battery_icon")
// TODO(b/293585143): Tracking Bug
- val INSTANT_TETHER = unreleasedFlag("instant_tether", teamfood = true)
+ val INSTANT_TETHER = releasedFlag("instant_tether")
// TODO(b/294588085): Tracking Bug
val WIFI_SECONDARY_NETWORKS = releasedFlag("wifi_secondary_networks")
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt
index 4d5c503d1c4e..67a12b06de0f 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt
@@ -22,6 +22,8 @@ import android.view.View
import android.view.View.OnLayoutChangeListener
import android.view.ViewGroup
import android.view.ViewGroup.OnHierarchyChangeListener
+import android.view.WindowInsets
+import android.view.WindowInsets.Type
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.repeatOnLifecycle
import com.android.internal.jank.InteractionJankMonitor
@@ -242,11 +244,18 @@ object KeyguardRootViewBinder {
}
)
+ view.setOnApplyWindowInsetsListener { v: View, insets: WindowInsets ->
+ val insetTypes = WindowInsets.Type.systemBars() or WindowInsets.Type.displayCutout()
+ viewModel.topInset = insets.getInsetsIgnoringVisibility(insetTypes).top
+ insets
+ }
+
return object : DisposableHandle {
override fun dispose() {
disposableHandle.dispose()
view.removeOnLayoutChangeListener(onLayoutChangeListener)
view.setOnHierarchyChangeListener(null)
+ view.setOnApplyWindowInsetsListener(null)
childViews.clear()
}
}
@@ -288,7 +297,6 @@ object KeyguardRootViewBinder {
oldBottom: Int
) {
val nsslPlaceholder = v.findViewById(R.id.nssl_placeholder) as View?
-
if (nsslPlaceholder != null) {
// After layout, ensure the notifications are positioned correctly
viewModel.onSharedNotificationContainerPositionChanged(
@@ -296,6 +304,11 @@ object KeyguardRootViewBinder {
nsslPlaceholder.bottom.toFloat(),
)
}
+
+ val ksv = v.findViewById(R.id.keyguard_status_view) as View?
+ if (ksv != null) {
+ viewModel.statusViewTop = ksv.top
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt
index 1f98082c4065..e12da53287ed 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt
@@ -65,7 +65,12 @@ constructor(
*/
private val previewMode = MutableStateFlow(PreviewMode())
- public var clockControllerProvider: Provider<ClockController>? = null
+ var clockControllerProvider: Provider<ClockController>? = null
+
+ /** System insets that keyguard needs to stay out of */
+ var topInset: Int = 0
+ /** Status view top, without translation added in */
+ var statusViewTop: Int = 0
val burnInLayerVisibility: Flow<Int> =
keyguardTransitionInteractor.startedKeyguardState
@@ -102,9 +107,12 @@ constructor(
scale = MathUtils.lerp(burnIn.scale, 1f, 1f - interpolation),
)
} else {
+ // Ensure the desired translation doesn't encroach on the top inset
+ val burnInY = MathUtils.lerp(0, burnIn.translationY, interpolation).toInt()
+ val translationY = -(statusViewTop - Math.max(topInset, statusViewTop + burnInY))
BurnInModel(
translationX = MathUtils.lerp(0, burnIn.translationX, interpolation).toInt(),
- translationY = MathUtils.lerp(0, burnIn.translationY, interpolation).toInt(),
+ translationY = translationY,
scale = MathUtils.lerp(burnIn.scale, 1f, 1f - interpolation),
scaleClockOnly = true,
)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTileNewImpl.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTileNewImpl.kt
index 8103152dda37..13271c32c52f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTileNewImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTileNewImpl.kt
@@ -21,8 +21,8 @@ import android.os.Handler
import android.os.Looper
import android.provider.Settings
import android.view.View
+import android.widget.Switch
import com.android.internal.logging.MetricsLogger
-import com.android.systemui.res.R
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.plugins.ActivityStarter
@@ -34,6 +34,7 @@ import com.android.systemui.qs.QsEventLogger
import com.android.systemui.qs.logging.QSLogger
import com.android.systemui.qs.tileimpl.QSTileImpl
import com.android.systemui.qs.tiles.dialog.InternetDialogFactory
+import com.android.systemui.res.R
import com.android.systemui.statusbar.connectivity.AccessPointController
import com.android.systemui.statusbar.pipeline.shared.ui.binder.InternetTileBinder
import com.android.systemui.statusbar.pipeline.shared.ui.model.InternetTileModel
@@ -96,6 +97,7 @@ constructor(
override fun handleUpdateState(state: QSTile.BooleanState, arg: Any?) {
state.label = mContext.resources.getString(R.string.quick_settings_internet_label)
+ state.expandedAccessibilityClassName = Switch::class.java.name
model.applyTo(state, mContext)
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index cc59f8750b56..dfe6adc49f9a 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -1070,7 +1070,6 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
mNotificationStackScrollLayoutController.setOnEmptySpaceClickListener(
mOnEmptySpaceClickListener);
mQsController.init();
- mShadeExpansionStateManager.addQsExpansionListener(this::onQsExpansionChanged);
mShadeHeadsUpTracker.addTrackingHeadsUpListener(
mNotificationStackScrollLayoutController::setTrackingHeadsUp);
if (!mFeatureFlags.isEnabled(Flags.MIGRATE_SPLIT_KEYGUARD_BOTTOM_AREA)) {
@@ -4219,7 +4218,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
return mShadeExpansionStateManager;
}
- private void onQsExpansionChanged(boolean expanded) {
+ void onQsExpansionChanged(boolean expanded) {
updateExpandedHeightToMaxHeight();
setStatusAccessibilityImportance(expanded
? View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java
index 04263882d3a8..51148263b6ac 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java
@@ -156,7 +156,6 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW
KeyguardStateController keyguardStateController,
ScreenOffAnimationController screenOffAnimationController,
AuthController authController,
- ShadeExpansionStateManager shadeExpansionStateManager,
Lazy<ShadeInteractor> shadeInteractorLazy,
ShadeWindowLogger logger,
Lazy<SelectedUserInteractor> userInteractor) {
@@ -185,7 +184,6 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW
.addCallback(mStateListener,
SysuiStatusBarStateController.RANK_STATUS_BAR_WINDOW_CONTROLLER);
configurationController.addCallback(this);
- shadeExpansionStateManager.addQsExpansionListener(this::onQsExpansionChanged);
float desiredPreferredRefreshRate = context.getResources()
.getInteger(R.integer.config_keyguardRefreshRate);
@@ -303,6 +301,11 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW
mShadeInteractorLazy.get().isAnyExpanded(),
this::onShadeOrQsExpanded
);
+ collectFlow(
+ mWindowRootView,
+ mShadeInteractorLazy.get().isQsExpanded(),
+ this::onQsExpansionChanged
+ );
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationsQSContainerController.kt b/packages/SystemUI/src/com/android/systemui/shade/NotificationsQSContainerController.kt
index cc46b23ec75f..866cfb443b0a 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationsQSContainerController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationsQSContainerController.kt
@@ -26,23 +26,27 @@ import androidx.constraintlayout.widget.ConstraintSet.END
import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID
import androidx.constraintlayout.widget.ConstraintSet.START
import androidx.constraintlayout.widget.ConstraintSet.TOP
-import com.android.systemui.res.R
+import androidx.lifecycle.lifecycleScope
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
import com.android.systemui.fragments.FragmentService
+import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.navigationbar.NavigationModeController
import com.android.systemui.plugins.qs.QS
import com.android.systemui.plugins.qs.QSContainerController
import com.android.systemui.recents.OverviewProxyService
import com.android.systemui.recents.OverviewProxyService.OverviewProxyListener
+import com.android.systemui.res.R
+import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.shared.system.QuickStepContract
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
import com.android.systemui.statusbar.policy.SplitShadeStateController
import com.android.systemui.util.LargeScreenUtils
import com.android.systemui.util.ViewController
import com.android.systemui.util.concurrency.DelayableExecutor
+import kotlinx.coroutines.launch
import java.util.function.Consumer
import javax.inject.Inject
import kotlin.reflect.KMutableProperty0
@@ -56,7 +60,7 @@ class NotificationsQSContainerController @Inject constructor(
private val navigationModeController: NavigationModeController,
private val overviewProxyService: OverviewProxyService,
private val shadeHeaderController: ShadeHeaderController,
- private val shadeExpansionStateManager: ShadeExpansionStateManager,
+ private val shadeInteractor: ShadeInteractor,
private val fragmentService: FragmentService,
@Main private val delayableExecutor: DelayableExecutor,
private val featureFlags: FeatureFlags,
@@ -65,7 +69,6 @@ class NotificationsQSContainerController @Inject constructor(
private val splitShadeStateController: SplitShadeStateController
) : ViewController<NotificationsQuickSettingsContainer>(view), QSContainerController {
- private var qsExpanded = false
private var splitShadeEnabled = false
private var isQSDetailShowing = false
private var isQSCustomizing = false
@@ -89,13 +92,6 @@ class NotificationsQSContainerController @Inject constructor(
taskbarVisible = visible
}
}
- private val shadeQsExpansionListener: ShadeQsExpansionListener =
- ShadeQsExpansionListener { isQsExpanded ->
- if (qsExpanded != isQsExpanded) {
- qsExpanded = isQsExpanded
- mView.invalidate()
- }
- }
// With certain configuration changes (like light/dark changes), the nav bar will disappear
// for a bit, causing `bottomStableInsets` to be unstable for some time. Debounce the value
@@ -122,6 +118,11 @@ class NotificationsQSContainerController @Inject constructor(
}
override fun onInit() {
+ mView.repeatWhenAttached {
+ lifecycleScope.launch {
+ shadeInteractor.isQsExpanded.collect{ _ -> mView.invalidate() }
+ }
+ }
val currentMode: Int = navigationModeController.addListener { mode: Int ->
isGestureNavigation = QuickStepContract.isGesturalMode(mode)
}
@@ -137,7 +138,6 @@ class NotificationsQSContainerController @Inject constructor(
public override fun onViewAttached() {
updateResources()
overviewProxyService.addCallback(taskbarVisibilityListener)
- shadeExpansionStateManager.addQsExpansionListener(shadeQsExpansionListener)
mView.setInsetsChangedListener(delayedInsetSetter)
mView.setQSFragmentAttachedListener { qs: QS -> qs.setContainerController(this) }
mView.setConfigurationChangedListener { updateResources() }
@@ -146,7 +146,6 @@ class NotificationsQSContainerController @Inject constructor(
override fun onViewDetached() {
overviewProxyService.removeCallback(taskbarVisibilityListener)
- shadeExpansionStateManager.removeQsExpansionListener(shadeQsExpansionListener)
mView.removeOnInsetsChangedListener()
mView.removeQSFragmentAttachedListener()
mView.setConfigurationChangedListener(null)
diff --git a/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java b/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java
index 0ec7a36b5a6d..d73fa1460bd4 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java
@@ -207,12 +207,6 @@ public class QuickSettingsController implements Dumpable {
/** pointerId of the pointer we're currently tracking */
private int mTrackingPointer;
- /**
- * Indicates that QS is in expanded state which can happen by:
- * - single pane shade: expanding shade and then expanding QS
- * - split shade: just expanding shade (QS are expanded automatically)
- */
- private boolean mExpanded;
/** Indicates QS is at its max height */
private boolean mFullyExpanded;
/**
@@ -594,9 +588,8 @@ public class QuickSettingsController implements Dumpable {
return twoFingerDrag || stylusButtonClickDrag || mouseButtonClickDrag;
}
-
public boolean getExpanded() {
- return mExpanded;
+ return mShadeRepository.getLegacyIsQsExpanded().getValue();
}
@VisibleForTesting
@@ -613,7 +606,7 @@ public class QuickSettingsController implements Dumpable {
// close the whole shade with one motion. Also this will be always true when closing
// split shade as there QS are always expanded so every collapsing motion is motion from
// expanded QS to closed panel
- return mExpandImmediate || (mExpanded
+ return mExpandImmediate || (getExpanded()
&& !isTracking() && !isExpansionAnimating()
&& !mExpansionFromOverscroll);
}
@@ -778,11 +771,11 @@ public class QuickSettingsController implements Dumpable {
@VisibleForTesting
void setExpanded(boolean expanded) {
- boolean changed = mExpanded != expanded;
+ boolean changed = getExpanded() != expanded;
if (changed) {
- mExpanded = expanded;
+ mShadeRepository.setLegacyIsQsExpanded(expanded);
updateQsState();
- mShadeExpansionStateManager.onQsExpansionChanged(expanded);
+ mPanelViewControllerLazy.get().onQsExpansionChanged(expanded);
mShadeLog.logQsExpansionChanged("QS Expansion Changed.", expanded,
getMinExpansionHeight(), getMaxExpansionHeight(),
mStackScrollerOverscrolling, mAnimatorExpand, mAnimating);
@@ -846,7 +839,7 @@ public class QuickSettingsController implements Dumpable {
/** Called when Shade view layout changed. Updates QS expansion or
* starts size change animation if height has changed. */
void handleShadeLayoutChanged(int oldMaxHeight) {
- if (mExpanded && mFullyExpanded) {
+ if (getExpanded() && mFullyExpanded) {
mExpansionHeight = mMaxExpansionHeight;
if (mExpansionHeightSetToMaxListener != null) {
mExpansionHeightSetToMaxListener.onExpansionHeightSetToMax(true);
@@ -988,24 +981,24 @@ public class QuickSettingsController implements Dumpable {
}
void updateQsState() {
- boolean qsFullScreen = mExpanded && !mSplitShadeEnabled;
+ boolean qsFullScreen = getExpanded() && !mSplitShadeEnabled;
mNotificationStackScrollLayoutController.setQsFullScreen(qsFullScreen);
mNotificationStackScrollLayoutController.setScrollingEnabled(
mBarState != KEYGUARD && (!qsFullScreen || mExpansionFromOverscroll));
if (mQsStateUpdateListener != null) {
- mQsStateUpdateListener.onQsStateUpdated(mExpanded, mStackScrollerOverscrolling);
+ mQsStateUpdateListener.onQsStateUpdated(getExpanded(), mStackScrollerOverscrolling);
}
if (mQs == null) return;
- mQs.setExpanded(mExpanded);
+ mQs.setExpanded(getExpanded());
}
/** update expanded state of QS */
public void updateExpansion() {
if (mQs == null) return;
final float squishiness;
- if ((mExpandImmediate || mExpanded) && !mSplitShadeEnabled) {
+ if ((mExpandImmediate || getExpanded()) && !mSplitShadeEnabled) {
squishiness = 1;
} else if (mTransitioningToFullShadeProgress > 0.0f) {
squishiness = mLockscreenShadeTransitionController.getQsSquishTransitionFraction();
@@ -1125,7 +1118,7 @@ public class QuickSettingsController implements Dumpable {
mMediaHierarchyManager.setCollapsingShadeFromQS(mExpandedWhenExpandingStarted
/* We also start expanding when flinging closed Qs. Let's exclude that */
&& !mAnimating);
- if (mExpanded) {
+ if (getExpanded()) {
onExpansionStarted();
}
// Since there are QS tiles in the header now, we need to make sure we start listening
@@ -1234,7 +1227,7 @@ public class QuickSettingsController implements Dumpable {
Math.min(top / (float) mScrimCornerRadius, 1f));
float bottomRadius = mSplitShadeEnabled ? screenCornerRadius : 0;
- if (!mExpanded) {
+ if (!getExpanded()) {
bottomRadius = calculateBottomCornerRadius(bottomRadius);
}
mScrimController.setNotificationBottomRadius(bottomRadius);
@@ -1547,7 +1540,7 @@ public class QuickSettingsController implements Dumpable {
@VisibleForTesting
void onHeightChanged() {
mMaxExpansionHeight = isQsFragmentCreated() ? mQs.getDesiredHeight() : 0;
- if (mExpanded && mFullyExpanded) {
+ if (getExpanded() && mFullyExpanded) {
mExpansionHeight = mMaxExpansionHeight;
if (mExpansionHeightSetToMaxListener != null) {
mExpansionHeightSetToMaxListener.onExpansionHeightSetToMax(true);
@@ -2083,7 +2076,7 @@ public class QuickSettingsController implements Dumpable {
ipw.print("mTrackingPointer=");
ipw.println(mTrackingPointer);
ipw.print("mExpanded=");
- ipw.println(mExpanded);
+ ipw.println(getExpanded());
ipw.print("mFullyExpanded=");
ipw.println(mFullyExpanded);
ipw.print("mExpandImmediate=");
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeExpansionStateManager.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeExpansionStateManager.kt
index 949398969d67..fca98f580702 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeExpansionStateManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeExpansionStateManager.kt
@@ -36,15 +36,12 @@ import javax.inject.Inject
class ShadeExpansionStateManager @Inject constructor() : ShadeStateEvents {
private val expansionListeners = CopyOnWriteArrayList<ShadeExpansionListener>()
- private val qsExpansionListeners = CopyOnWriteArrayList<ShadeQsExpansionListener>()
private val stateListeners = CopyOnWriteArrayList<ShadeStateListener>()
private val shadeStateEventsListeners = CopyOnWriteArrayList<ShadeStateEventsListener>()
@PanelState private var state: Int = STATE_CLOSED
@FloatRange(from = 0.0, to = 1.0) private var fraction: Float = 0f
private var expanded: Boolean = false
- private var qsExpanded: Boolean = false
- private var qsExpansionFraction = 0f
private var tracking: Boolean = false
private var dragDownPxAmount: Float = 0f
@@ -64,15 +61,6 @@ class ShadeExpansionStateManager @Inject constructor() : ShadeStateEvents {
expansionListeners.remove(listener)
}
- fun addQsExpansionListener(listener: ShadeQsExpansionListener) {
- qsExpansionListeners.add(listener)
- listener.onQsExpansionChanged(qsExpanded)
- }
-
- fun removeQsExpansionListener(listener: ShadeQsExpansionListener) {
- qsExpansionListeners.remove(listener)
- }
-
/** Adds a listener that will be notified when the panel state has changed. */
fun addStateListener(listener: ShadeStateListener) {
stateListeners.add(listener)
@@ -153,14 +141,6 @@ class ShadeExpansionStateManager @Inject constructor() : ShadeStateEvents {
expansionListeners.forEach { it.onPanelExpansionChanged(expansionChangeEvent) }
}
- /** Called when the quick settings expansion changes to fully expanded or collapsed. */
- fun onQsExpansionChanged(qsExpanded: Boolean) {
- this.qsExpanded = qsExpanded
-
- debugLog("qsExpanded=$qsExpanded")
- qsExpansionListeners.forEach { it.onQsExpansionChanged(qsExpanded) }
- }
-
/** Updates the panel state if necessary. */
fun updateState(@PanelState state: Int) {
debugLog(
diff --git a/packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeRepository.kt b/packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeRepository.kt
index 024c8e32a441..e2e4556f59f7 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeRepository.kt
@@ -83,6 +83,17 @@ interface ShadeRepository {
val legacyExpandedOrAwaitingInputTransfer: StateFlow<Boolean>
/**
+ * QuickSettingsController.mExpanded as a flow. Indicates that QS is in expanded state:
+ * - single pane shade: expanding shade and then expanding QS
+ * - split shade: just expanding shade (QS are expanded automatically)
+ */
+ @Deprecated("Use ShadeInteractor instead") val legacyIsQsExpanded: StateFlow<Boolean>
+
+ /** Sets whether QS is expanded. */
+ @Deprecated("Use ShadeInteractor instead")
+ fun setLegacyIsQsExpanded(legacyIsQsExpanded: Boolean)
+
+ /**
* Sets whether the expansion fraction is greater than zero or NPVC is about to accept an input
* transfer from the status bar, home screen, or trackpad.
*/
@@ -175,6 +186,15 @@ constructor(shadeExpansionStateManager: ShadeExpansionStateManager) : ShadeRepos
override val legacyExpandedOrAwaitingInputTransfer: StateFlow<Boolean> =
_legacyExpandedOrAwaitingInputTransfer.asStateFlow()
+ private val _legacyIsQsExpanded = MutableStateFlow(false)
+ @Deprecated("Use ShadeInteractor instead")
+ override val legacyIsQsExpanded: StateFlow<Boolean> = _legacyIsQsExpanded.asStateFlow()
+
+ @Deprecated("Use ShadeInteractor instead")
+ override fun setLegacyIsQsExpanded(legacyIsQsExpanded: Boolean) {
+ _legacyIsQsExpanded.value = legacyIsQsExpanded
+ }
+
@Deprecated("Use ShadeInteractor instead")
override fun setLegacyExpandedOrAwaitingInputTransfer(
legacyExpandedOrAwaitingInputTransfer: Boolean
diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractor.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractor.kt
index f043c717f923..a4c4503a6550 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractor.kt
@@ -121,16 +121,37 @@ constructor(
/**
* The amount [0-1] QS has been opened. Normal shade with notifications (QQS) visible will
- * report 0f.
+ * report 0f. If split shade is enabled, value matches shadeExpansion.
*/
val qsExpansion: StateFlow<Float> =
if (sceneContainerFlags.isEnabled()) {
- sceneBasedExpansion(sceneInteractorProvider.get(), SceneKey.QuickSettings)
+ val qsExp = sceneBasedExpansion(sceneInteractorProvider.get(), SceneKey.QuickSettings)
+ combine(isSplitShadeEnabled, shadeExpansion, qsExp) {
+ isSplitShadeEnabled,
+ shadeExp,
+ qsExp ->
+ if (isSplitShadeEnabled) {
+ shadeExp
+ } else {
+ qsExp
+ }
+ }
.stateIn(scope, SharingStarted.Eagerly, 0f)
} else {
repository.qsExpansion
}
+ /** Whether Quick Settings is expanded a non-zero amount. */
+ val isQsExpanded: StateFlow<Boolean> =
+ if (sceneContainerFlags.isEnabled()) {
+ qsExpansion
+ .map { it > 0 }
+ .distinctUntilChanged()
+ .stateIn(scope, SharingStarted.Eagerly, false)
+ } else {
+ repository.legacyIsQsExpanded
+ }
+
/** The amount [0-1] either QS or the shade has been opened. */
val anyExpansion: StateFlow<Float> =
combine(shadeExpansion, qsExpansion) { shadeExp, qsExp -> maxOf(shadeExp, qsExp) }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt b/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt
index 4ea70264b152..e19fcd05e9a4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt
@@ -32,17 +32,15 @@ import com.android.app.animation.Interpolators
import com.android.systemui.Dumpable
import com.android.systemui.Gefingerpoken
import com.android.systemui.classifier.Classifier.NOTIFICATION_DRAG_DOWN
-import com.android.systemui.classifier.FalsingCollector
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dump.DumpManager
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.res.R
-import com.android.systemui.shade.ShadeExpansionStateManager
+import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
import com.android.systemui.statusbar.notification.row.ExpandableView
-import com.android.systemui.statusbar.notification.stack.NotificationRoundnessManager
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.statusbar.policy.ConfigurationController
@@ -64,13 +62,11 @@ constructor(
private val wakeUpCoordinator: NotificationWakeUpCoordinator,
private val bypassController: KeyguardBypassController,
private val headsUpManager: HeadsUpManager,
- private val roundnessManager: NotificationRoundnessManager,
configurationController: ConfigurationController,
private val statusBarStateController: StatusBarStateController,
private val falsingManager: FalsingManager,
- shadeExpansionStateManager: ShadeExpansionStateManager,
+ private val shadeInteractor: ShadeInteractor,
private val lockscreenShadeTransitionController: LockscreenShadeTransitionController,
- private val falsingCollector: FalsingCollector,
dumpManager: DumpManager
) : Gefingerpoken, Dumpable {
companion object {
@@ -115,7 +111,6 @@ constructor(
private val isFalseTouch: Boolean
get() = falsingManager.isFalseTouch(NOTIFICATION_DRAG_DOWN)
- var qsExpanded: Boolean = false
var pulseExpandAbortListener: Runnable? = null
var bouncerShowing: Boolean = false
@@ -127,12 +122,6 @@ constructor(
}
})
- shadeExpansionStateManager.addQsExpansionListener { isQsExpanded ->
- if (qsExpanded != isQsExpanded) {
- qsExpanded = isQsExpanded
- }
- }
-
mPowerManager = context.getSystemService(PowerManager::class.java)
dumpManager.registerDumpable(this)
}
@@ -148,7 +137,8 @@ constructor(
}
private fun canHandleMotionEvent(): Boolean {
- return wakeUpCoordinator.canShowPulsingHuns && !qsExpanded && !bouncerShowing
+ return wakeUpCoordinator.canShowPulsingHuns && !shadeInteractor.isQsExpanded.value &&
+ !bouncerShowing
}
private fun startExpansion(event: MotionEvent): Boolean {
@@ -379,7 +369,6 @@ constructor(
it.println("isExpanding: $isExpanding")
it.println("leavingLockscreen: $leavingLockscreen")
it.println("mPulsing: $mPulsing")
- it.println("qsExpanded: $qsExpanded")
it.println("bouncerShowing: $bouncerShowing")
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt
index 5af7cfc212d5..a36d36c3827b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt
@@ -16,7 +16,6 @@
package com.android.systemui.statusbar.events
-import androidx.core.animation.Animator
import android.annotation.UiThread
import android.graphics.Point
import android.graphics.Rect
@@ -24,13 +23,15 @@ import android.util.Log
import android.view.Gravity
import android.view.View
import android.widget.FrameLayout
-import com.android.internal.annotations.GuardedBy
-import com.android.systemui.res.R
+import androidx.core.animation.Animator
import com.android.app.animation.Interpolators
+import com.android.internal.annotations.GuardedBy
import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.plugins.statusbar.StatusBarStateController
-import com.android.systemui.shade.ShadeExpansionStateManager
+import com.android.systemui.res.R
+import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.statusbar.StatusBarState.SHADE
import com.android.systemui.statusbar.StatusBarState.SHADE_LOCKED
import com.android.systemui.statusbar.phone.StatusBarContentInsetsChangedListener
@@ -43,6 +44,8 @@ import com.android.systemui.util.leak.RotationUtils.ROTATION_NONE
import com.android.systemui.util.leak.RotationUtils.ROTATION_SEASCAPE
import com.android.systemui.util.leak.RotationUtils.ROTATION_UPSIDE_DOWN
import com.android.systemui.util.leak.RotationUtils.Rotation
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
import java.util.concurrent.Executor
import javax.inject.Inject
@@ -64,11 +67,12 @@ import javax.inject.Inject
@SysUISingleton
open class PrivacyDotViewController @Inject constructor(
@Main private val mainExecutor: Executor,
+ @Application scope: CoroutineScope,
private val stateController: StatusBarStateController,
private val configurationController: ConfigurationController,
private val contentInsetsProvider: StatusBarContentInsetsProvider,
private val animationScheduler: SystemStatusAnimationScheduler,
- shadeExpansionStateManager: ShadeExpansionStateManager
+ shadeInteractor: ShadeInteractor?
) {
private lateinit var tl: View
private lateinit var tr: View
@@ -135,10 +139,12 @@ open class PrivacyDotViewController @Inject constructor(
}
})
- shadeExpansionStateManager.addQsExpansionListener { isQsExpanded ->
- dlog("setQsExpanded $isQsExpanded")
- synchronized(lock) {
- nextViewState = nextViewState.copy(qsExpanded = isQsExpanded)
+ scope.launch {
+ shadeInteractor?.isQsExpanded?.collect { isQsExpanded ->
+ dlog("setQsExpanded $isQsExpanded")
+ synchronized(lock) {
+ nextViewState = nextViewState.copy(qsExpanded = isQsExpanded)
+ }
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java
index 301ddbf42ff2..f2ade340fc4f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java
@@ -16,6 +16,9 @@
package com.android.systemui.statusbar.notification.interruption;
+import static android.provider.Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED;
+import static android.provider.Settings.Global.HEADS_UP_OFF;
+
import static com.android.systemui.statusbar.StatusBarState.SHADE;
import static com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProviderImpl.NotificationInterruptEvent.FSI_SUPPRESSED_NO_HUN_OR_KEYGUARD;
import static com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProviderImpl.NotificationInterruptEvent.FSI_SUPPRESSED_SUPPRESSIVE_BUBBLE_METADATA;
@@ -24,12 +27,10 @@ import static com.android.systemui.statusbar.notification.interruption.Notificat
import android.app.Notification;
import android.app.NotificationManager;
-import android.content.ContentResolver;
import android.database.ContentObserver;
import android.hardware.display.AmbientDisplayConfiguration;
import android.os.Handler;
import android.os.PowerManager;
-import android.provider.Settings;
import android.service.notification.StatusBarNotification;
import androidx.annotation.NonNull;
@@ -48,6 +49,8 @@ import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.util.settings.GlobalSettings;
+import com.android.systemui.util.time.SystemClock;
import java.util.ArrayList;
import java.util.List;
@@ -66,7 +69,6 @@ public class NotificationInterruptStateProviderImpl implements NotificationInter
private final List<NotificationInterruptSuppressor> mSuppressors = new ArrayList<>();
private final StatusBarStateController mStatusBarStateController;
private final KeyguardStateController mKeyguardStateController;
- private final ContentResolver mContentResolver;
private final PowerManager mPowerManager;
private final AmbientDisplayConfiguration mAmbientDisplayConfiguration;
private final BatteryController mBatteryController;
@@ -77,6 +79,8 @@ public class NotificationInterruptStateProviderImpl implements NotificationInter
private final UiEventLogger mUiEventLogger;
private final UserTracker mUserTracker;
private final DeviceProvisionedController mDeviceProvisionedController;
+ private final SystemClock mSystemClock;
+ private final GlobalSettings mGlobalSettings;
@VisibleForTesting
protected boolean mUseHeadsUp = false;
@@ -111,7 +115,6 @@ public class NotificationInterruptStateProviderImpl implements NotificationInter
@Inject
public NotificationInterruptStateProviderImpl(
- ContentResolver contentResolver,
PowerManager powerManager,
AmbientDisplayConfiguration ambientDisplayConfiguration,
BatteryController batteryController,
@@ -124,8 +127,9 @@ public class NotificationInterruptStateProviderImpl implements NotificationInter
KeyguardNotificationVisibilityProvider keyguardNotificationVisibilityProvider,
UiEventLogger uiEventLogger,
UserTracker userTracker,
- DeviceProvisionedController deviceProvisionedController) {
- mContentResolver = contentResolver;
+ DeviceProvisionedController deviceProvisionedController,
+ SystemClock systemClock,
+ GlobalSettings globalSettings) {
mPowerManager = powerManager;
mBatteryController = batteryController;
mAmbientDisplayConfiguration = ambientDisplayConfiguration;
@@ -137,15 +141,16 @@ public class NotificationInterruptStateProviderImpl implements NotificationInter
mKeyguardNotificationVisibilityProvider = keyguardNotificationVisibilityProvider;
mUiEventLogger = uiEventLogger;
mUserTracker = userTracker;
+ mDeviceProvisionedController = deviceProvisionedController;
+ mSystemClock = systemClock;
+ mGlobalSettings = globalSettings;
ContentObserver headsUpObserver = new ContentObserver(mainHandler) {
@Override
public void onChange(boolean selfChange) {
- boolean wasUsing = mUseHeadsUp;
- mUseHeadsUp = ENABLE_HEADS_UP
- && Settings.Global.HEADS_UP_OFF != Settings.Global.getInt(
- mContentResolver,
- Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED,
- Settings.Global.HEADS_UP_OFF);
+ final boolean wasUsing = mUseHeadsUp;
+ final boolean settingEnabled = HEADS_UP_OFF
+ != mGlobalSettings.getInt(HEADS_UP_NOTIFICATIONS_ENABLED, HEADS_UP_OFF);
+ mUseHeadsUp = ENABLE_HEADS_UP && settingEnabled;
mLogger.logHeadsUpFeatureChanged(mUseHeadsUp);
if (wasUsing != mUseHeadsUp) {
if (!mUseHeadsUp) {
@@ -157,16 +162,15 @@ public class NotificationInterruptStateProviderImpl implements NotificationInter
};
if (ENABLE_HEADS_UP) {
- mContentResolver.registerContentObserver(
- Settings.Global.getUriFor(Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED),
+ mGlobalSettings.registerContentObserver(
+ mGlobalSettings.getUriFor(HEADS_UP_NOTIFICATIONS_ENABLED),
true,
headsUpObserver);
- mContentResolver.registerContentObserver(
- Settings.Global.getUriFor(SETTING_HEADS_UP_TICKER), true,
+ mGlobalSettings.registerContentObserver(
+ mGlobalSettings.getUriFor(SETTING_HEADS_UP_TICKER), true,
headsUpObserver);
}
headsUpObserver.onChange(true); // set up
- mDeviceProvisionedController = deviceProvisionedController;
}
@Override
@@ -603,7 +607,7 @@ public class NotificationInterruptStateProviderImpl implements NotificationInter
}
final long when = notification.when;
- final long now = System.currentTimeMillis();
+ final long now = mSystemClock.currentTimeMillis();
final long age = now - when;
if (age < MAX_HUN_WHEN_AGE_MS) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProvider.kt
index 920bbe96b33b..7ead4bf3ed66 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProvider.kt
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package com.android.systemui.statusbar.notification.interruption
import com.android.systemui.statusbar.notification.collection.NotificationEntry
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionRefactor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionRefactor.kt
new file mode 100644
index 000000000000..2624363c7dec
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionRefactor.kt
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.interruption
+
+import com.android.systemui.Flags
+import com.android.systemui.flags.RefactorFlagUtils
+
+/** Helper for reading or using the visual interruptions refactor flag state. */
+object VisualInterruptionRefactor {
+ const val FLAG_NAME = Flags.FLAG_VISUAL_INTERRUPTIONS_REFACTOR
+
+ /** Whether the refactor is enabled */
+ @JvmStatic
+ inline val isEnabled
+ get() = Flags.visualInterruptionsRefactor()
+
+ /**
+ * Called to ensure code is only run when the flag is enabled. This protects users from the
+ * unintended behaviors caused by accidentally running new logic, while also crashing on an eng
+ * build to ensure that the refactor author catches issues in testing.
+ */
+ @JvmStatic
+ inline fun isUnexpectedlyInLegacyMode() =
+ RefactorFlagUtils.isUnexpectedlyInLegacyMode(isEnabled, FLAG_NAME)
+
+ /**
+ * Called to ensure code is only run when the flag is disabled. This will throw an exception if
+ * the flag is enabled to ensure that the refactor author catches issues in testing.
+ */
+ @JvmStatic
+ inline fun assertInLegacyMode() = RefactorFlagUtils.assertInLegacyMode(isEnabled, FLAG_NAME)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionSuppressor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionSuppressor.kt
index 4ef80e38bc63..d524637443cb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionSuppressor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionSuppressor.kt
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package com.android.systemui.statusbar.notification.interruption
import com.android.internal.logging.UiEventLogger.UiEventEnum
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt
index 2af7181f2f31..6785da4bf4f1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt
@@ -59,10 +59,8 @@ object SharedNotificationContainerBinder {
launch {
viewModel.position.collect {
- controller.updateTopPadding(
- it.top,
- controller.isAddOrRemoveAnimationPending()
- )
+ val animate = it.animate || controller.isAddOrRemoveAnimationPending()
+ controller.updateTopPadding(it.top, animate)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
index 1229cb9b49ac..b86b5dcc7939 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
@@ -25,6 +25,7 @@ import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
import com.android.systemui.statusbar.notification.stack.NotificationStackSizeCalculator
import com.android.systemui.statusbar.notification.stack.domain.interactor.SharedNotificationContainerInteractor
+import com.android.systemui.util.kotlin.sample
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
@@ -118,8 +119,15 @@ constructor(
}
}
} else {
- interactor.topPosition.map { top ->
- keyguardInteractor.sharedNotificationContainerPosition.value.copy(top = top)
+ interactor.topPosition.sample(shadeInteractor.qsExpansion, ::Pair).map {
+ (top, qsExpansion) ->
+ // When QS expansion > 0, it should directly set the top padding so do not
+ // animate it
+ val animate = qsExpansion == 0f
+ keyguardInteractor.sharedNotificationContainerPosition.value.copy(
+ top = top,
+ animate = animate
+ )
}
}
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerTest.java
index 4bacc3dfca0d..adcec10f9172 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerTest.java
@@ -20,7 +20,6 @@ import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRIN
import static com.android.keyguard.LockIconView.ICON_LOCK;
import static com.android.keyguard.LockIconView.ICON_UNLOCK;
-import static com.android.systemui.flags.Flags.ONE_WAY_HAPTICS_API_MIGRATION;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.anyBoolean;
@@ -354,26 +353,8 @@ public class LockIconViewControllerTest extends LockIconViewControllerBaseTest {
}
@Test
- public void playHaptic_onTouchExploration_NoOneWayHaptics_usesVibrate() {
- mFeatureFlags.set(ONE_WAY_HAPTICS_API_MIGRATION, false);
-
- // WHEN request to vibrate on touch exploration
- mUnderTest.vibrateOnTouchExploration();
-
- // THEN vibrates
- verify(mVibrator).vibrate(
- anyInt(),
- any(),
- eq(UdfpsController.EFFECT_CLICK),
- eq("lock-icon-down"),
- any());
- }
-
- @Test
- public void playHaptic_onTouchExploration_withOneWayHaptics_performHapticFeedback() {
- mFeatureFlags.set(ONE_WAY_HAPTICS_API_MIGRATION, true);
-
- // WHEN request to vibrate on touch exploration
+ public void playHaptic_onTouchExploration_performHapticFeedback() {
+ // WHEN request to vibrate on touch exploration
mUnderTest.vibrateOnTouchExploration();
// THEN performHapticFeedback is used
@@ -381,25 +362,7 @@ public class LockIconViewControllerTest extends LockIconViewControllerBaseTest {
}
@Test
- public void playHaptic_onLongPress_NoOneWayHaptics_usesVibrate() {
- mFeatureFlags.set(ONE_WAY_HAPTICS_API_MIGRATION, false);
-
- // WHEN request to vibrate on long press
- mUnderTest.vibrateOnLongPress();
-
- // THEN uses vibrate
- verify(mVibrator).vibrate(
- anyInt(),
- any(),
- eq(UdfpsController.EFFECT_CLICK),
- eq("lock-screen-lock-icon-longpress"),
- any());
- }
-
- @Test
- public void playHaptic_onLongPress_withOneWayHaptics_performHapticFeedback() {
- mFeatureFlags.set(ONE_WAY_HAPTICS_API_MIGRATION, true);
-
+ public void playHaptic_onLongPress_performHapticFeedback() {
// WHEN request to vibrate on long press
mUnderTest.vibrateOnLongPress();
@@ -411,7 +374,6 @@ public class LockIconViewControllerTest extends LockIconViewControllerBaseTest {
public void longPress_showBouncer_sceneContainerNotEnabled() {
init(/* useMigrationFlag= */ false);
mSceneTestUtils.getSceneContainerFlags().setEnabled(false);
- mFeatureFlags.set(ONE_WAY_HAPTICS_API_MIGRATION, true);
when(mFalsingManager.isFalseLongTap(anyInt())).thenReturn(false);
// WHEN longPress
@@ -426,7 +388,6 @@ public class LockIconViewControllerTest extends LockIconViewControllerBaseTest {
public void longPress_showBouncer() {
init(/* useMigrationFlag= */ false);
mSceneTestUtils.getSceneContainerFlags().setEnabled(true);
- mFeatureFlags.set(ONE_WAY_HAPTICS_API_MIGRATION, true);
when(mFalsingManager.isFalseLongTap(anyInt())).thenReturn(false);
// WHEN longPress
@@ -441,7 +402,6 @@ public class LockIconViewControllerTest extends LockIconViewControllerBaseTest {
public void longPress_falsingTriggered_doesNotShowBouncer() {
init(/* useMigrationFlag= */ false);
mSceneTestUtils.getSceneContainerFlags().setEnabled(true);
- mFeatureFlags.set(ONE_WAY_HAPTICS_API_MIGRATION, true);
when(mFalsingManager.isFalseLongTap(anyInt())).thenReturn(true);
// WHEN longPress
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java
index 06421dbbf2bb..044881e57897 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java
@@ -1072,6 +1072,7 @@ public class WindowMagnificationControllerTest extends SysuiTestCase {
assertTrue(TextUtils.equals(newA11yWindowTitle, getAccessibilityWindowTitle()));
}
+ @Ignore("it's flaky in presubmit but works in abtd, filter for now. b/305654925")
@Test
public void onSingleTap_enabled_scaleAnimates() {
mInstrumentation.runOnMainSync(() -> {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
index f899e2fb968a..5e7b85779599 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
@@ -505,7 +505,6 @@ open class AuthContainerViewTest : SysuiTestCase() {
this.authenticators = authenticators
}
},
- featureFlags,
testScope.backgroundScope,
fingerprintProps,
faceProps,
@@ -519,9 +518,7 @@ open class AuthContainerViewTest : SysuiTestCase() {
PromptViewModel(
displayStateInteractor,
promptSelectorInteractor,
- vibrator,
context,
- featureFlags
),
{ credentialViewModel },
Handler(TestableLooper.get(this).looper),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
index 885abcb72f1a..11c5d3bb27b3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
@@ -88,7 +88,6 @@ import com.android.systemui.biometrics.domain.interactor.PromptCredentialInterac
import com.android.systemui.biometrics.domain.interactor.PromptSelectorInteractor;
import com.android.systemui.biometrics.ui.viewmodel.CredentialViewModel;
import com.android.systemui.biometrics.ui.viewmodel.PromptViewModel;
-import com.android.systemui.flags.FakeFeatureFlags;
import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.VibratorHelper;
@@ -195,7 +194,6 @@ public class AuthControllerTest extends SysuiTestCase {
private Handler mHandler;
private DelayableExecutor mBackgroundExecutor;
private TestableAuthController mAuthController;
- private FakeFeatureFlags mFeatureFlags = new FakeFeatureFlags();
@Before
public void setup() throws RemoteException {
@@ -1023,7 +1021,7 @@ public class AuthControllerTest extends SysuiTestCase {
private PromptInfo mLastBiometricPromptInfo;
TestableAuthController(Context context) {
- super(context, mFeatureFlags, null /* applicationCoroutineScope */,
+ super(context, null /* applicationCoroutineScope */,
mExecution, mCommandQueue, mActivityTaskManager, mWindowManager,
mFingerprintManager, mFaceManager, () -> mUdfpsController,
() -> mSideFpsController, mDisplayManager, mWakefulnessLifecycle,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt
index b695a0ee1fa3..d06cbbb5e433 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt
@@ -44,18 +44,16 @@ import com.android.systemui.biometrics.shared.model.toSensorType
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.coroutines.collectValues
import com.android.systemui.display.data.repository.FakeDisplayRepository
-import com.android.systemui.flags.FakeFeatureFlags
-import com.android.systemui.flags.Flags.ONE_WAY_HAPTICS_API_MIGRATION
import com.android.systemui.res.R
import com.android.systemui.statusbar.VibratorHelper
import com.android.systemui.util.concurrency.FakeExecutor
-import com.android.systemui.util.mockito.any
import com.android.systemui.util.time.FakeSystemClock
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.advanceUntilIdle
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Before
@@ -64,9 +62,7 @@ import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
import org.mockito.Mock
-import org.mockito.Mockito.never
import org.mockito.Mockito.times
-import org.mockito.Mockito.verify
import org.mockito.junit.MockitoJUnit
private const val USER_ID = 4
@@ -95,7 +91,6 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa
private lateinit var selector: PromptSelectorInteractor
private lateinit var viewModel: PromptViewModel
private lateinit var iconViewModel: PromptIconViewModel
- private val featureFlags = FakeFeatureFlags()
@Before
fun setup() {
@@ -125,10 +120,8 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa
PromptSelectorInteractorImpl(fingerprintRepository, promptRepository, lockPatternUtils)
selector.resetPrompt()
- viewModel =
- PromptViewModel(displayStateInteractor, selector, vibrator, mContext, featureFlags)
+ viewModel = PromptViewModel(displayStateInteractor, selector, mContext)
iconViewModel = viewModel.iconViewModel
- featureFlags.set(ONE_WAY_HAPTICS_API_MIGRATION, false)
}
@Test
@@ -180,26 +173,29 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa
}
@Test
- fun play_haptic_on_confirm_when_confirmation_required_otherwise_on_authenticated() =
+ fun set_haptic_on_confirm_when_confirmation_required_otherwise_on_authenticated() =
runGenericTest {
val expectConfirmation = testCase.expectConfirmation(atLeastOneFailure = false)
viewModel.showAuthenticated(testCase.authenticatedModality, 1_000L)
- verify(vibrator, if (expectConfirmation) never() else times(1))
- .vibrateAuthSuccess(any())
+ val confirmConstant by collectLastValue(viewModel.hapticsToPlay)
+ assertThat(confirmConstant)
+ .isEqualTo(
+ if (expectConfirmation) HapticFeedbackConstants.NO_HAPTICS
+ else HapticFeedbackConstants.CONFIRM
+ )
if (expectConfirmation) {
viewModel.confirmAuthenticated()
}
- verify(vibrator).vibrateAuthSuccess(any())
- verify(vibrator, never()).vibrateAuthError(any())
+ val confirmedConstant by collectLastValue(viewModel.hapticsToPlay)
+ assertThat(confirmedConstant).isEqualTo(HapticFeedbackConstants.CONFIRM)
}
@Test
- fun playSuccessHaptic_onwayHapticsEnabled_SetsConfirmConstant() = runGenericTest {
- featureFlags.set(ONE_WAY_HAPTICS_API_MIGRATION, true)
+ fun playSuccessHaptic_SetsConfirmConstant() = runGenericTest {
val expectConfirmation = testCase.expectConfirmation(atLeastOneFailure = false)
viewModel.showAuthenticated(testCase.authenticatedModality, 1_000L)
@@ -212,8 +208,7 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa
}
@Test
- fun playErrorHaptic_onwayHapticsEnabled_SetsRejectConstant() = runGenericTest {
- featureFlags.set(ONE_WAY_HAPTICS_API_MIGRATION, true)
+ fun playErrorHaptic_SetsRejectConstant() = runGenericTest {
viewModel.showTemporaryError("test", "messageAfterError", false)
val currentConstant by collectLastValue(viewModel.hapticsToPlay)
@@ -251,7 +246,8 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa
DisplayRotation.ROTATION_180 ->
R.raw.biometricprompt_fingerprint_to_error_landscape
DisplayRotation.ROTATION_270 ->
- R.raw.biometricprompt_symbol_fingerprint_to_error_portrait_bottomright
+ R.raw
+ .biometricprompt_symbol_fingerprint_to_error_portrait_bottomright
else -> throw Exception("invalid rotation")
}
assertThat(iconOverlayAsset).isEqualTo(expectedOverlayAsset)
@@ -496,7 +492,8 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa
DisplayRotation.ROTATION_180 ->
R.raw.biometricprompt_symbol_fingerprint_to_success_landscape
DisplayRotation.ROTATION_270 ->
- R.raw.biometricprompt_symbol_fingerprint_to_success_portrait_bottomright
+ R.raw
+ .biometricprompt_symbol_fingerprint_to_success_portrait_bottomright
else -> throw Exception("invalid rotation")
}
assertThat(iconOverlayAsset).isEqualTo(expectedOverlayAsset)
@@ -733,7 +730,7 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa
}
@Test
- fun plays_haptic_on_errors() = runGenericTest {
+ fun set_haptic_on_errors() = runGenericTest {
viewModel.showTemporaryError(
"so sad",
messageAfterError = "",
@@ -741,8 +738,8 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa
hapticFeedback = true,
)
- verify(vibrator).vibrateAuthError(any())
- verify(vibrator, never()).vibrateAuthSuccess(any())
+ val constant by collectLastValue(viewModel.hapticsToPlay)
+ assertThat(constant).isEqualTo(HapticFeedbackConstants.REJECT)
}
@Test
@@ -754,8 +751,8 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa
hapticFeedback = false,
)
- verify(vibrator, never()).vibrateAuthError(any())
- verify(vibrator, never()).vibrateAuthSuccess(any())
+ val constant by collectLastValue(viewModel.hapticsToPlay)
+ assertThat(constant).isEqualTo(HapticFeedbackConstants.NO_HAPTICS)
}
private suspend fun TestScope.showTemporaryErrors(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingCollectorImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingCollectorImplTest.java
index 80fe9e762832..fcb18f52086d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingCollectorImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingCollectorImplTest.java
@@ -26,6 +26,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
import android.view.MotionEvent;
import androidx.test.filters.SmallTest;
@@ -35,13 +36,14 @@ import com.android.systemui.SysuiTestCase;
import com.android.systemui.dock.DockManager;
import com.android.systemui.dock.DockManagerFake;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.shade.ShadeExpansionStateManager;
+import com.android.systemui.shade.domain.interactor.ShadeInteractor;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.user.domain.interactor.SelectedUserInteractor;
import com.android.systemui.util.concurrency.FakeExecutor;
+import com.android.systemui.util.kotlin.JavaAdapter;
import com.android.systemui.util.sensors.ProximitySensor;
import com.android.systemui.util.sensors.ThresholdSensor;
import com.android.systemui.util.time.FakeSystemClock;
@@ -54,8 +56,11 @@ import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import kotlinx.coroutines.flow.StateFlowKt;
+
@SmallTest
@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
public class FalsingCollectorImplTest extends SysuiTestCase {
private FalsingCollectorImpl mFalsingCollector;
@@ -73,7 +78,9 @@ public class FalsingCollectorImplTest extends SysuiTestCase {
@Mock
private KeyguardStateController mKeyguardStateController;
@Mock
- private ShadeExpansionStateManager mShadeExpansionStateManager;
+ private ShadeInteractor mShadeInteractor;
+ @Mock
+ private JavaAdapter mJavaAdapter;
@Mock
private BatteryController mBatteryController;
@Mock
@@ -88,12 +95,16 @@ public class FalsingCollectorImplTest extends SysuiTestCase {
when(mStatusBarStateController.getState()).thenReturn(StatusBarState.KEYGUARD);
when(mKeyguardStateController.isShowing()).thenReturn(true);
+ when(mShadeInteractor.isQsExpanded()).thenReturn(StateFlowKt.MutableStateFlow(false));
mFalsingCollector = new FalsingCollectorImpl(mFalsingDataProvider, mFalsingManager,
mKeyguardUpdateMonitor, mHistoryTracker, mProximitySensor,
- mStatusBarStateController, mKeyguardStateController, mShadeExpansionStateManager,
- mBatteryController,
- mDockManager, mFakeExecutor, mFakeSystemClock, () -> mSelectedUserInteractor);
+ mStatusBarStateController, mKeyguardStateController,
+ () -> mShadeInteractor, mBatteryController,
+ mDockManager, mFakeExecutor,
+ mJavaAdapter, mFakeSystemClock, () -> mSelectedUserInteractor
+ );
+ mFalsingCollector.init();
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java
index 3af444a789c5..27fd3b13d55a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java
@@ -165,12 +165,28 @@ public class DozeScreenBrightnessTest extends SysuiTestCase {
int maxBrightness = 3;
when(mSystemSettings.getIntForUser(eq(Settings.System.SCREEN_BRIGHTNESS), anyInt(),
eq(UserHandle.USER_CURRENT))).thenReturn(maxBrightness);
+ when(mSystemSettings.getIntForUser(eq(Settings.System.SCREEN_BRIGHTNESS_MODE), anyInt(),
+ eq(UserHandle.USER_CURRENT)))
+ .thenReturn(Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL);
mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
assertEquals(maxBrightness, mServiceFake.screenBrightness);
}
@Test
+ public void testAod_usesLightSensorNotClampingToAutoBrightnessValue() {
+ int maxBrightness = 3;
+ when(mSystemSettings.getIntForUser(eq(Settings.System.SCREEN_BRIGHTNESS), anyInt(),
+ eq(UserHandle.USER_CURRENT))).thenReturn(maxBrightness);
+ when(mSystemSettings.getIntForUser(eq(Settings.System.SCREEN_BRIGHTNESS_MODE), anyInt(),
+ eq(UserHandle.USER_CURRENT)))
+ .thenReturn(Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
+
+ mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
+ assertEquals(DEFAULT_BRIGHTNESS, mServiceFake.screenBrightness);
+ }
+
+ @Test
public void doze_doesNotUseLightSensor() {
// GIVEN the device is DOZE and the display state changes to ON
mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
index 2b280c05ba1b..814a317a72f8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
@@ -253,7 +253,6 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
mKeyguardStateController,
mScreenOffAnimationController,
mAuthController,
- mShadeExpansionStateManager,
() -> mShadeInteractor,
mShadeWindowLogger,
() -> mSelectedUserInteractor);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt
index 4f545cb0e288..b80771ff646c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt
@@ -179,6 +179,8 @@ class KeyguardRootViewModelTest : SysuiTestCase() {
val translationY by collectLastValue(underTest.translationY)
val scale by collectLastValue(underTest.scale)
+ underTest.statusViewTop = 100
+
// Set to dozing (on AOD)
dozeAmountTransitionStep.emit(TransitionStep(value = 1f))
// Trigger a change to the burn-in model
@@ -200,6 +202,37 @@ class KeyguardRootViewModelTest : SysuiTestCase() {
}
@Test
+ fun translationAndScaleFromBurnFullyDozingStaysOutOfTopInset() =
+ testScope.runTest {
+ val translationX by collectLastValue(underTest.translationX)
+ val translationY by collectLastValue(underTest.translationY)
+ val scale by collectLastValue(underTest.scale)
+
+ underTest.statusViewTop = 100
+ underTest.topInset = 80
+
+ // Set to dozing (on AOD)
+ dozeAmountTransitionStep.emit(TransitionStep(value = 1f))
+ // Trigger a change to the burn-in model
+ burnInFlow.value =
+ BurnInModel(
+ translationX = 20,
+ translationY = -30,
+ scale = 0.5f,
+ )
+ assertThat(translationX).isEqualTo(20)
+ // -20 instead of -30, due to inset of 80
+ assertThat(translationY).isEqualTo(-20)
+ assertThat(scale).isEqualTo(Pair(0.5f, true /* scaleClockOnly */))
+
+ // Set to the beginning of GONE->AOD transition
+ goneToAodTransitionStep.emit(TransitionStep(value = 0f))
+ assertThat(translationX).isEqualTo(0)
+ assertThat(translationY).isEqualTo(0)
+ assertThat(scale).isEqualTo(Pair(1f, true /* scaleClockOnly */))
+ }
+
+ @Test
fun translationAndScaleFromBurnInUseScaleOnly() =
testScope.runTest {
whenever(clockController.config.useAlternateSmartspaceAODTransition).thenReturn(true)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
index 2ce4b04b037a..446a0b8116a6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
@@ -99,7 +99,6 @@ import com.android.systemui.keyguard.domain.interactor.KeyguardFaceAuthInteracto
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor;
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory;
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
-import com.android.systemui.keyguard.ui.view.KeyguardRootView;
import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel;
import com.android.systemui.keyguard.ui.viewmodel.GoneToDreamingLockscreenHostedTransitionViewModel;
import com.android.systemui.keyguard.ui.viewmodel.GoneToDreamingTransitionViewModel;
@@ -148,7 +147,6 @@ import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator
import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
import com.android.systemui.statusbar.notification.stack.AmbientState;
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
-import com.android.systemui.statusbar.notification.stack.NotificationRoundnessManager;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
import com.android.systemui.statusbar.notification.stack.NotificationStackSizeCalculator;
@@ -335,7 +333,6 @@ public class NotificationPanelViewControllerBaseTest extends SysuiTestCase {
@Mock protected KeyguardFaceAuthInteractor mKeyguardFaceAuthInteractor;
@Mock private JavaAdapter mJavaAdapter;
@Mock private CastController mCastController;
- @Mock private KeyguardRootView mKeyguardRootView;
@Mock private SharedNotificationContainerInteractor mSharedNotificationContainerInteractor;
@Mock private KeyguardClockPositionAlgorithm mKeyguardClockPositionAlgorithm;
@@ -575,14 +572,13 @@ public class NotificationPanelViewControllerBaseTest extends SysuiTestCase {
PulseExpansionHandler expansionHandler = new PulseExpansionHandler(
mContext,
coordinator,
- mKeyguardBypassController, mHeadsUpManager,
- mock(NotificationRoundnessManager.class),
+ mKeyguardBypassController,
+ mHeadsUpManager,
mConfigurationController,
mStatusBarStateController,
mFalsingManager,
- mShadeExpansionStateManager,
+ mShadeInteractor,
mLockscreenShadeTransitionController,
- new FalsingCollectorFake(),
mDumpManager);
when(mKeyguardStatusViewComponentFactory.build(any(), any()))
.thenReturn(mKeyguardStatusViewComponent);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java
index 4ba850c570c4..8e0cf7d7f695 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java
@@ -254,7 +254,6 @@ public class NotificationShadeWindowControllerImplTest extends SysuiTestCase {
mKeyguardStateController,
mScreenOffAnimationController,
mAuthController,
- mShadeExpansionStateManager,
() -> mShadeInteractor,
mShadeWindowLogger,
() -> mSelectedUserInteractor) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQSContainerControllerLegacyTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQSContainerControllerLegacyTest.kt
index e70dbc7f4fda..778cfa67cad7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQSContainerControllerLegacyTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQSContainerControllerLegacyTest.kt
@@ -18,7 +18,6 @@ package com.android.systemui.shade
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
-import android.testing.TestableResources
import android.view.View
import android.view.ViewGroup
import android.view.WindowInsets
@@ -27,7 +26,6 @@ import androidx.annotation.IdRes
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet
import androidx.test.filters.SmallTest
-import com.android.systemui.res.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.flags.Flags
@@ -38,6 +36,8 @@ import com.android.systemui.navigationbar.NavigationModeController.ModeChangedLi
import com.android.systemui.plugins.qs.QS
import com.android.systemui.recents.OverviewProxyService
import com.android.systemui.recents.OverviewProxyService.OverviewProxyListener
+import com.android.systemui.res.R
+import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController
import com.android.systemui.util.concurrency.FakeExecutor
@@ -46,6 +46,7 @@ import com.android.systemui.util.mockito.whenever
import com.android.systemui.util.time.FakeSystemClock
import com.google.common.truth.Truth.assertThat
import java.util.function.Consumer
+import kotlinx.coroutines.flow.MutableStateFlow
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -66,7 +67,7 @@ import org.mockito.MockitoAnnotations
/** Uses Flags.MIGRATE_NSSL set to false. If all goes well, this set of tests will be deleted. */
@RunWith(AndroidTestingRunner::class)
-@TestableLooper.RunWithLooper
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
@SmallTest
class NotificationsQSContainerControllerLegacyTest : SysuiTestCase() {
@@ -74,7 +75,7 @@ class NotificationsQSContainerControllerLegacyTest : SysuiTestCase() {
@Mock lateinit var navigationModeController: NavigationModeController
@Mock lateinit var overviewProxyService: OverviewProxyService
@Mock lateinit var shadeHeaderController: ShadeHeaderController
- @Mock lateinit var shadeExpansionStateManager: ShadeExpansionStateManager
+ @Mock lateinit var shadeInteractor: ShadeInteractor
@Mock lateinit var fragmentService: FragmentService
@Mock lateinit var fragmentHostManager: FragmentHostManager
@Mock
@@ -88,7 +89,6 @@ class NotificationsQSContainerControllerLegacyTest : SysuiTestCase() {
lateinit var underTest: NotificationsQSContainerController
- private lateinit var fakeResources: TestableResources
private lateinit var featureFlags: FakeFeatureFlags
private lateinit var navigationModeCallback: ModeChangedListener
private lateinit var taskbarVisibilityCallback: OverviewProxyListener
@@ -111,6 +111,7 @@ class NotificationsQSContainerControllerLegacyTest : SysuiTestCase() {
whenever(view.resources).thenReturn(mContext.resources)
whenever(fragmentService.getFragmentHostManager(any())).thenReturn(fragmentHostManager)
+ whenever(shadeInteractor.isQsExpanded).thenReturn(MutableStateFlow(false))
underTest =
NotificationsQSContainerController(
@@ -118,7 +119,7 @@ class NotificationsQSContainerControllerLegacyTest : SysuiTestCase() {
navigationModeController,
overviewProxyService,
shadeHeaderController,
- shadeExpansionStateManager,
+ shadeInteractor,
fragmentService,
delayableExecutor,
featureFlags,
@@ -475,7 +476,7 @@ class NotificationsQSContainerControllerLegacyTest : SysuiTestCase() {
navigationModeController,
overviewProxyService,
shadeHeaderController,
- shadeExpansionStateManager,
+ shadeInteractor,
fragmentService,
delayableExecutor,
featureFlags,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQSContainerControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQSContainerControllerTest.kt
index ac8c924fe689..23420037e233 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQSContainerControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQSContainerControllerTest.kt
@@ -18,7 +18,6 @@ package com.android.systemui.shade
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
-import android.testing.TestableResources
import android.view.View
import android.view.ViewGroup
import android.view.WindowInsets
@@ -27,7 +26,6 @@ import androidx.annotation.IdRes
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet
import androidx.test.filters.SmallTest
-import com.android.systemui.res.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.flags.Flags
@@ -38,6 +36,8 @@ import com.android.systemui.navigationbar.NavigationModeController.ModeChangedLi
import com.android.systemui.plugins.qs.QS
import com.android.systemui.recents.OverviewProxyService
import com.android.systemui.recents.OverviewProxyService.OverviewProxyListener
+import com.android.systemui.res.R
+import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController
import com.android.systemui.util.concurrency.FakeExecutor
@@ -46,6 +46,7 @@ import com.android.systemui.util.mockito.whenever
import com.android.systemui.util.time.FakeSystemClock
import com.google.common.truth.Truth.assertThat
import java.util.function.Consumer
+import kotlinx.coroutines.flow.MutableStateFlow
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -65,7 +66,7 @@ import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
@RunWith(AndroidTestingRunner::class)
-@TestableLooper.RunWithLooper
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
@SmallTest
class NotificationsQSContainerControllerTest : SysuiTestCase() {
@@ -73,7 +74,7 @@ class NotificationsQSContainerControllerTest : SysuiTestCase() {
@Mock lateinit var navigationModeController: NavigationModeController
@Mock lateinit var overviewProxyService: OverviewProxyService
@Mock lateinit var shadeHeaderController: ShadeHeaderController
- @Mock lateinit var shadeExpansionStateManager: ShadeExpansionStateManager
+ @Mock lateinit var shadeInteractor: ShadeInteractor
@Mock lateinit var fragmentService: FragmentService
@Mock lateinit var fragmentHostManager: FragmentHostManager
@Mock
@@ -87,7 +88,6 @@ class NotificationsQSContainerControllerTest : SysuiTestCase() {
lateinit var underTest: NotificationsQSContainerController
- private lateinit var fakeResources: TestableResources
private lateinit var featureFlags: FakeFeatureFlags
private lateinit var navigationModeCallback: ModeChangedListener
private lateinit var taskbarVisibilityCallback: OverviewProxyListener
@@ -111,13 +111,15 @@ class NotificationsQSContainerControllerTest : SysuiTestCase() {
whenever(fragmentService.getFragmentHostManager(any())).thenReturn(fragmentHostManager)
+ whenever(shadeInteractor.isQsExpanded).thenReturn(MutableStateFlow(false))
+
underTest =
NotificationsQSContainerController(
view,
navigationModeController,
overviewProxyService,
shadeHeaderController,
- shadeExpansionStateManager,
+ shadeInteractor,
fragmentService,
delayableExecutor,
featureFlags,
@@ -458,7 +460,7 @@ class NotificationsQSContainerControllerTest : SysuiTestCase() {
navigationModeController,
overviewProxyService,
shadeHeaderController,
- shadeExpansionStateManager,
+ shadeInteractor,
fragmentService,
delayableExecutor,
featureFlags,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeRepositoryImplTest.kt
index 6eeafefd0ac1..e920687753fd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeRepositoryImplTest.kt
@@ -189,4 +189,13 @@ class ShadeRepositoryImplTest : SysuiTestCase() {
underTest.setUdfpsTransitionToFullShadeProgress(1f)
assertThat(underTest.udfpsTransitionToFullShadeProgress.value).isEqualTo(1f)
}
+
+ @Test
+ fun updateLegacyIsQsExpanded() =
+ testScope.runTest {
+ assertThat(underTest.legacyIsQsExpanded.value).isEqualTo(false)
+
+ underTest.setLegacyIsQsExpanded(true)
+ assertThat(underTest.legacyIsQsExpanded.value).isEqualTo(true)
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/PulseExpansionHandlerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/PulseExpansionHandlerTest.kt
index 20e5c43cba19..49e5c456e645 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/PulseExpansionHandlerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/PulseExpansionHandlerTest.kt
@@ -21,18 +21,17 @@ import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
-import com.android.systemui.classifier.FalsingCollector
import com.android.systemui.dump.DumpManager
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.plugins.statusbar.StatusBarStateController
-import com.android.systemui.shade.ShadeExpansionStateManager
+import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator
import com.android.systemui.statusbar.notification.row.ExpandableView
-import com.android.systemui.statusbar.notification.stack.NotificationRoundnessManager
import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.statusbar.policy.HeadsUpManager
import com.android.systemui.util.mockito.mock
+import kotlinx.coroutines.flow.MutableStateFlow
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -53,19 +52,18 @@ class PulseExpansionHandlerTest : SysuiTestCase() {
private val wakeUpCoordinator: NotificationWakeUpCoordinator = mock()
private val bypassController: KeyguardBypassController = mock()
private val headsUpManager: HeadsUpManager = mock()
- private val roundnessManager: NotificationRoundnessManager = mock()
private val configurationController: ConfigurationController = mock()
private val statusBarStateController: StatusBarStateController = mock()
private val falsingManager: FalsingManager = mock()
- private val shadeExpansionStateManager: ShadeExpansionStateManager = mock()
+ private val shadeInteractor: ShadeInteractor = mock()
private val lockscreenShadeTransitionController: LockscreenShadeTransitionController = mock()
- private val falsingCollector: FalsingCollector = mock()
private val dumpManager: DumpManager = mock()
private val expandableView: ExpandableView = mock()
@Before
fun setUp() {
whenever(expandableView.collapsedHeight).thenReturn(collapsedHeight)
+ whenever(shadeInteractor.isQsExpanded).thenReturn(MutableStateFlow(false))
pulseExpansionHandler =
PulseExpansionHandler(
@@ -73,13 +71,11 @@ class PulseExpansionHandlerTest : SysuiTestCase() {
wakeUpCoordinator,
bypassController,
headsUpManager,
- roundnessManager,
configurationController,
statusBarStateController,
falsingManager,
- shadeExpansionStateManager,
+ shadeInteractor,
lockscreenShadeTransitionController,
- falsingCollector,
dumpManager
)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java
index 50ce265b67d1..1c621613c403 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java
@@ -13,8 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.systemui.statusbar.notification.interruption;
+package com.android.systemui.statusbar.notification.interruption;
import static android.app.Notification.FLAG_BUBBLE;
import static android.app.Notification.FLAG_FOREGROUND_SERVICE;
@@ -27,6 +27,8 @@ import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_AMBIENT;
import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK;
import static android.app.NotificationManager.VISIBILITY_NO_OVERRIDE;
+import static android.provider.Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED;
+import static android.provider.Settings.Global.HEADS_UP_ON;
import static com.android.systemui.statusbar.NotificationEntryHelper.modifyRanking;
import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
@@ -61,9 +63,9 @@ import android.testing.AndroidTestingRunner;
import androidx.test.filters.SmallTest;
import com.android.internal.logging.testing.UiEventLoggerFake;
-import com.android.systemui.res.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.res.R;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.statusbar.notification.NotifPipelineFlags;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -74,6 +76,8 @@ import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.util.settings.FakeGlobalSettings;
+import com.android.systemui.util.time.FakeSystemClock;
import org.junit.Before;
import org.junit.Test;
@@ -120,6 +124,8 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase {
UserTracker mUserTracker;
@Mock
DeviceProvisionedController mDeviceProvisionedController;
+ FakeSystemClock mSystemClock;
+ FakeGlobalSettings mGlobalSettings;
private NotificationInterruptStateProviderImpl mNotifInterruptionStateProvider;
@@ -129,10 +135,12 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase {
when(mUserTracker.getUserId()).thenReturn(ActivityManager.getCurrentUser());
mUiEventLoggerFake = new UiEventLoggerFake();
+ mSystemClock = new FakeSystemClock();
+ mGlobalSettings = new FakeGlobalSettings();
+ mGlobalSettings.putInt(HEADS_UP_NOTIFICATIONS_ENABLED, HEADS_UP_ON);
mNotifInterruptionStateProvider =
new NotificationInterruptStateProviderImpl(
- mContext.getContentResolver(),
mPowerManager,
mAmbientDisplayConfiguration,
mBatteryController,
@@ -145,7 +153,9 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase {
mKeyguardNotificationVisibilityProvider,
mUiEventLoggerFake,
mUserTracker,
- mDeviceProvisionedController);
+ mDeviceProvisionedController,
+ mSystemClock,
+ mGlobalSettings);
mNotifInterruptionStateProvider.mUseHeadsUp = true;
}
@@ -426,7 +436,7 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase {
}
private long makeWhenHoursAgo(long hoursAgo) {
- return System.currentTimeMillis() - (1000 * 60 * 60 * hoursAgo);
+ return mSystemClock.currentTimeMillis() - (1000 * 60 * 60 * hoursAgo);
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderWrapperTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderWrapperTest.kt
index 947bcfb5011b..21de73ac4c7b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderWrapperTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderWrapperTest.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
package com.android.systemui.statusbar.notification.interruption
import android.testing.AndroidTestingRunner
@@ -19,27 +35,28 @@ import org.junit.runner.RunWith
@SmallTest
@RunWith(AndroidTestingRunner::class)
class NotificationInterruptStateProviderWrapperTest : VisualInterruptionDecisionProviderTestBase() {
- override val provider: VisualInterruptionDecisionProvider
- get() =
- NotificationInterruptStateProviderWrapper(
- NotificationInterruptStateProviderImpl(
- context.contentResolver,
- powerManager,
- ambientDisplayConfiguration,
- batteryController,
- statusBarStateController,
- keyguardStateController,
- headsUpManager,
- logger,
- mainHandler,
- flags,
- keyguardNotificationVisibilityProvider,
- uiEventLogger,
- userTracker,
- deviceProvisionedController
- )
- .also { it.mUseHeadsUp = true }
- )
+ override val provider by lazy {
+ NotificationInterruptStateProviderWrapper(
+ NotificationInterruptStateProviderImpl(
+ powerManager,
+ ambientDisplayConfiguration,
+ batteryController,
+ statusBarStateController,
+ keyguardStateController,
+ headsUpManager,
+ logger,
+ mainHandler,
+ flags,
+ keyguardNotificationVisibilityProvider,
+ uiEventLogger,
+ userTracker,
+ deviceProvisionedController,
+ systemClock,
+ globalSettings,
+ )
+ .also { it.mUseHeadsUp = true }
+ )
+ }
// Tests of internals of the wrapper:
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestBase.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestBase.kt
index 6f4bbd5e21fc..c0aaa3670ace 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestBase.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestBase.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
package com.android.systemui.statusbar.notification.interruption
import android.app.ActivityManager
@@ -9,12 +25,15 @@ import android.app.NotificationManager.IMPORTANCE_HIGH
import android.app.NotificationManager.VISIBILITY_NO_OVERRIDE
import android.app.PendingIntent
import android.app.PendingIntent.FLAG_MUTABLE
+import android.content.Context
import android.content.Intent
import android.content.pm.UserInfo
import android.graphics.drawable.Icon
import android.hardware.display.FakeAmbientDisplayConfiguration
import android.os.Handler
import android.os.PowerManager
+import android.provider.Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED
+import android.provider.Settings.Global.HEADS_UP_ON
import com.android.internal.logging.testing.UiEventLoggerFake
import com.android.systemui.SysuiTestCase
import com.android.systemui.res.R
@@ -31,8 +50,11 @@ import com.android.systemui.statusbar.policy.HeadsUpManager
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.mock
+import com.android.systemui.util.settings.FakeGlobalSettings
+import com.android.systemui.util.time.FakeSystemClock
import com.android.systemui.utils.leaks.FakeBatteryController
import com.android.systemui.utils.leaks.LeakCheckedTest
+import junit.framework.Assert.assertFalse
import junit.framework.Assert.assertTrue
import org.junit.Before
import org.junit.Test
@@ -45,6 +67,7 @@ abstract class VisualInterruptionDecisionProviderTestBase : SysuiTestCase() {
protected val batteryController = FakeBatteryController(leakCheck)
protected val deviceProvisionedController: DeviceProvisionedController = mock()
protected val flags: NotifPipelineFlags = mock()
+ protected val globalSettings = FakeGlobalSettings()
protected val headsUpManager: HeadsUpManager = mock()
protected val keyguardNotificationVisibilityProvider: KeyguardNotificationVisibilityProvider =
mock()
@@ -53,164 +76,363 @@ abstract class VisualInterruptionDecisionProviderTestBase : SysuiTestCase() {
protected val mainHandler: Handler = mock()
protected val powerManager: PowerManager = mock()
protected val statusBarStateController = FakeStatusBarStateController()
+ protected val systemClock = FakeSystemClock()
protected val uiEventLogger = UiEventLoggerFake()
protected val userTracker = FakeUserTracker()
protected abstract val provider: VisualInterruptionDecisionProvider
+ private val neverSuppresses = object : NotificationInterruptSuppressor {}
+
+ private val alwaysSuppressesInterruptions =
+ object : NotificationInterruptSuppressor {
+ override fun suppressInterruptions(entry: NotificationEntry?) = true
+ }
+
+ private val alwaysSuppressesAwakeInterruptions =
+ object : NotificationInterruptSuppressor {
+ override fun suppressAwakeInterruptions(entry: NotificationEntry?) = true
+ }
+
+ private val alwaysSuppressesAwakeHeadsUp =
+ object : NotificationInterruptSuppressor {
+ override fun suppressAwakeHeadsUp(entry: NotificationEntry?) = true
+ }
+
@Before
fun setUp() {
+ globalSettings.putInt(HEADS_UP_NOTIFICATIONS_ENABLED, HEADS_UP_ON)
+
val user = UserInfo(ActivityManager.getCurrentUser(), "Current user", /* flags = */ 0)
userTracker.set(listOf(user), /* currentUserIndex = */ 0)
- whenever(headsUpManager.isSnoozed(any())).thenReturn(false)
whenever(keyguardNotificationVisibilityProvider.shouldHideNotification(any()))
.thenReturn(false)
}
@Test
fun testShouldPeek() {
- ensureStateForPeek()
+ ensurePeekState()
+ assertShouldHeadsUp(buildPeekEntry())
+ }
- assertTrue(provider.makeUnloggedHeadsUpDecision(createPeekEntry()).shouldInterrupt)
+ @Test
+ fun testShouldPeek_defaultLegacySuppressor() {
+ ensurePeekState()
+ provider.addLegacySuppressor(neverSuppresses)
+ assertShouldHeadsUp(buildPeekEntry())
}
@Test
- fun testShouldPulse() {
- ensureStateForPulse()
+ fun testShouldNotPeek_legacySuppressInterruptions() {
+ ensurePeekState()
+ provider.addLegacySuppressor(alwaysSuppressesInterruptions)
+ assertShouldNotHeadsUp(buildPeekEntry())
+ }
- assertTrue(provider.makeUnloggedHeadsUpDecision(createPulseEntry()).shouldInterrupt)
+ @Test
+ fun testShouldNotPeek_legacySuppressAwakeInterruptions() {
+ ensurePeekState()
+ provider.addLegacySuppressor(alwaysSuppressesAwakeInterruptions)
+ assertShouldNotHeadsUp(buildPeekEntry())
}
@Test
- fun testShouldFsi_awake() {
- ensureStateForAwakeFsi()
+ fun testShouldNotPeek_legacySuppressAwakeHeadsUp() {
+ ensurePeekState()
+ provider.addLegacySuppressor(alwaysSuppressesAwakeHeadsUp)
+ assertShouldNotHeadsUp(buildPeekEntry())
+ }
- assertTrue(provider.makeUnloggedFullScreenIntentDecision(createFsiEntry()).shouldInterrupt)
+ @Test
+ fun testShouldPulse() {
+ ensurePulseState()
+ assertShouldHeadsUp(buildPulseEntry())
}
@Test
- fun testShouldFsi_dreaming() {
- ensureStateForDreamingFsi()
+ fun testShouldPulse_defaultLegacySuppressor() {
+ ensurePulseState()
+ provider.addLegacySuppressor(neverSuppresses)
+ assertShouldHeadsUp(buildPulseEntry())
+ }
- assertTrue(provider.makeUnloggedFullScreenIntentDecision(createFsiEntry()).shouldInterrupt)
+ @Test
+ fun testShouldNotPulse_legacySuppressInterruptions() {
+ ensurePulseState()
+ provider.addLegacySuppressor(alwaysSuppressesInterruptions)
+ assertShouldNotHeadsUp(buildPulseEntry())
}
@Test
- fun testShouldFsi_keyguard() {
- ensureStateForKeyguardFsi()
+ fun testShouldPulse_legacySuppressAwakeInterruptions() {
+ ensurePulseState()
+ provider.addLegacySuppressor(alwaysSuppressesAwakeInterruptions)
+ assertShouldHeadsUp(buildPulseEntry())
+ }
- assertTrue(provider.makeUnloggedFullScreenIntentDecision(createFsiEntry()).shouldInterrupt)
+ @Test
+ fun testShouldPulse_legacySuppressAwakeHeadsUp() {
+ ensurePulseState()
+ provider.addLegacySuppressor(alwaysSuppressesAwakeHeadsUp)
+ assertShouldHeadsUp(buildPulseEntry())
}
@Test
fun testShouldBubble() {
- assertTrue(provider.makeAndLogBubbleDecision(createBubbleEntry()).shouldInterrupt)
+ ensureBubbleState()
+ assertShouldBubble(buildBubbleEntry())
}
- private fun ensureStateForPeek() {
- whenever(powerManager.isScreenOn).thenReturn(true)
- statusBarStateController.dozing = false
- statusBarStateController.dreaming = false
+ @Test
+ fun testShouldBubble_defaultLegacySuppressor() {
+ ensureBubbleState()
+ provider.addLegacySuppressor(neverSuppresses)
+ assertShouldBubble(buildBubbleEntry())
}
- private fun ensureStateForPulse() {
- ambientDisplayConfiguration.fakePulseOnNotificationEnabled = true
- batteryController.setIsAodPowerSave(false)
- statusBarStateController.dozing = true
+ @Test
+ fun testShouldNotBubble_legacySuppressInterruptions() {
+ ensureBubbleState()
+ provider.addLegacySuppressor(alwaysSuppressesInterruptions)
+ assertShouldNotBubble(buildBubbleEntry())
}
- private fun ensureStateForAwakeFsi() {
- whenever(powerManager.isInteractive).thenReturn(false)
- statusBarStateController.dreaming = false
- statusBarStateController.state = SHADE
+ @Test
+ fun testShouldNotBubble_legacySuppressAwakeInterruptions() {
+ ensureBubbleState()
+ provider.addLegacySuppressor(alwaysSuppressesAwakeInterruptions)
+ assertShouldNotBubble(buildBubbleEntry())
}
- private fun ensureStateForDreamingFsi() {
- whenever(powerManager.isInteractive).thenReturn(true)
- statusBarStateController.dreaming = true
- statusBarStateController.state = SHADE
+ @Test
+ fun testShouldBubble_legacySuppressAwakeHeadsUp() {
+ ensureBubbleState()
+ provider.addLegacySuppressor(alwaysSuppressesAwakeHeadsUp)
+ assertShouldBubble(buildBubbleEntry())
}
- private fun ensureStateForKeyguardFsi() {
- whenever(powerManager.isInteractive).thenReturn(true)
- statusBarStateController.dreaming = false
- statusBarStateController.state = KEYGUARD
+ @Test
+ fun testShouldFsi_notInteractive() {
+ ensureNotInteractiveFsiState()
+ assertShouldFsi(buildFsiEntry())
}
- private fun createNotif(
- hasFsi: Boolean = false,
- bubbleMetadata: BubbleMetadata? = null
- ): Notification {
- return Notification.Builder(context, TEST_CHANNEL_ID)
- .apply {
- setContentTitle(TEST_CONTENT_TITLE)
- setContentText(TEST_CONTENT_TEXT)
+ @Test
+ fun testShouldFsi_dreaming() {
+ ensureDreamingFsiState()
+ assertShouldFsi(buildFsiEntry())
+ }
- if (hasFsi) {
- setFullScreenIntent(mock(), /* highPriority = */ true)
- }
+ @Test
+ fun testShouldFsi_keyguard() {
+ ensureKeyguardFsiState()
+ assertShouldFsi(buildFsiEntry())
+ }
- if (bubbleMetadata != null) {
- setBubbleMetadata(bubbleMetadata)
- }
+ private data class State(
+ var hunSnoozed: Boolean? = null,
+ var isAodPowerSave: Boolean? = null,
+ var isDozing: Boolean? = null,
+ var isDreaming: Boolean? = null,
+ var isInteractive: Boolean? = null,
+ var isScreenOn: Boolean? = null,
+ var keyguardShouldHideNotification: Boolean? = null,
+ var pulseOnNotificationsEnabled: Boolean? = null,
+ var statusBarState: Int? = null,
+ )
+
+ private fun setState(state: State): Unit =
+ state.run {
+ hunSnoozed?.let { whenever(headsUpManager.isSnoozed(TEST_PACKAGE)).thenReturn(it) }
+
+ isAodPowerSave?.let { batteryController.setIsAodPowerSave(it) }
+
+ isDozing?.let { statusBarStateController.dozing = it }
+
+ isDreaming?.let { statusBarStateController.dreaming = it }
+
+ isInteractive?.let { whenever(powerManager.isInteractive).thenReturn(it) }
+
+ isScreenOn?.let { whenever(powerManager.isScreenOn).thenReturn(it) }
+
+ keyguardShouldHideNotification?.let {
+ whenever(keyguardNotificationVisibilityProvider.shouldHideNotification(any()))
+ .thenReturn(it)
+ }
+
+ pulseOnNotificationsEnabled?.let {
+ ambientDisplayConfiguration.fakePulseOnNotificationEnabled = it
+ }
+
+ statusBarState?.let { statusBarStateController.state = it }
+ }
+
+ private fun ensureState(block: State.() -> Unit) =
+ State()
+ .apply {
+ keyguardShouldHideNotification = false
+ apply(block)
}
- .setContentTitle(TEST_CONTENT_TITLE)
- .setContentText(TEST_CONTENT_TEXT)
- .build()
+ .run(this::setState)
+
+ private fun ensurePeekState(block: State.() -> Unit = {}) = ensureState {
+ hunSnoozed = false
+ isDozing = false
+ isDreaming = false
+ isScreenOn = true
+ run(block)
}
- private fun createBubbleMetadata(): BubbleMetadata {
- val pendingIntent =
- PendingIntent.getActivity(
- context,
- /* requestCode = */ 0,
- Intent().setPackage(context.packageName),
- FLAG_MUTABLE
- )
+ private fun ensurePulseState(block: State.() -> Unit = {}) = ensureState {
+ isAodPowerSave = false
+ isDozing = true
+ pulseOnNotificationsEnabled = true
+ run(block)
+ }
- val icon = Icon.createWithResource(context.resources, R.drawable.android)
+ private fun ensureBubbleState(block: State.() -> Unit = {}) = ensureState(block)
- return BubbleMetadata.Builder(pendingIntent, icon).build()
+ private fun ensureNotInteractiveFsiState(block: State.() -> Unit = {}) = ensureState {
+ isDreaming = false
+ isInteractive = false
+ statusBarState = SHADE
+ run(block)
}
- private fun createEntry(
- notif: Notification,
- importance: Int = IMPORTANCE_DEFAULT,
- canBubble: Boolean? = null
- ): NotificationEntry {
- return NotificationEntryBuilder()
- .apply {
- setPkg(TEST_PACKAGE)
- setOpPkg(TEST_PACKAGE)
- setTag(TEST_TAG)
- setChannel(NotificationChannel(TEST_CHANNEL_ID, TEST_CHANNEL_NAME, importance))
- setNotification(notif)
- setImportance(importance)
-
- if (canBubble != null) {
- setCanBubble(canBubble)
- }
- }
- .build()
+ private fun ensureDreamingFsiState(block: State.() -> Unit = {}) = ensureState {
+ isDreaming = true
+ isInteractive = true
+ statusBarState = SHADE
+ run(block)
+ }
+
+ private fun ensureKeyguardFsiState(block: State.() -> Unit = {}) = ensureState {
+ isDreaming = false
+ isInteractive = true
+ statusBarState = KEYGUARD
+ run(block)
}
- private fun createPeekEntry() = createEntry(notif = createNotif(), importance = IMPORTANCE_HIGH)
+ private fun assertShouldHeadsUp(entry: NotificationEntry) =
+ provider.makeUnloggedHeadsUpDecision(entry).let {
+ assertTrue("unexpected suppressed HUN: ${it.logReason}", it.shouldInterrupt)
+ }
+
+ private fun assertShouldNotHeadsUp(entry: NotificationEntry) =
+ provider.makeUnloggedHeadsUpDecision(entry).let {
+ assertFalse("unexpected unsuppressed HUN: ${it.logReason}", it.shouldInterrupt)
+ }
+
+ private fun assertShouldBubble(entry: NotificationEntry) =
+ provider.makeAndLogBubbleDecision(entry).let {
+ assertTrue("unexpected suppressed bubble: ${it.logReason}", it.shouldInterrupt)
+ }
+
+ private fun assertShouldNotBubble(entry: NotificationEntry) =
+ provider.makeAndLogBubbleDecision(entry).let {
+ assertFalse("unexpected unsuppressed bubble: ${it.logReason}", it.shouldInterrupt)
+ }
+
+ private fun assertShouldFsi(entry: NotificationEntry) =
+ provider.makeUnloggedFullScreenIntentDecision(entry).let {
+ assertTrue("unexpected suppressed FSI: ${it.logReason}", it.shouldInterrupt)
+ }
- private fun createPulseEntry() =
- createEntry(notif = createNotif(), importance = IMPORTANCE_HIGH).also {
- modifyRanking(it).setVisibilityOverride(VISIBILITY_NO_OVERRIDE).build()
+ private fun assertShouldNotFsi(entry: NotificationEntry) =
+ provider.makeUnloggedFullScreenIntentDecision(entry).let {
+ assertFalse("unexpected unsuppressed FSI: ${it.logReason}", it.shouldInterrupt)
}
- private fun createFsiEntry() =
- createEntry(notif = createNotif(hasFsi = true), importance = IMPORTANCE_HIGH)
+ private class EntryBuilder(val context: Context) {
+ var importance = IMPORTANCE_DEFAULT
+ var suppressedVisualEffects: Int? = null
+ var whenMs: Long? = null
+ var visibilityOverride: Int? = null
+ var hasFsi = false
+ var canBubble: Boolean? = null
+ var hasBubbleMetadata = false
+ var bubbleSuppressNotification: Boolean? = null
+
+ private fun buildBubbleMetadata() =
+ BubbleMetadata.Builder(
+ PendingIntent.getActivity(
+ context,
+ /* requestCode = */ 0,
+ Intent().setPackage(context.packageName),
+ FLAG_MUTABLE
+ ),
+ Icon.createWithResource(context.resources, R.drawable.android)
+ )
+ .apply { bubbleSuppressNotification?.let { setSuppressNotification(it) } }
+ .build()
+
+ fun build() =
+ Notification.Builder(context, TEST_CHANNEL_ID)
+ .apply {
+ setContentTitle(TEST_CONTENT_TITLE)
+ setContentText(TEST_CONTENT_TEXT)
+
+ if (hasFsi) {
+ setFullScreenIntent(mock(), /* highPriority = */ true)
+ }
+
+ whenMs?.let { setWhen(it) }
+
+ if (hasBubbleMetadata) {
+ setBubbleMetadata(buildBubbleMetadata())
+ }
+ }
+ .build()
+ .let { NotificationEntryBuilder().setNotification(it) }
+ .apply {
+ setPkg(TEST_PACKAGE)
+ setOpPkg(TEST_PACKAGE)
+ setTag(TEST_TAG)
+
+ setImportance(importance)
+ setChannel(NotificationChannel(TEST_CHANNEL_ID, TEST_CHANNEL_NAME, importance))
+
+ canBubble?.let { setCanBubble(it) }
+ }
+ .build()!!
+ .also {
+ modifyRanking(it)
+ .apply {
+ suppressedVisualEffects?.let { setSuppressedVisualEffects(it) }
+ visibilityOverride?.let { setVisibilityOverride(it) }
+ }
+ .build()
+ }
+ }
+
+ private fun buildEntry(block: EntryBuilder.() -> Unit) =
+ EntryBuilder(context).also(block).build()
+
+ private fun buildPeekEntry(block: EntryBuilder.() -> Unit = {}) = buildEntry {
+ importance = IMPORTANCE_HIGH
+ run(block)
+ }
+
+ private fun buildPulseEntry(block: EntryBuilder.() -> Unit = {}) = buildEntry {
+ importance = IMPORTANCE_DEFAULT
+ visibilityOverride = VISIBILITY_NO_OVERRIDE
+ run(block)
+ }
+
+ private fun buildFsiEntry(block: EntryBuilder.() -> Unit = {}) = buildEntry {
+ importance = IMPORTANCE_HIGH
+ hasFsi = true
+ run(block)
+ }
+
+ private fun buildBubbleEntry(block: EntryBuilder.() -> Unit = {}) = buildEntry {
+ canBubble = true
+ hasBubbleMetadata = true
+ run(block)
+ }
- private fun createBubbleEntry() =
- createEntry(
- notif = createNotif(bubbleMetadata = createBubbleMetadata()),
- importance = IMPORTANCE_HIGH,
- canBubble = true
- )
+ private fun whenAgo(whenAgeMs: Long) = systemClock.currentTimeMillis() - whenAgeMs
}
private const val TEST_CONTENT_TITLE = "Test Content Title"
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt
index 60421c981e6d..3a9d111bacf7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt
@@ -314,7 +314,26 @@ class SharedNotificationContainerViewModelTest : SysuiTestCase() {
sharedNotificationContainerInteractor.setTopPosition(10f)
assertThat(position)
- .isEqualTo(SharedNotificationContainerPosition(top = 10f, bottom = 0f))
+ .isEqualTo(
+ SharedNotificationContainerPosition(top = 10f, bottom = 0f, animate = true)
+ )
+ }
+
+ @Test
+ fun positionOnQS() =
+ testScope.runTest {
+ val position by collectLastValue(underTest.position)
+
+ // Start on lockscreen with shade expanded
+ showLockscreenWithQSExpanded()
+
+ // When not in split shade
+ sharedNotificationContainerInteractor.setTopPosition(10f)
+
+ assertThat(position)
+ .isEqualTo(
+ SharedNotificationContainerPosition(top = 10f, bottom = 0f, animate = false)
+ )
}
@Test
@@ -390,6 +409,17 @@ class SharedNotificationContainerViewModelTest : SysuiTestCase() {
)
}
+ private suspend fun TestScope.showLockscreenWithQSExpanded() {
+ shadeRepository.setLockscreenShadeExpansion(0f)
+ shadeRepository.setQsExpansion(1f)
+ keyguardRepository.setStatusBarState(StatusBarState.SHADE_LOCKED)
+ keyguardTransitionRepository.sendTransitionSteps(
+ from = KeyguardState.AOD,
+ to = KeyguardState.LOCKSCREEN,
+ this,
+ )
+ }
+
@SysUISingleton
@Component(
modules =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
index 05fd6d22f961..4a20f831a781 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
@@ -20,6 +20,8 @@ import static android.app.NotificationManager.IMPORTANCE_HIGH;
import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK;
import static android.app.StatusBarManager.WINDOW_STATE_HIDDEN;
import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
+import static android.provider.Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED;
+import static android.provider.Settings.Global.HEADS_UP_ON;
import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
import static com.android.systemui.statusbar.StatusBarState.SHADE;
@@ -51,7 +53,6 @@ import android.app.NotificationChannel;
import android.app.WallpaperManager;
import android.app.trust.TrustManager;
import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
import android.content.IntentFilter;
import android.hardware.devicestate.DeviceStateManager;
import android.hardware.display.AmbientDisplayConfiguration;
@@ -180,11 +181,16 @@ import com.android.systemui.util.WallpaperController;
import com.android.systemui.util.concurrency.FakeExecutor;
import com.android.systemui.util.concurrency.MessageRouterImpl;
import com.android.systemui.util.kotlin.JavaAdapter;
+import com.android.systemui.util.settings.FakeGlobalSettings;
+import com.android.systemui.util.settings.GlobalSettings;
import com.android.systemui.util.time.FakeSystemClock;
+import com.android.systemui.util.time.SystemClock;
import com.android.systemui.volume.VolumeComponent;
import com.android.wm.shell.bubbles.Bubbles;
import com.android.wm.shell.startingsurface.StartingSurface;
+import dagger.Lazy;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -198,8 +204,6 @@ import java.util.Optional;
import javax.inject.Provider;
-import dagger.Lazy;
-
@SmallTest
@RunWith(AndroidTestingRunner.class)
@RunWithLooper(setAsMainLooper = true)
@@ -319,6 +323,7 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
private ShadeController mShadeController;
private final FakeSystemClock mFakeSystemClock = new FakeSystemClock();
+ private final FakeGlobalSettings mFakeGlobalSettings = new FakeGlobalSettings();
private final FakeExecutor mMainExecutor = new FakeExecutor(mFakeSystemClock);
private final FakeExecutor mUiBgExecutor = new FakeExecutor(mFakeSystemClock);
private final FakeFeatureFlags mFeatureFlags = new FakeFeatureFlags();
@@ -349,8 +354,10 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
mPowerManager = new PowerManager(mContext, mPowerManagerService, thermalService,
Handler.createAsync(Looper.myLooper()));
+ mFakeGlobalSettings.putInt(HEADS_UP_NOTIFICATIONS_ENABLED, HEADS_UP_ON);
+
mNotificationInterruptStateProvider =
- new TestableNotificationInterruptStateProviderImpl(mContext.getContentResolver(),
+ new TestableNotificationInterruptStateProviderImpl(
mPowerManager,
mAmbientDisplayConfiguration,
mStatusBarStateController,
@@ -363,7 +370,9 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
mock(KeyguardNotificationVisibilityProvider.class),
mock(UiEventLogger.class),
mUserTracker,
- mDeviceProvisionedController);
+ mDeviceProvisionedController,
+ mFakeSystemClock,
+ mFakeGlobalSettings);
mContext.addMockSystemService(TrustManager.class, mock(TrustManager.class));
mContext.addMockSystemService(FingerprintManager.class, mock(FingerprintManager.class));
@@ -1162,7 +1171,6 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
NotificationInterruptStateProviderImpl {
TestableNotificationInterruptStateProviderImpl(
- ContentResolver contentResolver,
PowerManager powerManager,
AmbientDisplayConfiguration ambientDisplayConfiguration,
StatusBarStateController controller,
@@ -1175,9 +1183,10 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
KeyguardNotificationVisibilityProvider keyguardNotificationVisibilityProvider,
UiEventLogger uiEventLogger,
UserTracker userTracker,
- DeviceProvisionedController deviceProvisionedController) {
+ DeviceProvisionedController deviceProvisionedController,
+ SystemClock systemClock,
+ GlobalSettings globalSettings) {
super(
- contentResolver,
powerManager,
ambientDisplayConfiguration,
batteryController,
@@ -1190,7 +1199,9 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
keyguardNotificationVisibilityProvider,
uiEventLogger,
userTracker,
- deviceProvisionedController
+ deviceProvisionedController,
+ systemClock,
+ globalSettings
);
mUseHeadsUp = true;
}
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 ec808c796d46..8309b85620bd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
@@ -18,6 +18,8 @@ package com.android.systemui.wmshell;
import static android.app.Notification.FLAG_BUBBLE;
import static android.app.PendingIntent.FLAG_MUTABLE;
+import static android.provider.Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED;
+import static android.provider.Settings.Global.HEADS_UP_ON;
import static android.service.notification.NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_DELETED;
import static android.service.notification.NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED;
import static android.service.notification.NotificationListenerService.REASON_APP_CANCEL;
@@ -157,6 +159,8 @@ import com.android.systemui.statusbar.policy.ZenModeController;
import com.android.systemui.statusbar.policy.data.repository.FakeDeviceProvisioningRepository;
import com.android.systemui.user.domain.interactor.SelectedUserInteractor;
import com.android.systemui.user.domain.interactor.UserSwitcherInteractor;
+import com.android.systemui.util.settings.FakeGlobalSettings;
+import com.android.systemui.util.time.SystemClock;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.WindowManagerShellWrapper;
import com.android.wm.shell.bubbles.Bubble;
@@ -476,7 +480,6 @@ public class BubblesTest extends SysuiTestCase {
mKeyguardStateController,
mScreenOffAnimationController,
mAuthController,
- mShadeExpansionStateManager,
() -> mShadeInteractor,
mShadeWindowLogger,
() -> mSelectedUserInteractor
@@ -507,8 +510,11 @@ public class BubblesTest extends SysuiTestCase {
when(mUserManager.getProfiles(ActivityManager.getCurrentUser())).thenReturn(
Collections.singletonList(mock(UserInfo.class)));
+ final FakeGlobalSettings fakeGlobalSettings = new FakeGlobalSettings();
+ fakeGlobalSettings.putInt(HEADS_UP_NOTIFICATIONS_ENABLED, HEADS_UP_ON);
+
TestableNotificationInterruptStateProviderImpl interruptionStateProvider =
- new TestableNotificationInterruptStateProviderImpl(mContext.getContentResolver(),
+ new TestableNotificationInterruptStateProviderImpl(
mock(PowerManager.class),
mock(AmbientDisplayConfiguration.class),
mock(StatusBarStateController.class),
@@ -521,7 +527,9 @@ public class BubblesTest extends SysuiTestCase {
mock(KeyguardNotificationVisibilityProvider.class),
mock(UiEventLogger.class),
mock(UserTracker.class),
- mock(DeviceProvisionedController.class)
+ mock(DeviceProvisionedController.class),
+ mock(SystemClock.class),
+ fakeGlobalSettings
);
mShellTaskOrganizer = new ShellTaskOrganizer(mock(ShellInit.class),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableNotificationInterruptStateProviderImpl.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableNotificationInterruptStateProviderImpl.java
index 0df235dd2416..975555c1a46b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableNotificationInterruptStateProviderImpl.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableNotificationInterruptStateProviderImpl.java
@@ -16,7 +16,6 @@
package com.android.systemui.wmshell;
-import android.content.ContentResolver;
import android.hardware.display.AmbientDisplayConfiguration;
import android.os.Handler;
import android.os.PowerManager;
@@ -32,12 +31,13 @@ import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.util.settings.GlobalSettings;
+import com.android.systemui.util.time.SystemClock;
public class TestableNotificationInterruptStateProviderImpl
extends NotificationInterruptStateProviderImpl {
TestableNotificationInterruptStateProviderImpl(
- ContentResolver contentResolver,
PowerManager powerManager,
AmbientDisplayConfiguration ambientDisplayConfiguration,
StatusBarStateController statusBarStateController,
@@ -50,8 +50,10 @@ public class TestableNotificationInterruptStateProviderImpl
KeyguardNotificationVisibilityProvider keyguardNotificationVisibilityProvider,
UiEventLogger uiEventLogger,
UserTracker userTracker,
- DeviceProvisionedController deviceProvisionedController) {
- super(contentResolver,
+ DeviceProvisionedController deviceProvisionedController,
+ SystemClock systemClock,
+ GlobalSettings globalSettings) {
+ super(
powerManager,
ambientDisplayConfiguration,
batteryController,
@@ -64,7 +66,9 @@ public class TestableNotificationInterruptStateProviderImpl
keyguardNotificationVisibilityProvider,
uiEventLogger,
userTracker,
- deviceProvisionedController);
+ deviceProvisionedController,
+ systemClock,
+ globalSettings);
mUseHeadsUp = true;
}
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/data/repository/FakeShadeRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/data/repository/FakeShadeRepository.kt
index 3c49c58580cc..800593fe61a1 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/data/repository/FakeShadeRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/data/repository/FakeShadeRepository.kt
@@ -56,6 +56,14 @@ class FakeShadeRepository @Inject constructor() : ShadeRepository {
@Deprecated("Use ShadeInteractor instead")
override val legacyExpandedOrAwaitingInputTransfer = _legacyExpandedOrAwaitingInputTransfer
+ private val _legacyIsQsExpanded = MutableStateFlow(false)
+ @Deprecated("Use ShadeInteractor instead") override val legacyIsQsExpanded = _legacyIsQsExpanded
+
+ @Deprecated("Use ShadeInteractor instead")
+ override fun setLegacyIsQsExpanded(legacyIsQsExpanded: Boolean) {
+ _legacyIsQsExpanded.value = legacyIsQsExpanded
+ }
+
@Deprecated("Use ShadeInteractor instead")
override fun setLegacyExpandedOrAwaitingInputTransfer(
legacyExpandedOrAwaitingInputTransfer: Boolean
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/FakeStatusBarStateController.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/FakeStatusBarStateController.kt
index 19fdb6ddad02..a65813abd49f 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/FakeStatusBarStateController.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/FakeStatusBarStateController.kt
@@ -104,7 +104,7 @@ class FakeStatusBarStateController : SysuiStatusBarStateController {
override fun isDreaming() = dreaming
- override fun setIsDreaming(drreaming: Boolean): Boolean {
+ override fun setIsDreaming(dreaming: Boolean): Boolean {
dreaming != this.dreaming || return false
this.dreaming = dreaming
callbacks.forEach { it.onDreamingChanged(dreaming) }
diff --git a/packages/SystemUI/tools/lint/baseline.xml b/packages/SystemUI/tools/lint/baseline.xml
index 301c9b831c3b..43f830006504 100644
--- a/packages/SystemUI/tools/lint/baseline.xml
+++ b/packages/SystemUI/tools/lint/baseline.xml
@@ -1271,17 +1271,6 @@
</issue>
<issue
- id="MergeRootFrame"
- message="This `&lt;FrameLayout>` can be replaced with a `&lt;merge>` tag"
- errorLine1="&lt;FrameLayout"
- errorLine2="^">
- <location
- file="res/layout/volume_dnd_icon.xml"
- line="16"
- column="1"/>
- </issue>
-
- <issue
id="InefficientWeight"
message="Use a `layout_height` of `0dp` instead of `wrap_content` for better performance"
errorLine1=" android:layout_height=&quot;wrap_content&quot;"
@@ -88853,17 +88842,6 @@
errorLine1=" &lt;ImageView"
errorLine2=" ^">
<location
- file="res/layout/volume_dnd_icon.xml"
- line="23"
- column="5"/>
- </issue>
-
- <issue
- id="ContentDescription"
- message="[Accessibility] Missing `contentDescription` attribute on image"
- errorLine1=" &lt;ImageView"
- errorLine2=" ^">
- <location
file="res/layout/wireless_charging_layout.xml"
line="26"
column="5"/>
@@ -89783,15 +89761,4 @@
column="22"/>
</issue>
- <issue
- id="RtlHardcoded"
- message="Use &quot;`end`&quot; instead of &quot;`right`&quot; to ensure correct behavior in right-to-left locales"
- errorLine1=" android:layout_gravity=&quot;right|top&quot;"
- errorLine2=" ~~~~~~~~~">
- <location
- file="res/layout/volume_dnd_icon.xml"
- line="26"
- column="33"/>
- </issue>
-
</issues>
diff --git a/services/Android.bp b/services/Android.bp
index aca8409c284f..f1534b461607 100644
--- a/services/Android.bp
+++ b/services/Android.bp
@@ -41,7 +41,10 @@ soong_config_module_type {
name: "system_optimized_java_defaults",
module_type: "java_defaults",
config_namespace: "ANDROID",
- bool_variables: ["SYSTEM_OPTIMIZE_JAVA"],
+ bool_variables: [
+ "SYSTEM_OPTIMIZE_JAVA",
+ "FULL_SYSTEM_OPTIMIZE_JAVA",
+ ],
properties: [
"optimize",
"dxflags",
@@ -56,6 +59,7 @@ system_optimized_java_defaults {
enabled: true,
// TODO(b/210510433): Enable optimizations after improving
// retracing infra.
+ // See also FULL_SYSTEM_OPTIMIZE_JAVA.
optimize: false,
shrink: true,
ignore_warnings: false,
@@ -81,6 +85,12 @@ system_optimized_java_defaults {
dxflags: ["--debug"],
},
},
+ // Allow form factors to opt-in full system java optimization
+ FULL_SYSTEM_OPTIMIZE_JAVA: {
+ optimize: {
+ optimize: true,
+ },
+ },
},
}
diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java
index 959f69ea483f..92af68bc40a3 100644
--- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java
@@ -361,14 +361,6 @@ public class VirtualDeviceManagerService extends SystemService {
@NonNull IVirtualDeviceSoundEffectListener soundEffectListener) {
createVirtualDevice_enforcePermission();
attributionSource.enforceCallingUid();
- final long identity = Binder.clearCallingIdentity();
- try {
- if (Flags.moreLogs()) {
- Slog.i(TAG, "Creating VirtualDevice");
- }
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
final int callingUid = getCallingUid();
final String packageName = attributionSource.getPackageName();
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 15fc2dc15d02..02235096ac15 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -61,6 +61,7 @@ import android.app.KeyguardManager;
import android.app.PendingIntent;
import android.app.admin.SecurityLog;
import android.app.usage.StorageStatsManager;
+import android.content.AttributionSource;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -2138,8 +2139,13 @@ class StorageManagerService extends IStorageManager.Stub
| MATCH_DIRECT_BOOT_UNAWARE | MATCH_UNINSTALLED_PACKAGES | MATCH_ANY_USER,
userId, Process.myUid())) {
try {
- boolean hasLegacy = mIAppOpsService.checkOperation(OP_LEGACY_STORAGE, ai.uid,
- ai.packageName) == MODE_ALLOWED;
+ final AttributionSource attributionSource = new AttributionSource.Builder(ai.uid)
+ .setPackageName(ai.packageName)
+ .build();
+ boolean hasLegacy =
+ mIAppOpsService.checkOperationWithState(
+ OP_LEGACY_STORAGE, attributionSource.asState())
+ == MODE_ALLOWED;
updateLegacyStorageApps(ai.packageName, ai.uid, hasLegacy);
} catch (RemoteException e) {
Slog.e(TAG, "Failed to check legacy op for package " + ai.packageName, e);
@@ -4540,8 +4546,11 @@ class StorageManagerService extends IStorageManager.Stub
// sharing the uid and allow same level of storage access for all packages even if
// one of the packages has the appop granted.
for (String uidPackageName : packagesForUid) {
- if (mIAppOpsService.checkOperation(
- OP_REQUEST_INSTALL_PACKAGES, uid, uidPackageName) == MODE_ALLOWED) {
+ final AttributionSource attributionSource =
+ new AttributionSource.Builder(uid).setPackageName(uidPackageName).build();
+ if (mIAppOpsService.checkOperationWithState(
+ OP_REQUEST_INSTALL_PACKAGES, attributionSource.asState())
+ == MODE_ALLOWED) {
hasInstallOp = true;
break;
}
@@ -4838,8 +4847,11 @@ class StorageManagerService extends IStorageManager.Stub
@Override
public boolean hasExternalStorageAccess(int uid, String packageName) {
try {
- final int opMode = mIAppOpsService.checkOperation(
- OP_MANAGE_EXTERNAL_STORAGE, uid, packageName);
+ final AttributionSource attributionSource =
+ new AttributionSource.Builder(uid).setPackageName(packageName).build();
+ final int opMode =
+ mIAppOpsService.checkOperationWithState(
+ OP_MANAGE_EXTERNAL_STORAGE, attributionSource.asState());
if (opMode == AppOpsManager.MODE_DEFAULT) {
return mIPackageManager.checkUidPermission(
MANAGE_EXTERNAL_STORAGE, uid) == PERMISSION_GRANTED;
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 5f1a7e7e8123..4bdb4da97144 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -167,6 +167,7 @@ import android.compat.annotation.ChangeId;
import android.compat.annotation.EnabledAfter;
import android.compat.annotation.EnabledSince;
import android.compat.annotation.Overridable;
+import android.content.AttributionSource;
import android.content.ComponentName;
import android.content.ComponentName.WithComponentName;
import android.content.Context;
@@ -1100,8 +1101,12 @@ public final class ActiveServices {
SystemClock.uptimeMillis()); // Use current time, not lastActivity.
}
}
- mAm.mAppOpsService.startOperation(AppOpsManager.getToken(mAm.mAppOpsService),
- AppOpsManager.OP_START_FOREGROUND, r.appInfo.uid, r.packageName, null,
+ final AttributionSource attributionSource = new AttributionSource.Builder(r.appInfo.uid)
+ .setPackageName(r.packageName)
+ .build();
+ mAm.mAppOpsService.startOperationWithState(AppOpsManager.getToken(mAm.mAppOpsService),
+ AppOpsManager.OP_START_FOREGROUND,
+ attributionSource.asState(),
true, false, null, false, AppOpsManager.ATTRIBUTION_FLAGS_NONE,
AppOpsManager.ATTRIBUTION_CHAIN_ID_NONE);
}
@@ -2451,10 +2456,15 @@ public final class ActiveServices {
stopProcStatsOp = false;
}
- mAm.mAppOpsService.startOperation(
+ final AttributionSource attributionSource = new AttributionSource
+ .Builder(r.appInfo.uid)
+ .setPackageName(r.packageName)
+ .build();
+ mAm.mAppOpsService.startOperationWithState(
AppOpsManager.getToken(mAm.mAppOpsService),
- AppOpsManager.OP_START_FOREGROUND, r.appInfo.uid, r.packageName,
- null, true, false, "", false, AppOpsManager.ATTRIBUTION_FLAGS_NONE,
+ AppOpsManager.OP_START_FOREGROUND, attributionSource.asState(),
+ true, false, "", false,
+ AppOpsManager.ATTRIBUTION_FLAGS_NONE,
AppOpsManager.ATTRIBUTION_CHAIN_ID_NONE);
registerAppOpCallbackLocked(r);
mAm.updateForegroundServiceUsageStats(r.name, r.userId, true);
@@ -2514,10 +2524,13 @@ public final class ActiveServices {
if (alreadyStartedOp) {
// If we had previously done a start op for direct foreground start,
// we have cleared the flag so can now drop it.
- mAm.mAppOpsService.finishOperation(
+ final AttributionSource attributionSource = new AttributionSource
+ .Builder(r.appInfo.uid)
+ .setPackageName(r.packageName)
+ .build();
+ mAm.mAppOpsService.finishOperationWithState(
AppOpsManager.getToken(mAm.mAppOpsService),
- AppOpsManager.OP_START_FOREGROUND, r.appInfo.uid, r.packageName,
- null);
+ AppOpsManager.OP_START_FOREGROUND, attributionSource.asState());
}
}
} else {
@@ -2560,9 +2573,13 @@ public final class ActiveServices {
SystemClock.uptimeMillis());
}
}
- mAm.mAppOpsService.finishOperation(
+ final AttributionSource attributionSource =
+ new AttributionSource.Builder(r.appInfo.uid)
+ .setPackageName(r.packageName)
+ .build();
+ mAm.mAppOpsService.finishOperationWithState(
AppOpsManager.getToken(mAm.mAppOpsService),
- AppOpsManager.OP_START_FOREGROUND, r.appInfo.uid, r.packageName, null);
+ AppOpsManager.OP_START_FOREGROUND, attributionSource.asState());
unregisterAppOpCallbackLocked(r);
logFGSStateChangeLocked(r,
FOREGROUND_SERVICE_STATE_CHANGED__STATE__EXIT,
@@ -5704,8 +5721,12 @@ public final class ActiveServices {
SystemClock.uptimeMillis());
}
}
- mAm.mAppOpsService.finishOperation(AppOpsManager.getToken(mAm.mAppOpsService),
- AppOpsManager.OP_START_FOREGROUND, r.appInfo.uid, r.packageName, null);
+ final AttributionSource attributionSource = new AttributionSource
+ .Builder(r.appInfo.uid)
+ .setPackageName(r.packageName)
+ .build();
+ mAm.mAppOpsService.finishOperationWithState(AppOpsManager.getToken(mAm.mAppOpsService),
+ AppOpsManager.OP_START_FOREGROUND, attributionSource.asState());
mServiceFGAnrTimer.cancel(r);
if (r.app != null) {
Message msg = mAm.mHandler.obtainMessage(
@@ -5770,9 +5791,13 @@ public final class ActiveServices {
SystemClock.uptimeMillis());
}
}
- mAm.mAppOpsService.finishOperation(
+ final AttributionSource attributionSource = new AttributionSource
+ .Builder(r.appInfo.uid)
+ .setPackageName(r.packageName)
+ .build();
+ mAm.mAppOpsService.finishOperationWithState(
AppOpsManager.getToken(mAm.mAppOpsService),
- AppOpsManager.OP_START_FOREGROUND, r.appInfo.uid, r.packageName, null);
+ AppOpsManager.OP_START_FOREGROUND, attributionSource.asState());
unregisterAppOpCallbackLocked(r);
r.mFgsExitTime = SystemClock.uptimeMillis();
logFGSStateChangeLocked(r,
@@ -8491,8 +8516,11 @@ public final class ActiveServices {
mAm.mBatteryStatsService.noteServiceStartRunning(callingUid, callingPackage,
cn.getClassName());
- mAm.mAppOpsService.startOperation(AppOpsManager.getToken(mAm.mAppOpsService),
- AppOpsManager.OP_START_FOREGROUND, r.appInfo.uid, r.packageName, null,
+ final AttributionSource attributionSource = new AttributionSource.Builder(r.appInfo.uid)
+ .setPackageName(r.packageName)
+ .build();
+ mAm.mAppOpsService.startOperationWithState(AppOpsManager.getToken(mAm.mAppOpsService),
+ AppOpsManager.OP_START_FOREGROUND, attributionSource.asState(),
true, false, null, false,
AppOpsManager.ATTRIBUTION_FLAGS_NONE, AppOpsManager.ATTRIBUTION_CHAIN_ID_NONE);
registerAppOpCallbackLocked(r);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index ae79f19f70f1..88bb66f8ef22 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -428,10 +428,11 @@ import com.android.internal.util.FastPrintWriter;
import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.util.MemInfoReader;
import com.android.internal.util.Preconditions;
-import com.android.internal.util.function.HeptFunction;
import com.android.internal.util.function.HexFunction;
+import com.android.internal.util.function.NonaFunction;
import com.android.internal.util.function.QuadFunction;
import com.android.internal.util.function.QuintFunction;
+import com.android.internal.util.function.TriFunction;
import com.android.internal.util.function.UndecFunction;
import com.android.server.AlarmManagerInternal;
import com.android.server.BootReceiver;
@@ -3150,8 +3151,11 @@ public class ActivityManagerService extends IActivityManager.Stub
}
private boolean hasUsageStatsPermission(String callingPackage, int callingUid, int callingPid) {
- final int mode = mAppOpsService.noteOperation(AppOpsManager.OP_GET_USAGE_STATS,
- callingUid, callingPackage, null, false, "", false).getOpMode();
+ final AttributionSource attributionSource = new AttributionSource.Builder(callingUid)
+ .setPackageName(callingPackage)
+ .build();
+ final int mode = mAppOpsService.noteOperationWithState(AppOpsManager.OP_GET_USAGE_STATS,
+ attributionSource.asState(), false, "", false).getOpMode();
if (mode == AppOpsManager.MODE_DEFAULT) {
return checkPermission(Manifest.permission.PACKAGE_USAGE_STATS, callingPid, callingUid)
== PackageManager.PERMISSION_GRANTED;
@@ -5929,9 +5933,18 @@ public class ActivityManagerService extends IActivityManager.Stub
@Override
public int noteOp(String op, int uid, String packageName) {
// TODO moltmann: Allow to specify featureId
- return mActivityManagerService.mAppOpsService
- .noteOperation(AppOpsManager.strOpToOp(op), uid, packageName, null,
- false, "", false).getOpMode();
+ final AttributionSource attributionSource = new AttributionSource.Builder(uid)
+ .setPackageName(packageName)
+ .build();
+ return mActivityManagerService
+ .mAppOpsService
+ .noteOperationWithState(
+ AppOpsManager.strOpToOp(op),
+ attributionSource.asState(),
+ false,
+ "",
+ false)
+ .getOpMode();
}
@Override
@@ -15934,7 +15947,7 @@ public class ActivityManagerService extends IActivityManager.Stub
try {
sdkSandboxInfo =
sandboxManagerLocal.getSdkSandboxApplicationInfoForInstrumentation(
- sdkSandboxClientAppInfo, userId, isSdkInSandbox);
+ sdkSandboxClientAppInfo, isSdkInSandbox);
} catch (NameNotFoundException e) {
reportStartInstrumentationFailureLocked(
watcher, className, "Can't find SdkSandbox package");
@@ -20059,20 +20072,26 @@ public class ActivityManagerService extends IActivityManager.Stub
}
@Override
- public int checkOperation(int code, int uid, String packageName,
- String attributionTag, boolean raw,
- QuintFunction<Integer, Integer, String, String, Boolean, Integer> superImpl) {
+ public int checkOperation(int code, AttributionSource attributionSource, boolean raw,
+ TriFunction<Integer, AttributionSource, Boolean, Integer> superImpl) {
+ final int uid = attributionSource.getUid();
+
if (uid == mTargetUid && isTargetOp(code)) {
final int shellUid = UserHandle.getUid(UserHandle.getUserId(uid),
Process.SHELL_UID);
+ final AttributionSource shellAttributionSource =
+ new AttributionSource.Builder(shellUid)
+ .setPackageName("com.android.shell")
+ .build();
+
final long identity = Binder.clearCallingIdentity();
try {
- return superImpl.apply(code, shellUid, "com.android.shell", null, raw);
+ return superImpl.apply(code, shellAttributionSource, raw);
} finally {
Binder.restoreCallingIdentity(identity);
}
}
- return superImpl.apply(code, uid, packageName, attributionTag, raw);
+ return superImpl.apply(code, attributionSource, raw);
}
@Override
@@ -20092,23 +20111,30 @@ public class ActivityManagerService extends IActivityManager.Stub
}
@Override
- public SyncNotedAppOp noteOperation(int code, int uid, @Nullable String packageName,
- @Nullable String featureId, boolean shouldCollectAsyncNotedOp,
+ public SyncNotedAppOp noteOperation(int code, AttributionSource attributionSource,
+ boolean shouldCollectAsyncNotedOp,
@Nullable String message, boolean shouldCollectMessage,
- @NonNull HeptFunction<Integer, Integer, String, String, Boolean, String, Boolean,
+ @NonNull QuintFunction<Integer, AttributionSource, Boolean, String, Boolean,
SyncNotedAppOp> superImpl) {
+ final int uid = attributionSource.getUid();
+ final String attributionTag = attributionSource.getAttributionTag();
if (uid == mTargetUid && isTargetOp(code)) {
final int shellUid = UserHandle.getUid(UserHandle.getUserId(uid),
Process.SHELL_UID);
final long identity = Binder.clearCallingIdentity();
+ final AttributionSource shellAttributionSource =
+ new AttributionSource.Builder(shellUid)
+ .setPackageName("com.android.shell")
+ .setAttributionTag(attributionTag)
+ .build();
try {
- return superImpl.apply(code, shellUid, "com.android.shell", featureId,
+ return superImpl.apply(code, shellAttributionSource,
shouldCollectAsyncNotedOp, message, shouldCollectMessage);
} finally {
Binder.restoreCallingIdentity(identity);
}
}
- return superImpl.apply(code, uid, packageName, featureId, shouldCollectAsyncNotedOp,
+ return superImpl.apply(code, attributionSource, shouldCollectAsyncNotedOp,
message, shouldCollectMessage);
}
@@ -20139,28 +20165,37 @@ public class ActivityManagerService extends IActivityManager.Stub
}
@Override
- public SyncNotedAppOp startOperation(IBinder token, int code, int uid,
- @Nullable String packageName, @Nullable String attributionTag,
+ public SyncNotedAppOp startOperation(IBinder token, int code,
+ AttributionSource attributionSource,
boolean startIfModeDefault, boolean shouldCollectAsyncNotedOp,
@Nullable String message, boolean shouldCollectMessage,
@AttributionFlags int attributionFlags, int attributionChainId,
- @NonNull UndecFunction<IBinder, Integer, Integer, String, String, Boolean,
+ @NonNull NonaFunction<IBinder, Integer, AttributionSource, Boolean,
Boolean, String, Boolean, Integer, Integer, SyncNotedAppOp> superImpl) {
+ final int uid = attributionSource.getUid();
+ final String attributionTag = attributionSource.getAttributionTag();
+
if (uid == mTargetUid && isTargetOp(code)) {
final int shellUid = UserHandle.getUid(UserHandle.getUserId(uid),
Process.SHELL_UID);
final long identity = Binder.clearCallingIdentity();
try {
- return superImpl.apply(token, code, shellUid, "com.android.shell",
- attributionTag, startIfModeDefault, shouldCollectAsyncNotedOp, message,
+ final AttributionSource shellAttributionSource =
+ new AttributionSource.Builder(shellUid)
+ .setPackageName("com.android.shell")
+ .setAttributionTag(attributionTag)
+ .build();
+
+ return superImpl.apply(token, code, shellAttributionSource,
+ startIfModeDefault, shouldCollectAsyncNotedOp, message,
shouldCollectMessage, attributionFlags, attributionChainId);
} finally {
Binder.restoreCallingIdentity(identity);
}
}
- return superImpl.apply(token, code, uid, packageName, attributionTag,
- startIfModeDefault, shouldCollectAsyncNotedOp, message, shouldCollectMessage,
- attributionFlags, attributionChainId);
+ return superImpl.apply(token, code, attributionSource, startIfModeDefault,
+ shouldCollectAsyncNotedOp, message, shouldCollectMessage, attributionFlags,
+ attributionChainId);
}
@Override
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index 69bf612f3e54..26b23ff72d9d 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -1179,7 +1179,7 @@ final class ActivityManagerShellCommand extends ShellCommand {
synchronized (mInternal.mOomAdjuster.mCachedAppOptimizer.mFreezerLock) {
app.mOptRecord.setFreezeSticky(isSticky);
mInternal.mOomAdjuster.mCachedAppOptimizer.unfreezeAppInternalLSP(app, 0,
- false);
+ true);
}
}
}
diff --git a/services/core/java/com/android/server/am/AppPermissionTracker.java b/services/core/java/com/android/server/am/AppPermissionTracker.java
index 18a91535a34c..947fcd38f5a0 100644
--- a/services/core/java/com/android/server/am/AppPermissionTracker.java
+++ b/services/core/java/com/android/server/am/AppPermissionTracker.java
@@ -37,6 +37,7 @@ import static com.android.server.am.BaseAppStateTracker.STATE_TYPE_PERMISSION;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.AppOpsManager;
+import android.content.AttributionSource;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager.OnPermissionsChangedListener;
@@ -192,7 +193,11 @@ final class AppPermissionTracker extends BaseAppStateTracker<AppPermissionPolicy
if (DEBUG_PERMISSION_TRACKER) {
final IAppOpsService appOpsService = mInjector.getIAppOpsService();
try {
- final int mode = appOpsService.checkOperation(op, uid, packageName);
+ final AttributionSource attributionSource = new AttributionSource.Builder(uid)
+ .setPackageName(packageName)
+ .build();
+ final int mode =
+ appOpsService.checkOperationWithState(op, attributionSource.asState());
Slog.i(TAG, "onOpChanged: " + opToPublicName(op)
+ " " + UserHandle.formatUid(uid)
+ " " + packageName + " " + mode);
@@ -307,7 +312,11 @@ final class AppPermissionTracker extends BaseAppStateTracker<AppPermissionPolicy
final IAppOpsService appOpsService = mInjector.getIAppOpsService();
for (String pkg : packages) {
try {
- final int mode = appOpsService.checkOperation(mAppOp, mUid, pkg);
+ final AttributionSource attributionSource =
+ new AttributionSource.Builder(mUid).setPackageName(pkg).build();
+ final int mode =
+ appOpsService.checkOperationWithState(
+ mAppOp, attributionSource.asState());
if (mode == AppOpsManager.MODE_ALLOWED) {
mAppOpAllowed = true;
return;
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 052b0c2078d1..d6997daaa12b 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -1143,22 +1143,32 @@ public class AppOpsService extends IAppOpsService.Stub {
}
}, RARELY_USED_PACKAGES_INITIALIZATION_DELAY_MILLIS);
- getPackageManagerInternal().setExternalSourcesPolicy(
- new PackageManagerInternal.ExternalSourcesPolicy() {
- @Override
- public int getPackageTrustedToInstallApps(String packageName, int uid) {
- int appOpMode = checkOperation(AppOpsManager.OP_REQUEST_INSTALL_PACKAGES,
- uid, packageName);
- switch (appOpMode) {
- case AppOpsManager.MODE_ALLOWED:
- return PackageManagerInternal.ExternalSourcesPolicy.USER_TRUSTED;
- case AppOpsManager.MODE_ERRORED:
- return PackageManagerInternal.ExternalSourcesPolicy.USER_BLOCKED;
- default:
- return PackageManagerInternal.ExternalSourcesPolicy.USER_DEFAULT;
- }
- }
- });
+ getPackageManagerInternal()
+ .setExternalSourcesPolicy(
+ new PackageManagerInternal.ExternalSourcesPolicy() {
+ @Override
+ public int getPackageTrustedToInstallApps(String packageName, int uid) {
+ final AttributionSource attributionSource =
+ new AttributionSource.Builder(uid)
+ .setPackageName(packageName)
+ .build();
+ int appOpMode =
+ checkOperationWithState(
+ AppOpsManager.OP_REQUEST_INSTALL_PACKAGES,
+ attributionSource.asState());
+ switch (appOpMode) {
+ case AppOpsManager.MODE_ALLOWED:
+ return PackageManagerInternal.ExternalSourcesPolicy
+ .USER_TRUSTED;
+ case AppOpsManager.MODE_ERRORED:
+ return PackageManagerInternal.ExternalSourcesPolicy
+ .USER_BLOCKED;
+ default:
+ return PackageManagerInternal.ExternalSourcesPolicy
+ .USER_DEFAULT;
+ }
+ }
+ });
}
@VisibleForTesting
@@ -2534,22 +2544,41 @@ public class AppOpsService extends IAppOpsService.Stub {
}
}
+ /** @deprecated Use {@link #checkOperationWithStateRaw} instead. */
@Override
public int checkOperationRaw(int code, int uid, String packageName,
- @Nullable String attributionTag) {
- return mCheckOpsDelegateDispatcher.checkOperation(code, uid, packageName, attributionTag,
- true /*raw*/);
+ @Nullable String attributionTag) {
+ final AttributionSource attributionSource = new AttributionSource.Builder(uid)
+ .setPackageName(packageName).setAttributionTag(attributionTag).build();
+ return mCheckOpsDelegateDispatcher.checkOperation(code, attributionSource, true /*raw*/);
+ }
+
+ @Override
+ public int checkOperationWithStateRaw(int code, AttributionSourceState attributionSourceState) {
+ final AttributionSource attributionSource = new AttributionSource(attributionSourceState);
+ return mCheckOpsDelegateDispatcher.checkOperation(code, attributionSource, true /*raw*/);
}
+ /** @deprecated Use {@link #checkOperationWithState} instead. */
@Override
public int checkOperation(int code, int uid, String packageName) {
- return mCheckOpsDelegateDispatcher.checkOperation(code, uid, packageName, null,
- false /*raw*/);
+ final AttributionSource attributionSource = new AttributionSource.Builder(uid)
+ .setPackageName(packageName)
+ .build();
+ return mCheckOpsDelegateDispatcher.checkOperation(code, attributionSource, false /*raw*/);
}
- private int checkOperationImpl(int code, int uid, String packageName,
- @Nullable String attributionTag, boolean raw) {
+ @Override
+ public int checkOperationWithState(int code, AttributionSourceState attributionSourceState) {
+ final AttributionSource attributionSource = new AttributionSource(attributionSourceState);
+ return mCheckOpsDelegateDispatcher.checkOperation(code, attributionSource, false /*raw*/);
+ }
+
+ private int checkOperationImpl(int code, AttributionSource attributionSource, boolean raw) {
verifyIncomingOp(code);
+ final String packageName = attributionSource.getPackageName();
+ final int uid = attributionSource.getUid();
+ final String attributionTag = attributionSource.getAttributionTag();
if (!isIncomingPackageValid(packageName, UserHandle.getUserId(uid))) {
return AppOpsManager.opToDefaultMode(code);
}
@@ -2614,7 +2643,10 @@ public class AppOpsService extends IAppOpsService.Stub {
if (mode != AppOpsManager.MODE_ALLOWED) {
return mode;
}
- return checkOperation(code, uid, packageName);
+ final AttributionSource attributionSource = new AttributionSource.Builder(uid)
+ .setPackageName(packageName)
+ .build();
+ return checkOperationWithState(code, attributionSource.asState());
}
@Override
@@ -2758,17 +2790,38 @@ public class AppOpsService extends IAppOpsService.Stub {
proxiedFlags, shouldCollectAsyncNotedOp, message, shouldCollectMessage);
}
+ /** @deprecated Use {@link #noteOperationWithState} instead. */
@Override
public SyncNotedAppOp noteOperation(int code, int uid, String packageName,
String attributionTag, boolean shouldCollectAsyncNotedOp, String message,
boolean shouldCollectMessage) {
- return mCheckOpsDelegateDispatcher.noteOperation(code, uid, packageName,
- attributionTag, shouldCollectAsyncNotedOp, message, shouldCollectMessage);
+ final AttributionSource attributionSource = new AttributionSource.Builder(uid)
+ .setPackageName(packageName)
+ .setAttributionTag(attributionTag)
+ .build();
+ return mCheckOpsDelegateDispatcher.noteOperation(code, attributionSource,
+ shouldCollectAsyncNotedOp, message, shouldCollectMessage);
+ }
+
+ @Override
+ public SyncNotedAppOp noteOperationWithState(
+ int code,
+ AttributionSourceState attributionSourceState,
+ boolean shouldCollectAsyncNotedOp,
+ String message,
+ boolean shouldCollectMessage) {
+ final AttributionSource attributionSource = new AttributionSource(attributionSourceState);
+ return mCheckOpsDelegateDispatcher.noteOperation(
+ code, attributionSource, shouldCollectAsyncNotedOp, message, shouldCollectMessage);
}
- private SyncNotedAppOp noteOperationImpl(int code, int uid, @Nullable String packageName,
- @Nullable String attributionTag, boolean shouldCollectAsyncNotedOp,
+ private SyncNotedAppOp noteOperationImpl(int code, AttributionSource attributionSource,
+ boolean shouldCollectAsyncNotedOp,
@Nullable String message, boolean shouldCollectMessage) {
+ final int uid = attributionSource.getUid();
+ final String packageName = attributionSource.getPackageName();
+ final String attributionTag = attributionSource.getAttributionTag();
+
verifyIncomingUid(uid);
verifyIncomingOp(code);
if (!isIncomingPackageValid(packageName, UserHandle.getUserId(uid))) {
@@ -3163,22 +3216,42 @@ public class AppOpsService extends IAppOpsService.Stub {
}
}
+ /** @deprecated Use {@link #startOperationWithState} instead. */
@Override
public SyncNotedAppOp startOperation(IBinder token, int code, int uid,
- @Nullable String packageName, @Nullable String attributionTag,
+ @Nullable String packageName, @Nullable String attributionTag,
+ boolean startIfModeDefault, boolean shouldCollectAsyncNotedOp,
+ String message, boolean shouldCollectMessage, @AttributionFlags int attributionFlags,
+ int attributionChainId) {
+ final AttributionSource attributionSource = new AttributionSource.Builder(uid)
+ .setPackageName(packageName)
+ .setAttributionTag(attributionTag)
+ .build();
+ return mCheckOpsDelegateDispatcher.startOperation(token, code, attributionSource,
+ startIfModeDefault, shouldCollectAsyncNotedOp, message, shouldCollectMessage,
+ attributionFlags, attributionChainId);
+ }
+
+ @Override
+ public SyncNotedAppOp startOperationWithState(IBinder token, int code,
+ AttributionSourceState attributionSourceState,
boolean startIfModeDefault, boolean shouldCollectAsyncNotedOp,
String message, boolean shouldCollectMessage, @AttributionFlags int attributionFlags,
int attributionChainId) {
- return mCheckOpsDelegateDispatcher.startOperation(token, code, uid, packageName,
- attributionTag, startIfModeDefault, shouldCollectAsyncNotedOp, message,
+ final AttributionSource attributionSource = new AttributionSource(attributionSourceState);
+ return mCheckOpsDelegateDispatcher.startOperation(token, code, attributionSource,
+ startIfModeDefault, shouldCollectAsyncNotedOp, message,
shouldCollectMessage, attributionFlags, attributionChainId);
}
- private SyncNotedAppOp startOperationImpl(@NonNull IBinder clientId, int code, int uid,
- @Nullable String packageName, @Nullable String attributionTag,
- boolean startIfModeDefault, boolean shouldCollectAsyncNotedOp, @NonNull String message,
+ private SyncNotedAppOp startOperationImpl(@NonNull IBinder clientId, int code,
+ AttributionSource attributionSource, boolean startIfModeDefault,
+ boolean shouldCollectAsyncNotedOp, @NonNull String message,
boolean shouldCollectMessage, @AttributionFlags int attributionFlags,
int attributionChainId) {
+ final String packageName = attributionSource.getPackageName();
+ final int uid = attributionSource.getUid();
+ final String attributionTag = attributionSource.getAttributionTag();
verifyIncomingUid(uid);
verifyIncomingOp(code);
if (!isIncomingPackageValid(packageName, UserHandle.getUserId(uid))) {
@@ -3200,7 +3273,7 @@ public class AppOpsService extends IAppOpsService.Stub {
int result = MODE_DEFAULT;
if (code == OP_RECORD_AUDIO_HOTWORD || code == OP_RECEIVE_AMBIENT_TRIGGER_AUDIO
|| code == OP_RECORD_AUDIO_SANDBOXED) {
- result = checkOperation(OP_RECORD_AUDIO, uid, packageName);
+ result = checkOperationWithState(OP_RECORD_AUDIO, attributionSource.asState());
// Check result
if (result != AppOpsManager.MODE_ALLOWED) {
return new SyncNotedAppOp(result, code, attributionTag, packageName);
@@ -3208,7 +3281,7 @@ public class AppOpsService extends IAppOpsService.Stub {
}
// As a special case for OP_CAMERA_SANDBOXED.
if (code == OP_CAMERA_SANDBOXED) {
- result = checkOperation(OP_CAMERA, uid, packageName);
+ result = checkOperationWithState(OP_CAMERA, attributionSource.asState());
// Check result
if (result != AppOpsManager.MODE_ALLOWED) {
return new SyncNotedAppOp(result, code, attributionTag, packageName);
@@ -3512,15 +3585,29 @@ public class AppOpsService extends IAppOpsService.Stub {
packageName);
}
+ /** @deprecated Use {@link #finishOperationWithState} instead. */
@Override
public void finishOperation(IBinder clientId, int code, int uid, String packageName,
String attributionTag) {
- mCheckOpsDelegateDispatcher.finishOperation(clientId, code, uid, packageName,
- attributionTag);
+ final AttributionSource attributionSource = new AttributionSource.Builder(uid)
+ .setPackageName(packageName)
+ .setAttributionTag(attributionTag)
+ .build();
+ mCheckOpsDelegateDispatcher.finishOperation(clientId, code, attributionSource);
}
- private void finishOperationImpl(IBinder clientId, int code, int uid, String packageName,
- String attributionTag) {
+ @Override
+ public void finishOperationWithState(IBinder clientId, int code,
+ AttributionSourceState attributionSourceState) {
+ final AttributionSource attributionSource = new AttributionSource(attributionSourceState);
+ mCheckOpsDelegateDispatcher.finishOperation(clientId, code, attributionSource);
+ }
+
+ private void finishOperationImpl(IBinder clientId, int code,
+ AttributionSource attributionSource) {
+ final String packageName = attributionSource.getPackageName();
+ final int uid = attributionSource.getUid();
+ final String attributionTag = attributionSource.getAttributionTag();
verifyIncomingUid(uid);
verifyIncomingOp(code);
if (!isIncomingPackageValid(packageName, UserHandle.getUserId(uid))) {
@@ -5103,8 +5190,13 @@ public class AppOpsService extends IAppOpsService.Stub {
}
if (shell.packageName != null) {
- shell.mInterface.startOperation(shell.mToken, shell.op, shell.packageUid,
- shell.packageName, shell.attributionTag, true, true,
+ final AttributionSource shellAttributionSource =
+ new AttributionSource.Builder(shell.packageUid)
+ .setPackageName(shell.packageName)
+ .setAttributionTag(shell.attributionTag)
+ .build();
+ shell.mInterface.startOperationWithState(shell.mToken, shell.op,
+ shellAttributionSource.asState(), true, true,
"appops start shell command", true,
AppOpsManager.ATTRIBUTION_FLAG_ACCESSOR, ATTRIBUTION_CHAIN_ID_NONE);
} else {
@@ -5119,8 +5211,13 @@ public class AppOpsService extends IAppOpsService.Stub {
}
if (shell.packageName != null) {
- shell.mInterface.finishOperation(shell.mToken, shell.op, shell.packageUid,
- shell.packageName, shell.attributionTag);
+ final AttributionSource shellAttributionSource =
+ new AttributionSource.Builder(shell.packageUid)
+ .setPackageName(shell.packageName)
+ .setAttributionTag(shell.attributionTag)
+ .build();
+ shell.mInterface.finishOperationWithState(shell.mToken, shell.op,
+ shellAttributionSource.asState());
} else {
return -1;
}
@@ -6666,25 +6763,24 @@ public class AppOpsService extends IAppOpsService.Stub {
return mCheckOpsDelegate;
}
- public int checkOperation(int code, int uid, String packageName,
- @Nullable String attributionTag, boolean raw) {
+ public int checkOperation(int code, AttributionSource attributionSource, boolean raw) {
if (mPolicy != null) {
if (mCheckOpsDelegate != null) {
- return mPolicy.checkOperation(code, uid, packageName, attributionTag, raw,
+ return mPolicy.checkOperation(code, attributionSource, raw,
this::checkDelegateOperationImpl);
} else {
- return mPolicy.checkOperation(code, uid, packageName, attributionTag, raw,
+ return mPolicy.checkOperation(code, attributionSource, raw,
AppOpsService.this::checkOperationImpl);
}
} else if (mCheckOpsDelegate != null) {
- return checkDelegateOperationImpl(code, uid, packageName, attributionTag, raw);
+ return checkDelegateOperationImpl(code, attributionSource, raw);
}
- return checkOperationImpl(code, uid, packageName, attributionTag, raw);
+ return checkOperationImpl(code, attributionSource, raw);
}
- private int checkDelegateOperationImpl(int code, int uid, String packageName,
- @Nullable String attributionTag, boolean raw) {
- return mCheckOpsDelegate.checkOperation(code, uid, packageName, attributionTag, raw,
+ private int checkDelegateOperationImpl(int code, AttributionSource attributionSource,
+ boolean raw) {
+ return mCheckOpsDelegate.checkOperation(code, attributionSource, raw,
AppOpsService.this::checkOperationImpl);
}
@@ -6709,32 +6805,32 @@ public class AppOpsService extends IAppOpsService.Stub {
AppOpsService.this::checkAudioOperationImpl);
}
- public SyncNotedAppOp noteOperation(int code, int uid, String packageName,
- String attributionTag, boolean shouldCollectAsyncNotedOp, String message,
+ public SyncNotedAppOp noteOperation(int code, AttributionSource attributionSource,
+ boolean shouldCollectAsyncNotedOp, String message,
boolean shouldCollectMessage) {
if (mPolicy != null) {
if (mCheckOpsDelegate != null) {
- return mPolicy.noteOperation(code, uid, packageName, attributionTag,
+ return mPolicy.noteOperation(code, attributionSource,
shouldCollectAsyncNotedOp, message, shouldCollectMessage,
this::noteDelegateOperationImpl);
} else {
- return mPolicy.noteOperation(code, uid, packageName, attributionTag,
+ return mPolicy.noteOperation(code, attributionSource,
shouldCollectAsyncNotedOp, message, shouldCollectMessage,
AppOpsService.this::noteOperationImpl);
}
} else if (mCheckOpsDelegate != null) {
- return noteDelegateOperationImpl(code, uid, packageName,
- attributionTag, shouldCollectAsyncNotedOp, message, shouldCollectMessage);
+ return noteDelegateOperationImpl(code, attributionSource, shouldCollectAsyncNotedOp,
+ message, shouldCollectMessage);
}
- return noteOperationImpl(code, uid, packageName, attributionTag,
+ return noteOperationImpl(code, attributionSource,
shouldCollectAsyncNotedOp, message, shouldCollectMessage);
}
- private SyncNotedAppOp noteDelegateOperationImpl(int code, int uid,
- @Nullable String packageName, @Nullable String featureId,
+ private SyncNotedAppOp noteDelegateOperationImpl(int code,
+ AttributionSource attributionSource,
boolean shouldCollectAsyncNotedOp, @Nullable String message,
boolean shouldCollectMessage) {
- return mCheckOpsDelegate.noteOperation(code, uid, packageName, featureId,
+ return mCheckOpsDelegate.noteOperation(code, attributionSource,
shouldCollectAsyncNotedOp, message, shouldCollectMessage,
AppOpsService.this::noteOperationImpl);
}
@@ -6770,39 +6866,38 @@ public class AppOpsService extends IAppOpsService.Stub {
AppOpsService.this::noteProxyOperationImpl);
}
- public SyncNotedAppOp startOperation(IBinder token, int code, int uid,
- @Nullable String packageName, @NonNull String attributionTag,
- boolean startIfModeDefault, boolean shouldCollectAsyncNotedOp,
- @Nullable String message, boolean shouldCollectMessage,
- @AttributionFlags int attributionFlags, int attributionChainId) {
+ public SyncNotedAppOp startOperation(IBinder token, int code,
+ AttributionSource attributionSource, boolean startIfModeDefault,
+ boolean shouldCollectAsyncNotedOp, @Nullable String message,
+ boolean shouldCollectMessage, @AttributionFlags int attributionFlags,
+ int attributionChainId) {
if (mPolicy != null) {
if (mCheckOpsDelegate != null) {
- return mPolicy.startOperation(token, code, uid, packageName,
- attributionTag, startIfModeDefault, shouldCollectAsyncNotedOp, message,
+ return mPolicy.startOperation(token, code, attributionSource,
+ startIfModeDefault, shouldCollectAsyncNotedOp, message,
shouldCollectMessage, attributionFlags, attributionChainId,
this::startDelegateOperationImpl);
} else {
- return mPolicy.startOperation(token, code, uid, packageName, attributionTag,
+ return mPolicy.startOperation(token, code, attributionSource,
startIfModeDefault, shouldCollectAsyncNotedOp, message,
shouldCollectMessage, attributionFlags, attributionChainId,
AppOpsService.this::startOperationImpl);
}
} else if (mCheckOpsDelegate != null) {
- return startDelegateOperationImpl(token, code, uid, packageName, attributionTag,
+ return startDelegateOperationImpl(token, code, attributionSource,
startIfModeDefault, shouldCollectAsyncNotedOp, message,
shouldCollectMessage, attributionFlags, attributionChainId);
}
- return startOperationImpl(token, code, uid, packageName, attributionTag,
+ return startOperationImpl(token, code, attributionSource,
startIfModeDefault, shouldCollectAsyncNotedOp, message, shouldCollectMessage,
attributionFlags, attributionChainId);
}
- private SyncNotedAppOp startDelegateOperationImpl(IBinder token, int code, int uid,
- @Nullable String packageName, @Nullable String attributionTag,
- boolean startIfModeDefault, boolean shouldCollectAsyncNotedOp, String message,
- boolean shouldCollectMessage, @AttributionFlags int attributionFlags,
- int attributionChainId) {
- return mCheckOpsDelegate.startOperation(token, code, uid, packageName, attributionTag,
+ private SyncNotedAppOp startDelegateOperationImpl(IBinder token, int code,
+ AttributionSource attributionSource, boolean startIfModeDefault,
+ boolean shouldCollectAsyncNotedOp, String message, boolean shouldCollectMessage,
+ @AttributionFlags int attributionFlags, int attributionChainId) {
+ return mCheckOpsDelegate.startOperation(token, code, attributionSource,
startIfModeDefault, shouldCollectAsyncNotedOp, message, shouldCollectMessage,
attributionFlags, attributionChainId, AppOpsService.this::startOperationImpl);
}
@@ -6848,26 +6943,26 @@ public class AppOpsService extends IAppOpsService.Stub {
attributionChainId, AppOpsService.this::startProxyOperationImpl);
}
- public void finishOperation(IBinder clientId, int code, int uid, String packageName,
- String attributionTag) {
+ public void finishOperation(IBinder clientId, int code,
+ AttributionSource attributionSource) {
if (mPolicy != null) {
if (mCheckOpsDelegate != null) {
- mPolicy.finishOperation(clientId, code, uid, packageName, attributionTag,
+ mPolicy.finishOperation(clientId, code, attributionSource,
this::finishDelegateOperationImpl);
} else {
- mPolicy.finishOperation(clientId, code, uid, packageName, attributionTag,
+ mPolicy.finishOperation(clientId, code, attributionSource,
AppOpsService.this::finishOperationImpl);
}
} else if (mCheckOpsDelegate != null) {
- finishDelegateOperationImpl(clientId, code, uid, packageName, attributionTag);
+ finishDelegateOperationImpl(clientId, code, attributionSource);
} else {
- finishOperationImpl(clientId, code, uid, packageName, attributionTag);
+ finishOperationImpl(clientId, code, attributionSource);
}
}
- private void finishDelegateOperationImpl(IBinder clientId, int code, int uid,
- String packageName, String attributionTag) {
- mCheckOpsDelegate.finishOperation(clientId, code, uid, packageName, attributionTag,
+ private void finishDelegateOperationImpl(IBinder clientId, int code,
+ AttributionSource attributionSource) {
+ mCheckOpsDelegate.finishOperation(clientId, code, attributionSource,
AppOpsService.this::finishOperationImpl);
}
diff --git a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
index 7f3ea6a0a99e..0d3e0bc6b9cd 100644
--- a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
+++ b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
@@ -77,8 +77,8 @@ public class DisplayManagerFlags {
Flags::enablePowerThrottlingClamper);
private final FlagState mSmallAreaDetectionFlagState = new FlagState(
- Flags.FLAG_ENABLE_SMALL_AREA_DETECTION,
- Flags::enableSmallAreaDetection);
+ com.android.graphics.surfaceflinger.flags.Flags.FLAG_ENABLE_SMALL_AREA_DETECTION,
+ com.android.graphics.surfaceflinger.flags.Flags::enableSmallAreaDetection);
/** Returns whether connected display management is enabled or not. */
public boolean isConnectedDisplayManagementEnabled() {
diff --git a/services/core/java/com/android/server/display/feature/display_flags.aconfig b/services/core/java/com/android/server/display/feature/display_flags.aconfig
index 9141814da6fc..9ab9c9def61b 100644
--- a/services/core/java/com/android/server/display/feature/display_flags.aconfig
+++ b/services/core/java/com/android/server/display/feature/display_flags.aconfig
@@ -104,12 +104,3 @@ flag {
bug: "211737588"
is_fixed_read_only: true
}
-
-flag {
- name: "enable_small_area_detection"
- namespace: "display_manager"
- description: "Feature flag for SmallAreaDetection"
- bug: "298722189"
- is_fixed_read_only: true
-}
-
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java
index 08503cb2e9f8..3e46ee29346e 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java
@@ -50,6 +50,8 @@ public abstract class InputMethodManagerInternal {
/**
* Called by the power manager to tell the input method manager whether it
* should start watching for wake events.
+ *
+ * @param interactive the interactive mode parameter
*/
public abstract void setInteractive(boolean interactive);
@@ -61,16 +63,16 @@ public abstract class InputMethodManagerInternal {
/**
* Returns the list of installed input methods for the specified user.
*
- * @param userId The user ID to be queried.
- * @return A list of {@link InputMethodInfo}. VR-only IMEs are already excluded.
+ * @param userId the user ID to be queried
+ * @return a list of {@link InputMethodInfo}. VR-only IMEs are already excluded
*/
public abstract List<InputMethodInfo> getInputMethodListAsUser(@UserIdInt int userId);
/**
* Returns the list of installed input methods that are enabled for the specified user.
*
- * @param userId The user ID to be queried.
- * @return A list of {@link InputMethodInfo} that are enabled for {@code userId}.
+ * @param userId the user ID to be queried
+ * @return a list of {@link InputMethodInfo} that are enabled for {@code userId}
*/
public abstract List<InputMethodInfo> getEnabledInputMethodListAsUser(@UserIdInt int userId);
@@ -78,8 +80,10 @@ public abstract class InputMethodManagerInternal {
* Called by the Autofill Frameworks to request an {@link InlineSuggestionsRequest} from
* the input method.
*
+ * @param userId the user ID to be queried
* @param requestInfo information needed to create an {@link InlineSuggestionsRequest}.
- * @param cb {@link IInlineSuggestionsRequestCallback} used to pass back the request object.
+ * @param cb {@link IInlineSuggestionsRequestCallback} used to pass back the request
+ * object
*/
public abstract void onCreateInlineSuggestionsRequest(@UserIdInt int userId,
InlineSuggestionsRequestInfo requestInfo, IInlineSuggestionsRequestCallback cb);
@@ -88,8 +92,8 @@ public abstract class InputMethodManagerInternal {
* Force switch to the enabled input method by {@code imeId} for current user. If the input
* method with {@code imeId} is not enabled or not installed, do nothing.
*
- * @param imeId The input method ID to be switched to.
- * @param userId The user ID to be queried.
+ * @param imeId the input method ID to be switched to
+ * @param userId the user ID to be queried
* @return {@code true} if the current input method was successfully switched to the input
* method by {@code imeId}; {@code false} the input method with {@code imeId} is not available
* to be switched.
@@ -100,28 +104,30 @@ public abstract class InputMethodManagerInternal {
* Force enable or disable the input method associated with {@code imeId} for given user. If
* the input method associated with {@code imeId} is not installed, do nothing.
*
- * @param imeId The input method ID to be enabled or disabled.
+ * @param imeId the input method ID to be enabled or disabled
* @param enabled {@code true} if the input method associated with {@code imeId} should be
- * enabled.
- * @param userId The user ID to be queried.
+ * enabled
+ * @param userId the user ID to be queried
* @return {@code true} if the input method associated with {@code imeId} was successfully
- * enabled or disabled, {@code false} if the input method specified is not installed
- * or was unable to be enabled/disabled for some other reason.
+ * enabled or disabled, {@code false} if the input method specified is not installed
+ * or was unable to be enabled/disabled for some other reason.
*/
public abstract boolean setInputMethodEnabled(String imeId, boolean enabled,
@UserIdInt int userId);
/**
* Registers a new {@link InputMethodListListener}.
+ *
+ * @param listener the listener to add
*/
public abstract void registerInputMethodListListener(InputMethodListListener listener);
/**
* Transfers input focus from a given input token to that of the IME window.
*
- * @param sourceInputToken The source token.
- * @param displayId The display hosting the IME window.
- * @return {@code true} if the transfer is successful.
+ * @param sourceInputToken the source token.
+ * @param displayId the display hosting the IME window
+ * @return {@code true} if the transfer is successful
*/
public abstract boolean transferTouchFocusToImeWindow(@NonNull IBinder sourceInputToken,
int displayId);
@@ -132,7 +138,7 @@ public abstract class InputMethodManagerInternal {
* or SystemUI).
*
* @param windowToken the window token that is now in control, or {@code null} if no client
- * window is in control of the IME.
+ * window is in control of the IME
*/
public abstract void reportImeControl(@Nullable IBinder windowToken);
@@ -163,8 +169,8 @@ public abstract class InputMethodManagerInternal {
* Callback when the IInputMethodSession from the accessibility service with the specified
* accessibilityConnectionId is created.
*
- * @param accessibilityConnectionId The connection id of the accessibility service.
- * @param session The session passed back from the accessibility service.
+ * @param accessibilityConnectionId the connection id of the accessibility service
+ * @param session the session passed back from the accessibility service
*/
public abstract void onSessionForAccessibilityCreated(int accessibilityConnectionId,
IAccessibilityInputMethodSession session);
@@ -173,7 +179,7 @@ public abstract class InputMethodManagerInternal {
* Unbind the accessibility service with the specified accessibilityConnectionId from current
* client.
*
- * @param accessibilityConnectionId The connection id of the accessibility service.
+ * @param accessibilityConnectionId the connection id of the accessibility service
*/
public abstract void unbindAccessibilityFromCurrentClient(int accessibilityConnectionId);
@@ -181,7 +187,7 @@ public abstract class InputMethodManagerInternal {
* Switch the keyboard layout in response to a keyboard shortcut.
*
* @param direction {@code 1} to switch to the next subtype, {@code -1} to switch to the
- * previous subtype.
+ * previous subtype
*/
public abstract void switchKeyboardLayout(int direction);
@@ -192,7 +198,7 @@ public abstract class InputMethodManagerInternal {
public abstract boolean isAnyInputConnectionActive();
/**
- * Fake implementation of {@link InputMethodManagerInternal}. All the methods do nothing.
+ * Fake implementation of {@link InputMethodManagerInternal}. All the methods do nothing.
*/
private static final InputMethodManagerInternal NOP =
new InputMethodManagerInternal() {
@@ -282,7 +288,7 @@ public abstract class InputMethodManagerInternal {
};
/**
- * @return Global instance if exists. Otherwise, a fallback no-op instance.
+ * @return Global instance if exists. Otherwise, a fallback no-op instance.
*/
@NonNull
public static InputMethodManagerInternal get() {
diff --git a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
index 9dec1dff4cf0..d456a7478551 100644
--- a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
+++ b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
@@ -192,6 +192,7 @@ class MediaRouter2ServiceImpl {
// Start of methods that implement MediaRouter2 operations.
+ @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
@NonNull
public boolean verifyPackageExists(@NonNull String clientPackageName) {
final int pid = Binder.getCallingPid();
@@ -199,11 +200,7 @@ class MediaRouter2ServiceImpl {
final long token = Binder.clearCallingIdentity();
try {
- mContext.enforcePermission(
- Manifest.permission.MEDIA_CONTENT_CONTROL,
- pid,
- uid,
- "Must hold MEDIA_CONTENT_CONTROL permission.");
+ enforcePrivilegedRoutingPermissions(uid, pid);
PackageManager pm = mContext.getPackageManager();
pm.getPackageInfo(clientPackageName, PackageManager.PackageInfoFlags.of(0));
return true;
@@ -482,6 +479,7 @@ class MediaRouter2ServiceImpl {
}
}
+ @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
public void registerManager(@NonNull IMediaRouter2Manager manager,
@NonNull String callerPackageName) {
Objects.requireNonNull(manager, "manager must not be null");
@@ -729,6 +727,15 @@ class MediaRouter2ServiceImpl {
return hasBluetoothRoutingPermission;
}
+ @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
+ private void enforcePrivilegedRoutingPermissions(int callerUid, int callerPid) {
+ mContext.enforcePermission(
+ Manifest.permission.MEDIA_CONTENT_CONTROL,
+ callerPid,
+ callerUid,
+ "Must hold MEDIA_CONTENT_CONTROL permission.");
+ }
+
// End of methods that implements operations for both MediaRouter2 and MediaRouter2Manager.
public void dump(@NonNull PrintWriter pw, @NonNull String prefix) {
@@ -837,15 +844,18 @@ class MediaRouter2ServiceImpl {
private void unregisterRouter2Locked(@NonNull IMediaRouter2 router, boolean died) {
RouterRecord routerRecord = mAllRouterRecords.remove(router.asBinder());
if (routerRecord == null) {
- Slog.w(TAG, "Ignoring unregistering unknown router2");
+ Slog.w(
+ TAG,
+ TextUtils.formatSimple(
+ "Ignoring unregistering unknown router: %s, died: %b", router, died));
return;
}
Slog.i(
TAG,
TextUtils.formatSimple(
- "unregisterRouter2 | package: %s, router id: %d",
- routerRecord.mPackageName, routerRecord.mRouterId));
+ "unregisterRouter2 | package: %s, router id: %d, died: %b",
+ routerRecord.mPackageName, routerRecord.mRouterId, died));
UserRecord userRecord = routerRecord.mUserRecord;
userRecord.mRouterRecords.remove(routerRecord);
@@ -1161,6 +1171,7 @@ class MediaRouter2ServiceImpl {
return sessionInfos;
}
+ @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
@GuardedBy("mLock")
private void registerManagerLocked(
@NonNull IMediaRouter2Manager manager,
@@ -1184,8 +1195,7 @@ class MediaRouter2ServiceImpl {
+ " callerUserId: %d",
callerUid, callerPid, callerPackageName, callerUserId));
- mContext.enforcePermission(Manifest.permission.MEDIA_CONTENT_CONTROL, callerPid, callerUid,
- "Must hold MEDIA_CONTENT_CONTROL permission.");
+ enforcePrivilegedRoutingPermissions(callerUid, callerPid);
UserRecord userRecord = getOrCreateUserRecordLocked(callerUserId);
managerRecord = new ManagerRecord(
@@ -1230,15 +1240,22 @@ class MediaRouter2ServiceImpl {
private void unregisterManagerLocked(@NonNull IMediaRouter2Manager manager, boolean died) {
ManagerRecord managerRecord = mAllManagerRecords.remove(manager.asBinder());
if (managerRecord == null) {
+ Slog.w(
+ TAG,
+ TextUtils.formatSimple(
+ "Ignoring unregistering unknown manager: %s, died: %b", manager, died));
return;
}
UserRecord userRecord = managerRecord.mUserRecord;
- Slog.i(TAG, TextUtils.formatSimple(
- "unregisterManager | package: %s, user: %d, manager: %d",
- managerRecord.mOwnerPackageName,
- userRecord.mUserId,
- managerRecord.mManagerId));
+ Slog.i(
+ TAG,
+ TextUtils.formatSimple(
+ "unregisterManager | package: %s, user: %d, manager: %d, died: %b",
+ managerRecord.mOwnerPackageName,
+ userRecord.mUserId,
+ managerRecord.mManagerId,
+ died));
userRecord.mManagerRecords.remove(managerRecord);
managerRecord.dispose();
diff --git a/services/core/java/com/android/server/media/MediaRouterService.java b/services/core/java/com/android/server/media/MediaRouterService.java
index 44719f88351b..6df4a95f8b8c 100644
--- a/services/core/java/com/android/server/media/MediaRouterService.java
+++ b/services/core/java/com/android/server/media/MediaRouterService.java
@@ -409,6 +409,7 @@ public final class MediaRouterService extends IMediaRouterService.Stub
}
// Binder call
+ @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
@Override
public boolean verifyPackageExists(String clientPackageName) {
return mService2.verifyPackageExists(clientPackageName);
@@ -536,6 +537,7 @@ public final class MediaRouterService extends IMediaRouterService.Stub
}
// Binder call
+ @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
@Override
public void registerManager(IMediaRouter2Manager manager, String callerPackageName) {
final int uid = Binder.getCallingUid();
diff --git a/services/core/java/com/android/server/media/projection/FrameworkStatsLogWrapper.java b/services/core/java/com/android/server/media/projection/FrameworkStatsLogWrapper.java
index 5bad06777328..6c74cba99bcb 100644
--- a/services/core/java/com/android/server/media/projection/FrameworkStatsLogWrapper.java
+++ b/services/core/java/com/android/server/media/projection/FrameworkStatsLogWrapper.java
@@ -21,8 +21,8 @@ import com.android.internal.util.FrameworkStatsLog;
/** Wrapper around {@link FrameworkStatsLog} */
public class FrameworkStatsLogWrapper {
- /** Wrapper around {@link FrameworkStatsLog#write}. */
- public void write(
+ /** Wrapper around {@link FrameworkStatsLog#write} for MediaProjectionStateChanged atom. */
+ public void writeStateChanged(
int code,
int sessionId,
int state,
@@ -41,4 +41,21 @@ public class FrameworkStatsLogWrapper {
timeSinceLastActive,
creationSource);
}
+
+ /** Wrapper around {@link FrameworkStatsLog#write} for MediaProjectionTargetChanged atom. */
+ public void writeTargetChanged(
+ int code,
+ int sessionId,
+ int targetType,
+ int hostUid,
+ int targetUid,
+ int windowingMode) {
+ FrameworkStatsLog.write(
+ code,
+ sessionId,
+ targetType,
+ hostUid,
+ targetUid,
+ windowingMode);
+ }
}
diff --git a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
index 893ed6119f9f..6deda468f9a2 100644
--- a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
+++ b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
@@ -479,6 +479,18 @@ public final class MediaProjectionManagerService extends SystemService
mMediaProjectionMetricsLogger.logAppSelectorDisplayed(hostUid);
}
+ @VisibleForTesting
+ void notifyWindowingModeChanged(int contentToRecord, int targetUid, int windowingMode) {
+ synchronized (mLock) {
+ if (mProjectionGrant == null) {
+ Slog.i(TAG, "Cannot log MediaProjectionTargetChanged atom due to null projection");
+ } else {
+ mMediaProjectionMetricsLogger.logChangedWindowingMode(
+ contentToRecord, mProjectionGrant.uid, targetUid, windowingMode);
+ }
+ }
+ }
+
/**
* Handles result of dialog shown from
* {@link BinderService#buildReviewGrantedConsentIntentLocked()}.
@@ -905,6 +917,20 @@ public final class MediaProjectionManagerService extends SystemService
}
@Override // Binder call
+ @EnforcePermission(MANAGE_MEDIA_PROJECTION)
+ public void notifyWindowingModeChanged(
+ int contentToRecord, int targetUid, int windowingMode) {
+ notifyWindowingModeChanged_enforcePermission();
+ final long token = Binder.clearCallingIdentity();
+ try {
+ MediaProjectionManagerService.this.notifyWindowingModeChanged(
+ contentToRecord, targetUid, windowingMode);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ @Override // Binder call
public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) {
if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
final long token = Binder.clearCallingIdentity();
diff --git a/services/core/java/com/android/server/media/projection/MediaProjectionMetricsLogger.java b/services/core/java/com/android/server/media/projection/MediaProjectionMetricsLogger.java
index d7fefeb0b1fe..be2a25a755a5 100644
--- a/services/core/java/com/android/server/media/projection/MediaProjectionMetricsLogger.java
+++ b/services/core/java/com/android/server/media/projection/MediaProjectionMetricsLogger.java
@@ -16,16 +16,32 @@
package com.android.server.media.projection;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
+import static android.view.ContentRecordingSession.RECORD_CONTENT_DISPLAY;
+import static android.view.ContentRecordingSession.RECORD_CONTENT_TASK;
+
import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__CREATION_SOURCE__CREATION_SOURCE_UNKNOWN;
import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_APP_SELECTOR_DISPLAYED;
import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_CAPTURING_IN_PROGRESS;
import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_INITIATED;
import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_PERMISSION_REQUEST_DISPLAYED;
import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_STOPPED;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_TARGET_CHANGED__TARGET_TYPE__TARGET_TYPE_APP_TASK;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_TARGET_CHANGED__TARGET_TYPE__TARGET_TYPE_DISPLAY;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_TARGET_CHANGED__TARGET_TYPE__TARGET_TYPE_UNKNOWN;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_TARGET_CHANGED__TARGET_WINDOWING_MODE__WINDOWING_MODE_FREEFORM;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_TARGET_CHANGED__TARGET_WINDOWING_MODE__WINDOWING_MODE_FULLSCREEN;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_TARGET_CHANGED__TARGET_WINDOWING_MODE__WINDOWING_MODE_SPLIT_SCREEN;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_TARGET_CHANGED__TARGET_WINDOWING_MODE__WINDOWING_MODE_UNKNOWN;
+import android.app.WindowConfiguration.WindowingMode;
import android.content.Context;
import android.util.Log;
+import android.view.ContentRecordingSession.RecordContent;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.FrameworkStatsLog;
import java.time.Duration;
@@ -91,7 +107,7 @@ public class MediaProjectionMetricsLogger {
durationSinceLastActiveSession == null
? TIME_SINCE_LAST_ACTIVE_UNKNOWN
: (int) durationSinceLastActiveSession.toSeconds();
- write(
+ writeStateChanged(
mSessionIdGenerator.createAndGetNewSessionId(),
MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_INITIATED,
hostUid,
@@ -102,13 +118,13 @@ public class MediaProjectionMetricsLogger {
/**
* Logs that the user entered the setup flow and permission dialog is displayed. This state is
- * not sent when the permission is already granted and we skipped showing the permission dialog.
+ * not sent when the permission is already granted, and we skipped showing the permission dialog.
*
* @param hostUid UID of the package that initiates MediaProjection.
*/
public void logPermissionRequestDisplayed(int hostUid) {
Log.d(TAG, "logPermissionRequestDisplayed");
- write(
+ writeStateChanged(
mSessionIdGenerator.getCurrentSessionId(),
MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_PERMISSION_REQUEST_DISPLAYED,
hostUid,
@@ -123,7 +139,7 @@ public class MediaProjectionMetricsLogger {
* @param hostUid UID of the package that initiates MediaProjection.
*/
public void logProjectionPermissionRequestCancelled(int hostUid) {
- write(
+ writeStateChanged(
mSessionIdGenerator.getCurrentSessionId(),
FrameworkStatsLog
.MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_CANCELLED,
@@ -141,7 +157,7 @@ public class MediaProjectionMetricsLogger {
*/
public void logAppSelectorDisplayed(int hostUid) {
Log.d(TAG, "logAppSelectorDisplayed");
- write(
+ writeStateChanged(
mSessionIdGenerator.getCurrentSessionId(),
MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_APP_SELECTOR_DISPLAYED,
hostUid,
@@ -158,7 +174,7 @@ public class MediaProjectionMetricsLogger {
*/
public void logInProgress(int hostUid, int targetUid) {
Log.d(TAG, "logInProgress");
- write(
+ writeStateChanged(
mSessionIdGenerator.getCurrentSessionId(),
MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_CAPTURING_IN_PROGRESS,
hostUid,
@@ -168,6 +184,54 @@ public class MediaProjectionMetricsLogger {
}
/**
+ * Logs that the windowing mode of a projection has changed.
+ *
+ * @param contentToRecord ContentRecordingSession.RecordContent indicating whether it is a
+ * task capture or display capture - gets converted to the corresponding
+ * TargetType before being logged.
+ * @param hostUid UID of the package that initiates MediaProjection.
+ * @param targetUid UID of the package that is captured if selected.
+ * @param windowingMode Updated WindowConfiguration.WindowingMode of the captured region - gets
+ * converted to the corresponding TargetWindowingMode before being logged.
+ */
+ public void logChangedWindowingMode(
+ int contentToRecord, int hostUid, int targetUid, int windowingMode) {
+ Log.d(TAG, "logChangedWindowingMode");
+ writeTargetChanged(
+ mSessionIdGenerator.getCurrentSessionId(),
+ contentToRecordToTargetType(contentToRecord),
+ hostUid,
+ targetUid,
+ windowingModeToTargetWindowingMode(windowingMode));
+
+ }
+
+ @VisibleForTesting
+ public int contentToRecordToTargetType(@RecordContent int recordContentType) {
+ return switch (recordContentType) {
+ case RECORD_CONTENT_DISPLAY ->
+ MEDIA_PROJECTION_TARGET_CHANGED__TARGET_TYPE__TARGET_TYPE_DISPLAY;
+ case RECORD_CONTENT_TASK ->
+ MEDIA_PROJECTION_TARGET_CHANGED__TARGET_TYPE__TARGET_TYPE_APP_TASK;
+ default -> MEDIA_PROJECTION_TARGET_CHANGED__TARGET_TYPE__TARGET_TYPE_UNKNOWN;
+ };
+ }
+
+ @VisibleForTesting
+ public int windowingModeToTargetWindowingMode(@WindowingMode int windowingMode) {
+ return switch (windowingMode) {
+ case WINDOWING_MODE_FULLSCREEN ->
+ MEDIA_PROJECTION_TARGET_CHANGED__TARGET_WINDOWING_MODE__WINDOWING_MODE_FULLSCREEN;
+ case WINDOWING_MODE_FREEFORM ->
+ MEDIA_PROJECTION_TARGET_CHANGED__TARGET_WINDOWING_MODE__WINDOWING_MODE_FREEFORM;
+ case WINDOWING_MODE_MULTI_WINDOW ->
+ MEDIA_PROJECTION_TARGET_CHANGED__TARGET_WINDOWING_MODE__WINDOWING_MODE_SPLIT_SCREEN;
+ default ->
+ MEDIA_PROJECTION_TARGET_CHANGED__TARGET_WINDOWING_MODE__WINDOWING_MODE_UNKNOWN;
+ };
+ }
+
+ /**
* Logs that the capturing stopped, either normally or because of error.
*
* @param hostUid UID of the package that initiates MediaProjection.
@@ -178,7 +242,7 @@ public class MediaProjectionMetricsLogger {
mPreviousState
== MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_CAPTURING_IN_PROGRESS;
Log.d(TAG, "logStopped: wasCaptureInProgress=" + wasCaptureInProgress);
- write(
+ writeStateChanged(
mSessionIdGenerator.getCurrentSessionId(),
MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_STOPPED,
hostUid,
@@ -191,14 +255,31 @@ public class MediaProjectionMetricsLogger {
}
}
- private void write(
+ public void notifyProjectionStateChange(int hostUid, int state, int sessionCreationSource) {
+ writeStateChanged(hostUid, state, sessionCreationSource);
+ }
+
+ private void writeStateChanged(int hostUid, int state, int sessionCreationSource) {
+ mFrameworkStatsLogWrapper.writeStateChanged(
+ /* code */ FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED,
+ /* session_id */ 123,
+ /* state */ state,
+ /* previous_state */ FrameworkStatsLog
+ .MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_UNKNOWN,
+ /* host_uid */ hostUid,
+ /* target_uid */ -1,
+ /* time_since_last_active */ 0,
+ /* creation_source */ sessionCreationSource);
+ }
+
+ private void writeStateChanged(
int sessionId,
int state,
int hostUid,
int targetUid,
int timeSinceLastActive,
int creationSource) {
- mFrameworkStatsLogWrapper.write(
+ mFrameworkStatsLogWrapper.writeStateChanged(
/* code */ FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED,
sessionId,
state,
@@ -209,4 +290,19 @@ public class MediaProjectionMetricsLogger {
creationSource);
mPreviousState = state;
}
+
+ private void writeTargetChanged(
+ int sessionId,
+ int targetType,
+ int hostUid,
+ int targetUid,
+ int targetWindowingMode) {
+ mFrameworkStatsLogWrapper.writeTargetChanged(
+ /* code */ FrameworkStatsLog.MEDIA_PROJECTION_TARGET_CHANGED,
+ sessionId,
+ targetType,
+ hostUid,
+ targetUid,
+ targetWindowingMode);
+ }
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 4b5d52f0a8de..b2f00a246c23 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -291,6 +291,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.compat.IPlatformCompat;
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
import com.android.internal.config.sysui.SystemUiSystemPropertiesFlags;
+import com.android.internal.config.sysui.SystemUiSystemPropertiesFlags.NotificationFlags;
import com.android.internal.logging.InstanceId;
import com.android.internal.logging.InstanceIdSequence;
import com.android.internal.logging.MetricsLogger;
@@ -2909,7 +2910,16 @@ public class NotificationManagerService extends SystemService {
mPreferencesHelper.updateFixedImportance(mUm.getUsers());
mPreferencesHelper.migrateNotificationPermissions(mUm.getUsers());
} else if (phase == SystemService.PHASE_BOOT_COMPLETED) {
- if (expireBitmaps()) {
+ if (mFlagResolver.isEnabled(NotificationFlags.DEBUG_SHORT_BITMAP_DURATION)) {
+ new Thread(() -> {
+ while (true) {
+ try {
+ Thread.sleep(5000);
+ } catch (InterruptedException e) { }
+ mInternalService.removeBitmaps();
+ }
+ }).start();
+ } else if (expireBitmaps()) {
NotificationBitmapJobService.scheduleJob(getContext());
}
}
@@ -6765,7 +6775,14 @@ public class NotificationManagerService extends SystemService {
final long timePostedMs = r.getSbn().getPostTime();
final long timeNowMs = System.currentTimeMillis();
- if (isBitmapExpired(timePostedMs, timeNowMs, BITMAP_DURATION.toMillis())) {
+ final long bitmapDuration;
+ if (mFlagResolver.isEnabled(NotificationFlags.DEBUG_SHORT_BITMAP_DURATION)) {
+ bitmapDuration = Duration.ofSeconds(5).toMillis();
+ } else {
+ bitmapDuration = BITMAP_DURATION.toMillis();
+ }
+
+ if (isBitmapExpired(timePostedMs, timeNowMs, bitmapDuration)) {
removeBitmapAndRepost(r);
}
}
diff --git a/services/core/java/com/android/server/notification/flags.aconfig b/services/core/java/com/android/server/notification/flags.aconfig
index 66a76cc7fa70..25b7ca146ff1 100644
--- a/services/core/java/com/android/server/notification/flags.aconfig
+++ b/services/core/java/com/android/server/notification/flags.aconfig
@@ -7,12 +7,7 @@ flag {
bug: "290381858"
}
-flag {
- name: "modes_api"
- namespace: "systemui"
- description: "This flag controls new and updated DND apis"
- bug: "300477976"
-}
+
flag {
name: "polite_notifications"
diff --git a/services/core/java/com/android/server/pm/PackageArchiver.java b/services/core/java/com/android/server/pm/PackageArchiver.java
index 42a97f7e05b4..5cd62872e07b 100644
--- a/services/core/java/com/android/server/pm/PackageArchiver.java
+++ b/services/core/java/com/android/server/pm/PackageArchiver.java
@@ -17,8 +17,8 @@
package com.android.server.pm;
import static android.app.ComponentOptions.MODE_BACKGROUND_ACTIVITY_START_DENIED;
-import static android.content.pm.ArchivedActivity.bytesFromBitmap;
-import static android.content.pm.ArchivedActivity.drawableToBitmap;
+import static android.content.pm.ArchivedActivityInfo.bytesFromBitmap;
+import static android.content.pm.ArchivedActivityInfo.drawableToBitmap;
import static android.content.pm.PackageManager.DELETE_ARCHIVE;
import static android.content.pm.PackageManager.DELETE_KEEP_DATA;
import static android.os.PowerExemptionManager.REASON_PACKAGE_UNARCHIVE;
@@ -46,6 +46,12 @@ import android.content.pm.ResolveInfo;
import android.content.pm.VersionedPackage;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
+import android.graphics.Color;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffColorFilter;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.LayerDrawable;
import android.os.Binder;
import android.os.Bundle;
import android.os.Environment;
@@ -56,6 +62,7 @@ import android.os.UserHandle;
import android.text.TextUtils;
import android.util.Slog;
+import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.pm.pkg.ArchiveState;
@@ -367,7 +374,7 @@ public class PackageArchiver {
// TODO(b/298452477) Handle monochrome icons.
// In the rare case the archived app defined more than two launcher activities, we choose
// the first one arbitrarily.
- return decodeIcon(activityInfos.get(0));
+ return includeCloudOverlay(decodeIcon(activityInfos.get(0)));
}
@VisibleForTesting
@@ -375,6 +382,34 @@ public class PackageArchiver {
return BitmapFactory.decodeFile(archiveActivityInfo.getIconBitmap().toString());
}
+ Bitmap includeCloudOverlay(Bitmap bitmap) {
+ Drawable cloudDrawable =
+ mContext.getResources()
+ .getDrawable(R.drawable.archived_app_cloud_overlay, mContext.getTheme());
+ if (cloudDrawable == null) {
+ Slog.e(TAG, "Unable to locate cloud overlay for archived app!");
+ return bitmap;
+ }
+ BitmapDrawable appIconDrawable = new BitmapDrawable(mContext.getResources(), bitmap);
+ PorterDuffColorFilter colorFilter =
+ new PorterDuffColorFilter(
+ Color.argb(0.32f /* alpha */, 0f /* red */, 0f /* green */, 0f /* blue */),
+ PorterDuff.Mode.SRC_ATOP);
+ appIconDrawable.setColorFilter(colorFilter);
+ appIconDrawable.setBounds(
+ 0 /* left */,
+ 0 /* top */,
+ cloudDrawable.getIntrinsicWidth(),
+ cloudDrawable.getIntrinsicHeight());
+ LayerDrawable layerDrawable =
+ new LayerDrawable(new Drawable[] {appIconDrawable, cloudDrawable});
+ final int iconSize = mContext.getSystemService(
+ ActivityManager.class).getLauncherLargeIconSize();
+ Bitmap appIconWithCloudOverlay = drawableToBitmap(layerDrawable, iconSize);
+ bitmap.recycle();
+ return appIconWithCloudOverlay;
+ }
+
private void verifyArchived(PackageStateInternal ps, int userId)
throws PackageManager.NameNotFoundException {
PackageUserStateInternal userState = ps.getUserStateOrDefault(userId);
diff --git a/services/core/java/com/android/server/policy/AppOpsPolicy.java b/services/core/java/com/android/server/policy/AppOpsPolicy.java
index b83421fe78d7..c2821aef2142 100644
--- a/services/core/java/com/android/server/policy/AppOpsPolicy.java
+++ b/services/core/java/com/android/server/policy/AppOpsPolicy.java
@@ -50,11 +50,12 @@ import android.util.Log;
import android.util.SparseArray;
import com.android.internal.annotations.GuardedBy;
-import com.android.internal.util.function.HeptFunction;
import com.android.internal.util.function.HexFunction;
+import com.android.internal.util.function.NonaFunction;
import com.android.internal.util.function.QuadFunction;
-import com.android.internal.util.function.QuintConsumer;
import com.android.internal.util.function.QuintFunction;
+import com.android.internal.util.function.TriConsumer;
+import com.android.internal.util.function.TriFunction;
import com.android.internal.util.function.UndecFunction;
import com.android.server.LocalServices;
@@ -229,10 +230,12 @@ public final class AppOpsPolicy implements AppOpsManagerInternal.CheckOpsDelegat
}
@Override
- public int checkOperation(int code, int uid, String packageName,
- @Nullable String attributionTag, boolean raw,
- QuintFunction<Integer, Integer, String, String, Boolean, Integer> superImpl) {
- return superImpl.apply(code, resolveUid(code, uid), packageName, attributionTag, raw);
+ public int checkOperation(int code, AttributionSource attributionSource, boolean raw,
+ TriFunction<Integer, AttributionSource, Boolean, Integer> superImpl) {
+ final int uid = attributionSource.getUid();
+ final AttributionSource resolvedAttributionSource =
+ attributionSource.withUid(resolveUid(code, uid));
+ return superImpl.apply(code, resolvedAttributionSource, raw);
}
@Override
@@ -242,21 +245,25 @@ public final class AppOpsPolicy implements AppOpsManagerInternal.CheckOpsDelegat
}
@Override
- public SyncNotedAppOp noteOperation(int code, int uid, @Nullable String packageName,
- @Nullable String attributionTag, boolean shouldCollectAsyncNotedOp, @Nullable
- String message, boolean shouldCollectMessage, @NonNull HeptFunction<Integer, Integer,
- String, String, Boolean, String, Boolean, SyncNotedAppOp> superImpl) {
- return superImpl.apply(resolveDatasourceOp(code, uid, packageName, attributionTag),
- resolveUid(code, uid), packageName, attributionTag, shouldCollectAsyncNotedOp,
- message, shouldCollectMessage);
+ public SyncNotedAppOp noteOperation(int code, AttributionSource attributionSource,
+ boolean shouldCollectAsyncNotedOp, @Nullable
+ String message, boolean shouldCollectMessage,
+ @NonNull QuintFunction<Integer, AttributionSource, Boolean, String, Boolean,
+ SyncNotedAppOp> superImpl) {
+ final int uid = attributionSource.getUid();
+ final AttributionSource resolvedAttributionSource =
+ attributionSource.withUid(resolveUid(code, uid));
+ return superImpl.apply(resolveDatasourceOp(code, uid, attributionSource.getPackageName(),
+ attributionSource.getAttributionTag()), resolvedAttributionSource,
+ shouldCollectAsyncNotedOp, message, shouldCollectMessage);
}
@Override
public SyncNotedAppOp noteProxyOperation(int code, @NonNull AttributionSource attributionSource,
boolean shouldCollectAsyncNotedOp, @Nullable String message,
boolean shouldCollectMessage, boolean skipProxyOperation, @NonNull HexFunction<Integer,
- AttributionSource, Boolean, String, Boolean, Boolean,
- SyncNotedAppOp> superImpl) {
+ AttributionSource, Boolean, String, Boolean, Boolean,
+ SyncNotedAppOp> superImpl) {
return superImpl.apply(resolveDatasourceOp(code, attributionSource.getUid(),
attributionSource.getPackageName(), attributionSource.getAttributionTag()),
attributionSource, shouldCollectAsyncNotedOp, message, shouldCollectMessage,
@@ -264,17 +271,21 @@ public final class AppOpsPolicy implements AppOpsManagerInternal.CheckOpsDelegat
}
@Override
- public SyncNotedAppOp startOperation(IBinder token, int code, int uid,
- @Nullable String packageName, @Nullable String attributionTag,
+ public SyncNotedAppOp startOperation(IBinder token, int code,
+ AttributionSource attributionSource,
boolean startIfModeDefault, boolean shouldCollectAsyncNotedOp, String message,
boolean shouldCollectMessage, @AttributionFlags int attributionFlags,
- int attributionChainId, @NonNull UndecFunction<IBinder, Integer, Integer, String,
- String, Boolean, Boolean, String, Boolean, Integer, Integer,
- SyncNotedAppOp> superImpl) {
- return superImpl.apply(token, resolveDatasourceOp(code, uid, packageName, attributionTag),
- resolveUid(code, uid), packageName, attributionTag, startIfModeDefault,
- shouldCollectAsyncNotedOp, message, shouldCollectMessage, attributionFlags,
- attributionChainId);
+ int attributionChainId,
+ @NonNull NonaFunction<IBinder, Integer, AttributionSource, Boolean, Boolean, String,
+ Boolean, Integer, Integer,
+ SyncNotedAppOp> superImpl) {
+ final int uid = attributionSource.getUid();
+ final AttributionSource resolvedAttributionSource =
+ attributionSource.withUid(resolveUid(code, uid));
+ return superImpl.apply(token, resolveDatasourceOp(code, uid,
+ attributionSource.getPackageName(), attributionSource.getAttributionTag()),
+ resolvedAttributionSource, startIfModeDefault, shouldCollectAsyncNotedOp, message,
+ shouldCollectMessage, attributionFlags, attributionChainId);
}
@Override
@@ -293,11 +304,14 @@ public final class AppOpsPolicy implements AppOpsManagerInternal.CheckOpsDelegat
}
@Override
- public void finishOperation(IBinder clientId, int code, int uid, String packageName,
- String attributionTag,
- @NonNull QuintConsumer<IBinder, Integer, Integer, String, String> superImpl) {
- superImpl.accept(clientId, resolveDatasourceOp(code, uid, packageName, attributionTag),
- resolveUid(code, uid), packageName, attributionTag);
+ public void finishOperation(IBinder clientId, int code, AttributionSource attributionSource,
+ @NonNull TriConsumer<IBinder, Integer, AttributionSource> superImpl) {
+ final int uid = attributionSource.getUid();
+ final AttributionSource resolvedAttributionSource =
+ attributionSource.withUid(resolveUid(code, uid));
+ superImpl.accept(clientId, resolveDatasourceOp(code, uid,
+ attributionSource.getPackageName(), attributionSource.getAttributionTag()),
+ resolvedAttributionSource);
}
@Override
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 077812b49cdd..45ca690ba20f 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -19,6 +19,7 @@ package com.android.server.policy;
import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
import static android.Manifest.permission.SYSTEM_ALERT_WINDOW;
import static android.Manifest.permission.SYSTEM_APPLICATION_OVERLAY;
+import static android.app.AppOpsManager.OP_CREATE_ACCESSIBILITY_OVERLAY;
import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW;
import static android.app.AppOpsManager.OP_TOAST_WINDOW;
import static android.content.pm.PackageManager.FEATURE_AUTOMOTIVE;
@@ -31,6 +32,7 @@ import static android.os.Build.VERSION_CODES.M;
import static android.os.Build.VERSION_CODES.O;
import static android.os.IInputConstants.INVALID_INPUT_DEVICE_ID;
import static android.provider.Settings.Secure.VOLUME_HUSH_OFF;
+import static android.view.contentprotection.flags.Flags.createAccessibilityOverlayAppOpEnabled;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
import static android.view.Display.STATE_OFF;
@@ -2992,12 +2994,16 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// Window manager does the checking for this.
outAppOp[0] = OP_TOAST_WINDOW;
return ADD_OKAY;
+ case TYPE_ACCESSIBILITY_OVERLAY:
+ if (createAccessibilityOverlayAppOpEnabled()) {
+ outAppOp[0] = OP_CREATE_ACCESSIBILITY_OVERLAY;
+ return ADD_OKAY;
+ }
case TYPE_INPUT_METHOD:
case TYPE_WALLPAPER:
case TYPE_PRESENTATION:
case TYPE_PRIVATE_PRESENTATION:
case TYPE_VOICE_INTERACTION:
- case TYPE_ACCESSIBILITY_OVERLAY:
case TYPE_QS_DIALOG:
case TYPE_NAVIGATION_BAR_PANEL:
// The window manager will check these.
diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java
index b12ecc333d1f..e4c7fc1f3797 100644
--- a/services/core/java/com/android/server/tv/TvInputManagerService.java
+++ b/services/core/java/com/android/server/tv/TvInputManagerService.java
@@ -1166,7 +1166,11 @@ public final class TvInputManagerService extends SystemService {
.EXTERNAL_TV_INPUT_EVENT__EVENT_TYPE__CONNECTION_STATE_CHANGED,
mOnScreenInputId, mOnScreenSessionState);
} else if (mOnScreenInputId != null) {
- TvInputInfo currentInputInfo = userState.inputMap.get(mOnScreenInputId).info;
+ TvInputState currentInputState = userState.inputMap.get(mOnScreenInputId);
+ TvInputInfo currentInputInfo = null;
+ if (currentInputState != null) {
+ currentInputInfo = currentInputState.info;
+ }
if (currentInputInfo != null && currentInputInfo.getHdmiDeviceInfo() != null
&& inputId.equals(currentInputInfo.getParentId())) {
logExternalInputEvent(
diff --git a/services/core/java/com/android/server/wm/ContentRecorder.java b/services/core/java/com/android/server/wm/ContentRecorder.java
index 022ef6152929..8717098ff8e8 100644
--- a/services/core/java/com/android/server/wm/ContentRecorder.java
+++ b/services/core/java/com/android/server/wm/ContentRecorder.java
@@ -16,6 +16,7 @@
package com.android.server.wm;
+import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.content.Context.MEDIA_PROJECTION_SERVICE;
import static android.content.res.Configuration.ORIENTATION_UNDEFINED;
import static android.view.ContentRecordingSession.RECORD_CONTENT_DISPLAY;
@@ -100,6 +101,8 @@ final class ContentRecorder implements WindowContainerListener {
@Configuration.Orientation
private int mLastOrientation = ORIENTATION_UNDEFINED;
+ private int mLastWindowingMode = WINDOWING_MODE_UNDEFINED;
+
private final boolean mCorrectForAnisotropicPixels;
ContentRecorder(@NonNull DisplayContent displayContent) {
@@ -156,7 +159,8 @@ final class ContentRecorder implements WindowContainerListener {
* Handle a configuration change on the display content, and resize recording if needed.
* @param lastOrientation the prior orientation of the configuration
*/
- void onConfigurationChanged(@Configuration.Orientation int lastOrientation) {
+ void onConfigurationChanged(
+ @Configuration.Orientation int lastOrientation, int lastWindowingMode) {
// Update surface for MediaProjection, if this DisplayContent is being used for recording.
if (!isCurrentlyRecording() || mLastRecordedBounds == null) {
return;
@@ -185,6 +189,16 @@ final class ContentRecorder implements WindowContainerListener {
}
}
+ // Record updated windowing mode, if necessary.
+ int recordedContentWindowingMode = mRecordedWindowContainer.getWindowingMode();
+ if (lastWindowingMode != recordedContentWindowingMode) {
+ mMediaProjectionManager.notifyWindowingModeChanged(
+ mContentRecordingSession.getContentToRecord(),
+ mContentRecordingSession.getTargetUid(),
+ recordedContentWindowingMode
+ );
+ }
+
ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
"Content Recording: Display %d was already recording, so apply "
+ "transformations if necessary",
@@ -327,8 +341,10 @@ final class ContentRecorder implements WindowContainerListener {
return;
}
+ final int contentToRecord = mContentRecordingSession.getContentToRecord();
+
// TODO(b/297514518) Do not start capture if the app is in PIP, the bounds are inaccurate.
- if (mContentRecordingSession.getContentToRecord() == RECORD_CONTENT_TASK) {
+ if (contentToRecord == RECORD_CONTENT_TASK) {
if (mRecordedWindowContainer.asTask().inPinnedWindowingMode()) {
ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
"Content Recording: Display %d should start recording, but "
@@ -375,7 +391,7 @@ final class ContentRecorder implements WindowContainerListener {
// Notify the client about the visibility of the mirrored region, now that we have begun
// capture.
- if (mContentRecordingSession.getContentToRecord() == RECORD_CONTENT_TASK) {
+ if (contentToRecord == RECORD_CONTENT_TASK) {
mMediaProjectionManager.notifyActiveProjectionCapturedContentVisibilityChanged(
mRecordedWindowContainer.asTask().isVisibleRequested());
} else {
@@ -385,6 +401,11 @@ final class ContentRecorder implements WindowContainerListener {
currentDisplayState != DISPLAY_STATE_OFF);
}
+ // Record initial windowing mode after recording starts.
+ mMediaProjectionManager.notifyWindowingModeChanged(
+ contentToRecord, mContentRecordingSession.getTargetUid(),
+ mRecordedWindowContainer.getWindowConfiguration().getWindowingMode());
+
// No need to clean up. In SurfaceFlinger, parents hold references to their children. The
// mirrored SurfaceControl is alive since the parent DisplayContent SurfaceControl is
// holding a reference to it. Therefore, the mirrored SurfaceControl will be cleaned up
@@ -617,8 +638,9 @@ final class ContentRecorder implements WindowContainerListener {
Configuration mergedOverrideConfiguration) {
WindowContainerListener.super.onMergedOverrideConfigurationChanged(
mergedOverrideConfiguration);
- onConfigurationChanged(mLastOrientation);
+ onConfigurationChanged(mLastOrientation, mLastWindowingMode);
mLastOrientation = mergedOverrideConfiguration.orientation;
+ mLastWindowingMode = mergedOverrideConfiguration.windowConfiguration.getWindowingMode();
}
// WindowContainerListener
@@ -635,6 +657,7 @@ final class ContentRecorder implements WindowContainerListener {
void stopActiveProjection();
void notifyActiveProjectionCapturedContentResized(int width, int height);
void notifyActiveProjectionCapturedContentVisibilityChanged(boolean isVisible);
+ void notifyWindowingModeChanged(int contentToRecord, int targetUid, int windowingMode);
}
private static final class RemoteMediaProjectionManagerWrapper implements
@@ -700,6 +723,22 @@ final class ContentRecorder implements WindowContainerListener {
}
}
+ @Override
+ public void notifyWindowingModeChanged(int contentToRecord, int targetUid,
+ int windowingMode) {
+ fetchMediaProjectionManager();
+ if (mIMediaProjectionManager == null) {
+ return;
+ }
+ try {
+ mIMediaProjectionManager.notifyWindowingModeChanged(
+ contentToRecord, targetUid, windowingMode);
+ } catch (RemoteException e) {
+ ProtoLog.e(WM_DEBUG_CONTENT_RECORDING,
+ "Content Recording: Unable to tell log windowing mode change: %s", e);
+ }
+ }
+
private void fetchMediaProjectionManager() {
if (mIMediaProjectionManager != null) {
return;
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 576e8a48ab31..c716879a5097 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -2757,6 +2757,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
@Override
public void onConfigurationChanged(Configuration newParentConfig) {
final int lastOrientation = getConfiguration().orientation;
+ final int lastWindowingMode = getWindowingMode();
super.onConfigurationChanged(newParentConfig);
if (mDisplayPolicy != null) {
mDisplayPolicy.onConfigurationChanged();
@@ -2768,7 +2769,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
// Update surface for MediaProjection, if this DisplayContent is being used for recording.
if (mContentRecorder != null) {
- mContentRecorder.onConfigurationChanged(lastOrientation);
+ mContentRecorder.onConfigurationChanged(lastOrientation, lastWindowingMode);
}
if (lastOrientation != getConfiguration().orientation) {
diff --git a/services/core/java/com/android/server/wm/OWNERS b/services/core/java/com/android/server/wm/OWNERS
index f8c39d0906a0..cd704478aa83 100644
--- a/services/core/java/com/android/server/wm/OWNERS
+++ b/services/core/java/com/android/server/wm/OWNERS
@@ -18,5 +18,8 @@ rgl@google.com
yunfanc@google.com
wilsonshih@google.com
-per-file BackgroundActivityStartController.java = set noparent
-per-file BackgroundActivityStartController.java = brufino@google.com, topjohnwu@google.com, achim@google.com, ogunwale@google.com, louischang@google.com, lus@google.com
+# Files related to background activity launches
+per-file Background*Start* = set noparent
+per-file Background*Start* = file:/BAL_OWNERS
+per-file Background*Start* = ogunwale@google.com, louischang@google.com
+
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index 3775ccd79d4c..a756847d59ea 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -86,6 +86,7 @@ import com.android.internal.os.logging.MetricsLoggerWrapper;
import com.android.internal.protolog.common.ProtoLog;
import com.android.server.LocalServices;
import com.android.server.wm.WindowManagerService.H;
+import com.android.window.flags.Flags;
import java.io.PrintWriter;
import java.util.Collections;
@@ -166,8 +167,8 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
mCanSetUnrestrictedGestureExclusion =
service.mContext.checkCallingOrSelfPermission(SET_UNRESTRICTED_GESTURE_EXCLUSION)
== PERMISSION_GRANTED;
- mCanAlwaysUpdateWallpaper =
- service.mContext.checkCallingOrSelfPermission(ALWAYS_UPDATE_WALLPAPER)
+ mCanAlwaysUpdateWallpaper = Flags.alwaysUpdateWallpaperPermission()
+ && service.mContext.checkCallingOrSelfPermission(ALWAYS_UPDATE_WALLPAPER)
== PERMISSION_GRANTED;
mShowingAlertWindowNotificationAllowed = mService.mShowAlertWindowNotifications;
mDragDropController = mService.mDragDropController;
diff --git a/services/core/java/com/android/server/wm/SynchedDeviceConfig.java b/services/core/java/com/android/server/wm/SynchedDeviceConfig.java
index c2e819e4c60b..4d4f99f5b68e 100644
--- a/services/core/java/com/android/server/wm/SynchedDeviceConfig.java
+++ b/services/core/java/com/android/server/wm/SynchedDeviceConfig.java
@@ -20,7 +20,6 @@ import android.annotation.NonNull;
import android.provider.DeviceConfig;
import java.util.Map;
-import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;
@@ -98,27 +97,28 @@ final class SynchedDeviceConfig implements DeviceConfig.OnPropertiesChangedListe
* @throws IllegalArgumentException {@code key} isn't recognised.
*/
boolean getFlagValue(@NonNull String key) {
- return findEntry(key).map(SynchedDeviceConfigEntry::getValue)
- .orElseThrow(() -> new IllegalArgumentException("Unexpected flag name: " + key));
+ final SynchedDeviceConfigEntry entry = mDeviceConfigEntries.get(key);
+ if (entry == null) {
+ throw new IllegalArgumentException("Unexpected flag name: " + key);
+ }
+ return entry.getValue();
}
/**
* @return {@code true} if the flag for the given {@code key} was enabled at build time.
*/
boolean isBuildTimeFlagEnabled(@NonNull String key) {
- return findEntry(key).map(SynchedDeviceConfigEntry::isBuildTimeFlagEnabled)
- .orElseThrow(() -> new IllegalArgumentException("Unexpected flag name: " + key));
+ final SynchedDeviceConfigEntry entry = mDeviceConfigEntries.get(key);
+ if (entry == null) {
+ throw new IllegalArgumentException("Unexpected flag name: " + key);
+ }
+ return entry.isBuildTimeFlagEnabled();
}
private boolean isDeviceConfigFlagEnabled(@NonNull String key, boolean defaultValue) {
return DeviceConfig.getBoolean(mNamespace, key, defaultValue);
}
- @NonNull
- private Optional<SynchedDeviceConfigEntry> findEntry(@NonNull String key) {
- return Optional.ofNullable(mDeviceConfigEntries.get(key));
- }
-
static class SynchedDeviceConfigBuilder {
private final String mNamespace;
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 6cad16c7db40..5c5a1e1d23dc 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -6541,11 +6541,11 @@ class Task extends TaskFragment {
mActivityType = ACTIVITY_TYPE_STANDARD;
}
- if (mActivityType != ACTIVITY_TYPE_STANDARD
+ if (!DisplayContent.alwaysCreateRootTask(tda.getWindowingMode(), mActivityType)
&& mActivityType != ACTIVITY_TYPE_UNDEFINED) {
- // For now there can be only one root task of a particular non-standard activity
- // type on a display. So, get that ignoring whatever windowing mode it is
- // currently in.
+ // Only Recents or Standard activity types are allowed to have more than one
+ // root task on a display, this is independent of whatever windowing mode it
+ // is currently in.
Task rootTask = tda.getRootTask(WINDOWING_MODE_UNDEFINED, mActivityType);
if (rootTask != null) {
throw new IllegalArgumentException("Root task=" + rootTask + " of activityType="
diff --git a/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java b/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
index 34ae370a6099..e7a1cf106a44 100644
--- a/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
@@ -49,6 +49,7 @@ import android.view.RemoteAnimationDefinition;
import android.view.WindowManager;
import android.window.ITaskFragmentOrganizer;
import android.window.ITaskFragmentOrganizerController;
+import android.window.RemoteTransition;
import android.window.TaskFragmentInfo;
import android.window.TaskFragmentOperation;
import android.window.TaskFragmentParentInfo;
@@ -566,7 +567,8 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
// Keep the calling identity to avoid unsecure change.
synchronized (mGlobalLock) {
if (isValidTransaction(wct)) {
- applyTransaction(wct, transitionType, shouldApplyIndependently);
+ applyTransaction(
+ wct, transitionType, shouldApplyIndependently, null /* remoteTransition */);
}
// Even if the transaction is empty, we still need to invoke #onTransactionFinished
// unless the organizer has been unregistered.
@@ -587,14 +589,15 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
@Override
public void applyTransaction(@NonNull WindowContainerTransaction wct,
- @WindowManager.TransitionType int transitionType, boolean shouldApplyIndependently) {
+ @WindowManager.TransitionType int transitionType, boolean shouldApplyIndependently,
+ @Nullable RemoteTransition remoteTransition) {
// Keep the calling identity to avoid unsecure change.
synchronized (mGlobalLock) {
if (!isValidTransaction(wct)) {
return;
}
mWindowOrganizerController.applyTaskFragmentTransactionLocked(wct, transitionType,
- shouldApplyIndependently);
+ shouldApplyIndependently, remoteTransition);
}
}
@@ -839,6 +842,7 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
Slog.e(TAG, "Caller organizer=" + organizer + " is no longer registered");
return false;
}
+
return true;
}
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index a8b9417edb9b..3497353a9849 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -103,6 +103,7 @@ import android.window.ITransitionMetricsReporter;
import android.window.ITransitionPlayer;
import android.window.IWindowContainerTransactionCallback;
import android.window.IWindowOrganizerController;
+import android.window.RemoteTransition;
import android.window.TaskFragmentAnimationParams;
import android.window.TaskFragmentCreationParams;
import android.window.TaskFragmentOperation;
@@ -464,12 +465,20 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
* transition, which will be queued until the sync engine is
* free if there is any other active sync. If {@code false},
* the {@code wct} will be directly applied to the active sync.
+ * @param remoteTransition {@link RemoteTransition} to apply for the transaction. Only available
+ * for system organizers.
*/
void applyTaskFragmentTransactionLocked(@NonNull WindowContainerTransaction wct,
- @WindowManager.TransitionType int type, boolean shouldApplyIndependently) {
+ @WindowManager.TransitionType int type, boolean shouldApplyIndependently,
+ @Nullable RemoteTransition remoteTransition) {
enforceTaskFragmentOrganizerPermission("applyTaskFragmentTransaction()",
Objects.requireNonNull(wct.getTaskFragmentOrganizer()),
Objects.requireNonNull(wct));
+ if (remoteTransition != null && !mTaskFragmentOrganizerController.isSystemOrganizer(
+ wct.getTaskFragmentOrganizer().asBinder())) {
+ throw new SecurityException(
+ "Only a system organizer is allowed to use remote transition!");
+ }
final CallerInfo caller = new CallerInfo();
final long ident = Binder.clearCallingIdentity();
try {
@@ -512,7 +521,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
return;
}
mTransitionController.requestStartTransition(transition, null /* startTask */,
- null /* remoteTransition */, null /* displayChange */);
+ remoteTransition, null /* displayChange */);
transition.setAllReady();
};
mTransitionController.startCollectOrQueue(transition, doApply);
diff --git a/services/credentials/java/com/android/server/credentials/CredentialManagerService.java b/services/credentials/java/com/android/server/credentials/CredentialManagerService.java
index a4adf5866f3d..627461a2c6ed 100644
--- a/services/credentials/java/com/android/server/credentials/CredentialManagerService.java
+++ b/services/credentials/java/com/android/server/credentials/CredentialManagerService.java
@@ -862,37 +862,41 @@ public final class CredentialManagerService
Slog.i(TAG, "isEnabledCredentialProviderService with componentName: "
+ componentName.flattenToString());
- // TODO(253157366): Check additional set of services.
final int userId = UserHandle.getCallingUserId();
final int callingUid = Binder.getCallingUid();
enforceCallingPackage(callingPackage, callingUid);
- synchronized (mLock) {
- final List<CredentialManagerServiceImpl> services =
- getServiceListForUserLocked(userId);
- for (CredentialManagerServiceImpl s : services) {
- final ComponentName serviceComponentName = s.getServiceComponentName();
-
- if (serviceComponentName.equals(componentName)) {
- if (!s.getServicePackageName().equals(callingPackage)) {
- // The component name and the package name do not match.
- MetricUtilities.logApiCalledSimpleV2(
- ApiName.IS_ENABLED_CREDENTIAL_PROVIDER_SERVICE,
- ApiStatus.FAILURE, callingUid);
- Slog.w(
- TAG,
- "isEnabledCredentialProviderService: Component name does "
- + "not match package name.");
- return false;
- }
- MetricUtilities.logApiCalledSimpleV2(
- ApiName.IS_ENABLED_CREDENTIAL_PROVIDER_SERVICE,
- ApiStatus.SUCCESS, callingUid);
- return true;
- }
- }
+
+ if (componentName == null) {
+ Slog.w(TAG, "isEnabledCredentialProviderService componentName is null");
+ // If the component name was not specified then throw an error and
+ // record a failure because the request failed due to invalid input.
+ MetricUtilities.logApiCalledSimpleV2(
+ ApiName.IS_ENABLED_CREDENTIAL_PROVIDER_SERVICE,
+ ApiStatus.FAILURE, callingUid);
+ return false;
+ }
+
+ if (!componentName.getPackageName().equals(callingPackage)) {
+ Slog.w(TAG, "isEnabledCredentialProviderService component name"
+ + " does not match requested component");
+ // If the requested component name package name does not match
+ // the calling package then throw an error and record a failure
+ // metric (because the request failed due to invalid input).
+ MetricUtilities.logApiCalledSimpleV2(
+ ApiName.IS_ENABLED_CREDENTIAL_PROVIDER_SERVICE,
+ ApiStatus.FAILURE, callingUid);
+ throw new IllegalArgumentException("provided component name does not match"
+ + " does not match requesting component");
}
- return false;
+ final Set<ComponentName> enabledProviders = getEnabledProvidersForUser(userId);
+ MetricUtilities.logApiCalledSimpleV2(
+ ApiName.IS_ENABLED_CREDENTIAL_PROVIDER_SERVICE,
+ ApiStatus.SUCCESS, callingUid);
+ if (enabledProviders == null) {
+ return false;
+ }
+ return enabledProviders.contains(componentName);
}
@Override
diff --git a/services/proguard.flags b/services/proguard.flags
index e11e613adb5c..261bb7cacdc4 100644
--- a/services/proguard.flags
+++ b/services/proguard.flags
@@ -47,6 +47,11 @@
-keep,allowoptimization,allowaccessmodification class com.android.net.module.util.* { *; }
-keep,allowoptimization,allowaccessmodification public class com.android.server.net.IpConfigStore { *; }
-keep,allowoptimization,allowaccessmodification public class com.android.server.net.BaseNetworkObserver { *; }
+-keep,allowoptimization,allowaccessmodification class com.android.server.display.feature.DisplayManagerFlags { *; }
+-keep,allowoptimization,allowaccessmodification class android.app.admin.flags.FeatureFlagsImpl { *; }
+-keep,allowoptimization,allowaccessmodification class com.android.server.input.NativeInputManagerService$NativeImpl { *; }
+-keep,allowoptimization,allowaccessmodification class com.android.server.ThreadPriorityBooster { *; }
+-keep,allowaccessmodification class android.app.admin.flags.Flags { *; }
# Referenced via CarServiceHelperService in car-frameworks-service (avoid removing)
-keep public class com.android.server.utils.Slogf { *; }
@@ -99,9 +104,6 @@
-keep,allowoptimization,allowaccessmodification class com.android.server.input.InputManagerService {
<methods>;
}
--keep,allowoptimization,allowaccessmodification class com.android.server.input.NativeInputManagerService$NativeImpl {
- <methods>;
-}
-keep,allowoptimization,allowaccessmodification class com.android.server.usb.UsbHostManager {
*** usbDeviceRemoved(...);
*** usbDeviceAdded(...);
diff --git a/services/tests/mockingservicestests/src/com/android/server/AppStateTrackerTest.java b/services/tests/mockingservicestests/src/com/android/server/AppStateTrackerTest.java
index 47ae97fc5d27..7ceccc57c0f1 100644
--- a/services/tests/mockingservicestests/src/com/android/server/AppStateTrackerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/AppStateTrackerTest.java
@@ -44,6 +44,7 @@ import android.app.AppOpsManager.PackageOps;
import android.app.IActivityManager;
import android.app.IUidObserver;
import android.app.usage.UsageStatsManager;
+import android.content.AttributionSourceState;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -229,12 +230,20 @@ public class AppStateTrackerTest {
private AppStateTrackerTestable newInstance() throws Exception {
MockitoAnnotations.initMocks(this);
- when(mMockIAppOpsService.checkOperation(eq(TARGET_OP), anyInt(), anyString()))
- .thenAnswer(inv -> {
- return mRestrictedPackages.indexOf(
- Pair.create(inv.getArgument(1), inv.getArgument(2))) >= 0 ?
- AppOpsManager.MODE_IGNORED : AppOpsManager.MODE_ALLOWED;
- });
+ when(mMockIAppOpsService.checkOperationWithState(eq(TARGET_OP), any()))
+ .thenAnswer(
+ (Answer<Integer>)
+ invocation -> {
+ AttributionSourceState attribution =
+ (AttributionSourceState) invocation.getArguments()[1];
+ return mRestrictedPackages.indexOf(
+ Pair.create(
+ attribution.uid,
+ attribution.packageName))
+ >= 0
+ ? AppOpsManager.MODE_IGNORED
+ : AppOpsManager.MODE_ALLOWED;
+ });
final AppStateTrackerTestable instance = new AppStateTrackerTestable();
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerServiceTest.java
index 40b5458b06b9..3ee8050cda3e 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerServiceTest.java
@@ -69,6 +69,7 @@ import android.app.BroadcastOptions;
import android.app.IApplicationThread;
import android.app.IUidObserver;
import android.app.SyncNotedAppOp;
+import android.content.AttributionSourceState;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -223,12 +224,16 @@ public class ActivityManagerServiceTest {
assertThat(sProcessListSettingsListener).isNotNull();
}
- private void mockNoteOperation() {
+ private void mockNoteOp() {
SyncNotedAppOp allowed = new SyncNotedAppOp(AppOpsManager.MODE_ALLOWED,
AppOpsManager.OP_GET_USAGE_STATS, null, mContext.getPackageName());
- when(mAppOpsService.noteOperation(eq(AppOpsManager.OP_GET_USAGE_STATS), eq(Process.myUid()),
- nullable(String.class), nullable(String.class), any(Boolean.class),
- nullable(String.class), any(Boolean.class))).thenReturn(allowed);
+ when(mAppOpsService.noteOperationWithState(
+ eq(AppOpsManager.OP_GET_USAGE_STATS),
+ any(AttributionSourceState.class),
+ any(Boolean.class),
+ nullable(String.class),
+ any(Boolean.class)))
+ .thenReturn(allowed);
}
@After
@@ -609,7 +614,7 @@ public class ActivityManagerServiceTest {
*/
@Test
public void testDispatchUids_dispatchNeededChanges() throws RemoteException {
- mockNoteOperation();
+ mockNoteOp();
final int[] changesToObserve = {
ActivityManager.UID_OBSERVER_PROCSTATE,
@@ -818,7 +823,7 @@ public class ActivityManagerServiceTest {
*/
@Test
public void testDispatchUidChanges_procStateCutpoint() throws RemoteException {
- mockNoteOperation();
+ mockNoteOp();
final IUidObserver observer = mock(IUidObserver.Stub.class);
@@ -888,7 +893,7 @@ public class ActivityManagerServiceTest {
*/
@Test
public void testDispatchUidChanges_validateUidsUpdated() {
- mockNoteOperation();
+ mockNoteOp();
final int[] changesForPendingItems = UID_RECORD_CHANGES;
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/BackgroundRestrictionTest.java b/services/tests/mockingservicestests/src/com/android/server/am/BackgroundRestrictionTest.java
index bb91939c430e..dcbee83b839b 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/BackgroundRestrictionTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/BackgroundRestrictionTest.java
@@ -113,6 +113,8 @@ import android.app.Notification;
import android.app.NotificationManager;
import android.app.role.RoleManager;
import android.app.usage.AppStandbyInfo;
+import android.content.AttributionSource;
+import android.content.AttributionSourceState;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
@@ -2454,9 +2456,12 @@ public final class BackgroundRestrictionTest {
doReturn(granted ? MODE_ALLOWED : MODE_IGNORED)
.when(mAppOpsManager)
.checkOpNoThrow(op, uid, packageName);
+ AttributionSource attributionSource =
+ new AttributionSource.Builder(uid).setPackageName(packageName).build();
+ AttributionSourceState attributionSourceState = attributionSource.asState();
doReturn(granted ? MODE_ALLOWED : MODE_IGNORED)
.when(mIAppOpsService)
- .checkOperation(op, uid, packageName);
+ .checkOperationWithState(eq(op), eq(attributionSourceState));
} catch (RemoteException e) {
// Ignore.
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java
index 646f4862d75d..daed5df4edd7 100644
--- a/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java
@@ -49,6 +49,7 @@ import static org.mockito.ArgumentMatchers.nullable;
import android.app.AppOpsManager;
import android.app.AppOpsManager.OpEntry;
import android.app.AppOpsManager.PackageOps;
+import android.content.AttributionSource;
import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.PackageManagerInternal;
@@ -216,18 +217,21 @@ public class AppOpsServiceTest {
}
@Test
- public void testNoteOperationAndGetOpsForPackage() {
+ public void testNoteOpAndGetOpsForPackage() {
mAppOpsService.setMode(OP_READ_SMS, mMyUid, sMyPackageName, MODE_ALLOWED);
mAppOpsService.setMode(OP_WRITE_SMS, mMyUid, sMyPackageName, MODE_ERRORED);
+ AttributionSource attributionSource =
+ new AttributionSource.Builder(mMyUid).setPackageName(sMyPackageName).build();
// Note an op that's allowed.
- mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, sMyPackageName, null, false, null, false);
+ mAppOpsService.noteOperationWithState(OP_READ_SMS, attributionSource.asState(), false,
+ null, false);
List<PackageOps> loggedOps = getLoggedOps();
assertContainsOp(loggedOps, OP_READ_SMS, mTestStartMillis, -1, MODE_ALLOWED);
// Note another op that's not allowed.
- mAppOpsService.noteOperation(OP_WRITE_SMS, mMyUid, sMyPackageName, null, false, null,
- false);
+ mAppOpsService.noteOperationWithState(OP_WRITE_SMS, attributionSource.asState(), false,
+ null, false);
loggedOps = getLoggedOps();
assertContainsOp(loggedOps, OP_READ_SMS, mTestStartMillis, -1, MODE_ALLOWED);
assertContainsOp(loggedOps, OP_WRITE_SMS, -1, mTestStartMillis, MODE_ERRORED);
@@ -239,20 +243,24 @@ public class AppOpsServiceTest {
* ACCESS_COARSE_LOCATION op is used to check whether WIFI_SCAN is allowed.
*/
@Test
- public void testNoteOperationAndGetOpsForPackage_controlledByDifferentOp() {
+ public void testNoteOpAndGetOpsForPackage_controlledByDifferentOp() {
// This op controls WIFI_SCAN
mAppOpsService.setMode(OP_COARSE_LOCATION, mMyUid, sMyPackageName, MODE_ALLOWED);
- assertThat(mAppOpsService.noteOperation(OP_WIFI_SCAN, mMyUid, sMyPackageName, null, false,
- null, false).getOpMode()).isEqualTo(MODE_ALLOWED);
+ assertThat(mAppOpsService.noteOperationWithState(OP_WIFI_SCAN,
+ new AttributionSource.Builder(mMyUid).setPackageName(sMyPackageName)
+ .build().asState(), false, null, false).getOpMode())
+ .isEqualTo(MODE_ALLOWED);
assertContainsOp(getLoggedOps(), OP_WIFI_SCAN, mTestStartMillis, -1,
MODE_ALLOWED /* default for WIFI_SCAN; this is not changed or used in this test */);
// Now set COARSE_LOCATION to ERRORED -> this will make WIFI_SCAN disabled as well.
mAppOpsService.setMode(OP_COARSE_LOCATION, mMyUid, sMyPackageName, MODE_ERRORED);
- assertThat(mAppOpsService.noteOperation(OP_WIFI_SCAN, mMyUid, sMyPackageName, null, false,
- null, false).getOpMode()).isEqualTo(MODE_ERRORED);
+ assertThat(mAppOpsService.noteOperationWithState(OP_WIFI_SCAN,
+ new AttributionSource.Builder(mMyUid).setPackageName(sMyPackageName)
+ .build().asState(), false, null, false)
+ .getOpMode()).isEqualTo(MODE_ERRORED);
assertContainsOp(getLoggedOps(), OP_WIFI_SCAN, mTestStartMillis, mTestStartMillis,
MODE_ALLOWED /* default for WIFI_SCAN; this is not changed or used in this test */);
@@ -263,9 +271,12 @@ public class AppOpsServiceTest {
public void testStatePersistence() {
mAppOpsService.setMode(OP_READ_SMS, mMyUid, sMyPackageName, MODE_ALLOWED);
mAppOpsService.setMode(OP_WRITE_SMS, mMyUid, sMyPackageName, MODE_ERRORED);
- mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, sMyPackageName, null, false, null, false);
- mAppOpsService.noteOperation(OP_WRITE_SMS, mMyUid, sMyPackageName, null, false, null,
- false);
+ AttributionSource attributionSource =
+ new AttributionSource.Builder(mMyUid).setPackageName(sMyPackageName).build();
+ mAppOpsService.noteOperationWithState(OP_READ_SMS, attributionSource.asState(), false,
+ null, false);
+ mAppOpsService.noteOperationWithState(OP_WRITE_SMS, attributionSource.asState(), false,
+ null, false);
mAppOpsService.shutdown();
@@ -283,7 +294,10 @@ public class AppOpsServiceTest {
@Test
public void testShutdown() {
mAppOpsService.setMode(OP_READ_SMS, mMyUid, sMyPackageName, MODE_ALLOWED);
- mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, sMyPackageName, null, false, null, false);
+ AttributionSource attributionSource =
+ new AttributionSource.Builder(mMyUid).setPackageName(sMyPackageName).build();
+ mAppOpsService.noteOperationWithState(OP_READ_SMS, attributionSource.asState(), false,
+ null, false);
mAppOpsService.shutdown();
// Create a new app ops service which will initialize its state from XML.
@@ -297,7 +311,10 @@ public class AppOpsServiceTest {
@Test
public void testGetOpsForPackage() {
mAppOpsService.setMode(OP_READ_SMS, mMyUid, sMyPackageName, MODE_ALLOWED);
- mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, sMyPackageName, null, false, null, false);
+ AttributionSource attributionSource =
+ new AttributionSource.Builder(mMyUid).setPackageName(sMyPackageName).build();
+ mAppOpsService.noteOperationWithState(OP_READ_SMS, attributionSource.asState(), false,
+ null, false);
// Query all ops
List<PackageOps> loggedOps = mAppOpsService.getOpsForPackage(
@@ -326,7 +343,10 @@ public class AppOpsServiceTest {
@Test
public void testPackageRemoved() {
mAppOpsService.setMode(OP_READ_SMS, mMyUid, sMyPackageName, MODE_ALLOWED);
- mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, sMyPackageName, null, false, null, false);
+ AttributionSource attributionSource =
+ new AttributionSource.Builder(mMyUid).setPackageName(sMyPackageName).build();
+ mAppOpsService.noteOperationWithState(OP_READ_SMS, attributionSource.asState(), false,
+ null, false);
List<PackageOps> loggedOps = getLoggedOps();
assertContainsOp(loggedOps, OP_READ_SMS, mTestStartMillis, -1, MODE_ALLOWED);
@@ -341,7 +361,8 @@ public class AppOpsServiceTest {
@Test
public void testPackageRemovedHistoricalOps() throws InterruptedException {
mAppOpsService.setMode(OP_READ_SMS, mMyUid, sMyPackageName, MODE_ALLOWED);
- mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, sMyPackageName, null, false, null, false);
+ mAppOpsService.noteOperationWithState(OP_READ_SMS, mMyUid, sMyPackageName, null, false,
+ null, false);
AppOpsManager.HistoricalOps historicalOps = new AppOpsManager.HistoricalOps(0, 15000);
historicalOps.increaseAccessCount(OP_READ_SMS, mMyUid, sMyPackageName, null,
@@ -381,7 +402,10 @@ public class AppOpsServiceTest {
@Test
public void testUidRemoved() {
mAppOpsService.setMode(OP_READ_SMS, mMyUid, sMyPackageName, MODE_ALLOWED);
- mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, sMyPackageName, null, false, null, false);
+ AttributionSource attributionSource =
+ new AttributionSource.Builder(mMyUid).setPackageName(sMyPackageName).build();
+ mAppOpsService.noteOperationWithState(OP_READ_SMS, attributionSource.asState(),
+ false, null, false);
List<PackageOps> loggedOps = getLoggedOps();
assertContainsOp(loggedOps, OP_READ_SMS, mTestStartMillis, -1, MODE_ALLOWED);
@@ -393,7 +417,10 @@ public class AppOpsServiceTest {
@Test
public void testUidStateInitializationDoesntClearState() throws InterruptedException {
mAppOpsService.setMode(OP_READ_SMS, mMyUid, sMyPackageName, MODE_ALLOWED);
- mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, sMyPackageName, null, false, null, false);
+ AttributionSource attributionSource =
+ new AttributionSource.Builder(mMyUid).setPackageName(sMyPackageName).build();
+ mAppOpsService.noteOperationWithState(OP_READ_SMS, attributionSource.asState(), false,
+ null, false);
mAppOpsService.initializeUidStates();
List<PackageOps> ops = mAppOpsService.getOpsForPackage(mMyUid, sMyPackageName,
new int[]{OP_READ_SMS});
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/PackageArchiverTest.java b/services/tests/mockingservicestests/src/com/android/server/pm/PackageArchiverTest.java
index e7f1d16e1dfd..5c8a19c76887 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/PackageArchiverTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/PackageArchiverTest.java
@@ -182,6 +182,10 @@ public class PackageArchiverTest {
any(LauncherActivityInfo.class), eq(mUserId), anyInt(), anyInt());
doReturn(mIcon).when(mArchiveManager).decodeIcon(
any(ArchiveState.ArchiveActivityInfo.class));
+ Resources mockResources = mock(Resources.class);
+ doReturn(mockResources)
+ .when(mContext)
+ .getResources();
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java
index ece3dfeabafa..097cc5177a83 100644
--- a/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java
@@ -17,12 +17,17 @@
package com.android.server.media.projection;
+import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
import static android.media.projection.MediaProjectionManager.TYPE_MIRRORING;
import static android.media.projection.ReviewGrantedConsentResult.RECORD_CANCEL;
import static android.media.projection.ReviewGrantedConsentResult.RECORD_CONTENT_DISPLAY;
import static android.media.projection.ReviewGrantedConsentResult.RECORD_CONTENT_TASK;
import static android.media.projection.ReviewGrantedConsentResult.UNKNOWN;
+import static android.view.ContentRecordingSession.TARGET_UID_FULL_SCREEN;
+import static android.view.ContentRecordingSession.TARGET_UID_UNKNOWN;
+import static android.view.ContentRecordingSession.createDisplaySession;
+import static android.view.ContentRecordingSession.createTaskSession;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
@@ -62,6 +67,7 @@ import android.os.UserHandle;
import android.os.test.TestLooper;
import android.platform.test.annotations.Presubmit;
import android.view.ContentRecordingSession;
+import android.view.ContentRecordingSession.RecordContent;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.FlakyTest;
@@ -99,7 +105,7 @@ public class MediaProjectionManagerServiceTest {
private final ApplicationInfo mAppInfo = new ApplicationInfo();
private final TestLooper mTestLooper = new TestLooper();
private static final ContentRecordingSession DISPLAY_SESSION =
- ContentRecordingSession.createDisplaySession(DEFAULT_DISPLAY);
+ createDisplaySession(DEFAULT_DISPLAY);
// Callback registered by an app on a MediaProjection instance.
private final FakeIMediaProjectionCallback mIMediaProjectionCallback =
new FakeIMediaProjectionCallback();
@@ -142,7 +148,7 @@ public class MediaProjectionManagerServiceTest {
private MediaProjectionManagerService mService;
private OffsettableClock mClock;
private ContentRecordingSession mWaitingDisplaySession =
- ContentRecordingSession.createDisplaySession(DEFAULT_DISPLAY);
+ createDisplaySession(DEFAULT_DISPLAY);
@Mock
private ActivityManagerInternal mAmInternal;
@@ -333,7 +339,7 @@ public class MediaProjectionManagerServiceTest {
projection.stop();
verify(mMediaProjectionMetricsLogger)
- .logStopped(UID, ContentRecordingSession.TARGET_UID_UNKNOWN);
+ .logStopped(UID, TARGET_UID_UNKNOWN);
}
@Test
@@ -351,7 +357,7 @@ public class MediaProjectionManagerServiceTest {
projection.stop();
verify(mMediaProjectionMetricsLogger)
- .logStopped(UID, ContentRecordingSession.TARGET_UID_FULL_SCREEN);
+ .logStopped(UID, TARGET_UID_FULL_SCREEN);
}
@Test
@@ -366,7 +372,7 @@ public class MediaProjectionManagerServiceTest {
.when(mWindowManagerInternal)
.setContentRecordingSession(any(ContentRecordingSession.class));
ContentRecordingSession taskSession =
- ContentRecordingSession.createTaskSession(mock(IBinder.class), targetUid);
+ createTaskSession(mock(IBinder.class), targetUid);
service.setContentRecordingSession(taskSession);
projection.stop();
@@ -695,6 +701,26 @@ public class MediaProjectionManagerServiceTest {
verify(mMediaProjectionMetricsLogger).logAppSelectorDisplayed(hostUid);
}
+ @Test
+ public void notifyWindowingModeChanged_forwardsToLogger() throws Exception {
+ int targetUid = 123;
+ mService =
+ new MediaProjectionManagerService(mContext, mMediaProjectionMetricsLoggerInjector);
+
+ ContentRecordingSession taskSession =
+ createTaskSession(mock(IBinder.class), targetUid);
+ mService.setContentRecordingSession(taskSession);
+
+ MediaProjectionManagerService.MediaProjection projection = startProjectionPreconditions();
+ projection.start(mIMediaProjectionCallback);
+
+ mService.notifyWindowingModeChanged(
+ RECORD_CONTENT_TASK, targetUid, WINDOWING_MODE_MULTI_WINDOW);
+
+ verify(mMediaProjectionMetricsLogger).logChangedWindowingMode(RECORD_CONTENT_TASK,
+ projection.uid, targetUid, WINDOWING_MODE_MULTI_WINDOW);
+ }
+
/**
* Executes and validates scenario where the consent result indicates the projection ends.
*/
@@ -755,7 +781,7 @@ public class MediaProjectionManagerServiceTest {
*/
private void testSetUserReviewGrantedConsentResult_startedSession(
@ReviewGrantedConsentResult int consentResult,
- @ContentRecordingSession.RecordContent int recordedContent)
+ @RecordContent int recordedContent)
throws NameNotFoundException {
MediaProjectionManagerService.MediaProjection projection = startProjectionPreconditions();
projection.setLaunchCookie(mock(IBinder.class));
@@ -777,7 +803,7 @@ public class MediaProjectionManagerServiceTest {
*/
private void testSetUserReviewGrantedConsentResult_failedToStartSession(
@ReviewGrantedConsentResult int consentResult,
- @ContentRecordingSession.RecordContent int recordedContent)
+ @RecordContent int recordedContent)
throws NameNotFoundException {
MediaProjectionManagerService.MediaProjection projection = startProjectionPreconditions();
projection.start(mIMediaProjectionCallback);
@@ -889,7 +915,7 @@ public class MediaProjectionManagerServiceTest {
int targetUid = 123455;
ContentRecordingSession taskSession =
- ContentRecordingSession.createTaskSession(mock(IBinder.class), targetUid);
+ createTaskSession(mock(IBinder.class), targetUid);
service.setContentRecordingSession(taskSession);
verify(mMediaProjectionMetricsLogger).logInProgress(projection.uid, targetUid);
@@ -970,7 +996,7 @@ public class MediaProjectionManagerServiceTest {
verify(mWatcherCallback, never()).onRecordingSessionSet(any(), any());
}
- private void verifySetSessionWithContent(@ContentRecordingSession.RecordContent int content) {
+ private void verifySetSessionWithContent(@RecordContent int content) {
verify(mWindowManagerInternal, atLeastOnce()).setContentRecordingSession(
mSessionCaptor.capture());
assertThat(mSessionCaptor.getValue()).isNotNull();
diff --git a/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionMetricsLoggerTest.java b/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionMetricsLoggerTest.java
index ad1cd6eca5ac..72ce9fe9a23f 100644
--- a/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionMetricsLoggerTest.java
+++ b/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionMetricsLoggerTest.java
@@ -16,6 +16,14 @@
package com.android.server.media.projection;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static android.view.ContentRecordingSession.RECORD_CONTENT_DISPLAY;
+import static android.view.ContentRecordingSession.RECORD_CONTENT_TASK;
+
import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__CREATION_SOURCE__CREATION_SOURCE_UNKNOWN;
import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_APP_SELECTOR_DISPLAYED;
import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_CANCELLED;
@@ -24,6 +32,13 @@ import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE
import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_PERMISSION_REQUEST_DISPLAYED;
import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_STOPPED;
import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_UNKNOWN;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_TARGET_CHANGED__TARGET_TYPE__TARGET_TYPE_APP_TASK;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_TARGET_CHANGED__TARGET_TYPE__TARGET_TYPE_DISPLAY;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_TARGET_CHANGED__TARGET_TYPE__TARGET_TYPE_UNKNOWN;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_TARGET_CHANGED__TARGET_WINDOWING_MODE__WINDOWING_MODE_FREEFORM;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_TARGET_CHANGED__TARGET_WINDOWING_MODE__WINDOWING_MODE_FULLSCREEN;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_TARGET_CHANGED__TARGET_WINDOWING_MODE__WINDOWING_MODE_SPLIT_SCREEN;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_TARGET_CHANGED__TARGET_WINDOWING_MODE__WINDOWING_MODE_UNKNOWN;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
@@ -38,10 +53,14 @@ import androidx.test.filters.SmallTest;
import com.android.internal.util.FrameworkStatsLog;
+import com.google.common.truth.Expect;
+
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
+import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import java.time.Duration;
@@ -60,12 +79,18 @@ public class MediaProjectionMetricsLoggerTest {
private static final int TEST_TARGET_UID = 456;
private static final int TEST_CREATION_SOURCE = 789;
+ private static final int TEST_WINDOWING_MODE = 987;
+ private static final int TEST_CONTENT_TO_RECORD = 654;
+
@Mock private FrameworkStatsLogWrapper mFrameworkStatsLogWrapper;
@Mock private MediaProjectionSessionIdGenerator mSessionIdGenerator;
@Mock private MediaProjectionTimestampStore mTimestampStore;
private MediaProjectionMetricsLogger mLogger;
+ @Rule
+ public Expect mExpect = Expect.create();
+
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
@@ -93,7 +118,7 @@ public class MediaProjectionMetricsLoggerTest {
public void logInitiated_logsHostUid() {
mLogger.logInitiated(TEST_HOST_UID, TEST_CREATION_SOURCE);
- verifyHostUidLogged(TEST_HOST_UID);
+ verifyStateChangedHostUidLogged(TEST_HOST_UID);
}
@Test
@@ -107,7 +132,7 @@ public class MediaProjectionMetricsLoggerTest {
public void logInitiated_logsUnknownTargetUid() {
mLogger.logInitiated(TEST_HOST_UID, TEST_CREATION_SOURCE);
- verifyTargetUidLogged(-2);
+ verifyStageChangedTargetUidLogged(-2);
}
@Test
@@ -178,14 +203,14 @@ public class MediaProjectionMetricsLoggerTest {
public void logStopped_logsHostUid() {
mLogger.logStopped(TEST_HOST_UID, TEST_TARGET_UID);
- verifyHostUidLogged(TEST_HOST_UID);
+ verifyStateChangedHostUidLogged(TEST_HOST_UID);
}
@Test
public void logStopped_logsTargetUid() {
mLogger.logStopped(TEST_HOST_UID, TEST_TARGET_UID);
- verifyTargetUidLogged(TEST_TARGET_UID);
+ verifyStageChangedTargetUidLogged(TEST_TARGET_UID);
}
@Test
@@ -263,14 +288,14 @@ public class MediaProjectionMetricsLoggerTest {
public void logInProgress_logsHostUid() {
mLogger.logInProgress(TEST_HOST_UID, TEST_TARGET_UID);
- verifyHostUidLogged(TEST_HOST_UID);
+ verifyStateChangedHostUidLogged(TEST_HOST_UID);
}
@Test
public void logInProgress_logsTargetUid() {
mLogger.logInProgress(TEST_HOST_UID, TEST_TARGET_UID);
- verifyTargetUidLogged(TEST_TARGET_UID);
+ verifyStageChangedTargetUidLogged(TEST_TARGET_UID);
}
@Test
@@ -336,14 +361,14 @@ public class MediaProjectionMetricsLoggerTest {
public void logPermissionRequestDisplayed_logsHostUid() {
mLogger.logPermissionRequestDisplayed(TEST_HOST_UID);
- verifyHostUidLogged(TEST_HOST_UID);
+ verifyStateChangedHostUidLogged(TEST_HOST_UID);
}
@Test
public void logPermissionRequestDisplayed_logsUnknownTargetUid() {
mLogger.logPermissionRequestDisplayed(TEST_HOST_UID);
- verifyTargetUidLogged(-2);
+ verifyStageChangedTargetUidLogged(-2);
}
@Test
@@ -409,14 +434,14 @@ public class MediaProjectionMetricsLoggerTest {
public void logAppSelectorDisplayed_logsHostUid() {
mLogger.logAppSelectorDisplayed(TEST_HOST_UID);
- verifyHostUidLogged(TEST_HOST_UID);
+ verifyStateChangedHostUidLogged(TEST_HOST_UID);
}
@Test
public void logAppSelectorDisplayed_logsUnknownTargetUid() {
mLogger.logAppSelectorDisplayed(TEST_HOST_UID);
- verifyTargetUidLogged(-2);
+ verifyStageChangedTargetUidLogged(-2);
}
@Test
@@ -492,14 +517,14 @@ public class MediaProjectionMetricsLoggerTest {
public void logProjectionPermissionRequestCancelled_logsHostUid() {
mLogger.logProjectionPermissionRequestCancelled(TEST_HOST_UID);
- verifyHostUidLogged(TEST_HOST_UID);
+ verifyStateChangedHostUidLogged(TEST_HOST_UID);
}
@Test
public void logProjectionPermissionRequestCancelled_logsUnknownTargetUid() {
mLogger.logProjectionPermissionRequestCancelled(TEST_HOST_UID);
- verifyTargetUidLogged(-2);
+ verifyStageChangedTargetUidLogged(-2);
}
@Test
@@ -510,9 +535,88 @@ public class MediaProjectionMetricsLoggerTest {
MEDIA_PROJECTION_STATE_CHANGED__CREATION_SOURCE__CREATION_SOURCE_UNKNOWN);
}
+ @Test
+ public void logWindowingModeChanged_logsTargetChangedAtomId() {
+ mLogger.logChangedWindowingMode(
+ TEST_CONTENT_TO_RECORD, TEST_HOST_UID, TEST_TARGET_UID, TEST_WINDOWING_MODE);
+
+ verifyTargetChangedAtomIdLogged();
+ }
+
+ @Test
+ public void logWindowingModeChanged_logsTargetType() {
+ MediaProjectionMetricsLogger logger = Mockito.spy(mLogger);
+ final int testTargetType = 111;
+ when(logger.contentToRecordToTargetType(TEST_CONTENT_TO_RECORD)).thenReturn(testTargetType);
+ logger.logChangedWindowingMode(
+ TEST_CONTENT_TO_RECORD, TEST_HOST_UID, TEST_TARGET_UID, TEST_WINDOWING_MODE);
+ verifyTargetTypeLogged(testTargetType);
+ }
+
+ @Test
+ public void logWindowingModeChanged_logsHostUid() {
+ mLogger.logChangedWindowingMode(
+ TEST_CONTENT_TO_RECORD, TEST_HOST_UID, TEST_TARGET_UID, TEST_WINDOWING_MODE);
+ verifyTargetChangedHostUidLogged(TEST_HOST_UID);
+ }
+
+ @Test
+ public void logWindowingModeChanged_logsTargetUid() {
+ mLogger.logChangedWindowingMode(
+ TEST_CONTENT_TO_RECORD, TEST_HOST_UID, TEST_TARGET_UID, TEST_WINDOWING_MODE);
+ verifyTargetChangedTargetUidLogged(TEST_TARGET_UID);
+ }
+
+ @Test
+ public void logWindowingModeChanged_logsTargetWindowingMode() {
+ MediaProjectionMetricsLogger logger = Mockito.spy(mLogger);
+ final int testTargetWindowingMode = 222;
+ when(logger.windowingModeToTargetWindowingMode(TEST_WINDOWING_MODE))
+ .thenReturn(testTargetWindowingMode);
+ logger.logChangedWindowingMode(
+ TEST_CONTENT_TO_RECORD, TEST_HOST_UID, TEST_TARGET_UID, TEST_WINDOWING_MODE);
+ verifyWindowingModeLogged(testTargetWindowingMode);
+ }
+
+ @Test
+ public void testContentToRecordToTargetType() {
+ mExpect.that(mLogger.contentToRecordToTargetType(RECORD_CONTENT_DISPLAY))
+ .isEqualTo(MEDIA_PROJECTION_TARGET_CHANGED__TARGET_TYPE__TARGET_TYPE_DISPLAY);
+
+ mExpect.that(mLogger.contentToRecordToTargetType(RECORD_CONTENT_TASK))
+ .isEqualTo(MEDIA_PROJECTION_TARGET_CHANGED__TARGET_TYPE__TARGET_TYPE_APP_TASK);
+
+ mExpect.that(mLogger.contentToRecordToTargetType(2))
+ .isEqualTo(MEDIA_PROJECTION_TARGET_CHANGED__TARGET_TYPE__TARGET_TYPE_UNKNOWN);
+
+ mExpect.that(mLogger.contentToRecordToTargetType(-1))
+ .isEqualTo(MEDIA_PROJECTION_TARGET_CHANGED__TARGET_TYPE__TARGET_TYPE_UNKNOWN);
+
+ mExpect.that(mLogger.contentToRecordToTargetType(100))
+ .isEqualTo(MEDIA_PROJECTION_TARGET_CHANGED__TARGET_TYPE__TARGET_TYPE_UNKNOWN);
+ }
+
+ @Test
+ public void testWindowingModeToTargetWindowingMode() {
+ mExpect.that(mLogger.windowingModeToTargetWindowingMode(WINDOWING_MODE_FULLSCREEN))
+ .isEqualTo(MEDIA_PROJECTION_TARGET_CHANGED__TARGET_WINDOWING_MODE__WINDOWING_MODE_FULLSCREEN);
+
+ mExpect.that(mLogger.windowingModeToTargetWindowingMode(WINDOWING_MODE_MULTI_WINDOW))
+ .isEqualTo(MEDIA_PROJECTION_TARGET_CHANGED__TARGET_WINDOWING_MODE__WINDOWING_MODE_SPLIT_SCREEN);
+
+ mExpect.that(mLogger.windowingModeToTargetWindowingMode(WINDOWING_MODE_FREEFORM))
+ .isEqualTo(MEDIA_PROJECTION_TARGET_CHANGED__TARGET_WINDOWING_MODE__WINDOWING_MODE_FREEFORM);
+
+ mExpect.that(mLogger.windowingModeToTargetWindowingMode(WINDOWING_MODE_PINNED))
+ .isEqualTo(MEDIA_PROJECTION_TARGET_CHANGED__TARGET_WINDOWING_MODE__WINDOWING_MODE_UNKNOWN);
+
+ mExpect.that(mLogger.windowingModeToTargetWindowingMode(WINDOWING_MODE_UNDEFINED))
+ .isEqualTo(MEDIA_PROJECTION_TARGET_CHANGED__TARGET_WINDOWING_MODE__WINDOWING_MODE_UNKNOWN);
+ }
+
private void verifyStateChangedAtomIdLogged() {
verify(mFrameworkStatsLogWrapper)
- .write(
+ .writeStateChanged(
/* code= */ eq(FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED),
/* sessionId= */ anyInt(),
/* state= */ anyInt(),
@@ -525,7 +629,7 @@ public class MediaProjectionMetricsLoggerTest {
private void verifyStateLogged(int state) {
verify(mFrameworkStatsLogWrapper)
- .write(
+ .writeStateChanged(
/* code= */ anyInt(),
/* sessionId= */ anyInt(),
eq(state),
@@ -536,9 +640,9 @@ public class MediaProjectionMetricsLoggerTest {
/* creationSource= */ anyInt());
}
- private void verifyHostUidLogged(int hostUid) {
+ private void verifyStateChangedHostUidLogged(int hostUid) {
verify(mFrameworkStatsLogWrapper)
- .write(
+ .writeStateChanged(
/* code= */ anyInt(),
/* sessionId= */ anyInt(),
/* state= */ anyInt(),
@@ -551,7 +655,7 @@ public class MediaProjectionMetricsLoggerTest {
private void verifyCreationSourceLogged(int creationSource) {
verify(mFrameworkStatsLogWrapper)
- .write(
+ .writeStateChanged(
/* code= */ anyInt(),
/* sessionId= */ anyInt(),
/* state= */ anyInt(),
@@ -562,9 +666,9 @@ public class MediaProjectionMetricsLoggerTest {
eq(creationSource));
}
- private void verifyTargetUidLogged(int targetUid) {
+ private void verifyStageChangedTargetUidLogged(int targetUid) {
verify(mFrameworkStatsLogWrapper)
- .write(
+ .writeStateChanged(
/* code= */ anyInt(),
/* sessionId= */ anyInt(),
/* state= */ anyInt(),
@@ -577,7 +681,7 @@ public class MediaProjectionMetricsLoggerTest {
private void verifyTimeSinceLastActiveSessionLogged(int timeSinceLastActiveSession) {
verify(mFrameworkStatsLogWrapper)
- .write(
+ .writeStateChanged(
/* code= */ anyInt(),
/* sessionId= */ anyInt(),
/* state= */ anyInt(),
@@ -590,7 +694,7 @@ public class MediaProjectionMetricsLoggerTest {
private void verifySessionIdLogged(int newSessionId) {
verify(mFrameworkStatsLogWrapper)
- .write(
+ .writeStateChanged(
/* code= */ anyInt(),
/* sessionId= */ eq(newSessionId),
/* state= */ anyInt(),
@@ -603,7 +707,7 @@ public class MediaProjectionMetricsLoggerTest {
private void verifyPreviousStateLogged(int previousState) {
verify(mFrameworkStatsLogWrapper)
- .write(
+ .writeStateChanged(
/* code= */ anyInt(),
/* sessionId= */ anyInt(),
/* state= */ anyInt(),
@@ -613,4 +717,59 @@ public class MediaProjectionMetricsLoggerTest {
/* timeSinceLastActive= */ anyInt(),
/* creationSource= */ anyInt());
}
+
+ private void verifyTargetChangedAtomIdLogged() {
+ verify(mFrameworkStatsLogWrapper)
+ .writeTargetChanged(
+ eq(FrameworkStatsLog.MEDIA_PROJECTION_TARGET_CHANGED),
+ /* sessionId= */ anyInt(),
+ /* targetType= */ anyInt(),
+ /* hostUid= */ anyInt(),
+ /* targetUid= */ anyInt(),
+ /* targetWindowingMode= */ anyInt());
+ }
+
+ private void verifyTargetTypeLogged(int targetType) {
+ verify(mFrameworkStatsLogWrapper)
+ .writeTargetChanged(
+ /* code= */ anyInt(),
+ /* sessionId= */ anyInt(),
+ eq(targetType),
+ /* hostUid= */ anyInt(),
+ /* targetUid= */ anyInt(),
+ /* targetWindowingMode= */ anyInt());
+ }
+
+ private void verifyTargetChangedHostUidLogged(int hostUid) {
+ verify(mFrameworkStatsLogWrapper)
+ .writeTargetChanged(
+ /* code= */ anyInt(),
+ /* sessionId= */ anyInt(),
+ /* targetType= */ anyInt(),
+ eq(hostUid),
+ /* targetUid= */ anyInt(),
+ /* targetWindowingMode= */ anyInt());
+ }
+
+ private void verifyTargetChangedTargetUidLogged(int targetUid) {
+ verify(mFrameworkStatsLogWrapper)
+ .writeTargetChanged(
+ /* code= */ anyInt(),
+ /* sessionId= */ anyInt(),
+ /* targetType= */ anyInt(),
+ /* hostUid= */ anyInt(),
+ eq(targetUid),
+ /* targetWindowingMode= */ anyInt());
+ }
+
+ private void verifyWindowingModeLogged(int targetWindowingMode) {
+ verify(mFrameworkStatsLogWrapper)
+ .writeTargetChanged(
+ /* code= */ anyInt(),
+ /* sessionId= */ anyInt(),
+ /* targetType= */ anyInt(),
+ /* hostUid= */ anyInt(),
+ /* targetUid= */ anyInt(),
+ eq(targetWindowingMode));
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/SuspendPackagesTest.java b/services/tests/servicestests/src/com/android/server/pm/SuspendPackagesTest.java
index 398148ff4d3b..01a91c1db1e6 100644
--- a/services/tests/servicestests/src/com/android/server/pm/SuspendPackagesTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/SuspendPackagesTest.java
@@ -30,6 +30,7 @@ import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import android.app.AppGlobals;
+import android.content.AttributionSource;
import android.content.Context;
import android.content.pm.IPackageManager;
import android.content.pm.LauncherApps;
@@ -281,12 +282,16 @@ public class SuspendPackagesTest {
};
iAppOps.startWatchingMode(code, TEST_APP_PACKAGE_NAME, watcher);
final int testPackageUid = mPackageManager.getPackageUid(TEST_APP_PACKAGE_NAME, 0);
- int opMode = iAppOps.checkOperation(code, testPackageUid, TEST_APP_PACKAGE_NAME);
+ AttributionSource attributionSource =
+ new AttributionSource.Builder(testPackageUid)
+ .setPackageName(TEST_APP_PACKAGE_NAME)
+ .build();
+ int opMode = iAppOps.checkOperationWithState(code, attributionSource.asState());
assertEquals("Op " + opToName(code) + " disallowed for unsuspended package", MODE_ALLOWED,
opMode);
suspendTestPackage(null, null, null);
assertTrue("AppOpsWatcher did not callback", latch.await(5, TimeUnit.SECONDS));
- opMode = iAppOps.checkOperation(code, testPackageUid, TEST_APP_PACKAGE_NAME);
+ opMode = iAppOps.checkOperationWithState(code, attributionSource.asState());
assertEquals("Op " + opToName(code) + " allowed for suspended package", MODE_IGNORED,
opMode);
iAppOps.stopWatchingMode(watcher);
diff --git a/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java b/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java
index 78566fb06179..887e5ee0c58a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java
@@ -42,6 +42,7 @@ import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
import android.app.WindowConfiguration;
import android.content.pm.ActivityInfo;
@@ -232,7 +233,7 @@ public class ContentRecorderTests extends WindowTestsBase {
@Test
public void testOnConfigurationChanged_neverRecording() {
defaultInit();
- mContentRecorder.onConfigurationChanged(ORIENTATION_PORTRAIT);
+ mContentRecorder.onConfigurationChanged(ORIENTATION_PORTRAIT, WINDOWING_MODE_FULLSCREEN);
verify(mTransaction, never()).setPosition(eq(mRecordedSurface), anyFloat(), anyFloat());
verify(mTransaction, never()).setMatrix(eq(mRecordedSurface), anyFloat(), anyFloat(),
@@ -248,7 +249,7 @@ public class ContentRecorderTests extends WindowTestsBase {
@Configuration.Orientation final int lastOrientation =
mDisplayContent.getConfiguration().orientation == ORIENTATION_PORTRAIT
? ORIENTATION_LANDSCAPE : ORIENTATION_PORTRAIT;
- mContentRecorder.onConfigurationChanged(lastOrientation);
+ mContentRecorder.onConfigurationChanged(lastOrientation, WINDOWING_MODE_FULLSCREEN);
verify(mTransaction, atLeast(2)).setPosition(eq(mRecordedSurface), anyFloat(),
anyFloat());
@@ -266,7 +267,8 @@ public class ContentRecorderTests extends WindowTestsBase {
// The user rotates the device, so the host app resizes the virtual display for the capture.
resizeDisplay(mDisplayContent, newWidth, mSurfaceSize.y);
resizeDisplay(mVirtualDisplayContent, newWidth, mSurfaceSize.y);
- mContentRecorder.onConfigurationChanged(mDisplayContent.getConfiguration().orientation);
+ mContentRecorder.onConfigurationChanged(
+ mDisplayContent.getConfiguration().orientation, WINDOWING_MODE_FULLSCREEN);
verify(mTransaction, atLeast(2)).setPosition(eq(mRecordedSurface), anyFloat(),
anyFloat());
@@ -283,7 +285,7 @@ public class ContentRecorderTests extends WindowTestsBase {
// Change a value that we shouldn't rely upon; it has the wrong type.
mVirtualDisplayContent.setOverrideOrientation(SCREEN_ORIENTATION_FULL_SENSOR);
mContentRecorder.onConfigurationChanged(
- mVirtualDisplayContent.getConfiguration().orientation);
+ mVirtualDisplayContent.getConfiguration().orientation, WINDOWING_MODE_FULLSCREEN);
// No resize is issued, only the initial transformations when we started recording.
verify(mTransaction).setPosition(eq(mRecordedSurface), anyFloat(),
@@ -307,7 +309,7 @@ public class ContentRecorderTests extends WindowTestsBase {
doReturn(newSurfaceSize).when(mWm.mDisplayManagerInternal).getDisplaySurfaceDefaultSize(
anyInt());
mContentRecorder.onConfigurationChanged(
- mVirtualDisplayContent.getConfiguration().orientation);
+ mVirtualDisplayContent.getConfiguration().orientation, WINDOWING_MODE_FULLSCREEN);
// No resize is issued, only the initial transformations when we started recording.
verify(mTransaction, atLeast(2)).setPosition(eq(mRecordedSurface), anyFloat(),
@@ -379,6 +381,55 @@ public class ContentRecorderTests extends WindowTestsBase {
}
@Test
+ public void testTaskWindowingModeChanged_changeWindowMode_notifyWindowModeChanged() {
+ defaultInit();
+ // WHEN a recording is ongoing.
+ mTask.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+ mContentRecorder.setContentRecordingSession(mTaskSession);
+ mContentRecorder.updateRecording();
+ assertThat(mContentRecorder.isCurrentlyRecording()).isTrue();
+
+ // THEN the windowing mode change callback is notified.
+ verify(mMediaProjectionManagerWrapper)
+ .notifyWindowingModeChanged(mTaskSession.getContentToRecord(),
+ mTaskSession.getTargetUid(), WINDOWING_MODE_FULLSCREEN);
+
+ // WHEN a configuration change arrives, and the task is now multi-window mode.
+ mTask.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
+ Configuration configuration = mTask.getConfiguration();
+ mTask.onConfigurationChanged(configuration);
+
+ // THEN windowing mode change callback is notified again.
+ verify(mMediaProjectionManagerWrapper)
+ .notifyWindowingModeChanged(mTaskSession.getContentToRecord(),
+ mTaskSession.getTargetUid(), WINDOWING_MODE_MULTI_WINDOW);
+ }
+
+ @Test
+ public void testTaskWindowingModeChanged_sameWindowMode_notifyWindowModeChanged() {
+ defaultInit();
+ // WHEN a recording is ongoing.
+ mTask.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+ mContentRecorder.setContentRecordingSession(mTaskSession);
+ mContentRecorder.updateRecording();
+ assertThat(mContentRecorder.isCurrentlyRecording()).isTrue();
+
+ // THEN the windowing mode change callback is notified.
+ verify(mMediaProjectionManagerWrapper)
+ .notifyWindowingModeChanged(mTaskSession.getContentToRecord(),
+ mTaskSession.getTargetUid(), WINDOWING_MODE_FULLSCREEN);
+
+ // WHEN a configuration change arrives, and the task is STILL fullscreen.
+ mTask.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+ Configuration configuration = mTask.getConfiguration();
+ mTask.onConfigurationChanged(configuration);
+
+ // THEN the windowing mode change callback is NOT called notified again.
+ verify(mMediaProjectionManagerWrapper, times(1))
+ .notifyWindowingModeChanged(anyInt(), anyInt(), anyInt());
+ }
+
+ @Test
public void testTaskWindowingModeChanged_pip_stopsRecording() {
defaultInit();
// WHEN a recording is ongoing.
@@ -421,9 +472,12 @@ public class ContentRecorderTests extends WindowTestsBase {
mContentRecorder.updateRecording();
assertThat(mContentRecorder.isCurrentlyRecording()).isTrue();
- // THEN the visibility change callback is notified.
+ // THEN the visibility change & windowing mode change callbacks are notified.
verify(mMediaProjectionManagerWrapper)
.notifyActiveProjectionCapturedContentVisibilityChanged(true);
+ verify(mMediaProjectionManagerWrapper)
+ .notifyWindowingModeChanged(mTaskSession.getContentToRecord(),
+ mTaskSession.getTargetUid(), mRootWindowContainer.getWindowingMode());
}
@Test
@@ -434,9 +488,12 @@ public class ContentRecorderTests extends WindowTestsBase {
mContentRecorder.updateRecording();
assertThat(mContentRecorder.isCurrentlyRecording()).isTrue();
- // THEN the visibility change callback is notified.
+ // THEN the visibility change & windowing mode change callbacks are notified.
verify(mMediaProjectionManagerWrapper)
.notifyActiveProjectionCapturedContentVisibilityChanged(true);
+ verify(mMediaProjectionManagerWrapper)
+ .notifyWindowingModeChanged(mDisplaySession.getContentToRecord(),
+ mDisplaySession.getTargetUid(), mRootWindowContainer.getWindowingMode());
}
@Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/InputMethodDialogWindowContextTest.java b/services/tests/wmtests/src/com/android/server/wm/InputMethodDialogWindowContextTest.java
index 41659113b1b2..da3a02ac525a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InputMethodDialogWindowContextTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InputMethodDialogWindowContextTest.java
@@ -160,6 +160,9 @@ public class InputMethodDialogWindowContextTest extends WindowTestsBase {
final DisplayAreaGroup firstDaGroup = mSecondaryDisplay.mFirstRoot;
maxBoundsVerifier.setMaxBounds(firstDaGroup.getMaxBounds());
+ // Clear the previous invocation histories in case we may count the previous
+ // onConfigurationChanged invocation into the next verification.
+ clearInvocations(tokenClient, imeContainer);
firstDaGroup.placeImeContainer(imeContainer);
verify(imeContainer, timeout(WAIT_TIMEOUT_MS)).onConfigurationChanged(
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
index c57b05130e77..8a90f127f4eb 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
@@ -86,7 +86,9 @@ import android.os.RemoteException;
import android.platform.test.annotations.Presubmit;
import android.view.RemoteAnimationDefinition;
import android.view.SurfaceControl;
+import android.window.IRemoteTransition;
import android.window.ITaskFragmentOrganizer;
+import android.window.RemoteTransition;
import android.window.TaskFragmentAnimationParams;
import android.window.TaskFragmentCreationParams;
import android.window.TaskFragmentInfo;
@@ -546,6 +548,35 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
}
@Test
+ public void testApplyTransaction_disallowRemoteTransitionForNonSystemOrganizer() {
+ mTransaction.setRelativeBounds(mFragmentWindowToken, new Rect(0, 0, 100, 100));
+ mTaskFragment.setTaskFragmentOrganizer(mOrganizerToken, 10 /* uid */,
+ "Test:TaskFragmentOrganizer" /* processName */);
+
+ // Throw exception if the transaction has remote transition and is not requested by system
+ // organizer
+ assertThrows(SecurityException.class, () ->
+ mController.applyTransaction(mTransaction, TASK_FRAGMENT_TRANSIT_CHANGE,
+ true /* shouldApplyIndependently */,
+ new RemoteTransition(mock(IRemoteTransition.class))));
+ }
+
+ @Test
+ public void testApplyTransaction_allowRemoteTransitionForSystemOrganizer() {
+ mController.unregisterOrganizer(mIOrganizer);
+ mController.registerOrganizerInternal(mIOrganizer, true /* isSystemOrganizer */);
+
+ mTransaction.setRelativeBounds(mFragmentWindowToken, new Rect(0, 0, 100, 100));
+ mTaskFragment.setTaskFragmentOrganizer(mOrganizerToken, 10 /* uid */,
+ "Test:TaskFragmentOrganizer" /* processName */);
+
+ // Remote transition is allowed for system organizer
+ mController.applyTransaction(mTransaction, TASK_FRAGMENT_TRANSIT_CHANGE,
+ true /* shouldApplyIndependently */,
+ new RemoteTransition(mock(IRemoteTransition.class)));
+ }
+
+ @Test
public void testApplyTransaction_enforceConfigurationChangeOnOrganizedTaskFragment() {
// Throw exception if the transaction is trying to change a window that is not organized by
// the organizer.
@@ -1801,13 +1832,13 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
private void assertApplyTransactionDisallowed(WindowContainerTransaction t) {
assertThrows(SecurityException.class, () ->
mController.applyTransaction(t, TASK_FRAGMENT_TRANSIT_CHANGE,
- false /* shouldApplyIndependently */));
+ false /* shouldApplyIndependently */, null /* remoteTransition */));
}
/** Asserts that applying the given transaction will not throw any exception. */
private void assertApplyTransactionAllowed(WindowContainerTransaction t) {
mController.applyTransaction(t, TASK_FRAGMENT_TRANSIT_CHANGE,
- false /* shouldApplyIndependently */);
+ false /* shouldApplyIndependently */, null /* remoteTransition */);
}
/** Asserts that there will be a transaction for TaskFragment appeared. */
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
index 699580a6536d..2c3917387aec 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
@@ -614,7 +614,7 @@ public class WindowOrganizerTests extends WindowTestsBase {
t.setForceTranslucent(taskFragment.mRemoteToken.toWindowContainerToken(), true);
mWm.mAtmService.mWindowOrganizerController.applyTaskFragmentTransactionLocked(
t, TaskFragmentOrganizer.TASK_FRAGMENT_TRANSIT_CHANGE,
- false /* shouldApplyIndependently */);
+ false /* shouldApplyIndependently */, null /* remoteTransition */);
// Should be not visible and not focusable after the transaction.
assertFalse(taskFragment.shouldBeVisible(null));
@@ -628,7 +628,7 @@ public class WindowOrganizerTests extends WindowTestsBase {
t.setForceTranslucent(taskFragment.mRemoteToken.toWindowContainerToken(), false);
mWm.mAtmService.mWindowOrganizerController.applyTaskFragmentTransactionLocked(
t, TaskFragmentOrganizer.TASK_FRAGMENT_TRANSIT_CHANGE,
- false /* shouldApplyIndependently */);
+ false /* shouldApplyIndependently */, null /* remoteTransition */);
// Should be visible and focusable after the transaction.
assertTrue(taskFragment.shouldBeVisible(null));
@@ -680,7 +680,7 @@ public class WindowOrganizerTests extends WindowTestsBase {
assertThrows(SecurityException.class, () ->
mWm.mAtmService.mWindowOrganizerController.applyTaskFragmentTransactionLocked(
t, TaskFragmentOrganizer.TASK_FRAGMENT_TRANSIT_CHANGE,
- false /* shouldApplyIndependently */)
+ false /* shouldApplyIndependently */, null /* remoteTransition */)
);
}
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 1f32c978fad1..55fecfccf108 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -19,6 +19,7 @@ import static android.content.Intent.LOCAL_FLAG_FROM_SYSTEM;
import android.Manifest;
import android.annotation.CallbackExecutor;
+import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -54,6 +55,7 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.telecom.ClientTransactionalServiceRepository;
import com.android.internal.telecom.ClientTransactionalServiceWrapper;
import com.android.internal.telecom.ITelecomService;
+import com.android.server.telecom.flags.Flags;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -412,6 +414,14 @@ public class TelecomManager {
"android.telecom.extra.CALL_CREATED_TIME_MILLIS";
/**
+ * The extra for call log uri that was used to mark missed calls as read when dialer gets the
+ * notification on reboot.
+ */
+ @FlaggedApi(Flags.FLAG_ADD_CALL_URI_FOR_MISSED_CALLS)
+ public static final String EXTRA_CALL_LOG_URI =
+ "android.telecom.extra.CALL_LOG_URI";
+
+ /**
* Optional extra for incoming containing a long which specifies the time the
* call was answered by user. This value is in milliseconds.
* @hide
@@ -2361,6 +2371,11 @@ public class TelecomManager {
* <p>
* <b>Note</b>: {@link android.app.Notification.CallStyle} notifications should be posted after
* the call is placed in order for the notification to be non-dismissible.
+ * <p><b>Note</b>: Call Forwarding MMI codes can only be dialed by applications that are
+ * configured as the user defined default dialer or system dialer role. If a call containing a
+ * call forwarding MMI code is placed by an application that is not in one of these roles, the
+ * dialer will be launched with a UI showing the MMI code already populated so that the user can
+ * confirm the action before the call is placed.
* @param address The address to make the call to.
* @param extras Bundle of extras to use with the call.
*/
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 042b2a3de0a1..4250bd14da52 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -9692,6 +9692,7 @@ public class CarrierConfigManager {
*
* @see TelephonyManager#PURCHASE_PREMIUM_CAPABILITY_RESULT_USER_CANCELED
* @see TelephonyManager#PURCHASE_PREMIUM_CAPABILITY_RESULT_TIMEOUT
+ * @see TelephonyManager#PURCHASE_PREMIUM_CAPABILITY_RESULT_USER_DISABLED
*/
public static final String
KEY_PREMIUM_CAPABILITY_NOTIFICATION_BACKOFF_HYSTERESIS_TIME_MILLIS_LONG =
diff --git a/telephony/java/android/telephony/IBooleanConsumer.aidl b/telephony/java/android/telephony/IBooleanConsumer.aidl
new file mode 100644
index 000000000000..69f7c9e6e065
--- /dev/null
+++ b/telephony/java/android/telephony/IBooleanConsumer.aidl
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony;
+
+/**
+ * Consumer pattern for an operation that requires a boolean result from another process to finish.
+ * @hide
+ */
+oneway interface IBooleanConsumer {
+ void accept(boolean result);
+} \ No newline at end of file
diff --git a/telephony/java/android/telephony/IIntegerConsumer.aidl b/telephony/java/android/telephony/IIntegerConsumer.aidl
new file mode 100644
index 000000000000..3e84c327734f
--- /dev/null
+++ b/telephony/java/android/telephony/IIntegerConsumer.aidl
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony;
+
+/**
+ * Consumer pattern for an operation that requires an integer result from another process to finish.
+ * @hide
+ */
+oneway interface IIntegerConsumer {
+ void accept(int result);
+} \ No newline at end of file
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 8e90fe7ea975..f8608b8fead2 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -265,8 +265,8 @@ public class SubscriptionManager {
}
}
- private static VoidPropertyInvalidatedCache<Integer> sGetDefaultSubIdCache =
- new VoidPropertyInvalidatedCache<>(ISub::getDefaultSubId,
+ private static IntegerPropertyInvalidatedCache<Integer> sGetDefaultSubIdCacheAsUser =
+ new IntegerPropertyInvalidatedCache<>(ISub::getDefaultSubIdAsUser,
CACHE_KEY_SUBSCRIPTION_MANAGER_SERVICE_PROPERTY,
INVALID_SUBSCRIPTION_ID);
@@ -275,8 +275,8 @@ public class SubscriptionManager {
CACHE_KEY_SUBSCRIPTION_MANAGER_SERVICE_PROPERTY,
INVALID_SUBSCRIPTION_ID);
- private static VoidPropertyInvalidatedCache<Integer> sGetDefaultSmsSubIdCache =
- new VoidPropertyInvalidatedCache<>(ISub::getDefaultSmsSubId,
+ private static IntegerPropertyInvalidatedCache<Integer> sGetDefaultSmsSubIdCacheAsUser =
+ new IntegerPropertyInvalidatedCache<>(ISub::getDefaultSmsSubIdAsUser,
CACHE_KEY_SUBSCRIPTION_MANAGER_SERVICE_PROPERTY,
INVALID_SUBSCRIPTION_ID);
@@ -2309,7 +2309,7 @@ public class SubscriptionManager {
* @return the "system" default subscription id.
*/
public static int getDefaultSubscriptionId() {
- return sGetDefaultSubIdCache.query(null);
+ return sGetDefaultSubIdCacheAsUser.query(Process.myUserHandle().getIdentifier());
}
/**
@@ -2325,7 +2325,7 @@ public class SubscriptionManager {
try {
ISub iSub = TelephonyManager.getSubscriptionService();
if (iSub != null) {
- subId = iSub.getDefaultVoiceSubId();
+ subId = iSub.getDefaultVoiceSubIdAsUser(Process.myUserHandle().getIdentifier());
}
} catch (RemoteException ex) {
// ignore it
@@ -2397,7 +2397,7 @@ public class SubscriptionManager {
* @return the default SMS subscription Id.
*/
public static int getDefaultSmsSubscriptionId() {
- return sGetDefaultSmsSubIdCache.query(null);
+ return sGetDefaultSmsSubIdCacheAsUser.query(Process.myUserHandle().getIdentifier());
}
/**
@@ -3927,10 +3927,10 @@ public class SubscriptionManager {
* @hide
*/
public static void disableCaching() {
- sGetDefaultSubIdCache.disableLocal();
+ sGetDefaultSubIdCacheAsUser.disableLocal();
sGetDefaultDataSubIdCache.disableLocal();
sGetActiveDataSubscriptionIdCache.disableLocal();
- sGetDefaultSmsSubIdCache.disableLocal();
+ sGetDefaultSmsSubIdCacheAsUser.disableLocal();
sGetSlotIndexCache.disableLocal();
sGetSubIdCache.disableLocal();
sGetPhoneIdCache.disableLocal();
@@ -3941,10 +3941,10 @@ public class SubscriptionManager {
*
* @hide */
public static void clearCaches() {
- sGetDefaultSubIdCache.clear();
+ sGetDefaultSubIdCacheAsUser.clear();
sGetDefaultDataSubIdCache.clear();
sGetActiveDataSubscriptionIdCache.clear();
- sGetDefaultSmsSubIdCache.clear();
+ sGetDefaultSmsSubIdCacheAsUser.clear();
sGetSlotIndexCache.clear();
sGetSubIdCache.clear();
sGetPhoneIdCache.clear();
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index c0d6b301def0..e9ea5a7c2ce2 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -17483,9 +17483,8 @@ public class TelephonyManager {
* {@link CarrierConfigManager
* #KEY_PREMIUM_CAPABILITY_NOTIFICATION_BACKOFF_HYSTERESIS_TIME_MILLIS_LONG}
* and return {@link #PURCHASE_PREMIUM_CAPABILITY_RESULT_THROTTLED}.
- *
- * @hide
*/
+ @FlaggedApi(Flags.FLAG_SLICING_ADDITIONAL_ERROR_CODES)
public static final int PURCHASE_PREMIUM_CAPABILITY_RESULT_USER_DISABLED = 16;
/**
diff --git a/telephony/java/android/telephony/satellite/stub/ISatellite.aidl b/telephony/java/android/telephony/satellite/stub/ISatellite.aidl
index e2cd4f8da2c4..711be02761fe 100644
--- a/telephony/java/android/telephony/satellite/stub/ISatellite.aidl
+++ b/telephony/java/android/telephony/satellite/stub/ISatellite.aidl
@@ -16,14 +16,14 @@
package android.telephony.satellite.stub;
+import android.telephony.IBooleanConsumer;
+import android.telephony.IIntegerConsumer;
+
import android.telephony.satellite.stub.INtnSignalStrengthConsumer;
import android.telephony.satellite.stub.ISatelliteCapabilitiesConsumer;
import android.telephony.satellite.stub.ISatelliteListener;
import android.telephony.satellite.stub.SatelliteDatagram;
-import com.android.internal.telephony.IBooleanConsumer;
-import com.android.internal.telephony.IIntegerConsumer;
-
/**
* {@hide}
*/
diff --git a/telephony/java/android/telephony/satellite/stub/SatelliteImplBase.java b/telephony/java/android/telephony/satellite/stub/SatelliteImplBase.java
index a636a6128e61..c0d0830e6105 100644
--- a/telephony/java/android/telephony/satellite/stub/SatelliteImplBase.java
+++ b/telephony/java/android/telephony/satellite/stub/SatelliteImplBase.java
@@ -19,10 +19,10 @@ package android.telephony.satellite.stub;
import android.annotation.NonNull;
import android.os.IBinder;
import android.os.RemoteException;
+import android.telephony.IBooleanConsumer;
+import android.telephony.IIntegerConsumer;
import android.util.Log;
-import com.android.internal.telephony.IBooleanConsumer;
-import com.android.internal.telephony.IIntegerConsumer;
import com.android.internal.telephony.util.TelephonyUtils;
import java.util.List;
diff --git a/telephony/java/com/android/internal/telephony/ISub.aidl b/telephony/java/com/android/internal/telephony/ISub.aidl
index a5a23e8659d8..d2dbeb7aff74 100644
--- a/telephony/java/com/android/internal/telephony/ISub.aidl
+++ b/telephony/java/com/android/internal/telephony/ISub.aidl
@@ -239,6 +239,7 @@ interface ISub {
int getSubId(int slotIndex);
int getDefaultSubId();
+ int getDefaultSubIdAsUser(int userId);
int getPhoneId(int subId);
@@ -251,10 +252,12 @@ interface ISub {
void setDefaultDataSubId(int subId);
int getDefaultVoiceSubId();
+ int getDefaultVoiceSubIdAsUser(int userId);
void setDefaultVoiceSubId(int subId);
int getDefaultSmsSubId();
+ int getDefaultSmsSubIdAsUser(int userId);
void setDefaultSmsSubId(int subId);
diff --git a/tests/FlickerTests/Android.bp b/tests/FlickerTests/Android.bp
index f4f2be642e81..3d49d81a0f5a 100644
--- a/tests/FlickerTests/Android.bp
+++ b/tests/FlickerTests/Android.bp
@@ -166,22 +166,6 @@ android_test {
}
android_test {
- name: "FlickerTestsAppLaunch",
- defaults: ["FlickerTestsDefault"],
- additional_manifests: ["manifests/AndroidManifestAppLaunch.xml"],
- package_name: "com.android.server.wm.flicker.launch",
- instrumentation_target_package: "com.android.server.wm.flicker.launch",
- srcs: [
- ":FlickerTestsBase-src",
- ":FlickerTestsAppLaunchCommon-src",
- ":FlickerTestsAppLaunch2-src",
- ],
- exclude_srcs: [
- ":FlickerTestsActivityEmbedding-src",
- ],
-}
-
-android_test {
name: "FlickerTestsAppLaunch1",
defaults: ["FlickerTestsDefault"],
additional_manifests: ["manifests/AndroidManifestAppLaunch.xml"],
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/open/OpenActivityEmbeddingPlaceholderSplitTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/open/OpenActivityEmbeddingPlaceholderSplitTest.kt
index 48edf6ddeba6..59ff0c65c4fc 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/open/OpenActivityEmbeddingPlaceholderSplitTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/open/OpenActivityEmbeddingPlaceholderSplitTest.kt
@@ -88,14 +88,20 @@ class OpenActivityEmbeddingPlaceholderSplitTest(flicker: LegacyFlickerTest) :
flicker.assertWm {
notContains(ActivityEmbeddingAppHelper.PLACEHOLDER_PRIMARY_COMPONENT)
.then()
- .isAppWindowInvisible(ActivityEmbeddingAppHelper.PLACEHOLDER_PRIMARY_COMPONENT)
+ .isAppWindowInvisible(
+ ActivityEmbeddingAppHelper.PLACEHOLDER_PRIMARY_COMPONENT,
+ isOptional = true
+ )
.then()
.isAppWindowVisible(ActivityEmbeddingAppHelper.PLACEHOLDER_PRIMARY_COMPONENT)
}
flicker.assertWm {
notContains(ActivityEmbeddingAppHelper.PLACEHOLDER_SECONDARY_COMPONENT)
.then()
- .isAppWindowInvisible(ActivityEmbeddingAppHelper.PLACEHOLDER_SECONDARY_COMPONENT)
+ .isAppWindowInvisible(
+ ActivityEmbeddingAppHelper.PLACEHOLDER_SECONDARY_COMPONENT,
+ isOptional = true
+ )
.then()
.isAppWindowVisible(ActivityEmbeddingAppHelper.PLACEHOLDER_SECONDARY_COMPONENT)
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/common/OpenTransferSplashscreenAppFromLauncherTransition.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/common/OpenTransferSplashscreenAppFromLauncherTransition.kt
index 2e9620bb13c5..17f749079da6 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/common/OpenTransferSplashscreenAppFromLauncherTransition.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/common/OpenTransferSplashscreenAppFromLauncherTransition.kt
@@ -24,6 +24,7 @@ import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.FlakyTest
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.helpers.TransferSplashscreenAppHelper
+import com.android.server.wm.flicker.replacesLayer
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -119,7 +120,13 @@ class OpenTransferSplashscreenAppFromLauncherTransition(flicker: LegacyFlickerTe
@FlakyTest(bugId = 240916028)
@Test
override fun appLayerReplacesLauncher() {
- super.appLayerReplacesLauncher()
+ flicker.replacesLayer(
+ ComponentNameMatcher.LAUNCHER,
+ testApp,
+ ignoreEntriesWithRotationLayer = true,
+ ignoreSnapshot = true,
+ ignoreSplashscreen = false
+ )
}
@FlakyTest(bugId = 240916028)