summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/api/system-current.txt7
-rw-r--r--core/java/android/app/ActivityOptions.java5
-rw-r--r--core/java/android/app/AppOpsManager.java6
-rw-r--r--core/java/android/app/IUserSwitchObserver.aidl12
-rw-r--r--core/java/android/app/NotificationManager.java88
-rw-r--r--core/java/android/app/ResourcesManager.java3
-rw-r--r--core/java/android/app/UserSwitchObserver.java6
-rw-r--r--core/java/android/content/res/ResourcesImpl.java15
-rw-r--r--core/java/android/net/http/X509TrustManagerExtensions.java6
-rw-r--r--core/java/android/os/PerfettoTrace.java395
-rw-r--r--core/java/android/os/PerfettoTrackEventExtra.java1081
-rw-r--r--core/java/android/os/flags.aconfig7
-rw-r--r--core/java/android/provider/BlockedNumbersManager.java2
-rw-r--r--core/java/android/provider/Settings.java1
-rw-r--r--core/java/android/security/intrusiondetection/IntrusionDetectionEvent.java51
-rw-r--r--core/java/android/security/intrusiondetection/IntrusionDetectionEventTransport.java3
-rw-r--r--core/java/android/security/intrusiondetection/IntrusionDetectionManager.java2
-rw-r--r--core/java/android/security/net/config/NetworkSecurityTrustManager.java22
-rw-r--r--core/java/android/security/net/config/OWNERS7
-rw-r--r--core/java/android/security/net/config/RootTrustManager.java18
-rw-r--r--core/java/android/view/Choreographer.java1
-rw-r--r--core/java/android/view/IWindowManager.aidl3
-rw-r--r--core/java/android/view/KeyEvent.java26
-rw-r--r--core/java/android/window/flags/lse_desktop_experience.aconfig7
-rw-r--r--core/java/android/window/flags/windowing_frontend.aconfig11
-rw-r--r--core/java/com/android/internal/util/LatencyTracker.java14
-rw-r--r--core/java/com/android/internal/widget/remotecompose/accessibility/PlatformRemoteComposeTouchHelper.java2
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java127
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/Operations.java13
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/PaintContext.java147
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/PaintOperation.java5
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/Platform.java31
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/RemoteComposeBuffer.java87
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java43
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/SerializableToString.java6
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/TouchListener.java9
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/documentation/DocumentationBuilder.java22
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/documentation/DocumentedCompanionOperation.java5
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/documentation/DocumentedOperation.java61
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/documentation/OperationField.java16
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/Header.java14
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/ParticlesCreate.java247
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/ParticlesLoop.java295
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/RootContentBehavior.java9
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/RootContentDescription.java6
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/Theme.java6
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/TouchExpression.java1
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/CanvasContent.java6
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/ClickModifierOperation.java11
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/Component.java167
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentStart.java20
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/Container.java6
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/ContainerEnd.java5
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/ImpulseOperation.java231
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/ImpulseProcess.java154
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponent.java5
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponentContent.java6
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/ListActionsOperation.java12
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/LoopOperation.java11
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/RootLayoutComponent.java23
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/layout/utils/DebugLog.java30
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/utilities/AnimatedFloatExpression.java18
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/operations/utilities/touch/VelocityEasing.java4
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/semantics/AccessibilityModifier.java15
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/semantics/AccessibleComponent.java92
-rw-r--r--core/java/com/android/internal/widget/remotecompose/core/semantics/CoreSemantics.java24
-rw-r--r--core/java/com/android/internal/widget/remotecompose/player/platform/RemoteComposeCanvas.java107
-rw-r--r--core/jni/Android.bp15
-rw-r--r--core/jni/AndroidRuntime.cpp4
-rw-r--r--core/jni/android_os_PerfettoTrace.cpp143
-rw-r--r--core/jni/android_os_PerfettoTrackEventExtra.cpp536
-rw-r--r--core/jni/platform/darwin/libandroid_runtime_export.exp38
-rw-r--r--core/jni/platform/linux/libandroid_runtime_export.txt49
-rw-r--r--core/tests/coretests/Android.bp2
-rw-r--r--core/tests/coretests/jni/Android.bp24
-rw-r--r--core/tests/coretests/jni/PerfettoTraceTest.cpp117
-rw-r--r--core/tests/coretests/src/android/app/NotificationManagerTest.java53
-rw-r--r--core/tests/coretests/src/android/net/http/OWNERS1
-rw-r--r--core/tests/coretests/src/android/net/http/X509TrustManagerExtensionsTest.java22
-rw-r--r--core/tests/coretests/src/android/os/PerfettoTraceTest.java600
-rw-r--r--libs/WindowManager/Shell/AndroidManifest.xml1
-rw-r--r--libs/WindowManager/Shell/aconfig/multitasking.aconfig7
-rw-r--r--libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerViewTest.kt131
-rw-r--r--libs/WindowManager/Shell/shared/res/drawable/floating_dismiss_background.xml27
-rw-r--r--libs/WindowManager/Shell/shared/res/drawable/floating_dismiss_ic_close.xml26
-rw-r--r--libs/WindowManager/Shell/shared/res/values/dimen.xml20
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/DismissViewExt.kt9
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayController.java26
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java70
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java12
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java12
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserver.kt3
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeTransitionTypes.kt26
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandler.kt6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ToggleResizeDesktopTaskTransitionHandler.kt2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/HomeTransitionObserver.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java25
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayControllerTests.java5
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayLayoutTest.java36
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java47
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserverTest.kt5
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt56
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandlerTest.kt6
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/HomeTransitionObserverTest.java2
-rw-r--r--nfc/tests/src/android/nfc/NfcRoutingTableEntryTest.java61
-rw-r--r--nfc/tests/src/android/nfc/OemLogItemsTest.java90
-rw-r--r--nfc/tests/src/android/nfc/cardemulation/CardemulationTest.java73
-rw-r--r--nfc/tests/src/android/nfc/tech/NfcVTest.java119
-rw-r--r--packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/Permissions.kt162
-rw-r--r--packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/SettingsGlobalStore.kt4
-rw-r--r--packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/SettingsSecureStore.kt4
-rw-r--r--packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/SettingsSystemStore.kt4
-rw-r--r--packages/SettingsLib/DataStore/tests/src/com/android/settingslib/datastore/PermissionsTest.kt327
-rw-r--r--packages/SettingsLib/Graph/graph.proto18
-rw-r--r--packages/SettingsLib/Graph/src/com/android/settingslib/graph/PermissionsProtos.kt89
-rw-r--r--packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceGraphBuilder.kt23
-rw-r--r--packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceSetterApi.kt13
-rw-r--r--packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PersistentPreference.kt5
-rw-r--r--packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsDimension.kt5
-rw-r--r--packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsTypography.kt541
-rw-r--r--packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/button/ActionButtons.kt3
-rw-r--r--packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/IntroPreference.kt5
-rw-r--r--packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/ZeroStatePreference.kt5
-rw-r--r--packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/Actions.kt37
-rw-r--r--packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/CustomizedAppBar.kt50
-rw-r--r--packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Category.kt15
-rw-r--r--packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Spinner.kt4
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java51
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java5
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothEventManagerTest.java1
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java4
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java14
-rw-r--r--packages/SettingsProvider/test/src/com/android/providers/settings/SettingsBackupAgentTest.java174
-rw-r--r--packages/SettingsProvider/test/src/com/android/providers/settings/SettingsHelperTest.java114
-rw-r--r--packages/SystemUI/compose/core/src/com/android/compose/gesture/NestedDraggable.kt215
-rw-r--r--packages/SystemUI/compose/core/tests/src/com/android/compose/gesture/NestedDraggableTest.kt169
-rw-r--r--packages/SystemUI/compose/core/tests/src/com/android/compose/gesture/TestOverscrollEffect.kt54
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt5
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt13
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalScene.kt1
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/Notifications.kt12
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeOverlay.kt4
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitions.kt12
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt5
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateSharedAsState.kt12
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt60
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt73
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MovableElement.kt27
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/NestedScrollToScene.kt178
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt27
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt10
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt9
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitions.kt60
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SharedElement.kt18
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeAnimation.kt133
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeToScene.kt44
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDsl.kt59
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDslImpl.kt64
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/Content.kt28
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/state/TransitionState.kt91
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/reveal/ContainerReveal.kt21
-rw-r--r--packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Translate.kt70
-rw-r--r--packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/AnimatedSharedAsStateTest.kt56
-rw-r--r--packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt406
-rw-r--r--packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ElementTest.kt680
-rw-r--r--packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/NestedScrollToSceneTest.kt318
-rw-r--r--packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/OverlayTest.kt16
-rw-r--r--packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutStateTest.kt112
-rw-r--r--packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutTest.kt41
-rw-r--r--packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SwipeToSceneTest.kt165
-rw-r--r--packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/TransitionDslTest.kt30
-rw-r--r--packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/subjects/TransitionStateSubject.kt22
-rw-r--r--packages/SystemUI/compose/scene/tests/src/com/android/compose/nestedscroll/LargeTopAppBarNestedScrollConnectionTest.kt10
-rw-r--r--packages/SystemUI/compose/scene/tests/src/com/android/compose/test/TestOverlayTransition.kt14
-rw-r--r--packages/SystemUI/compose/scene/tests/src/com/android/compose/test/TestReplaceOverlayTransition.kt14
-rw-r--r--packages/SystemUI/compose/scene/tests/src/com/android/compose/test/TestSceneTransition.kt13
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/external/TileServiceRequestControllerTestComposeOn.kt12
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ShadeDisplayChangeLatencyTrackerTest.kt130
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractorTest.kt11
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shared/system/QuickStepContractTest.kt3
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/featurepods/media/domain/interactor/MediaControlChipInteractorTest.kt105
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorImplTest.kt11
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationsProviderTest.kt69
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicyTest.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/common/ui/view/ChoreographerUtils.kt78
-rw-r--r--packages/SystemUI/src/com/android/systemui/common/ui/view/FakeChoreographerUtils.kt51
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/settings/UserTracker.kt11
-rw-r--r--packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayAwareModule.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayChangeLatencyTracker.kt142
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/ShadeTraceLogger.kt32
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractor.kt35
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/featurepods/media/domain/interactor/MediaControlChipInteractor.kt75
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/featurepods/media/shared/model/MediaControlChipModel.kt (renamed from packages/SystemUI/compose/scene/tests/src/com/android/compose/test/Selectors.kt)19
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/dagger/ReferenceCoordinatorsModule.kt (renamed from packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/dagger/CoordinatorsModule.kt)16
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/ReferenceNotificationsModule.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/AutomaticPromotionCoordinator.kt (renamed from packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/promoted/FakePromotedNotificationsProvider.kt)25
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractor.kt18
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationsProvider.kt39
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/ReferenceAutomaticPromotionModule.kt (renamed from packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationsModule.kt)12
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/accessibility/FullscreenMagnificationControllerTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/settings/UserTrackerImplTest.kt18
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/common/ui/view/ChoreographerUtilsKosmos.kt (renamed from packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationsProviderKosmos.kt)6
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorFactory.kt4
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorKosmos.kt1
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/shade/ShadeDisplayChangeLatencyTrackerKosmos.kt36
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractorKosmos.kt7
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/featurepods/media/domain/interactor/MediaControlChipInteractorKosmos.kt29
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorKosmos.kt6
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowBuilder.kt2
-rw-r--r--services/core/java/com/android/server/am/UserController.java174
-rw-r--r--services/core/java/com/android/server/display/BrightnessRangeController.java8
-rw-r--r--services/core/java/com/android/server/display/DisplayPowerController.java2
-rw-r--r--services/core/java/com/android/server/display/HighBrightnessModeController.java15
-rw-r--r--services/core/java/com/android/server/policy/PhoneWindowManager.java20
-rw-r--r--services/core/java/com/android/server/powerstats/PowerStatsLogger.java10
-rw-r--r--services/core/java/com/android/server/security/intrusiondetection/NetworkLogSource.java6
-rw-r--r--services/core/java/com/android/server/security/intrusiondetection/SecurityLogSource.java2
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskManagerService.java9
-rw-r--r--services/core/java/com/android/server/wm/BackgroundActivityStartController.java14
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java1
-rw-r--r--services/core/java/com/android/server/wm/DisplayWindowSettings.java3
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java32
-rw-r--r--services/permission/java/com/android/server/permission/access/appop/AppOpService.kt4
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/HighBrightnessModeControllerTest.java19
-rw-r--r--services/tests/security/intrusiondetection/src/com/android/server/security/intrusiondetection/IntrusionDetectionServiceTest.java11
-rw-r--r--services/tests/servicestests/assets/shortcut/dumpsys_expected.txt4
-rw-r--r--services/tests/servicestests/src/com/android/server/am/UserControllerTest.java92
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java134
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java2740
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest10.java37
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest11.java262
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest12.java26
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java310
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest3.java18
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest4.java6
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest6.java52
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest7.java134
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest8.java202
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest9.java10
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java6
248 files changed, 10847 insertions, 6031 deletions
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index b42c4dacf24f..ff5b2bda7ccf 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -12260,7 +12260,6 @@ package android.provider {
}
@FlaggedApi("com.android.server.telecom.flags.telecom_mainline_blocked_numbers_manager") public static final class BlockedNumbersManager.BlockSuppressionStatus {
- ctor public BlockedNumbersManager.BlockSuppressionStatus(boolean, long);
method public boolean getIsSuppressed();
method public long getUntilTimestampMillis();
}
@@ -12729,9 +12728,9 @@ package android.security.authenticationpolicy {
package android.security.intrusiondetection {
@FlaggedApi("android.security.afl_api") public final class IntrusionDetectionEvent implements android.os.Parcelable {
- ctor public IntrusionDetectionEvent(@NonNull android.app.admin.SecurityLog.SecurityEvent);
- ctor public IntrusionDetectionEvent(@NonNull android.app.admin.DnsEvent);
- ctor public IntrusionDetectionEvent(@NonNull android.app.admin.ConnectEvent);
+ method @NonNull public static android.security.intrusiondetection.IntrusionDetectionEvent createForConnectEvent(@NonNull android.app.admin.ConnectEvent);
+ method @NonNull public static android.security.intrusiondetection.IntrusionDetectionEvent createForDnsEvent(@NonNull android.app.admin.DnsEvent);
+ method @NonNull public static android.security.intrusiondetection.IntrusionDetectionEvent createForSecurityEvent(@NonNull android.app.admin.SecurityLog.SecurityEvent);
method @FlaggedApi("android.security.afl_api") public int describeContents();
method @NonNull public android.app.admin.ConnectEvent getConnectEvent();
method @NonNull public android.app.admin.DnsEvent getDnsEvent();
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index 832c88a795e5..af6978a6b70c 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -1892,7 +1892,7 @@ public class ActivityOptions extends ComponentOptions {
* app to pass through touch events to it when touches fall outside the content window.
*
* <p> By default, touches that fall on a translucent non-touchable area of an overlaying
- * activity window are blocked from passing through to the activity below (source activity),
+ * activity window may be blocked from passing through to the activity below (source activity),
* unless the overlaying activity is from the same UID as the source activity. The source
* activity may use this method to opt in and allow the overlaying activities from the
* to-be-launched app to pass through touches to itself. The source activity needs to ensure
@@ -1900,6 +1900,9 @@ public class ActivityOptions extends ComponentOptions {
* attacks. The flag is ignored if the context calling
* {@link Context#startActivity(Intent, Bundle)} is not an activity.
*
+ * <p> Apps with target SDK 36 and above that depend on cross-uid pass-through touches must
+ * opt in to ensure that pass-through touches work correctly.
+ *
* <p> For backward compatibility, apps with target SDK 35 and below may still receive
* pass-through touches without opt-in if the cross-uid activity is launched by the source
* activity.
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 53b4b54e9f93..efcd278ed118 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -2814,7 +2814,7 @@ public class AppOpsManager {
.setDefaultMode(AppOpsManager.MODE_ALLOWED)
.build(),
new AppOpInfo.Builder(OP_TAKE_AUDIO_FOCUS, OPSTR_TAKE_AUDIO_FOCUS, "TAKE_AUDIO_FOCUS")
- .setDefaultMode(AppOpsManager.MODE_ALLOWED).build(),
+ .setDefaultMode(AppOpsManager.MODE_FOREGROUND).build(),
new AppOpInfo.Builder(OP_AUDIO_MASTER_VOLUME, OPSTR_AUDIO_MASTER_VOLUME,
"AUDIO_MASTER_VOLUME").setSwitchCode(OP_AUDIO_MASTER_VOLUME)
.setRestriction(UserManager.DISALLOW_ADJUST_VOLUME)
@@ -3377,10 +3377,6 @@ public class AppOpsManager {
* @hide
*/
public static @Mode int opToDefaultMode(int op) {
- if (op == OP_TAKE_AUDIO_FOCUS && roForegroundAudioControl()) {
- // when removing the flag, change the entry in sAppOpInfos for OP_TAKE_AUDIO_FOCUS
- return AppOpsManager.MODE_FOREGROUND;
- }
return sAppOpInfos[op].defaultMode;
}
diff --git a/core/java/android/app/IUserSwitchObserver.aidl b/core/java/android/app/IUserSwitchObserver.aidl
index d71ee7c712e7..1ff7a17e578f 100644
--- a/core/java/android/app/IUserSwitchObserver.aidl
+++ b/core/java/android/app/IUserSwitchObserver.aidl
@@ -19,10 +19,10 @@ package android.app;
import android.os.IRemoteCallback;
/** {@hide} */
-oneway interface IUserSwitchObserver {
- void onBeforeUserSwitching(int newUserId, IRemoteCallback reply);
- void onUserSwitching(int newUserId, IRemoteCallback reply);
- void onUserSwitchComplete(int newUserId);
- void onForegroundProfileSwitch(int newProfileId);
- void onLockedBootComplete(int newUserId);
+interface IUserSwitchObserver {
+ void onBeforeUserSwitching(int newUserId);
+ oneway void onUserSwitching(int newUserId, IRemoteCallback reply);
+ oneway void onUserSwitchComplete(int newUserId);
+ oneway void onForegroundProfileSwitch(int newProfileId);
+ oneway void onLockedBootComplete(int newUserId);
}
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index e9b889a2f1aa..2da71471488c 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -68,6 +68,7 @@ import android.service.notification.ZenModeConfig;
import android.service.notification.ZenPolicy;
import android.util.Log;
import android.util.LruCache;
+import android.util.Slog;
import android.util.proto.ProtoOutputStream;
import java.lang.annotation.Retention;
@@ -646,16 +647,21 @@ public class NotificationManager {
*/
public static int MAX_SERVICE_COMPONENT_NAME_LENGTH = 500;
- private static final float MAX_NOTIFICATION_ENQUEUE_RATE = 5f;
+ private static final float MAX_NOTIFICATION_UPDATE_RATE = 5f;
+ private static final float MAX_NOTIFICATION_UNNECESSARY_CANCEL_RATE = 5f;
+ private static final int KNOWN_STATUS_ENQUEUED = 1;
+ private static final int KNOWN_STATUS_CANCELLED = 2;
private final Context mContext;
private final Map<CallNotificationEventListener, CallNotificationEventCallbackStub>
mCallNotificationEventCallbacks = new HashMap<>();
private final InstantSource mClock;
- private final RateEstimator mEnqueueRateEstimator = new RateEstimator();
- private final LruCache<String, Boolean> mEnqueuedNotificationKeys = new LruCache<>(10);
- private final Object mEnqueueThrottleLock = new Object();
+ private final RateEstimator mUpdateRateEstimator = new RateEstimator();
+ private final RateEstimator mUnnecessaryCancelRateEstimator = new RateEstimator();
+ // Value is KNOWN_STATUS_ENQUEUED/_CANCELLED
+ private final LruCache<NotificationKey, Integer> mKnownNotifications = new LruCache<>(100);
+ private final Object mThrottleLock = new Object();
@UnsupportedAppUsage
private static INotificationManager sService;
@@ -780,7 +786,7 @@ public class NotificationManager {
{
INotificationManager service = service();
String pkg = mContext.getPackageName();
- if (discardNotify(tag, id, notification)) {
+ if (discardNotify(user, pkg, tag, id, notification)) {
return;
}
@@ -797,32 +803,39 @@ public class NotificationManager {
* Determines whether a {@link #notify} call should be skipped. If the notification is not
* skipped, updates tracking metadata to use in future decisions.
*/
- private boolean discardNotify(@Nullable String tag, int id, Notification notification) {
+ private boolean discardNotify(UserHandle user, String pkg, @Nullable String tag, int id,
+ Notification notification) {
if (notificationClassification()
&& NotificationChannel.SYSTEM_RESERVED_IDS.contains(notification.getChannelId())) {
return true;
}
if (Flags.nmBinderPerfThrottleNotify()) {
- String key = toEnqueuedNotificationKey(tag, id);
+ NotificationKey key = new NotificationKey(user, pkg, tag, id);
long now = mClock.millis();
- synchronized (mEnqueueThrottleLock) {
- if (mEnqueuedNotificationKeys.get(key) != null
- && !notification.hasCompletedProgress()
- && mEnqueueRateEstimator.getRate(now) > MAX_NOTIFICATION_ENQUEUE_RATE) {
- return true;
+ synchronized (mThrottleLock) {
+ Integer status = mKnownNotifications.get(key);
+ if (status != null && status == KNOWN_STATUS_ENQUEUED
+ && !notification.hasCompletedProgress()) {
+ float updateRate = mUpdateRateEstimator.getRate(now);
+ if (updateRate > MAX_NOTIFICATION_UPDATE_RATE) {
+ Slog.w(TAG, "Shedding update of " + key
+ + ", notification update maximum rate exceeded (" + updateRate
+ + ")");
+ return true;
+ }
+ mUpdateRateEstimator.update(now);
}
- mEnqueueRateEstimator.update(now);
- mEnqueuedNotificationKeys.put(key, Boolean.TRUE);
+ mKnownNotifications.put(key, KNOWN_STATUS_ENQUEUED);
}
}
return false;
}
- private static String toEnqueuedNotificationKey(@Nullable String tag, int id) {
- return tag + "," + id;
- }
+
+ private record NotificationKey(@NonNull UserHandle user, @NonNull String pkg,
+ @Nullable String tag, int id) { }
private Notification fixNotification(Notification notification) {
String pkg = mContext.getPackageName();
@@ -920,14 +933,12 @@ public class NotificationManager {
@UnsupportedAppUsage
public void cancelAsUser(@Nullable String tag, int id, UserHandle user)
{
- if (Flags.nmBinderPerfThrottleNotify()) {
- synchronized (mEnqueueThrottleLock) {
- mEnqueuedNotificationKeys.remove(toEnqueuedNotificationKey(tag, id));
- }
+ String pkg = mContext.getPackageName();
+ if (discardCancel(user, pkg, tag, id)) {
+ return;
}
INotificationManager service = service();
- String pkg = mContext.getPackageName();
if (localLOGV) Log.v(TAG, pkg + ": cancel(" + id + ")");
try {
service.cancelNotificationWithTag(
@@ -938,14 +949,43 @@ public class NotificationManager {
}
/**
+ * Determines whether a {@link #cancel} call should be skipped. If not skipped, updates tracking
+ * metadata to use in future decisions.
+ */
+ private boolean discardCancel(UserHandle user, String pkg, @Nullable String tag, int id) {
+ if (Flags.nmBinderPerfThrottleNotify()) {
+ NotificationKey key = new NotificationKey(user, pkg, tag, id);
+ long now = mClock.millis();
+ synchronized (mThrottleLock) {
+ Integer status = mKnownNotifications.get(key);
+ if (status != null && status == KNOWN_STATUS_CANCELLED) {
+ float cancelRate = mUnnecessaryCancelRateEstimator.getRate(now);
+ if (cancelRate > MAX_NOTIFICATION_UNNECESSARY_CANCEL_RATE) {
+ Slog.w(TAG, "Shedding cancel of " + key
+ + ", presumably unnecessary and maximum rate exceeded ("
+ + cancelRate + ")");
+ return true;
+ }
+ mUnnecessaryCancelRateEstimator.update(now);
+ }
+ mKnownNotifications.put(key, KNOWN_STATUS_CANCELLED);
+ }
+ }
+
+ return false;
+ }
+
+ /**
* Cancel all previously shown notifications. See {@link #cancel} for the
* detailed behavior.
*/
public void cancelAll()
{
if (Flags.nmBinderPerfThrottleNotify()) {
- synchronized (mEnqueueThrottleLock) {
- mEnqueuedNotificationKeys.evictAll();
+ synchronized (mThrottleLock) {
+ for (NotificationKey key : mKnownNotifications.snapshot().keySet()) {
+ mKnownNotifications.put(key, KNOWN_STATUS_CANCELLED);
+ }
}
}
diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java
index 51d0b18467f4..d66429a2192d 100644
--- a/core/java/android/app/ResourcesManager.java
+++ b/core/java/android/app/ResourcesManager.java
@@ -77,6 +77,7 @@ import java.util.function.Function;
public class ResourcesManager {
static final String TAG = "ResourcesManager";
private static final boolean DEBUG = false;
+ public static final String RESOURCE_CACHE_DIR = "/data/resource-cache/";
private static volatile ResourcesManager sResourcesManager;
@@ -581,7 +582,7 @@ public class ResourcesManager {
}
private static String overlayPathToIdmapPath(String path) {
- return "/data/resource-cache/" + path.substring(1).replace('/', '@') + "@idmap";
+ return RESOURCE_CACHE_DIR + path.substring(1).replace('/', '@') + "@idmap";
}
/**
diff --git a/core/java/android/app/UserSwitchObserver.java b/core/java/android/app/UserSwitchObserver.java
index 1664cfb6f7a8..727799a1f948 100644
--- a/core/java/android/app/UserSwitchObserver.java
+++ b/core/java/android/app/UserSwitchObserver.java
@@ -30,11 +30,7 @@ public class UserSwitchObserver extends IUserSwitchObserver.Stub {
}
@Override
- public void onBeforeUserSwitching(int newUserId, IRemoteCallback reply) throws RemoteException {
- if (reply != null) {
- reply.sendResult(null);
- }
- }
+ public void onBeforeUserSwitching(int newUserId) throws RemoteException {}
@Override
public void onUserSwitching(int newUserId, IRemoteCallback reply) throws RemoteException {
diff --git a/core/java/android/content/res/ResourcesImpl.java b/core/java/android/content/res/ResourcesImpl.java
index bcaceb24d767..96c71765d102 100644
--- a/core/java/android/content/res/ResourcesImpl.java
+++ b/core/java/android/content/res/ResourcesImpl.java
@@ -992,15 +992,24 @@ public class ResourcesImpl {
} else {
dr = loadXmlDrawable(wrapper, value, id, density, file);
}
- } else if (file.startsWith("frro://")) {
+ } else if (file.startsWith("frro:/")) {
Uri uri = Uri.parse(file);
+ long offset = Long.parseLong(uri.getQueryParameter("offset"));
+ long size = Long.parseLong(uri.getQueryParameter("size"));
+ if (offset < 0 || size <= 0) {
+ throw new NotFoundException("invalid frro parameters");
+ }
File f = new File('/' + uri.getHost() + uri.getPath());
+ if (!f.getCanonicalPath().startsWith(ResourcesManager.RESOURCE_CACHE_DIR)
+ || !f.getCanonicalPath().endsWith(".frro") || !f.canRead()) {
+ throw new NotFoundException("invalid frro path");
+ }
ParcelFileDescriptor pfd = ParcelFileDescriptor.open(f,
ParcelFileDescriptor.MODE_READ_ONLY);
AssetFileDescriptor afd = new AssetFileDescriptor(
pfd,
- Long.parseLong(uri.getQueryParameter("offset")),
- Long.parseLong(uri.getQueryParameter("size")));
+ offset,
+ size);
FileInputStream is = afd.createInputStream();
dr = decodeImageDrawable(is, wrapper);
} else {
diff --git a/core/java/android/net/http/X509TrustManagerExtensions.java b/core/java/android/net/http/X509TrustManagerExtensions.java
index 3425b77be954..0eb9f29e1ec3 100644
--- a/core/java/android/net/http/X509TrustManagerExtensions.java
+++ b/core/java/android/net/http/X509TrustManagerExtensions.java
@@ -86,8 +86,8 @@ public class X509TrustManagerExtensions {
try {
checkServerTrustedOcspAndTlsData = tm.getClass().getMethod("checkServerTrusted",
X509Certificate[].class,
- Byte[].class,
- Byte[].class,
+ byte[].class,
+ byte[].class,
String.class,
String.class);
} catch (ReflectiveOperationException ignored) { }
@@ -179,7 +179,7 @@ public class X509TrustManagerExtensions {
}
try {
result = (List<X509Certificate>) mCheckServerTrustedOcspAndTlsData.invoke(mTrustManager,
- ocspData, tlsSctData, chain, authType, host);
+ chain, ocspData, tlsSctData, authType, host);
return result == null ? Collections.emptyList() : result;
} catch (IllegalAccessException e) {
throw new CertificateException("Failed to call checkServerTrusted", e);
diff --git a/core/java/android/os/PerfettoTrace.java b/core/java/android/os/PerfettoTrace.java
new file mode 100644
index 000000000000..164561acac32
--- /dev/null
+++ b/core/java/android/os/PerfettoTrace.java
@@ -0,0 +1,395 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os;
+
+import dalvik.annotation.optimization.CriticalNative;
+import dalvik.annotation.optimization.FastNative;
+
+import libcore.util.NativeAllocationRegistry;
+
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Consumer;
+
+/**
+ * Writes trace events to the perfetto trace buffer. These trace events can be
+ * collected and visualized using the Perfetto UI.
+ *
+ * <p>This tracing mechanism is independent of the method tracing mechanism
+ * offered by {@link Debug#startMethodTracing} or {@link Trace}.
+ *
+ * @hide
+ */
+public final class PerfettoTrace {
+ private static final String TAG = "PerfettoTrace";
+
+ // Keep in sync with C++
+ private static final int PERFETTO_TE_TYPE_SLICE_BEGIN = 1;
+ private static final int PERFETTO_TE_TYPE_SLICE_END = 2;
+ private static final int PERFETTO_TE_TYPE_INSTANT = 3;
+ private static final int PERFETTO_TE_TYPE_COUNTER = 4;
+
+ private static final boolean IS_FLAG_ENABLED = android.os.Flags.perfettoSdkTracingV2();
+
+ /**
+ * For fetching the next flow event id in a process.
+ */
+ private static final AtomicInteger sFlowEventId = new AtomicInteger();
+
+ /**
+ * Perfetto category a trace event belongs to.
+ * Registering a category is not sufficient to capture events within the category, it must
+ * also be enabled in the trace config.
+ */
+ public static final class Category implements PerfettoTrackEventExtra.PerfettoPointer {
+ private static final NativeAllocationRegistry sRegistry =
+ NativeAllocationRegistry.createMalloced(
+ Category.class.getClassLoader(), native_delete());
+
+ private final long mPtr;
+ private final long mExtraPtr;
+ private final String mName;
+ private final String mTag;
+ private final String mSeverity;
+ private boolean mIsRegistered;
+
+ /**
+ * Category ctor.
+ *
+ * @param name The category name.
+ */
+ public Category(String name) {
+ this(name, null, null);
+ }
+
+ /**
+ * Category ctor.
+ *
+ * @param name The category name.
+ * @param tag An atrace tag name that this category maps to.
+ */
+ public Category(String name, String tag) {
+ this(name, tag, null);
+ }
+
+ /**
+ * Category ctor.
+ *
+ * @param name The category name.
+ * @param tag An atrace tag name that this category maps to.
+ * @param severity A Log style severity string for the category.
+ */
+ public Category(String name, String tag, String severity) {
+ mName = name;
+ mTag = tag;
+ mSeverity = severity;
+ mPtr = native_init(name, tag, severity);
+ mExtraPtr = native_get_extra_ptr(mPtr);
+ sRegistry.registerNativeAllocation(this, mPtr);
+ }
+
+ @FastNative
+ private static native long native_init(String name, String tag, String severity);
+ @CriticalNative
+ private static native long native_delete();
+ @CriticalNative
+ private static native void native_register(long ptr);
+ @CriticalNative
+ private static native void native_unregister(long ptr);
+ @CriticalNative
+ private static native boolean native_is_enabled(long ptr);
+ @CriticalNative
+ private static native long native_get_extra_ptr(long ptr);
+
+ /**
+ * Register the category.
+ */
+ public Category register() {
+ native_register(mPtr);
+ mIsRegistered = true;
+ return this;
+ }
+
+ /**
+ * Unregister the category.
+ */
+ public Category unregister() {
+ native_unregister(mPtr);
+ mIsRegistered = false;
+ return this;
+ }
+
+ /**
+ * Whether the category is enabled or not.
+ */
+ public boolean isEnabled() {
+ return IS_FLAG_ENABLED && native_is_enabled(mPtr);
+ }
+
+ /**
+ * Whether the category is registered or not.
+ */
+ public boolean isRegistered() {
+ return mIsRegistered;
+ }
+
+ /**
+ * Returns the native pointer for the category.
+ */
+ @Override
+ public long getPtr() {
+ return mExtraPtr;
+ }
+ }
+
+ @FastNative
+ private static native void native_event(int type, long tag, String name, long ptr);
+
+ @CriticalNative
+ private static native long native_get_process_track_uuid();
+
+ @CriticalNative
+ private static native long native_get_thread_track_uuid(long tid);
+
+ @FastNative
+ private static native void native_activate_trigger(String name, int ttlMs);
+
+ /**
+ * Writes a trace message to indicate a given section of code was invoked.
+ *
+ * @param category The perfetto category pointer.
+ * @param eventName The event name to appear in the trace.
+ * @param extra The extra arguments.
+ */
+ public static void instant(Category category, String eventName, PerfettoTrackEventExtra extra) {
+ if (!category.isEnabled()) {
+ return;
+ }
+
+ native_event(PERFETTO_TE_TYPE_INSTANT, category.getPtr(), eventName, extra.getPtr());
+ extra.reset();
+ }
+
+ /**
+ * Writes a trace message to indicate a given section of code was invoked.
+ *
+ * @param category The perfetto category.
+ * @param eventName The event name to appear in the trace.
+ * @param extraConfig Consumer for the extra arguments.
+ */
+ public static void instant(Category category, String eventName,
+ Consumer<PerfettoTrackEventExtra.Builder> extraConfig) {
+ PerfettoTrackEventExtra.Builder extra = PerfettoTrackEventExtra.builder();
+ extraConfig.accept(extra);
+ instant(category, eventName, extra.build());
+ }
+
+ /**
+ * Writes a trace message to indicate a given section of code was invoked.
+ *
+ * @param category The perfetto category.
+ * @param eventName The event name to appear in the trace.
+ */
+ public static void instant(Category category, String eventName) {
+ instant(category, eventName, PerfettoTrackEventExtra.builder().build());
+ }
+
+ /**
+ * Writes a trace message to indicate the start of a given section of code.
+ *
+ * @param category The perfetto category pointer.
+ * @param eventName The event name to appear in the trace.
+ * @param extra The extra arguments.
+ */
+ public static void begin(Category category, String eventName, PerfettoTrackEventExtra extra) {
+ if (!category.isEnabled()) {
+ return;
+ }
+
+ native_event(PERFETTO_TE_TYPE_SLICE_BEGIN, category.getPtr(), eventName, extra.getPtr());
+ extra.reset();
+ }
+
+ /**
+ * Writes a trace message to indicate the start of a given section of code.
+ *
+ * @param category The perfetto category pointer.
+ * @param eventName The event name to appear in the trace.
+ * @param extraConfig Consumer for the extra arguments.
+ */
+ public static void begin(Category category, String eventName,
+ Consumer<PerfettoTrackEventExtra.Builder> extraConfig) {
+ PerfettoTrackEventExtra.Builder extra = PerfettoTrackEventExtra.builder();
+ extraConfig.accept(extra);
+ begin(category, eventName, extra.build());
+ }
+
+ /**
+ * Writes a trace message to indicate the start of a given section of code.
+ *
+ * @param category The perfetto category pointer.
+ * @param eventName The event name to appear in the trace.
+ */
+ public static void begin(Category category, String eventName) {
+ begin(category, eventName, PerfettoTrackEventExtra.builder().build());
+ }
+
+ /**
+ * Writes a trace message to indicate the end of a given section of code.
+ *
+ * @param category The perfetto category pointer.
+ * @param extra The extra arguments.
+ */
+ public static void end(Category category, PerfettoTrackEventExtra extra) {
+ if (!category.isEnabled()) {
+ return;
+ }
+
+ native_event(PERFETTO_TE_TYPE_SLICE_END, category.getPtr(), "", extra.getPtr());
+ extra.reset();
+ }
+
+ /**
+ * Writes a trace message to indicate the end of a given section of code.
+ *
+ * @param category The perfetto category pointer.
+ * @param extraConfig Consumer for the extra arguments.
+ */
+ public static void end(Category category,
+ Consumer<PerfettoTrackEventExtra.Builder> extraConfig) {
+ PerfettoTrackEventExtra.Builder extra = PerfettoTrackEventExtra.builder();
+ extraConfig.accept(extra);
+ end(category, extra.build());
+ }
+
+ /**
+ * Writes a trace message to indicate the end of a given section of code.
+ *
+ * @param category The perfetto category pointer.
+ */
+ public static void end(Category category) {
+ end(category, PerfettoTrackEventExtra.builder().build());
+ }
+
+ /**
+ * Writes a trace message to indicate the value of a given section of code.
+ *
+ * @param category The perfetto category pointer.
+ * @param extra The extra arguments.
+ */
+ public static void counter(Category category, PerfettoTrackEventExtra extra) {
+ if (!category.isEnabled()) {
+ return;
+ }
+
+ native_event(PERFETTO_TE_TYPE_COUNTER, category.getPtr(), "", extra.getPtr());
+ extra.reset();
+ }
+
+ /**
+ * Writes a trace message to indicate the value of a given section of code.
+ *
+ * @param category The perfetto category pointer.
+ * @param extraConfig Consumer for the extra arguments.
+ */
+ public static void counter(Category category,
+ Consumer<PerfettoTrackEventExtra.Builder> extraConfig) {
+ PerfettoTrackEventExtra.Builder extra = PerfettoTrackEventExtra.builder();
+ extraConfig.accept(extra);
+ counter(category, extra.build());
+ }
+
+ /**
+ * Writes a trace message to indicate the value of a given section of code.
+ *
+ * @param category The perfetto category pointer.
+ * @param trackName The trackName for the event.
+ * @param value The value of the counter.
+ */
+ public static void counter(Category category, String trackName, long value) {
+ PerfettoTrackEventExtra extra = PerfettoTrackEventExtra.builder()
+ .usingCounterTrack(trackName, PerfettoTrace.getProcessTrackUuid())
+ .setCounter(value)
+ .build();
+ counter(category, extra);
+ }
+
+ /**
+ * Writes a trace message to indicate the value of a given section of code.
+ *
+ * @param category The perfetto category pointer.
+ * @param trackName The trackName for the event.
+ * @param value The value of the counter.
+ */
+ public static void counter(Category category, String trackName, double value) {
+ PerfettoTrackEventExtra extra = PerfettoTrackEventExtra.builder()
+ .usingCounterTrack(trackName, PerfettoTrace.getProcessTrackUuid())
+ .setCounter(value)
+ .build();
+ counter(category, extra);
+ }
+
+ /**
+ * Returns the next flow id to be used.
+ */
+ public static int getFlowId() {
+ return sFlowEventId.incrementAndGet();
+ }
+
+ /**
+ * Returns the global track uuid that can be used as a parent track uuid.
+ */
+ public static long getGlobalTrackUuid() {
+ return 0;
+ }
+
+ /**
+ * Returns the process track uuid that can be used as a parent track uuid.
+ */
+ public static long getProcessTrackUuid() {
+ if (IS_FLAG_ENABLED) {
+ return 0;
+ }
+ return native_get_process_track_uuid();
+ }
+
+ /**
+ * Given a thread tid, returns the thread track uuid that can be used as a parent track uuid.
+ */
+ public static long getThreadTrackUuid(long tid) {
+ if (IS_FLAG_ENABLED) {
+ return 0;
+ }
+ return native_get_thread_track_uuid(tid);
+ }
+
+ /**
+ * Activates a trigger by name {@code triggerName} with expiry in {@code ttlMs}.
+ */
+ public static void activateTrigger(String triggerName, int ttlMs) {
+ if (IS_FLAG_ENABLED) {
+ return;
+ }
+ native_activate_trigger(triggerName, ttlMs);
+ }
+
+ /**
+ * Registers the process with Perfetto.
+ */
+ public static void register() {
+ Trace.registerWithPerfetto();
+ }
+}
diff --git a/core/java/android/os/PerfettoTrackEventExtra.java b/core/java/android/os/PerfettoTrackEventExtra.java
new file mode 100644
index 000000000000..a219b3b5678b
--- /dev/null
+++ b/core/java/android/os/PerfettoTrackEventExtra.java
@@ -0,0 +1,1081 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os;
+
+import dalvik.annotation.optimization.CriticalNative;
+import dalvik.annotation.optimization.FastNative;
+
+import libcore.util.NativeAllocationRegistry;
+
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.function.Supplier;
+
+/**
+ * Holds extras to be passed to Perfetto track events in {@link PerfettoTrace}.
+ *
+ * @hide
+ */
+public final class PerfettoTrackEventExtra {
+ private static final int DEFAULT_EXTRA_CACHE_SIZE = 5;
+ private static final ThreadLocal<PerfettoTrackEventExtra> sTrackEventExtra =
+ new ThreadLocal<PerfettoTrackEventExtra>() {
+ @Override
+ protected PerfettoTrackEventExtra initialValue() {
+ return new PerfettoTrackEventExtra();
+ }
+ };
+ private static final AtomicLong sNamedTrackId = new AtomicLong();
+
+ private boolean mIsInUse;
+ private CounterInt64 mCounterInt64;
+ private CounterDouble mCounterDouble;
+ private Proto mProto;
+
+ /**
+ * Represents a native pointer to a Perfetto C SDK struct. E.g. PerfettoTeHlExtra.
+ */
+ public interface PerfettoPointer {
+ /**
+ * Returns the perfetto struct native pointer.
+ */
+ long getPtr();
+ }
+
+ /**
+ * Container for {@link Field} instances.
+ */
+ public interface FieldContainer {
+ /**
+ * Add {@link Field} to the container.
+ */
+ void addField(PerfettoPointer field);
+ }
+
+ /**
+ * RingBuffer implemented on top of a SparseArray.
+ *
+ * Bounds a SparseArray with a FIFO algorithm.
+ */
+ private static final class RingBuffer<T> {
+ private final int mCapacity;
+ private final int[] mKeyArray;
+ private final T[] mValueArray;
+ private int mWriteEnd = 0;
+
+ RingBuffer(int capacity) {
+ mCapacity = capacity;
+ mKeyArray = new int[capacity];
+ mValueArray = (T[]) new Object[capacity];
+ }
+
+ public void put(int key, T value) {
+ mKeyArray[mWriteEnd] = key;
+ mValueArray[mWriteEnd] = value;
+ mWriteEnd = (mWriteEnd + 1) % mCapacity;
+ }
+
+ public T get(int key) {
+ for (int i = 0; i < mCapacity; i++) {
+ if (mKeyArray[i] == key) {
+ return mValueArray[i];
+ }
+ }
+ return null;
+ }
+ }
+
+ private static final class Pool<T> {
+ private final int mCapacity;
+ private final T[] mValueArray;
+ private int mIdx = 0;
+
+ Pool(int capacity) {
+ mCapacity = capacity;
+ mValueArray = (T[]) new Object[capacity];
+ }
+
+ public void reset() {
+ mIdx = 0;
+ }
+
+ public T get(Supplier<T> supplier) {
+ if (mIdx >= mCapacity) {
+ return supplier.get();
+ }
+ if (mValueArray[mIdx] == null) {
+ mValueArray[mIdx] = supplier.get();
+ }
+ return mValueArray[mIdx++];
+ }
+ }
+
+ /**
+ * Builder for Perfetto track event extras.
+ */
+ public static final class Builder {
+ // For performance reasons, we hold a reference to mExtra as a holder for
+ // perfetto pointers being added. This way, we avoid an additional list to hold
+ // the pointers in Java and we can pass them down directly to native code.
+ private final PerfettoTrackEventExtra mExtra;
+ private boolean mIsBuilt;
+ private Builder mParent;
+ private FieldContainer mCurrentContainer;
+
+ private final CounterInt64 mCounterInt64;
+ private final CounterDouble mCounterDouble;
+ private final Proto mProto;
+
+ private final RingBuffer<NamedTrack> mNamedTrackCache;
+ private final RingBuffer<CounterTrack> mCounterTrackCache;
+ private final RingBuffer<ArgInt64> mArgInt64Cache;
+ private final RingBuffer<ArgBool> mArgBoolCache;
+ private final RingBuffer<ArgDouble> mArgDoubleCache;
+ private final RingBuffer<ArgString> mArgStringCache;
+
+ private final Pool<FieldInt64> mFieldInt64Cache;
+ private final Pool<FieldDouble> mFieldDoubleCache;
+ private final Pool<FieldString> mFieldStringCache;
+ private final Pool<FieldNested> mFieldNestedCache;
+ private final Pool<Flow> mFlowCache;
+ private final Pool<Builder> mBuilderCache;
+
+ private Builder() {
+ this(sTrackEventExtra.get(), null, null);
+ }
+
+ private Builder(PerfettoTrackEventExtra extra, Builder parent, FieldContainer container) {
+ mExtra = extra;
+ mParent = parent;
+ mCurrentContainer = container;
+
+ mNamedTrackCache = mExtra.mNamedTrackCache;
+ mCounterTrackCache = mExtra.mCounterTrackCache;
+ mArgInt64Cache = mExtra.mArgInt64Cache;
+ mArgDoubleCache = mExtra.mArgDoubleCache;
+ mArgBoolCache = mExtra.mArgBoolCache;
+ mArgStringCache = mExtra.mArgStringCache;
+ mFieldInt64Cache = mExtra.mFieldInt64Cache;
+ mFieldDoubleCache = mExtra.mFieldDoubleCache;
+ mFieldStringCache = mExtra.mFieldStringCache;
+ mFieldNestedCache = mExtra.mFieldNestedCache;
+ mFlowCache = mExtra.mFlowCache;
+ mBuilderCache = mExtra.mBuilderCache;
+
+ mCounterInt64 = mExtra.getCounterInt64();
+ mCounterDouble = mExtra.getCounterDouble();
+ mProto = mExtra.getProto();
+ }
+
+ /**
+ * Builds the track event extra.
+ */
+ public PerfettoTrackEventExtra build() {
+ checkParent();
+ mIsBuilt = true;
+
+ mFieldInt64Cache.reset();
+ mFieldDoubleCache.reset();
+ mFieldStringCache.reset();
+ mFieldNestedCache.reset();
+ mBuilderCache.reset();
+
+ return mExtra;
+ }
+
+ /**
+ * Adds a debug arg with key {@code name} and value {@code val}.
+ */
+ public Builder addArg(String name, long val) {
+ checkParent();
+ ArgInt64 arg = mArgInt64Cache.get(name.hashCode());
+ if (arg == null || !arg.getName().equals(name)) {
+ arg = new ArgInt64(name);
+ mArgInt64Cache.put(name.hashCode(), arg);
+ }
+ arg.setValue(val);
+ mExtra.addPerfettoPointer(arg);
+ return this;
+ }
+
+ /**
+ * Adds a debug arg with key {@code name} and value {@code val}.
+ */
+ public Builder addArg(String name, boolean val) {
+ checkParent();
+ ArgBool arg = mArgBoolCache.get(name.hashCode());
+ if (arg == null || !arg.getName().equals(name)) {
+ arg = new ArgBool(name);
+ mArgBoolCache.put(name.hashCode(), arg);
+ }
+ arg.setValue(val);
+ mExtra.addPerfettoPointer(arg);
+ return this;
+ }
+
+ /**
+ * Adds a debug arg with key {@code name} and value {@code val}.
+ */
+ public Builder addArg(String name, double val) {
+ checkParent();
+ ArgDouble arg = mArgDoubleCache.get(name.hashCode());
+ if (arg == null || !arg.getName().equals(name)) {
+ arg = new ArgDouble(name);
+ mArgDoubleCache.put(name.hashCode(), arg);
+ }
+ arg.setValue(val);
+ mExtra.addPerfettoPointer(arg);
+ return this;
+ }
+
+ /**
+ * Adds a debug arg with key {@code name} and value {@code val}.
+ */
+ public Builder addArg(String name, String val) {
+ checkParent();
+ ArgString arg = mArgStringCache.get(name.hashCode());
+ if (arg == null || !arg.getName().equals(name)) {
+ arg = new ArgString(name);
+ mArgStringCache.put(name.hashCode(), arg);
+ }
+ arg.setValue(val);
+ mExtra.addPerfettoPointer(arg);
+ return this;
+ }
+
+ /**
+ * Adds a flow with {@code id}.
+ */
+ public Builder addFlow(int id) {
+ checkParent();
+ Flow flow = mFlowCache.get(Flow::new);
+ flow.setProcessFlow(id);
+ mExtra.addPerfettoPointer(flow);
+ return this;
+ }
+
+ /**
+ * Adds a terminating flow with {@code id}.
+ */
+ public Builder addTerminatingFlow(int id) {
+ checkParent();
+ Flow flow = mFlowCache.get(Flow::new);
+ flow.setProcessTerminatingFlow(id);
+ mExtra.addPerfettoPointer(flow);
+ return this;
+ }
+
+ /**
+ * Adds the events to a named track instead of the thread track where the
+ * event occurred.
+ */
+ public Builder usingNamedTrack(String name, long parentUuid) {
+ checkParent();
+ NamedTrack track = mNamedTrackCache.get(name.hashCode());
+ if (track == null || !track.getName().equals(name)) {
+ track = new NamedTrack(name, parentUuid);
+ mNamedTrackCache.put(name.hashCode(), track);
+ }
+ mExtra.addPerfettoPointer(track);
+ return this;
+ }
+
+ /**
+ * Adds the events to a counter track instead. This is required for
+ * setting counter values.
+ *
+ */
+ public Builder usingCounterTrack(String name, long parentUuid) {
+ checkParent();
+ CounterTrack track = mCounterTrackCache.get(name.hashCode());
+ if (track == null || !track.getName().equals(name)) {
+ track = new CounterTrack(name, parentUuid);
+ mCounterTrackCache.put(name.hashCode(), track);
+ }
+ mExtra.addPerfettoPointer(track);
+ return this;
+ }
+
+ /**
+ * Sets a long counter value on the event.
+ *
+ */
+ public Builder setCounter(long val) {
+ checkParent();
+ mCounterInt64.setValue(val);
+ mExtra.addPerfettoPointer(mCounterInt64);
+ return this;
+ }
+
+ /**
+ * Sets a double counter value on the event.
+ *
+ */
+ public Builder setCounter(double val) {
+ checkParent();
+ mCounterDouble.setValue(val);
+ mExtra.addPerfettoPointer(mCounterDouble);
+ return this;
+ }
+
+ /**
+ * Adds a proto field with field id {@code id} and value {@code val}.
+ */
+ public Builder addField(long id, long val) {
+ checkContainer();
+ FieldInt64 field = mFieldInt64Cache.get(FieldInt64::new);
+ field.setValue(id, val);
+ mCurrentContainer.addField(field);
+ return this;
+ }
+
+ /**
+ * Adds a proto field with field id {@code id} and value {@code val}.
+ */
+ public Builder addField(long id, double val) {
+ checkContainer();
+ FieldDouble field = mFieldDoubleCache.get(FieldDouble::new);
+ field.setValue(id, val);
+ mCurrentContainer.addField(field);
+ return this;
+ }
+
+ /**
+ * Adds a proto field with field id {@code id} and value {@code val}.
+ */
+ public Builder addField(long id, String val) {
+ checkContainer();
+ FieldString field = mFieldStringCache.get(FieldString::new);
+ field.setValue(id, val);
+ mCurrentContainer.addField(field);
+ return this;
+ }
+
+ /**
+ * Begins a proto field with field
+ * Fields can be added from this point and there must be a corresponding
+ * {@link endProto}.
+ *
+ * The proto field is a singleton and all proto fields get added inside the
+ * one {@link beginProto} and {@link endProto} within the {@link Builder}.
+ */
+ public Builder beginProto() {
+ checkParent();
+ mProto.clearFields();
+ mExtra.addPerfettoPointer(mProto);
+ return mBuilderCache.get(Builder::new).init(this, mProto);
+ }
+
+ /**
+ * Ends a proto field.
+ */
+ public Builder endProto() {
+ if (mParent == null || mCurrentContainer == null) {
+ throw new IllegalStateException("No proto to end");
+ }
+ return mParent;
+ }
+
+ /**
+ * Begins a nested proto field with field id {@code id}.
+ * Fields can be added from this point and there must be a corresponding
+ * {@link endNested}.
+ */
+ public Builder beginNested(long id) {
+ checkContainer();
+ FieldNested field = mFieldNestedCache.get(FieldNested::new);
+ field.setId(id);
+ mCurrentContainer.addField(field);
+ return mBuilderCache.get(Builder::new).init(this, field);
+ }
+
+ /**
+ * Ends a nested proto field.
+ */
+ public Builder endNested() {
+ if (mParent == null || mCurrentContainer == null) {
+ throw new IllegalStateException("No nested field to end");
+ }
+ return mParent;
+ }
+
+ /**
+ * Initializes a {@link Builder}.
+ */
+ public Builder init(Builder parent, FieldContainer container) {
+ mParent = parent;
+ mCurrentContainer = container;
+ mIsBuilt = false;
+
+ if (mParent == null) {
+ if (mExtra.mIsInUse) {
+ throw new IllegalStateException("Cannot create a new builder when another"
+ + " extra is in use");
+ }
+ mExtra.mIsInUse = true;
+ }
+ return this;
+ }
+
+ private void checkState() {
+ if (mIsBuilt) {
+ throw new IllegalStateException(
+ "This builder has already been used. Create a new builder for another event.");
+ }
+ }
+
+ private void checkParent() {
+ checkState();
+ if (mParent != null) {
+ throw new IllegalStateException(
+ "This builder has already been used. Create a new builder for another event.");
+ }
+ }
+
+ private void checkContainer() {
+ checkState();
+ if (mCurrentContainer == null) {
+ throw new IllegalStateException(
+ "Field operations must be within beginProto/endProto block");
+ }
+ }
+ }
+
+ /**
+ * Start a {@link Builder} to build a {@link PerfettoTrackEventExtra}.
+ */
+ public static Builder builder() {
+ return sTrackEventExtra.get().mBuilderCache.get(Builder::new).init(null, null);
+ }
+
+ private final RingBuffer<NamedTrack> mNamedTrackCache =
+ new RingBuffer(DEFAULT_EXTRA_CACHE_SIZE);
+ private final RingBuffer<CounterTrack> mCounterTrackCache =
+ new RingBuffer(DEFAULT_EXTRA_CACHE_SIZE);
+
+ private final RingBuffer<ArgInt64> mArgInt64Cache = new RingBuffer(DEFAULT_EXTRA_CACHE_SIZE);
+ private final RingBuffer<ArgBool> mArgBoolCache = new RingBuffer(DEFAULT_EXTRA_CACHE_SIZE);
+ private final RingBuffer<ArgDouble> mArgDoubleCache = new RingBuffer(DEFAULT_EXTRA_CACHE_SIZE);
+ private final RingBuffer<ArgString> mArgStringCache = new RingBuffer(DEFAULT_EXTRA_CACHE_SIZE);
+
+ private final Pool<FieldInt64> mFieldInt64Cache = new Pool(DEFAULT_EXTRA_CACHE_SIZE);
+ private final Pool<FieldDouble> mFieldDoubleCache = new Pool(DEFAULT_EXTRA_CACHE_SIZE);
+ private final Pool<FieldString> mFieldStringCache = new Pool(DEFAULT_EXTRA_CACHE_SIZE);
+ private final Pool<FieldNested> mFieldNestedCache = new Pool(DEFAULT_EXTRA_CACHE_SIZE);
+ private final Pool<Flow> mFlowCache = new Pool(DEFAULT_EXTRA_CACHE_SIZE);
+ private final Pool<Builder> mBuilderCache = new Pool(DEFAULT_EXTRA_CACHE_SIZE);
+
+ private static final NativeAllocationRegistry sRegistry =
+ NativeAllocationRegistry.createMalloced(
+ PerfettoTrackEventExtra.class.getClassLoader(), native_delete());
+
+ private final long mPtr;
+ private static final String TAG = "PerfettoTrackEventExtra";
+
+ private PerfettoTrackEventExtra() {
+ mPtr = native_init();
+ sRegistry.registerNativeAllocation(this, mPtr);
+ }
+
+ /**
+ * Returns the native pointer.
+ */
+ public long getPtr() {
+ return mPtr;
+ }
+
+ /**
+ * Adds a pointer representing a track event parameter.
+ */
+ public void addPerfettoPointer(PerfettoPointer extra) {
+ native_add_arg(mPtr, extra.getPtr());
+ }
+
+ /**
+ * Resets the track event extra.
+ */
+ public void reset() {
+ native_clear_args(mPtr);
+ mIsInUse = false;
+ }
+
+ private CounterInt64 getCounterInt64() {
+ if (mCounterInt64 == null) {
+ mCounterInt64 = new CounterInt64();
+ }
+ return mCounterInt64;
+ }
+
+ private CounterDouble getCounterDouble() {
+ if (mCounterDouble == null) {
+ mCounterDouble = new CounterDouble();
+ }
+ return mCounterDouble;
+ }
+
+ private Proto getProto() {
+ if (mProto == null) {
+ mProto = new Proto();
+ }
+ return mProto;
+ }
+
+ private static final class Flow implements PerfettoPointer {
+ private static final NativeAllocationRegistry sRegistry =
+ NativeAllocationRegistry.createMalloced(
+ Flow.class.getClassLoader(), native_delete());
+
+ private final long mPtr;
+ private final long mExtraPtr;
+
+ Flow() {
+ mPtr = native_init();
+ mExtraPtr = native_get_extra_ptr(mPtr);
+ sRegistry.registerNativeAllocation(this, mPtr);
+ }
+
+ public void setProcessFlow(long type) {
+ native_set_process_flow(mPtr, type);
+ }
+
+ public void setProcessTerminatingFlow(long id) {
+ native_set_process_terminating_flow(mPtr, id);
+ }
+
+ @Override
+ public long getPtr() {
+ return mExtraPtr;
+ }
+
+ @CriticalNative
+ private static native long native_init();
+ @CriticalNative
+ private static native long native_delete();
+ @CriticalNative
+ private static native void native_set_process_flow(long ptr, long type);
+ @CriticalNative
+ private static native void native_set_process_terminating_flow(long ptr, long id);
+ @CriticalNative
+ private static native long native_get_extra_ptr(long ptr);
+ }
+
+ private static class NamedTrack implements PerfettoPointer {
+ private static final NativeAllocationRegistry sRegistry =
+ NativeAllocationRegistry.createMalloced(
+ NamedTrack.class.getClassLoader(), native_delete());
+
+ private final long mPtr;
+ private final long mExtraPtr;
+ private final String mName;
+
+ NamedTrack(String name, long parentUuid) {
+ mPtr = native_init(sNamedTrackId.incrementAndGet(), name, parentUuid);
+ mExtraPtr = native_get_extra_ptr(mPtr);
+ mName = name;
+ sRegistry.registerNativeAllocation(this, mPtr);
+ }
+
+ @Override
+ public long getPtr() {
+ return mExtraPtr;
+ }
+
+ public String getName() {
+ return mName;
+ }
+
+ @FastNative
+ private static native long native_init(long id, String name, long parentUuid);
+ @CriticalNative
+ private static native long native_delete();
+ @CriticalNative
+ private static native long native_get_extra_ptr(long ptr);
+ }
+
+ private static final class CounterTrack implements PerfettoPointer {
+ private static final NativeAllocationRegistry sRegistry =
+ NativeAllocationRegistry.createMalloced(
+ CounterTrack.class.getClassLoader(), native_delete());
+
+ private final long mPtr;
+ private final long mExtraPtr;
+ private final String mName;
+
+ CounterTrack(String name, long parentUuid) {
+ mPtr = native_init(name, parentUuid);
+ mExtraPtr = native_get_extra_ptr(mPtr);
+ mName = name;
+ sRegistry.registerNativeAllocation(this, mPtr);
+ }
+
+ @Override
+ public long getPtr() {
+ return mExtraPtr;
+ }
+
+ public String getName() {
+ return mName;
+ }
+
+ @FastNative
+ private static native long native_init(String name, long parentUuid);
+ @CriticalNative
+ private static native long native_delete();
+ @CriticalNative
+ private static native long native_get_extra_ptr(long ptr);
+ }
+
+ private static final class CounterInt64 implements PerfettoPointer {
+ private static final NativeAllocationRegistry sRegistry =
+ NativeAllocationRegistry.createMalloced(
+ CounterInt64.class.getClassLoader(), native_delete());
+
+ private final long mPtr;
+ private final long mExtraPtr;
+
+ CounterInt64() {
+ mPtr = native_init();
+ mExtraPtr = native_get_extra_ptr(mPtr);
+ sRegistry.registerNativeAllocation(this, mPtr);
+ }
+
+ @Override
+ public long getPtr() {
+ return mExtraPtr;
+ }
+
+ public void setValue(long value) {
+ native_set_value(mPtr, value);
+ }
+
+ @CriticalNative
+ private static native long native_init();
+ @CriticalNative
+ private static native long native_delete();
+ @CriticalNative
+ private static native void native_set_value(long ptr, long value);
+ @CriticalNative
+ private static native long native_get_extra_ptr(long ptr);
+ }
+
+ private static final class CounterDouble implements PerfettoPointer {
+ private static final NativeAllocationRegistry sRegistry =
+ NativeAllocationRegistry.createMalloced(
+ CounterDouble.class.getClassLoader(), native_delete());
+
+ private final long mPtr;
+ private final long mExtraPtr;
+
+ CounterDouble() {
+ mPtr = native_init();
+ mExtraPtr = native_get_extra_ptr(mPtr);
+ sRegistry.registerNativeAllocation(this, mPtr);
+ }
+
+ @Override
+ public long getPtr() {
+ return mExtraPtr;
+ }
+
+ public void setValue(double value) {
+ native_set_value(mPtr, value);
+ }
+
+ @CriticalNative
+ private static native long native_init();
+ @CriticalNative
+ private static native long native_delete();
+ @CriticalNative
+ private static native void native_set_value(long ptr, double value);
+ @CriticalNative
+ private static native long native_get_extra_ptr(long ptr);
+ }
+
+ private static final class ArgInt64 implements PerfettoPointer {
+ private static final NativeAllocationRegistry sRegistry =
+ NativeAllocationRegistry.createMalloced(
+ ArgInt64.class.getClassLoader(), native_delete());
+
+ // Private pointer holding Perfetto object with metadata
+ private final long mPtr;
+
+ // Public pointer to Perfetto object itself
+ private final long mExtraPtr;
+
+ private final String mName;
+
+ ArgInt64(String name) {
+ mPtr = native_init(name);
+ mExtraPtr = native_get_extra_ptr(mPtr);
+ mName = name;
+ sRegistry.registerNativeAllocation(this, mPtr);
+ }
+
+ @Override
+ public long getPtr() {
+ return mExtraPtr;
+ }
+
+ public String getName() {
+ return mName;
+ }
+
+ public void setValue(long val) {
+ native_set_value(mPtr, val);
+ }
+
+ @FastNative
+ private static native long native_init(String name);
+ @CriticalNative
+ private static native long native_delete();
+ @CriticalNative
+ private static native long native_get_extra_ptr(long ptr);
+ @CriticalNative
+ private static native void native_set_value(long ptr, long val);
+ }
+
+ private static final class ArgBool implements PerfettoPointer {
+ private static final NativeAllocationRegistry sRegistry =
+ NativeAllocationRegistry.createMalloced(
+ ArgBool.class.getClassLoader(), native_delete());
+
+ // Private pointer holding Perfetto object with metadata
+ private final long mPtr;
+
+ // Public pointer to Perfetto object itself
+ private final long mExtraPtr;
+
+ private final String mName;
+
+ ArgBool(String name) {
+ mPtr = native_init(name);
+ mExtraPtr = native_get_extra_ptr(mPtr);
+ mName = name;
+ sRegistry.registerNativeAllocation(this, mPtr);
+ }
+
+ @Override
+ public long getPtr() {
+ return mExtraPtr;
+ }
+
+ public String getName() {
+ return mName;
+ }
+
+ public void setValue(boolean val) {
+ native_set_value(mPtr, val);
+ }
+
+ @FastNative
+ private static native long native_init(String name);
+ @CriticalNative
+ private static native long native_delete();
+ @CriticalNative
+ private static native long native_get_extra_ptr(long ptr);
+ @CriticalNative
+ private static native void native_set_value(long ptr, boolean val);
+ }
+
+ private static final class ArgDouble implements PerfettoPointer {
+ private static final NativeAllocationRegistry sRegistry =
+ NativeAllocationRegistry.createMalloced(
+ ArgDouble.class.getClassLoader(), native_delete());
+
+ // Private pointer holding Perfetto object with metadata
+ private final long mPtr;
+
+ // Public pointer to Perfetto object itself
+ private final long mExtraPtr;
+
+ private final String mName;
+
+ ArgDouble(String name) {
+ mPtr = native_init(name);
+ mExtraPtr = native_get_extra_ptr(mPtr);
+ mName = name;
+ sRegistry.registerNativeAllocation(this, mPtr);
+ }
+
+ @Override
+ public long getPtr() {
+ return mExtraPtr;
+ }
+
+ public String getName() {
+ return mName;
+ }
+
+ public void setValue(double val) {
+ native_set_value(mPtr, val);
+ }
+
+ @FastNative
+ private static native long native_init(String name);
+ @CriticalNative
+ private static native long native_delete();
+ @CriticalNative
+ private static native long native_get_extra_ptr(long ptr);
+ @CriticalNative
+ private static native void native_set_value(long ptr, double val);
+ }
+
+ private static final class ArgString implements PerfettoPointer {
+ private static final NativeAllocationRegistry sRegistry =
+ NativeAllocationRegistry.createMalloced(
+ ArgString.class.getClassLoader(), native_delete());
+
+ // Private pointer holding Perfetto object with metadata
+ private final long mPtr;
+
+ // Public pointer to Perfetto object itself
+ private final long mExtraPtr;
+
+ private final String mName;
+
+ ArgString(String name) {
+ mPtr = native_init(name);
+ mExtraPtr = native_get_extra_ptr(mPtr);
+ mName = name;
+ sRegistry.registerNativeAllocation(this, mPtr);
+ }
+
+ @Override
+ public long getPtr() {
+ return mExtraPtr;
+ }
+
+ public String getName() {
+ return mName;
+ }
+
+ public void setValue(String val) {
+ native_set_value(mPtr, val);
+ }
+
+ @FastNative
+ private static native long native_init(String name);
+ @CriticalNative
+ private static native long native_delete();
+ @CriticalNative
+ private static native long native_get_extra_ptr(long ptr);
+ @FastNative
+ private static native void native_set_value(long ptr, String val);
+ }
+
+ private static final class Proto implements PerfettoPointer, FieldContainer {
+ private static final NativeAllocationRegistry sRegistry =
+ NativeAllocationRegistry.createMalloced(
+ Proto.class.getClassLoader(), native_delete());
+
+ // Private pointer holding Perfetto object with metadata
+ private final long mPtr;
+
+ // Public pointer to Perfetto object itself
+ private final long mExtraPtr;
+
+ Proto() {
+ mPtr = native_init();
+ mExtraPtr = native_get_extra_ptr(mPtr);
+ sRegistry.registerNativeAllocation(this, mPtr);
+ }
+
+ @Override
+ public long getPtr() {
+ return mExtraPtr;
+ }
+
+ @Override
+ public void addField(PerfettoPointer field) {
+ native_add_field(mPtr, field.getPtr());
+ }
+
+ public void clearFields() {
+ native_clear_fields(mPtr);
+ }
+
+ @CriticalNative
+ private static native long native_init();
+ @CriticalNative
+ private static native long native_delete();
+ @CriticalNative
+ private static native long native_get_extra_ptr(long ptr);
+ @CriticalNative
+ private static native void native_add_field(long ptr, long extraPtr);
+ @CriticalNative
+ private static native void native_clear_fields(long ptr);
+ }
+
+ private static final class FieldInt64 implements PerfettoPointer {
+ private static final NativeAllocationRegistry sRegistry =
+ NativeAllocationRegistry.createMalloced(
+ FieldInt64.class.getClassLoader(), native_delete());
+
+ // Private pointer holding Perfetto object with metadata
+ private final long mPtr;
+
+ // Public pointer to Perfetto object itself
+ private final long mFieldPtr;
+
+ FieldInt64() {
+ mPtr = native_init();
+ mFieldPtr = native_get_extra_ptr(mPtr);
+ sRegistry.registerNativeAllocation(this, mPtr);
+ }
+
+ @Override
+ public long getPtr() {
+ return mFieldPtr;
+ }
+
+ public void setValue(long id, long val) {
+ native_set_value(mPtr, id, val);
+ }
+
+ @CriticalNative
+ private static native long native_init();
+ @CriticalNative
+ private static native long native_delete();
+ @CriticalNative
+ private static native long native_get_extra_ptr(long ptr);
+ @CriticalNative
+ private static native void native_set_value(long ptr, long id, long val);
+ }
+
+ private static final class FieldDouble implements PerfettoPointer {
+ private static final NativeAllocationRegistry sRegistry =
+ NativeAllocationRegistry.createMalloced(
+ FieldDouble.class.getClassLoader(), native_delete());
+
+ // Private pointer holding Perfetto object with metadata
+ private final long mPtr;
+
+ // Public pointer to Perfetto object itself
+ private final long mFieldPtr;
+
+ FieldDouble() {
+ mPtr = native_init();
+ mFieldPtr = native_get_extra_ptr(mPtr);
+ sRegistry.registerNativeAllocation(this, mPtr);
+ }
+
+ @Override
+ public long getPtr() {
+ return mFieldPtr;
+ }
+
+ public void setValue(long id, double val) {
+ native_set_value(mPtr, id, val);
+ }
+
+ @CriticalNative
+ private static native long native_init();
+ @CriticalNative
+ private static native long native_delete();
+ @CriticalNative
+ private static native long native_get_extra_ptr(long ptr);
+ @CriticalNative
+ private static native void native_set_value(long ptr, long id, double val);
+ }
+
+ private static final class FieldString implements PerfettoPointer {
+ private static final NativeAllocationRegistry sRegistry =
+ NativeAllocationRegistry.createMalloced(
+ FieldString.class.getClassLoader(), native_delete());
+
+ // Private pointer holding Perfetto object with metadata
+ private final long mPtr;
+
+ // Public pointer to Perfetto object itself
+ private final long mFieldPtr;
+
+ FieldString() {
+ mPtr = native_init();
+ mFieldPtr = native_get_extra_ptr(mPtr);
+ sRegistry.registerNativeAllocation(this, mPtr);
+ }
+
+ @Override
+ public long getPtr() {
+ return mFieldPtr;
+ }
+
+ public void setValue(long id, String val) {
+ native_set_value(mPtr, id, val);
+ }
+
+ @CriticalNative
+ private static native long native_init();
+ @CriticalNative
+ private static native long native_delete();
+ @CriticalNative
+ private static native long native_get_extra_ptr(long ptr);
+ @FastNative
+ private static native void native_set_value(long ptr, long id, String val);
+ }
+
+ private static final class FieldNested implements PerfettoPointer, FieldContainer {
+ private static final NativeAllocationRegistry sRegistry =
+ NativeAllocationRegistry.createMalloced(
+ FieldNested.class.getClassLoader(), native_delete());
+
+ // Private pointer holding Perfetto object with metadata
+ private final long mPtr;
+
+ // Public pointer to Perfetto object itself
+ private final long mFieldPtr;
+
+ FieldNested() {
+ mPtr = native_init();
+ mFieldPtr = native_get_extra_ptr(mPtr);
+ sRegistry.registerNativeAllocation(this, mPtr);
+ }
+
+ @Override
+ public long getPtr() {
+ return mFieldPtr;
+ }
+
+ @Override
+ public void addField(PerfettoPointer field) {
+ native_add_field(mPtr, field.getPtr());
+ }
+
+ public void setId(long id) {
+ native_set_id(mPtr, id);
+ }
+
+ @CriticalNative
+ private static native long native_init();
+ @CriticalNative
+ private static native long native_delete();
+ @CriticalNative
+ private static native long native_get_extra_ptr(long ptr);
+ @CriticalNative
+ private static native void native_add_field(long ptr, long extraPtr);
+ @CriticalNative
+ private static native void native_set_id(long ptr, long id);
+ }
+
+ @CriticalNative
+ private static native long native_init();
+ @CriticalNative
+ private static native long native_delete();
+ @CriticalNative
+ private static native void native_add_arg(long ptr, long extraPtr);
+ @CriticalNative
+ private static native void native_clear_args(long ptr);
+}
diff --git a/core/java/android/os/flags.aconfig b/core/java/android/os/flags.aconfig
index 2a467386569d..e24f08b7dfe5 100644
--- a/core/java/android/os/flags.aconfig
+++ b/core/java/android/os/flags.aconfig
@@ -340,6 +340,13 @@ flag {
flag {
namespace: "system_performance"
+ name: "perfetto_sdk_tracing_v2"
+ description: "Tracing using Perfetto SDK API."
+ bug: "303199244"
+}
+
+flag {
+ namespace: "system_performance"
name: "telemetry_apis_framework_initialization"
is_exported: true
description: "Control framework initialization APIs of telemetry APIs feature."
diff --git a/core/java/android/provider/BlockedNumbersManager.java b/core/java/android/provider/BlockedNumbersManager.java
index aee396dec5bc..a0dc176c884b 100644
--- a/core/java/android/provider/BlockedNumbersManager.java
+++ b/core/java/android/provider/BlockedNumbersManager.java
@@ -357,7 +357,7 @@ public final class BlockedNumbersManager {
*/
private long mUntilTimestampMillis;
- public BlockSuppressionStatus(boolean isSuppressed, long untilTimestampMillis) {
+ BlockSuppressionStatus(boolean isSuppressed, long untilTimestampMillis) {
this.mIsSuppressed = isSuppressed;
this.mUntilTimestampMillis = untilTimestampMillis;
}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 6898fcef23ab..c1dd36101fc8 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -5723,6 +5723,7 @@ public final class Settings {
* The value 1 - enable, 0 - disable
* @hide
*/
+ @Readable
public static final String NOTIFICATION_COOLDOWN_ENABLED =
"notification_cooldown_enabled";
diff --git a/core/java/android/security/intrusiondetection/IntrusionDetectionEvent.java b/core/java/android/security/intrusiondetection/IntrusionDetectionEvent.java
index b479ca7a0b6f..76ee4480c222 100644
--- a/core/java/android/security/intrusiondetection/IntrusionDetectionEvent.java
+++ b/core/java/android/security/intrusiondetection/IntrusionDetectionEvent.java
@@ -91,12 +91,12 @@ public final class IntrusionDetectionEvent implements Parcelable {
};
/**
- * Creates an IntrusionDetectionEvent object with a
- * {@link SecurityEvent} object as the event source.
+ * Creates an IntrusionDetectionEvent object with a {@link SecurityEvent} object as the event
+ * source.
*
* @param securityEvent The SecurityEvent object.
*/
- public IntrusionDetectionEvent(@NonNull SecurityEvent securityEvent) {
+ private IntrusionDetectionEvent(@NonNull SecurityEvent securityEvent) {
mType = SECURITY_EVENT;
mSecurityEvent = securityEvent;
mNetworkEventDns = null;
@@ -104,12 +104,11 @@ public final class IntrusionDetectionEvent implements Parcelable {
}
/**
- * Creates an IntrusionDetectionEvent object with a
- * {@link DnsEvent} object as the event source.
+ * Creates an IntrusionDetectionEvent object with a {@link DnsEvent} object as the event source.
*
* @param dnsEvent The DnsEvent object.
*/
- public IntrusionDetectionEvent(@NonNull DnsEvent dnsEvent) {
+ private IntrusionDetectionEvent(@NonNull DnsEvent dnsEvent) {
mType = NETWORK_EVENT_DNS;
mNetworkEventDns = dnsEvent;
mSecurityEvent = null;
@@ -117,18 +116,52 @@ public final class IntrusionDetectionEvent implements Parcelable {
}
/**
- * Creates an IntrusionDetectionEvent object with a
- * {@link ConnectEvent} object as the event source.
+ * Creates an IntrusionDetectionEvent object with a {@link ConnectEvent} object as the event
+ * source.
*
* @param connectEvent The ConnectEvent object.
*/
- public IntrusionDetectionEvent(@NonNull ConnectEvent connectEvent) {
+ private IntrusionDetectionEvent(@NonNull ConnectEvent connectEvent) {
mType = NETWORK_EVENT_CONNECT;
mNetworkEventConnect = connectEvent;
mSecurityEvent = null;
mNetworkEventDns = null;
}
+ /**
+ * Creates an IntrusionDetectionEvent object with a {@link SecurityEvent} object as the event
+ * source.
+ *
+ * @param securityEvent The SecurityEvent object.
+ */
+ @NonNull
+ public static IntrusionDetectionEvent createForSecurityEvent(
+ @NonNull SecurityEvent securityEvent) {
+ return new IntrusionDetectionEvent(securityEvent);
+ }
+
+ /**
+ * Creates an IntrusionDetectionEvent object with a {@link DnsEvent} object as the event source.
+ *
+ * @param dnsEvent The DnsEvent object.
+ */
+ @NonNull
+ public static IntrusionDetectionEvent createForDnsEvent(@NonNull DnsEvent dnsEvent) {
+ return new IntrusionDetectionEvent(dnsEvent);
+ }
+
+ /**
+ * Creates an IntrusionDetectionEvent object with a {@link ConnectEvent} object as the event
+ * source.
+ *
+ * @param connectEvent The ConnectEvent object.
+ */
+ @NonNull
+ public static IntrusionDetectionEvent createForConnectEvent(
+ @NonNull ConnectEvent connectEvent) {
+ return new IntrusionDetectionEvent(connectEvent);
+ }
+
private IntrusionDetectionEvent(@NonNull Parcel in) {
mType = in.readInt();
switch (mType) {
diff --git a/core/java/android/security/intrusiondetection/IntrusionDetectionEventTransport.java b/core/java/android/security/intrusiondetection/IntrusionDetectionEventTransport.java
index 2e2d0f7f2dd2..4755eaf8542c 100644
--- a/core/java/android/security/intrusiondetection/IntrusionDetectionEventTransport.java
+++ b/core/java/android/security/intrusiondetection/IntrusionDetectionEventTransport.java
@@ -44,7 +44,8 @@ import java.util.List;
* which will then be delivered to the specified location.
*
* Usage:
- * 1. Obtain an instance of {@link IntrusionDetectionEventTransport} using the constructor.
+ * 1. Obtain an instance of {@link IntrusionDetectionEventTransport} using the appropriate
+ * creation method.
* 2. Initialize the transport by calling {@link #initialize()}.
* 3. Add events to the transport queue using {@link #addData(List)}.
* 4. Release the transport when finished by calling {@link #release()}.
diff --git a/core/java/android/security/intrusiondetection/IntrusionDetectionManager.java b/core/java/android/security/intrusiondetection/IntrusionDetectionManager.java
index e2463384d0c8..8a7ec0d61f52 100644
--- a/core/java/android/security/intrusiondetection/IntrusionDetectionManager.java
+++ b/core/java/android/security/intrusiondetection/IntrusionDetectionManager.java
@@ -230,7 +230,7 @@ public class IntrusionDetectionManager {
/**
* Disable intrusion detection.
* If successful, IntrusionDetectionService will transition to {@link #STATE_DISABLED}.
- * <p>
+ *
* When intrusion detection is disabled, device events will no longer be collected.
* Any events that have been collected but not yet sent to IntrusionDetectionEventTransport
* will be transferred as a final batch.
diff --git a/core/java/android/security/net/config/NetworkSecurityTrustManager.java b/core/java/android/security/net/config/NetworkSecurityTrustManager.java
index d9cc82a77a85..029b674b6be1 100644
--- a/core/java/android/security/net/config/NetworkSecurityTrustManager.java
+++ b/core/java/android/security/net/config/NetworkSecurityTrustManager.java
@@ -16,16 +16,17 @@
package android.security.net.config;
+import android.util.ArrayMap;
+
import com.android.org.conscrypt.TrustManagerImpl;
-import android.util.ArrayMap;
import java.io.IOException;
import java.net.Socket;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.MessageDigest;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -105,7 +106,7 @@ public class NetworkSecurityTrustManager extends X509ExtendedTrustManager {
/**
* Hostname aware version of {@link #checkServerTrusted(X509Certificate[], String)}.
- * This interface is used by conscrypt and android.net.http.X509TrustManagerExtensions do not
+ * This interface is used by Conscrypt and android.net.http.X509TrustManagerExtensions do not
* modify without modifying those callers.
*/
public List<X509Certificate> checkServerTrusted(X509Certificate[] certs, String authType,
@@ -115,6 +116,19 @@ public class NetworkSecurityTrustManager extends X509ExtendedTrustManager {
return trustedChain;
}
+ /**
+ * This interface is used by Conscrypt and android.net.http.X509TrustManagerExtensions do not
+ * modify without modifying those callers.
+ */
+ public List<X509Certificate> checkServerTrusted(X509Certificate[] certs,
+ byte[] ocspData, byte[] tlsSctData, String authType,
+ String host) throws CertificateException {
+ List<X509Certificate> trustedChain = mDelegate.checkServerTrusted(
+ certs, ocspData, tlsSctData, authType, host);
+ checkPins(trustedChain);
+ return trustedChain;
+ }
+
private void checkPins(List<X509Certificate> chain) throws CertificateException {
PinSet pinSet = mNetworkSecurityConfig.getPins();
if (pinSet.pins.isEmpty()
diff --git a/core/java/android/security/net/config/OWNERS b/core/java/android/security/net/config/OWNERS
index 85ce3c63f18b..e945ff98a96f 100644
--- a/core/java/android/security/net/config/OWNERS
+++ b/core/java/android/security/net/config/OWNERS
@@ -1,5 +1,6 @@
-# Bug component: 36824
-set noparent
+# Bug component: 1479456
-cbrubaker@google.com
+bessiej@google.com
brambonne@google.com
+sandrom@google.com
+tweek@google.com
diff --git a/core/java/android/security/net/config/RootTrustManager.java b/core/java/android/security/net/config/RootTrustManager.java
index 58dc4ba8df21..a1bdec5280db 100644
--- a/core/java/android/security/net/config/RootTrustManager.java
+++ b/core/java/android/security/net/config/RootTrustManager.java
@@ -120,7 +120,7 @@ public class RootTrustManager extends X509ExtendedTrustManager {
/**
* Hostname aware version of {@link #checkServerTrusted(X509Certificate[], String)}.
- * This interface is used by conscrypt and android.net.http.X509TrustManagerExtensions do not
+ * This interface is used by Conscrypt and android.net.http.X509TrustManagerExtensions do not
* modify without modifying those callers.
*/
@UnsupportedAppUsage
@@ -134,6 +134,22 @@ public class RootTrustManager extends X509ExtendedTrustManager {
return config.getTrustManager().checkServerTrusted(certs, authType, hostname);
}
+ /**
+ * This interface is used by Conscrypt and android.net.http.X509TrustManagerExtensions do not
+ * modify without modifying those callers.
+ */
+ public List<X509Certificate> checkServerTrusted(X509Certificate[] certs,
+ byte[] ocspData, byte[] tlsSctData, String authType,
+ String hostname) throws CertificateException {
+ if (hostname == null && mConfig.hasPerDomainConfigs()) {
+ throw new CertificateException(
+ "Domain specific configurations require that the hostname be provided");
+ }
+ NetworkSecurityConfig config = mConfig.getConfigForHostname(hostname);
+ return config.getTrustManager().checkServerTrusted(
+ certs, ocspData, tlsSctData, authType, hostname);
+ }
+
@Override
public X509Certificate[] getAcceptedIssuers() {
// getAcceptedIssuers is meant to be used to determine which trust anchors the server will
diff --git a/core/java/android/view/Choreographer.java b/core/java/android/view/Choreographer.java
index 6c50b5f945a5..992790e092d1 100644
--- a/core/java/android/view/Choreographer.java
+++ b/core/java/android/view/Choreographer.java
@@ -240,6 +240,7 @@ public final class Choreographer {
* stuffing events.
*/
public void reset() {
+ isStuffed.set(false);
isRecovering = false;
numberWaitsForNextVsync = 0;
}
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 072a037aa84a..2b4087439323 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -722,6 +722,9 @@ interface IWindowManager
*/
void setDisplayImePolicy(int displayId, int imePolicy);
+ /** Called when the expanded state of notification shade is changed. */
+ void onNotificationShadeExpanded(IBinder token, boolean expanded);
+
/**
* Waits until input information has been sent from WindowManager to native InputManager,
* optionally waiting for animations to complete.
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index 38e4e2760d25..ad43c7b7cdc3 100644
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -2590,6 +2590,32 @@ public class KeyEvent extends InputEvent implements Parcelable {
return keyCode == KeyEvent.KEYCODE_ALT_LEFT || keyCode == KeyEvent.KEYCODE_ALT_RIGHT;
}
+ /**
+ * Returns whether the key code passed as argument is allowed for visible background users.
+ * Visible background users are expected to run on secondary displays with certain limitations
+ * on system keys.
+ *
+ * @hide
+ */
+ public static boolean isVisibleBackgroundUserAllowedKey(int keyCode) {
+ switch (keyCode) {
+ case KeyEvent.KEYCODE_POWER:
+ case KeyEvent.KEYCODE_SLEEP:
+ case KeyEvent.KEYCODE_WAKEUP:
+ case KeyEvent.KEYCODE_CALL:
+ case KeyEvent.KEYCODE_ENDCALL:
+ case KeyEvent.KEYCODE_ASSIST:
+ case KeyEvent.KEYCODE_VOICE_ASSIST:
+ case KeyEvent.KEYCODE_MUTE:
+ case KeyEvent.KEYCODE_VOLUME_MUTE:
+ case KeyEvent.KEYCODE_RECENT_APPS:
+ case KeyEvent.KEYCODE_APP_SWITCH:
+ case KeyEvent.KEYCODE_NOTIFICATION:
+ return false;
+ }
+ return true;
+ }
+
/** {@inheritDoc} */
@Override
public final int getDeviceId() {
diff --git a/core/java/android/window/flags/lse_desktop_experience.aconfig b/core/java/android/window/flags/lse_desktop_experience.aconfig
index 3b77b1f65dac..b5582ff9d9be 100644
--- a/core/java/android/window/flags/lse_desktop_experience.aconfig
+++ b/core/java/android/window/flags/lse_desktop_experience.aconfig
@@ -485,6 +485,13 @@ flag {
}
flag {
+ name: "enable_multiple_desktops_backend"
+ namespace: "lse_desktop_experience"
+ description: "Enable multiple desktop sessions for desktop windowing (backend)."
+ bug: "362720497"
+}
+
+flag {
name: "enable_connected_displays_dnd"
namespace: "lse_desktop_experience"
description: "Enable drag-and-drop between connected displays."
diff --git a/core/java/android/window/flags/windowing_frontend.aconfig b/core/java/android/window/flags/windowing_frontend.aconfig
index c1ed51264e23..f346544780b3 100644
--- a/core/java/android/window/flags/windowing_frontend.aconfig
+++ b/core/java/android/window/flags/windowing_frontend.aconfig
@@ -235,6 +235,17 @@ flag {
}
flag {
+ name: "scheduling_for_notification_shade"
+ namespace: "windowing_frontend"
+ description: "Demote top-app when notification shade is expanded"
+ bug: "362467878"
+ is_fixed_read_only: true
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
name: "release_snapshot_aggressively"
namespace: "windowing_frontend"
description: "Actively release task snapshot memory"
diff --git a/core/java/com/android/internal/util/LatencyTracker.java b/core/java/com/android/internal/util/LatencyTracker.java
index d49afa735646..f443b0adcb9d 100644
--- a/core/java/com/android/internal/util/LatencyTracker.java
+++ b/core/java/com/android/internal/util/LatencyTracker.java
@@ -38,6 +38,7 @@ import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPOR
import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_ROTATE_SCREEN;
import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_ROTATE_SCREEN_CAMERA_CHECK;
import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_ROTATE_SCREEN_SENSOR;
+import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_SHADE_WINDOW_DISPLAY_CHANGE;
import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_SHOW_BACK_ARROW;
import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_SHOW_SELECTION_TOOLBAR;
import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_SHOW_VOICE_INTERACTION;
@@ -257,6 +258,14 @@ public class LatencyTracker {
*/
public static final int ACTION_KEYGUARD_FACE_UNLOCK_TO_HOME = 28;
+ /**
+ * Time it takes for the shade window to move display after a user interaction.
+ * <p>
+ * This starts when the user does an interaction that triggers the window reparenting, and
+ * finishes after the first doFrame done with the new display configuration.
+ */
+ public static final int ACTION_SHADE_WINDOW_DISPLAY_CHANGE = 29;
+
private static final int[] ACTIONS_ALL = {
ACTION_EXPAND_PANEL,
ACTION_TOGGLE_RECENTS,
@@ -287,6 +296,7 @@ public class LatencyTracker {
ACTION_NOTIFICATIONS_HIDDEN_FOR_MEASURE,
ACTION_NOTIFICATIONS_HIDDEN_FOR_MEASURE_WITH_SHADE_OPEN,
ACTION_KEYGUARD_FACE_UNLOCK_TO_HOME,
+ ACTION_SHADE_WINDOW_DISPLAY_CHANGE,
};
/** @hide */
@@ -320,6 +330,7 @@ public class LatencyTracker {
ACTION_NOTIFICATIONS_HIDDEN_FOR_MEASURE,
ACTION_NOTIFICATIONS_HIDDEN_FOR_MEASURE_WITH_SHADE_OPEN,
ACTION_KEYGUARD_FACE_UNLOCK_TO_HOME,
+ ACTION_SHADE_WINDOW_DISPLAY_CHANGE,
})
@Retention(RetentionPolicy.SOURCE)
public @interface Action {
@@ -356,6 +367,7 @@ public class LatencyTracker {
UIACTION_LATENCY_REPORTED__ACTION__ACTION_NOTIFICATIONS_HIDDEN_FOR_MEASURE,
UIACTION_LATENCY_REPORTED__ACTION__ACTION_NOTIFICATIONS_HIDDEN_FOR_MEASURE_WITH_SHADE_OPEN,
UIACTION_LATENCY_REPORTED__ACTION__ACTION_KEYGUARD_FACE_UNLOCK_TO_HOME,
+ UIACTION_LATENCY_REPORTED__ACTION__ACTION_SHADE_WINDOW_DISPLAY_CHANGE,
};
private final Object mLock = new Object();
@@ -554,6 +566,8 @@ public class LatencyTracker {
return "ACTION_NOTIFICATIONS_HIDDEN_FOR_MEASURE_WITH_SHADE_OPEN";
case UIACTION_LATENCY_REPORTED__ACTION__ACTION_KEYGUARD_FACE_UNLOCK_TO_HOME:
return "ACTION_KEYGUARD_FACE_UNLOCK_TO_HOME";
+ case UIACTION_LATENCY_REPORTED__ACTION__ACTION_SHADE_WINDOW_DISPLAY_CHANGE:
+ return "ACTION_SHADE_WINDOW_DISPLAY_CHANGE";
default:
throw new IllegalArgumentException("Invalid action");
}
diff --git a/core/java/com/android/internal/widget/remotecompose/accessibility/PlatformRemoteComposeTouchHelper.java b/core/java/com/android/internal/widget/remotecompose/accessibility/PlatformRemoteComposeTouchHelper.java
index 39a2ab3010ac..43118a0800fb 100644
--- a/core/java/com/android/internal/widget/remotecompose/accessibility/PlatformRemoteComposeTouchHelper.java
+++ b/core/java/com/android/internal/widget/remotecompose/accessibility/PlatformRemoteComposeTouchHelper.java
@@ -30,7 +30,7 @@ import com.android.internal.widget.ExploreByTouchHelper;
import com.android.internal.widget.remotecompose.core.CoreDocument;
import com.android.internal.widget.remotecompose.core.operations.layout.Component;
import com.android.internal.widget.remotecompose.core.semantics.AccessibilitySemantics;
-import com.android.internal.widget.remotecompose.core.semantics.CoreSemantics.Mode;
+import com.android.internal.widget.remotecompose.core.semantics.AccessibleComponent.Mode;
import java.util.HashSet;
import java.util.List;
diff --git a/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java b/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java
index 60767ed9eb00..fb560a568a9c 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java
@@ -62,7 +62,7 @@ public class CoreDocument {
// We also keep a more fine-grained BUILD number, exposed as
// ID_API_LEVEL = DOCUMENT_API_LEVEL + BUILD
- static final float BUILD = 0.0f;
+ static final float BUILD = 0.1f;
@NonNull ArrayList<Operation> mOperations = new ArrayList<>();
@@ -123,6 +123,11 @@ public class CoreDocument {
return mWidth;
}
+ /**
+ * Set the viewport width of the document
+ *
+ * @param width document width
+ */
public void setWidth(int width) {
this.mWidth = width;
mRemoteComposeState.setWindowWidth(width);
@@ -132,6 +137,11 @@ public class CoreDocument {
return mHeight;
}
+ /**
+ * Set the viewport height of the document
+ *
+ * @param height document height
+ */
public void setHeight(int height) {
this.mHeight = height;
mRemoteComposeState.setWindowHeight(height);
@@ -395,6 +405,11 @@ public class CoreDocument {
// ============== Haptic support ==================
public interface HapticEngine {
+ /**
+ * Implements a haptic effect
+ *
+ * @param type the type of effect
+ */
void haptic(int type);
}
@@ -404,6 +419,11 @@ public class CoreDocument {
mHapticEngine = engine;
}
+ /**
+ * Execute an haptic command
+ *
+ * @param type the type of haptic pre-defined effect
+ */
public void haptic(int type) {
if (mHapticEngine != null) {
mHapticEngine.haptic(type);
@@ -412,12 +432,23 @@ public class CoreDocument {
// ============== Haptic support ==================
- public void appliedTouchOperation(Component operation) {
- mAppliedTouchOperations.add(operation);
+ /**
+ * To signal that the given component will apply the touch operation
+ *
+ * @param component the component applying the touch
+ */
+ public void appliedTouchOperation(Component component) {
+ mAppliedTouchOperations.add(component);
}
/** Callback interface for host actions */
public interface ActionCallback {
+ /**
+ * Callback for actions
+ *
+ * @param name the action name
+ * @param value the payload of the action
+ */
void onAction(@NonNull String name, Object value);
}
@@ -450,7 +481,14 @@ public class CoreDocument {
mActionListeners.clear();
}
+ /** Id Actions */
public interface IdActionCallback {
+ /**
+ * Callback on Id Actions
+ *
+ * @param id the actio id triggered
+ * @param metadata optional metadata
+ */
void onAction(int id, @Nullable String metadata);
}
@@ -530,10 +568,20 @@ public class CoreDocument {
return mTop;
}
+ /**
+ * Returns the width of the click area
+ *
+ * @return the width of the click area
+ */
public float width() {
return Math.max(0, mRight - mLeft);
}
+ /**
+ * Returns the height of the click area
+ *
+ * @return the height of the click area
+ */
public float height() {
return Math.max(0, mBottom - mTop);
}
@@ -816,6 +864,7 @@ public class CoreDocument {
for (ClickAreaRepresentation clickArea : mClickAreas) {
if (clickArea.mId == id) {
warnClickListeners(clickArea);
+ return;
}
}
for (IdActionCallback listener : mIdActionListeners) {
@@ -1127,6 +1176,11 @@ public class CoreDocument {
return count;
}
+ /**
+ * Returns a list of useful statistics for the runtime document
+ *
+ * @return
+ */
@NonNull
public String[] getStats() {
ArrayList<String> ret = new ArrayList<>();
@@ -1145,8 +1199,8 @@ public class CoreDocument {
values[0] += 1;
values[1] += sizeOfComponent(mOperation, buffer);
- if (mOperation instanceof Component) {
- Component com = (Component) mOperation;
+ if (mOperation instanceof Container) {
+ Container com = (Container) mOperation;
count += addChildren(com, map, buffer);
} else if (mOperation instanceof LoopOperation) {
LoopOperation com = (LoopOperation) mOperation;
@@ -1172,35 +1226,9 @@ public class CoreDocument {
}
private int addChildren(
- @NonNull Component base, @NonNull HashMap<String, int[]> map, @NonNull WireBuffer tmp) {
- int count = base.mList.size();
- for (Operation mOperation : base.mList) {
- Class<? extends Operation> c = mOperation.getClass();
- int[] values;
- if (map.containsKey(c.getSimpleName())) {
- values = map.get(c.getSimpleName());
- } else {
- values = new int[2];
- map.put(c.getSimpleName(), values);
- }
- values[0] += 1;
- values[1] += sizeOfComponent(mOperation, tmp);
- if (mOperation instanceof Component) {
- count += addChildren((Component) mOperation, map, tmp);
- }
- if (mOperation instanceof LoopOperation) {
- count += addChildren((LoopOperation) mOperation, map, tmp);
- }
- }
- return count;
- }
-
- private int addChildren(
- @NonNull LoopOperation base,
- @NonNull HashMap<String, int[]> map,
- @NonNull WireBuffer tmp) {
- int count = base.mList.size();
- for (Operation mOperation : base.mList) {
+ @NonNull Container base, @NonNull HashMap<String, int[]> map, @NonNull WireBuffer tmp) {
+ int count = base.getList().size();
+ for (Operation mOperation : base.getList()) {
Class<? extends Operation> c = mOperation.getClass();
int[] values;
if (map.containsKey(c.getSimpleName())) {
@@ -1211,39 +1239,42 @@ public class CoreDocument {
}
values[0] += 1;
values[1] += sizeOfComponent(mOperation, tmp);
- if (mOperation instanceof Component) {
- count += addChildren((Component) mOperation, map, tmp);
- }
- if (mOperation instanceof LoopOperation) {
- count += addChildren((LoopOperation) mOperation, map, tmp);
+ if (mOperation instanceof Container) {
+ count += addChildren((Container) mOperation, map, tmp);
}
}
return count;
}
+ /**
+ * Returns a string representation of the operations, traversing the list of operations &
+ * containers
+ *
+ * @return
+ */
@NonNull
public String toNestedString() {
StringBuilder ret = new StringBuilder();
for (Operation mOperation : mOperations) {
ret.append(mOperation.toString());
ret.append("\n");
- if (mOperation instanceof Component) {
- toNestedString((Component) mOperation, ret, " ");
+ if (mOperation instanceof Container) {
+ toNestedString((Container) mOperation, ret, " ");
}
}
return ret.toString();
}
private void toNestedString(
- @NonNull Component base, @NonNull StringBuilder ret, String indent) {
- for (Operation mOperation : base.mList) {
+ @NonNull Container base, @NonNull StringBuilder ret, String indent) {
+ for (Operation mOperation : base.getList()) {
for (String line : mOperation.toString().split("\n")) {
ret.append(indent);
ret.append(line);
ret.append("\n");
}
- if (mOperation instanceof Component) {
- toNestedString((Component) mOperation, ret, indent + " ");
+ if (mOperation instanceof Container) {
+ toNestedString((Container) mOperation, ret, indent + " ");
}
}
}
@@ -1255,6 +1286,12 @@ public class CoreDocument {
/** defines if a shader can be run */
public interface ShaderControl {
+ /**
+ * validate if a shader can run in the document
+ *
+ * @param shader the source of the shader
+ * @return true if the shader is allowed to run
+ */
boolean isShaderValid(String shader);
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/Operations.java b/core/java/com/android/internal/widget/remotecompose/core/Operations.java
index d9f12cb71d53..9a37a22390a2 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/Operations.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/Operations.java
@@ -55,6 +55,8 @@ import com.android.internal.widget.remotecompose.core.operations.MatrixSkew;
import com.android.internal.widget.remotecompose.core.operations.MatrixTranslate;
import com.android.internal.widget.remotecompose.core.operations.NamedVariable;
import com.android.internal.widget.remotecompose.core.operations.PaintData;
+import com.android.internal.widget.remotecompose.core.operations.ParticlesCreate;
+import com.android.internal.widget.remotecompose.core.operations.ParticlesLoop;
import com.android.internal.widget.remotecompose.core.operations.PathAppend;
import com.android.internal.widget.remotecompose.core.operations.PathCreate;
import com.android.internal.widget.remotecompose.core.operations.PathData;
@@ -75,6 +77,8 @@ import com.android.internal.widget.remotecompose.core.operations.layout.CanvasCo
import com.android.internal.widget.remotecompose.core.operations.layout.ClickModifierOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.ComponentStart;
import com.android.internal.widget.remotecompose.core.operations.layout.ContainerEnd;
+import com.android.internal.widget.remotecompose.core.operations.layout.ImpulseOperation;
+import com.android.internal.widget.remotecompose.core.operations.layout.ImpulseProcess;
import com.android.internal.widget.remotecompose.core.operations.layout.LayoutComponentContent;
import com.android.internal.widget.remotecompose.core.operations.layout.LoopOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.RootLayoutComponent;
@@ -188,6 +192,11 @@ public class Operations {
public static final int PATH_TWEEN = 158;
public static final int PATH_CREATE = 159;
public static final int PATH_ADD = 160;
+ public static final int PARTICLE_CREATE = 161;
+ public static final int PARTICLE_PROCESS = 162;
+ public static final int PARTICLE_LOOP = 163;
+ public static final int IMPULSE_START = 164;
+ public static final int IMPULSE_PROCESS = 165;
///////////////////////////////////////// ======================
@@ -366,6 +375,10 @@ public class Operations {
map.put(PATH_TWEEN, PathTween::read);
map.put(PATH_CREATE, PathCreate::read);
map.put(PATH_ADD, PathAppend::read);
+ map.put(IMPULSE_START, ImpulseOperation::read);
+ map.put(IMPULSE_PROCESS, ImpulseProcess::read);
+ map.put(PARTICLE_CREATE, ParticlesCreate::read);
+ map.put(PARTICLE_LOOP, ParticlesLoop::read);
map.put(ACCESSIBILITY_SEMANTICS, CoreSemantics::read);
// map.put(ACCESSIBILITY_CUSTOM_ACTION, CoreSemantics::read);
diff --git a/core/java/com/android/internal/widget/remotecompose/core/PaintContext.java b/core/java/com/android/internal/widget/remotecompose/core/PaintContext.java
index 4a40a31ef6ab..49a0457c3595 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/PaintContext.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/PaintContext.java
@@ -33,10 +33,16 @@ public abstract class PaintContext {
return mContext;
}
+ /**
+ * Returns true if the needsRepaint flag is set
+ *
+ * @return true if the document asks to be repainted
+ */
public boolean doesNeedsRepaint() {
return mNeedsRepaint;
}
+ /** Clear the needsRepaint flag */
public void clearNeedsRepaint() {
mNeedsRepaint = false;
}
@@ -65,6 +71,20 @@ public abstract class PaintContext {
matrixSave();
}
+ /**
+ * Draw a bitmap
+ *
+ * @param imageId
+ * @param srcLeft
+ * @param srcTop
+ * @param srcRight
+ * @param srcBottom
+ * @param dstLeft
+ * @param dstTop
+ * @param dstRight
+ * @param dstBottom
+ * @param cdId
+ */
public abstract void drawBitmap(
int imageId,
int srcLeft,
@@ -77,26 +97,105 @@ public abstract class PaintContext {
int dstBottom,
int cdId);
+ /**
+ * scale the following commands
+ *
+ * @param scaleX horizontal scale factor
+ * @param scaleY vertical scale factor
+ */
public abstract void scale(float scaleX, float scaleY);
+ /**
+ * Rotate the following commands
+ *
+ * @param translateX horizontal translation
+ * @param translateY vertical translation
+ */
public abstract void translate(float translateX, float translateY);
+ /**
+ * Draw an arc
+ *
+ * @param left
+ * @param top
+ * @param right
+ * @param bottom
+ * @param startAngle
+ * @param sweepAngle
+ */
public abstract void drawArc(
float left, float top, float right, float bottom, float startAngle, float sweepAngle);
+ /**
+ * Draw a sector
+ *
+ * @param left
+ * @param top
+ * @param right
+ * @param bottom
+ * @param startAngle
+ * @param sweepAngle
+ */
public abstract void drawSector(
float left, float top, float right, float bottom, float startAngle, float sweepAngle);
+ /**
+ * Draw a bitmap
+ *
+ * @param id
+ * @param left
+ * @param top
+ * @param right
+ * @param bottom
+ */
public abstract void drawBitmap(int id, float left, float top, float right, float bottom);
+ /**
+ * Draw a circle
+ *
+ * @param centerX
+ * @param centerY
+ * @param radius
+ */
public abstract void drawCircle(float centerX, float centerY, float radius);
+ /**
+ * Draw a line
+ *
+ * @param x1
+ * @param y1
+ * @param x2
+ * @param y2
+ */
public abstract void drawLine(float x1, float y1, float x2, float y2);
+ /**
+ * Draw an oval
+ *
+ * @param left
+ * @param top
+ * @param right
+ * @param bottom
+ */
public abstract void drawOval(float left, float top, float right, float bottom);
+ /**
+ * Draw a path
+ *
+ * @param id the path id
+ * @param start starting point of the path where we start drawing it
+ * @param end ending point of the path where we stop drawing it
+ */
public abstract void drawPath(int id, float start, float end);
+ /**
+ * Draw a rectangle
+ *
+ * @param left left coordinate of the rectangle
+ * @param top top coordinate of the rectangle
+ * @param right right coordinate of the rectangle
+ * @param bottom bottom coordinate of the rectangle
+ */
public abstract void drawRect(float left, float top, float right, float bottom);
/** this caches the paint to a paint stack */
@@ -105,9 +204,27 @@ public abstract class PaintContext {
/** This restores the paint form the paint stack */
public abstract void restorePaint();
+ /**
+ * draw a round rect
+ *
+ * @param left left coordinate of the rectangle
+ * @param top top coordinate of the rectangle
+ * @param right right coordinate of the rectangle
+ * @param bottom bottom coordinate of the rectangle
+ * @param radiusX horizontal radius of the rounded corner
+ * @param radiusY vertical radius of the rounded corner
+ */
public abstract void drawRoundRect(
float left, float top, float right, float bottom, float radiusX, float radiusY);
+ /**
+ * Draw the text glyphs on the provided path
+ *
+ * @param textId id of the text
+ * @param pathId id of the path
+ * @param hOffset horizontal offset
+ * @param vOffset vertical offset
+ */
public abstract void drawTextOnPath(int textId, int pathId, float hOffset, float vOffset);
/**
@@ -158,6 +275,14 @@ public abstract class PaintContext {
public abstract void drawTweenPath(
int path1Id, int path2Id, float tween, float start, float stop);
+ /**
+ * Interpolate between two path and return the resulting path
+ *
+ * @param out the interpolated path
+ * @param path1 start path
+ * @param path2 end path
+ * @param tween interpolation value from 0 (start path) to 1 (end path)
+ */
public abstract void tweenPath(int out, int path1, int path2, float tween);
/**
@@ -275,12 +400,33 @@ public abstract class PaintContext {
System.out.println("[LOG] " + content);
}
+ /** Indicates the document needs to be repainted */
public void needsRepaint() {
mNeedsRepaint = true;
}
+ /**
+ * Starts a graphics layer
+ *
+ * @param w
+ * @param h
+ */
public abstract void startGraphicsLayer(int w, int h);
+ /**
+ * Starts a graphics layer
+ *
+ * @param scaleX
+ * @param scaleY
+ * @param rotationX
+ * @param rotationY
+ * @param rotationZ
+ * @param shadowElevation
+ * @param transformOriginX
+ * @param transformOriginY
+ * @param alpha
+ * @param renderEffectId
+ */
public abstract void setGraphicsLayer(
float scaleX,
float scaleY,
@@ -293,6 +439,7 @@ public abstract class PaintContext {
float alpha,
int renderEffectId);
+ /** Ends a graphics layer */
public abstract void endGraphicsLayer();
public boolean isVisualDebug() {
diff --git a/core/java/com/android/internal/widget/remotecompose/core/PaintOperation.java b/core/java/com/android/internal/widget/remotecompose/core/PaintOperation.java
index cfdd52212b03..f355676be63e 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/PaintOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/PaintOperation.java
@@ -39,6 +39,11 @@ public abstract class PaintOperation extends Operation {
return indent + toString();
}
+ /**
+ * Paint the operation in the context
+ *
+ * @param context painting context
+ */
public abstract void paint(@NonNull PaintContext context);
/**
diff --git a/core/java/com/android/internal/widget/remotecompose/core/Platform.java b/core/java/com/android/internal/widget/remotecompose/core/Platform.java
index dcb8efebeecc..e4a063d7d6ff 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/Platform.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/Platform.java
@@ -20,13 +20,38 @@ import android.annotation.Nullable;
/** Services that are needed to be provided by the platform during encoding. */
public interface Platform {
+
+ /**
+ * Converts a platform-specific image object into a platform-independent byte buffer
+ *
+ * @param image
+ * @return
+ */
@Nullable
byte[] imageToByteArray(@NonNull Object image);
+ /**
+ * Returns the width of a platform-specific image object
+ *
+ * @param image platform-specific image object
+ * @return the width of the image in pixels
+ */
int getImageWidth(@NonNull Object image);
+ /**
+ * Returns the height of a platform-specific image object
+ *
+ * @param image platform-specific image object
+ * @return the height of the image in pixels
+ */
int getImageHeight(@NonNull Object image);
+ /**
+ * Converts a platform-specific path object into a platform-independent float buffer
+ *
+ * @param path
+ * @return
+ */
@Nullable
float[] pathToFloatArray(@NonNull Object path);
@@ -38,6 +63,12 @@ public interface Platform {
TODO,
}
+ /**
+ * Log a message
+ *
+ * @param category
+ * @param message
+ */
void log(LogCategory category, String message);
Platform None =
diff --git a/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeBuffer.java b/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeBuffer.java
index fc1e36d45a81..39cc997fadc2 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeBuffer.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeBuffer.java
@@ -58,6 +58,8 @@ import com.android.internal.widget.remotecompose.core.operations.MatrixSkew;
import com.android.internal.widget.remotecompose.core.operations.MatrixTranslate;
import com.android.internal.widget.remotecompose.core.operations.NamedVariable;
import com.android.internal.widget.remotecompose.core.operations.PaintData;
+import com.android.internal.widget.remotecompose.core.operations.ParticlesCreate;
+import com.android.internal.widget.remotecompose.core.operations.ParticlesLoop;
import com.android.internal.widget.remotecompose.core.operations.PathAppend;
import com.android.internal.widget.remotecompose.core.operations.PathCreate;
import com.android.internal.widget.remotecompose.core.operations.PathData;
@@ -77,6 +79,8 @@ import com.android.internal.widget.remotecompose.core.operations.Utils;
import com.android.internal.widget.remotecompose.core.operations.layout.CanvasContent;
import com.android.internal.widget.remotecompose.core.operations.layout.ComponentStart;
import com.android.internal.widget.remotecompose.core.operations.layout.ContainerEnd;
+import com.android.internal.widget.remotecompose.core.operations.layout.ImpulseOperation;
+import com.android.internal.widget.remotecompose.core.operations.layout.ImpulseProcess;
import com.android.internal.widget.remotecompose.core.operations.layout.LayoutComponentContent;
import com.android.internal.widget.remotecompose.core.operations.layout.LoopOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.RootLayoutComponent;
@@ -411,11 +415,7 @@ public class RemoteComposeBuffer {
BitmapData.apply(
mBuffer, imageId, imageWidth, imageHeight, data); // todo: potential npe
}
- int contentDescriptionId = 0;
- if (contentDescription != null) {
- contentDescriptionId = addText(contentDescription);
- }
- DrawBitmap.apply(mBuffer, imageId, left, top, right, bottom, contentDescriptionId);
+ addDrawBitmap(imageId, left, top, right, bottom, contentDescription);
}
/**
@@ -441,6 +441,24 @@ public class RemoteComposeBuffer {
}
/**
+ * @param imageId The Id bitmap to be drawn
+ * @param left left coordinate of rectangle that the bitmap will be to fit into
+ * @param top top coordinate of rectangle that the bitmap will be to fit into
+ * @param contentDescription content description of the image
+ */
+ public void addDrawBitmap(
+ int imageId, float left, float top, @Nullable String contentDescription) {
+ int imageWidth = mPlatform.getImageWidth(imageId);
+ int imageHeight = mPlatform.getImageHeight(imageId);
+ int contentDescriptionId = 0;
+ if (contentDescription != null) {
+ contentDescriptionId = addText(contentDescription);
+ }
+ DrawBitmap.apply(
+ mBuffer, imageId, left, top, imageWidth, imageHeight, contentDescriptionId);
+ }
+
+ /**
* @param image The bitmap to be drawn
* @param srcLeft left coordinate in the source bitmap will be to extracted
* @param srcTop top coordinate in the source bitmap will be to extracted
@@ -537,7 +555,7 @@ public class RemoteComposeBuffer {
}
/**
- * This defines the name of the color given the id.
+ * This defines the name of the bitmap given the id.
*
* @param id of the Bitmap
* @param name Name of the color
@@ -2060,4 +2078,61 @@ public class RemoteComposeBuffer {
public int nextId() {
return mRemoteComposeState.nextId();
}
+
+ private boolean mInImpulseProcess = false;
+
+ /**
+ * add an impulse. (must be followed by impulse end)
+ *
+ * @param duration duration of the impulse
+ * @param start the start time
+ */
+ public void addImpulse(float duration, float start) {
+ ImpulseOperation.apply(mBuffer, duration, start);
+ mInImpulseProcess = false;
+ }
+
+ /** add an impulse process */
+ public void addImpulseProcess() {
+ ImpulseProcess.apply(mBuffer);
+ mInImpulseProcess = true;
+ }
+
+ /** Add an impulse end */
+ public void addImpulseEnd() {
+ ContainerEnd.apply(mBuffer);
+ if (mInImpulseProcess) {
+ ContainerEnd.apply(mBuffer);
+ }
+ mInImpulseProcess = false;
+ }
+
+ /**
+ * Start a particle engine container & initial setup
+ *
+ * @param id the particle engine id
+ * @param varIds list of variable ids
+ * @param initialExpressions the expressions used to initialize the variables
+ * @param particleCount the number of particles to draw
+ */
+ public void addParticles(
+ int id, int[] varIds, float[][] initialExpressions, int particleCount) {
+ ParticlesCreate.apply(mBuffer, id, varIds, initialExpressions, particleCount);
+ }
+
+ /**
+ * Setup the particle engine loop
+ *
+ * @param id the particle engine id
+ * @param restart value on restart
+ * @param expressions the expressions used to update the variables during the particles run
+ */
+ public void addParticlesLoop(int id, float[] restart, float[][] expressions) {
+ ParticlesLoop.apply(mBuffer, id, restart, expressions);
+ }
+
+ /** Closes the particle engine container */
+ public void addParticleLoopEnd() {
+ ContainerEnd.apply(mBuffer);
+ }
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java b/core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java
index 63469aabaed5..ec336633e960 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java
@@ -40,12 +40,12 @@ import java.time.ZoneOffset;
* <p>We also contain a PaintContext, so that any operation can draw as needed.
*/
public abstract class RemoteContext {
- private static final int MAX_OP_COUNT = 100_000; // Maximum cmds per frame
+ private static final int MAX_OP_COUNT = 20_000; // Maximum cmds per frame
protected @NonNull CoreDocument mDocument =
new CoreDocument(); // todo: is this a valid way to initialize? bbade@
public @NonNull RemoteComposeState mRemoteComposeState =
new RemoteComposeState(); // todo, is this a valid use of RemoteComposeState -- bbade@
- long mStart = System.nanoTime(); // todo This should be set at a hi level
+
@Nullable protected PaintContext mPaintContext = null;
protected float mDensity = 2.75f;
@@ -71,6 +71,11 @@ public abstract class RemoteContext {
return mDensity;
}
+ /**
+ * Set the density of the document
+ *
+ * @param density
+ */
public void setDensity(float density) {
if (density > 0) {
mDensity = density;
@@ -142,7 +147,6 @@ public abstract class RemoteContext {
* @return a monotonic time in seconds (arbitrary zero point)
*/
public float getAnimationTime() {
- mAnimationTime = (System.nanoTime() - mStart) * 1E-9f; // Eliminate
return mAnimationTime;
}
@@ -243,6 +247,11 @@ public abstract class RemoteContext {
public abstract @Nullable Object getObject(int mId);
+ /**
+ * Add a touch listener to the context
+ *
+ * @param touchExpression
+ */
public void addTouchListener(TouchListener touchExpression) {}
/**
@@ -337,6 +346,16 @@ public abstract class RemoteContext {
// Operations
///////////////////////////////////////////////////////////////////////////////////////////////
+ /**
+ * Set the main information about a document
+ *
+ * @param majorVersion major version of the document protocol used
+ * @param minorVersion minor version of the document protocol used
+ * @param patchVersion patch version of the document protocol used
+ * @param width original width of the document when created
+ * @param height original height of the document when created
+ * @param capabilities bitmask of capabilities used in the document (TBD)
+ */
public void header(
int majorVersion,
int minorVersion,
@@ -552,6 +571,15 @@ public abstract class RemoteContext {
/** Defines when the last build was made */
public static final int ID_API_LEVEL = 28;
+ /** Defines when the TOUCH EVENT HAPPENED */
+ public static final int ID_TOUCH_EVENT_TIME = 29;
+
+ /** Animation time in seconds */
+ public static final int ID_ANIMATION_TIME = 30;
+
+ /** The delta between current and last Frame */
+ public static final int ID_ANIMATION_DELTA_TIME = 31;
+
public static final float FLOAT_DENSITY = Utils.asNan(ID_DENSITY);
/** CONTINUOUS_SEC is seconds from midnight looping every hour 0-3600 */
@@ -595,6 +623,15 @@ public abstract class RemoteContext {
/** TOUCH_VEL_Y is the x velocity of the touch */
public static final float FLOAT_TOUCH_VEL_Y = Utils.asNan(ID_TOUCH_VEL_Y);
+ /** TOUCH_EVENT_TIME the time of the touch */
+ public static final float FLOAT_TOUCH_EVENT_TIME = Utils.asNan(ID_TOUCH_EVENT_TIME);
+
+ /** Animation time in seconds */
+ public static final float FLOAT_ANIMATION_TIME = Utils.asNan(ID_ANIMATION_TIME);
+
+ /** Animation time in seconds */
+ public static final float FLOAT_ANIMATION_DELTA_TIME = Utils.asNan(ID_ANIMATION_DELTA_TIME);
+
/** X acceleration sensor value in M/s^2 */
public static final float FLOAT_ACCELERATION_X = Utils.asNan(ID_ACCELERATION_X);
diff --git a/core/java/com/android/internal/widget/remotecompose/core/SerializableToString.java b/core/java/com/android/internal/widget/remotecompose/core/SerializableToString.java
index 79ac789a454e..37896211bcef 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/SerializableToString.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/SerializableToString.java
@@ -20,5 +20,11 @@ import android.annotation.NonNull;
import com.android.internal.widget.remotecompose.core.operations.utilities.StringSerializer;
public interface SerializableToString {
+ /**
+ * Returns a stable string representation of an operation
+ *
+ * @param indent the indentation for that operation
+ * @param serializer the serializer object
+ */
void serializeToString(int indent, @NonNull StringSerializer serializer);
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/TouchListener.java b/core/java/com/android/internal/widget/remotecompose/core/TouchListener.java
index 611ba97c10cb..0a1be82bc53a 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/TouchListener.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/TouchListener.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.widget.remotecompose.core;
+import com.android.internal.widget.remotecompose.core.operations.layout.Component;
+
/** Interface used by objects to register for touch events */
public interface TouchListener {
/**
@@ -45,4 +47,11 @@ public interface TouchListener {
* @param y the y coord of the drag
*/
void touchDrag(RemoteContext context, float x, float y);
+
+ /**
+ * Called after the touch event handler is inflated
+ *
+ * @param component component it is under
+ */
+ void setComponent(Component component);
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/documentation/DocumentationBuilder.java b/core/java/com/android/internal/widget/remotecompose/core/documentation/DocumentationBuilder.java
index 0174ce531d3f..0972e05e39b6 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/documentation/DocumentationBuilder.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/documentation/DocumentationBuilder.java
@@ -18,11 +18,33 @@ package com.android.internal.widget.remotecompose.core.documentation;
import android.annotation.NonNull;
public interface DocumentationBuilder {
+
+ /**
+ * Add arbitrary text to the documentation
+ *
+ * @param value
+ */
void add(@NonNull String value);
+ /**
+ * Add the operation to the documentation
+ *
+ * @param category category of the operation
+ * @param id the OPCODE of the operation
+ * @param name the name of the operation
+ * @return a DocumentedOperation
+ */
@NonNull
DocumentedOperation operation(@NonNull String category, int id, @NonNull String name);
+ /**
+ * Add the operation to the documentation as a Work in Progress (WIP) operation
+ *
+ * @param category category of the operation
+ * @param id the OPCODE of the operation
+ * @param name the name of the operation
+ * @return a DocumentedOperation
+ */
@NonNull
DocumentedOperation wipOperation(@NonNull String category, int id, @NonNull String name);
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/documentation/DocumentedCompanionOperation.java b/core/java/com/android/internal/widget/remotecompose/core/documentation/DocumentedCompanionOperation.java
index 2806a5e1ad1d..487ea2ebfacb 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/documentation/DocumentedCompanionOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/documentation/DocumentedCompanionOperation.java
@@ -18,5 +18,10 @@ package com.android.internal.widget.remotecompose.core.documentation;
import android.annotation.NonNull;
public interface DocumentedCompanionOperation {
+ /**
+ * A callback to populate the documentation of an operation
+ *
+ * @param doc the document being built
+ */
void documentation(@NonNull DocumentationBuilder doc);
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/documentation/DocumentedOperation.java b/core/java/com/android/internal/widget/remotecompose/core/documentation/DocumentedOperation.java
index bfab62365736..ffe887156e40 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/documentation/DocumentedOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/documentation/DocumentedOperation.java
@@ -49,6 +49,12 @@ public class DocumentedOperation {
int mExamplesWidth = 100;
int mExamplesHeight = 100;
+ /**
+ * Returns the string representation of a field type
+ *
+ * @param type
+ * @return
+ */
@NonNull
public static String getType(int type) {
switch (type) {
@@ -117,6 +123,11 @@ public class DocumentedOperation {
return mVarSize;
}
+ /**
+ * Returns the size of the operation fields
+ *
+ * @return size in bytes
+ */
public int getSizeFields() {
int size = 0;
mVarSize = "";
@@ -152,12 +163,29 @@ public class DocumentedOperation {
return mExamplesHeight;
}
+ /**
+ * Document a field of the operation
+ *
+ * @param type
+ * @param name
+ * @param description
+ * @return
+ */
@NonNull
public DocumentedOperation field(int type, @NonNull String name, @NonNull String description) {
mFields.add(new OperationField(type, name, description));
return this;
}
+ /**
+ * Document a field of the operation
+ *
+ * @param type
+ * @param name
+ * @param varSize
+ * @param description
+ * @return
+ */
@NonNull
public DocumentedOperation field(
int type, @NonNull String name, @NonNull String varSize, @NonNull String description) {
@@ -165,6 +193,13 @@ public class DocumentedOperation {
return this;
}
+ /**
+ * Add possible values for the operation field
+ *
+ * @param name
+ * @param value
+ * @return
+ */
@NonNull
public DocumentedOperation possibleValues(@NonNull String name, int value) {
if (!mFields.isEmpty()) {
@@ -173,24 +208,50 @@ public class DocumentedOperation {
return this;
}
+ /**
+ * Add a description
+ *
+ * @param description
+ * @return
+ */
@NonNull
public DocumentedOperation description(@NonNull String description) {
mDescription = description;
return this;
}
+ /**
+ * Add arbitrary text as examples
+ *
+ * @param examples
+ * @return
+ */
@NonNull
public DocumentedOperation examples(@NonNull String examples) {
mTextExamples = examples;
return this;
}
+ /**
+ * Add an example image
+ *
+ * @param name the title of the image
+ * @param imagePath the path of the image
+ * @return
+ */
@NonNull
public DocumentedOperation exampleImage(@NonNull String name, @NonNull String imagePath) {
mExamples.add(new StringPair(name, imagePath));
return this;
}
+ /**
+ * Add examples with a given size
+ *
+ * @param width
+ * @param height
+ * @return
+ */
@NonNull
public DocumentedOperation examplesDimension(int width, int height) {
mExamplesWidth = width;
diff --git a/core/java/com/android/internal/widget/remotecompose/core/documentation/OperationField.java b/core/java/com/android/internal/widget/remotecompose/core/documentation/OperationField.java
index 9febcfe57047..e120f3150a96 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/documentation/OperationField.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/documentation/OperationField.java
@@ -61,10 +61,21 @@ public class OperationField {
return mPossibleValues;
}
+ /**
+ * Add possible values for a field
+ *
+ * @param name
+ * @param value
+ */
public void possibleValue(@NonNull String name, @NonNull String value) {
mPossibleValues.add(new StringPair(name, value));
}
+ /**
+ * Return true if the field has enumerated values
+ *
+ * @return true if enumerated values, false otherwise
+ */
public boolean hasEnumeratedValues() {
return !mPossibleValues.isEmpty();
}
@@ -74,6 +85,11 @@ public class OperationField {
return mVarSize;
}
+ /**
+ * Returns the size in byte of the field depending on its type, or -1 if unknown
+ *
+ * @return the size in bytes
+ */
public int getSize() {
switch (mType) {
case DocumentedOperation.BYTE:
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/Header.java b/core/java/com/android/internal/widget/remotecompose/core/operations/Header.java
index 4c9602572721..98c2745380d7 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/Header.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/Header.java
@@ -135,6 +135,15 @@ public class Header extends Operation implements RemoteComposeOperation {
return OP_CODE;
}
+ /**
+ * Apply the header to the wire buffer
+ *
+ * @param buffer
+ * @param width
+ * @param height
+ * @param density
+ * @param capabilities
+ */
public static void apply(
@NonNull WireBuffer buffer, int width, int height, float density, long capabilities) {
buffer.start(OP_CODE);
@@ -193,6 +202,11 @@ public class Header extends Operation implements RemoteComposeOperation {
.field(LONG, "CAPABILITIES", "Major version");
}
+ /**
+ * Set the version on a document
+ *
+ * @param document
+ */
public void setVersion(CoreDocument document) {
document.setVersion(mMajorVersion, mMinorVersion, mPatchVersion);
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/ParticlesCreate.java b/core/java/com/android/internal/widget/remotecompose/core/operations/ParticlesCreate.java
new file mode 100644
index 000000000000..9e891c48c065
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/ParticlesCreate.java
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations;
+
+import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.FLOAT_ARRAY;
+import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
+import static com.android.internal.widget.remotecompose.core.operations.utilities.AnimatedFloatExpression.VAR1;
+
+import android.annotation.NonNull;
+
+import com.android.internal.widget.remotecompose.core.Operation;
+import com.android.internal.widget.remotecompose.core.Operations;
+import com.android.internal.widget.remotecompose.core.RemoteContext;
+import com.android.internal.widget.remotecompose.core.VariableSupport;
+import com.android.internal.widget.remotecompose.core.WireBuffer;
+import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder;
+import com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation;
+import com.android.internal.widget.remotecompose.core.operations.utilities.AnimatedFloatExpression;
+import com.android.internal.widget.remotecompose.core.operations.utilities.NanMap;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * This creates a particle system. which consist of id, particleCount, array of id's and equations
+ * for constructing the particles
+ */
+public class ParticlesCreate extends Operation implements VariableSupport {
+ private static final int OP_CODE = Operations.PARTICLE_CREATE;
+ private static final String CLASS_NAME = "ParticlesCreate";
+ private final int mId;
+ private final float[][] mEquations;
+ private final float[][] mOutEquations;
+ private final float[][] mParticles;
+ private final int[] mIndexeVars; // the elements in mEquations that INDEXES
+ private final int mParticleCount;
+ private final int[] mVarId;
+ private static final int MAX_FLOAT_ARRAY = 2000;
+ private static final int MAX_EQU_LENGTH = 32;
+ @NonNull AnimatedFloatExpression mExp = new AnimatedFloatExpression();
+
+ public ParticlesCreate(int id, int[] varId, float[][] values, int particleCount) {
+ mId = id;
+ mVarId = varId;
+ mEquations = values;
+ mParticleCount = particleCount;
+ mOutEquations = new float[values.length][];
+ for (int i = 0; i < values.length; i++) {
+ mOutEquations[i] = new float[values[i].length];
+ System.arraycopy(values[i], 0, mOutEquations[i], 0, values[i].length);
+ }
+ mParticles = new float[particleCount][varId.length];
+
+ int[] index = new int[20];
+ int indexes = 0;
+ int var1Int = Float.floatToRawIntBits(VAR1);
+ for (int j = 0; j < mEquations.length; j++) {
+ for (int k = 0; k < mEquations[j].length; k++) {
+ if (Float.isNaN(mEquations[j][k])
+ && Float.floatToRawIntBits(mEquations[j][k]) == var1Int) {
+ index[indexes++] = j * mEquations.length + k;
+ }
+ }
+ }
+ mIndexeVars = Arrays.copyOf(index, indexes);
+ }
+
+ @Override
+ public void updateVariables(@NonNull RemoteContext context) {
+ for (int i = 0; i < mEquations.length; i++) {
+
+ for (int j = 0; j < mEquations[i].length; j++) {
+ float v = mEquations[i][j];
+ mOutEquations[i][j] =
+ (Float.isNaN(v)
+ && !AnimatedFloatExpression.isMathOperator(v)
+ && !NanMap.isDataVariable(v))
+ ? context.getFloat(Utils.idFromNan(v))
+ : v;
+ }
+ }
+ }
+
+ @Override
+ public void registerListening(@NonNull RemoteContext context) {
+ context.putObject(mId, this); // T
+ for (int i = 0; i < mEquations.length; i++) {
+ float[] mEquation = mEquations[i];
+ for (float v : mEquation) {
+ if (Float.isNaN(v)
+ && !AnimatedFloatExpression.isMathOperator(v)
+ && !NanMap.isDataVariable(v)) {
+ context.listensTo(Utils.idFromNan(v), this);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void write(@NonNull WireBuffer buffer) {
+ apply(buffer, mId, mVarId, mEquations, mParticleCount);
+ }
+
+ @NonNull
+ @Override
+ public String toString() {
+ String str = "ParticlesCreate[" + Utils.idString(mId) + "] ";
+ for (int j = 0; j < mVarId.length; j++) {
+ str += "[" + mVarId[j] + "] ";
+ float[] equation = mEquations[j];
+ String[] labels = new String[equation.length];
+ for (int i = 0; i < equation.length; i++) {
+ if (Float.isNaN(equation[i])) {
+ labels[i] = "[" + Utils.idStringFromNan(equation[i]) + "]";
+ }
+ }
+ str += AnimatedFloatExpression.toString(equation, labels) + "\n";
+ }
+
+ return str;
+ }
+
+ /**
+ * Write the operation on the buffer
+ *
+ * @param buffer
+ * @param id
+ * @param varId
+ * @param equations
+ * @param particleCount
+ */
+ public static void apply(
+ @NonNull WireBuffer buffer,
+ int id,
+ @NonNull int[] varId,
+ @NonNull float[][] equations,
+ int particleCount) {
+ buffer.start(OP_CODE);
+ buffer.writeInt(id);
+ buffer.writeInt(particleCount);
+ buffer.writeInt(varId.length);
+ for (int i = 0; i < varId.length; i++) {
+ buffer.writeInt(varId[i]);
+ buffer.writeInt(equations[i].length);
+ for (int j = 0; j < equations[i].length; j++) {
+ buffer.writeFloat(equations[i][j]);
+ }
+ }
+ }
+
+ /**
+ * Read this operation and add it to the list of operations
+ *
+ * @param buffer the buffer to read
+ * @param operations the list of operations that will be added to
+ */
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
+ int id = buffer.readInt();
+ int particleCount = buffer.readInt();
+ int varLen = buffer.readInt();
+ if (varLen > MAX_FLOAT_ARRAY) {
+ throw new RuntimeException(varLen + " map entries more than max = " + MAX_FLOAT_ARRAY);
+ }
+ int[] varId = new int[varLen];
+ float[][] equations = new float[varLen][];
+ for (int i = 0; i < varId.length; i++) {
+ varId[i] = buffer.readInt();
+ int equLen = buffer.readInt();
+ if (equLen > MAX_EQU_LENGTH) {
+ throw new RuntimeException(
+ equLen + " map entries more than max = " + MAX_FLOAT_ARRAY);
+ }
+ equations[i] = new float[equLen];
+ for (int j = 0; j < equations[i].length; j++) {
+ equations[i][j] = buffer.readFloat();
+ }
+ }
+ ParticlesCreate data = new ParticlesCreate(id, varId, equations, particleCount);
+ operations.add(data);
+ }
+
+ /**
+ * Populate the documentation with a description of this operation
+ *
+ * @param doc to append the description to.
+ */
+ public static void documentation(@NonNull DocumentationBuilder doc) {
+ doc.operation("Data Operations", OP_CODE, CLASS_NAME)
+ .description("Creates a particle system")
+ .field(DocumentedOperation.INT, "id", "The reference of the particle system")
+ .field(INT, "particleCount", "number of particles to create")
+ .field(INT, "varLen", "number of variables asociate with the particles")
+ .field(FLOAT_ARRAY, "id", "varLen", "id followed by equations")
+ .field(INT, "equLen", "length of the equation")
+ .field(FLOAT_ARRAY, "equation", "varLen * equLen", "float array equations");
+ }
+
+ @NonNull
+ @Override
+ public String deepToString(@NonNull String indent) {
+ return indent + toString();
+ }
+
+ void initializeParticle(int pNo) {
+ for (int j = 0; j < mParticles[pNo].length; j++) {
+ for (int k = 0; k < mIndexeVars.length; k++) {
+ int pos = mIndexeVars[k];
+ int jIndex = pos / mOutEquations.length;
+ int kIndex = pos % mOutEquations.length;
+ mOutEquations[jIndex][kIndex] = pNo;
+ }
+ mParticles[pNo][j] = mExp.eval(mOutEquations[j], mOutEquations[j].length);
+ }
+ }
+
+ @Override
+ public void apply(@NonNull RemoteContext context) {
+ for (int i = 0; i < mParticles.length; i++) {
+ initializeParticle(i);
+ }
+ }
+
+ public float[][] getParticles() {
+ return mParticles;
+ }
+
+ public int[] getVariableIds() {
+ return mVarId;
+ }
+
+ public float[][] getEquations() {
+ return mOutEquations;
+ }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/ParticlesLoop.java b/core/java/com/android/internal/widget/remotecompose/core/operations/ParticlesLoop.java
new file mode 100644
index 000000000000..791079070622
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/ParticlesLoop.java
@@ -0,0 +1,295 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations;
+
+import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.FLOAT_ARRAY;
+import static com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation.INT;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+import com.android.internal.widget.remotecompose.core.Operation;
+import com.android.internal.widget.remotecompose.core.Operations;
+import com.android.internal.widget.remotecompose.core.PaintContext;
+import com.android.internal.widget.remotecompose.core.PaintOperation;
+import com.android.internal.widget.remotecompose.core.RemoteContext;
+import com.android.internal.widget.remotecompose.core.VariableSupport;
+import com.android.internal.widget.remotecompose.core.WireBuffer;
+import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder;
+import com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation;
+import com.android.internal.widget.remotecompose.core.operations.layout.Container;
+import com.android.internal.widget.remotecompose.core.operations.utilities.AnimatedFloatExpression;
+import com.android.internal.widget.remotecompose.core.operations.utilities.NanMap;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This provides the mechinism to evolve the particles It consist of a restart equation and a list
+ * of equations particle restarts if restart equation > 0
+ */
+public class ParticlesLoop extends PaintOperation implements VariableSupport, Container {
+ private static final int OP_CODE = Operations.PARTICLE_LOOP;
+ private static final String CLASS_NAME = "ParticlesLoop";
+ private final int mId;
+ private final float[] mRestart;
+ private final float[] mOutRestart;
+ private final float[][] mEquations;
+ private final float[][] mOutEquations;
+ private int[] mVarId;
+ private float[][] mParticles;
+ private static final int MAX_FLOAT_ARRAY = 2000;
+ private static final int MAX_EQU_LENGTH = 32;
+ ParticlesCreate mParticlesSource;
+
+ @NonNull
+ @Override
+ public ArrayList<Operation> getList() {
+ return mList;
+ }
+
+ @NonNull private ArrayList<Operation> mList = new ArrayList<>();
+
+ @NonNull AnimatedFloatExpression mExp = new AnimatedFloatExpression();
+
+ /**
+ * Create a new ParticlesLoop operation
+ *
+ * @param id of the create
+ * @param restart the restart equation kills and restart when positive
+ * @param values the loop equations
+ */
+ public ParticlesLoop(int id, float[] restart, float[][] values) {
+ mId = id;
+ mRestart = restart;
+ if (restart != null) {
+ mOutRestart = new float[restart.length];
+ System.arraycopy(restart, 0, mOutRestart, 0, restart.length);
+ } else {
+ mOutRestart = null;
+ }
+
+ mEquations = values;
+ mOutEquations = new float[values.length][];
+ for (int i = 0; i < values.length; i++) {
+ mOutEquations[i] = new float[values[i].length];
+ System.arraycopy(values[i], 0, mOutEquations[i], 0, values[i].length);
+ }
+ }
+
+ @Override
+ public void updateVariables(@NonNull RemoteContext context) {
+ if (mOutRestart != null) {
+ for (int i = 0; i < mRestart.length; i++) {
+ float v = mRestart[i];
+ mOutRestart[i] =
+ (Float.isNaN(v)
+ && !AnimatedFloatExpression.isMathOperator(v)
+ && !NanMap.isDataVariable(v))
+ ? context.getFloat(Utils.idFromNan(v))
+ : v;
+ }
+ }
+ for (int i = 0; i < mEquations.length; i++) {
+ float[] mEquation = mEquations[i];
+ for (int j = 0; j < mEquation.length; j++) {
+ float v = mEquation[j];
+ mOutEquations[i][j] =
+ (Float.isNaN(v)
+ && !AnimatedFloatExpression.isMathOperator(v)
+ && !NanMap.isDataVariable(v))
+ ? context.getFloat(Utils.idFromNan(v))
+ : v;
+ }
+ }
+ }
+
+ @Override
+ public void registerListening(@NonNull RemoteContext context) {
+ mParticlesSource = (ParticlesCreate) context.getObject(mId);
+ mParticles = mParticlesSource.getParticles();
+ mVarId = mParticlesSource.getVariableIds();
+ if (mRestart != null) {
+ for (int i = 0; i < mRestart.length; i++) {
+ float v = mRestart[i];
+ if (Float.isNaN(v)
+ && !AnimatedFloatExpression.isMathOperator(v)
+ && !NanMap.isDataVariable(v)) {
+ context.listensTo(Utils.idFromNan(v), this);
+ }
+ }
+ }
+ for (int i = 0; i < mEquations.length; i++) {
+ float[] mEquation = mEquations[i];
+ for (float v : mEquation) {
+ if (Float.isNaN(v)
+ && !AnimatedFloatExpression.isMathOperator(v)
+ && !NanMap.isDataVariable(v)) {
+ context.listensTo(Utils.idFromNan(v), this);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void write(@NonNull WireBuffer buffer) {
+ apply(buffer, mId, mRestart, mEquations);
+ }
+
+ @NonNull
+ @Override
+ public String toString() {
+ String str = "ParticlesLoop[" + Utils.idString(mId) + "] ";
+ return str;
+ }
+
+ /**
+ * Write the operation on the buffer
+ *
+ * @param buffer
+ * @param id
+ * @param restart
+ * @param equations
+ */
+ public static void apply(
+ @NonNull WireBuffer buffer,
+ int id,
+ @Nullable float[] restart,
+ @NonNull float[][] equations) {
+ buffer.start(OP_CODE);
+ buffer.writeInt(id);
+ if (restart != null) {
+ buffer.writeInt(restart.length);
+ for (int i = 0; i < restart.length; i++) {
+ buffer.writeFloat(restart[i]);
+ }
+ } else {
+ buffer.writeInt(0);
+ }
+ buffer.writeInt(equations.length);
+ for (int i = 0; i < equations.length; i++) {
+ buffer.writeInt(equations[i].length);
+ for (int j = 0; j < equations[i].length; j++) {
+ buffer.writeFloat(equations[i][j]);
+ }
+ }
+ }
+
+ /**
+ * Read this operation and add it to the list of operations
+ *
+ * @param buffer the buffer to read
+ * @param operations the list of operations that will be added to
+ */
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
+ int id = buffer.readInt();
+ int restartLen = buffer.readInt();
+ float[] restart = null;
+ if (restartLen > 0) {
+ restart = new float[restartLen];
+ for (int i = 0; i < restartLen; i++) {
+ restart[i] = buffer.readFloat();
+ }
+ }
+
+ int varLen = buffer.readInt();
+ if (varLen > MAX_FLOAT_ARRAY) {
+ throw new RuntimeException(varLen + " map entries more than max = " + MAX_FLOAT_ARRAY);
+ }
+
+ float[][] equations = new float[varLen][];
+ for (int i = 0; i < varLen; i++) {
+
+ int equLen = buffer.readInt();
+ if (equLen > MAX_EQU_LENGTH) {
+ throw new RuntimeException(
+ equLen + " map entries more than max = " + MAX_FLOAT_ARRAY);
+ }
+ equations[i] = new float[equLen];
+ for (int j = 0; j < equations[i].length; j++) {
+ equations[i][j] = buffer.readFloat();
+ }
+ }
+ ParticlesLoop data = new ParticlesLoop(id, restart, equations);
+ operations.add(data);
+ }
+
+ /**
+ * Populate the documentation with a description of this operation
+ *
+ * @param doc to append the description to.
+ */
+ public static void documentation(@NonNull DocumentationBuilder doc) {
+ doc.operation("Data Operations", OP_CODE, CLASS_NAME)
+ .description("This evolves the particles & recycles them")
+ .field(DocumentedOperation.INT, "id", "id of particle system")
+ .field(
+ INT,
+ "recycleLen",
+ "the number of floats in restart equeation if 0 no restart")
+ .field(FLOAT_ARRAY, "values", "recycleLen", "array of floats")
+ .field(INT, "varLen", "the number of equations to follow")
+ .field(INT, "equLen", "the number of equations to follow")
+ .field(FLOAT_ARRAY, "values", "equLen", "floats for the equation");
+ }
+
+ @NonNull
+ @Override
+ public String deepToString(@NonNull String indent) {
+ return indent + toString();
+ }
+
+ @Override
+ public void paint(@NonNull PaintContext context) {
+ RemoteContext remoteContext = context.getContext();
+ for (int i = 0; i < mParticles.length; i++) {
+ // Save the values to context TODO hand code the update
+ for (int j = 0; j < mParticles[i].length; j++) {
+ remoteContext.loadFloat(mVarId[j], mParticles[i][j]);
+ updateVariables(remoteContext);
+ }
+ // Evaluate the update function
+ for (int j = 0; j < mParticles[i].length; j++) {
+ mParticles[i][j] = mExp.eval(mOutEquations[j], mOutEquations[j].length);
+ remoteContext.loadFloat(mVarId[j], mParticles[i][j]);
+ }
+ // test for reset
+ if (mOutRestart != null) {
+ for (int k = 0; k < mRestart.length; k++) {
+ float v = mRestart[k];
+ mOutRestart[k] =
+ (Float.isNaN(v)
+ && !AnimatedFloatExpression.isMathOperator(v)
+ && !NanMap.isDataVariable(v))
+ ? remoteContext.getFloat(Utils.idFromNan(v))
+ : v;
+ }
+ if (mExp.eval(mOutRestart, mOutRestart.length) > 0) {
+ mParticlesSource.initializeParticle(i);
+ }
+ }
+
+ for (Operation op : mList) {
+ if (op instanceof VariableSupport) {
+ ((VariableSupport) op).updateVariables(context.getContext());
+ }
+
+ remoteContext.incrementOpCount();
+ op.apply(context.getContext());
+ }
+ }
+ }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/RootContentBehavior.java b/core/java/com/android/internal/widget/remotecompose/core/operations/RootContentBehavior.java
index 55dd88233265..129201c2b2d2 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/RootContentBehavior.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/RootContentBehavior.java
@@ -219,6 +219,15 @@ public class RootContentBehavior extends Operation implements RemoteComposeOpera
return OP_CODE;
}
+ /**
+ * Write the operation on the buffer
+ *
+ * @param buffer
+ * @param scroll
+ * @param alignment
+ * @param sizing
+ * @param mode
+ */
public static void apply(
@NonNull WireBuffer buffer, int scroll, int alignment, int sizing, int mode) {
buffer.start(OP_CODE);
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/RootContentDescription.java b/core/java/com/android/internal/widget/remotecompose/core/operations/RootContentDescription.java
index ad86e0f2b1f3..c1ddf63264fa 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/RootContentDescription.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/RootContentDescription.java
@@ -95,6 +95,12 @@ public class RootContentDescription extends Operation
return OP_CODE;
}
+ /**
+ * Write the operation on the buffer
+ *
+ * @param buffer
+ * @param contentDescription
+ */
public static void apply(@NonNull WireBuffer buffer, int contentDescription) {
buffer.start(Operations.ROOT_CONTENT_DESCRIPTION);
buffer.writeInt(contentDescription);
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/Theme.java b/core/java/com/android/internal/widget/remotecompose/core/operations/Theme.java
index e9aae1ebad45..1698ecb9d3fc 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/Theme.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/Theme.java
@@ -92,6 +92,12 @@ public class Theme extends Operation implements RemoteComposeOperation {
return OP_CODE;
}
+ /**
+ * Write the operation on the buffer
+ *
+ * @param buffer
+ * @param theme
+ */
public static void apply(@NonNull WireBuffer buffer, int theme) {
buffer.start(OP_CODE);
buffer.writeInt(theme);
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/TouchExpression.java b/core/java/com/android/internal/widget/remotecompose/core/operations/TouchExpression.java
index 3b293bd1b8e0..997628140c46 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/TouchExpression.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/TouchExpression.java
@@ -368,6 +368,7 @@ public class TouchExpression extends Operation implements VariableSupport, Touch
*
* @param component the component, or null if outside
*/
+ @Override
public void setComponent(@Nullable Component component) {
mComponent = component;
if (mComponent != null) {
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/CanvasContent.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/CanvasContent.java
index 511858aa2b29..abb7ad8910f9 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/CanvasContent.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/CanvasContent.java
@@ -66,6 +66,12 @@ public class CanvasContent extends Component {
return "CANVAS_CONTENT";
}
+ /**
+ * Write the operation on the buffer
+ *
+ * @param buffer
+ * @param componentId
+ */
public static void apply(@NonNull WireBuffer buffer, int componentId) {
buffer.start(Operations.LAYOUT_CANVAS_CONTENT);
buffer.writeInt(componentId);
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ClickModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ClickModifierOperation.java
index 5f084e938588..110bd3079697 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ClickModifierOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ClickModifierOperation.java
@@ -77,6 +77,12 @@ public class ClickModifierOperation extends PaintOperation
return CoreSemantics.Mode.MERGE;
}
+ /**
+ * Animate ripple
+ *
+ * @param x starting position x of the ripple
+ * @param y starting position y of the ripple
+ */
public void animateRipple(float x, float y) {
mAnimateRippleStart = System.currentTimeMillis();
mAnimateRippleX = x;
@@ -212,6 +218,11 @@ public class ClickModifierOperation extends PaintOperation
return "ClickModifier";
}
+ /**
+ * Write the operation on the buffer
+ *
+ * @param buffer
+ */
public static void apply(@NonNull WireBuffer buffer) {
buffer.start(OP_CODE);
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/Component.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/Component.java
index eee2aabe1d8b..8e733ce1d808 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/Component.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/Component.java
@@ -24,6 +24,7 @@ import com.android.internal.widget.remotecompose.core.PaintContext;
import com.android.internal.widget.remotecompose.core.PaintOperation;
import com.android.internal.widget.remotecompose.core.RemoteContext;
import com.android.internal.widget.remotecompose.core.SerializableToString;
+import com.android.internal.widget.remotecompose.core.TouchListener;
import com.android.internal.widget.remotecompose.core.VariableSupport;
import com.android.internal.widget.remotecompose.core.WireBuffer;
import com.android.internal.widget.remotecompose.core.operations.ComponentValue;
@@ -236,6 +237,7 @@ public class Component extends PaintOperation
finalizeCreation();
}
+ /** Callback on component creation TODO: replace with inflate() */
public void finalizeCreation() {
for (Operation op : mList) {
if (op instanceof Component) {
@@ -273,6 +275,11 @@ public class Component extends PaintOperation
context.mLastComponent = prev;
}
+ /**
+ * Add a component value to the component
+ *
+ * @param v
+ */
public void addComponentValue(@NonNull ComponentValue v) {
mComponentValues.add(v);
}
@@ -303,10 +310,10 @@ public class Component extends PaintOperation
*/
public void inflate() {
for (Operation op : mList) {
- if (op instanceof TouchExpression) {
+ if (op instanceof TouchListener) {
// Make sure to set the component of a touch expression that belongs to us!
- TouchExpression touchExpression = (TouchExpression) op;
- touchExpression.setComponent(this);
+ TouchListener touchListener = (TouchListener) op;
+ touchListener.setComponent(this);
}
}
}
@@ -317,6 +324,11 @@ public class Component extends PaintOperation
INVISIBLE
}
+ /**
+ * Returns true if the component is visible
+ *
+ * @return
+ */
public boolean isVisible() {
if (mVisibility != Visibility.VISIBLE || mParent == null) {
return mVisibility == Visibility.VISIBLE;
@@ -327,6 +339,11 @@ public class Component extends PaintOperation
return true;
}
+ /**
+ * Set the visibility of the component
+ *
+ * @param visibility can be VISIBLE, INVISIBLE or GONE
+ */
public void setVisibility(@NonNull Visibility visibility) {
if (visibility != mVisibility || visibility != mScheduledVisibility) {
mScheduledVisibility = visibility;
@@ -443,6 +460,13 @@ public class Component extends PaintOperation
@NonNull public float[] locationInWindow = new float[2];
+ /**
+ * Hit detection -- returns true if the point (x, y) is inside the component
+ *
+ * @param x
+ * @param y
+ * @return
+ */
public boolean contains(float x, float y) {
locationInWindow[0] = 0f;
locationInWindow[1] = 0f;
@@ -454,14 +478,32 @@ public class Component extends PaintOperation
return x >= lx1 && x < lx2 && y >= ly1 && y < ly2;
}
+ /**
+ * Returns the horizontal scroll value of the content of this component
+ *
+ * @return 0 if no scroll
+ */
public float getScrollX() {
return 0;
}
+ /**
+ * Returns the vertical scroll value of the content of this component
+ *
+ * @return 0 if no scroll
+ */
public float getScrollY() {
return 0;
}
+ /**
+ * Click handler
+ *
+ * @param context
+ * @param document
+ * @param x
+ * @param y
+ */
public void onClick(
@NonNull RemoteContext context, @NonNull CoreDocument document, float x, float y) {
if (!contains(x, y)) {
@@ -479,6 +521,14 @@ public class Component extends PaintOperation
}
}
+ /**
+ * Touch down handler
+ *
+ * @param context
+ * @param document
+ * @param x
+ * @param y
+ */
public void onTouchDown(RemoteContext context, CoreDocument document, float x, float y) {
if (!contains(x, y)) {
return;
@@ -501,6 +551,17 @@ public class Component extends PaintOperation
}
}
+ /**
+ * Touch Up handler
+ *
+ * @param context
+ * @param document
+ * @param x
+ * @param y
+ * @param dx
+ * @param dy
+ * @param force
+ */
public void onTouchUp(
RemoteContext context,
CoreDocument document,
@@ -529,6 +590,15 @@ public class Component extends PaintOperation
}
}
+ /**
+ * Touch Cancel handler
+ *
+ * @param context
+ * @param document
+ * @param x
+ * @param y
+ * @param force
+ */
public void onTouchCancel(
RemoteContext context, CoreDocument document, float x, float y, boolean force) {
if (!force && !contains(x, y)) {
@@ -551,6 +621,15 @@ public class Component extends PaintOperation
}
}
+ /**
+ * Touch Drag handler
+ *
+ * @param context
+ * @param document
+ * @param x
+ * @param y
+ * @param force
+ */
public void onTouchDrag(
RemoteContext context, CoreDocument document, float x, float y, boolean force) {
if (!force && !contains(x, y)) {
@@ -573,6 +652,12 @@ public class Component extends PaintOperation
}
}
+ /**
+ * Returns the location of the component relative to the root component
+ *
+ * @param value a 2 dimension float array that will receive the horizontal and vertical position
+ * of the component.
+ */
public void getLocationInWindow(@NonNull float[] value) {
value[0] += mX;
value[1] += mY;
@@ -681,6 +766,7 @@ public class Component extends PaintOperation
}
}
+ /** Mark the tree as needing a repaint */
public void needsRepaint() {
try {
getRoot().mNeedsRepaint = true;
@@ -689,6 +775,11 @@ public class Component extends PaintOperation
}
}
+ /**
+ * Debugging function returning the list of child operations
+ *
+ * @return a formatted string with the list of operations
+ */
@NonNull
public String content() {
StringBuilder builder = new StringBuilder();
@@ -700,6 +791,11 @@ public class Component extends PaintOperation
return builder.toString();
}
+ /**
+ * Returns a string containing the text operations if any
+ *
+ * @return
+ */
@NonNull
public String textContent() {
StringBuilder builder = new StringBuilder();
@@ -713,6 +809,12 @@ public class Component extends PaintOperation
return builder.toString();
}
+ /**
+ * Utility debug function
+ *
+ * @param component
+ * @param context
+ */
public void debugBox(@NonNull Component component, @NonNull PaintContext context) {
float width = component.mWidth;
float height = component.mHeight;
@@ -731,11 +833,22 @@ public class Component extends PaintOperation
context.restorePaint();
}
+ /**
+ * Set the position of this component relative to its parent
+ *
+ * @param x horizontal position
+ * @param y vertical position
+ */
public void setLayoutPosition(float x, float y) {
this.mX = x;
this.mY = y;
}
+ /**
+ * The vertical position of this component relative to its parent
+ *
+ * @return
+ */
public float getTranslateX() {
if (mParent != null) {
return mX - mParent.mX;
@@ -743,6 +856,11 @@ public class Component extends PaintOperation
return 0f;
}
+ /**
+ * The horizontal position of this component relative to its parent
+ *
+ * @return
+ */
public float getTranslateY() {
if (mParent != null) {
return mY - mParent.mY;
@@ -750,6 +868,11 @@ public class Component extends PaintOperation
return 0f;
}
+ /**
+ * Paint the component itself.
+ *
+ * @param context
+ */
public void paintingComponent(@NonNull PaintContext context) {
if (mPreTranslate != null) {
mPreTranslate.paint(context);
@@ -778,6 +901,12 @@ public class Component extends PaintOperation
context.getContext().mLastComponent = prev;
}
+ /**
+ * If animation is turned on and we need to be animated, we'll apply it.
+ *
+ * @param context
+ * @return
+ */
public boolean applyAnimationAsNeeded(@NonNull PaintContext context) {
if (context.isAnimationEnabled() && mAnimateMeasure != null) {
mAnimateMeasure.paint(context);
@@ -822,6 +951,11 @@ public class Component extends PaintOperation
paintingComponent(context);
}
+ /**
+ * Extract child components
+ *
+ * @param components an ArrayList that will be populated by child components (if any)
+ */
public void getComponents(@NonNull ArrayList<Component> components) {
for (Operation op : mList) {
if (op instanceof Component) {
@@ -830,6 +964,11 @@ public class Component extends PaintOperation
}
}
+ /**
+ * Extract child TextData elements
+ *
+ * @param data an ArrayList that will be populated with the TextData elements (if any)
+ */
public void getData(@NonNull ArrayList<TextData> data) {
for (Operation op : mList) {
if (op instanceof TextData) {
@@ -838,6 +977,11 @@ public class Component extends PaintOperation
}
}
+ /**
+ * Returns the number of children components
+ *
+ * @return
+ */
public int getComponentCount() {
int count = 0;
for (Operation op : mList) {
@@ -848,6 +992,12 @@ public class Component extends PaintOperation
return count;
}
+ /**
+ * Return the id used for painting the component -- either its component id or its animation id
+ * (if set)
+ *
+ * @return
+ */
public int getPaintId() {
if (mAnimationId != -1) {
return mAnimationId;
@@ -855,10 +1005,21 @@ public class Component extends PaintOperation
return mComponentId;
}
+ /**
+ * Return true if the needsRepaint flag is set on this component
+ *
+ * @return
+ */
public boolean doesNeedsRepaint() {
return mNeedsRepaint;
}
+ /**
+ * Utility function to return a component from its id
+ *
+ * @param cid
+ * @return
+ */
@Nullable
public Component getComponent(int cid) {
if (mComponentId == cid || mAnimationId == cid) {
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentStart.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentStart.java
index f009d8801159..5ef71d006107 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentStart.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ComponentStart.java
@@ -126,6 +126,12 @@ public class ComponentStart extends Operation implements Container {
public static final int LAYOUT_ROW = 15;
public static final int LAYOUT_COLUMN = 16;
+ /**
+ * Returns the string representation of the component type
+ *
+ * @param type
+ * @return a string representing the component type
+ */
@NonNull
public static String typeDescription(int type) {
switch (type) {
@@ -179,6 +185,15 @@ public class ComponentStart extends Operation implements Container {
return Operations.COMPONENT_START;
}
+ /**
+ * Write the operation on the buffer
+ *
+ * @param buffer
+ * @param type
+ * @param componentId
+ * @param width
+ * @param height
+ */
public static void apply(
@NonNull WireBuffer buffer, int type, int componentId, float width, float height) {
buffer.start(Operations.COMPONENT_START);
@@ -188,6 +203,11 @@ public class ComponentStart extends Operation implements Container {
buffer.writeFloat(height);
}
+ /**
+ * Return the size of the operation in byte
+ *
+ * @return the size in byte
+ */
public static int size() {
return 1 + 4 + 4 + 4;
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/Container.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/Container.java
index c678f6c22cef..41e2bf801009 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/Container.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/Container.java
@@ -21,7 +21,13 @@ import com.android.internal.widget.remotecompose.core.Operation;
import java.util.ArrayList;
+/** An Operation container */
public interface Container {
+ /**
+ * Returns a list of child operations
+ *
+ * @return a list of child operations
+ */
@NonNull
ArrayList<Operation> getList();
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ContainerEnd.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ContainerEnd.java
index 4290c4bc3c2b..004f19407c90 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ContainerEnd.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ContainerEnd.java
@@ -68,6 +68,11 @@ public class ContainerEnd extends Operation {
return Operations.CONTAINER_END;
}
+ /**
+ * Write the operation on the buffer
+ *
+ * @param buffer
+ */
public static void apply(@NonNull WireBuffer buffer) {
buffer.start(id());
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ImpulseOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ImpulseOperation.java
new file mode 100644
index 000000000000..e277d49325be
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ImpulseOperation.java
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations.layout;
+
+import android.annotation.NonNull;
+
+import com.android.internal.widget.remotecompose.core.Operation;
+import com.android.internal.widget.remotecompose.core.Operations;
+import com.android.internal.widget.remotecompose.core.PaintContext;
+import com.android.internal.widget.remotecompose.core.PaintOperation;
+import com.android.internal.widget.remotecompose.core.RemoteContext;
+import com.android.internal.widget.remotecompose.core.VariableSupport;
+import com.android.internal.widget.remotecompose.core.WireBuffer;
+import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder;
+import com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation;
+import com.android.internal.widget.remotecompose.core.operations.Utils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Represents a Impulse Event To trigger an impulse event. set the startAt time to the
+ * context.getAnimationTime() Impluse Operation. This operation execute a list of actions once and
+ * the impluseProcess is executed for a fixed duration
+ */
+public class ImpulseOperation extends PaintOperation implements VariableSupport, Container {
+ private static final int OP_CODE = Operations.IMPULSE_START;
+ private static final String CLASS_NAME = "ImpulseOperation";
+ private float mDuration;
+ private float mStartAt;
+ private float mOutDuration;
+ private float mOutStartAt;
+ private boolean mInitialPass = true;
+ @NonNull public ArrayList<Operation> mList = new ArrayList<>();
+
+ int mIndexVariableId;
+
+ private ImpulseProcess mProcess;
+
+ /**
+ * Constructor for a Impulse Operation
+ *
+ * @param duration the duration of the impluse
+ * @param startAt the start time of the impluse
+ */
+ public ImpulseOperation(float duration, float startAt) {
+ mDuration = duration;
+ mStartAt = startAt;
+ mOutStartAt = startAt;
+ mOutDuration = duration;
+ }
+
+ @Override
+ public void registerListening(RemoteContext context) {
+ if (mProcess == null) {
+ System.out.println(".....");
+ Operation last = mList.get(mList.size() - 1);
+ if (last instanceof ImpulseProcess) {
+ mProcess = (ImpulseProcess) last;
+ mList.remove(last);
+ }
+ }
+ if (Float.isNaN(mStartAt)) {
+ context.listensTo(Utils.idFromNan(mStartAt), this);
+ }
+ if (Float.isNaN(mDuration)) {
+ context.listensTo(Utils.idFromNan(mDuration), this);
+ }
+ for (Operation operation : mList) {
+ if (operation instanceof VariableSupport) {
+ VariableSupport variableSupport = (VariableSupport) operation;
+ variableSupport.registerListening(context);
+ }
+ }
+ if (mProcess != null) {
+ mProcess.registerListening(context);
+ }
+ }
+
+ @Override
+ public void updateVariables(RemoteContext context) {
+
+ mOutDuration =
+ Float.isNaN(mDuration) ? context.getFloat(Utils.idFromNan(mDuration)) : mDuration;
+
+ mOutStartAt =
+ Float.isNaN(mStartAt) ? context.getFloat(Utils.idFromNan(mStartAt)) : mStartAt;
+ if (mProcess != null) {
+ mProcess.updateVariables(context);
+ }
+ }
+
+ @NonNull
+ public ArrayList<Operation> getList() {
+ return mList;
+ }
+
+ @Override
+ public void write(@NonNull WireBuffer buffer) {
+ apply(buffer, mDuration, mStartAt);
+ }
+
+ @NonNull
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder("LoopOperation\n");
+ for (Operation operation : mList) {
+ builder.append(" startAt: ");
+ builder.append(mStartAt);
+ builder.append(" duration: ");
+ builder.append(mDuration);
+ builder.append("\n");
+ }
+ return builder.toString();
+ }
+
+ @NonNull
+ @Override
+ public String deepToString(@NonNull String indent) {
+ return (indent != null ? indent : "") + toString();
+ }
+
+ @Override
+ public void paint(@NonNull PaintContext context) {
+ RemoteContext remoteContext = context.getContext();
+
+ if (remoteContext.getAnimationTime() < mOutStartAt + mOutDuration) {
+ if (mInitialPass) {
+ for (Operation op : mList) {
+ if (op instanceof VariableSupport && op.isDirty()) {
+ ((VariableSupport) op).updateVariables(context.getContext());
+ }
+ remoteContext.incrementOpCount();
+ op.apply(context.getContext());
+ }
+ mInitialPass = false;
+ } else {
+ remoteContext.incrementOpCount();
+ if (mProcess != null) {
+ mProcess.paint(context);
+ }
+ }
+ } else {
+ mInitialPass = true;
+ }
+ }
+
+ /**
+ * The name of the class
+ *
+ * @return the name
+ */
+ @NonNull
+ public static String name() {
+ return CLASS_NAME;
+ }
+
+ /**
+ * Write the operation on the buffer
+ *
+ * @param buffer
+ * @param duration
+ * @param startAt
+ */
+ public static void apply(@NonNull WireBuffer buffer, float duration, float startAt) {
+ buffer.start(OP_CODE);
+ buffer.writeFloat(duration);
+ buffer.writeFloat(startAt);
+ }
+
+ /**
+ * Read this operation and add it to the list of operations
+ *
+ * @param buffer the buffer to read
+ * @param operations the list of operations that will be added to
+ */
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
+ float duration = buffer.readFloat();
+ float startAt = buffer.readFloat();
+
+ operations.add(new ImpulseOperation(duration, startAt));
+ }
+
+ /**
+ * Populate the documentation with a description of this operation
+ *
+ * @param doc to append the description to.
+ */
+ public static void documentation(@NonNull DocumentationBuilder doc) {
+ doc.operation("Operations", OP_CODE, name())
+ .description(
+ "Impulse Operation. This operation execute a list of action for a fixed"
+ + " duration")
+ .field(DocumentedOperation.FLOAT, "duration", "How long to last")
+ .field(DocumentedOperation.FLOAT, "startAt", "value step");
+ }
+
+ /**
+ * Calculate and estimate of the number of iterations
+ *
+ * @return number of loops or 10 if based on variables
+ */
+ public int estimateIterations() {
+ if (Float.isNaN(mDuration)) {
+ return 10; // this is a generic estmate if the values are variables;
+ }
+ return (int) (mDuration * 60);
+ }
+
+ /**
+ * set the impulse process. This gets executed for the duration of the impulse
+ *
+ * @param impulseProcess process to be executed every time
+ */
+ public void setProcess(ImpulseProcess impulseProcess) {
+ mProcess = impulseProcess;
+ }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ImpulseProcess.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ImpulseProcess.java
new file mode 100644
index 000000000000..f896f3d8ee9c
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ImpulseProcess.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations.layout;
+
+import android.annotation.NonNull;
+
+import com.android.internal.widget.remotecompose.core.Operation;
+import com.android.internal.widget.remotecompose.core.Operations;
+import com.android.internal.widget.remotecompose.core.PaintContext;
+import com.android.internal.widget.remotecompose.core.PaintOperation;
+import com.android.internal.widget.remotecompose.core.RemoteContext;
+import com.android.internal.widget.remotecompose.core.VariableSupport;
+import com.android.internal.widget.remotecompose.core.WireBuffer;
+import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/** Represents the repeating part of an Impulse. */
+public class ImpulseProcess extends PaintOperation implements VariableSupport, Container {
+ private static final int OP_CODE = Operations.IMPULSE_PROCESS;
+ private static final String CLASS_NAME = "ImpulseProcess";
+
+ @NonNull public ArrayList<Operation> mList = new ArrayList<>();
+
+ /** The constructor */
+ public ImpulseProcess() {}
+
+ @Override
+ public void registerListening(RemoteContext context) {
+ for (Operation operation : mList) {
+ if (operation instanceof VariableSupport) {
+ VariableSupport variableSupport = (VariableSupport) operation;
+ variableSupport.registerListening(context);
+ }
+ }
+ }
+
+ @Override
+ public void updateVariables(RemoteContext context) {
+ for (Operation operation : mList) {
+ if (operation instanceof VariableSupport) {
+ VariableSupport variableSupport = (VariableSupport) operation;
+ variableSupport.updateVariables(context);
+ }
+ }
+ }
+
+ /**
+ * The returns a list to be filled
+ *
+ * @return list to be filled
+ */
+ @NonNull
+ public ArrayList<Operation> getList() {
+ return mList;
+ }
+
+ @Override
+ public void write(@NonNull WireBuffer buffer) {
+ apply(buffer);
+ }
+
+ @NonNull
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder(CLASS_NAME + "\n");
+ for (Operation operation : mList) {
+ builder.append(" ");
+ builder.append(operation);
+ builder.append("\n");
+ }
+ return builder.toString();
+ }
+
+ @NonNull
+ @Override
+ public String deepToString(@NonNull String indent) {
+ return (indent != null ? indent : "") + toString();
+ }
+
+ @Override
+ public void paint(@NonNull PaintContext context) {
+ RemoteContext remoteContext = context.getContext();
+ for (Operation op : mList) {
+ if (op instanceof VariableSupport && op.isDirty()) {
+ ((VariableSupport) op).updateVariables(context.getContext());
+ }
+ remoteContext.incrementOpCount();
+ op.apply(context.getContext());
+ }
+ }
+
+ /**
+ * The name of the class
+ *
+ * @return the name
+ */
+ @NonNull
+ public static String name() {
+ return "Loop";
+ }
+
+ /**
+ * Apply this operation to the buffer
+ *
+ * @param buffer
+ */
+ public static void apply(@NonNull WireBuffer buffer) {
+ buffer.start(OP_CODE);
+ }
+
+ /**
+ * Read this operation and add it to the list of operations
+ *
+ * @param buffer the buffer to read
+ * @param operations the list of operations that will be added to
+ */
+ public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
+ operations.add(new ImpulseProcess());
+ }
+
+ /**
+ * Populate the documentation with a description of this operation
+ *
+ * @param doc to append the description to.
+ */
+ public static void documentation(@NonNull DocumentationBuilder doc) {
+ doc.operation("Operations", OP_CODE, name())
+ .description("Impulse Process that runs a list of operations");
+ }
+
+ /**
+ * Calculate and estimate of the number of iterations
+ *
+ * @return number of loops or 10 if based on variables
+ */
+ public int estimateIterations() {
+ return 1;
+ }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponent.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponent.java
index 91038852573e..e71cb9a51830 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponent.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponent.java
@@ -22,6 +22,7 @@ import com.android.internal.widget.remotecompose.core.Operation;
import com.android.internal.widget.remotecompose.core.OperationInterface;
import com.android.internal.widget.remotecompose.core.PaintContext;
import com.android.internal.widget.remotecompose.core.RemoteContext;
+import com.android.internal.widget.remotecompose.core.TouchListener;
import com.android.internal.widget.remotecompose.core.VariableSupport;
import com.android.internal.widget.remotecompose.core.operations.BitmapData;
import com.android.internal.widget.remotecompose.core.operations.FloatExpression;
@@ -176,8 +177,8 @@ public class LayoutComponent extends Component {
|| (op instanceof PaintData)
|| (op instanceof FloatExpression)) {
supportedOperations.add(op);
- if (op instanceof TouchExpression) {
- ((TouchExpression) op).setComponent(this);
+ if (op instanceof TouchListener) {
+ ((TouchListener) op).setComponent(this);
}
} else {
// nothing
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponentContent.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponentContent.java
index 27172aa7672c..4babe5f036a5 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponentContent.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponentContent.java
@@ -66,6 +66,12 @@ public class LayoutComponentContent extends Component {
return "CONTENT";
}
+ /**
+ * Write the operation on the buffer
+ *
+ * @param buffer
+ * @param componentId
+ */
public static void apply(@NonNull WireBuffer buffer, int componentId) {
buffer.start(Operations.LAYOUT_CONTENT);
buffer.writeInt(componentId);
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ListActionsOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ListActionsOperation.java
index 6dce6f115572..bfa417e87637 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ListActionsOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/ListActionsOperation.java
@@ -88,6 +88,18 @@ public abstract class ListActionsOperation extends PaintOperation
}
}
+ /**
+ * Execute the list of actions
+ *
+ * @param context the RemoteContext
+ * @param document the current document
+ * @param component the component we belong to
+ * @param x the x touch down coordinate
+ * @param y the y touch down coordinate
+ * @param force if true, will apply the actions even if the component is not visible / not
+ * containing the touch down coordinates
+ * @return true if we applied the actions, false otherwise
+ */
public boolean applyActions(
RemoteContext context,
CoreDocument document,
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LoopOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LoopOperation.java
index f5954eea04af..0f4cf562eae6 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LoopOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LoopOperation.java
@@ -33,6 +33,7 @@ import java.util.List;
/** Represents a loop of operations */
public class LoopOperation extends PaintOperation implements Container, VariableSupport {
+
private static final int OP_CODE = Operations.LOOP_START;
@NonNull public ArrayList<Operation> mList = new ArrayList<>();
@@ -77,6 +78,7 @@ public class LoopOperation extends PaintOperation implements Container, Variable
mIndexVariableId = indexId;
}
+ @Override
@NonNull
public ArrayList<Operation> getList() {
return mList;
@@ -139,6 +141,15 @@ public class LoopOperation extends PaintOperation implements Container, Variable
return "Loop";
}
+ /**
+ * Write the operation on the buffer
+ *
+ * @param buffer
+ * @param indexId
+ * @param from
+ * @param step
+ * @param until
+ */
public static void apply(
@NonNull WireBuffer buffer, int indexId, float from, float step, float until) {
buffer.start(OP_CODE);
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/RootLayoutComponent.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/RootLayoutComponent.java
index baff5ee488a7..f94cda21aca7 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/RootLayoutComponent.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/RootLayoutComponent.java
@@ -174,6 +174,11 @@ public class RootLayoutComponent extends Component {
context.restore();
}
+ /**
+ * Display the component hierarchy
+ *
+ * @return a formatted string containing the component hierarchy
+ */
@NonNull
public String displayHierarchy() {
StringSerializer serializer = new StringSerializer();
@@ -181,6 +186,13 @@ public class RootLayoutComponent extends Component {
return serializer.toString();
}
+ /**
+ * Display the component hierarchy
+ *
+ * @param component the current component
+ * @param indent the current indentation level
+ * @param serializer the serializer we write to
+ */
public void displayHierarchy(
@NonNull Component component, int indent, @NonNull StringSerializer serializer) {
component.serializeToString(indent, serializer);
@@ -214,6 +226,12 @@ public class RootLayoutComponent extends Component {
return Operations.LAYOUT_ROOT;
}
+ /**
+ * Write the operation on the buffer
+ *
+ * @param buffer
+ * @param componentId
+ */
public static void apply(@NonNull WireBuffer buffer, int componentId) {
buffer.start(Operations.LAYOUT_ROOT);
buffer.writeInt(componentId);
@@ -249,6 +267,11 @@ public class RootLayoutComponent extends Component {
apply(buffer, mComponentId);
}
+ /**
+ * Returns true if we have components with a touch listener
+ *
+ * @return true if listeners, false otherwise
+ */
public boolean hasTouchListeners() {
return mHasTouchListeners;
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/utils/DebugLog.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/utils/DebugLog.java
index 842c9c161aee..96e29cdd01ab 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/utils/DebugLog.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/utils/DebugLog.java
@@ -40,6 +40,11 @@ public class DebugLog {
}
}
+ /**
+ * Add a node to the current node
+ *
+ * @param node
+ */
public void add(@NonNull Node node) {
list.add(node);
}
@@ -54,23 +59,35 @@ public class DebugLog {
@NonNull public static Node node = new Node(null, "Root");
@NonNull public static Node currentNode = node;
+ /** clear the current logging */
public static void clear() {
node = new Node(null, "Root");
currentNode = node;
}
+ /**
+ * start a node
+ *
+ * @param valueSupplier
+ */
public static void s(@NonNull StringValueSupplier valueSupplier) {
if (DEBUG_LAYOUT_ON) {
currentNode = new Node(currentNode, valueSupplier.getString());
}
}
+ /**
+ * arbitrary log statement
+ *
+ * @param valueSupplier
+ */
public static void log(@NonNull StringValueSupplier valueSupplier) {
if (DEBUG_LAYOUT_ON) {
new LogNode(currentNode, valueSupplier.getString());
}
}
+ /** end a node */
public static void e() {
if (DEBUG_LAYOUT_ON) {
if (currentNode.parent != null) {
@@ -81,6 +98,11 @@ public class DebugLog {
}
}
+ /**
+ * end a node
+ *
+ * @param valueSupplier
+ */
public static void e(@NonNull StringValueSupplier valueSupplier) {
if (DEBUG_LAYOUT_ON) {
currentNode.endString = valueSupplier.getString();
@@ -92,6 +114,13 @@ public class DebugLog {
}
}
+ /**
+ * print a given node
+ *
+ * @param indent
+ * @param node
+ * @param builder
+ */
public static void printNode(int indent, @NonNull Node node, @NonNull StringBuilder builder) {
if (DEBUG_LAYOUT_ON) {
StringBuilder indentationBuilder = new StringBuilder();
@@ -121,6 +150,7 @@ public class DebugLog {
}
}
+ /** Output the captured log to System.out */
public static void display() {
if (DEBUG_LAYOUT_ON) {
StringBuilder builder = new StringBuilder();
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/AnimatedFloatExpression.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/AnimatedFloatExpression.java
index 7e467012536d..b2ea0afd8fab 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/AnimatedFloatExpression.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/AnimatedFloatExpression.java
@@ -162,7 +162,7 @@ public class AnimatedFloatExpression {
/** VAR2 operator */
public static final float VAR3 = asNan(OFFSET + 43);
- // TODO CLAMP, CBRT, DEG, RAD, EXPM1, CEIL, FLOOR
+ // TODO SQUARE, DUP, HYPOT, SWAP
// private static final float FP_PI = (float) Math.PI;
private static final float FP_TO_RAD = 57.29578f; // 180/PI
private static final float FP_TO_DEG = 0.017453292f; // 180/PI
@@ -172,7 +172,7 @@ public class AnimatedFloatExpression {
@NonNull float[] mVar = new float[0];
@Nullable CollectionsAccess mCollectionsAccess;
IntMap<MonotonicSpline> mSplineMap = new IntMap<>();
- private Random mRandom;
+ private static Random sRandom;
private float getSplineValue(int arrayId, float pos) {
MonotonicSpline fit = mSplineMap.get(arrayId);
@@ -806,21 +806,21 @@ public class AnimatedFloatExpression {
return sp - 1;
case OP_RAND:
- if (mRandom == null) {
- mRandom = new Random();
+ if (sRandom == null) {
+ sRandom = new Random();
}
- mStack[sp + 1] = mRandom.nextFloat();
+ mStack[sp + 1] = sRandom.nextFloat();
return sp + 1;
case OP_RAND_SEED:
float seed = mStack[sp];
if (seed == 0) {
- mRandom = new Random();
+ sRandom = new Random();
} else {
- if (mRandom == null) {
- mRandom = new Random(Float.floatToRawIntBits(seed));
+ if (sRandom == null) {
+ sRandom = new Random(Float.floatToRawIntBits(seed));
} else {
- mRandom.setSeed(Float.floatToRawIntBits(seed));
+ sRandom.setSeed(Float.floatToRawIntBits(seed));
}
}
return sp - 1;
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/touch/VelocityEasing.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/touch/VelocityEasing.java
index c7e2442221cd..56a041026c1f 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/touch/VelocityEasing.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/touch/VelocityEasing.java
@@ -108,14 +108,14 @@ public class VelocityEasing {
return mStage[i].getPos(t);
}
}
- var ret = (float) getEasing((t - mStage[lastStages].mStartTime));
+ float ret = (float) getEasing((t - mStage[lastStages].mStartTime));
ret += mStage[lastStages].mStartPos;
return ret;
}
@Override
public String toString() {
- var s = " ";
+ String s = " ";
for (int i = 0; i < mNumberOfStages; i++) {
Stage stage = mStage[i];
s += " $i $stage";
diff --git a/core/java/com/android/internal/widget/remotecompose/core/semantics/AccessibilityModifier.java b/core/java/com/android/internal/widget/remotecompose/core/semantics/AccessibilityModifier.java
index cd8b7b865cd2..098c4c3190e5 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/semantics/AccessibilityModifier.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/semantics/AccessibilityModifier.java
@@ -17,7 +17,20 @@ package com.android.internal.widget.remotecompose.core.semantics;
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ModifierOperation;
-/** A Modifier that provides semantic info. */
+/**
+ * A Modifier that provides semantic info.
+ *
+ * <p>This is needed since `AccessibilityModifier` is generally an open set and designed to be
+ * extended.
+ */
public interface AccessibilityModifier extends ModifierOperation, AccessibleComponent {
+ /**
+ * This method retrieves the operation code.
+ *
+ * <p>This function is used to get the current operation code associated with the object or
+ * context this method belongs to.
+ *
+ * @return The operation code as an integer.
+ */
int getOpCode();
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/semantics/AccessibleComponent.java b/core/java/com/android/internal/widget/remotecompose/core/semantics/AccessibleComponent.java
index e07fc4d9a8f8..cc6c2a6ac7a9 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/semantics/AccessibleComponent.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/semantics/AccessibleComponent.java
@@ -17,29 +17,100 @@ package com.android.internal.widget.remotecompose.core.semantics;
import android.annotation.Nullable;
+/**
+ * Interface representing an accessible component in the UI. This interface defines properties and
+ * methods related to accessibility semantics for a component. It extends the {@link
+ * AccessibilitySemantics} interface to inherit semantic properties.
+ *
+ * <p>This is similar to {@link CoreSemantics} but handles built in operations that also expose
+ * those core semantics.
+ */
public interface AccessibleComponent extends AccessibilitySemantics {
+ /**
+ * Returns the ID of the content description for this item.
+ *
+ * <p>The content description is used to provide textual information about the item to
+ * accessibility services, such as screen readers. This allows users with visual impairments to
+ * understand the purpose and content of the item.
+ *
+ * <p>This is similar to AccessibilityNodeInfo.getContentDescription().
+ *
+ * @return The ID of a RemoteString for the content description, or null if no content
+ * description is provided.
+ */
default @Nullable Integer getContentDescriptionId() {
return null;
}
+ /**
+ * Gets the text ID associated with this object.
+ *
+ * <p>This method is intended to be overridden by subclasses that need to associate a specific
+ * text ID with themselves. The default implementation returns null, indicating that no text ID
+ * is associated with the object.
+ *
+ * <p>This is similar to AccessibilityNodeInfo.getText().
+ *
+ * @return The text ID, or null if no text ID is associated with this object.
+ */
default @Nullable Integer getTextId() {
return null;
}
+ /**
+ * Retrieves the role associated with this object. The enum type deliberately matches the
+ * Compose Role. In the platform it will be applied as ROLE_DESCRIPTION_KEY.
+ *
+ * <p>The default implementation returns {@code null}, indicating that no role is assigned.
+ *
+ * @return The role associated with this object, or {@code null} if no role is assigned.
+ */
default @Nullable Role getRole() {
return null;
}
+ /**
+ * Checks if the element is clickable.
+ *
+ * <p>By default, elements are not considered clickable. Subclasses should override this method
+ * to indicate clickability based on their specific properties and behavior.
+ *
+ * <p>This is similar to AccessibilityNodeInfo.isClickable().
+ *
+ * @return {@code true} if the element is clickable, {@code false} otherwise.
+ */
default boolean isClickable() {
return false;
}
+ /**
+ * Gets the merge mode of the operation.
+ *
+ * <p>The mode indicates the type of operation being performed. By default it returns {@link
+ * CoreSemantics.Mode#SET}, indicating a "set" operation.
+ *
+ * <p>{@link CoreSemantics.Mode#CLEAR_AND_SET} matches a Compose modifier of
+ * `Modifier.clearAndSetSemantics {}`
+ *
+ * <p>{@link CoreSemantics.Mode#MERGE} matches a Compose modifier of
+ * `Modifier.semantics(mergeDescendants = true) {}`
+ *
+ * @return The mode of the operation, which defaults to {@link CoreSemantics.Mode#SET}.
+ */
default CoreSemantics.Mode getMode() {
return CoreSemantics.Mode.SET;
}
- // Our master list
- // https://developer.android.com/reference/kotlin/androidx/compose/ui/semantics/Role
+ /**
+ * Represents the role of an accessible component.
+ *
+ * <p>The enum type deliberately matches the Compose Role. In the platform it will be applied as
+ * ROLE_DESCRIPTION_KEY.
+ *
+ * @link <a
+ * href="https://developer.android.com/reference/androidx/compose/ui/semantics/Role">Compose
+ * Semantics Role</a>
+ */
enum Role {
BUTTON("Button"),
CHECKBOX("Checkbox"),
@@ -70,4 +141,21 @@ public interface AccessibleComponent extends AccessibilitySemantics {
return Role.UNKNOWN;
}
}
+
+ /**
+ * Defines the merge mode of an element in the semantic tree.
+ *
+ * <p>{@link CoreSemantics.Mode#CLEAR_AND_SET} matches a Compose modifier of
+ * `Modifier.clearAndSetSemantics {}`
+ *
+ * <p>{@link CoreSemantics.Mode#MERGE} matches a Compose modifier of
+ * `Modifier.semantics(mergeDescendants = true) {}`
+ *
+ * <p>{@link CoreSemantics.Mode#SET} adds or overrides semantics on an element.
+ */
+ enum Mode {
+ SET,
+ CLEAR_AND_SET,
+ MERGE
+ }
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/semantics/CoreSemantics.java b/core/java/com/android/internal/widget/remotecompose/core/semantics/CoreSemantics.java
index 4047dd27d163..5b35ee5fc7ed 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/semantics/CoreSemantics.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/semantics/CoreSemantics.java
@@ -118,16 +118,22 @@ public class CoreSemantics extends Operation implements AccessibilityModifier {
return indent + this;
}
- @NonNull
- public String serializedName() {
- return "SEMANTICS";
- }
-
@Override
public void serializeToString(int indent, @NonNull StringSerializer serializer) {
- serializer.append(indent, serializedName() + " = " + this);
+ serializer.append(indent, "SEMANTICS" + " = " + this);
}
+ /**
+ * Reads a CoreSemantics object from a WireBuffer and adds it to a list of operations.
+ *
+ * <p>This method reads the data required to construct a CoreSemantics object from the provided
+ * WireBuffer. After reading and constructing the CoreSemantics object, it is added to the
+ * provided list of operations.
+ *
+ * @param buffer The WireBuffer to read data from.
+ * @param operations The list of operations to which the read CoreSemantics object will be
+ * added.
+ */
public static void read(WireBuffer buffer, List<Operation> operations) {
CoreSemantics semantics = new CoreSemantics();
@@ -148,10 +154,4 @@ public class CoreSemantics extends Operation implements AccessibilityModifier {
public @Nullable Integer getTextId() {
return mTextId != 0 ? mTextId : null;
}
-
- public enum Mode {
- SET,
- CLEAR_AND_SET,
- MERGE
- }
}
diff --git a/core/java/com/android/internal/widget/remotecompose/player/platform/RemoteComposeCanvas.java b/core/java/com/android/internal/widget/remotecompose/player/platform/RemoteComposeCanvas.java
index da65a9cf5cc9..970cc4a44672 100644
--- a/core/java/com/android/internal/widget/remotecompose/player/platform/RemoteComposeCanvas.java
+++ b/core/java/com/android/internal/widget/remotecompose/player/platform/RemoteComposeCanvas.java
@@ -19,7 +19,9 @@ import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
+import android.graphics.Paint;
import android.graphics.Point;
+import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.Choreographer;
import android.view.MotionEvent;
@@ -47,6 +49,7 @@ public class RemoteComposeCanvas extends FrameLayout implements View.OnAttachSta
Point mActionDownPoint = new Point(0, 0);
AndroidRemoteContext mARContext = new AndroidRemoteContext();
float mDensity = 1f;
+ long mStart = System.nanoTime();
long mLastFrameDelay = 1;
float mMaxFrameRate = 60f; // frames per seconds
@@ -103,12 +106,14 @@ public class RemoteComposeCanvas extends FrameLayout implements View.OnAttachSta
public void setDocument(RemoteComposeDocument value) {
mDocument = value;
mDocument.initializeContext(mARContext);
+ mDisable = false;
mARContext.setAnimationEnabled(true);
mARContext.setDensity(mDensity);
mARContext.setUseChoreographer(true);
setContentDescription(mDocument.getDocument().getContentDescription());
updateClickAreas();
requestLayout();
+ mARContext.loadFloat(RemoteContext.ID_TOUCH_EVENT_TIME, -Float.MAX_VALUE);
invalidate();
}
@@ -337,6 +342,8 @@ public class RemoteComposeCanvas extends FrameLayout implements View.OnAttachSta
mActionDownPoint.y = (int) event.getY();
CoreDocument doc = mDocument.getDocument();
if (doc.hasTouchListener()) {
+ mARContext.loadFloat(
+ RemoteContext.ID_TOUCH_EVENT_TIME, mARContext.getAnimationTime());
mInActionDown = true;
if (mVelocityTracker == null) {
mVelocityTracker = VelocityTracker.obtain();
@@ -368,6 +375,8 @@ public class RemoteComposeCanvas extends FrameLayout implements View.OnAttachSta
performClick();
doc = mDocument.getDocument();
if (doc.hasTouchListener()) {
+ mARContext.loadFloat(
+ RemoteContext.ID_TOUCH_EVENT_TIME, mARContext.getAnimationTime());
mVelocityTracker.computeCurrentVelocity(1000);
float dx = mVelocityTracker.getXVelocity(pointerId);
float dy = mVelocityTracker.getYVelocity(pointerId);
@@ -380,6 +389,8 @@ public class RemoteComposeCanvas extends FrameLayout implements View.OnAttachSta
case MotionEvent.ACTION_MOVE:
if (mInActionDown) {
if (mVelocityTracker != null) {
+ mARContext.loadFloat(
+ RemoteContext.ID_TOUCH_EVENT_TIME, mARContext.getAnimationTime());
mVelocityTracker.addMovement(event);
doc = mDocument.getDocument();
boolean repaint = doc.touchDrag(mARContext, event.getX(), event.getY());
@@ -453,7 +464,9 @@ public class RemoteComposeCanvas extends FrameLayout implements View.OnAttachSta
private int mCount;
private long mTime = System.nanoTime();
private long mDuration;
- private boolean mEvalTime = false;
+ private boolean mEvalTime = false; // turn on to measure eval time
+ private float mLastAnimationTime = 0.1f; // set to random non 0 number
+ private boolean mDisable = false;
/**
* This returns the amount of time in ms the player used to evalueate a pass it is averaged over
@@ -480,36 +493,76 @@ public class RemoteComposeCanvas extends FrameLayout implements View.OnAttachSta
if (mDocument == null) {
return;
}
- long start = mEvalTime ? System.nanoTime() : 0;
- mARContext.useCanvas(canvas);
- mARContext.mWidth = getWidth();
- mARContext.mHeight = getHeight();
- mDocument.paint(mARContext, mTheme);
- if (mDebug == 1) {
- mCount++;
- if (System.nanoTime() - mTime > 1000000000L) {
- System.out.println(" count " + mCount + " fps");
- mCount = 0;
- mTime = System.nanoTime();
- }
+ if (mDisable) {
+ drawDisable(canvas);
+ return;
}
- int nextFrame = mDocument.needsRepaint();
- if (nextFrame > 0) {
- mLastFrameDelay = Math.max(mMaxFrameDelay, nextFrame);
- if (mChoreographer != null) {
- mChoreographer.postFrameCallbackDelayed(mFrameCallback, mLastFrameDelay);
+ try {
+
+ long start = mEvalTime ? System.nanoTime() : 0; // measure execut of commands
+
+ float animationTime = (System.nanoTime() - mStart) * 1E-9f;
+ mARContext.setAnimationTime(animationTime);
+ mARContext.loadFloat(RemoteContext.ID_ANIMATION_TIME, animationTime);
+ float loopTime = animationTime - mLastAnimationTime;
+ mARContext.loadFloat(RemoteContext.ID_ANIMATION_DELTA_TIME, loopTime);
+ mLastAnimationTime = animationTime;
+ mARContext.setAnimationEnabled(true);
+ mARContext.currentTime = System.currentTimeMillis();
+ mARContext.setDebug(mDebug);
+ float density = getContext().getResources().getDisplayMetrics().density;
+ mARContext.useCanvas(canvas);
+ mARContext.mWidth = getWidth();
+ mARContext.mHeight = getHeight();
+ mDocument.paint(mARContext, mTheme);
+ if (mDebug == 1) {
+ mCount++;
+ if (System.nanoTime() - mTime > 1000000000L) {
+ System.out.println(" count " + mCount + " fps");
+ mCount = 0;
+ mTime = System.nanoTime();
+ }
}
- if (!mARContext.useChoreographer()) {
- invalidate();
+ int nextFrame = mDocument.needsRepaint();
+ if (nextFrame > 0) {
+ mLastFrameDelay = Math.max(mMaxFrameDelay, nextFrame);
+ if (mChoreographer != null) {
+ mChoreographer.postFrameCallbackDelayed(mFrameCallback, mLastFrameDelay);
+ }
+ if (!mARContext.useChoreographer()) {
+ invalidate();
+ }
+ } else {
+ if (mChoreographer != null) {
+ mChoreographer.removeFrameCallback(mFrameCallback);
+ }
}
- } else {
- if (mChoreographer != null) {
- mChoreographer.removeFrameCallback(mFrameCallback);
+ if (mEvalTime) {
+ mDuration += System.nanoTime() - start;
+ mCount++;
}
+ } catch (Exception ex) {
+ mARContext.getLastOpCount();
+ mDisable = true;
+ invalidate();
}
- if (mEvalTime) {
- mDuration += System.nanoTime() - start;
- mCount++;
- }
+ }
+
+ private void drawDisable(Canvas canvas) {
+ Rect rect = new Rect();
+ canvas.drawColor(Color.BLACK);
+ Paint paint = new Paint();
+ paint.setTextSize(128f);
+ paint.setColor(Color.RED);
+ int w = getWidth();
+ int h = getHeight();
+
+ String str = "âš ";
+ paint.getTextBounds(str, 0, 1, rect);
+
+ float x = w / 2f - rect.width() / 2f - rect.left;
+ float y = h / 2f + rect.height() / 2f - rect.bottom;
+
+ canvas.drawText(str, x, y, paint);
}
}
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 027113a75f6b..3afe27ea591f 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -179,6 +179,8 @@ cc_library_shared_for_libandroid_runtime {
"android_os_NativeHandle.cpp",
"android_os_MemoryFile.cpp",
"android_os_MessageQueue.cpp",
+ "android_os_PerfettoTrace.cpp",
+ "android_os_PerfettoTrackEventExtra.cpp",
"android_os_Parcel.cpp",
"android_os_PerformanceHintManager.cpp",
"android_os_SELinux.cpp",
@@ -482,11 +484,22 @@ cc_library_shared_for_libandroid_runtime {
"libbinder",
"libhidlbase", // libhwbinder is in here
],
+ version_script: "platform/linux/libandroid_runtime_export.txt",
+ },
+ darwin: {
+ host_ldlibs: [
+ "-framework AppKit",
+ ],
+ dist: {
+ targets: ["layoutlib_jni"],
+ dir: "layoutlib_native/darwin",
+ },
+ exported_symbols_list: "platform/darwin/libandroid_runtime_export.exp",
},
linux_glibc_x86_64: {
ldflags: ["-static-libgcc"],
dist: {
- targets: ["layoutlib"],
+ targets: ["layoutlib_jni"],
dir: "layoutlib_native/linux",
tag: "stripped_all",
},
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 78d69f0714e0..aea1734918d6 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -158,6 +158,8 @@ extern int register_android_os_SELinux(JNIEnv* env);
extern int register_android_os_storage_StorageManager(JNIEnv* env);
extern int register_android_os_SystemProperties(JNIEnv *env);
extern int register_android_os_SystemClock(JNIEnv* env);
+extern int register_android_os_PerfettoTrace(JNIEnv* env);
+extern int register_android_os_PerfettoTrackEventExtra(JNIEnv* env);
extern int register_android_os_Trace(JNIEnv* env);
extern int register_android_os_FileObserver(JNIEnv *env);
extern int register_android_os_UEventObserver(JNIEnv* env);
@@ -1605,6 +1607,8 @@ static const RegJNIRec gRegJNI[] = {
REG_JNI(register_android_os_GraphicsEnvironment),
REG_JNI(register_android_os_MessageQueue),
REG_JNI(register_android_os_SELinux),
+ REG_JNI(register_android_os_PerfettoTrace),
+ REG_JNI(register_android_os_PerfettoTrackEventExtra),
REG_JNI(register_android_os_Trace),
REG_JNI(register_android_os_UEventObserver),
REG_JNI(register_android_net_LocalSocketImpl),
diff --git a/core/jni/android_os_PerfettoTrace.cpp b/core/jni/android_os_PerfettoTrace.cpp
new file mode 100644
index 000000000000..988aea722be3
--- /dev/null
+++ b/core/jni/android_os_PerfettoTrace.cpp
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <android-base/logging.h>
+#include <android-base/properties.h>
+#include <cutils/compiler.h>
+#include <cutils/trace.h>
+#include <jni.h>
+#include <log/log.h>
+#include <nativehelper/JNIHelp.h>
+#include <nativehelper/scoped_local_ref.h>
+#include <nativehelper/scoped_primitive_array.h>
+#include <nativehelper/scoped_utf_chars.h>
+#include <tracing_sdk.h>
+
+namespace android {
+template <typename T>
+inline static T* toPointer(jlong ptr) {
+ return reinterpret_cast<T*>(static_cast<uintptr_t>(ptr));
+}
+
+template <typename T>
+inline static jlong toJLong(T* ptr) {
+ return static_cast<jlong>(reinterpret_cast<uintptr_t>(ptr));
+}
+
+static const char* fromJavaString(JNIEnv* env, jstring jstr) {
+ if (!jstr) return "";
+ ScopedUtfChars chars(env, jstr);
+
+ if (!chars.c_str()) {
+ ALOGE("Failed extracting string");
+ return "";
+ }
+
+ return chars.c_str();
+}
+
+static void android_os_PerfettoTrace_event(JNIEnv* env, jclass, jint type, jlong cat_ptr,
+ jstring name, jlong extra_ptr) {
+ ScopedUtfChars name_utf(env, name);
+ if (!name_utf.c_str()) {
+ ALOGE("Failed extracting string");
+ }
+
+ tracing_perfetto::Category* category = toPointer<tracing_perfetto::Category>(cat_ptr);
+ tracing_perfetto::trace_event(type, category->get(), name_utf.c_str(),
+ toPointer<tracing_perfetto::Extra>(extra_ptr));
+}
+
+static jlong android_os_PerfettoTrace_get_process_track_uuid() {
+ return tracing_perfetto::get_process_track_uuid();
+}
+
+static jlong android_os_PerfettoTrace_get_thread_track_uuid(jlong tid) {
+ return tracing_perfetto::get_thread_track_uuid(tid);
+}
+
+static void android_os_PerfettoTrace_activate_trigger(JNIEnv* env, jclass, jstring name,
+ jint ttl_ms) {
+ ScopedUtfChars name_utf(env, name);
+ if (!name_utf.c_str()) {
+ ALOGE("Failed extracting string");
+ return;
+ }
+
+ tracing_perfetto::activate_trigger(name_utf.c_str(), static_cast<uint32_t>(ttl_ms));
+}
+
+static jlong android_os_PerfettoTraceCategory_init(JNIEnv* env, jclass, jstring name, jstring tag,
+ jstring severity) {
+ return toJLong(new tracing_perfetto::Category(fromJavaString(env, name),
+ fromJavaString(env, tag),
+ fromJavaString(env, severity)));
+}
+
+static jlong android_os_PerfettoTraceCategory_delete() {
+ return toJLong(&tracing_perfetto::Category::delete_category);
+}
+
+static void android_os_PerfettoTraceCategory_register(jlong ptr) {
+ tracing_perfetto::Category* category = toPointer<tracing_perfetto::Category>(ptr);
+ category->register_category();
+}
+
+static void android_os_PerfettoTraceCategory_unregister(jlong ptr) {
+ tracing_perfetto::Category* category = toPointer<tracing_perfetto::Category>(ptr);
+ category->unregister_category();
+}
+
+static jboolean android_os_PerfettoTraceCategory_is_enabled(jlong ptr) {
+ tracing_perfetto::Category* category = toPointer<tracing_perfetto::Category>(ptr);
+ return category->is_category_enabled();
+}
+
+static jlong android_os_PerfettoTraceCategory_get_extra_ptr(jlong ptr) {
+ tracing_perfetto::Category* category = toPointer<tracing_perfetto::Category>(ptr);
+ return toJLong(category->get());
+}
+
+static const JNINativeMethod gCategoryMethods[] = {
+ {"native_init", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)J",
+ (void*)android_os_PerfettoTraceCategory_init},
+ {"native_delete", "()J", (void*)android_os_PerfettoTraceCategory_delete},
+ {"native_register", "(J)V", (void*)android_os_PerfettoTraceCategory_register},
+ {"native_unregister", "(J)V", (void*)android_os_PerfettoTraceCategory_unregister},
+ {"native_is_enabled", "(J)Z", (void*)android_os_PerfettoTraceCategory_is_enabled},
+ {"native_get_extra_ptr", "(J)J", (void*)android_os_PerfettoTraceCategory_get_extra_ptr},
+};
+
+static const JNINativeMethod gTraceMethods[] =
+ {{"native_event", "(IJLjava/lang/String;J)V", (void*)android_os_PerfettoTrace_event},
+ {"native_get_process_track_uuid", "()J",
+ (void*)android_os_PerfettoTrace_get_process_track_uuid},
+ {"native_get_thread_track_uuid", "(J)J",
+ (void*)android_os_PerfettoTrace_get_thread_track_uuid},
+ {"native_activate_trigger", "(Ljava/lang/String;I)V",
+ (void*)android_os_PerfettoTrace_activate_trigger}};
+
+int register_android_os_PerfettoTrace(JNIEnv* env) {
+ int res = jniRegisterNativeMethods(env, "android/os/PerfettoTrace", gTraceMethods,
+ NELEM(gTraceMethods));
+
+ res = jniRegisterNativeMethods(env, "android/os/PerfettoTrace$Category", gCategoryMethods,
+ NELEM(gCategoryMethods));
+ LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register native methods.");
+
+ return 0;
+}
+
+} // namespace android
diff --git a/core/jni/android_os_PerfettoTrackEventExtra.cpp b/core/jni/android_os_PerfettoTrackEventExtra.cpp
new file mode 100644
index 000000000000..9adad7bca940
--- /dev/null
+++ b/core/jni/android_os_PerfettoTrackEventExtra.cpp
@@ -0,0 +1,536 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <cutils/compiler.h>
+#include <cutils/trace.h>
+#include <jni.h>
+#include <log/log.h>
+#include <nativehelper/JNIHelp.h>
+#include <nativehelper/scoped_utf_chars.h>
+#include <tracing_sdk.h>
+
+static constexpr ssize_t kMaxStrLen = 4096;
+namespace android {
+template <typename T>
+inline static T* toPointer(jlong ptr) {
+ return reinterpret_cast<T*>(static_cast<uintptr_t>(ptr));
+}
+
+template <typename T>
+inline static jlong toJLong(T* ptr) {
+ return static_cast<jlong>(reinterpret_cast<uintptr_t>(ptr));
+}
+
+static const char* fromJavaString(JNIEnv* env, jstring jstr) {
+ if (!jstr) return "";
+ ScopedUtfChars chars(env, jstr);
+
+ if (!chars.c_str()) {
+ ALOGE("Failed extracting string");
+ return "";
+ }
+
+ return chars.c_str();
+}
+
+static jlong android_os_PerfettoTrackEventExtraArgInt64_init(JNIEnv* env, jclass, jstring name) {
+ return toJLong(new tracing_perfetto::DebugArg<int64_t>(fromJavaString(env, name)));
+}
+
+static jlong android_os_PerfettoTrackEventExtraArgBool_init(JNIEnv* env, jclass, jstring name) {
+ return toJLong(new tracing_perfetto::DebugArg<bool>(fromJavaString(env, name)));
+}
+
+static jlong android_os_PerfettoTrackEventExtraArgDouble_init(JNIEnv* env, jclass, jstring name) {
+ return toJLong(new tracing_perfetto::DebugArg<double>(fromJavaString(env, name)));
+}
+
+static jlong android_os_PerfettoTrackEventExtraArgString_init(JNIEnv* env, jclass, jstring name) {
+ return toJLong(new tracing_perfetto::DebugArg<const char*>(fromJavaString(env, name)));
+}
+
+static jlong android_os_PerfettoTrackEventExtraArgInt64_delete() {
+ return toJLong(&tracing_perfetto::DebugArg<int64_t>::delete_arg);
+}
+
+static jlong android_os_PerfettoTrackEventExtraArgBool_delete() {
+ return toJLong(&tracing_perfetto::DebugArg<bool>::delete_arg);
+}
+
+static jlong android_os_PerfettoTrackEventExtraArgDouble_delete() {
+ return toJLong(&tracing_perfetto::DebugArg<double>::delete_arg);
+}
+
+static jlong android_os_PerfettoTrackEventExtraArgString_delete() {
+ return toJLong(&tracing_perfetto::DebugArg<const char*>::delete_arg);
+}
+
+static jlong android_os_PerfettoTrackEventExtraArgInt64_get_extra_ptr(jlong ptr) {
+ tracing_perfetto::DebugArg<int64_t>* arg = toPointer<tracing_perfetto::DebugArg<int64_t>>(ptr);
+ return toJLong(arg->get());
+}
+
+static jlong android_os_PerfettoTrackEventExtraArgBool_get_extra_ptr(jlong ptr) {
+ tracing_perfetto::DebugArg<bool>* arg = toPointer<tracing_perfetto::DebugArg<bool>>(ptr);
+ return toJLong(arg->get());
+}
+
+static jlong android_os_PerfettoTrackEventExtraArgDouble_get_extra_ptr(jlong ptr) {
+ tracing_perfetto::DebugArg<double>* arg = toPointer<tracing_perfetto::DebugArg<double>>(ptr);
+ return toJLong(arg->get());
+}
+
+static jlong android_os_PerfettoTrackEventExtraArgString_get_extra_ptr(jlong ptr) {
+ tracing_perfetto::DebugArg<const char*>* arg =
+ toPointer<tracing_perfetto::DebugArg<const char*>>(ptr);
+ return toJLong(arg->get());
+}
+
+static void android_os_PerfettoTrackEventExtraArgInt64_set_value(jlong ptr, jlong val) {
+ tracing_perfetto::DebugArg<int64_t>* arg = toPointer<tracing_perfetto::DebugArg<int64_t>>(ptr);
+ arg->set_value(val);
+}
+
+static void android_os_PerfettoTrackEventExtraArgBool_set_value(jlong ptr, jboolean val) {
+ tracing_perfetto::DebugArg<bool>* arg = toPointer<tracing_perfetto::DebugArg<bool>>(ptr);
+ arg->set_value(val);
+}
+
+static void android_os_PerfettoTrackEventExtraArgDouble_set_value(jlong ptr, jdouble val) {
+ tracing_perfetto::DebugArg<double>* arg = toPointer<tracing_perfetto::DebugArg<double>>(ptr);
+ arg->set_value(val);
+}
+
+static void android_os_PerfettoTrackEventExtraArgString_set_value(JNIEnv* env, jclass, jlong ptr,
+ jstring val) {
+ tracing_perfetto::DebugArg<const char*>* arg =
+ toPointer<tracing_perfetto::DebugArg<const char*>>(ptr);
+ arg->set_value(strdup(fromJavaString(env, val)));
+}
+
+static jlong android_os_PerfettoTrackEventExtraFieldInt64_init() {
+ return toJLong(new tracing_perfetto::ProtoField<int64_t>());
+}
+
+static jlong android_os_PerfettoTrackEventExtraFieldDouble_init() {
+ return toJLong(new tracing_perfetto::ProtoField<double>());
+}
+
+static jlong android_os_PerfettoTrackEventExtraFieldString_init() {
+ return toJLong(new tracing_perfetto::ProtoField<const char*>());
+}
+
+static jlong android_os_PerfettoTrackEventExtraFieldNested_init() {
+ return toJLong(new tracing_perfetto::ProtoFieldNested());
+}
+
+static jlong android_os_PerfettoTrackEventExtraFieldInt64_delete() {
+ return toJLong(&tracing_perfetto::ProtoField<int64_t>::delete_field);
+}
+
+static jlong android_os_PerfettoTrackEventExtraFieldDouble_delete() {
+ return toJLong(&tracing_perfetto::ProtoField<double>::delete_field);
+}
+
+static jlong android_os_PerfettoTrackEventExtraFieldString_delete() {
+ return toJLong(&tracing_perfetto::ProtoField<const char*>::delete_field);
+}
+
+static jlong android_os_PerfettoTrackEventExtraFieldNested_delete() {
+ return toJLong(&tracing_perfetto::ProtoFieldNested::delete_field);
+}
+
+static jlong android_os_PerfettoTrackEventExtraFieldInt64_get_extra_ptr(jlong ptr) {
+ tracing_perfetto::ProtoField<int64_t>* field =
+ toPointer<tracing_perfetto::ProtoField<int64_t>>(ptr);
+ return toJLong(field->get());
+}
+
+static jlong android_os_PerfettoTrackEventExtraFieldDouble_get_extra_ptr(jlong ptr) {
+ tracing_perfetto::ProtoField<double>* field =
+ toPointer<tracing_perfetto::ProtoField<double>>(ptr);
+ return toJLong(field->get());
+}
+
+static jlong android_os_PerfettoTrackEventExtraFieldString_get_extra_ptr(jlong ptr) {
+ tracing_perfetto::ProtoField<const char*>* field =
+ toPointer<tracing_perfetto::ProtoField<const char*>>(ptr);
+ return toJLong(field->get());
+}
+
+static jlong android_os_PerfettoTrackEventExtraFieldNested_get_extra_ptr(jlong ptr) {
+ tracing_perfetto::ProtoFieldNested* field = toPointer<tracing_perfetto::ProtoFieldNested>(ptr);
+ return toJLong(field->get());
+}
+
+static void android_os_PerfettoTrackEventExtraFieldInt64_set_value(jlong ptr, jlong id, jlong val) {
+ tracing_perfetto::ProtoField<int64_t>* field =
+ toPointer<tracing_perfetto::ProtoField<int64_t>>(ptr);
+ field->set_value(id, val);
+}
+
+static void android_os_PerfettoTrackEventExtraFieldDouble_set_value(jlong ptr, jlong id,
+ jdouble val) {
+ tracing_perfetto::ProtoField<double>* field =
+ toPointer<tracing_perfetto::ProtoField<double>>(ptr);
+ field->set_value(id, val);
+}
+
+static void android_os_PerfettoTrackEventExtraFieldString_set_value(JNIEnv* env, jclass, jlong ptr,
+ jlong id, jstring val) {
+ tracing_perfetto::ProtoField<const char*>* field =
+ toPointer<tracing_perfetto::ProtoField<const char*>>(ptr);
+ field->set_value(id, strdup(fromJavaString(env, val)));
+}
+
+static void android_os_PerfettoTrackEventExtraFieldNested_add_field(jlong field_ptr,
+ jlong arg_ptr) {
+ tracing_perfetto::ProtoFieldNested* field =
+ toPointer<tracing_perfetto::ProtoFieldNested>(field_ptr);
+ field->add_field(toPointer<PerfettoTeHlProtoField>(arg_ptr));
+}
+
+static void android_os_PerfettoTrackEventExtraFieldNested_set_id(jlong ptr, jlong id) {
+ tracing_perfetto::ProtoFieldNested* field = toPointer<tracing_perfetto::ProtoFieldNested>(ptr);
+ field->set_id(id);
+}
+
+static jlong android_os_PerfettoTrackEventExtraFlow_init() {
+ return toJLong(new tracing_perfetto::Flow());
+}
+
+static void android_os_PerfettoTrackEventExtraFlow_set_process_flow(jlong ptr, jlong id) {
+ tracing_perfetto::Flow* flow = toPointer<tracing_perfetto::Flow>(ptr);
+ flow->set_process_flow(id);
+}
+
+static void android_os_PerfettoTrackEventExtraFlow_set_process_terminating_flow(jlong ptr,
+ jlong id) {
+ tracing_perfetto::Flow* flow = toPointer<tracing_perfetto::Flow>(ptr);
+ flow->set_process_terminating_flow(id);
+}
+
+static jlong android_os_PerfettoTrackEventExtraFlow_delete() {
+ return toJLong(&tracing_perfetto::Flow::delete_flow);
+}
+
+static jlong android_os_PerfettoTrackEventExtraFlow_get_extra_ptr(jlong ptr) {
+ tracing_perfetto::Flow* flow = toPointer<tracing_perfetto::Flow>(ptr);
+ return toJLong(flow->get());
+}
+
+static jlong android_os_PerfettoTrackEventExtraNamedTrack_init(JNIEnv* env, jclass, jlong id,
+ jstring name, jlong parent_uuid) {
+ return toJLong(new tracing_perfetto::NamedTrack(id, parent_uuid, fromJavaString(env, name)));
+}
+
+static jlong android_os_PerfettoTrackEventExtraNamedTrack_delete() {
+ return toJLong(&tracing_perfetto::NamedTrack::delete_track);
+}
+
+static jlong android_os_PerfettoTrackEventExtraNamedTrack_get_extra_ptr(jlong ptr) {
+ tracing_perfetto::NamedTrack* track = toPointer<tracing_perfetto::NamedTrack>(ptr);
+ return toJLong(track->get());
+}
+
+static jlong android_os_PerfettoTrackEventExtraCounterTrack_init(JNIEnv* env, jclass, jstring name,
+ jlong parent_uuid) {
+ return toJLong(
+ new tracing_perfetto::RegisteredTrack(1, parent_uuid, fromJavaString(env, name), true));
+}
+
+static jlong android_os_PerfettoTrackEventExtraCounterTrack_delete() {
+ return toJLong(&tracing_perfetto::RegisteredTrack::delete_track);
+}
+
+static jlong android_os_PerfettoTrackEventExtraCounterTrack_get_extra_ptr(jlong ptr) {
+ tracing_perfetto::RegisteredTrack* track = toPointer<tracing_perfetto::RegisteredTrack>(ptr);
+ return toJLong(track->get());
+}
+
+static jlong android_os_PerfettoTrackEventExtraCounterInt64_init() {
+ return toJLong(new tracing_perfetto::Counter<int64_t>());
+}
+
+static jlong android_os_PerfettoTrackEventExtraCounterInt64_delete() {
+ return toJLong(&tracing_perfetto::Counter<int64_t>::delete_counter);
+}
+
+static void android_os_PerfettoTrackEventExtraCounterInt64_set_value(jlong ptr, jlong val) {
+ tracing_perfetto::Counter<int64_t>* counter =
+ toPointer<tracing_perfetto::Counter<int64_t>>(ptr);
+ counter->set_value(val);
+}
+
+static jlong android_os_PerfettoTrackEventExtraCounterInt64_get_extra_ptr(jlong ptr) {
+ tracing_perfetto::Counter<int64_t>* counter =
+ toPointer<tracing_perfetto::Counter<int64_t>>(ptr);
+ return toJLong(counter->get());
+}
+
+static jlong android_os_PerfettoTrackEventExtraCounterDouble_init() {
+ return toJLong(new tracing_perfetto::Counter<double>());
+}
+
+static jlong android_os_PerfettoTrackEventExtraCounterDouble_delete() {
+ return toJLong(&tracing_perfetto::Counter<double>::delete_counter);
+}
+
+static void android_os_PerfettoTrackEventExtraCounterDouble_set_value(jlong ptr, jdouble val) {
+ tracing_perfetto::Counter<double>* counter = toPointer<tracing_perfetto::Counter<double>>(ptr);
+ counter->set_value(val);
+}
+
+static jlong android_os_PerfettoTrackEventExtraCounterDouble_get_extra_ptr(jlong ptr) {
+ tracing_perfetto::Counter<double>* counter = toPointer<tracing_perfetto::Counter<double>>(ptr);
+ return toJLong(counter->get());
+}
+
+static jlong android_os_PerfettoTrackEventExtra_init() {
+ return toJLong(new tracing_perfetto::Extra());
+}
+
+static jlong android_os_PerfettoTrackEventExtra_delete() {
+ return toJLong(&tracing_perfetto::Extra::delete_extra);
+}
+
+static void android_os_PerfettoTrackEventExtra_add_arg(jlong extra_ptr, jlong arg_ptr) {
+ tracing_perfetto::Extra* extra = toPointer<tracing_perfetto::Extra>(extra_ptr);
+ extra->push_extra(toPointer<PerfettoTeHlExtra>(arg_ptr));
+}
+
+static void android_os_PerfettoTrackEventExtra_clear_args(jlong ptr) {
+ tracing_perfetto::Extra* extra = toPointer<tracing_perfetto::Extra>(ptr);
+ extra->clear_extras();
+}
+
+static jlong android_os_PerfettoTrackEventExtraProto_init() {
+ return toJLong(new tracing_perfetto::Proto());
+}
+
+static jlong android_os_PerfettoTrackEventExtraProto_delete() {
+ return toJLong(&tracing_perfetto::Proto::delete_proto);
+}
+
+static jlong android_os_PerfettoTrackEventExtraProto_get_extra_ptr(jlong ptr) {
+ tracing_perfetto::Proto* proto = toPointer<tracing_perfetto::Proto>(ptr);
+ return toJLong(proto->get());
+}
+
+static void android_os_PerfettoTrackEventExtraProto_add_field(long proto_ptr, jlong arg_ptr) {
+ tracing_perfetto::Proto* proto = toPointer<tracing_perfetto::Proto>(proto_ptr);
+ proto->add_field(toPointer<PerfettoTeHlProtoField>(arg_ptr));
+}
+
+static void android_os_PerfettoTrackEventExtraProto_clear_fields(jlong ptr) {
+ tracing_perfetto::Proto* proto = toPointer<tracing_perfetto::Proto>(ptr);
+ proto->clear_fields();
+}
+
+static const JNINativeMethod gExtraMethods[] =
+ {{"native_init", "()J", (void*)android_os_PerfettoTrackEventExtra_init},
+ {"native_delete", "()J", (void*)android_os_PerfettoTrackEventExtra_delete},
+ {"native_add_arg", "(JJ)V", (void*)android_os_PerfettoTrackEventExtra_add_arg},
+ {"native_clear_args", "(J)V", (void*)android_os_PerfettoTrackEventExtra_clear_args}};
+
+static const JNINativeMethod gProtoMethods[] =
+ {{"native_init", "()J", (void*)android_os_PerfettoTrackEventExtraProto_init},
+ {"native_delete", "()J", (void*)android_os_PerfettoTrackEventExtraProto_delete},
+ {"native_get_extra_ptr", "(J)J",
+ (void*)android_os_PerfettoTrackEventExtraProto_get_extra_ptr},
+ {"native_add_field", "(JJ)V", (void*)android_os_PerfettoTrackEventExtraProto_add_field},
+ {"native_clear_fields", "(J)V",
+ (void*)android_os_PerfettoTrackEventExtraProto_clear_fields}};
+
+static const JNINativeMethod gArgInt64Methods[] = {
+ {"native_init", "(Ljava/lang/String;)J",
+ (void*)android_os_PerfettoTrackEventExtraArgInt64_init},
+ {"native_delete", "()J", (void*)android_os_PerfettoTrackEventExtraArgInt64_delete},
+ {"native_get_extra_ptr", "(J)J",
+ (void*)android_os_PerfettoTrackEventExtraArgInt64_get_extra_ptr},
+ {"native_set_value", "(JJ)V", (void*)android_os_PerfettoTrackEventExtraArgInt64_set_value},
+};
+
+static const JNINativeMethod gArgBoolMethods[] = {
+ {"native_init", "(Ljava/lang/String;)J",
+ (void*)android_os_PerfettoTrackEventExtraArgBool_init},
+ {"native_delete", "()J", (void*)android_os_PerfettoTrackEventExtraArgBool_delete},
+ {"native_get_extra_ptr", "(J)J",
+ (void*)android_os_PerfettoTrackEventExtraArgBool_get_extra_ptr},
+ {"native_set_value", "(JZ)V", (void*)android_os_PerfettoTrackEventExtraArgBool_set_value},
+};
+
+static const JNINativeMethod gArgDoubleMethods[] = {
+ {"native_init", "(Ljava/lang/String;)J",
+ (void*)android_os_PerfettoTrackEventExtraArgDouble_init},
+ {"native_delete", "()J", (void*)android_os_PerfettoTrackEventExtraArgDouble_delete},
+ {"native_get_extra_ptr", "(J)J",
+ (void*)android_os_PerfettoTrackEventExtraArgDouble_get_extra_ptr},
+ {"native_set_value", "(JD)V", (void*)android_os_PerfettoTrackEventExtraArgDouble_set_value},
+};
+
+static const JNINativeMethod gArgStringMethods[] = {
+ {"native_init", "(Ljava/lang/String;)J",
+ (void*)android_os_PerfettoTrackEventExtraArgString_init},
+ {"native_delete", "()J", (void*)android_os_PerfettoTrackEventExtraArgString_delete},
+ {"native_get_extra_ptr", "(J)J",
+ (void*)android_os_PerfettoTrackEventExtraArgString_get_extra_ptr},
+ {"native_set_value", "(JLjava/lang/String;)V",
+ (void*)android_os_PerfettoTrackEventExtraArgString_set_value},
+};
+
+static const JNINativeMethod gFieldInt64Methods[] = {
+ {"native_init", "()J", (void*)android_os_PerfettoTrackEventExtraFieldInt64_init},
+ {"native_delete", "()J", (void*)android_os_PerfettoTrackEventExtraFieldInt64_delete},
+ {"native_get_extra_ptr", "(J)J",
+ (void*)android_os_PerfettoTrackEventExtraFieldInt64_get_extra_ptr},
+ {"native_set_value", "(JJJ)V",
+ (void*)android_os_PerfettoTrackEventExtraFieldInt64_set_value},
+};
+
+static const JNINativeMethod gFieldDoubleMethods[] = {
+ {"native_init", "()J", (void*)android_os_PerfettoTrackEventExtraFieldDouble_init},
+ {"native_delete", "()J", (void*)android_os_PerfettoTrackEventExtraFieldDouble_delete},
+ {"native_get_extra_ptr", "(J)J",
+ (void*)android_os_PerfettoTrackEventExtraFieldDouble_get_extra_ptr},
+ {"native_set_value", "(JJD)V",
+ (void*)android_os_PerfettoTrackEventExtraFieldDouble_set_value},
+};
+
+static const JNINativeMethod gFieldStringMethods[] = {
+ {"native_init", "()J", (void*)android_os_PerfettoTrackEventExtraFieldString_init},
+ {"native_delete", "()J", (void*)android_os_PerfettoTrackEventExtraFieldString_delete},
+ {"native_get_extra_ptr", "(J)J",
+ (void*)android_os_PerfettoTrackEventExtraFieldString_get_extra_ptr},
+ {"native_set_value", "(JJLjava/lang/String;)V",
+ (void*)android_os_PerfettoTrackEventExtraFieldString_set_value},
+};
+
+static const JNINativeMethod gFieldNestedMethods[] =
+ {{"native_init", "()J", (void*)android_os_PerfettoTrackEventExtraFieldNested_init},
+ {"native_delete", "()J", (void*)android_os_PerfettoTrackEventExtraFieldNested_delete},
+ {"native_get_extra_ptr", "(J)J",
+ (void*)android_os_PerfettoTrackEventExtraFieldNested_get_extra_ptr},
+ {"native_add_field", "(JJ)V",
+ (void*)android_os_PerfettoTrackEventExtraFieldNested_add_field},
+ {"native_set_id", "(JJ)V", (void*)android_os_PerfettoTrackEventExtraFieldNested_set_id}};
+
+static const JNINativeMethod gFlowMethods[] = {
+ {"native_init", "()J", (void*)android_os_PerfettoTrackEventExtraFlow_init},
+ {"native_delete", "()J", (void*)android_os_PerfettoTrackEventExtraFlow_delete},
+ {"native_set_process_flow", "(JJ)V",
+ (void*)android_os_PerfettoTrackEventExtraFlow_set_process_flow},
+ {"native_set_process_terminating_flow", "(JJ)V",
+ (void*)android_os_PerfettoTrackEventExtraFlow_set_process_terminating_flow},
+ {"native_get_extra_ptr", "(J)J",
+ (void*)android_os_PerfettoTrackEventExtraFlow_get_extra_ptr},
+};
+
+static const JNINativeMethod gNamedTrackMethods[] = {
+ {"native_init", "(JLjava/lang/String;J)J",
+ (void*)android_os_PerfettoTrackEventExtraNamedTrack_init},
+ {"native_delete", "()J", (void*)android_os_PerfettoTrackEventExtraNamedTrack_delete},
+ {"native_get_extra_ptr", "(J)J",
+ (void*)android_os_PerfettoTrackEventExtraNamedTrack_get_extra_ptr},
+};
+
+static const JNINativeMethod gCounterTrackMethods[] =
+ {{"native_init", "(Ljava/lang/String;J)J",
+ (void*)android_os_PerfettoTrackEventExtraCounterTrack_init},
+ {"native_delete", "()J", (void*)android_os_PerfettoTrackEventExtraCounterTrack_delete},
+ {"native_get_extra_ptr", "(J)J",
+ (void*)android_os_PerfettoTrackEventExtraCounterTrack_get_extra_ptr}};
+
+static const JNINativeMethod gCounterInt64Methods[] =
+ {{"native_init", "()J", (void*)android_os_PerfettoTrackEventExtraCounterInt64_init},
+ {"native_delete", "()J", (void*)android_os_PerfettoTrackEventExtraCounterInt64_delete},
+ {"native_set_value", "(JJ)V",
+ (void*)android_os_PerfettoTrackEventExtraCounterInt64_set_value},
+ {"native_get_extra_ptr", "(J)J",
+ (void*)android_os_PerfettoTrackEventExtraCounterInt64_get_extra_ptr}};
+
+static const JNINativeMethod gCounterDoubleMethods[] =
+ {{"native_init", "()J", (void*)android_os_PerfettoTrackEventExtraCounterDouble_init},
+ {"native_delete", "()J", (void*)android_os_PerfettoTrackEventExtraCounterDouble_delete},
+ {"native_set_value", "(JD)V",
+ (void*)android_os_PerfettoTrackEventExtraCounterDouble_set_value},
+ {"native_get_extra_ptr", "(J)J",
+ (void*)android_os_PerfettoTrackEventExtraCounterDouble_get_extra_ptr}};
+
+int register_android_os_PerfettoTrackEventExtra(JNIEnv* env) {
+ int res = jniRegisterNativeMethods(env, "android/os/PerfettoTrackEventExtra$ArgInt64",
+ gArgInt64Methods, NELEM(gArgInt64Methods));
+ LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register arg int64 native methods.");
+
+ res = jniRegisterNativeMethods(env, "android/os/PerfettoTrackEventExtra$ArgBool",
+ gArgBoolMethods, NELEM(gArgBoolMethods));
+ LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register arg bool native methods.");
+
+ res = jniRegisterNativeMethods(env, "android/os/PerfettoTrackEventExtra$ArgDouble",
+ gArgDoubleMethods, NELEM(gArgDoubleMethods));
+ LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register arg double native methods.");
+
+ res = jniRegisterNativeMethods(env, "android/os/PerfettoTrackEventExtra$ArgString",
+ gArgStringMethods, NELEM(gArgStringMethods));
+ LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register arg string native methods.");
+
+ res = jniRegisterNativeMethods(env, "android/os/PerfettoTrackEventExtra$FieldInt64",
+ gFieldInt64Methods, NELEM(gFieldInt64Methods));
+ LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register field int64 native methods.");
+
+ res = jniRegisterNativeMethods(env, "android/os/PerfettoTrackEventExtra$FieldDouble",
+ gFieldDoubleMethods, NELEM(gFieldDoubleMethods));
+ LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register field double native methods.");
+
+ res = jniRegisterNativeMethods(env, "android/os/PerfettoTrackEventExtra$FieldString",
+ gFieldStringMethods, NELEM(gFieldStringMethods));
+ LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register field string native methods.");
+
+ res = jniRegisterNativeMethods(env, "android/os/PerfettoTrackEventExtra$FieldNested",
+ gFieldNestedMethods, NELEM(gFieldNestedMethods));
+ LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register field nested native methods.");
+
+ res = jniRegisterNativeMethods(env, "android/os/PerfettoTrackEventExtra", gExtraMethods,
+ NELEM(gExtraMethods));
+ LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register extra native methods.");
+
+ res = jniRegisterNativeMethods(env, "android/os/PerfettoTrackEventExtra$Proto", gProtoMethods,
+ NELEM(gProtoMethods));
+ LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register proto native methods.");
+
+ res = jniRegisterNativeMethods(env, "android/os/PerfettoTrackEventExtra$Flow", gFlowMethods,
+ NELEM(gFlowMethods));
+ LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register flow native methods.");
+
+ res = jniRegisterNativeMethods(env, "android/os/PerfettoTrackEventExtra$NamedTrack",
+ gNamedTrackMethods, NELEM(gNamedTrackMethods));
+ LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register named track native methods.");
+
+ res = jniRegisterNativeMethods(env, "android/os/PerfettoTrackEventExtra$CounterTrack",
+ gCounterTrackMethods, NELEM(gCounterTrackMethods));
+ LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register counter track native methods.");
+
+ res = jniRegisterNativeMethods(env, "android/os/PerfettoTrackEventExtra$CounterInt64",
+ gCounterInt64Methods, NELEM(gCounterInt64Methods));
+ LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register counter int64 native methods.");
+
+ res = jniRegisterNativeMethods(env, "android/os/PerfettoTrackEventExtra$CounterDouble",
+ gCounterDoubleMethods, NELEM(gCounterDoubleMethods));
+ LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register counter double native methods.");
+ return 0;
+}
+
+} // namespace android
diff --git a/core/jni/platform/darwin/libandroid_runtime_export.exp b/core/jni/platform/darwin/libandroid_runtime_export.exp
new file mode 100644
index 000000000000..00a7585719ea
--- /dev/null
+++ b/core/jni/platform/darwin/libandroid_runtime_export.exp
@@ -0,0 +1,38 @@
+#
+# Copyright (C) 2024 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# symbols needed for the JNI operations
+_JNI_OnLoad
+_ANativeWindow*
+
+# symbols needed to link with layoutlib_jni
+___android_log*
+__ZNK7android7RefBase*
+__ZN7android4base9SetLogger*
+__ZN7android4base10SetAborter*
+__ZN7android4base11GetProperty*
+__ZN7android4Rect*
+__ZN7android5Fence*
+__ZN7android7RefBase*
+__ZN7android7String*
+__ZN7android10VectorImpl*
+__ZN7android11BufferQueue*
+__ZN7android14AndroidRuntime*
+__ZN7android14sp_report_raceEv*
+__ZN7android15KeyCharacterMap*
+__ZN7android15InputDeviceInfo*
+__ZN7android31android_view_InputDevice_create*
+__ZN7android53android_view_Surface_createFromIGraphicBufferProducer*
diff --git a/core/jni/platform/linux/libandroid_runtime_export.txt b/core/jni/platform/linux/libandroid_runtime_export.txt
new file mode 100644
index 000000000000..50e0b750f61e
--- /dev/null
+++ b/core/jni/platform/linux/libandroid_runtime_export.txt
@@ -0,0 +1,49 @@
+#
+# Copyright (C) 2024 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+{
+ global:
+ # symbols needed for the JNI operations
+ JNI_OnLoad;
+ ANativeWindow*;
+
+ # symbols needed to link with layoutlib_jni
+ __android_log*;
+ _ZNK7android7RefBase*;
+ _ZN7android4base9SetLogger*;
+ _ZN7android4base10SetAborter*;
+ _ZN7android4base11GetProperty*;
+ _ZN7android4Rect*;
+ _ZN7android5Fence*;
+ _ZN7android7RefBase*;
+ _ZN7android7String*;
+ _ZN7android10VectorImpl*;
+ _ZN7android11BufferQueue*;
+ _ZN7android14AndroidRuntime*;
+ _ZN7android14sp_report_raceEv*;
+ _ZN7android15KeyCharacterMap*;
+ _ZN7android15InputDeviceInfo*;
+ _ZN7android31android_view_InputDevice_create*;
+ _ZN7android53android_view_Surface_createFromIGraphicBufferProducer*;
+
+ # symbols needed by Ravenwood to override system properties
+ __system_property_find;
+ __system_property_get;
+ __system_property_read_callback;
+ __system_property_set;
+ local:
+ *;
+};
diff --git a/core/tests/coretests/Android.bp b/core/tests/coretests/Android.bp
index c67a0f9659f0..3ef3dfdc0183 100644
--- a/core/tests/coretests/Android.bp
+++ b/core/tests/coretests/Android.bp
@@ -119,6 +119,7 @@ android_test {
"android.view.flags-aconfig-java",
],
jni_libs: [
+ "libperfetto_trace_test_jni",
"libpowermanagertest_jni",
"libviewRootImplTest_jni",
"libworksourceparceltest_jni",
@@ -260,6 +261,7 @@ android_ravenwood_test {
"compatibility-device-util-axt-ravenwood",
"flag-junit",
"platform-test-annotations",
+ "perfetto_trace_java_protos",
"flag-junit",
"testng",
],
diff --git a/core/tests/coretests/jni/Android.bp b/core/tests/coretests/jni/Android.bp
index d6379ca8c3e6..798ec90eb884 100644
--- a/core/tests/coretests/jni/Android.bp
+++ b/core/tests/coretests/jni/Android.bp
@@ -111,3 +111,27 @@ cc_test_library {
],
gtest: false,
}
+
+cc_test_library {
+ name: "libperfetto_trace_test_jni",
+ srcs: [
+ "PerfettoTraceTest.cpp",
+ ],
+ static_libs: [
+ "perfetto_trace_protos",
+ "libtracing_perfetto_test_utils",
+ ],
+ shared_libs: [
+ "liblog",
+ "libnativehelper",
+ "libperfetto_c",
+ "libprotobuf-cpp-lite",
+ "libtracing_perfetto",
+ ],
+ stl: "libc++_static",
+ cflags: [
+ "-Werror",
+ "-Wall",
+ ],
+ gtest: false,
+}
diff --git a/core/tests/coretests/jni/PerfettoTraceTest.cpp b/core/tests/coretests/jni/PerfettoTraceTest.cpp
new file mode 100644
index 000000000000..41d02ed70c9a
--- /dev/null
+++ b/core/tests/coretests/jni/PerfettoTraceTest.cpp
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// #define LOG_NDEBUG 0
+#define LOG_TAG "PerfettoTraceTest"
+
+#include <nativehelper/JNIHelp.h>
+#include <utils/Log.h>
+
+#include "jni.h"
+#include "perfetto/public/abi/data_source_abi.h"
+#include "perfetto/public/abi/heap_buffer.h"
+#include "perfetto/public/abi/pb_decoder_abi.h"
+#include "perfetto/public/abi/tracing_session_abi.h"
+#include "perfetto/public/abi/track_event_abi.h"
+#include "perfetto/public/compiler.h"
+#include "perfetto/public/data_source.h"
+#include "perfetto/public/pb_decoder.h"
+#include "perfetto/public/producer.h"
+#include "perfetto/public/protos/config/trace_config.pzc.h"
+#include "perfetto/public/protos/trace/interned_data/interned_data.pzc.h"
+#include "perfetto/public/protos/trace/test_event.pzc.h"
+#include "perfetto/public/protos/trace/trace.pzc.h"
+#include "perfetto/public/protos/trace/trace_packet.pzc.h"
+#include "perfetto/public/protos/trace/track_event/debug_annotation.pzc.h"
+#include "perfetto/public/protos/trace/track_event/track_descriptor.pzc.h"
+#include "perfetto/public/protos/trace/track_event/track_event.pzc.h"
+#include "perfetto/public/protos/trace/trigger.pzc.h"
+#include "perfetto/public/te_category_macros.h"
+#include "perfetto/public/te_macros.h"
+#include "perfetto/public/track_event.h"
+#include "protos/perfetto/trace/interned_data/interned_data.pb.h"
+#include "protos/perfetto/trace/trace.pb.h"
+#include "protos/perfetto/trace/trace_packet.pb.h"
+#include "tracing_perfetto.h"
+#include "utils.h"
+
+namespace android {
+using ::perfetto::protos::EventCategory;
+using ::perfetto::protos::EventName;
+using ::perfetto::protos::FtraceEvent;
+using ::perfetto::protos::FtraceEventBundle;
+using ::perfetto::protos::InternedData;
+using ::perfetto::protos::Trace;
+using ::perfetto::protos::TracePacket;
+
+using ::perfetto::shlib::test_utils::TracingSession;
+
+struct TracingSessionHolder {
+ TracingSession tracing_session;
+};
+
+static void nativeRegisterPerfetto([[maybe_unused]] JNIEnv* env, jclass /* obj */) {
+ tracing_perfetto::registerWithPerfetto(false /* test */);
+}
+
+static jlong nativeStartTracing(JNIEnv* env, jclass /* obj */, jbyteArray configBytes) {
+ jsize length = env->GetArrayLength(configBytes);
+ std::vector<uint8_t> data;
+ data.reserve(length);
+ env->GetByteArrayRegion(configBytes, 0, length, reinterpret_cast<jbyte*>(data.data()));
+
+ TracingSession session = TracingSession::FromBytes(data.data(), length);
+ TracingSessionHolder* holder = new TracingSessionHolder(std::move(session));
+
+ return reinterpret_cast<long>(holder);
+}
+
+static jbyteArray nativeStopTracing([[maybe_unused]] JNIEnv* env, jclass /* obj */, jlong ptr) {
+ TracingSessionHolder* holder = reinterpret_cast<TracingSessionHolder*>(ptr);
+
+ // Stop
+ holder->tracing_session.FlushBlocking(5000);
+ holder->tracing_session.StopBlocking();
+
+ std::vector<uint8_t> data = holder->tracing_session.ReadBlocking();
+
+ delete holder;
+
+ jbyteArray bytes = env->NewByteArray(data.size());
+ env->SetByteArrayRegion(bytes, 0, data.size(), reinterpret_cast<jbyte*>(data.data()));
+ return bytes;
+}
+
+extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */) {
+ JNIEnv* env;
+ const JNINativeMethod methodTable[] = {/* name, signature, funcPtr */
+ {"nativeStartTracing", "([B)J",
+ (void*)nativeStartTracing},
+ {"nativeStopTracing", "(J)[B", (void*)nativeStopTracing},
+ {"nativeRegisterPerfetto", "()V",
+ (void*)nativeRegisterPerfetto}};
+
+ if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
+ return JNI_ERR;
+ }
+
+ jniRegisterNativeMethods(env, "android/os/PerfettoTraceTest", methodTable,
+ sizeof(methodTable) / sizeof(JNINativeMethod));
+
+ return JNI_VERSION_1_6;
+}
+
+} /* namespace android */
diff --git a/core/tests/coretests/src/android/app/NotificationManagerTest.java b/core/tests/coretests/src/android/app/NotificationManagerTest.java
index 3213abe13d8a..a47fc9436226 100644
--- a/core/tests/coretests/src/android/app/NotificationManagerTest.java
+++ b/core/tests/coretests/src/android/app/NotificationManagerTest.java
@@ -18,6 +18,7 @@ package android.app;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.atMost;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
@@ -67,6 +68,8 @@ public class NotificationManagerTest {
mClock.advanceByMillis(5);
}
+ verify(mNotificationManager.mBackendService, atLeast(20)).enqueueNotificationWithTag(any(),
+ any(), any(), anyInt(), any(), anyInt());
verify(mNotificationManager.mBackendService, atMost(30)).enqueueNotificationWithTag(any(),
any(), any(), anyInt(), any(), anyInt());
}
@@ -101,7 +104,38 @@ public class NotificationManagerTest {
@Test
@EnableFlags(Flags.FLAG_NM_BINDER_PERF_THROTTLE_NOTIFY)
- public void notify_rapidAddAndCancel_isNotThrottled() throws Exception {
+ public void cancel_unnecessaryAndRapid_isThrottled() throws Exception {
+
+ for (int i = 0; i < 100; i++) {
+ mNotificationManager.cancel(1);
+ mClock.advanceByMillis(5);
+ }
+
+ verify(mNotificationManager.mBackendService, atLeast(20)).cancelNotificationWithTag(any(),
+ any(), any(), anyInt(), anyInt());
+ verify(mNotificationManager.mBackendService, atMost(30)).cancelNotificationWithTag(any(),
+ any(), any(), anyInt(), anyInt());
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_NM_BINDER_PERF_THROTTLE_NOTIFY)
+ public void cancel_unnecessaryButReasonable_isNotThrottled() throws Exception {
+ // Scenario: the app tries to repeatedly cancel a single notification, but at a reasonable
+ // rate. Strange, but not what we're trying to block with NM_BINDER_PERF_THROTTLE_NOTIFY.
+ for (int i = 0; i < 100; i++) {
+ mNotificationManager.cancel(1);
+ mClock.advanceByMillis(500);
+ }
+
+ verify(mNotificationManager.mBackendService, times(100)).cancelNotificationWithTag(any(),
+ any(), any(), anyInt(), anyInt());
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_NM_BINDER_PERF_THROTTLE_NOTIFY)
+ public void cancel_necessaryAndRapid_isNotThrottled() throws Exception {
+ // Scenario: the app posts and immediately cancels a bunch of notifications. Strange,
+ // but not what we're trying to block with NM_BINDER_PERF_THROTTLE_NOTIFY.
Notification n = exampleNotification();
for (int i = 0; i < 100; i++) {
@@ -112,6 +146,23 @@ public class NotificationManagerTest {
verify(mNotificationManager.mBackendService, times(100)).enqueueNotificationWithTag(any(),
any(), any(), anyInt(), any(), anyInt());
+ verify(mNotificationManager.mBackendService, times(100)).cancelNotificationWithTag(any(),
+ any(), any(), anyInt(), anyInt());
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_NM_BINDER_PERF_THROTTLE_NOTIFY)
+ public void cancel_maybeNecessaryAndRapid_isNotThrottled() throws Exception {
+ // Scenario: the app posted a lot of notifications, is killed, then restarts (so NM client
+ // doesn't know about them), then cancels them one by one. We don't want to throttle this
+ // case.
+ for (int i = 0; i < 100; i++) {
+ mNotificationManager.cancel(i);
+ mClock.advanceByMillis(1);
+ }
+
+ verify(mNotificationManager.mBackendService, times(100)).cancelNotificationWithTag(any(),
+ any(), any(), anyInt(), anyInt());
}
private Notification exampleNotification() {
diff --git a/core/tests/coretests/src/android/net/http/OWNERS b/core/tests/coretests/src/android/net/http/OWNERS
new file mode 100644
index 000000000000..c93a4195c2d9
--- /dev/null
+++ b/core/tests/coretests/src/android/net/http/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/net/http/OWNERS
diff --git a/core/tests/coretests/src/android/net/http/X509TrustManagerExtensionsTest.java b/core/tests/coretests/src/android/net/http/X509TrustManagerExtensionsTest.java
index 04aa62a3e38e..a6ad80d344c5 100644
--- a/core/tests/coretests/src/android/net/http/X509TrustManagerExtensionsTest.java
+++ b/core/tests/coretests/src/android/net/http/X509TrustManagerExtensionsTest.java
@@ -16,6 +16,17 @@
package android.net.http;
+import static org.junit.Assert.fail;
+
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.org.conscrypt.TrustManagerImpl;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
import java.security.KeyStore;
import java.security.cert.X509Certificate;
@@ -23,11 +34,9 @@ import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
-import junit.framework.TestCase;
-
-import com.android.org.conscrypt.TrustManagerImpl;
-
-public class X509TrustManagerExtensionsTest extends TestCase {
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class X509TrustManagerExtensionsTest {
private class NotATrustManagerImpl implements X509TrustManager {
@@ -40,6 +49,7 @@ public class X509TrustManagerExtensionsTest extends TestCase {
}
}
+ @Test
public void testBadCast() throws Exception {
NotATrustManagerImpl ntmi = new NotATrustManagerImpl();
try {
@@ -49,12 +59,14 @@ public class X509TrustManagerExtensionsTest extends TestCase {
}
}
+ @Test
public void testGoodCast() throws Exception {
String defaultType = KeyStore.getDefaultType();
TrustManagerImpl tmi = new TrustManagerImpl(KeyStore.getInstance(defaultType));
X509TrustManagerExtensions tme = new X509TrustManagerExtensions(tmi);
}
+ @Test
public void testNormalUseCase() throws Exception {
String defaultAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(defaultAlgorithm);
diff --git a/core/tests/coretests/src/android/os/PerfettoTraceTest.java b/core/tests/coretests/src/android/os/PerfettoTraceTest.java
new file mode 100644
index 000000000000..292f7500479b
--- /dev/null
+++ b/core/tests/coretests/src/android/os/PerfettoTraceTest.java
@@ -0,0 +1,600 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os;
+
+import static android.os.PerfettoTrace.Category;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static perfetto.protos.ChromeLatencyInfoOuterClass.ChromeLatencyInfo.LatencyComponentType.COMPONENT_INPUT_EVENT_LATENCY_BEGIN_RWH;
+import static perfetto.protos.ChromeLatencyInfoOuterClass.ChromeLatencyInfo.LatencyComponentType.COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL;
+
+import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.RequiresFlagsEnabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
+import android.util.ArraySet;
+import android.util.Log;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import perfetto.protos.ChromeLatencyInfoOuterClass.ChromeLatencyInfo;
+import perfetto.protos.ChromeLatencyInfoOuterClass.ChromeLatencyInfo.ComponentInfo;
+import perfetto.protos.DataSourceConfigOuterClass.DataSourceConfig;
+import perfetto.protos.DebugAnnotationOuterClass.DebugAnnotation;
+import perfetto.protos.DebugAnnotationOuterClass.DebugAnnotationName;
+import perfetto.protos.InternedDataOuterClass.InternedData;
+import perfetto.protos.SourceLocationOuterClass.SourceLocation;
+import perfetto.protos.TraceConfigOuterClass.TraceConfig;
+import perfetto.protos.TraceConfigOuterClass.TraceConfig.BufferConfig;
+import perfetto.protos.TraceConfigOuterClass.TraceConfig.DataSource;
+import perfetto.protos.TraceConfigOuterClass.TraceConfig.TriggerConfig;
+import perfetto.protos.TraceConfigOuterClass.TraceConfig.TriggerConfig.Trigger;
+import perfetto.protos.TraceOuterClass.Trace;
+import perfetto.protos.TracePacketOuterClass.TracePacket;
+import perfetto.protos.TrackDescriptorOuterClass.TrackDescriptor;
+import perfetto.protos.TrackEventConfigOuterClass.TrackEventConfig;
+import perfetto.protos.TrackEventOuterClass.EventCategory;
+import perfetto.protos.TrackEventOuterClass.EventName;
+import perfetto.protos.TrackEventOuterClass.TrackEvent;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * This class is used to test the native tracing support. Run this test
+ * while tracing on the emulator and then run traceview to view the trace.
+ */
+@RunWith(AndroidJUnit4.class)
+@IgnoreUnderRavenwood(blockedBy = PerfettoTrace.class)
+public class PerfettoTraceTest {
+ @Rule
+ public final CheckFlagsRule mCheckFlagsRule =
+ DeviceFlagsValueProvider.createCheckFlagsRule(
+ InstrumentationRegistry.getInstrumentation().getUiAutomation());
+
+ private static final String TAG = "PerfettoTraceTest";
+ private static final String FOO = "foo";
+ private static final String BAR = "bar";
+
+ private static final Category FOO_CATEGORY = new Category(FOO);
+
+ private final Set<String> mCategoryNames = new ArraySet<>();
+ private final Set<String> mEventNames = new ArraySet<>();
+ private final Set<String> mDebugAnnotationNames = new ArraySet<>();
+ private final Set<String> mTrackNames = new ArraySet<>();
+
+ static {
+ try {
+ System.loadLibrary("perfetto_trace_test_jni");
+ Log.i(TAG, "Successfully loaded trace_test native library");
+ } catch (UnsatisfiedLinkError ule) {
+ Log.w(TAG, "Could not load trace_test native library");
+ }
+ }
+
+ @Before
+ public void setUp() {
+ PerfettoTrace.register();
+ nativeRegisterPerfetto();
+ FOO_CATEGORY.register();
+
+ mCategoryNames.clear();
+ mEventNames.clear();
+ mDebugAnnotationNames.clear();
+ mTrackNames.clear();
+ }
+
+ @Test
+ @RequiresFlagsEnabled(android.os.Flags.FLAG_PERFETTO_SDK_TRACING_V2)
+ public void testDebugAnnotations() throws Exception {
+ TraceConfig traceConfig = getTraceConfig(FOO);
+
+ long ptr = nativeStartTracing(traceConfig.toByteArray());
+
+ PerfettoTrackEventExtra extra = PerfettoTrackEventExtra.builder()
+ .addFlow(2)
+ .addTerminatingFlow(3)
+ .addArg("long_val", 10000000000L)
+ .addArg("bool_val", true)
+ .addArg("double_val", 3.14)
+ .addArg("string_val", FOO)
+ .build();
+ PerfettoTrace.instant(FOO_CATEGORY, "event", extra);
+
+ byte[] traceBytes = nativeStopTracing(ptr);
+
+ Trace trace = Trace.parseFrom(traceBytes);
+
+ boolean hasTrackEvent = false;
+ boolean hasDebugAnnotations = false;
+ for (TracePacket packet: trace.getPacketList()) {
+ TrackEvent event;
+ if (packet.hasTrackEvent()) {
+ hasTrackEvent = true;
+ event = packet.getTrackEvent();
+
+ if (TrackEvent.Type.TYPE_INSTANT.equals(event.getType())
+ && event.getDebugAnnotationsCount() == 4 && event.getFlowIdsCount() == 1
+ && event.getTerminatingFlowIdsCount() == 1) {
+ hasDebugAnnotations = true;
+
+ List<DebugAnnotation> annotations = event.getDebugAnnotationsList();
+
+ assertThat(annotations.get(0).getIntValue()).isEqualTo(10000000000L);
+ assertThat(annotations.get(1).getBoolValue()).isTrue();
+ assertThat(annotations.get(2).getDoubleValue()).isEqualTo(3.14);
+ assertThat(annotations.get(3).getStringValue()).isEqualTo(FOO);
+ }
+ }
+
+ collectInternedData(packet);
+ }
+
+ assertThat(hasTrackEvent).isTrue();
+ assertThat(hasDebugAnnotations).isTrue();
+ assertThat(mCategoryNames).contains(FOO);
+
+ assertThat(mDebugAnnotationNames).contains("long_val");
+ assertThat(mDebugAnnotationNames).contains("bool_val");
+ assertThat(mDebugAnnotationNames).contains("double_val");
+ assertThat(mDebugAnnotationNames).contains("string_val");
+ }
+
+ @Test
+ @RequiresFlagsEnabled(android.os.Flags.FLAG_PERFETTO_SDK_TRACING_V2)
+ public void testDebugAnnotationsWithLamda() throws Exception {
+ TraceConfig traceConfig = getTraceConfig(FOO);
+
+ long ptr = nativeStartTracing(traceConfig.toByteArray());
+
+ PerfettoTrace.instant(FOO_CATEGORY, "event", e -> e.addArg("long_val", 123L));
+
+ byte[] traceBytes = nativeStopTracing(ptr);
+
+ Trace trace = Trace.parseFrom(traceBytes);
+
+ boolean hasTrackEvent = false;
+ boolean hasDebugAnnotations = false;
+ for (TracePacket packet: trace.getPacketList()) {
+ TrackEvent event;
+ if (packet.hasTrackEvent()) {
+ hasTrackEvent = true;
+ event = packet.getTrackEvent();
+
+ if (TrackEvent.Type.TYPE_INSTANT.equals(event.getType())
+ && event.getDebugAnnotationsCount() == 1) {
+ hasDebugAnnotations = true;
+
+ List<DebugAnnotation> annotations = event.getDebugAnnotationsList();
+ assertThat(annotations.get(0).getIntValue()).isEqualTo(123L);
+ }
+ }
+ }
+
+ assertThat(hasTrackEvent).isTrue();
+ assertThat(hasDebugAnnotations).isTrue();
+ }
+
+ @Test
+ @RequiresFlagsEnabled(android.os.Flags.FLAG_PERFETTO_SDK_TRACING_V2)
+ public void testNamedTrack() throws Exception {
+ TraceConfig traceConfig = getTraceConfig(FOO);
+
+ long ptr = nativeStartTracing(traceConfig.toByteArray());
+
+ PerfettoTrackEventExtra beginExtra = PerfettoTrackEventExtra.builder()
+ .usingNamedTrack(FOO, PerfettoTrace.getProcessTrackUuid())
+ .build();
+ PerfettoTrace.begin(FOO_CATEGORY, "event", beginExtra);
+
+ PerfettoTrackEventExtra endExtra = PerfettoTrackEventExtra.builder()
+ .usingNamedTrack("bar", PerfettoTrace.getThreadTrackUuid(Process.myTid()))
+ .build();
+ PerfettoTrace.end(FOO_CATEGORY, endExtra);
+
+ Trace trace = Trace.parseFrom(nativeStopTracing(ptr));
+
+ boolean hasTrackEvent = false;
+ boolean hasTrackUuid = false;
+ for (TracePacket packet: trace.getPacketList()) {
+ TrackEvent event;
+ if (packet.hasTrackEvent()) {
+ hasTrackEvent = true;
+ event = packet.getTrackEvent();
+
+ if (TrackEvent.Type.TYPE_SLICE_BEGIN.equals(event.getType())
+ && event.hasTrackUuid()) {
+ hasTrackUuid = true;
+ }
+
+ if (TrackEvent.Type.TYPE_SLICE_END.equals(event.getType())
+ && event.hasTrackUuid()) {
+ hasTrackUuid &= true;
+ }
+ }
+
+ collectInternedData(packet);
+ collectTrackNames(packet);
+ }
+
+ assertThat(hasTrackEvent).isTrue();
+ assertThat(hasTrackUuid).isTrue();
+ assertThat(mCategoryNames).contains(FOO);
+ assertThat(mTrackNames).contains(FOO);
+ }
+
+ @Test
+ @RequiresFlagsEnabled(android.os.Flags.FLAG_PERFETTO_SDK_TRACING_V2)
+ public void testCounter() throws Exception {
+ TraceConfig traceConfig = getTraceConfig(FOO);
+
+ long ptr = nativeStartTracing(traceConfig.toByteArray());
+
+ PerfettoTrackEventExtra intExtra = PerfettoTrackEventExtra.builder()
+ .usingCounterTrack(FOO, PerfettoTrace.getProcessTrackUuid())
+ .setCounter(16)
+ .build();
+ PerfettoTrace.counter(FOO_CATEGORY, intExtra);
+
+ PerfettoTrackEventExtra doubleExtra = PerfettoTrackEventExtra.builder()
+ .usingCounterTrack("bar", PerfettoTrace.getProcessTrackUuid())
+ .setCounter(3.14)
+ .build();
+ PerfettoTrace.counter(FOO_CATEGORY, doubleExtra);
+
+ Trace trace = Trace.parseFrom(nativeStopTracing(ptr));
+
+ boolean hasTrackEvent = false;
+ boolean hasCounterValue = false;
+ boolean hasDoubleCounterValue = false;
+ for (TracePacket packet: trace.getPacketList()) {
+ TrackEvent event;
+ if (packet.hasTrackEvent()) {
+ hasTrackEvent = true;
+ event = packet.getTrackEvent();
+
+ if (TrackEvent.Type.TYPE_COUNTER.equals(event.getType())
+ && event.getCounterValue() == 16) {
+ hasCounterValue = true;
+ }
+
+ if (TrackEvent.Type.TYPE_COUNTER.equals(event.getType())
+ && event.getDoubleCounterValue() == 3.14) {
+ hasDoubleCounterValue = true;
+ }
+ }
+
+ collectTrackNames(packet);
+ }
+
+ assertThat(hasTrackEvent).isTrue();
+ assertThat(hasCounterValue).isTrue();
+ assertThat(hasDoubleCounterValue).isTrue();
+ assertThat(mTrackNames).contains(FOO);
+ assertThat(mTrackNames).contains(BAR);
+ }
+
+ @Test
+ @RequiresFlagsEnabled(android.os.Flags.FLAG_PERFETTO_SDK_TRACING_V2)
+ public void testProto() throws Exception {
+ TraceConfig traceConfig = getTraceConfig(FOO);
+
+ long ptr = nativeStartTracing(traceConfig.toByteArray());
+
+ PerfettoTrackEventExtra extra5 = PerfettoTrackEventExtra.builder()
+ .beginProto()
+ .beginNested(33L)
+ .addField(4L, 2L)
+ .addField(3, "ActivityManagerService.java:11489")
+ .endNested()
+ .addField(2001, "AIDL::IActivityManager")
+ .endProto()
+ .build();
+ PerfettoTrace.instant(FOO_CATEGORY, "event_proto", extra5);
+
+ byte[] traceBytes = nativeStopTracing(ptr);
+
+ Trace trace = Trace.parseFrom(traceBytes);
+
+ boolean hasTrackEvent = false;
+ boolean hasSourceLocation = false;
+
+ for (TracePacket packet: trace.getPacketList()) {
+ TrackEvent event;
+ if (packet.hasTrackEvent()) {
+ hasTrackEvent = true;
+ event = packet.getTrackEvent();
+
+ if (TrackEvent.Type.TYPE_INSTANT.equals(event.getType())
+ && event.hasSourceLocation()) {
+ SourceLocation loc = event.getSourceLocation();
+ if ("ActivityManagerService.java:11489".equals(loc.getFunctionName())
+ && loc.getLineNumber() == 2) {
+ hasSourceLocation = true;
+ }
+ }
+ }
+
+ collectInternedData(packet);
+ }
+
+ assertThat(hasTrackEvent).isTrue();
+ assertThat(hasSourceLocation).isTrue();
+ assertThat(mCategoryNames).contains(FOO);
+ }
+
+ @Test
+ @RequiresFlagsEnabled(android.os.Flags.FLAG_PERFETTO_SDK_TRACING_V2)
+ public void testProtoNested() throws Exception {
+ TraceConfig traceConfig = getTraceConfig(FOO);
+
+ long ptr = nativeStartTracing(traceConfig.toByteArray());
+
+ PerfettoTrackEventExtra extra6 = PerfettoTrackEventExtra.builder()
+ .beginProto()
+ .beginNested(29L)
+ .beginNested(4L)
+ .addField(1L, 2)
+ .addField(2L, 20000)
+ .endNested()
+ .beginNested(4L)
+ .addField(1L, 1)
+ .addField(2L, 40000)
+ .endNested()
+ .endNested()
+ .endProto()
+ .build();
+ PerfettoTrace.instant(FOO_CATEGORY, "event_proto_nested", extra6);
+
+ byte[] traceBytes = nativeStopTracing(ptr);
+
+ Trace trace = Trace.parseFrom(traceBytes);
+
+ boolean hasTrackEvent = false;
+ boolean hasChromeLatencyInfo = false;
+
+ for (TracePacket packet: trace.getPacketList()) {
+ TrackEvent event;
+ if (packet.hasTrackEvent()) {
+ hasTrackEvent = true;
+ event = packet.getTrackEvent();
+
+ if (TrackEvent.Type.TYPE_INSTANT.equals(event.getType())
+ && event.hasChromeLatencyInfo()) {
+ ChromeLatencyInfo latencyInfo = event.getChromeLatencyInfo();
+ if (latencyInfo.getComponentInfoCount() == 2) {
+ hasChromeLatencyInfo = true;
+ ComponentInfo cmpInfo1 = latencyInfo.getComponentInfo(0);
+ assertThat(cmpInfo1.getComponentType())
+ .isEqualTo(COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL);
+ assertThat(cmpInfo1.getTimeUs()).isEqualTo(20000);
+
+ ComponentInfo cmpInfo2 = latencyInfo.getComponentInfo(1);
+ assertThat(cmpInfo2.getComponentType())
+ .isEqualTo(COMPONENT_INPUT_EVENT_LATENCY_BEGIN_RWH);
+ assertThat(cmpInfo2.getTimeUs()).isEqualTo(40000);
+ }
+ }
+ }
+
+ collectInternedData(packet);
+ }
+
+ assertThat(hasTrackEvent).isTrue();
+ assertThat(hasChromeLatencyInfo).isTrue();
+ assertThat(mCategoryNames).contains(FOO);
+ }
+
+ @Test
+ @RequiresFlagsEnabled(android.os.Flags.FLAG_PERFETTO_SDK_TRACING_V2)
+ public void testActivateTrigger() throws Exception {
+ TraceConfig traceConfig = getTriggerTraceConfig(FOO, FOO);
+
+ long ptr = nativeStartTracing(traceConfig.toByteArray());
+
+ PerfettoTrackEventExtra extra = PerfettoTrackEventExtra.builder().build();
+ PerfettoTrace.instant(FOO_CATEGORY, "event_trigger", extra);
+
+ PerfettoTrace.activateTrigger(FOO, 1000);
+
+ byte[] traceBytes = nativeStopTracing(ptr);
+
+ Trace trace = Trace.parseFrom(traceBytes);
+
+ boolean hasTrackEvent = false;
+ boolean hasChromeLatencyInfo = false;
+
+ for (TracePacket packet: trace.getPacketList()) {
+ TrackEvent event;
+ if (packet.hasTrackEvent()) {
+ hasTrackEvent = true;
+ }
+
+ collectInternedData(packet);
+ }
+
+ assertThat(mCategoryNames).contains(FOO);
+ }
+
+ @Test
+ @RequiresFlagsEnabled(android.os.Flags.FLAG_PERFETTO_SDK_TRACING_V2)
+ public void testMultipleExtras() throws Exception {
+ boolean hasException = false;
+ try {
+ PerfettoTrackEventExtra.builder();
+
+ // Unclosed extra will throw an exception here
+ PerfettoTrackEventExtra.builder();
+ } catch (Exception e) {
+ hasException = true;
+ }
+
+ try {
+ PerfettoTrackEventExtra.builder().build();
+
+ // Closed extra but unused (reset hasn't been called internally) will throw an exception
+ // here.
+ PerfettoTrackEventExtra.builder();
+ } catch (Exception e) {
+ hasException &= true;
+ }
+
+ assertThat(hasException).isTrue();
+ }
+
+ @Test
+ @RequiresFlagsEnabled(android.os.Flags.FLAG_PERFETTO_SDK_TRACING_V2)
+ public void testRegister() throws Exception {
+ TraceConfig traceConfig = getTraceConfig(BAR);
+
+ Category barCategory = new Category(BAR);
+ long ptr = nativeStartTracing(traceConfig.toByteArray());
+
+ PerfettoTrackEventExtra beforeExtra = PerfettoTrackEventExtra.builder()
+ .addArg("before", 1)
+ .build();
+ PerfettoTrace.instant(barCategory, "event", beforeExtra);
+
+ barCategory.register();
+
+ PerfettoTrackEventExtra afterExtra = PerfettoTrackEventExtra.builder()
+ .addArg("after", 1)
+ .build();
+ PerfettoTrace.instant(barCategory, "event", afterExtra);
+
+ byte[] traceBytes = nativeStopTracing(ptr);
+
+ Trace trace = Trace.parseFrom(traceBytes);
+
+ boolean hasTrackEvent = false;
+ for (TracePacket packet: trace.getPacketList()) {
+ TrackEvent event;
+ if (packet.hasTrackEvent()) {
+ hasTrackEvent = true;
+ event = packet.getTrackEvent();
+ }
+
+ collectInternedData(packet);
+ }
+
+ assertThat(hasTrackEvent).isTrue();
+ assertThat(mCategoryNames).contains(BAR);
+
+ assertThat(mDebugAnnotationNames).contains("after");
+ assertThat(mDebugAnnotationNames).doesNotContain("before");
+ }
+
+ private static native long nativeStartTracing(byte[] config);
+ private static native void nativeRegisterPerfetto();
+ private static native byte[] nativeStopTracing(long ptr);
+
+ private TrackEvent getTrackEvent(Trace trace, int idx) {
+ int curIdx = 0;
+ for (TracePacket packet: trace.getPacketList()) {
+ if (packet.hasTrackEvent()) {
+ if (curIdx++ == idx) {
+ return packet.getTrackEvent();
+ }
+ }
+ }
+
+ return null;
+ }
+
+ private TraceConfig getTraceConfig(String cat) {
+ BufferConfig bufferConfig = BufferConfig.newBuilder().setSizeKb(1024).build();
+ TrackEventConfig trackEventConfig = TrackEventConfig
+ .newBuilder()
+ .addEnabledCategories(cat)
+ .build();
+ DataSourceConfig dsConfig = DataSourceConfig
+ .newBuilder()
+ .setName("track_event")
+ .setTargetBuffer(0)
+ .setTrackEventConfig(trackEventConfig)
+ .build();
+ DataSource ds = DataSource.newBuilder().setConfig(dsConfig).build();
+ TraceConfig traceConfig = TraceConfig
+ .newBuilder()
+ .addBuffers(bufferConfig)
+ .addDataSources(ds)
+ .build();
+ return traceConfig;
+ }
+
+ private TraceConfig getTriggerTraceConfig(String cat, String triggerName) {
+ BufferConfig bufferConfig = BufferConfig.newBuilder().setSizeKb(1024).build();
+ TrackEventConfig trackEventConfig = TrackEventConfig
+ .newBuilder()
+ .addEnabledCategories(cat)
+ .build();
+ DataSourceConfig dsConfig = DataSourceConfig
+ .newBuilder()
+ .setName("track_event")
+ .setTargetBuffer(0)
+ .setTrackEventConfig(trackEventConfig)
+ .build();
+ DataSource ds = DataSource.newBuilder().setConfig(dsConfig).build();
+ Trigger trigger = Trigger.newBuilder().setName(triggerName).build();
+ TriggerConfig triggerConfig = TriggerConfig
+ .newBuilder()
+ .setTriggerMode(TriggerConfig.TriggerMode.STOP_TRACING)
+ .setTriggerTimeoutMs(1000)
+ .addTriggers(trigger)
+ .build();
+ TraceConfig traceConfig = TraceConfig
+ .newBuilder()
+ .addBuffers(bufferConfig)
+ .addDataSources(ds)
+ .setTriggerConfig(triggerConfig)
+ .build();
+ return traceConfig;
+ }
+
+ private void collectInternedData(TracePacket packet) {
+ if (!packet.hasInternedData()) {
+ return;
+ }
+
+ InternedData data = packet.getInternedData();
+
+ for (EventCategory cat : data.getEventCategoriesList()) {
+ mCategoryNames.add(cat.getName());
+ }
+ for (EventName ev : data.getEventNamesList()) {
+ mEventNames.add(ev.getName());
+ }
+ for (DebugAnnotationName dbg : data.getDebugAnnotationNamesList()) {
+ mDebugAnnotationNames.add(dbg.getName());
+ }
+ }
+
+ private void collectTrackNames(TracePacket packet) {
+ if (!packet.hasTrackDescriptor()) {
+ return;
+ }
+ TrackDescriptor desc = packet.getTrackDescriptor();
+ mTrackNames.add(desc.getName());
+ }
+}
diff --git a/libs/WindowManager/Shell/AndroidManifest.xml b/libs/WindowManager/Shell/AndroidManifest.xml
index 636e3cfd571d..46fe53716c01 100644
--- a/libs/WindowManager/Shell/AndroidManifest.xml
+++ b/libs/WindowManager/Shell/AndroidManifest.xml
@@ -26,6 +26,7 @@
<uses-permission android:name="android.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE" />
<uses-permission android:name="android.permission.UPDATE_DOMAIN_VERIFICATION_USER_SELECTION" />
<uses-permission android:name="android.permission.MANAGE_KEY_GESTURES" />
+ <uses-permission android:name="android.permission.MANAGE_DISPLAYS" />
<application>
<activity
diff --git a/libs/WindowManager/Shell/aconfig/multitasking.aconfig b/libs/WindowManager/Shell/aconfig/multitasking.aconfig
index 500548500927..bbdcbc9147e4 100644
--- a/libs/WindowManager/Shell/aconfig/multitasking.aconfig
+++ b/libs/WindowManager/Shell/aconfig/multitasking.aconfig
@@ -178,3 +178,10 @@ flag {
description: "Factor task-view state tracking out of taskviewtransitions"
bug: "384976265"
}
+
+flag {
+ name: "enable_non_default_display_split"
+ namespace: "multitasking"
+ description: "Enables split screen on non default displays"
+ bug: "384999213"
+}
diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerViewTest.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerViewTest.kt
index 04c9ffbac287..5c86b321b60f 100644
--- a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerViewTest.kt
+++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerViewTest.kt
@@ -16,6 +16,7 @@
package com.android.wm.shell.bubbles.bar
+import android.animation.AnimatorTestRule
import android.content.Context
import android.content.pm.LauncherApps
import android.graphics.PointF
@@ -25,7 +26,7 @@ import android.view.IWindowManager
import android.view.MotionEvent
import android.view.View
import android.view.WindowManager
-import androidx.core.animation.AnimatorTestRule
+import androidx.core.view.children
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
@@ -41,7 +42,7 @@ import com.android.wm.shell.bubbles.Bubble
import com.android.wm.shell.bubbles.BubbleController
import com.android.wm.shell.bubbles.BubbleData
import com.android.wm.shell.bubbles.BubbleDataRepository
-import com.android.wm.shell.bubbles.BubbleEducationController
+import com.android.wm.shell.bubbles.BubbleExpandedViewManager
import com.android.wm.shell.bubbles.BubbleLogger
import com.android.wm.shell.bubbles.BubblePositioner
import com.android.wm.shell.bubbles.Bubbles.SysuiProxy
@@ -68,32 +69,31 @@ import com.android.wm.shell.transition.Transitions
import com.google.common.truth.Truth.assertThat
import org.junit.After
import org.junit.Before
-import org.junit.ClassRule
+import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito.mock
import org.mockito.kotlin.mock
+import org.mockito.kotlin.whenever
/** Tests for [BubbleBarLayerView] */
@SmallTest
@RunWith(AndroidJUnit4::class)
class BubbleBarLayerViewTest {
- companion object {
- @JvmField @ClassRule val animatorTestRule: AnimatorTestRule = AnimatorTestRule()
- }
+ @get:Rule val animatorTestRule: AnimatorTestRule = AnimatorTestRule(this)
private val context = ApplicationProvider.getApplicationContext<Context>()
private lateinit var bubbleBarLayerView: BubbleBarLayerView
-
private lateinit var uiEventLoggerFake: UiEventLoggerFake
-
private lateinit var bubbleController: BubbleController
-
private lateinit var bubblePositioner: BubblePositioner
-
- private lateinit var bubble: Bubble
+ private lateinit var expandedViewManager: BubbleExpandedViewManager
+ private lateinit var mainExecutor: TestShellExecutor
+ private lateinit var bgExecutor: TestShellExecutor
+ private lateinit var bubbleLogger: BubbleLogger
+ private lateinit var testBubblesList: MutableList<Bubble>
@Before
fun setUp() {
@@ -102,25 +102,20 @@ class BubbleBarLayerViewTest {
PhysicsAnimatorTestUtils.prepareForTest()
uiEventLoggerFake = UiEventLoggerFake()
- val bubbleLogger = BubbleLogger(uiEventLoggerFake)
+ bubbleLogger = BubbleLogger(uiEventLoggerFake)
- val mainExecutor = TestShellExecutor()
- val bgExecutor = TestShellExecutor()
+ mainExecutor = TestShellExecutor()
+ bgExecutor = TestShellExecutor()
val windowManager = context.getSystemService(WindowManager::class.java)
bubblePositioner = BubblePositioner(context, windowManager)
bubblePositioner.setShowingInBubbleBar(true)
- val bubbleData =
- BubbleData(
- context,
- bubbleLogger,
- bubblePositioner,
- BubbleEducationController(context),
- mainExecutor,
- bgExecutor,
- )
+ testBubblesList = mutableListOf()
+ val bubbleData = mock<BubbleData>()
+ whenever(bubbleData.bubbles).thenReturn(testBubblesList)
+ whenever(bubbleData.hasBubbles()).thenReturn(!testBubblesList.isEmpty())
bubbleController =
createBubbleController(
@@ -137,21 +132,7 @@ class BubbleBarLayerViewTest {
bubbleBarLayerView = BubbleBarLayerView(context, bubbleController, bubbleData, bubbleLogger)
- val expandedViewManager = FakeBubbleExpandedViewManager(bubbleBar = true, expanded = true)
- val bubbleTaskView = FakeBubbleTaskViewFactory(context, mainExecutor).create()
- val bubbleBarExpandedView =
- FakeBubbleFactory.createExpandedView(
- context,
- bubblePositioner,
- expandedViewManager,
- bubbleTaskView,
- mainExecutor,
- bgExecutor,
- bubbleLogger,
- )
-
- val viewInfo = FakeBubbleFactory.createViewInfo(bubbleBarExpandedView)
- bubble = FakeBubbleFactory.createChatBubble(context, viewInfo = viewInfo)
+ expandedViewManager = FakeBubbleExpandedViewManager(bubbleBar = true, expanded = true)
}
@After
@@ -221,7 +202,54 @@ class BubbleBarLayerViewTest {
}
@Test
+ fun showExpandedView() {
+ val bubble = createBubble("first")
+
+ getInstrumentation().runOnMainSync { bubbleBarLayerView.showExpandedView(bubble) }
+ waitForExpandedViewAnimation()
+
+ // Scrim, dismiss view and expanded view
+ assertThat(bubbleBarLayerView.childCount).isEqualTo(3)
+ assertThat(bubbleBarLayerView.getChildAt(2)).isEqualTo(bubble.bubbleBarExpandedView)
+ }
+
+ @Test
+ fun twoBubbles_dismissActiveBubble_newBubbleShown() {
+ val firstBubble = createBubble("first")
+ val secondBubble = createBubble("second")
+
+ getInstrumentation().runOnMainSync { bubbleBarLayerView.showExpandedView(firstBubble) }
+ waitForExpandedViewAnimation()
+
+ getInstrumentation().runOnMainSync { bubbleBarLayerView.removeBubble(firstBubble) {} }
+ // Expanded view is removed when bubble is removed
+ assertThat(firstBubble.bubbleBarExpandedView).isNull()
+
+ getInstrumentation().runOnMainSync { bubbleBarLayerView.showExpandedView(secondBubble) }
+ waitForExpandedViewAnimation()
+
+ assertThat(bubbleBarLayerView.children.count { it is BubbleBarExpandedView }).isEqualTo(1)
+ assertThat(bubbleBarLayerView.children.last()).isEqualTo(secondBubble.bubbleBarExpandedView)
+ }
+
+ @Test
+ fun twoBubbles_switchBubbles_newBubbleShown() {
+ val firstBubble = createBubble("first")
+ val secondBubble = createBubble("second")
+
+ getInstrumentation().runOnMainSync { bubbleBarLayerView.showExpandedView(firstBubble) }
+ waitForExpandedViewAnimation()
+
+ getInstrumentation().runOnMainSync { bubbleBarLayerView.showExpandedView(secondBubble) }
+ waitForExpandedViewAnimation()
+
+ assertThat(bubbleBarLayerView.children.count { it is BubbleBarExpandedView }).isEqualTo(1)
+ assertThat(bubbleBarLayerView.children.last()).isEqualTo(secondBubble.bubbleBarExpandedView)
+ }
+
+ @Test
fun testEventLogging_dismissExpandedViewViaDrag() {
+ val bubble = createBubble("first")
getInstrumentation().runOnMainSync { bubbleBarLayerView.showExpandedView(bubble) }
assertThat(bubbleBarLayerView.findViewById<View>(R.id.bubble_bar_handle_view)).isNotNull()
@@ -235,6 +263,7 @@ class BubbleBarLayerViewTest {
@Test
fun testEventLogging_dragExpandedViewLeft() {
+ val bubble = createBubble("first")
bubblePositioner.bubbleBarLocation = BubbleBarLocation.RIGHT
getInstrumentation().runOnMainSync {
@@ -259,6 +288,7 @@ class BubbleBarLayerViewTest {
@Test
fun testEventLogging_dragExpandedViewRight() {
+ val bubble = createBubble("first")
bubblePositioner.bubbleBarLocation = BubbleBarLocation.LEFT
getInstrumentation().runOnMainSync {
@@ -281,6 +311,27 @@ class BubbleBarLayerViewTest {
assertThat(uiEventLoggerFake.logs[0]).hasBubbleInfo(bubble)
}
+ private fun createBubble(key: String): Bubble {
+ val bubbleTaskView = FakeBubbleTaskViewFactory(context, mainExecutor).create()
+ val bubbleBarExpandedView =
+ FakeBubbleFactory.createExpandedView(
+ context,
+ bubblePositioner,
+ expandedViewManager,
+ bubbleTaskView,
+ mainExecutor,
+ bgExecutor,
+ bubbleLogger,
+ )
+ // Mark visible so we don't wait for task view before animations can start
+ bubbleBarExpandedView.onContentVisibilityChanged(true)
+
+ val viewInfo = FakeBubbleFactory.createViewInfo(bubbleBarExpandedView)
+ return FakeBubbleFactory.createChatBubble(context, key, viewInfo).also {
+ testBubblesList.add(it)
+ }
+ }
+
private fun leftEdge(): PointF {
val screenSize = bubblePositioner.availableRect
return PointF(screenSize.left.toFloat(), screenSize.height() / 2f)
@@ -293,12 +344,12 @@ class BubbleBarLayerViewTest {
private fun waitForExpandedViewAnimation() {
// wait for idle to allow the animation to start
- getInstrumentation().waitForIdleSync()
- getInstrumentation().runOnMainSync { animatorTestRule.advanceTimeBy(200) }
+ getInstrumentation().runOnMainSync { animatorTestRule.advanceTimeBy(1000) }
PhysicsAnimatorTestUtils.blockUntilAnimationsEnd(
AnimatableScaleMatrix.SCALE_X,
AnimatableScaleMatrix.SCALE_Y,
)
+ getInstrumentation().waitForIdleSync()
}
private fun View.dispatchTouchEvent(eventTime: Long, action: Int, point: PointF) {
diff --git a/libs/WindowManager/Shell/shared/res/drawable/floating_dismiss_background.xml b/libs/WindowManager/Shell/shared/res/drawable/floating_dismiss_background.xml
new file mode 100644
index 000000000000..003f397ff97d
--- /dev/null
+++ b/libs/WindowManager/Shell/shared/res/drawable/floating_dismiss_background.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2024 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<shape
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="oval">
+
+ <stroke
+ android:width="2dp"
+ android:color="@android:color/system_primary_fixed" />
+
+ <solid android:color="@android:color/system_primary_fixed" />
+</shape> \ No newline at end of file
diff --git a/libs/WindowManager/Shell/shared/res/drawable/floating_dismiss_ic_close.xml b/libs/WindowManager/Shell/shared/res/drawable/floating_dismiss_ic_close.xml
new file mode 100644
index 000000000000..8b133a417f79
--- /dev/null
+++ b/libs/WindowManager/Shell/shared/res/drawable/floating_dismiss_ic_close.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2024 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="32dp"
+ android:height="32dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:pathData="M19.000000,6.400000l-1.400000,-1.400000 -5.600000,5.600000 -5.600000,-5.600000 -1.400000,1.400000 5.600000,5.600000 -5.600000,5.600000 1.400000,1.400000 5.600000,-5.600000 5.600000,5.600000 1.400000,-1.400000 -5.600000,-5.600000z"
+ android:fillColor="@android:color/system_on_primary_fixed"/>
+</vector>
diff --git a/libs/WindowManager/Shell/shared/res/values/dimen.xml b/libs/WindowManager/Shell/shared/res/values/dimen.xml
new file mode 100644
index 000000000000..0b1f76f5ce0e
--- /dev/null
+++ b/libs/WindowManager/Shell/shared/res/values/dimen.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ Copyright (C) 2024 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<resources>
+ <dimen name="floating_dismiss_icon_size">32dp</dimen>
+ <dimen name="floating_dismiss_background_size">96dp</dimen>
+</resources> \ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/DismissViewExt.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/DismissViewExt.kt
index 00a81727a9ac..2f0b62c20df9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/DismissViewExt.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/DismissViewExt.kt
@@ -19,16 +19,17 @@ package com.android.wm.shell.bubbles
import com.android.wm.shell.R
import com.android.wm.shell.shared.bubbles.DismissView
+import com.android.wm.shell.shared.R as SharedR
fun DismissView.setup() {
setup(DismissView.Config(
dismissViewResId = R.id.dismiss_view,
- targetSizeResId = R.dimen.dismiss_circle_size,
- iconSizeResId = R.dimen.dismiss_target_x_size,
+ targetSizeResId = SharedR.dimen.floating_dismiss_background_size,
+ iconSizeResId = SharedR.dimen.floating_dismiss_icon_size,
bottomMarginResId = R.dimen.floating_dismiss_bottom_margin,
floatingGradientHeightResId = R.dimen.floating_dismiss_gradient_height,
floatingGradientColorResId = android.R.color.system_neutral1_900,
- backgroundResId = R.drawable.dismiss_circle_background,
- iconResId = R.drawable.pip_ic_close_white
+ backgroundResId = SharedR.drawable.floating_dismiss_background,
+ iconResId = SharedR.drawable.floating_dismiss_ic_close,
))
} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java
index 425afbed0742..88f34f3043e1 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java
@@ -184,7 +184,7 @@ public class BubbleBarLayerView extends FrameLayout
}
BubbleViewProvider previousBubble = null;
if (mExpandedBubble != null && !b.getKey().equals(mExpandedBubble.getKey())) {
- if (mIsExpanded) {
+ if (mIsExpanded && mExpandedBubble.getBubbleBarExpandedView() != null) {
// Previous expanded view open, keep it visible to animate the switch
previousBubble = mExpandedBubble;
} else {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayController.java
index f532be6b8277..3a8a7f6e46d3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayController.java
@@ -21,6 +21,7 @@ import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.hardware.display.DisplayManager;
+import android.hardware.display.DisplayTopology;
import android.os.RemoteException;
import android.util.ArraySet;
import android.util.Size;
@@ -54,6 +55,7 @@ public class DisplayController {
private final ShellExecutor mMainExecutor;
private final Context mContext;
private final IWindowManager mWmService;
+ private final DisplayManager mDisplayManager;
private final DisplayChangeController mChangeController;
private final IDisplayWindowListener mDisplayContainerListener;
@@ -61,10 +63,11 @@ public class DisplayController {
private final ArrayList<OnDisplaysChangedListener> mDisplayChangedListeners = new ArrayList<>();
public DisplayController(Context context, IWindowManager wmService, ShellInit shellInit,
- ShellExecutor mainExecutor) {
+ ShellExecutor mainExecutor, DisplayManager displayManager) {
mMainExecutor = mainExecutor;
mContext = context;
mWmService = wmService;
+ mDisplayManager = displayManager;
// TODO: Inject this instead
mChangeController = new DisplayChangeController(mWmService, shellInit, mainExecutor);
mDisplayContainerListener = new DisplayWindowListenerImpl();
@@ -74,7 +77,7 @@ public class DisplayController {
}
/**
- * Initializes the window listener.
+ * Initializes the window listener and the topology listener.
*/
public void onInit() {
try {
@@ -82,6 +85,9 @@ public class DisplayController {
for (int i = 0; i < displayIds.length; i++) {
onDisplayAdded(displayIds[i]);
}
+
+ mDisplayManager.registerTopologyListener(mMainExecutor, this::onDisplayTopologyChanged);
+ onDisplayTopologyChanged(mDisplayManager.getDisplayTopology());
} catch (RemoteException e) {
throw new RuntimeException("Unable to register display controller");
}
@@ -91,8 +97,7 @@ public class DisplayController {
* Gets a display by id from DisplayManager.
*/
public Display getDisplay(int displayId) {
- final DisplayManager displayManager = mContext.getSystemService(DisplayManager.class);
- return displayManager.getDisplay(displayId);
+ return mDisplayManager.getDisplay(displayId);
}
/**
@@ -221,6 +226,14 @@ public class DisplayController {
}
}
+ private void onDisplayTopologyChanged(DisplayTopology topology) {
+ // TODO(b/381472611): Call DisplayTopology#getCoordinates and update values in
+ // DisplayLayout when DM code is ready.
+ for (int i = 0; i < mDisplayChangedListeners.size(); ++i) {
+ mDisplayChangedListeners.get(i).onTopologyChanged();
+ }
+ }
+
private void onDisplayConfigurationChanged(int displayId, Configuration newConfig) {
synchronized (mDisplays) {
final DisplayRecord dr = mDisplays.get(displayId);
@@ -408,5 +421,10 @@ public class DisplayController {
*/
default void onKeepClearAreasChanged(int displayId, Set<Rect> restricted,
Set<Rect> unrestricted) {}
+
+ /**
+ * Called when the display topology has changed.
+ */
+ default void onTopologyChanged() {}
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java
index b6a1686bd087..4973a6f16409 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java
@@ -31,7 +31,9 @@ import android.content.ContentResolver;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Insets;
+import android.graphics.PointF;
import android.graphics.Rect;
+import android.graphics.RectF;
import android.os.SystemProperties;
import android.provider.Settings;
import android.util.DisplayMetrics;
@@ -71,9 +73,12 @@ public class DisplayLayout {
public static final int NAV_BAR_RIGHT = 1 << 1;
public static final int NAV_BAR_BOTTOM = 1 << 2;
+ private static final String TAG = "DisplayLayout";
+
private int mUiMode;
private int mWidth;
private int mHeight;
+ private RectF mGlobalBoundsDp;
private DisplayCutout mCutout;
private int mRotation;
private int mDensityDpi;
@@ -109,6 +114,7 @@ public class DisplayLayout {
return mUiMode == other.mUiMode
&& mWidth == other.mWidth
&& mHeight == other.mHeight
+ && Objects.equals(mGlobalBoundsDp, other.mGlobalBoundsDp)
&& Objects.equals(mCutout, other.mCutout)
&& mRotation == other.mRotation
&& mDensityDpi == other.mDensityDpi
@@ -127,8 +133,8 @@ public class DisplayLayout {
@Override
public int hashCode() {
- return Objects.hash(mUiMode, mWidth, mHeight, mCutout, mRotation, mDensityDpi,
- mNonDecorInsets, mStableInsets, mHasNavigationBar, mHasStatusBar,
+ return Objects.hash(mUiMode, mWidth, mHeight, mGlobalBoundsDp, mCutout, mRotation,
+ mDensityDpi, mNonDecorInsets, mStableInsets, mHasNavigationBar, mHasStatusBar,
mNavBarFrameHeight, mTaskbarFrameHeight, mAllowSeamlessRotationDespiteNavBarMoving,
mNavigationBarCanMove, mReverseDefaultRotation, mInsetsState);
}
@@ -170,6 +176,7 @@ public class DisplayLayout {
mUiMode = dl.mUiMode;
mWidth = dl.mWidth;
mHeight = dl.mHeight;
+ mGlobalBoundsDp = dl.mGlobalBoundsDp;
mCutout = dl.mCutout;
mRotation = dl.mRotation;
mDensityDpi = dl.mDensityDpi;
@@ -193,6 +200,7 @@ public class DisplayLayout {
mRotation = info.rotation;
mCutout = info.displayCutout;
mDensityDpi = info.logicalDensityDpi;
+ mGlobalBoundsDp = new RectF(0, 0, pxToDp(mWidth), pxToDp(mHeight));
mHasNavigationBar = hasNavigationBar;
mHasStatusBar = hasStatusBar;
mAllowSeamlessRotationDespiteNavBarMoving = res.getBoolean(
@@ -255,6 +263,11 @@ public class DisplayLayout {
recalcInsets(res);
}
+ /** Update the global bounds of this layout, in DP. */
+ public void setGlobalBoundsDp(RectF bounds) {
+ mGlobalBoundsDp = bounds;
+ }
+
/** Get this layout's non-decor insets. */
public Rect nonDecorInsets() {
return mNonDecorInsets;
@@ -265,16 +278,21 @@ public class DisplayLayout {
return mStableInsets;
}
- /** Get this layout's width. */
+ /** Get this layout's width in pixels. */
public int width() {
return mWidth;
}
- /** Get this layout's height. */
+ /** Get this layout's height in pixels. */
public int height() {
return mHeight;
}
+ /** Get this layout's global bounds in the multi-display coordinate system in DP. */
+ public RectF globalBoundsDp() {
+ return mGlobalBoundsDp;
+ }
+
/** Get this layout's display rotation. */
public int rotation() {
return mRotation;
@@ -486,4 +504,48 @@ public class DisplayLayout {
? R.dimen.navigation_bar_frame_height_landscape
: R.dimen.navigation_bar_frame_height);
}
+
+ /**
+ * Converts a pixel value to a density-independent pixel (dp) value.
+ *
+ * @param px The pixel value to convert.
+ * @return The equivalent value in DP units.
+ */
+ public float pxToDp(Number px) {
+ return px.floatValue() * DisplayMetrics.DENSITY_DEFAULT / mDensityDpi;
+ }
+
+ /**
+ * Converts a density-independent pixel (dp) value to a pixel value.
+ *
+ * @param dp The DP value to convert.
+ * @return The equivalent value in pixel units.
+ */
+ public float dpToPx(Number dp) {
+ return dp.floatValue() * mDensityDpi / DisplayMetrics.DENSITY_DEFAULT;
+ }
+
+ /**
+ * Converts local pixel coordinates on this layout to global DP coordinates.
+ *
+ * @param xPx The x-coordinate in pixels, relative to the layout's origin.
+ * @param yPx The y-coordinate in pixels, relative to the layout's origin.
+ * @return A PointF object representing the coordinates in global DP units.
+ */
+ public PointF localPxToGlobalDp(Number xPx, Number yPx) {
+ return new PointF(mGlobalBoundsDp.left + pxToDp(xPx),
+ mGlobalBoundsDp.top + pxToDp(yPx));
+ }
+
+ /**
+ * Converts global DP coordinates to local pixel coordinates on this layout.
+ *
+ * @param xDp The x-coordinate in global DP units.
+ * @param yDp The y-coordinate in global DP units.
+ * @return A PointF object representing the coordinates in local pixel units on this layout.
+ */
+ public PointF globalDpToLocalPx(Number xDp, Number yDp) {
+ return new PointF(dpToPx(xDp.floatValue() - mGlobalBoundsDp.left),
+ dpToPx(yDp.floatValue() - mGlobalBoundsDp.top));
+ }
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java
index fe6066c8c4fb..b796b411dd1a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java
@@ -20,6 +20,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.app.ActivityManager.RunningTaskInfo;
import android.app.TaskInfo;
import android.content.ComponentName;
import android.content.Context;
@@ -59,6 +60,7 @@ import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
import com.android.wm.shell.sysui.KeyguardChangeListener;
import com.android.wm.shell.sysui.ShellController;
import com.android.wm.shell.sysui.ShellInit;
+import com.android.wm.shell.transition.FocusTransitionObserver;
import com.android.wm.shell.transition.Transitions;
import dagger.Lazy;
@@ -196,6 +198,9 @@ public class CompatUIController implements OnDisplaysChangedListener,
private final CompatUIStatusManager mCompatUIStatusManager;
@NonNull
+ private final FocusTransitionObserver mFocusTransitionObserver;
+
+ @NonNull
private final Optional<DesktopUserRepositories> mDesktopUserRepositories;
public CompatUIController(@NonNull Context context,
@@ -212,7 +217,8 @@ public class CompatUIController implements OnDisplaysChangedListener,
@NonNull CompatUIShellCommandHandler compatUIShellCommandHandler,
@NonNull AccessibilityManager accessibilityManager,
@NonNull CompatUIStatusManager compatUIStatusManager,
- @NonNull Optional<DesktopUserRepositories> desktopUserRepositories) {
+ @NonNull Optional<DesktopUserRepositories> desktopUserRepositories,
+ @NonNull FocusTransitionObserver focusTransitionObserver) {
mContext = context;
mShellController = shellController;
mDisplayController = displayController;
@@ -229,6 +235,7 @@ public class CompatUIController implements OnDisplaysChangedListener,
DISAPPEAR_DELAY_MS, flags);
mCompatUIStatusManager = compatUIStatusManager;
mDesktopUserRepositories = desktopUserRepositories;
+ mFocusTransitionObserver = focusTransitionObserver;
shellInit.addInitCallback(this::onInit, this);
}
@@ -405,7 +412,8 @@ public class CompatUIController implements OnDisplaysChangedListener,
// start tracking the buttons visibility for this task.
if (mTopActivityTaskId != taskInfo.taskId
&& !taskInfo.isTopActivityTransparent
- && taskInfo.isVisible && taskInfo.isFocused) {
+ && taskInfo.isVisible
+ && mFocusTransitionObserver.hasGlobalFocus((RunningTaskInfo) taskInfo)) {
mTopActivityTaskId = taskInfo.taskId;
setHasShownUserAspectRatioSettingsButton(false);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
index 6c805c87c08f..de0048a68ef9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
@@ -25,6 +25,7 @@ import android.annotation.NonNull;
import android.app.ActivityTaskManager;
import android.content.Context;
import android.content.pm.PackageManager;
+import android.hardware.display.DisplayManager;
import android.os.Handler;
import android.os.SystemProperties;
import android.provider.Settings;
@@ -172,8 +173,9 @@ public abstract class WMShellBaseModule {
static DisplayController provideDisplayController(Context context,
IWindowManager wmService,
ShellInit shellInit,
- @ShellMainThread ShellExecutor mainExecutor) {
- return new DisplayController(context, wmService, shellInit, mainExecutor);
+ @ShellMainThread ShellExecutor mainExecutor,
+ DisplayManager displayManager) {
+ return new DisplayController(context, wmService, shellInit, mainExecutor, displayManager);
}
@WMSingleton
@@ -272,7 +274,8 @@ public abstract class WMShellBaseModule {
@NonNull CompatUIState compatUIState,
@NonNull CompatUIComponentIdGenerator componentIdGenerator,
@NonNull CompatUIComponentFactory compatUIComponentFactory,
- CompatUIStatusManager compatUIStatusManager) {
+ CompatUIStatusManager compatUIStatusManager,
+ @NonNull FocusTransitionObserver focusTransitionObserver) {
if (!context.getResources().getBoolean(R.bool.config_enableCompatUIController)) {
return Optional.empty();
}
@@ -297,7 +300,8 @@ public abstract class WMShellBaseModule {
compatUIShellCommandHandler.get(),
accessibilityManager.get(),
compatUIStatusManager,
- desktopUserRepositories));
+ desktopUserRepositories,
+ focusTransitionObserver));
}
@WMSingleton
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserver.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserver.kt
index ccfbbeef89c9..e975b586c1ee 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserver.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserver.kt
@@ -40,6 +40,7 @@ import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.EnterRe
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ExitReason
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.MinimizeReason
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.TaskUpdate
+import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_DESKTOP_MODE_END_DRAG_TO_DESKTOP
import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_ENTER_DESKTOP_FROM_APP_FROM_OVERVIEW
import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_ENTER_DESKTOP_FROM_APP_HANDLE_MENU_BUTTON
import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_ENTER_DESKTOP_FROM_KEYBOARD_SHORTCUT
@@ -363,7 +364,7 @@ class DesktopModeLoggerTransitionObserver(
||
(transitionInfo.type == WindowManager.TRANSIT_TO_BACK &&
wasPreviousTransitionExitByScreenOff) -> EnterReason.SCREEN_ON
- transitionInfo.type == Transitions.TRANSIT_DESKTOP_MODE_END_DRAG_TO_DESKTOP ->
+ transitionInfo.type == TRANSIT_DESKTOP_MODE_END_DRAG_TO_DESKTOP ->
EnterReason.APP_HANDLE_DRAG
transitionInfo.type == TRANSIT_ENTER_DESKTOP_FROM_APP_HANDLE_MENU_BUTTON ->
EnterReason.APP_HANDLE_MENU_BUTTON
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeTransitionTypes.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeTransitionTypes.kt
index 9b3caca7b2d4..2a10edb8a1c2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeTransitionTypes.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeTransitionTypes.kt
@@ -35,6 +35,18 @@ object DesktopModeTransitionTypes {
const val TRANSIT_EXIT_DESKTOP_MODE_KEYBOARD_SHORTCUT = TRANSIT_DESKTOP_MODE_TYPES + 7
const val TRANSIT_EXIT_DESKTOP_MODE_UNKNOWN = TRANSIT_DESKTOP_MODE_TYPES + 8
+ /** Transition type for starting the drag to desktop mode. */
+ const val TRANSIT_DESKTOP_MODE_START_DRAG_TO_DESKTOP = TRANSIT_DESKTOP_MODE_TYPES + 9
+
+ /** Transition type for finalizing the drag to desktop mode. */
+ const val TRANSIT_DESKTOP_MODE_END_DRAG_TO_DESKTOP = TRANSIT_DESKTOP_MODE_TYPES + 10
+
+ /** Transition type to cancel the drag to desktop mode. */
+ const val TRANSIT_DESKTOP_MODE_CANCEL_DRAG_TO_DESKTOP = TRANSIT_DESKTOP_MODE_TYPES + 11
+
+ /** Transition type to animate the toggle resize between the max and default desktop sizes. */
+ const val TRANSIT_DESKTOP_MODE_TOGGLE_RESIZE = TRANSIT_DESKTOP_MODE_TYPES + 12
+
/** Return whether the [TransitionType] corresponds to a transition to enter desktop mode. */
@JvmStatic
fun @receiver:TransitionType Int.isEnterDesktopModeTransition(): Boolean {
@@ -92,4 +104,18 @@ object DesktopModeTransitionTypes {
else -> TRANSIT_EXIT_DESKTOP_MODE_UNKNOWN
}
}
+
+ /**
+ * Returns a string representing the [TransitionType]. If not supported, returns an empty
+ * string.
+ */
+ @JvmStatic
+ fun transitTypeToString(transitType: Int): String =
+ when (transitType) {
+ TRANSIT_DESKTOP_MODE_START_DRAG_TO_DESKTOP -> "DESKTOP_MODE_START_DRAG_TO_DESKTOP"
+ TRANSIT_DESKTOP_MODE_END_DRAG_TO_DESKTOP -> "DESKTOP_MODE_END_DRAG_TO_DESKTOP"
+ TRANSIT_DESKTOP_MODE_CANCEL_DRAG_TO_DESKTOP -> "DESKTOP_MODE_CANCEL_DRAG_TO_DESKTOP"
+ TRANSIT_DESKTOP_MODE_TOGGLE_RESIZE -> "DESKTOP_MODE_TOGGLE_RESIZE"
+ else -> ""
+ }
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
index a3d3a90fef3e..94955709bf79 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
@@ -881,6 +881,12 @@ class DesktopTasksController(
applyFreeformDisplayChange(wct, task, displayId)
}
wct.reparent(task.token, displayAreaInfo.token, true /* onTop */)
+ if (Flags.enableDisplayFocusInShellTransitions()) {
+ // Bring the destination display to top with includingParents=true, so that the
+ // destination display gains the display focus, which makes the top task in the display
+ // gains the global focus.
+ wct.reorder(task.token, /* onTop= */ true, /* includingParents= */ true)
+ }
if (Flags.enablePerDisplayDesktopWallpaperActivity()) {
performDesktopExitCleanupIfNeeded(task.taskId, task.displayId, wct)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandler.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandler.kt
index d23c9d0b8ffd..72c064248988 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandler.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandler.kt
@@ -37,6 +37,9 @@ import com.android.internal.jank.InteractionJankMonitor
import com.android.internal.protolog.ProtoLog
import com.android.wm.shell.RootTaskDisplayAreaOrganizer
import com.android.wm.shell.animation.FloatProperties
+import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_DESKTOP_MODE_CANCEL_DRAG_TO_DESKTOP
+import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_DESKTOP_MODE_END_DRAG_TO_DESKTOP
+import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_DESKTOP_MODE_START_DRAG_TO_DESKTOP
import com.android.wm.shell.protolog.ShellProtoLogGroup
import com.android.wm.shell.shared.TransitionUtil
import com.android.wm.shell.shared.animation.PhysicsAnimator
@@ -46,9 +49,6 @@ import com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_UND
import com.android.wm.shell.shared.split.SplitScreenConstants.SplitPosition
import com.android.wm.shell.splitscreen.SplitScreenController
import com.android.wm.shell.transition.Transitions
-import com.android.wm.shell.transition.Transitions.TRANSIT_DESKTOP_MODE_CANCEL_DRAG_TO_DESKTOP
-import com.android.wm.shell.transition.Transitions.TRANSIT_DESKTOP_MODE_END_DRAG_TO_DESKTOP
-import com.android.wm.shell.transition.Transitions.TRANSIT_DESKTOP_MODE_START_DRAG_TO_DESKTOP
import com.android.wm.shell.transition.Transitions.TransitionHandler
import com.android.wm.shell.windowdecor.MoveToDesktopAnimator
import com.android.wm.shell.windowdecor.MoveToDesktopAnimator.Companion.DRAG_FREEFORM_SCALE
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ToggleResizeDesktopTaskTransitionHandler.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ToggleResizeDesktopTaskTransitionHandler.kt
index e683f62644c4..a47e9370b58d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ToggleResizeDesktopTaskTransitionHandler.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ToggleResizeDesktopTaskTransitionHandler.kt
@@ -30,8 +30,8 @@ import android.window.WindowContainerTransaction
import androidx.core.animation.addListener
import com.android.internal.jank.Cuj
import com.android.internal.jank.InteractionJankMonitor
+import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_DESKTOP_MODE_TOGGLE_RESIZE
import com.android.wm.shell.transition.Transitions
-import com.android.wm.shell.transition.Transitions.TRANSIT_DESKTOP_MODE_TOGGLE_RESIZE
import com.android.wm.shell.windowdecor.OnTaskResizeAnimationListener
import java.util.function.Supplier
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/HomeTransitionObserver.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/HomeTransitionObserver.java
index 1c7e62b71218..b5220c4ffb50 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/HomeTransitionObserver.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/HomeTransitionObserver.java
@@ -20,7 +20,7 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.window.TransitionInfo.FLAG_BACK_GESTURE_ANIMATED;
-import static com.android.wm.shell.transition.Transitions.TRANSIT_DESKTOP_MODE_START_DRAG_TO_DESKTOP;
+import static com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_DESKTOP_MODE_START_DRAG_TO_DESKTOP;
import static com.android.wm.shell.transition.Transitions.TransitionObserver;
import android.annotation.NonNull;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
index a7d6301ecf06..df81821ff13f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
@@ -85,6 +85,7 @@ import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.ExternalInterfaceBinder;
import com.android.wm.shell.common.RemoteCallable;
import com.android.wm.shell.common.ShellExecutor;
+import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes;
import com.android.wm.shell.keyguard.KeyguardTransitionHandler;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.shared.FocusTransitionListener;
@@ -167,22 +168,6 @@ public class Transitions implements RemoteCallable<Transitions>,
/** Transition type for maximize to freeform transition. */
public static final int TRANSIT_RESTORE_FROM_MAXIMIZE = WindowManager.TRANSIT_FIRST_CUSTOM + 9;
- /** Transition type for starting the drag to desktop mode. */
- public static final int TRANSIT_DESKTOP_MODE_START_DRAG_TO_DESKTOP =
- WindowManager.TRANSIT_FIRST_CUSTOM + 10;
-
- /** Transition type for finalizing the drag to desktop mode. */
- public static final int TRANSIT_DESKTOP_MODE_END_DRAG_TO_DESKTOP =
- WindowManager.TRANSIT_FIRST_CUSTOM + 11;
-
- /** Transition type to cancel the drag to desktop mode. */
- public static final int TRANSIT_DESKTOP_MODE_CANCEL_DRAG_TO_DESKTOP =
- WindowManager.TRANSIT_FIRST_CUSTOM + 13;
-
- /** Transition type to animate the toggle resize between the max and default desktop sizes. */
- public static final int TRANSIT_DESKTOP_MODE_TOGGLE_RESIZE =
- WindowManager.TRANSIT_FIRST_CUSTOM + 14;
-
/** Transition to resize PiP task. */
public static final int TRANSIT_RESIZE_PIP = TRANSIT_FIRST_CUSTOM + 16;
@@ -1872,11 +1857,6 @@ public class Transitions implements RemoteCallable<Transitions>,
case TRANSIT_SPLIT_DISMISS -> "SPLIT_DISMISS";
case TRANSIT_MAXIMIZE -> "MAXIMIZE";
case TRANSIT_RESTORE_FROM_MAXIMIZE -> "RESTORE_FROM_MAXIMIZE";
- case TRANSIT_DESKTOP_MODE_START_DRAG_TO_DESKTOP -> "DESKTOP_MODE_START_DRAG_TO_DESKTOP";
- case TRANSIT_DESKTOP_MODE_END_DRAG_TO_DESKTOP -> "DESKTOP_MODE_END_DRAG_TO_DESKTOP";
- case TRANSIT_DESKTOP_MODE_CANCEL_DRAG_TO_DESKTOP ->
- "DESKTOP_MODE_CANCEL_DRAG_TO_DESKTOP";
- case TRANSIT_DESKTOP_MODE_TOGGLE_RESIZE -> "DESKTOP_MODE_TOGGLE_RESIZE";
case TRANSIT_RESIZE_PIP -> "RESIZE_PIP";
case TRANSIT_TASK_FRAGMENT_DRAG_RESIZE -> "TASK_FRAGMENT_DRAG_RESIZE";
case TRANSIT_SPLIT_PASSTHROUGH -> "SPLIT_PASSTHROUGH";
@@ -1886,6 +1866,9 @@ public class Transitions implements RemoteCallable<Transitions>,
case TRANSIT_END_RECENTS_TRANSITION -> "END_RECENTS_TRANSITION";
default -> "";
};
+ if (typeStr.isEmpty()) {
+ typeStr = DesktopModeTransitionTypes.transitTypeToString(transitType);
+ }
return typeStr + "(FIRST_CUSTOM+" + (transitType - TRANSIT_FIRST_CUSTOM) + ")";
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayControllerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayControllerTests.java
index 1e5e153fdfe1..d3de0f7c09b4 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayControllerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayControllerTests.java
@@ -22,6 +22,7 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import android.content.Context;
+import android.hardware.display.DisplayManager;
import android.view.IWindowManager;
import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -50,12 +51,14 @@ public class DisplayControllerTests extends ShellTestCase {
private @Mock IWindowManager mWM;
private @Mock ShellInit mShellInit;
private @Mock ShellExecutor mMainExecutor;
+ private @Mock DisplayManager mDisplayManager;
private DisplayController mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- mController = new DisplayController(mContext, mWM, mShellInit, mMainExecutor);
+ mController = new DisplayController(
+ mContext, mWM, mShellInit, mMainExecutor, mDisplayManager);
}
@Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayLayoutTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayLayoutTest.java
index d467b399ebbb..b0a455d1bcf8 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayLayoutTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayLayoutTest.java
@@ -33,7 +33,9 @@ import static org.mockito.Mockito.when;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Insets;
+import android.graphics.PointF;
import android.graphics.Rect;
+import android.graphics.RectF;
import android.view.DisplayCutout;
import android.view.DisplayInfo;
@@ -58,6 +60,7 @@ import org.mockito.quality.Strictness;
@SmallTest
public class DisplayLayoutTest extends ShellTestCase {
private MockitoSession mMockitoSession;
+ private static final float DELTA = 0.1f; // Constant for assertion delta
@Before
public void setup() {
@@ -130,6 +133,39 @@ public class DisplayLayoutTest extends ShellTestCase {
assertEquals(new Rect(40, 0, 60, 0), dl.nonDecorInsets());
}
+ @Test
+ public void testDpPxConversion() {
+ int px = 100;
+ float dp = 53.33f;
+ int xPx = 100;
+ int yPx = 200;
+ float xDp = 164.33f;
+ float yDp = 328.66f;
+
+ Resources res = createResources(40, 50, false);
+ DisplayInfo info = createDisplayInfo(1000, 1500, 0, ROTATION_0);
+ DisplayLayout dl = new DisplayLayout(info, res, false, false);
+ dl.setGlobalBoundsDp(new RectF(111f, 222f, 300f, 400f));
+
+ // Test pxToDp
+ float resultDp = dl.pxToDp(px);
+ assertEquals(dp, resultDp, DELTA);
+
+ // Test dpToPx
+ float resultPx = dl.dpToPx(dp);
+ assertEquals(px, resultPx, DELTA);
+
+ // Test localPxToGlobalDp
+ PointF resultGlobalDp = dl.localPxToGlobalDp(xPx, yPx);
+ assertEquals(xDp, resultGlobalDp.x, DELTA);
+ assertEquals(yDp, resultGlobalDp.y, DELTA);
+
+ // Test globalDpToLocalPx
+ PointF resultLocalPx = dl.globalDpToLocalPx(xDp, yDp);
+ assertEquals(xPx, resultLocalPx.x, DELTA);
+ assertEquals(yPx, resultLocalPx.y, DELTA);
+ }
+
private Resources createResources(int navLand, int navPort, boolean navMoves) {
Configuration cfg = new Configuration();
cfg.uiMode = UI_MODE_TYPE_NORMAL;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java
index ecf766db0be3..784e1907894d 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java
@@ -62,6 +62,7 @@ import com.android.wm.shell.desktopmode.DesktopRepository;
import com.android.wm.shell.desktopmode.DesktopUserRepositories;
import com.android.wm.shell.sysui.ShellController;
import com.android.wm.shell.sysui.ShellInit;
+import com.android.wm.shell.transition.FocusTransitionObserver;
import com.android.wm.shell.transition.Transitions;
import dagger.Lazy;
@@ -127,6 +128,8 @@ public class CompatUIControllerTest extends CompatUIShellTestCase {
private DesktopUserRepositories mDesktopUserRepositories;
@Mock
private DesktopRepository mDesktopRepository;
+ @Mock
+ private FocusTransitionObserver mFocusTransitionObserver;
@Captor
ArgumentCaptor<OnInsetsChangedListener> mOnInsetsChangedListenerCaptor;
@@ -162,7 +165,8 @@ public class CompatUIControllerTest extends CompatUIShellTestCase {
mMockDisplayController, mMockDisplayInsetsController, mMockImeController,
mMockSyncQueue, mMockExecutor, mMockTransitionsLazy, mDockStateReader,
mCompatUIConfiguration, mCompatUIShellCommandHandler, mAccessibilityManager,
- mCompatUIStatusManager, Optional.of(mDesktopUserRepositories)) {
+ mCompatUIStatusManager, Optional.of(mDesktopUserRepositories),
+ mFocusTransitionObserver) {
@Override
CompatUIWindowManager createCompatUiWindowManager(Context context, TaskInfo taskInfo,
ShellTaskOrganizer.TaskListener taskListener) {
@@ -280,6 +284,7 @@ public class CompatUIControllerTest extends CompatUIShellTestCase {
doReturn(false).when(mMockRestartDialogLayout).updateCompatInfo(any(), any(), anyBoolean());
TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true);
+ when(mFocusTransitionObserver.hasGlobalFocus((RunningTaskInfo) taskInfo)).thenReturn(true);
mController.onCompatInfoChanged(new CompatUIInfo(taskInfo, mMockTaskListener));
verify(mController).createCompatUiWindowManager(any(), eq(taskInfo), eq(mMockTaskListener));
@@ -411,6 +416,7 @@ public class CompatUIControllerTest extends CompatUIShellTestCase {
// Verify button remains hidden while IME is showing.
TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true);
mController.onCompatInfoChanged(new CompatUIInfo(taskInfo, mMockTaskListener));
+ when(mFocusTransitionObserver.hasGlobalFocus((RunningTaskInfo) taskInfo)).thenReturn(false);
verify(mMockCompatLayout).updateCompatInfo(taskInfo, mMockTaskListener,
/* canShow= */ false);
@@ -443,6 +449,7 @@ public class CompatUIControllerTest extends CompatUIShellTestCase {
// Verify button remains hidden while keyguard is showing.
TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true);
mController.onCompatInfoChanged(new CompatUIInfo(taskInfo, mMockTaskListener));
+ when(mFocusTransitionObserver.hasGlobalFocus((RunningTaskInfo) taskInfo)).thenReturn(false);
verify(mMockCompatLayout).updateCompatInfo(taskInfo, mMockTaskListener,
/* canShow= */ false);
@@ -523,6 +530,7 @@ public class CompatUIControllerTest extends CompatUIShellTestCase {
@RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testRestartLayoutRecreatedIfNeeded() {
final TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true);
+ when(mFocusTransitionObserver.hasGlobalFocus((RunningTaskInfo) taskInfo)).thenReturn(false);
doReturn(true).when(mMockRestartDialogLayout)
.needsToBeRecreated(any(TaskInfo.class),
any(ShellTaskOrganizer.TaskListener.class));
@@ -538,6 +546,7 @@ public class CompatUIControllerTest extends CompatUIShellTestCase {
@RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
public void testRestartLayoutNotRecreatedIfNotNeeded() {
final TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true);
+ when(mFocusTransitionObserver.hasGlobalFocus((RunningTaskInfo) taskInfo)).thenReturn(false);
doReturn(false).when(mMockRestartDialogLayout)
.needsToBeRecreated(any(TaskInfo.class),
any(ShellTaskOrganizer.TaskListener.class));
@@ -558,7 +567,8 @@ public class CompatUIControllerTest extends CompatUIShellTestCase {
// Create new task
final TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true,
- /* isVisible */ true, /* isFocused */ true);
+ /* isVisible */ true);
+ when(mFocusTransitionObserver.hasGlobalFocus((RunningTaskInfo) taskInfo)).thenReturn(true);
// Simulate new task being shown
mController.updateActiveTaskInfo(taskInfo);
@@ -574,7 +584,8 @@ public class CompatUIControllerTest extends CompatUIShellTestCase {
public void testUpdateActiveTaskInfo_newTask_notVisibleOrFocused_notUpdated() {
// Create new task
final TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true,
- /* isVisible */ true, /* isFocused */ true);
+ /* isVisible */ true);
+ when(mFocusTransitionObserver.hasGlobalFocus((RunningTaskInfo) taskInfo)).thenReturn(true);
// Simulate task being shown
mController.updateActiveTaskInfo(taskInfo);
@@ -592,7 +603,8 @@ public class CompatUIControllerTest extends CompatUIShellTestCase {
// Create visible but NOT focused task
final TaskInfo taskInfo1 = createTaskInfo(DISPLAY_ID, newTaskId, /* hasSizeCompat= */ true,
- /* isVisible */ true, /* isFocused */ false);
+ /* isVisible */ true);
+ when(mFocusTransitionObserver.hasGlobalFocus((RunningTaskInfo) taskInfo)).thenReturn(false);
// Simulate new task being shown
mController.updateActiveTaskInfo(taskInfo1);
@@ -604,7 +616,8 @@ public class CompatUIControllerTest extends CompatUIShellTestCase {
// Create focused but NOT visible task
final TaskInfo taskInfo2 = createTaskInfo(DISPLAY_ID, newTaskId, /* hasSizeCompat= */ true,
- /* isVisible */ false, /* isFocused */ true);
+ /* isVisible */ false);
+ when(mFocusTransitionObserver.hasGlobalFocus((RunningTaskInfo) taskInfo)).thenReturn(true);
// Simulate new task being shown
mController.updateActiveTaskInfo(taskInfo2);
@@ -616,7 +629,8 @@ public class CompatUIControllerTest extends CompatUIShellTestCase {
// Create NOT focused but NOT visible task
final TaskInfo taskInfo3 = createTaskInfo(DISPLAY_ID, newTaskId, /* hasSizeCompat= */ true,
- /* isVisible */ false, /* isFocused */ false);
+ /* isVisible */ false);
+ when(mFocusTransitionObserver.hasGlobalFocus((RunningTaskInfo) taskInfo)).thenReturn(false);
// Simulate new task being shown
mController.updateActiveTaskInfo(taskInfo3);
@@ -632,7 +646,8 @@ public class CompatUIControllerTest extends CompatUIShellTestCase {
public void testUpdateActiveTaskInfo_sameTask_notUpdated() {
// Create new task
final TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true,
- /* isVisible */ true, /* isFocused */ true);
+ /* isVisible */ true);
+ when(mFocusTransitionObserver.hasGlobalFocus((RunningTaskInfo) taskInfo)).thenReturn(true);
// Simulate new task being shown
mController.updateActiveTaskInfo(taskInfo);
@@ -660,7 +675,8 @@ public class CompatUIControllerTest extends CompatUIShellTestCase {
public void testUpdateActiveTaskInfo_transparentTask_notUpdated() {
// Create new task
final TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true,
- /* isVisible */ true, /* isFocused */ true);
+ /* isVisible */ true);
+ when(mFocusTransitionObserver.hasGlobalFocus((RunningTaskInfo) taskInfo)).thenReturn(true);
// Simulate new task being shown
mController.updateActiveTaskInfo(taskInfo);
@@ -678,7 +694,8 @@ public class CompatUIControllerTest extends CompatUIShellTestCase {
// Create transparent task
final TaskInfo taskInfo1 = createTaskInfo(DISPLAY_ID, newTaskId, /* hasSizeCompat= */ true,
- /* isVisible */ true, /* isFocused */ true, /* isTopActivityTransparent */ true);
+ /* isVisible */ true, /* isTopActivityTransparent */ true);
+ when(mFocusTransitionObserver.hasGlobalFocus((RunningTaskInfo) taskInfo)).thenReturn(true);
// Simulate new task being shown
mController.updateActiveTaskInfo(taskInfo1);
@@ -694,6 +711,7 @@ public class CompatUIControllerTest extends CompatUIShellTestCase {
public void testLetterboxEduLayout_notCreatedWhenLetterboxEducationIsDisabled() {
TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true);
taskInfo.appCompatTaskInfo.setLetterboxEducationEnabled(false);
+ when(mFocusTransitionObserver.hasGlobalFocus((RunningTaskInfo) taskInfo)).thenReturn(false);
mController.onCompatInfoChanged(new CompatUIInfo(taskInfo, mMockTaskListener));
@@ -707,6 +725,7 @@ public class CompatUIControllerTest extends CompatUIShellTestCase {
public void testUpdateActiveTaskInfo_removeAllComponentWhenInDesktopModeFlagEnabled() {
TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true);
when(mDesktopUserRepositories.getCurrent().getVisibleTaskCount(DISPLAY_ID)).thenReturn(0);
+ when(mFocusTransitionObserver.hasGlobalFocus((RunningTaskInfo) taskInfo)).thenReturn(false);
mController.onCompatInfoChanged(new CompatUIInfo(taskInfo, mMockTaskListener));
@@ -725,6 +744,7 @@ public class CompatUIControllerTest extends CompatUIShellTestCase {
public void testUpdateActiveTaskInfo_removeAllComponentWhenInDesktopModeFlagDisabled() {
when(mDesktopUserRepositories.getCurrent().getVisibleTaskCount(DISPLAY_ID)).thenReturn(0);
TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true);
+ when(mFocusTransitionObserver.hasGlobalFocus((RunningTaskInfo) taskInfo)).thenReturn(false);
mController.onCompatInfoChanged(new CompatUIInfo(taskInfo, mMockTaskListener));
@@ -739,23 +759,22 @@ public class CompatUIControllerTest extends CompatUIShellTestCase {
private static TaskInfo createTaskInfo(int displayId, int taskId, boolean hasSizeCompat) {
return createTaskInfo(displayId, taskId, hasSizeCompat, /* isVisible */ false,
- /* isFocused */ false, /* isTopActivityTransparent */ false);
+ /* isTopActivityTransparent */ false);
}
private static TaskInfo createTaskInfo(int displayId, int taskId, boolean hasSizeCompat,
- boolean isVisible, boolean isFocused) {
+ boolean isVisible) {
return createTaskInfo(displayId, taskId, hasSizeCompat,
- isVisible, isFocused, /* isTopActivityTransparent */ false);
+ isVisible, /* isTopActivityTransparent */ false);
}
private static TaskInfo createTaskInfo(int displayId, int taskId, boolean hasSizeCompat,
- boolean isVisible, boolean isFocused, boolean isTopActivityTransparent) {
+ boolean isVisible, boolean isTopActivityTransparent) {
RunningTaskInfo taskInfo = new RunningTaskInfo();
taskInfo.taskId = taskId;
taskInfo.displayId = displayId;
taskInfo.appCompatTaskInfo.setTopActivityInSizeCompat(hasSizeCompat);
taskInfo.isVisible = isVisible;
- taskInfo.isFocused = isFocused;
taskInfo.isTopActivityTransparent = isTopActivityTransparent;
taskInfo.appCompatTaskInfo.setLetterboxEducationEnabled(true);
taskInfo.appCompatTaskInfo.setTopActivityLetterboxed(true);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserverTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserverTest.kt
index 9d410137fc4a..4317143aebfe 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserverTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserverTest.kt
@@ -48,6 +48,7 @@ import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.EnterRe
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ExitReason
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.MinimizeReason
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.TaskUpdate
+import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_DESKTOP_MODE_END_DRAG_TO_DESKTOP
import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_ENTER_DESKTOP_FROM_APP_FROM_OVERVIEW
import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_ENTER_DESKTOP_FROM_APP_HANDLE_MENU_BUTTON
import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_ENTER_DESKTOP_FROM_KEYBOARD_SHORTCUT
@@ -175,7 +176,7 @@ class DesktopModeLoggerTransitionObserverTest : ShellTestCase() {
val change = createChange(TRANSIT_TO_FRONT, createTaskInfo(WINDOWING_MODE_FREEFORM))
// task change is finalised when drag ends
val transitionInfo =
- TransitionInfoBuilder(Transitions.TRANSIT_DESKTOP_MODE_END_DRAG_TO_DESKTOP, 0)
+ TransitionInfoBuilder(TRANSIT_DESKTOP_MODE_END_DRAG_TO_DESKTOP, 0)
.addChange(change)
.build()
@@ -436,7 +437,7 @@ class DesktopModeLoggerTransitionObserverTest : ShellTestCase() {
// desktop right after turning the screen on, we move to fullscreen then move another task
// to desktop
val transitionInfo =
- TransitionInfoBuilder(Transitions.TRANSIT_DESKTOP_MODE_END_DRAG_TO_DESKTOP, 0)
+ TransitionInfoBuilder(TRANSIT_DESKTOP_MODE_END_DRAG_TO_DESKTOP, 0)
.addChange(createChange(TRANSIT_TO_FRONT, freeformTask))
.build()
callOnTransitionReady(transitionInfo)
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
index e1c2153014fa..61aec739724a 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
@@ -82,6 +82,7 @@ import com.android.dx.mockito.inline.extended.StaticMockitoSession
import com.android.internal.jank.InteractionJankMonitor
import com.android.window.flags.Flags
import com.android.window.flags.Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE
+import com.android.window.flags.Flags.FLAG_ENABLE_DISPLAY_FOCUS_IN_SHELL_TRANSITIONS
import com.android.window.flags.Flags.FLAG_ENABLE_FULLY_IMMERSIVE_IN_DESKTOP
import com.android.window.flags.Flags.FLAG_ENABLE_MOVE_TO_NEXT_DISPLAY_SHORTCUT
import com.android.window.flags.Flags.FLAG_ENABLE_PER_DISPLAY_DESKTOP_WALLPAPER_ACTIVITY
@@ -1703,13 +1704,14 @@ class DesktopTasksControllerTest : ShellTestCase() {
val task = setUpFreeformTask(displayId = DEFAULT_DISPLAY)
controller.moveToNextDisplay(task.taskId)
- with(getLatestWct(type = TRANSIT_CHANGE)) {
- assertThat(hierarchyOps).hasSize(1)
- assertThat(hierarchyOps[0].container).isEqualTo(task.token.asBinder())
- assertThat(hierarchyOps[0].isReparent).isTrue()
- assertThat(hierarchyOps[0].newParent).isEqualTo(secondDisplayArea.token.asBinder())
- assertThat(hierarchyOps[0].toTop).isTrue()
- }
+
+ val taskChange =
+ getLatestWct(type = TRANSIT_CHANGE).hierarchyOps.find {
+ it.container == task.token.asBinder() && it.isReparent
+ }
+ assertNotNull(taskChange)
+ assertThat(taskChange.newParent).isEqualTo(secondDisplayArea.token.asBinder())
+ assertThat(taskChange.toTop).isTrue()
}
@Test
@@ -1725,13 +1727,13 @@ class DesktopTasksControllerTest : ShellTestCase() {
val task = setUpFreeformTask(displayId = SECOND_DISPLAY)
controller.moveToNextDisplay(task.taskId)
- with(getLatestWct(type = TRANSIT_CHANGE)) {
- assertThat(hierarchyOps).hasSize(1)
- assertThat(hierarchyOps[0].container).isEqualTo(task.token.asBinder())
- assertThat(hierarchyOps[0].isReparent).isTrue()
- assertThat(hierarchyOps[0].newParent).isEqualTo(defaultDisplayArea.token.asBinder())
- assertThat(hierarchyOps[0].toTop).isTrue()
- }
+ val taskChange =
+ getLatestWct(type = TRANSIT_CHANGE).hierarchyOps.find {
+ it.container == task.token.asBinder() && it.isReparent
+ }
+ assertNotNull(taskChange)
+ assertThat(taskChange.newParent).isEqualTo(defaultDisplayArea.token.asBinder())
+ assertThat(taskChange.toTop).isTrue()
}
@Test
@@ -1908,6 +1910,32 @@ class DesktopTasksControllerTest : ShellTestCase() {
}
@Test
+ @EnableFlags(
+ FLAG_ENABLE_DISPLAY_FOCUS_IN_SHELL_TRANSITIONS,
+ FLAG_ENABLE_MOVE_TO_NEXT_DISPLAY_SHORTCUT,
+ )
+ fun moveToNextDisplay_destinationGainGlobalFocus() {
+ // Set up two display ids
+ whenever(rootTaskDisplayAreaOrganizer.displayIds)
+ .thenReturn(intArrayOf(DEFAULT_DISPLAY, SECOND_DISPLAY))
+ // Create a mock for the target display area: second display
+ val secondDisplayArea = DisplayAreaInfo(MockToken().token(), SECOND_DISPLAY, 0)
+ whenever(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(SECOND_DISPLAY))
+ .thenReturn(secondDisplayArea)
+
+ val task = setUpFreeformTask(displayId = DEFAULT_DISPLAY)
+ controller.moveToNextDisplay(task.taskId)
+
+ val taskChange =
+ getLatestWct(type = TRANSIT_CHANGE).hierarchyOps.find {
+ it.container == task.token.asBinder() && it.type == HIERARCHY_OP_TYPE_REORDER
+ }
+ assertNotNull(taskChange)
+ assertThat(taskChange.toTop).isTrue()
+ assertThat(taskChange.includingParents()).isTrue()
+ }
+
+ @Test
fun getTaskWindowingMode() {
val fullscreenTask = setUpFullscreenTask()
val freeformTask = setUpFreeformTask()
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandlerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandlerTest.kt
index e4eff9f1d592..2216d5452ce5 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandlerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandlerTest.kt
@@ -25,14 +25,14 @@ import com.android.internal.jank.InteractionJankMonitor
import com.android.wm.shell.RootTaskDisplayAreaOrganizer
import com.android.wm.shell.ShellTestCase
import com.android.wm.shell.TestRunningTaskInfoBuilder
+import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_DESKTOP_MODE_CANCEL_DRAG_TO_DESKTOP
+import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_DESKTOP_MODE_END_DRAG_TO_DESKTOP
+import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_DESKTOP_MODE_START_DRAG_TO_DESKTOP
import com.android.wm.shell.desktopmode.DragToDesktopTransitionHandler.Companion.DRAG_TO_DESKTOP_FINISH_ANIM_DURATION_MS
import com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT
import com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT
import com.android.wm.shell.splitscreen.SplitScreenController
import com.android.wm.shell.transition.Transitions
-import com.android.wm.shell.transition.Transitions.TRANSIT_DESKTOP_MODE_CANCEL_DRAG_TO_DESKTOP
-import com.android.wm.shell.transition.Transitions.TRANSIT_DESKTOP_MODE_END_DRAG_TO_DESKTOP
-import com.android.wm.shell.transition.Transitions.TRANSIT_DESKTOP_MODE_START_DRAG_TO_DESKTOP
import com.android.wm.shell.windowdecor.MoveToDesktopAnimator
import java.util.function.Supplier
import junit.framework.Assert.assertEquals
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/HomeTransitionObserverTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/HomeTransitionObserverTest.java
index 8dfdfb4dcbcf..8bdefa7cf866 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/HomeTransitionObserverTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/HomeTransitionObserverTest.java
@@ -25,7 +25,7 @@ import static android.view.WindowManager.TRANSIT_TO_BACK;
import static android.window.TransitionInfo.FLAG_BACK_GESTURE_ANIMATED;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
-import static com.android.wm.shell.transition.Transitions.TRANSIT_DESKTOP_MODE_START_DRAG_TO_DESKTOP;
+import static com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_DESKTOP_MODE_START_DRAG_TO_DESKTOP;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.Mockito.mock;
diff --git a/nfc/tests/src/android/nfc/NfcRoutingTableEntryTest.java b/nfc/tests/src/android/nfc/NfcRoutingTableEntryTest.java
new file mode 100644
index 000000000000..a90a716b6081
--- /dev/null
+++ b/nfc/tests/src/android/nfc/NfcRoutingTableEntryTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.nfc;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public final class NfcRoutingTableEntryTest {
+
+ @Test
+ public void testAidEntry_GetAid() {
+ String expectedAid = "A00000061A02";
+ RoutingTableAidEntry entry = new RoutingTableAidEntry(1, expectedAid, 0);
+
+ assertEquals(expectedAid, entry.getAid());
+ }
+
+ @Test
+ public void testProtocolEntry_GetProtocol() {
+ RoutingTableProtocolEntry entry =
+ new RoutingTableProtocolEntry(1, RoutingTableProtocolEntry.PROTOCOL_T1T, 0);
+
+ assertEquals(RoutingTableProtocolEntry.PROTOCOL_T1T, entry.getProtocol());
+ }
+
+ @Test
+ public void testSystemCodeEntry_GetSystemCode() {
+ byte[] expectedSystemCode = {0x01, 0x02, 0x03};
+ RoutingTableSystemCodeEntry entry =
+ new RoutingTableSystemCodeEntry(1, expectedSystemCode, 0);
+
+ assertArrayEquals(expectedSystemCode, entry.getSystemCode());
+ }
+
+ @Test
+ public void testTechnologyEntry_GetTechnology_A() {
+ RoutingTableTechnologyEntry entry =
+ new RoutingTableTechnologyEntry(1, RoutingTableTechnologyEntry.TECHNOLOGY_A, 0);
+
+ assertEquals(RoutingTableTechnologyEntry.TECHNOLOGY_A, entry.getTechnology());
+ }
+}
diff --git a/nfc/tests/src/android/nfc/OemLogItemsTest.java b/nfc/tests/src/android/nfc/OemLogItemsTest.java
new file mode 100644
index 000000000000..21ef80485cc4
--- /dev/null
+++ b/nfc/tests/src/android/nfc/OemLogItemsTest.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.nfc;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.time.Instant;
+
+@RunWith(JUnit4.class)
+public final class OemLogItemsTest {
+
+ @Test
+ public void testGetAction() {
+ OemLogItems item = new OemLogItems.Builder(OemLogItems.LOG_ACTION_RF_FIELD_STATE_CHANGED)
+ .build();
+ assertEquals(OemLogItems.LOG_ACTION_RF_FIELD_STATE_CHANGED, item.getAction());
+ }
+
+ @Test
+ public void testGetEvent() {
+ OemLogItems item = new OemLogItems.Builder(OemLogItems.LOG_ACTION_NFC_TOGGLE)
+ .setCallingEvent(OemLogItems.EVENT_ENABLE)
+ .build();
+ assertEquals(OemLogItems.EVENT_ENABLE, item.getEvent());
+ }
+
+ @Test
+ public void testGetCallingPid() {
+ OemLogItems item = new OemLogItems.Builder(OemLogItems.LOG_ACTION_NFC_TOGGLE)
+ .setCallingPid(1234)
+ .build();
+ assertEquals(1234, item.getCallingPid());
+ }
+
+ @Test
+ public void testGetCommandApdu() {
+ byte[] commandApdu = {0x01, 0x02, 0x03};
+ OemLogItems item = new OemLogItems.Builder(OemLogItems.LOG_ACTION_HCE_DATA)
+ .setApduCommand(commandApdu)
+ .build();
+ assertArrayEquals(commandApdu, item.getCommandApdu());
+ }
+
+ @Test
+ public void testGetResponseApdu() {
+ byte[] responseApdu = {0x04, 0x05, 0x06};
+ OemLogItems item = new OemLogItems.Builder(OemLogItems.LOG_ACTION_HCE_DATA)
+ .setApduResponse(responseApdu)
+ .build();
+ assertArrayEquals(responseApdu, item.getResponseApdu());
+ }
+
+ @Test
+ public void testGetRfFieldEventTimeMillis() {
+ Instant expectedTime = Instant.ofEpochSecond(1688768000, 123456789);
+ OemLogItems item = new OemLogItems.Builder(OemLogItems.LOG_ACTION_RF_FIELD_STATE_CHANGED)
+ .setRfFieldOnTime(expectedTime)
+ .build();
+ assertEquals(expectedTime, item.getRfFieldEventTimeMillis());
+ }
+
+ @Test
+ public void testGetTag() {
+ Tag mockTag = mock(Tag.class);
+ OemLogItems item = new OemLogItems.Builder(OemLogItems.LOG_ACTION_TAG_DETECTED)
+ .setTag(mockTag)
+ .build();
+ assertEquals(mockTag, item.getTag());
+ }
+}
diff --git a/nfc/tests/src/android/nfc/cardemulation/CardemulationTest.java b/nfc/tests/src/android/nfc/cardemulation/CardemulationTest.java
index 6be95adbeba0..a21583542a66 100644
--- a/nfc/tests/src/android/nfc/cardemulation/CardemulationTest.java
+++ b/nfc/tests/src/android/nfc/cardemulation/CardemulationTest.java
@@ -18,17 +18,25 @@ package android.nfc.cardemulation;
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.app.role.RoleManager;
import android.content.ComponentName;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.PackageManager;
+import android.nfc.Constants;
import android.nfc.INfcCardEmulation;
import android.nfc.NfcAdapter;
import android.os.RemoteException;
import android.os.UserHandle;
+import android.provider.Settings;
import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -61,6 +69,7 @@ public class CardemulationTest {
public void setUp() {
mMockitoSession = ExtendedMockito.mockitoSession()
.mockStatic(NfcAdapter.class)
+ .mockStatic(Settings.Secure.class)
.strictness(Strictness.LENIENT)
.startMocking();
MockitoAnnotations.initMocks(this);
@@ -110,4 +119,68 @@ public class CardemulationTest {
verify(mINfcCardEmulation).isDefaultServiceForAid(1, componentName,
"payment");
}
+
+ @Test
+ public void testCategoryAllowsForegroundPreference() throws Settings.SettingNotFoundException {
+ when(mContext.createContextAsUser(any(), anyInt())).thenReturn(mContext);
+ RoleManager roleManager = mock(RoleManager.class);
+ when(roleManager.isRoleAvailable(RoleManager.ROLE_WALLET)).thenReturn(false);
+ when(mContext.getSystemService(RoleManager.class)).thenReturn(roleManager);
+ ContentResolver contentResolver = mock(ContentResolver.class);
+ when(mContext.getContentResolver()).thenReturn(contentResolver);
+ when(Settings.Secure.getInt(contentResolver, Constants
+ .SETTINGS_SECURE_NFC_PAYMENT_FOREGROUND)).thenReturn(1);
+ boolean result = mCardEmulation.categoryAllowsForegroundPreference("payment");
+ assertThat(result).isTrue();
+ }
+
+ @Test
+ public void testGetSelectionModeForCategory() throws RemoteException {
+ when(mINfcCardEmulation.isDefaultPaymentRegistered()).thenReturn(true);
+ int result = mCardEmulation.getSelectionModeForCategory("payment");
+ assertThat(result).isEqualTo(0);
+ }
+
+ @Test
+ public void testSetShouldDefaultToObserveModeForService() throws RemoteException {
+ UserHandle userHandle = mock(UserHandle.class);
+ when(userHandle.getIdentifier()).thenReturn(1);
+ when(mContext.getUser()).thenReturn(userHandle);
+ ComponentName componentName = mock(ComponentName.class);
+ when(mINfcCardEmulation.setShouldDefaultToObserveModeForService(1, componentName, true))
+ .thenReturn(true);
+ boolean result = mCardEmulation
+ .setShouldDefaultToObserveModeForService(componentName, true);
+ assertThat(result).isTrue();
+ verify(mINfcCardEmulation).setShouldDefaultToObserveModeForService(1, componentName, true);
+ }
+
+ @Test
+ public void testRegisterPollingLoopFilterForService()throws RemoteException {
+ UserHandle userHandle = mock(UserHandle.class);
+ when(userHandle.getIdentifier()).thenReturn(1);
+ when(mContext.getUser()).thenReturn(userHandle);
+ ComponentName componentName = mock(ComponentName.class);
+ when(mINfcCardEmulation.registerPollingLoopFilterForService(anyInt(),
+ any(), anyString(), anyBoolean())).thenReturn(true);
+ boolean result = mCardEmulation.registerPollingLoopFilterForService(componentName,
+ "A0000000041010", true);
+ assertThat(result).isTrue();
+ verify(mINfcCardEmulation)
+ .registerPollingLoopFilterForService(anyInt(), any(), anyString(), anyBoolean());
+ }
+
+ @Test
+ public void testRemovePollingLoopFilterForService()throws RemoteException {
+ UserHandle userHandle = mock(UserHandle.class);
+ when(userHandle.getIdentifier()).thenReturn(1);
+ when(mContext.getUser()).thenReturn(userHandle);
+ ComponentName componentName = mock(ComponentName.class);
+ when(mINfcCardEmulation.removePollingLoopFilterForService(anyInt(), any(), anyString()))
+ .thenReturn(true);
+ boolean result = mCardEmulation
+ .removePollingLoopFilterForService(componentName, "A0000000041010");
+ assertThat(result).isTrue();
+ verify(mINfcCardEmulation).removePollingLoopFilterForService(anyInt(), any(), anyString());
+ }
}
diff --git a/nfc/tests/src/android/nfc/tech/NfcVTest.java b/nfc/tests/src/android/nfc/tech/NfcVTest.java
new file mode 100644
index 000000000000..6a99921b9287
--- /dev/null
+++ b/nfc/tests/src/android/nfc/tech/NfcVTest.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2010 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.nfc.tech;
+
+import static android.nfc.tech.NfcV.EXTRA_DSFID;
+import static android.nfc.tech.NfcV.EXTRA_RESP_FLAGS;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.nfc.INfcTag;
+import android.nfc.Tag;
+import android.nfc.TransceiveResult;
+import android.os.Bundle;
+import android.os.RemoteException;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.io.IOException;
+
+public class NfcVTest {
+ private final byte mSampleRespFlags = (byte) 1;
+ private final byte mSampleDsfId = (byte) 2;
+ @Mock
+ private Tag mMockTag;
+ @Mock
+ private INfcTag mMockTagService;
+ @Mock
+ private Bundle mMockBundle;
+ private NfcV mNfcV;
+
+ @Before
+ public void setUp() throws RemoteException {
+ MockitoAnnotations.initMocks(this);
+ when(mMockBundle.getByte(EXTRA_RESP_FLAGS)).thenReturn(mSampleRespFlags);
+ when(mMockBundle.getByte(EXTRA_DSFID)).thenReturn(mSampleDsfId);
+ when(mMockTag.getTechExtras(TagTechnology.NFC_V)).thenReturn(mMockBundle);
+
+ mNfcV = new NfcV(mMockTag);
+ }
+
+ @Test
+ public void testGetResponseFlag() {
+ assertEquals(mSampleRespFlags, mNfcV.getResponseFlags());
+ }
+
+ @Test
+ public void testGetDsfId() {
+ assertEquals(mSampleDsfId, mNfcV.getDsfId());
+ }
+
+ @Test
+ public void testGetNfcVInstance() {
+ Tag tag = mock(Tag.class);
+ when(tag.hasTech(TagTechnology.NFC_V)).thenReturn(true);
+ when(tag.getTechExtras(TagTechnology.NFC_V)).thenReturn(mMockBundle);
+
+ assertNotNull(NfcV.get(tag));
+ verify(tag).getTechExtras(TagTechnology.NFC_V);
+ verify(tag).hasTech(TagTechnology.NFC_V);
+ }
+
+ @Test
+ public void testGetNfcVNullInstance() {
+ Tag tag = mock(Tag.class);
+ when(tag.hasTech(TagTechnology.NFC_V)).thenReturn(false);
+
+ assertNull(NfcV.get(tag));
+ verify(tag, never()).getTechExtras(TagTechnology.NFC_V);
+ verify(tag).hasTech(TagTechnology.NFC_V);
+ }
+
+ @Test
+ public void testTransceive() throws IOException, RemoteException {
+ byte[] sampleData = new byte[] {1, 2, 3, 4, 5};
+ TransceiveResult mockTransceiveResult = mock(TransceiveResult.class);
+ when(mMockTag.getConnectedTechnology()).thenReturn(TagTechnology.NFC_V);
+ when(mMockTag.getTagService()).thenReturn(mMockTagService);
+ when(mMockTag.getServiceHandle()).thenReturn(1);
+ when(mMockTagService.transceive(1, sampleData, true))
+ .thenReturn(mockTransceiveResult);
+ when(mockTransceiveResult.getResponseOrThrow()).thenReturn(sampleData);
+
+ mNfcV.transceive(sampleData);
+ verify(mMockTag).getTagService();
+ verify(mMockTag).getServiceHandle();
+ }
+
+ @Test
+ public void testGetMaxTransceiveLength() throws RemoteException {
+ when(mMockTag.getTagService()).thenReturn(mMockTagService);
+ when(mMockTagService.getMaxTransceiveLength(TagTechnology.NFC_V)).thenReturn(1);
+
+ mNfcV.getMaxTransceiveLength();
+ verify(mMockTag).getTagService();
+ }
+}
diff --git a/packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/Permissions.kt b/packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/Permissions.kt
new file mode 100644
index 000000000000..871642054aef
--- /dev/null
+++ b/packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/Permissions.kt
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.datastore
+
+import android.content.Context
+import android.content.pm.PackageManager.PERMISSION_GRANTED
+
+/**
+ * Class to manage permissions, which supports a combination of AND / OR.
+ *
+ * Samples:
+ * - `Permissions.EMPTY`: no permission is required
+ * - `Permissions.allOf(p1, p2) or p3 or Permissions.allOf(p4, p5)`
+ * - `Permissions.anyOf(p1, p2) and p3 and Permissions.anyOf(p4, p5)`
+ * - `Permissions.allOf(p1, p2) or (Permissions.allOf(p3, p4) and p5)`: ALWAYS add `()` explicitly
+ * when and/or operators are used at the same time.
+ */
+sealed class Permissions(vararg permissions: Any) {
+ internal val permissions = mutableSetOf(*permissions)
+
+ val size: Int
+ get() = permissions.size
+
+ override fun hashCode() = permissions.hashCode()
+
+ override fun equals(other: Any?) =
+ other is Permissions &&
+ permissions == other.permissions &&
+ (permissions.size == 1 || javaClass == other.javaClass)
+
+ abstract fun check(context: Context, pid: Int, uid: Int): Boolean
+
+ internal fun addForAnd(permission: Any): Permissions =
+ when {
+ // ensure empty permissions will never been modified
+ permissions.isEmpty() -> (permission as? Permissions) ?: AllOfPermissions(permission)
+ permission is Permissions && permission.permissions.isEmpty() -> this
+ this is AllOfPermissions -> apply { and(permission) }
+ permission is AllOfPermissions -> permission.also { it.and(this) }
+ // anyOf(p1) and p2 => allOf(p1, p2)
+ permissions.size == 1 && this is AnyOfPermissions && permission is String ->
+ AllOfPermissions(permissions.first(), permission)
+ // anyOf(p1) and anyOf(p2) => allOf(p1, p2)
+ permissions.size == 1 &&
+ permission is AnyOfPermissions &&
+ permission.permissions.size == 1 ->
+ AllOfPermissions(permissions.first(), permission.permissions.first())
+ else -> AllOfPermissions(this, permission)
+ }
+
+ internal fun addForOr(permission: Any): Permissions =
+ when {
+ // ensure empty permissions will never been modified
+ permissions.isEmpty() -> (permission as? Permissions) ?: AnyOfPermissions(permission)
+ permission is Permissions && permission.permissions.isEmpty() -> this
+ this is AnyOfPermissions -> apply { or(permission) }
+ permission is AnyOfPermissions -> permission.also { it.or(this) }
+ // allOf(p1) or p2 => anyOf(p1, p2)
+ permissions.size == 1 && this is AllOfPermissions && permission is String ->
+ AnyOfPermissions(permissions.first(), permission)
+ // allOf(p1) or allOf(p2) => anyOf(p1, p2)
+ permissions.size == 1 &&
+ permission is AllOfPermissions &&
+ permission.permissions.size == 1 ->
+ AnyOfPermissions(permissions.first(), permission.permissions.first())
+ else -> AnyOfPermissions(this, permission)
+ }
+
+ protected fun Any.check(context: Context, pid: Int, uid: Int) =
+ when (this) {
+ is String -> context.checkPermission(this, pid, uid) == PERMISSION_GRANTED
+ else -> (this as Permissions).check(context, pid, uid)
+ }
+
+ fun forEach(action: (Any) -> Unit) {
+ for (permission in permissions) action(permission)
+ }
+
+ companion object {
+ /** Returns [Permissions] that requires all of the permissions. */
+ fun allOf(vararg permissions: String): Permissions =
+ if (permissions.isEmpty()) EMPTY else AllOfPermissions(*permissions)
+
+ /** Returns [Permissions] that requires any of the permissions. */
+ fun anyOf(vararg permissions: String): Permissions =
+ if (permissions.isEmpty()) EMPTY else AnyOfPermissions(*permissions)
+
+ /** No permission required. */
+ val EMPTY: Permissions = AllOfPermissions()
+ }
+}
+
+class AllOfPermissions internal constructor(vararg permissions: Any) : Permissions(*permissions) {
+
+ override fun toString() = permissions.joinToString(prefix = "allOf(", postfix = ")")
+
+ override fun check(context: Context, pid: Int, uid: Int): Boolean {
+ // use for-loop explicitly instead of "all" extension for empty permissions
+ for (permission in permissions) {
+ if (!permission.check(context, pid, uid)) return false
+ }
+ return true
+ }
+
+ internal fun and(permission: Any) {
+ when {
+ // in-place merge to reduce the hierarchy
+ permission is AllOfPermissions -> permissions.addAll(permission.permissions)
+ // allOf(...) and anyOf(p) => allOf(..., p)
+ permission is AnyOfPermissions && permission.permissions.size == 1 ->
+ permissions.add(permission.permissions.first())
+
+ else -> permissions.add(permission)
+ }
+ }
+}
+
+class AnyOfPermissions internal constructor(vararg permissions: Any) : Permissions(*permissions) {
+
+ override fun toString() = permissions.joinToString(prefix = "anyOf(", postfix = ")")
+
+ override fun check(context: Context, pid: Int, uid: Int): Boolean {
+ // use for-loop explicitly instead of "any" extension for empty permissions
+ for (permission in permissions) {
+ if (permission.check(context, pid, uid)) return true
+ }
+ return permissions.isEmpty()
+ }
+
+ internal fun or(permission: Any) {
+ when {
+ // in-place merge to reduce the hierarchy
+ permission is AnyOfPermissions -> permissions.addAll(permission.permissions)
+ // anyOf(...) or allOf(p) => anyOf(..., p)
+ permission is AllOfPermissions && permission.permissions.size == 1 ->
+ permissions.add(permission.permissions.first())
+ else -> permissions.add(permission)
+ }
+ }
+}
+
+infix fun Permissions.and(permission: String): Permissions = addForAnd(permission)
+
+infix fun Permissions.and(permissions: Permissions): Permissions = addForAnd(permissions)
+
+infix fun Permissions.or(permission: String): Permissions = addForOr(permission)
+
+infix fun Permissions.or(permissions: Permissions): Permissions = addForOr(permissions)
diff --git a/packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/SettingsGlobalStore.kt b/packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/SettingsGlobalStore.kt
index 8335ee43df26..614bcb221780 100644
--- a/packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/SettingsGlobalStore.kt
+++ b/packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/SettingsGlobalStore.kt
@@ -85,9 +85,9 @@ class SettingsGlobalStore private constructor(contentResolver: ContentResolver)
}
/** Returns the required permissions to read [Global] settings. */
- fun getReadPermissions() = arrayOf<String>()
+ fun getReadPermissions() = Permissions.EMPTY
/** Returns the required permissions to write [Global] settings. */
- fun getWritePermissions() = arrayOf(Manifest.permission.WRITE_SECURE_SETTINGS)
+ fun getWritePermissions() = Permissions.allOf(Manifest.permission.WRITE_SECURE_SETTINGS)
}
}
diff --git a/packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/SettingsSecureStore.kt b/packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/SettingsSecureStore.kt
index c117b926d1eb..2621de1fbcb8 100644
--- a/packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/SettingsSecureStore.kt
+++ b/packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/SettingsSecureStore.kt
@@ -85,9 +85,9 @@ class SettingsSecureStore private constructor(contentResolver: ContentResolver)
}
/** Returns the required permissions to read [Secure] settings. */
- fun getReadPermissions() = arrayOf<String>()
+ fun getReadPermissions() = Permissions.EMPTY
/** Returns the required permissions to write [Secure] settings. */
- fun getWritePermissions() = arrayOf(Manifest.permission.WRITE_SECURE_SETTINGS)
+ fun getWritePermissions() = Permissions.allOf(Manifest.permission.WRITE_SECURE_SETTINGS)
}
}
diff --git a/packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/SettingsSystemStore.kt b/packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/SettingsSystemStore.kt
index f5a2f940bc03..740ac39ec2e9 100644
--- a/packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/SettingsSystemStore.kt
+++ b/packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/SettingsSystemStore.kt
@@ -85,9 +85,9 @@ class SettingsSystemStore private constructor(contentResolver: ContentResolver)
}
/** Returns the required permissions to read [System] settings. */
- fun getReadPermissions() = arrayOf<String>()
+ fun getReadPermissions() = Permissions.EMPTY
/** Returns the required permissions to write [System] settings. */
- fun getWritePermissions() = arrayOf(Manifest.permission.WRITE_SETTINGS)
+ fun getWritePermissions() = Permissions.allOf(Manifest.permission.WRITE_SETTINGS)
}
}
diff --git a/packages/SettingsLib/DataStore/tests/src/com/android/settingslib/datastore/PermissionsTest.kt b/packages/SettingsLib/DataStore/tests/src/com/android/settingslib/datastore/PermissionsTest.kt
new file mode 100644
index 000000000000..5641f0d82e57
--- /dev/null
+++ b/packages/SettingsLib/DataStore/tests/src/com/android/settingslib/datastore/PermissionsTest.kt
@@ -0,0 +1,327 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.datastore
+
+import android.content.Context
+import android.content.ContextWrapper
+import android.content.pm.PackageManager.PERMISSION_DENIED
+import android.content.pm.PackageManager.PERMISSION_GRANTED
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.settingslib.datastore.Permissions.Companion.EMPTY
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+class PermissionsTest {
+ private val context: Context = ApplicationProvider.getApplicationContext()
+
+ @Test
+ fun empty() {
+ assertThat(Permissions.allOf()).isSameInstanceAs(EMPTY)
+ assertThat(Permissions.anyOf()).isSameInstanceAs(EMPTY)
+ assertThat(EMPTY.check(context, 0, 0)).isTrue()
+ assertThat((EMPTY and "a").permissions).containsExactly("a")
+ assertThat((EMPTY or "a").permissions).containsExactly("a")
+ }
+
+ @Test
+ fun allOf_op_empty() {
+ val allOf = Permissions.allOf("a")
+ assertThat(allOf and EMPTY).isSameInstanceAs(allOf)
+ assertThat(EMPTY and allOf).isSameInstanceAs(allOf)
+ assertThat(EMPTY or allOf).isSameInstanceAs(allOf)
+ assertThat(allOf or EMPTY).isSameInstanceAs(allOf)
+ }
+
+ @Test
+ fun anyOf_op_empty() {
+ val anyOf = Permissions.anyOf("a")
+ assertThat(anyOf and EMPTY).isSameInstanceAs(anyOf)
+ assertThat(EMPTY and anyOf).isSameInstanceAs(anyOf)
+ assertThat(EMPTY or anyOf).isSameInstanceAs(anyOf)
+ assertThat(anyOf or EMPTY).isSameInstanceAs(anyOf)
+ }
+
+ @Test
+ fun allOf1_and_allOf1() {
+ val allOf = Permissions.allOf("a")
+ assertThat(allOf and Permissions.allOf("b")).isSameInstanceAs(allOf)
+ assertThat(allOf.permissions).containsExactly("a", "b")
+ }
+
+ @Test
+ fun allOf1_or_allOf1() {
+ val merged = Permissions.allOf("a") or Permissions.allOf("b")
+ assertThat(merged.permissions).containsExactly("a", "b")
+ assertThat(merged).isInstanceOf(AnyOfPermissions::class.java)
+ }
+
+ @Test
+ fun allOf1_and_anyOf1() {
+ val allOf = Permissions.allOf("a")
+ val anyOf = Permissions.anyOf("b")
+ assertThat(allOf and anyOf).isSameInstanceAs(allOf)
+ assertThat(allOf.permissions).containsExactly("a", "b")
+ }
+
+ @Test
+ fun allOf1_or_anyOf1() {
+ val allOf = Permissions.allOf("a")
+ val anyOf = Permissions.anyOf("b")
+ assertThat(allOf or anyOf).isSameInstanceAs(anyOf)
+ assertThat(anyOf.permissions).containsExactly("a", "b")
+ }
+
+ @Test
+ fun anyOf1_and_allOf1() {
+ val anyOf = Permissions.anyOf("a")
+ val allOf = Permissions.allOf("b")
+ assertThat(anyOf and allOf).isSameInstanceAs(allOf)
+ assertThat(allOf.permissions).containsExactly("a", "b")
+ }
+
+ @Test
+ fun anyOf1_or_allOf1() {
+ val anyOf = Permissions.anyOf("a")
+ val allOf = Permissions.allOf("b")
+ assertThat(anyOf or allOf).isSameInstanceAs(anyOf)
+ assertThat(anyOf.permissions).containsExactly("a", "b")
+ }
+
+ @Test
+ fun anyOf1_and_anyOf1() {
+ val merged = Permissions.anyOf("a") and Permissions.anyOf("b")
+ assertThat(merged.permissions).containsExactly("a", "b")
+ assertThat(merged).isInstanceOf(AllOfPermissions::class.java)
+ }
+
+ @Test
+ fun anyOf1_or_anyOf1() {
+ val anyOf = Permissions.anyOf("a")
+ assertThat(anyOf or Permissions.anyOf("b")).isSameInstanceAs(anyOf)
+ assertThat(anyOf.permissions).containsExactly("a", "b")
+ }
+
+ @Test
+ fun allOf1_and_anyOf2() {
+ val allOf = Permissions.allOf("a")
+ val anyOf = Permissions.anyOf("a", "b")
+ assertThat(allOf and anyOf).isSameInstanceAs(allOf)
+ assertThat(allOf.permissions).containsExactly("a", anyOf)
+ }
+
+ @Test
+ fun allOf1_or_anyOf2() {
+ val allOf = Permissions.allOf("a")
+ val anyOf = Permissions.anyOf("a", "b")
+ assertThat(allOf and anyOf).isSameInstanceAs(allOf)
+ assertThat(allOf.permissions).containsExactly("a", anyOf)
+ }
+
+ @Test
+ fun allOf2_and_anyOf1() {
+ val allOf = Permissions.allOf("a", "b")
+ val anyOf = Permissions.anyOf("c")
+ assertThat(allOf and anyOf).isSameInstanceAs(allOf)
+ assertThat(allOf.permissions).containsExactly("a", "b", "c")
+ }
+
+ @Test
+ fun allOf2_or_anyOf1() {
+ val allOf = Permissions.allOf("a", "b")
+ val anyOf = Permissions.anyOf("b")
+ assertThat(allOf or anyOf).isSameInstanceAs(anyOf)
+ assertThat(anyOf.permissions).containsExactly("b", allOf)
+ }
+
+ @Test
+ fun anyOf1_and_allOf2() {
+ val anyOf = Permissions.anyOf("c")
+ val allOf = Permissions.allOf("a", "b")
+ assertThat(anyOf and allOf).isSameInstanceAs(allOf)
+ assertThat(allOf.permissions).containsExactly("a", "b", "c")
+ }
+
+ @Test
+ fun anyOf1_or_allOf2() {
+ val anyOf = Permissions.anyOf("a")
+ val allOf = Permissions.allOf("a", "b")
+ assertThat(anyOf or allOf).isSameInstanceAs(anyOf)
+ assertThat(anyOf.permissions).containsExactly("a", allOf)
+ }
+
+ @Test
+ fun anyOf2_and_allOf1() {
+ val anyOf = Permissions.anyOf("a", "b")
+ val allOf = Permissions.allOf("a")
+ assertThat(anyOf and allOf).isSameInstanceAs(allOf)
+ assertThat(allOf.permissions).containsExactly("a", anyOf)
+ }
+
+ @Test
+ fun anyOf2_or_allOf1() {
+ val anyOf = Permissions.anyOf("a", "b")
+ val allOf = Permissions.allOf("c")
+ assertThat(anyOf or allOf).isSameInstanceAs(anyOf)
+ assertThat(anyOf.permissions).containsExactly("a", "b", "c")
+ }
+
+ @Test
+ fun allOf2_and_allOf2() {
+ val allOf = Permissions.allOf("a", "b")
+ assertThat(allOf and Permissions.allOf("a", "c")).isSameInstanceAs(allOf)
+ assertThat(allOf.permissions).containsExactly("a", "b", "c")
+ }
+
+ @Test
+ fun allOf2_or_allOf2() {
+ val allOf1 = Permissions.allOf("a", "b")
+ val allOf2 = Permissions.allOf("a", "c")
+ assertThat((allOf1 or allOf2).permissions).containsExactly(allOf1, allOf2)
+ }
+
+ @Test
+ fun allOf2_and_anyOf2() {
+ val allOf = Permissions.allOf("a", "b")
+ val anyOf = Permissions.anyOf("a", "c")
+ assertThat(allOf and anyOf).isSameInstanceAs(allOf)
+ assertThat(allOf.permissions).containsExactly("a", "b", anyOf)
+ }
+
+ @Test
+ fun allOf2_or_anyOf2() {
+ val allOf = Permissions.allOf("a", "b")
+ val anyOf = Permissions.anyOf("a", "c")
+ assertThat(allOf or anyOf).isSameInstanceAs(anyOf)
+ assertThat(anyOf.permissions).containsExactly("a", "c", allOf)
+ }
+
+ @Test
+ fun anyOf2_and_allOf2() {
+ val anyOf = Permissions.anyOf("a", "b")
+ val allOf = Permissions.allOf("a", "c")
+ assertThat(anyOf and allOf).isSameInstanceAs(allOf)
+ assertThat(allOf.permissions).containsExactly("a", "c", anyOf)
+ }
+
+ @Test
+ fun anyOf2_or_allOf2() {
+ val anyOf = Permissions.anyOf("a", "b")
+ val allOf = Permissions.allOf("a", "c")
+ assertThat(anyOf or allOf).isSameInstanceAs(anyOf)
+ assertThat(anyOf.permissions).containsExactly("a", "b", allOf)
+ }
+
+ @Test
+ fun anyOf2_and_anyOf2() {
+ val anyOf1 = Permissions.anyOf("a", "b")
+ val anyOf2 = Permissions.anyOf("a", "c")
+ assertThat((anyOf1 and anyOf2).permissions).containsExactly(anyOf1, anyOf2)
+ }
+
+ @Test
+ fun anyOf2_or_anyOf2() {
+ val anyOf = Permissions.anyOf("a", "b")
+ assertThat(anyOf or Permissions.anyOf("a", "c")).isSameInstanceAs(anyOf)
+ assertThat(anyOf.permissions).containsExactly("a", "b", "c")
+ }
+
+ @Test
+ fun check_allOf() {
+ val permissions = Permissions.allOf("a", "b")
+ assertThat(permissions.check(PermissionsContext(setOf()), 0, 0)).isFalse()
+ assertThat(permissions.check(PermissionsContext(setOf("a")), 0, 0)).isFalse()
+ assertThat(permissions.check(PermissionsContext(setOf("b")), 0, 0)).isFalse()
+ assertThat(permissions.check(PermissionsContext(setOf("a", "b")), 0, 0)).isTrue()
+ }
+
+ @Test
+ fun check_allOf_mixed() {
+ val permissions = Permissions.allOf("a", "b") or "c"
+ assertThat(permissions.permissions).hasSize(2)
+ assertThat(permissions.check(PermissionsContext(setOf()), 0, 0)).isFalse()
+ assertThat(permissions.check(PermissionsContext(setOf("a")), 0, 0)).isFalse()
+ assertThat(permissions.check(PermissionsContext(setOf("b")), 0, 0)).isFalse()
+ assertThat(permissions.check(PermissionsContext(setOf("a", "b")), 0, 0)).isTrue()
+ assertThat(permissions.check(PermissionsContext(setOf("c")), 0, 0)).isTrue()
+ assertThat(permissions.check(PermissionsContext(setOf("a", "c")), 0, 0)).isTrue()
+ assertThat(permissions.check(PermissionsContext(setOf("b", "c")), 0, 0)).isTrue()
+ assertThat(permissions.check(PermissionsContext(setOf("a", "b", "c")), 0, 0)).isTrue()
+ }
+
+ @Test
+ fun check_anyOf() {
+ val permissions = Permissions.anyOf("a", "b")
+ assertThat(permissions.check(PermissionsContext(setOf()), 0, 0)).isFalse()
+ assertThat(permissions.check(PermissionsContext(setOf("a")), 0, 0)).isTrue()
+ assertThat(permissions.check(PermissionsContext(setOf("b")), 0, 0)).isTrue()
+ assertThat(permissions.check(PermissionsContext(setOf("a", "b")), 0, 0)).isTrue()
+ }
+
+ @Test
+ fun check_anyOf_mixed() {
+ val permissions = Permissions.anyOf("a", "b") and "c"
+ assertThat(permissions.permissions).hasSize(2)
+ assertThat(permissions.check(PermissionsContext(setOf()), 0, 0)).isFalse()
+ assertThat(permissions.check(PermissionsContext(setOf("a")), 0, 0)).isFalse()
+ assertThat(permissions.check(PermissionsContext(setOf("b")), 0, 0)).isFalse()
+ assertThat(permissions.check(PermissionsContext(setOf("a", "b")), 0, 0)).isFalse()
+ assertThat(permissions.check(PermissionsContext(setOf("c")), 0, 0)).isFalse()
+ assertThat(permissions.check(PermissionsContext(setOf("a", "c")), 0, 0)).isTrue()
+ assertThat(permissions.check(PermissionsContext(setOf("b", "c")), 0, 0)).isTrue()
+ assertThat(permissions.check(PermissionsContext(setOf("a", "b", "c")), 0, 0)).isTrue()
+ }
+
+ @Test
+ fun equals() {
+ assertThat(Permissions.allOf("a")).isEqualTo(Permissions.allOf("a"))
+ assertThat(Permissions.allOf("a")).isEqualTo(Permissions.anyOf("a"))
+ assertThat(Permissions.anyOf("a")).isEqualTo(Permissions.allOf("a"))
+ assertThat(Permissions.anyOf("a")).isEqualTo(Permissions.anyOf("a"))
+
+ assertThat(Permissions.anyOf("a") and "b").isEqualTo(Permissions.allOf("a", "b"))
+ assertThat(Permissions.allOf("a") or "b").isEqualTo(Permissions.anyOf("a", "b"))
+ assertThat(Permissions.allOf("a") and "a").isEqualTo(Permissions.allOf("a"))
+ assertThat(Permissions.anyOf("a") or "a").isEqualTo(Permissions.anyOf("a"))
+
+ assertThat(Permissions.allOf("a", "c") and Permissions.allOf("c", "b"))
+ .isEqualTo(Permissions.allOf("a", "b", "c"))
+ assertThat(Permissions.anyOf("a", "c") or Permissions.anyOf("c", "b"))
+ .isEqualTo(Permissions.anyOf("a", "b", "c"))
+
+ assertThat(Permissions.allOf("a", "c") and Permissions.allOf("c", "b"))
+ .isEqualTo(Permissions.allOf("b", "c") and Permissions.allOf("c", "a"))
+ assertThat(Permissions.anyOf("a", "c") or Permissions.anyOf("c", "b"))
+ .isEqualTo(Permissions.anyOf("b", "c") or Permissions.anyOf("c", "a"))
+ }
+
+ @Test
+ fun notEquals() {
+ assertThat(Permissions.allOf("a")).isNotEqualTo(Permissions.allOf("a", "b"))
+ assertThat(Permissions.anyOf("a")).isNotEqualTo(Permissions.anyOf("a", "b"))
+ assertThat(Permissions.allOf("a", "b")).isNotEqualTo(Permissions.anyOf("a", "b"))
+ }
+}
+
+private class PermissionsContext(private val granted: Set<String>) :
+ ContextWrapper(ApplicationProvider.getApplicationContext()) {
+
+ override fun checkPermission(permission: String, pid: Int, uid: Int) =
+ if (permission in granted) PERMISSION_GRANTED else PERMISSION_DENIED
+}
diff --git a/packages/SettingsLib/Graph/graph.proto b/packages/SettingsLib/Graph/graph.proto
index 2aa619aa67f9..33a7df4c6ba8 100644
--- a/packages/SettingsLib/Graph/graph.proto
+++ b/packages/SettingsLib/Graph/graph.proto
@@ -82,9 +82,9 @@ message PreferenceProto {
// Indicate how sensitive of the preference.
optional int32 sensitivity_level = 16;
// The required permissions to read preference value.
- repeated string read_permissions = 17;
+ optional PermissionsProto read_permissions = 17;
// The required permissions to write preference value.
- repeated string write_permissions = 18;
+ optional PermissionsProto write_permissions = 18;
// Target of an Intent
message ActionTarget {
@@ -99,6 +99,20 @@ message PreferenceProto {
}
}
+// Proto of permissions
+message PermissionsProto {
+ repeated PermissionProto all_of = 1;
+ repeated PermissionProto any_of = 2;
+}
+
+// Proto of permission
+message PermissionProto {
+ oneof kind {
+ string permission = 1;
+ PermissionsProto permissions = 2;
+ }
+}
+
// Proto of string or string resource id.
message TextProto {
oneof text {
diff --git a/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PermissionsProtos.kt b/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PermissionsProtos.kt
new file mode 100644
index 000000000000..5971b4255c44
--- /dev/null
+++ b/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PermissionsProtos.kt
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.graph
+
+import com.android.settingslib.datastore.AllOfPermissions
+import com.android.settingslib.datastore.AnyOfPermissions
+import com.android.settingslib.datastore.Permissions
+import com.android.settingslib.datastore.and
+import com.android.settingslib.datastore.or
+import com.android.settingslib.graph.proto.PermissionProto
+import com.android.settingslib.graph.proto.PermissionsProto
+
+inline fun permissionsProto(init: PermissionsProto.Builder.() -> Unit): PermissionsProto =
+ PermissionsProto.newBuilder().also(init).build()
+
+inline fun permissionProto(init: PermissionProto.Builder.() -> Unit): PermissionProto =
+ PermissionProto.newBuilder().also(init).build()
+
+fun Permissions.toProto(): PermissionsProto = permissionsProto {
+ when (this@toProto) {
+ is AllOfPermissions -> {
+ forEach { addAllOf(it.toPermissionProto()) }
+ }
+ is AnyOfPermissions -> {
+ forEach { addAnyOf(it.toPermissionProto()) }
+ }
+ }
+}
+
+private fun Any.toPermissionProto() =
+ when {
+ this is Permissions -> permissionProto { permissions = toProto() }
+ else -> permissionProto { permission = this@toPermissionProto as String }
+ }
+
+fun PermissionsProto.getAllPermissions(): List<String> {
+ val permissions = mutableSetOf<String>()
+ fun Permissions.collect() {
+ forEach {
+ when {
+ it is String -> permissions.add(it)
+ else -> (it as Permissions).collect()
+ }
+ }
+ }
+ toPermissions().collect()
+ return permissions.toList()
+}
+
+fun PermissionsProto.toPermissions(): Permissions {
+ var permissions = Permissions.EMPTY
+ for (index in 0 until allOfCount) {
+ val permission = getAllOf(index).toPermission()
+ permissions =
+ when (permission) {
+ is String -> permissions and permission
+ else -> permissions and (permission as Permissions)
+ }
+ }
+ for (index in 0 until anyOfCount) {
+ val permission = getAnyOf(index).toPermission()
+ permissions =
+ when (permission) {
+ is String -> permissions or permission
+ else -> permissions or (permission as Permissions)
+ }
+ }
+ return permissions
+}
+
+private fun PermissionProto.toPermission(): Any =
+ when {
+ hasPermissions() -> permissions.toPermissions()
+ else -> permission
+ }
diff --git a/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceGraphBuilder.kt b/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceGraphBuilder.kt
index 91dec03bf2af..2cf32decd5e2 100644
--- a/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceGraphBuilder.kt
+++ b/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceGraphBuilder.kt
@@ -22,7 +22,6 @@ import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
-import android.content.pm.PackageManager.PERMISSION_GRANTED
import android.content.res.Configuration
import android.os.Build
import android.os.Bundle
@@ -393,10 +392,12 @@ fun PreferenceMetadata.toProto(
if (persistent) {
if (metadata is PersistentPreference<*>) {
sensitivityLevel = metadata.sensitivityLevel
- val readPermissions = metadata.getReadPermissions(context)
- readPermissions.forEach { addReadPermissions(it) }
- val writePermissions = metadata.getWritePermissions(context)
- writePermissions.forEach { addWritePermissions(it) }
+ metadata.getReadPermissions(context)?.let {
+ if (it.size > 0) readPermissions = it.toProto()
+ }
+ metadata.getWritePermissions(context)?.let {
+ if (it.size > 0) writePermissions = it.toProto()
+ }
}
if (
flags.includeValue() &&
@@ -439,14 +440,12 @@ fun <T> PersistentPreference<T>.evalReadPermit(
context: Context,
callingPid: Int,
callingUid: Int,
-): Int {
- for (permission in getReadPermissions(context)) {
- if (context.checkPermission(permission, callingPid, callingUid) != PERMISSION_GRANTED) {
- return ReadWritePermit.REQUIRE_APP_PERMISSION
- }
+): Int =
+ when {
+ getReadPermissions(context)?.check(context, callingPid, callingUid) == false ->
+ ReadWritePermit.REQUIRE_APP_PERMISSION
+ else -> getReadPermit(context, callingPid, callingUid)
}
- return getReadPermit(context, callingPid, callingUid)
-}
private fun PreferenceMetadata.getTitleTextProto(context: Context, isRoot: Boolean): TextProto? {
if (isRoot && this is PreferenceScreenMetadata) {
diff --git a/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceSetterApi.kt b/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceSetterApi.kt
index 83c430488317..bef4bb297654 100644
--- a/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceSetterApi.kt
+++ b/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceSetterApi.kt
@@ -18,7 +18,6 @@ package com.android.settingslib.graph
import android.app.Application
import android.content.Context
-import android.content.pm.PackageManager.PERMISSION_GRANTED
import android.os.Bundle
import androidx.annotation.IntDef
import com.android.settingslib.graph.proto.PreferenceValueProto
@@ -185,14 +184,12 @@ fun <T> PersistentPreference<T>.evalWritePermit(
value: T?,
callingPid: Int,
callingUid: Int,
-): Int {
- for (permission in getWritePermissions(context)) {
- if (context.checkPermission(permission, callingPid, callingUid) != PERMISSION_GRANTED) {
- return ReadWritePermit.REQUIRE_APP_PERMISSION
- }
+): Int =
+ when {
+ getWritePermissions(context)?.check(context, callingPid, callingUid) == false ->
+ ReadWritePermit.REQUIRE_APP_PERMISSION
+ else -> getWritePermit(context, value, callingPid, callingUid)
}
- return getWritePermit(context, value, callingPid, callingUid)
-}
/** Message codec for [PreferenceSetterRequest]. */
object PreferenceSetterRequestCodec : MessageCodec<PreferenceSetterRequest> {
diff --git a/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PersistentPreference.kt b/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PersistentPreference.kt
index 3dd6c47833fd..e5bf41f87999 100644
--- a/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PersistentPreference.kt
+++ b/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PersistentPreference.kt
@@ -20,6 +20,7 @@ import android.content.Context
import androidx.annotation.ArrayRes
import androidx.annotation.IntDef
import com.android.settingslib.datastore.KeyValueStore
+import com.android.settingslib.datastore.Permissions
/** Permit of read and write request. */
@IntDef(
@@ -69,7 +70,7 @@ interface PersistentPreference<T> {
PreferenceScreenRegistry.getKeyValueStore(context, this as PreferenceMetadata)!!
/** Returns the required permissions to read preference value. */
- fun getReadPermissions(context: Context): Array<String> = arrayOf()
+ fun getReadPermissions(context: Context): Permissions? = null
/**
* Returns if the external application (identified by [callingPid] and [callingUid]) is
@@ -88,7 +89,7 @@ interface PersistentPreference<T> {
)
/** Returns the required permissions to write preference value. */
- fun getWritePermissions(context: Context): Array<String> = arrayOf()
+ fun getWritePermissions(context: Context): Permissions? = null
/**
* Returns if the external application (identified by [callingPid] and [callingUid]) is
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsDimension.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsDimension.kt
index 08bedf99519d..fcaedd2b80bd 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsDimension.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsDimension.kt
@@ -33,9 +33,8 @@ object SettingsDimension {
val spinnerHorizontalPadding = paddingExtraLarge
val spinnerVerticalPadding = paddingLarge
- val actionIconWidth = 32.dp
- val actionIconHeight = 40.dp
- val actionIconPadding = 4.dp
+ val actionIconSize = 40.dp
+ val actionIconPadding = 8.dp
val itemIconSize = 24.dp
val itemIconContainerSizeSmall = 40.dp
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsTypography.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsTypography.kt
index 965c97124329..701825dd8bbf 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsTypography.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsTypography.kt
@@ -16,6 +16,7 @@
package com.android.settingslib.spa.framework.theme
+import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.Typography
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
@@ -29,134 +30,428 @@ private class SettingsTypography(settingsFontFamily: SettingsFontFamily) {
private val brand = settingsFontFamily.brand
private val plain = settingsFontFamily.plain
- val typography = Typography(
- displayLarge = TextStyle(
- fontFamily = brand,
- fontWeight = FontWeight.Normal,
- fontSize = 57.sp,
- lineHeight = 64.sp,
- letterSpacing = (-0.2).sp,
- hyphens = Hyphens.Auto,
- ),
- displayMedium = TextStyle(
- fontFamily = brand,
- fontWeight = FontWeight.Normal,
- fontSize = 45.sp,
- lineHeight = 52.sp,
- letterSpacing = 0.0.sp,
- hyphens = Hyphens.Auto,
- ),
- displaySmall = TextStyle(
- fontFamily = brand,
- fontWeight = FontWeight.Normal,
- fontSize = 36.sp,
- lineHeight = 44.sp,
- letterSpacing = 0.0.sp,
- hyphens = Hyphens.Auto,
- ),
- headlineLarge = TextStyle(
- fontFamily = brand,
- fontWeight = FontWeight.Normal,
- fontSize = 32.sp,
- lineHeight = 40.sp,
- letterSpacing = 0.0.sp,
- hyphens = Hyphens.Auto,
- ),
- headlineMedium = TextStyle(
- fontFamily = brand,
- fontWeight = FontWeight.Normal,
- fontSize = 28.sp,
- lineHeight = 36.sp,
- letterSpacing = 0.0.sp,
- hyphens = Hyphens.Auto,
- ),
- headlineSmall = TextStyle(
- fontFamily = brand,
- fontWeight = FontWeight.Normal,
- fontSize = 24.sp,
- lineHeight = 32.sp,
- letterSpacing = 0.0.sp,
- hyphens = Hyphens.Auto,
- ),
- titleLarge = TextStyle(
- fontFamily = brand,
- fontWeight = FontWeight.Normal,
- fontSize = 22.sp,
- lineHeight = 28.sp,
- letterSpacing = 0.02.em,
- hyphens = Hyphens.Auto,
- ),
- titleMedium = TextStyle(
- fontFamily = brand,
- fontWeight = FontWeight.Normal,
- fontSize = 20.sp,
- lineHeight = 24.sp,
- letterSpacing = 0.02.em,
- hyphens = Hyphens.Auto,
- ),
- titleSmall = TextStyle(
- fontFamily = brand,
- fontWeight = FontWeight.Normal,
- fontSize = 18.sp,
- lineHeight = 20.sp,
- letterSpacing = 0.02.em,
- hyphens = Hyphens.Auto,
- ),
- bodyLarge = TextStyle(
- fontFamily = plain,
- fontWeight = FontWeight.Normal,
- fontSize = 16.sp,
- lineHeight = 24.sp,
- letterSpacing = 0.01.em,
- hyphens = Hyphens.Auto,
- ),
- bodyMedium = TextStyle(
- fontFamily = plain,
- fontWeight = FontWeight.Normal,
- fontSize = 14.sp,
- lineHeight = 20.sp,
- letterSpacing = 0.01.em,
- hyphens = Hyphens.Auto,
- ),
- bodySmall = TextStyle(
- fontFamily = plain,
- fontWeight = FontWeight.Normal,
- fontSize = 12.sp,
- lineHeight = 16.sp,
- letterSpacing = 0.01.em,
- hyphens = Hyphens.Auto,
- ),
- labelLarge = TextStyle(
- fontFamily = plain,
- fontWeight = FontWeight.Medium,
- fontSize = 16.sp,
- lineHeight = 24.sp,
- letterSpacing = 0.01.em,
- hyphens = Hyphens.Auto,
- ),
- labelMedium = TextStyle(
- fontFamily = plain,
- fontWeight = FontWeight.Medium,
- fontSize = 14.sp,
- lineHeight = 20.sp,
- letterSpacing = 0.01.em,
- hyphens = Hyphens.Auto,
- ),
- labelSmall = TextStyle(
- fontFamily = plain,
- fontWeight = FontWeight.Medium,
- fontSize = 12.sp,
- lineHeight = 16.sp,
- letterSpacing = 0.01.em,
- hyphens = Hyphens.Auto,
- ),
- )
+ val typography =
+ Typography(
+ displayLarge =
+ TextStyle(
+ fontFamily = brand,
+ fontWeight = FontWeight.Normal,
+ fontSize = 57.sp,
+ lineHeight = 64.sp,
+ letterSpacing = (-0.2).sp,
+ hyphens = Hyphens.Auto,
+ ),
+ displayMedium =
+ TextStyle(
+ fontFamily = brand,
+ fontWeight = FontWeight.Normal,
+ fontSize = 45.sp,
+ lineHeight = 52.sp,
+ letterSpacing = 0.0.sp,
+ hyphens = Hyphens.Auto,
+ ),
+ displaySmall =
+ TextStyle(
+ fontFamily = brand,
+ fontWeight = FontWeight.Normal,
+ fontSize = 36.sp,
+ lineHeight = 44.sp,
+ letterSpacing = 0.0.sp,
+ hyphens = Hyphens.Auto,
+ ),
+ headlineLarge =
+ TextStyle(
+ fontFamily = brand,
+ fontWeight = FontWeight.Normal,
+ fontSize = 32.sp,
+ lineHeight = 40.sp,
+ letterSpacing = 0.0.sp,
+ hyphens = Hyphens.Auto,
+ ),
+ headlineMedium =
+ TextStyle(
+ fontFamily = brand,
+ fontWeight = FontWeight.Normal,
+ fontSize = 28.sp,
+ lineHeight = 36.sp,
+ letterSpacing = 0.0.sp,
+ hyphens = Hyphens.Auto,
+ ),
+ headlineSmall =
+ TextStyle(
+ fontFamily = brand,
+ fontWeight = FontWeight.Normal,
+ fontSize = 24.sp,
+ lineHeight = 32.sp,
+ letterSpacing = 0.0.sp,
+ hyphens = Hyphens.Auto,
+ ),
+ titleLarge =
+ TextStyle(
+ fontFamily = brand,
+ fontWeight = FontWeight.Normal,
+ fontSize = 22.sp,
+ lineHeight = 28.sp,
+ letterSpacing = 0.02.em,
+ hyphens = Hyphens.Auto,
+ ),
+ titleMedium =
+ TextStyle(
+ fontFamily = brand,
+ fontWeight = FontWeight.Normal,
+ fontSize = 20.sp,
+ lineHeight = 24.sp,
+ letterSpacing = 0.02.em,
+ hyphens = Hyphens.Auto,
+ ),
+ titleSmall =
+ TextStyle(
+ fontFamily = brand,
+ fontWeight = FontWeight.Normal,
+ fontSize = 18.sp,
+ lineHeight = 20.sp,
+ letterSpacing = 0.02.em,
+ hyphens = Hyphens.Auto,
+ ),
+ bodyLarge =
+ TextStyle(
+ fontFamily = plain,
+ fontWeight = FontWeight.Normal,
+ fontSize = 16.sp,
+ lineHeight = 24.sp,
+ letterSpacing = 0.01.em,
+ hyphens = Hyphens.Auto,
+ ),
+ bodyMedium =
+ TextStyle(
+ fontFamily = plain,
+ fontWeight = FontWeight.Normal,
+ fontSize = 14.sp,
+ lineHeight = 20.sp,
+ letterSpacing = 0.01.em,
+ hyphens = Hyphens.Auto,
+ ),
+ bodySmall =
+ TextStyle(
+ fontFamily = plain,
+ fontWeight = FontWeight.Normal,
+ fontSize = 12.sp,
+ lineHeight = 16.sp,
+ letterSpacing = 0.01.em,
+ hyphens = Hyphens.Auto,
+ ),
+ labelLarge =
+ TextStyle(
+ fontFamily = plain,
+ fontWeight = FontWeight.Medium,
+ fontSize = 16.sp,
+ lineHeight = 24.sp,
+ letterSpacing = 0.01.em,
+ hyphens = Hyphens.Auto,
+ ),
+ labelMedium =
+ TextStyle(
+ fontFamily = plain,
+ fontWeight = FontWeight.Medium,
+ fontSize = 14.sp,
+ lineHeight = 20.sp,
+ letterSpacing = 0.01.em,
+ hyphens = Hyphens.Auto,
+ ),
+ labelSmall =
+ TextStyle(
+ fontFamily = plain,
+ fontWeight = FontWeight.Medium,
+ fontSize = 12.sp,
+ lineHeight = 16.sp,
+ letterSpacing = 0.01.em,
+ hyphens = Hyphens.Auto,
+ ),
+ )
+
+ @OptIn(ExperimentalMaterial3ExpressiveApi::class)
+ val expressiveTypography =
+ Typography(
+ displayLarge =
+ TextStyle(
+ fontFamily = brand,
+ fontWeight = FontWeight.Normal,
+ fontSize = 57.sp,
+ lineHeight = 64.sp,
+ letterSpacing = (-0.2).sp,
+ hyphens = Hyphens.Auto,
+ ),
+ displayLargeEmphasized =
+ TextStyle(
+ fontFamily = brand,
+ fontWeight = FontWeight.Medium,
+ fontSize = 57.sp,
+ lineHeight = 64.sp,
+ letterSpacing = (-0.2).sp,
+ hyphens = Hyphens.Auto,
+ ),
+ displayMedium =
+ TextStyle(
+ fontFamily = brand,
+ fontWeight = FontWeight.Normal,
+ fontSize = 45.sp,
+ lineHeight = 52.sp,
+ letterSpacing = 0.0.sp,
+ hyphens = Hyphens.Auto,
+ ),
+ displayMediumEmphasized =
+ TextStyle(
+ fontFamily = brand,
+ fontWeight = FontWeight.Medium,
+ fontSize = 45.sp,
+ lineHeight = 52.sp,
+ letterSpacing = 0.0.sp,
+ hyphens = Hyphens.Auto,
+ ),
+ displaySmall =
+ TextStyle(
+ fontFamily = brand,
+ fontWeight = FontWeight.Normal,
+ fontSize = 36.sp,
+ lineHeight = 44.sp,
+ letterSpacing = 0.0.sp,
+ hyphens = Hyphens.Auto,
+ ),
+ displaySmallEmphasized =
+ TextStyle(
+ fontFamily = brand,
+ fontWeight = FontWeight.Medium,
+ fontSize = 36.sp,
+ lineHeight = 44.sp,
+ letterSpacing = 0.0.sp,
+ hyphens = Hyphens.Auto,
+ ),
+ headlineLarge =
+ TextStyle(
+ fontFamily = brand,
+ fontWeight = FontWeight.Normal,
+ fontSize = 32.sp,
+ lineHeight = 40.sp,
+ letterSpacing = 0.0.sp,
+ hyphens = Hyphens.Auto,
+ ),
+ headlineLargeEmphasized =
+ TextStyle(
+ fontFamily = brand,
+ fontWeight = FontWeight.Medium,
+ fontSize = 32.sp,
+ lineHeight = 40.sp,
+ letterSpacing = 0.0.sp,
+ hyphens = Hyphens.Auto,
+ ),
+ headlineMedium =
+ TextStyle(
+ fontFamily = brand,
+ fontWeight = FontWeight.Normal,
+ fontSize = 28.sp,
+ lineHeight = 36.sp,
+ letterSpacing = 0.0.sp,
+ hyphens = Hyphens.Auto,
+ ),
+ headlineMediumEmphasized =
+ TextStyle(
+ fontFamily = brand,
+ fontWeight = FontWeight.Medium,
+ fontSize = 28.sp,
+ lineHeight = 36.sp,
+ letterSpacing = 0.0.sp,
+ hyphens = Hyphens.Auto,
+ ),
+ headlineSmall =
+ TextStyle(
+ fontFamily = brand,
+ fontWeight = FontWeight.Normal,
+ fontSize = 24.sp,
+ lineHeight = 32.sp,
+ letterSpacing = 0.0.sp,
+ hyphens = Hyphens.Auto,
+ ),
+ headlineSmallEmphasized =
+ TextStyle(
+ fontFamily = brand,
+ fontWeight = FontWeight.Medium,
+ fontSize = 24.sp,
+ lineHeight = 32.sp,
+ letterSpacing = 0.0.sp,
+ hyphens = Hyphens.Auto,
+ ),
+ titleLarge =
+ TextStyle(
+ fontFamily = brand,
+ fontWeight = FontWeight.Normal,
+ fontSize = 22.sp,
+ lineHeight = 28.sp,
+ letterSpacing = 0.02.em,
+ hyphens = Hyphens.Auto,
+ ),
+ titleLargeEmphasized =
+ TextStyle(
+ fontFamily = brand,
+ fontWeight = FontWeight.Medium,
+ fontSize = 22.sp,
+ lineHeight = 28.sp,
+ letterSpacing = 0.02.em,
+ hyphens = Hyphens.Auto,
+ ),
+ titleMedium =
+ TextStyle(
+ fontFamily = brand,
+ fontWeight = FontWeight.Medium,
+ fontSize = 16.sp,
+ lineHeight = 24.sp,
+ letterSpacing = 0.02.em,
+ hyphens = Hyphens.Auto,
+ ),
+ titleMediumEmphasized =
+ TextStyle(
+ fontFamily = brand,
+ fontWeight = FontWeight.SemiBold,
+ fontSize = 16.sp,
+ lineHeight = 24.sp,
+ letterSpacing = 0.02.em,
+ hyphens = Hyphens.Auto,
+ ),
+ titleSmall =
+ TextStyle(
+ fontFamily = brand,
+ fontWeight = FontWeight.Medium,
+ fontSize = 14.sp,
+ lineHeight = 20.sp,
+ letterSpacing = 0.02.em,
+ hyphens = Hyphens.Auto,
+ ),
+ titleSmallEmphasized =
+ TextStyle(
+ fontFamily = brand,
+ fontWeight = FontWeight.SemiBold,
+ fontSize = 14.sp,
+ lineHeight = 20.sp,
+ letterSpacing = 0.02.em,
+ hyphens = Hyphens.Auto,
+ ),
+ bodyLarge =
+ TextStyle(
+ fontFamily = plain,
+ fontWeight = FontWeight.Normal,
+ fontSize = 16.sp,
+ lineHeight = 24.sp,
+ letterSpacing = 0.01.em,
+ hyphens = Hyphens.Auto,
+ ),
+ bodyLargeEmphasized =
+ TextStyle(
+ fontFamily = plain,
+ fontWeight = FontWeight.Medium,
+ fontSize = 16.sp,
+ lineHeight = 24.sp,
+ letterSpacing = 0.01.em,
+ hyphens = Hyphens.Auto,
+ ),
+ bodyMedium =
+ TextStyle(
+ fontFamily = plain,
+ fontWeight = FontWeight.Normal,
+ fontSize = 14.sp,
+ lineHeight = 20.sp,
+ letterSpacing = 0.01.em,
+ hyphens = Hyphens.Auto,
+ ),
+ bodyMediumEmphasized =
+ TextStyle(
+ fontFamily = plain,
+ fontWeight = FontWeight.Medium,
+ fontSize = 14.sp,
+ lineHeight = 20.sp,
+ letterSpacing = 0.01.em,
+ hyphens = Hyphens.Auto,
+ ),
+ bodySmall =
+ TextStyle(
+ fontFamily = plain,
+ fontWeight = FontWeight.Normal,
+ fontSize = 12.sp,
+ lineHeight = 16.sp,
+ letterSpacing = 0.01.em,
+ hyphens = Hyphens.Auto,
+ ),
+ bodySmallEmphasized =
+ TextStyle(
+ fontFamily = plain,
+ fontWeight = FontWeight.Medium,
+ fontSize = 12.sp,
+ lineHeight = 16.sp,
+ letterSpacing = 0.01.em,
+ hyphens = Hyphens.Auto,
+ ),
+ labelLarge =
+ TextStyle(
+ fontFamily = plain,
+ fontWeight = FontWeight.Medium,
+ fontSize = 14.sp,
+ lineHeight = 20.sp,
+ letterSpacing = 0.01.em,
+ hyphens = Hyphens.Auto,
+ ),
+ labelLargeEmphasized =
+ TextStyle(
+ fontFamily = plain,
+ fontWeight = FontWeight.SemiBold,
+ fontSize = 14.sp,
+ lineHeight = 20.sp,
+ letterSpacing = 0.01.em,
+ hyphens = Hyphens.Auto,
+ ),
+ labelMedium =
+ TextStyle(
+ fontFamily = plain,
+ fontWeight = FontWeight.Medium,
+ fontSize = 12.sp,
+ lineHeight = 16.sp,
+ letterSpacing = 0.01.em,
+ hyphens = Hyphens.Auto,
+ ),
+ labelMediumEmphasized =
+ TextStyle(
+ fontFamily = plain,
+ fontWeight = FontWeight.SemiBold,
+ fontSize = 12.sp,
+ lineHeight = 16.sp,
+ letterSpacing = 0.01.em,
+ hyphens = Hyphens.Auto,
+ ),
+ labelSmall =
+ TextStyle(
+ fontFamily = plain,
+ fontWeight = FontWeight.Medium,
+ fontSize = 11.sp,
+ lineHeight = 16.sp,
+ letterSpacing = 0.01.em,
+ hyphens = Hyphens.Auto,
+ ),
+ labelSmallEmphasized =
+ TextStyle(
+ fontFamily = plain,
+ fontWeight = FontWeight.SemiBold,
+ fontSize = 11.sp,
+ lineHeight = 16.sp,
+ letterSpacing = 0.01.em,
+ hyphens = Hyphens.Auto,
+ ),
+ )
}
@Composable
internal fun rememberSettingsTypography(): Typography {
val settingsFontFamily = rememberSettingsFontFamily()
- return remember { SettingsTypography(settingsFontFamily).typography }
+ return remember {
+ if (isSpaExpressiveEnabled) SettingsTypography(settingsFontFamily).expressiveTypography
+ else SettingsTypography(settingsFontFamily).typography
+ }
}
/** Creates a new [TextStyle] which font weight set to medium. */
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/button/ActionButtons.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/button/ActionButtons.kt
index 203a8bd39fae..adebccb2ed26 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/button/ActionButtons.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/button/ActionButtons.kt
@@ -56,7 +56,6 @@ import com.android.settingslib.spa.framework.theme.SettingsShape
import com.android.settingslib.spa.framework.theme.SettingsTheme
import com.android.settingslib.spa.framework.theme.divider
import com.android.settingslib.spa.framework.theme.isSpaExpressiveEnabled
-import com.android.settingslib.spa.framework.theme.toSemiBoldWeight
data class ActionButton(
val text: String,
@@ -130,7 +129,7 @@ private fun RowScope.ActionButton(actionButton: ActionButton) {
Text(
text = actionButton.text,
textAlign = TextAlign.Center,
- style = MaterialTheme.typography.labelLarge.toSemiBoldWeight(),
+ style = MaterialTheme.typography.titleSmall,
)
}
}
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/IntroPreference.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/IntroPreference.kt
index 6d3f7bc1147d..c786dde4c6a7 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/IntroPreference.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/IntroPreference.kt
@@ -36,7 +36,6 @@ import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import com.android.settingslib.spa.framework.theme.SettingsDimension
-import com.android.settingslib.spa.framework.theme.toSemiBoldWeight
@Composable
fun IntroPreference(
@@ -113,7 +112,7 @@ private fun IntroTitle(title: String) {
Text(
text = title,
textAlign = TextAlign.Center,
- style = MaterialTheme.typography.titleLarge.toSemiBoldWeight(),
+ style = MaterialTheme.typography.titleLarge,
color = MaterialTheme.colorScheme.onSurface,
)
}
@@ -127,7 +126,7 @@ private fun IntroDescription(descriptions: List<String>?) {
Text(
text = description,
textAlign = TextAlign.Center,
- style = MaterialTheme.typography.bodyLarge,
+ style = MaterialTheme.typography.titleMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant,
modifier = Modifier.padding(top = SettingsDimension.paddingExtraSmall),
)
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/ZeroStatePreference.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/ZeroStatePreference.kt
index 541922335387..3ebe18d4c342 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/ZeroStatePreference.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/ZeroStatePreference.kt
@@ -23,6 +23,7 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.History
+import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
@@ -47,8 +48,8 @@ import androidx.graphics.shapes.CornerRounding
import androidx.graphics.shapes.RoundedPolygon
import androidx.graphics.shapes.star
import androidx.graphics.shapes.toPath
-import com.android.settingslib.spa.framework.theme.toSemiBoldWeight
+@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Composable
fun ZeroStatePreference(icon: ImageVector, text: String? = null, description: String? = null) {
val zeroStateShape = remember {
@@ -81,7 +82,7 @@ fun ZeroStatePreference(icon: ImageVector, text: String? = null, description: St
Text(
text = text,
textAlign = TextAlign.Center,
- style = MaterialTheme.typography.titleMedium.toSemiBoldWeight(),
+ style = MaterialTheme.typography.titleMediumEmphasized,
color = MaterialTheme.colorScheme.onSurfaceVariant,
modifier = Modifier.padding(top = 24.dp),
)
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/Actions.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/Actions.kt
index f99d20669183..668f683523a6 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/Actions.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/Actions.kt
@@ -56,32 +56,27 @@ private fun BackAction(contentDescription: String, onClick: () -> Unit) {
IconButton(
onClick = onClick,
modifier =
- if (isSpaExpressiveEnabled)
- Modifier
- .padding(
- start = SettingsDimension.paddingLarge,
- end = SettingsDimension.paddingSmall,
- top = SettingsDimension.paddingExtraSmall,
- bottom = SettingsDimension.paddingExtraSmall,
- )
- .size(SettingsDimension.actionIconWidth, SettingsDimension.actionIconHeight)
- .clip(SettingsShape.CornerExtraLarge)
- else Modifier,
+ if (isSpaExpressiveEnabled)
+ Modifier.padding(
+ start = SettingsDimension.paddingExtraSmall5,
+ end = SettingsDimension.paddingSmall,
+ top = SettingsDimension.paddingExtraSmall,
+ bottom = SettingsDimension.paddingExtraSmall,
+ )
+ .size(SettingsDimension.actionIconSize)
+ .clip(SettingsShape.CornerExtraLarge)
+ else Modifier,
) {
Icon(
imageVector = Icons.AutoMirrored.Outlined.ArrowBack,
contentDescription = contentDescription,
modifier =
- if (isSpaExpressiveEnabled)
- Modifier
- .size(
- SettingsDimension.actionIconWidth,
- SettingsDimension.actionIconHeight,
- )
- .clip(SettingsShape.CornerExtraLarge)
- .background(MaterialTheme.colorScheme.surfaceContainerHighest)
- .padding(SettingsDimension.actionIconPadding)
- else Modifier,
+ if (isSpaExpressiveEnabled)
+ Modifier.size(SettingsDimension.actionIconSize)
+ .clip(SettingsShape.CornerExtraLarge)
+ .background(MaterialTheme.colorScheme.surfaceContainerHighest)
+ .padding(SettingsDimension.actionIconPadding)
+ else Modifier,
)
}
}
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/CustomizedAppBar.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/CustomizedAppBar.kt
index 693fb3541bb8..0c0ece487578 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/CustomizedAppBar.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/CustomizedAppBar.kt
@@ -142,10 +142,11 @@ private fun Title(title: String, maxLines: Int = Int.MAX_VALUE) {
Text(
text = title,
modifier =
- Modifier.padding(
+ Modifier
+ .padding(
start =
- if (isSpaExpressiveEnabled) SettingsDimension.paddingExtraSmall
- else SettingsDimension.itemPaddingAround,
+ if (isSpaExpressiveEnabled) SettingsDimension.paddingExtraSmall
+ else SettingsDimension.itemPaddingAround,
end = SettingsDimension.itemPaddingEnd,
)
.semantics { heading() },
@@ -156,13 +157,22 @@ private fun Title(title: String, maxLines: Int = Int.MAX_VALUE) {
@Composable
private fun topAppBarColors() =
- TopAppBarColors(
- containerColor = MaterialTheme.colorScheme.settingsBackground,
- scrolledContainerColor = MaterialTheme.colorScheme.surfaceVariant,
- navigationIconContentColor = MaterialTheme.colorScheme.onSurface,
- titleContentColor = MaterialTheme.colorScheme.onSurface,
- actionIconContentColor = MaterialTheme.colorScheme.onSurfaceVariant,
- )
+ if (isSpaExpressiveEnabled)
+ TopAppBarColors(
+ containerColor = MaterialTheme.colorScheme.surfaceContainer,
+ scrolledContainerColor = MaterialTheme.colorScheme.surfaceContainer,
+ navigationIconContentColor = MaterialTheme.colorScheme.onSurface,
+ titleContentColor = MaterialTheme.colorScheme.onSurface,
+ actionIconContentColor = MaterialTheme.colorScheme.primary,
+ )
+ else
+ TopAppBarColors(
+ containerColor = MaterialTheme.colorScheme.settingsBackground,
+ scrolledContainerColor = MaterialTheme.colorScheme.surfaceVariant,
+ navigationIconContentColor = MaterialTheme.colorScheme.onSurface,
+ titleContentColor = MaterialTheme.colorScheme.onSurface,
+ actionIconContentColor = MaterialTheme.colorScheme.onSurfaceVariant,
+ )
/**
* Represents the colors used by a top app bar in different states.
@@ -257,14 +267,16 @@ private fun SingleRowTopAppBar(
// Compose a Surface with a TopAppBarLayout content.
Box(
modifier =
- Modifier.drawBehind { drawRect(color = colors.scrolledContainerColor) }
+ Modifier
+ .drawBehind { drawRect(color = colors.scrolledContainerColor) }
.semantics { isTraversalGroup = true }
.pointerInput(Unit) {}
) {
val height = LocalDensity.current.run { ContainerHeight.toPx() }
TopAppBarLayout(
modifier =
- Modifier.windowInsetsPadding(windowInsets)
+ Modifier
+ .windowInsetsPadding(windowInsets)
// clip after padding so we don't show the title over the inset area
.clipToBounds(),
heightPx = height,
@@ -387,7 +399,8 @@ private fun TwoRowsTopAppBar(
Column {
TopAppBarLayout(
modifier =
- Modifier.windowInsetsPadding(windowInsets)
+ Modifier
+ .windowInsetsPadding(windowInsets)
// clip after padding so we don't show the title over the inset area
.clipToBounds(),
heightPx = pinnedHeightPx,
@@ -495,14 +508,17 @@ private fun TopAppBarLayout(
) {
Layout(
{
- Box(Modifier.layoutId("navigationIcon").padding(start = TopAppBarHorizontalPadding)) {
+ Box(Modifier
+ .layoutId("navigationIcon")
+ .padding(start = TopAppBarHorizontalPadding)) {
CompositionLocalProvider(
LocalContentColor provides navigationIconContentColor,
content = navigationIcon,
)
}
Box(
- Modifier.layoutId("title")
+ Modifier
+ .layoutId("title")
.padding(horizontal = TopAppBarHorizontalPadding)
.then(if (hideTitleSemantics) Modifier.clearAndSetSemantics {} else Modifier)
.graphicsLayer { alpha = titleAlpha() }
@@ -521,7 +537,9 @@ private fun TopAppBarLayout(
)
}
}
- Box(Modifier.layoutId("actionIcons").padding(end = TopAppBarHorizontalPadding)) {
+ Box(Modifier
+ .layoutId("actionIcons")
+ .padding(end = TopAppBarHorizontalPadding)) {
CompositionLocalProvider(
LocalContentColor provides actionIconContentColor,
content = actions,
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Category.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Category.kt
index 62bc00a8b347..f10f96afd389 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Category.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Category.kt
@@ -28,6 +28,7 @@ import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.TouchApp
+import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
@@ -51,6 +52,7 @@ import com.android.settingslib.spa.widget.preference.Preference
import com.android.settingslib.spa.widget.preference.PreferenceModel
/** A category title that is placed before a group of similar items. */
+@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Composable
fun CategoryTitle(title: String) {
Text(
@@ -67,7 +69,9 @@ fun CategoryTitle(title: String) {
bottom = 8.dp,
),
color = MaterialTheme.colorScheme.primary,
- style = MaterialTheme.typography.labelMedium,
+ style =
+ if (isSpaExpressiveEnabled) MaterialTheme.typography.labelLargeEmphasized
+ else MaterialTheme.typography.labelMedium,
)
}
@@ -76,7 +80,11 @@ fun CategoryTitle(title: String) {
* visually separates groups of items.
*/
@Composable
-fun Category(title: String? = null, modifier: Modifier = Modifier, content: @Composable ColumnScope.() -> Unit) {
+fun Category(
+ title: String? = null,
+ modifier: Modifier = Modifier,
+ content: @Composable ColumnScope.() -> Unit,
+) {
var displayTitle by remember { mutableStateOf(false) }
Column(
modifier =
@@ -90,7 +98,8 @@ fun Category(title: String? = null, modifier: Modifier = Modifier, content: @Com
if (title != null && displayTitle) CategoryTitle(title = title)
Column(
modifier =
- modifier.onGloballyPositioned { coordinates ->
+ modifier
+ .onGloballyPositioned { coordinates ->
displayTitle = coordinates.size.height > 0
}
.then(
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Spinner.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Spinner.kt
index 6e4fd78a039b..03777cc49df7 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Spinner.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Spinner.kt
@@ -195,7 +195,9 @@ private fun SpinnerText(
else Modifier
),
color = color,
- style = MaterialTheme.typography.labelLarge,
+ style =
+ if (isSpaExpressiveEnabled) MaterialTheme.typography.titleMedium
+ else MaterialTheme.typography.labelLarge,
)
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java
index 0c642d7b8f98..3c36c4438bca 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java
@@ -30,6 +30,7 @@ import android.net.Uri;
import android.provider.DeviceConfig;
import android.provider.MediaStore;
import android.provider.Settings;
+import android.sysprop.BluetoothProperties;
import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
@@ -648,8 +649,10 @@ public class BluetoothUtils {
/** Returns if the le audio sharing UI is available. */
public static boolean isAudioSharingUIAvailable(@Nullable Context context) {
- return isAudioSharingEnabled() || (context != null && isAudioSharingPreviewEnabled(
- context.getContentResolver()));
+ return (Flags.enableLeAudioSharing()
+ || (context != null && Flags.audioSharingDeveloperOption()
+ && getAudioSharingPreviewValue(context.getContentResolver())))
+ && isAudioSharingSupported();
}
/** Returns if the le audio sharing hysteresis mode fix is available. */
@@ -662,31 +665,39 @@ public class BluetoothUtils {
/** Returns if the le audio sharing is enabled. */
public static boolean isAudioSharingEnabled() {
- BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
- try {
- return Flags.enableLeAudioSharing()
- && adapter.isLeAudioBroadcastSourceSupported()
- == BluetoothStatusCodes.FEATURE_SUPPORTED
- && adapter.isLeAudioBroadcastAssistantSupported()
- == BluetoothStatusCodes.FEATURE_SUPPORTED;
- } catch (IllegalStateException e) {
- Log.d(TAG, "Fail to check isAudioSharingEnabled, e = ", e);
- return false;
- }
+ return Flags.enableLeAudioSharing() && isAudioSharingSupported();
}
/** Returns if the le audio sharing preview is enabled in developer option. */
public static boolean isAudioSharingPreviewEnabled(@Nullable ContentResolver contentResolver) {
+ return Flags.audioSharingDeveloperOption()
+ && getAudioSharingPreviewValue(contentResolver)
+ && isAudioSharingSupported();
+ }
+
+ /** Returns if the device has le audio sharing capability */
+ private static boolean isAudioSharingSupported() {
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
try {
- return Flags.audioSharingDeveloperOption()
- && getAudioSharingPreviewValue(contentResolver)
- && adapter.isLeAudioBroadcastSourceSupported()
- == BluetoothStatusCodes.FEATURE_SUPPORTED
- && adapter.isLeAudioBroadcastAssistantSupported()
- == BluetoothStatusCodes.FEATURE_SUPPORTED;
+ // b/381777424 The APIs have to return ERROR_BLUETOOTH_NOT_ENABLED when BT off based on
+ // CDD definition.
+ // However, app layer need to gate the feature based on whether the device has audio
+ // sharing capability regardless of the BT state.
+ // So here we check the BluetoothProperties when BT off.
+ //
+ // TODO: Also check SystemProperties "persist.bluetooth.leaudio_dynamic_switcher.mode"
+ // and return true if it is in broadcast mode.
+ // Now SystemUI don't have access to read the value.
+ int sourceSupportedCode = adapter.isLeAudioBroadcastSourceSupported();
+ int assistantSupportedCode = adapter.isLeAudioBroadcastAssistantSupported();
+ return (sourceSupportedCode == BluetoothStatusCodes.FEATURE_SUPPORTED
+ || (sourceSupportedCode == BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED
+ && BluetoothProperties.isProfileBapBroadcastSourceEnabled().orElse(false)))
+ && (assistantSupportedCode == BluetoothStatusCodes.FEATURE_SUPPORTED
+ || (assistantSupportedCode == BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED
+ && BluetoothProperties.isProfileBapBroadcastAssistEnabled().orElse(false)));
} catch (IllegalStateException e) {
- Log.d(TAG, "Fail to check isAudioSharingPreviewEnabled, e = ", e);
+ Log.d(TAG, "Fail to check isAudioSharingSupported, e = ", e);
return false;
}
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java
index 2c99a2d4818c..7d5eece6c30e 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java
@@ -56,6 +56,7 @@ import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import com.android.settingslib.R;
+import com.android.settingslib.flags.Flags;
import com.google.common.collect.ImmutableList;
@@ -1126,6 +1127,10 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile {
/** Update fallback active device if needed. */
public void updateFallbackActiveDeviceIfNeeded() {
+ if (Flags.disableAudioSharingAutoPickFallbackInUi()) {
+ Log.d(TAG, "Skip updateFallbackActiveDeviceIfNeeded, disable flag is on");
+ return;
+ }
if (isWorkProfile(mContext)) {
Log.d(TAG, "Skip updateFallbackActiveDeviceIfNeeded for work profile.");
return;
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothEventManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothEventManagerTest.java
index 22b315084f3f..b86f4b3715b5 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothEventManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothEventManagerTest.java
@@ -309,6 +309,7 @@ public class BluetoothEventManagerTest {
private void setUpAudioSharing(boolean enableFlag, boolean enableFeature,
boolean enableProfile, boolean workProfile) {
+ mSetFlagsRule.disableFlags(Flags.FLAG_DISABLE_AUDIO_SHARING_AUTO_PICK_FALLBACK_IN_UI);
if (enableFlag) {
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
} else {
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
index e01cb84f60ae..a2cc008843a4 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
@@ -1053,14 +1053,10 @@ public class SettingsBackupAgent extends BackupAgentHelper {
Log.d(TAG, "Restored font scale from: " + toRestore + " to " + value);
}
- // TODO(b/379861078): Log metrics inside this method.
settingsHelper.restoreValue(this, cr, contentValues, destination, key, value,
mRestoredFromSdkInt);
Log.d(TAG, "Restored setting: " + destination + " : " + key + "=" + value);
- if (areAgentMetricsEnabled) {
- mBackupRestoreEventLogger.logItemsRestored(finalSettingsKey, /* count= */ 1);
- }
}
}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
index ab8d739feb43..4f5203136bbc 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
@@ -81,6 +81,7 @@ public class SettingsHelper {
// Error messages for logging metrics.
private static final String ERROR_REMOTE_EXCEPTION_SETTING_LOCALE_DATA =
"remote_exception_setting_locale_data";
+ private static final String ERROR_FAILED_TO_RESTORE_SETTING = "failed_to_restore_setting";
private Context mContext;
private AudioManager mAudioManager;
@@ -206,6 +207,12 @@ public class SettingsHelper {
table = sGlobalLookup;
}
+ // Get datatype for B&R metrics logging.
+ String datatype = "";
+ if (Flags.enableMetricsSettingsBackupAgents()) {
+ datatype = SettingsBackupRestoreKeys.getKeyFromUri(destination);
+ }
+
sendBroadcast = sBroadcastOnRestore.contains(name);
sendBroadcastSystemUI = sBroadcastOnRestoreSystemUI.contains(name);
sendBroadcastAccessibility = sBroadcastOnRestoreAccessibility.contains(name);
@@ -292,12 +299,19 @@ public class SettingsHelper {
contentValues.put(Settings.NameValueTable.NAME, name);
contentValues.put(Settings.NameValueTable.VALUE, value);
cr.insert(destination, contentValues);
+ if (Flags.enableMetricsSettingsBackupAgents()) {
+ mBackupRestoreEventLogger.logItemsRestored(datatype, /* count= */ 1);
+ }
} catch (Exception e) {
// If we fail to apply the setting, by definition nothing happened
sendBroadcast = false;
sendBroadcastSystemUI = false;
sendBroadcastAccessibility = false;
Log.e(TAG, "Failed to restore setting name: " + name + " + value: " + value, e);
+ if (Flags.enableMetricsSettingsBackupAgents()) {
+ mBackupRestoreEventLogger.logItemsRestoreFailed(
+ datatype, /* count= */ 1, ERROR_FAILED_TO_RESTORE_SETTING);
+ }
} finally {
// If this was an element of interest, send the "we just restored it"
// broadcast with the historical value now that the new value has
diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsBackupAgentTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsBackupAgentTest.java
index 350c149f40de..18c43a704bcc 100644
--- a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsBackupAgentTest.java
+++ b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsBackupAgentTest.java
@@ -422,75 +422,6 @@ public class SettingsBackupAgentTest extends BaseSettingsProviderTest {
@Test
@EnableFlags(com.android.server.backup.Flags.FLAG_ENABLE_METRICS_SETTINGS_BACKUP_AGENTS)
- public void restoreSettings_agentMetricsAreEnabled_agentMetricsAreLogged() {
- mAgentUnderTest.onCreate(
- UserHandle.SYSTEM, BackupDestination.CLOUD, OperationType.RESTORE);
- SettingsBackupAgent.SettingsBackupAllowlist allowlist =
- new SettingsBackupAgent.SettingsBackupAllowlist(
- new String[] {OVERRIDDEN_TEST_SETTING},
- TEST_VALUES_VALIDATORS);
- mAgentUnderTest.setSettingsAllowlist(allowlist);
- mAgentUnderTest.setBlockedSettings();
- TestSettingsHelper settingsHelper = new TestSettingsHelper(mContext);
- mAgentUnderTest.mSettingsHelper = settingsHelper;
-
- byte[] backupData = generateBackupData(TEST_VALUES);
- mAgentUnderTest
- .restoreSettings(
- backupData,
- /* pos= */ 0,
- backupData.length,
- TEST_URI,
- /* movedToGlobal= */ null,
- /* movedToSecure= */ null,
- /* movedToSystem= */ null,
- /* blockedSettingsArrayId= */ 0,
- /* dynamicBlockList= */ Collections.emptySet(),
- /* settingsToPreserve= */ Collections.emptySet(),
- TEST_KEY);
-
- DataTypeResult loggingResult =
- getLoggingResultForDatatype(TEST_KEY, mAgentUnderTest);
- assertNotNull(loggingResult);
- assertEquals(loggingResult.getSuccessCount(), 1);
- }
-
- @Test
- @DisableFlags(com.android.server.backup.Flags.FLAG_ENABLE_METRICS_SETTINGS_BACKUP_AGENTS)
- public void restoreSettings_agentMetricsAreDisabled_agentMetricsAreNotLogged() {
- mAgentUnderTest.onCreate(
- UserHandle.SYSTEM, BackupDestination.CLOUD, OperationType.RESTORE);
- SettingsBackupAgent.SettingsBackupAllowlist allowlist =
- new SettingsBackupAgent.SettingsBackupAllowlist(
- new String[] {OVERRIDDEN_TEST_SETTING},
- TEST_VALUES_VALIDATORS);
- mAgentUnderTest.setSettingsAllowlist(allowlist);
- mAgentUnderTest.setBlockedSettings();
- TestSettingsHelper settingsHelper = new TestSettingsHelper(mContext);
- mAgentUnderTest.mSettingsHelper = settingsHelper;
-
- byte[] backupData = generateBackupData(TEST_VALUES);
- mAgentUnderTest
- .restoreSettings(
- backupData,
- /* pos= */ 0,
- backupData.length,
- TEST_URI,
- /* movedToGlobal= */ null,
- /* movedToSecure= */ null,
- /* movedToSystem= */ null,
- /* blockedSettingsArrayId= */ 0,
- /* dynamicBlockList= */ Collections.emptySet(),
- /* settingsToPreserve= */ Collections.emptySet(),
- TEST_KEY);
-
- DataTypeResult loggingResult =
- getLoggingResultForDatatype(TEST_KEY, mAgentUnderTest);
- assertNull(loggingResult);
- }
-
- @Test
- @EnableFlags(com.android.server.backup.Flags.FLAG_ENABLE_METRICS_SETTINGS_BACKUP_AGENTS)
public void restoreSettings_agentMetricsAreEnabled_readEntityDataFails_failureIsLogged()
throws IOException {
when(mBackupDataInput.readEntityData(any(byte[].class), anyInt(), anyInt()))
@@ -577,6 +508,40 @@ public class SettingsBackupAgentTest extends BaseSettingsProviderTest {
}
@Test
+ @DisableFlags(com.android.server.backup.Flags.FLAG_ENABLE_METRICS_SETTINGS_BACKUP_AGENTS)
+ public void
+ restoreSettings_agentMetricsAreDisabled_settingIsSkippedBySystem_failureIsNotLogged() {
+ mAgentUnderTest.onCreate(
+ UserHandle.SYSTEM, BackupDestination.CLOUD, OperationType.RESTORE);
+ String[] settingBlockedBySystem = new String[] {OVERRIDDEN_TEST_SETTING};
+ SettingsBackupAgent.SettingsBackupAllowlist allowlist =
+ new SettingsBackupAgent.SettingsBackupAllowlist(
+ settingBlockedBySystem,
+ TEST_VALUES_VALIDATORS);
+ mAgentUnderTest.setSettingsAllowlist(allowlist);
+ mAgentUnderTest.setBlockedSettings(settingBlockedBySystem);
+ TestSettingsHelper settingsHelper = new TestSettingsHelper(mContext);
+ mAgentUnderTest.mSettingsHelper = settingsHelper;
+
+ byte[] backupData = generateBackupData(TEST_VALUES);
+ mAgentUnderTest
+ .restoreSettings(
+ backupData,
+ /* pos= */ 0,
+ backupData.length,
+ TEST_URI,
+ /* movedToGlobal= */ null,
+ /* movedToSecure= */ null,
+ /* movedToSystem= */ null,
+ /* blockedSettingsArrayId= */ 0,
+ /* dynamicBlockList= */ Collections.emptySet(),
+ /* settingsToPreserve= */ Collections.emptySet(),
+ TEST_KEY);
+
+ assertNull(getLoggingResultForDatatype(TEST_KEY, mAgentUnderTest));
+ }
+
+ @Test
@EnableFlags(com.android.server.backup.Flags.FLAG_ENABLE_METRICS_SETTINGS_BACKUP_AGENTS)
public void restoreSettings_agentMetricsAreEnabled_settingIsSkippedByBlockList_failureIsLogged() {
mAgentUnderTest.onCreate(
@@ -615,8 +580,9 @@ public class SettingsBackupAgentTest extends BaseSettingsProviderTest {
}
@Test
- @EnableFlags(com.android.server.backup.Flags.FLAG_ENABLE_METRICS_SETTINGS_BACKUP_AGENTS)
- public void restoreSettings_agentMetricsAreEnabled_settingIsPreserved_failureIsLogged() {
+ @DisableFlags(com.android.server.backup.Flags.FLAG_ENABLE_METRICS_SETTINGS_BACKUP_AGENTS)
+ public void
+ restoreSettings_agentMetricsAreDisabled_settingIsSkippedByBlockList_failureIsNotLogged() {
mAgentUnderTest.onCreate(
UserHandle.SYSTEM, BackupDestination.CLOUD, OperationType.RESTORE);
SettingsBackupAgent.SettingsBackupAllowlist allowlist =
@@ -627,7 +593,7 @@ public class SettingsBackupAgentTest extends BaseSettingsProviderTest {
mAgentUnderTest.setBlockedSettings();
TestSettingsHelper settingsHelper = new TestSettingsHelper(mContext);
mAgentUnderTest.mSettingsHelper = settingsHelper;
- Set<String> preservedSettings =
+ Set<String> dynamicBlockList =
Set.of(Uri.withAppendedPath(TEST_URI, OVERRIDDEN_TEST_SETTING).toString());
byte[] backupData = generateBackupData(TEST_VALUES);
@@ -641,30 +607,28 @@ public class SettingsBackupAgentTest extends BaseSettingsProviderTest {
/* movedToSecure= */ null,
/* movedToSystem= */ null,
/* blockedSettingsArrayId= */ 0,
- /* dynamicBlockList = */ Collections.emptySet(),
- preservedSettings,
+ dynamicBlockList,
+ /* settingsToPreserve= */ Collections.emptySet(),
TEST_KEY);
- DataTypeResult loggingResult =
- getLoggingResultForDatatype(TEST_KEY, mAgentUnderTest);
- assertNotNull(loggingResult);
- assertEquals(loggingResult.getFailCount(), 1);
- assertTrue(loggingResult.getErrors().containsKey(ERROR_SKIPPED_PRESERVED));
+ assertNull(getLoggingResultForDatatype(TEST_KEY, mAgentUnderTest));
}
@Test
@EnableFlags(com.android.server.backup.Flags.FLAG_ENABLE_METRICS_SETTINGS_BACKUP_AGENTS)
- public void restoreSettings_agentMetricsAreEnabled_settingIsNotValid_failureIsLogged() {
+ public void restoreSettings_agentMetricsAreEnabled_settingIsPreserved_failureIsLogged() {
mAgentUnderTest.onCreate(
UserHandle.SYSTEM, BackupDestination.CLOUD, OperationType.RESTORE);
SettingsBackupAgent.SettingsBackupAllowlist allowlist =
new SettingsBackupAgent.SettingsBackupAllowlist(
new String[] {OVERRIDDEN_TEST_SETTING},
- /* settingsValidators= */ null);
+ TEST_VALUES_VALIDATORS);
mAgentUnderTest.setSettingsAllowlist(allowlist);
mAgentUnderTest.setBlockedSettings();
TestSettingsHelper settingsHelper = new TestSettingsHelper(mContext);
mAgentUnderTest.mSettingsHelper = settingsHelper;
+ Set<String> preservedSettings =
+ Set.of(Uri.withAppendedPath(TEST_URI, OVERRIDDEN_TEST_SETTING).toString());
byte[] backupData = generateBackupData(TEST_VALUES);
mAgentUnderTest
@@ -678,19 +642,19 @@ public class SettingsBackupAgentTest extends BaseSettingsProviderTest {
/* movedToSystem= */ null,
/* blockedSettingsArrayId= */ 0,
/* dynamicBlockList = */ Collections.emptySet(),
- /* settingsToPreserve= */ Collections.emptySet(),
+ preservedSettings,
TEST_KEY);
DataTypeResult loggingResult =
getLoggingResultForDatatype(TEST_KEY, mAgentUnderTest);
assertNotNull(loggingResult);
assertEquals(loggingResult.getFailCount(), 1);
- assertTrue(loggingResult.getErrors().containsKey(ERROR_DID_NOT_PASS_VALIDATION));
+ assertTrue(loggingResult.getErrors().containsKey(ERROR_SKIPPED_PRESERVED));
}
@Test
- @EnableFlags(com.android.server.backup.Flags.FLAG_ENABLE_METRICS_SETTINGS_BACKUP_AGENTS)
- public void restoreSettings_agentMetricsAreEnabled_settingIsMarkedAsMovedToGlobal_agentMetricsAreLoggedWithGlobalKey() {
+ @DisableFlags(com.android.server.backup.Flags.FLAG_ENABLE_METRICS_SETTINGS_BACKUP_AGENTS)
+ public void restoreSettings_agentMetricsAreDisabled_settingIsPreserved_failureIsNotLogged() {
mAgentUnderTest.onCreate(
UserHandle.SYSTEM, BackupDestination.CLOUD, OperationType.RESTORE);
SettingsBackupAgent.SettingsBackupAllowlist allowlist =
@@ -701,6 +665,8 @@ public class SettingsBackupAgentTest extends BaseSettingsProviderTest {
mAgentUnderTest.setBlockedSettings();
TestSettingsHelper settingsHelper = new TestSettingsHelper(mContext);
mAgentUnderTest.mSettingsHelper = settingsHelper;
+ Set<String> preservedSettings =
+ Set.of(Uri.withAppendedPath(TEST_URI, OVERRIDDEN_TEST_SETTING).toString());
byte[] backupData = generateBackupData(TEST_VALUES);
mAgentUnderTest
@@ -709,30 +675,26 @@ public class SettingsBackupAgentTest extends BaseSettingsProviderTest {
/* pos= */ 0,
backupData.length,
TEST_URI,
- /* movedToGlobal= */ Set.of(OVERRIDDEN_TEST_SETTING),
+ /* movedToGlobal= */ null,
/* movedToSecure= */ null,
/* movedToSystem= */ null,
/* blockedSettingsArrayId= */ 0,
- /* dynamicBlockList= */ Collections.emptySet(),
- /* settingsToPreserve= */ Collections.emptySet(),
+ /* dynamicBlockList = */ Collections.emptySet(),
+ preservedSettings,
TEST_KEY);
- DataTypeResult loggingResult =
- getLoggingResultForDatatype(KEY_GLOBAL, mAgentUnderTest);
- assertNotNull(loggingResult);
- assertEquals(loggingResult.getSuccessCount(), 1);
assertNull(getLoggingResultForDatatype(TEST_KEY, mAgentUnderTest));
}
@Test
@EnableFlags(com.android.server.backup.Flags.FLAG_ENABLE_METRICS_SETTINGS_BACKUP_AGENTS)
- public void restoreSettings_agentMetricsAreEnabled_settingIsMarkedAsMovedToSecure_agentMetricsAreLoggedWithSecureKey() {
+ public void restoreSettings_agentMetricsAreEnabled_settingIsNotValid_failureIsLogged() {
mAgentUnderTest.onCreate(
UserHandle.SYSTEM, BackupDestination.CLOUD, OperationType.RESTORE);
SettingsBackupAgent.SettingsBackupAllowlist allowlist =
new SettingsBackupAgent.SettingsBackupAllowlist(
new String[] {OVERRIDDEN_TEST_SETTING},
- TEST_VALUES_VALIDATORS);
+ /* settingsValidators= */ null);
mAgentUnderTest.setSettingsAllowlist(allowlist);
mAgentUnderTest.setBlockedSettings();
TestSettingsHelper settingsHelper = new TestSettingsHelper(mContext);
@@ -746,29 +708,29 @@ public class SettingsBackupAgentTest extends BaseSettingsProviderTest {
backupData.length,
TEST_URI,
/* movedToGlobal= */ null,
- /* movedToSecure= */ Set.of(OVERRIDDEN_TEST_SETTING),
+ /* movedToSecure= */ null,
/* movedToSystem= */ null,
/* blockedSettingsArrayId= */ 0,
- /* dynamicBlockList= */ Collections.emptySet(),
+ /* dynamicBlockList = */ Collections.emptySet(),
/* settingsToPreserve= */ Collections.emptySet(),
TEST_KEY);
DataTypeResult loggingResult =
- getLoggingResultForDatatype(KEY_SECURE, mAgentUnderTest);
+ getLoggingResultForDatatype(TEST_KEY, mAgentUnderTest);
assertNotNull(loggingResult);
- assertEquals(loggingResult.getSuccessCount(), 1);
- assertNull(getLoggingResultForDatatype(TEST_KEY, mAgentUnderTest));
+ assertEquals(loggingResult.getFailCount(), 1);
+ assertTrue(loggingResult.getErrors().containsKey(ERROR_DID_NOT_PASS_VALIDATION));
}
@Test
- @EnableFlags(com.android.server.backup.Flags.FLAG_ENABLE_METRICS_SETTINGS_BACKUP_AGENTS)
- public void restoreSettings_agentMetricsAreEnabled_settingIsMarkedAsMovedToSystem_agentMetricsAreLoggedWithSystemKey() {
+ @DisableFlags(com.android.server.backup.Flags.FLAG_ENABLE_METRICS_SETTINGS_BACKUP_AGENTS)
+ public void restoreSettings_agentMetricsAreDisabled_settingIsNotValid_failureIsNotLogged() {
mAgentUnderTest.onCreate(
UserHandle.SYSTEM, BackupDestination.CLOUD, OperationType.RESTORE);
SettingsBackupAgent.SettingsBackupAllowlist allowlist =
new SettingsBackupAgent.SettingsBackupAllowlist(
new String[] {OVERRIDDEN_TEST_SETTING},
- TEST_VALUES_VALIDATORS);
+ /* settingsValidators= */ null);
mAgentUnderTest.setSettingsAllowlist(allowlist);
mAgentUnderTest.setBlockedSettings();
TestSettingsHelper settingsHelper = new TestSettingsHelper(mContext);
@@ -783,16 +745,12 @@ public class SettingsBackupAgentTest extends BaseSettingsProviderTest {
TEST_URI,
/* movedToGlobal= */ null,
/* movedToSecure= */ null,
- /* movedToSystem= */ Set.of(OVERRIDDEN_TEST_SETTING),
+ /* movedToSystem= */ null,
/* blockedSettingsArrayId= */ 0,
- /* dynamicBlockList= */ Collections.emptySet(),
+ /* dynamicBlockList = */ Collections.emptySet(),
/* settingsToPreserve= */ Collections.emptySet(),
TEST_KEY);
- DataTypeResult loggingResult =
- getLoggingResultForDatatype(KEY_SYSTEM, mAgentUnderTest);
- assertNotNull(loggingResult);
- assertEquals(loggingResult.getSuccessCount(), 1);
assertNull(getLoggingResultForDatatype(TEST_KEY, mAgentUnderTest));
}
diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsHelperTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsHelperTest.java
index 58200d4f6553..40654b0e2f37 100644
--- a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsHelperTest.java
+++ b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsHelperTest.java
@@ -28,6 +28,9 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
+import android.app.backup.BackupAnnotations.OperationType;
+import android.app.backup.BackupRestoreEventLogger;
+import android.app.backup.BackupRestoreEventLogger.DataTypeResult;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.Context;
@@ -42,6 +45,7 @@ import android.media.Utils;
import android.net.Uri;
import android.os.Bundle;
import android.os.LocaleList;
+import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.BaseColumns;
@@ -65,6 +69,8 @@ import org.junit.runner.RunWith;
import org.junit.runners.MethodSorters;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
/**
* Tests for the SettingsHelperTest
@@ -91,6 +97,8 @@ public class SettingsHelperTest {
@Rule
public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+ @Rule
+ public MockitoRule mockitoRule = MockitoJUnit.rule();
@Mock private Context mContext;
@Mock private Resources mResources;
@@ -100,6 +108,8 @@ public class SettingsHelperTest {
@Mock private MockContentResolver mContentResolver;
private MockSettingsProvider mSettingsProvider;
+ private BackupRestoreEventLogger mBackupRestoreEventLogger;
+
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
@@ -115,6 +125,8 @@ public class SettingsHelperTest {
when(mContext.getContentResolver()).thenReturn(mContentResolver);
mSettingsProvider = new MockSettingsProvider(mContext);
mContentResolver.addProvider(Settings.AUTHORITY, mSettingsProvider);
+ mBackupRestoreEventLogger = new BackupRestoreEventLogger(OperationType.RESTORE);
+ mSettingsHelper.setBackupRestoreEventLogger(mBackupRestoreEventLogger);
}
@After
@@ -791,6 +803,99 @@ public class SettingsHelperTest {
assertThat(mSettingsHelper.getLocaleList()).isEqualTo(LOCALE_LIST);
}
+ @Test
+ @EnableFlags(com.android.server.backup.Flags.FLAG_ENABLE_METRICS_SETTINGS_BACKUP_AGENTS)
+ public void
+ restoreValue_metricsFlagIsEnabled_restoresSetting_secureUri_logsSuccessWithSecureDatatype()
+ {
+ mSettingsHelper.restoreValue(
+ mContext,
+ mContentResolver,
+ new ContentValues(),
+ Settings.Secure.CONTENT_URI,
+ SETTING_KEY,
+ SETTING_VALUE,
+ /* restoredFromSdkInt */ 0);
+
+ DataTypeResult loggingResult =
+ getLoggingResultForDatatype(SettingsBackupRestoreKeys.KEY_SECURE);
+ assertThat(loggingResult).isNotNull();
+ assertThat(loggingResult.getSuccessCount()).isEqualTo(1);
+ }
+
+ @Test
+ @EnableFlags(com.android.server.backup.Flags.FLAG_ENABLE_METRICS_SETTINGS_BACKUP_AGENTS)
+ public void
+ restoreValue_metricsFlagIsEnabled_restoresSetting_systemUri_logsSuccessWithSystemDatatype()
+ {
+ mSettingsHelper.restoreValue(
+ mContext,
+ mContentResolver,
+ new ContentValues(),
+ Settings.System.CONTENT_URI,
+ SETTING_KEY,
+ SETTING_VALUE,
+ /* restoredFromSdkInt */ 0);
+
+ DataTypeResult loggingResult =
+ getLoggingResultForDatatype(SettingsBackupRestoreKeys.KEY_SYSTEM);
+ assertThat(loggingResult).isNotNull();
+ assertThat(loggingResult.getSuccessCount()).isEqualTo(1);
+ }
+
+ @Test
+ @EnableFlags(com.android.server.backup.Flags.FLAG_ENABLE_METRICS_SETTINGS_BACKUP_AGENTS)
+ public void
+ restoreValue_metricsFlagIsEnabled_restoresSetting_globalUri_logsSuccessWithGlobalDatatype()
+ {
+ mSettingsHelper.restoreValue(
+ mContext,
+ mContentResolver,
+ new ContentValues(),
+ Settings.Global.CONTENT_URI,
+ SETTING_KEY,
+ SETTING_VALUE,
+ /* restoredFromSdkInt */ 0);
+
+ DataTypeResult loggingResult =
+ getLoggingResultForDatatype(SettingsBackupRestoreKeys.KEY_GLOBAL);
+ assertThat(loggingResult).isNotNull();
+ assertThat(loggingResult.getSuccessCount()).isEqualTo(1);
+ }
+
+ @Test
+ @EnableFlags(com.android.server.backup.Flags.FLAG_ENABLE_METRICS_SETTINGS_BACKUP_AGENTS)
+ public void restoreValue_metricsFlagIsEnabled_doesNotRestoreSetting_logsFailure() {
+ mSettingsHelper.restoreValue(
+ mContext,
+ mContentResolver,
+ new ContentValues(),
+ Uri.EMPTY,
+ SETTING_KEY,
+ SETTING_VALUE,
+ /* restoredFromSdkInt */ 0);
+
+ DataTypeResult loggingResult =
+ getLoggingResultForDatatype(SettingsBackupRestoreKeys.KEY_UNKNOWN);
+ assertThat(loggingResult).isNotNull();
+ assertThat(loggingResult.getFailCount()).isEqualTo(1);
+ }
+
+ @Test
+ @DisableFlags(com.android.server.backup.Flags.FLAG_ENABLE_METRICS_SETTINGS_BACKUP_AGENTS)
+ public void restoreValue_metricsFlagIsDisabled_doesNotLogMetrics() {
+ mSettingsHelper.restoreValue(
+ mContext,
+ mContentResolver,
+ new ContentValues(),
+ Uri.EMPTY,
+ SETTING_KEY,
+ SETTING_VALUE,
+ /* restoredFromSdkInt */ 0);
+
+ assertThat(getLoggingResultForDatatype(SettingsBackupRestoreKeys.KEY_UNKNOWN)).isNull();
+ }
+
private int getAutoRotationSettingValue() {
return Settings.System.getInt(mContentResolver,
Settings.System.ACCELEROMETER_ROTATION,
@@ -851,4 +956,13 @@ public class SettingsHelperTest {
assertThat(Settings.System.getString(mContentResolver, settings))
.isEqualTo(testRingtoneSettingsValue);
}
+
+ private DataTypeResult getLoggingResultForDatatype(String dataType) {
+ for (DataTypeResult result : mBackupRestoreEventLogger.getLoggingResults()) {
+ if (result.getDataType().equals(dataType)) {
+ return result;
+ }
+ }
+ return null;
+ }
}
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/gesture/NestedDraggable.kt b/packages/SystemUI/compose/core/src/com/android/compose/gesture/NestedDraggable.kt
index 029b9cde4da9..35e85a0aa615 100644
--- a/packages/SystemUI/compose/core/src/com/android/compose/gesture/NestedDraggable.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/gesture/NestedDraggable.kt
@@ -41,6 +41,7 @@ import androidx.compose.ui.input.pointer.SuspendingPointerInputModifierNode
import androidx.compose.ui.input.pointer.changedToDownIgnoreConsumed
import androidx.compose.ui.input.pointer.changedToUpIgnoreConsumed
import androidx.compose.ui.input.pointer.positionChange
+import androidx.compose.ui.input.pointer.positionChangeIgnoreConsumed
import androidx.compose.ui.input.pointer.util.VelocityTracker
import androidx.compose.ui.input.pointer.util.addPointerInputChange
import androidx.compose.ui.node.CompositionLocalConsumerModifierNode
@@ -55,8 +56,7 @@ import androidx.compose.ui.util.fastAny
import androidx.compose.ui.util.fastSumBy
import com.android.compose.modifiers.thenIf
import kotlin.math.sign
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.CoroutineStart
+import kotlinx.coroutines.async
import kotlinx.coroutines.launch
/**
@@ -67,6 +67,16 @@ import kotlinx.coroutines.launch
*/
interface NestedDraggable {
/**
+ * Return whether we should start a drag given the pointer [change].
+ *
+ * This is called when the touch slop is reached. If this returns `true`, then the [change] will
+ * be consumed and [onDragStarted] will be called. If this returns `false`, then the current
+ * touch slop detection will be reset and restarted at the current
+ * [change position][PointerInputChange.position].
+ */
+ fun shouldStartDrag(change: PointerInputChange): Boolean = true
+
+ /**
* Called when a drag is started in the given [position] (*before* dragging the touch slop) and
* in the direction given by [sign], with the given number of [pointersDown] when the touch slop
* was detected.
@@ -161,11 +171,7 @@ private class NestedDraggableNode(
}
/** The controller created by the nested scroll logic (and *not* the drag logic). */
- private var nestedScrollController: WrappedController? = null
- set(value) {
- field?.ensureOnDragStoppedIsCalled()
- field = value
- }
+ private var nestedScrollController: NestedScrollController? = null
/**
* The last pointer which was the first down since the last time all pointers were up.
@@ -183,6 +189,7 @@ private class NestedDraggableNode(
override fun onDetach() {
nestedScrollController?.ensureOnDragStoppedIsCalled()
+ nestedScrollController = null
}
fun update(
@@ -199,6 +206,7 @@ private class NestedDraggableNode(
trackDownPositionDelegate?.resetPointerInputHandler()
detectDragsDelegate?.resetPointerInputHandler()
nestedScrollController?.ensureOnDragStoppedIsCalled()
+ nestedScrollController = null
if (!enabled && trackDownPositionDelegate != null) {
check(detectDragsDelegate != null)
@@ -248,8 +256,14 @@ private class NestedDraggableNode(
var overSlop = 0f
val onTouchSlopReached = { change: PointerInputChange, over: Float ->
- change.consume()
- overSlop = over
+ if (draggable.shouldStartDrag(change)) {
+ change.consume()
+ overSlop = over
+ }
+
+ // If shouldStartDrag() returned false, then we didn't consume the event and
+ // awaitTouchSlopOrCancellation() will reset the touch slop detector so that the
+ // user has to drag by at least the touch slop again.
}
suspend fun AwaitPointerEventScope.awaitTouchSlopOrCancellation(
@@ -288,15 +302,21 @@ private class NestedDraggableNode(
if (drag != null) {
velocityTracker.resetTracking()
- val sign = (drag.position - down.position).toFloat().sign
+ val sign = drag.positionChangeIgnoreConsumed().toFloat().sign
+ check(sign != 0f) {
+ buildString {
+ append("sign is equal to 0 ")
+ append("touchSlop ${currentValueOf(LocalViewConfiguration).touchSlop} ")
+ append("down.position ${down.position} ")
+ append("drag.position ${drag.position} ")
+ append("drag.previousPosition ${drag.previousPosition}")
+ }
+ }
+
check(pointersDownCount > 0) { "pointersDownCount is equal to $pointersDownCount" }
- val wrappedController =
- WrappedController(
- coroutineScope,
- draggable.onDragStarted(down.position, sign, pointersDownCount),
- )
+ val controller = draggable.onDragStarted(down.position, sign, pointersDownCount)
if (overSlop != 0f) {
- onDrag(wrappedController, drag, overSlop, velocityTracker)
+ onDrag(controller, drag, overSlop, velocityTracker)
}
// If a drag was started, we cancel any other drag started by a nested scrollable.
@@ -304,12 +324,13 @@ private class NestedDraggableNode(
// Note: we cancel the nested drag here *after* starting the new drag so that in the
// STL case, the cancelled drag will not change the current scene of the STL.
nestedScrollController?.ensureOnDragStoppedIsCalled()
+ nestedScrollController = null
val isSuccessful =
try {
val onDrag = { change: PointerInputChange ->
onDrag(
- wrappedController,
+ controller,
change,
change.positionChange().toFloat(),
velocityTracker,
@@ -322,19 +343,17 @@ private class NestedDraggableNode(
Orientation.Vertical -> verticalDrag(drag.id, onDrag)
}
} catch (t: Throwable) {
- wrappedController.ensureOnDragStoppedIsCalled()
+ onDragStopped(controller, Velocity.Zero)
throw t
}
if (isSuccessful) {
val maxVelocity = currentValueOf(LocalViewConfiguration).maximumFlingVelocity
val velocity =
- velocityTracker
- .calculateVelocity(Velocity(maxVelocity, maxVelocity))
- .toFloat()
- onDragStopped(wrappedController, velocity)
+ velocityTracker.calculateVelocity(Velocity(maxVelocity, maxVelocity))
+ onDragStopped(controller, velocity)
} else {
- onDragStopped(wrappedController, velocity = 0f)
+ onDragStopped(controller, Velocity.Zero)
}
}
}
@@ -348,88 +367,87 @@ private class NestedDraggableNode(
) {
velocityTracker.addPointerInputChange(change)
- scrollWithOverscroll(delta) { deltaFromOverscroll ->
+ scrollWithOverscroll(delta.toOffset()) { deltaFromOverscroll ->
scrollWithNestedScroll(deltaFromOverscroll) { deltaFromNestedScroll ->
- controller.onDrag(deltaFromNestedScroll)
+ controller.onDrag(deltaFromNestedScroll.toFloat()).toOffset()
}
}
}
- private fun onDragStopped(controller: WrappedController, velocity: Float) {
- coroutineScope.launch(start = CoroutineStart.UNDISPATCHED) {
- try {
- flingWithOverscroll(velocity) { velocityFromOverscroll ->
- flingWithNestedScroll(velocityFromOverscroll) { velocityFromNestedScroll ->
- controller.onDragStopped(velocityFromNestedScroll)
- }
+ private fun onDragStopped(controller: NestedDraggable.Controller, velocity: Velocity) {
+ // We launch in the scope of the dispatcher so that the fling is not cancelled if this node
+ // is removed right after onDragStopped() is called.
+ nestedScrollDispatcher.coroutineScope.launch {
+ flingWithOverscroll(velocity) { velocityFromOverscroll ->
+ flingWithNestedScroll(velocityFromOverscroll) { velocityFromNestedScroll ->
+ controller.onDragStopped(velocityFromNestedScroll.toFloat()).toVelocity()
}
- } finally {
- controller.ensureOnDragStoppedIsCalled()
}
}
}
- private fun scrollWithOverscroll(delta: Float, performScroll: (Float) -> Float): Float {
+ private fun scrollWithOverscroll(delta: Offset, performScroll: (Offset) -> Offset): Offset {
val effect = overscrollEffect
return if (effect != null) {
- effect
- .applyToScroll(delta.toOffset(), source = NestedScrollSource.UserInput) {
- performScroll(it.toFloat()).toOffset()
- }
- .toFloat()
+ effect.applyToScroll(delta, source = NestedScrollSource.UserInput) { performScroll(it) }
} else {
performScroll(delta)
}
}
- private fun scrollWithNestedScroll(delta: Float, performScroll: (Float) -> Float): Float {
+ private fun scrollWithNestedScroll(delta: Offset, performScroll: (Offset) -> Offset): Offset {
val preConsumed =
- nestedScrollDispatcher
- .dispatchPreScroll(
- available = delta.toOffset(),
- source = NestedScrollSource.UserInput,
- )
- .toFloat()
+ nestedScrollDispatcher.dispatchPreScroll(
+ available = delta,
+ source = NestedScrollSource.UserInput,
+ )
val available = delta - preConsumed
val consumed = performScroll(available)
val left = available - consumed
val postConsumed =
- nestedScrollDispatcher
- .dispatchPostScroll(
- consumed = (preConsumed + consumed).toOffset(),
- available = left.toOffset(),
- source = NestedScrollSource.UserInput,
- )
- .toFloat()
+ nestedScrollDispatcher.dispatchPostScroll(
+ consumed = preConsumed + consumed,
+ available = left,
+ source = NestedScrollSource.UserInput,
+ )
return consumed + preConsumed + postConsumed
}
private suspend fun flingWithOverscroll(
- velocity: Float,
- performFling: suspend (Float) -> Float,
- ) {
+ velocity: Velocity,
+ performFling: suspend (Velocity) -> Velocity,
+ ): Velocity {
val effect = overscrollEffect
- if (effect != null) {
- effect.applyToFling(velocity.toVelocity()) { performFling(it.toFloat()).toVelocity() }
+ return flingWithOverscroll(effect, velocity, performFling)
+ }
+
+ private suspend fun flingWithOverscroll(
+ overscrollEffect: OverscrollEffect?,
+ velocity: Velocity,
+ performFling: suspend (Velocity) -> Velocity,
+ ): Velocity {
+ return if (overscrollEffect != null) {
+ overscrollEffect.applyToFling(velocity) { performFling(it) }
+
+ // Effects always consume the whole velocity.
+ velocity
} else {
performFling(velocity)
}
}
private suspend fun flingWithNestedScroll(
- velocity: Float,
- performFling: suspend (Float) -> Float,
- ): Float {
- val preConsumed = nestedScrollDispatcher.dispatchPreFling(available = velocity.toVelocity())
- val available = velocity - preConsumed.toFloat()
+ velocity: Velocity,
+ performFling: suspend (Velocity) -> Velocity,
+ ): Velocity {
+ val preConsumed = nestedScrollDispatcher.dispatchPreFling(available = velocity)
+ val available = velocity - preConsumed
val consumed = performFling(available)
val left = available - consumed
- return nestedScrollDispatcher
- .dispatchPostFling(
- consumed = consumed.toVelocity() + preConsumed,
- available = left.toVelocity(),
- )
- .toFloat()
+ return nestedScrollDispatcher.dispatchPostFling(
+ consumed = consumed + preConsumed,
+ available = left,
+ )
}
/*
@@ -459,8 +477,7 @@ private class NestedDraggableNode(
override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
val controller = nestedScrollController ?: return Offset.Zero
- val consumed = controller.onDrag(available.toFloat())
- return consumed.toOffset()
+ return scrollWithOverscroll(controller, available)
}
override fun onPostScroll(
@@ -485,49 +502,43 @@ private class NestedDraggableNode(
// TODO(b/382665591): Replace this by check(pointersDownCount > 0).
val pointersDown = pointersDownCount.coerceAtLeast(1)
nestedScrollController =
- WrappedController(
- coroutineScope,
+ NestedScrollController(
+ overscrollEffect,
draggable.onDragStarted(startedPosition, sign, pointersDown),
)
}
val controller = nestedScrollController ?: return Offset.Zero
- return controller.onDrag(offset).toOffset()
+ return scrollWithOverscroll(controller, available)
+ }
+
+ private fun scrollWithOverscroll(controller: NestedScrollController, offset: Offset): Offset {
+ return scrollWithOverscroll(offset) {
+ controller.controller.onDrag(it.toFloat()).toOffset()
+ }
}
override suspend fun onPreFling(available: Velocity): Velocity {
val controller = nestedScrollController ?: return Velocity.Zero
nestedScrollController = null
- val consumed = controller.onDragStopped(available.toFloat())
- return consumed.toVelocity()
+ return nestedScrollDispatcher.coroutineScope
+ .async { controller.flingWithOverscroll(available) }
+ .await()
}
-}
-/**
- * A controller that wraps [delegate] and can be used to ensure that [onDragStopped] is called, but
- * not more than once.
- */
-private class WrappedController(
- private val coroutineScope: CoroutineScope,
- private val delegate: NestedDraggable.Controller,
-) : NestedDraggable.Controller by delegate {
- private var onDragStoppedCalled = false
-
- override fun onDrag(delta: Float): Float {
- if (onDragStoppedCalled) return 0f
- return delegate.onDrag(delta)
- }
-
- override suspend fun onDragStopped(velocity: Float): Float {
- if (onDragStoppedCalled) return 0f
- onDragStoppedCalled = true
- return delegate.onDragStopped(velocity)
- }
+ private inner class NestedScrollController(
+ private val overscrollEffect: OverscrollEffect?,
+ val controller: NestedDraggable.Controller,
+ ) {
+ fun ensureOnDragStoppedIsCalled() {
+ nestedScrollDispatcher.coroutineScope.launch { flingWithOverscroll(Velocity.Zero) }
+ }
- fun ensureOnDragStoppedIsCalled() {
- // Start with UNDISPATCHED so that onDragStopped() is always run until its first suspension
- // point, even if coroutineScope is cancelled.
- coroutineScope.launch(start = CoroutineStart.UNDISPATCHED) { onDragStopped(velocity = 0f) }
+ suspend fun flingWithOverscroll(velocity: Velocity): Velocity {
+ return flingWithOverscroll(overscrollEffect, velocity) {
+ controller.onDragStopped(it.toFloat()).toVelocity()
+ }
+ }
}
}
diff --git a/packages/SystemUI/compose/core/tests/src/com/android/compose/gesture/NestedDraggableTest.kt b/packages/SystemUI/compose/core/tests/src/com/android/compose/gesture/NestedDraggableTest.kt
index 735ab68bc6a6..f98b090e77fd 100644
--- a/packages/SystemUI/compose/core/tests/src/com/android/compose/gesture/NestedDraggableTest.kt
+++ b/packages/SystemUI/compose/core/tests/src/com/android/compose/gesture/NestedDraggableTest.kt
@@ -32,6 +32,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
import androidx.compose.ui.input.nestedscroll.nestedScroll
+import androidx.compose.ui.input.pointer.PointerInputChange
import androidx.compose.ui.platform.LocalViewConfiguration
import androidx.compose.ui.test.junit4.ComposeContentTestRule
import androidx.compose.ui.test.junit4.createComposeRule
@@ -42,7 +43,8 @@ import androidx.compose.ui.test.swipeLeft
import androidx.compose.ui.unit.Velocity
import com.google.common.truth.Truth.assertThat
import kotlin.math.ceil
-import kotlinx.coroutines.awaitCancellation
+import kotlinx.coroutines.CompletableDeferred
+import kotlinx.coroutines.delay
import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
@@ -62,9 +64,10 @@ class NestedDraggableTest(override val orientation: Orientation) : OrientationAw
@Test
fun simpleDrag() {
val draggable = TestDraggable()
+ val effect = TestOverscrollEffect(orientation) { 0f }
val touchSlop =
rule.setContentWithTouchSlop {
- Box(Modifier.fillMaxSize().nestedDraggable(draggable, orientation))
+ Box(Modifier.fillMaxSize().nestedDraggable(draggable, orientation, effect))
}
assertThat(draggable.onDragStartedCalled).isFalse()
@@ -89,6 +92,7 @@ class NestedDraggableTest(override val orientation: Orientation) : OrientationAw
assertThat(draggable.onDragDelta).isEqualTo(30f)
assertThat(draggable.onDragStoppedCalled).isFalse()
+ assertThat(effect.applyToFlingDone).isFalse()
rule.onRoot().performTouchInput {
moveBy((-15f).toOffset())
@@ -97,16 +101,18 @@ class NestedDraggableTest(override val orientation: Orientation) : OrientationAw
assertThat(draggable.onDragDelta).isEqualTo(15f)
assertThat(draggable.onDragStoppedCalled).isTrue()
+ assertThat(effect.applyToFlingDone).isTrue()
}
@Test
fun nestedScrollable() {
val draggable = TestDraggable()
+ val effect = TestOverscrollEffect(orientation) { 0f }
val touchSlop =
rule.setContentWithTouchSlop {
Box(
Modifier.fillMaxSize()
- .nestedDraggable(draggable, orientation)
+ .nestedDraggable(draggable, orientation, effect)
.nestedScrollable(rememberScrollState())
)
}
@@ -135,6 +141,7 @@ class NestedDraggableTest(override val orientation: Orientation) : OrientationAw
assertThat(draggable.onDragCalled).isTrue()
assertThat(draggable.onDragDelta).isEqualTo(-30f)
assertThat(draggable.onDragStoppedCalled).isFalse()
+ assertThat(effect.applyToFlingDone).isFalse()
rule.onRoot().performTouchInput {
moveBy(15f.toOffset())
@@ -145,15 +152,17 @@ class NestedDraggableTest(override val orientation: Orientation) : OrientationAw
assertThat(draggable.onDragCalled).isTrue()
assertThat(draggable.onDragDelta).isEqualTo(-15f)
assertThat(draggable.onDragStoppedCalled).isTrue()
+ assertThat(effect.applyToFlingDone).isTrue()
}
@Test
fun onDragStoppedIsCalledWhenDraggableIsUpdatedAndReset() {
val draggable = TestDraggable()
+ val effect = TestOverscrollEffect(orientation) { 0f }
var orientation by mutableStateOf(orientation)
val touchSlop =
rule.setContentWithTouchSlop {
- Box(Modifier.fillMaxSize().nestedDraggable(draggable, orientation))
+ Box(Modifier.fillMaxSize().nestedDraggable(draggable, orientation, effect))
}
assertThat(draggable.onDragStartedCalled).isFalse()
@@ -165,6 +174,7 @@ class NestedDraggableTest(override val orientation: Orientation) : OrientationAw
assertThat(draggable.onDragStartedCalled).isTrue()
assertThat(draggable.onDragStoppedCalled).isFalse()
+ assertThat(effect.applyToFlingDone).isFalse()
orientation =
when (orientation) {
@@ -173,17 +183,19 @@ class NestedDraggableTest(override val orientation: Orientation) : OrientationAw
}
rule.waitForIdle()
assertThat(draggable.onDragStoppedCalled).isTrue()
+ assertThat(effect.applyToFlingDone).isTrue()
}
@Test
fun onDragStoppedIsCalledWhenDraggableIsUpdatedAndReset_nestedScroll() {
val draggable = TestDraggable()
+ val effect = TestOverscrollEffect(orientation) { 0f }
var orientation by mutableStateOf(orientation)
val touchSlop =
rule.setContentWithTouchSlop {
Box(
Modifier.fillMaxSize()
- .nestedDraggable(draggable, orientation)
+ .nestedDraggable(draggable, orientation, effect)
.nestedScrollable(rememberScrollState())
)
}
@@ -197,6 +209,7 @@ class NestedDraggableTest(override val orientation: Orientation) : OrientationAw
assertThat(draggable.onDragStartedCalled).isTrue()
assertThat(draggable.onDragStoppedCalled).isFalse()
+ assertThat(effect.applyToFlingDone).isFalse()
orientation =
when (orientation) {
@@ -205,16 +218,34 @@ class NestedDraggableTest(override val orientation: Orientation) : OrientationAw
}
rule.waitForIdle()
assertThat(draggable.onDragStoppedCalled).isTrue()
+ assertThat(effect.applyToFlingDone).isTrue()
}
@Test
fun onDragStoppedIsCalledWhenDraggableIsRemovedDuringDrag() {
val draggable = TestDraggable()
+ val postFlingDelay = 10 * 16L
+ val effect =
+ TestOverscrollEffect(
+ orientation,
+ onPostFling = {
+ // We delay the fling so that we can check that the draggable node methods are
+ // still called until completion even when the node is removed.
+ delay(postFlingDelay)
+ it
+ },
+ ) {
+ 0f
+ }
var composeContent by mutableStateOf(true)
val touchSlop =
rule.setContentWithTouchSlop {
- if (composeContent) {
- Box(Modifier.fillMaxSize().nestedDraggable(draggable, orientation))
+ // We add an empty nested scroll connection here from which the scope will be used
+ // when dispatching the flings.
+ Box(Modifier.nestedScroll(remember { object : NestedScrollConnection {} })) {
+ if (composeContent) {
+ Box(Modifier.fillMaxSize().nestedDraggable(draggable, orientation, effect))
+ }
}
}
@@ -227,24 +258,44 @@ class NestedDraggableTest(override val orientation: Orientation) : OrientationAw
assertThat(draggable.onDragStartedCalled).isTrue()
assertThat(draggable.onDragStoppedCalled).isFalse()
+ assertThat(effect.applyToFlingDone).isFalse()
composeContent = false
rule.waitForIdle()
+ rule.mainClock.advanceTimeBy(postFlingDelay)
assertThat(draggable.onDragStoppedCalled).isTrue()
+ assertThat(effect.applyToFlingDone).isTrue()
}
@Test
fun onDragStoppedIsCalledWhenDraggableIsRemovedDuringDrag_nestedScroll() {
val draggable = TestDraggable()
+ val postFlingDelay = 10 * 16L
+ val effect =
+ TestOverscrollEffect(
+ orientation,
+ onPostFling = {
+ // We delay the fling so that we can check that the draggable node methods are
+ // still called until completion even when the node is removed.
+ delay(postFlingDelay)
+ it
+ },
+ ) {
+ 0f
+ }
var composeContent by mutableStateOf(true)
val touchSlop =
rule.setContentWithTouchSlop {
- if (composeContent) {
- Box(
- Modifier.fillMaxSize()
- .nestedDraggable(draggable, orientation)
- .nestedScrollable(rememberScrollState())
- )
+ // We add an empty nested scroll connection here from which the scope will be used
+ // when dispatching the flings.
+ Box(Modifier.nestedScroll(remember { object : NestedScrollConnection {} })) {
+ if (composeContent) {
+ Box(
+ Modifier.fillMaxSize()
+ .nestedDraggable(draggable, orientation, effect)
+ .nestedScrollable(rememberScrollState())
+ )
+ }
}
}
@@ -257,17 +308,22 @@ class NestedDraggableTest(override val orientation: Orientation) : OrientationAw
assertThat(draggable.onDragStartedCalled).isTrue()
assertThat(draggable.onDragStoppedCalled).isFalse()
+ assertThat(effect.applyToFlingDone).isFalse()
composeContent = false
rule.waitForIdle()
+ rule.mainClock.advanceTimeBy(postFlingDelay)
assertThat(draggable.onDragStoppedCalled).isTrue()
+ assertThat(effect.applyToFlingDone).isTrue()
}
@Test
fun onDragStoppedIsCalledWhenDraggableIsRemovedDuringFling() {
val draggable = TestDraggable()
+ val effect = TestOverscrollEffect(orientation) { 0f }
var composeContent by mutableStateOf(true)
var preFlingCalled = false
+ val unblockPrefling = CompletableDeferred<Velocity>()
rule.setContent {
if (composeContent) {
Box(
@@ -281,12 +337,12 @@ class NestedDraggableTest(override val orientation: Orientation) : OrientationAw
object : NestedScrollConnection {
override suspend fun onPreFling(available: Velocity): Velocity {
preFlingCalled = true
- awaitCancellation()
+ return unblockPrefling.await()
}
}
}
)
- .nestedDraggable(draggable, orientation)
+ .nestedDraggable(draggable, orientation, effect)
)
}
}
@@ -303,11 +359,14 @@ class NestedDraggableTest(override val orientation: Orientation) : OrientationAw
assertThat(draggable.onDragStartedCalled).isTrue()
assertThat(draggable.onDragStoppedCalled).isFalse()
+ assertThat(effect.applyToFlingDone).isFalse()
assertThat(preFlingCalled).isTrue()
composeContent = false
+ unblockPrefling.complete(Velocity.Zero)
rule.waitForIdle()
assertThat(draggable.onDragStoppedCalled).isTrue()
+ assertThat(effect.applyToFlingDone).isTrue()
}
@Test
@@ -457,6 +516,83 @@ class NestedDraggableTest(override val orientation: Orientation) : OrientationAw
assertThat(draggable.onDragStartedPointersDown).isEqualTo(6)
}
+ @Test
+ fun shouldStartDrag() {
+ val draggable = TestDraggable()
+ val touchSlop =
+ rule.setContentWithTouchSlop {
+ Box(Modifier.fillMaxSize().nestedDraggable(draggable, orientation))
+ }
+
+ // Drag in one direction.
+ draggable.shouldStartDrag = false
+ rule.onRoot().performTouchInput {
+ down(center)
+ moveBy(touchSlop.toOffset())
+ }
+ assertThat(draggable.onDragStartedCalled).isFalse()
+
+ // Drag in the other direction.
+ draggable.shouldStartDrag = true
+ rule.onRoot().performTouchInput { moveBy(-touchSlop.toOffset()) }
+ assertThat(draggable.onDragStartedCalled).isTrue()
+ assertThat(draggable.onDragStartedSign).isEqualTo(-1f)
+ assertThat(draggable.onDragDelta).isEqualTo(0f)
+ }
+
+ @Test
+ fun overscrollEffectIsUsedDuringNestedScroll() {
+ var consumeDrag = true
+ var consumedByDrag = 0f
+ var consumedByEffect = 0f
+ val draggable =
+ TestDraggable(
+ onDrag = {
+ if (consumeDrag) {
+ consumedByDrag += it
+ it
+ } else {
+ 0f
+ }
+ }
+ )
+ val effect =
+ TestOverscrollEffect(orientation) { delta ->
+ /* Consumes everything. */
+ consumedByEffect += delta
+ delta
+ }
+
+ val touchSlop =
+ rule.setContentWithTouchSlop {
+ Box(
+ Modifier.fillMaxSize()
+ .nestedDraggable(draggable, orientation, overscrollEffect = effect)
+ .nestedScrollable(rememberScrollState())
+ )
+ }
+
+ // Swipe on the nested scroll. The draggable consumes the scrolls.
+ rule.onRoot().performTouchInput {
+ down(center)
+ moveBy((touchSlop + 10f).toOffset())
+ }
+ assertThat(draggable.onDragStartedCalled).isTrue()
+ assertThat(consumedByDrag).isEqualTo(10f)
+ assertThat(consumedByEffect).isEqualTo(0f)
+
+ // Stop consuming the scrolls in the draggable. The overscroll effect should now consume
+ // the scrolls.
+ consumeDrag = false
+ rule.onRoot().performTouchInput { moveBy(20f.toOffset()) }
+ assertThat(consumedByDrag).isEqualTo(10f)
+ assertThat(consumedByEffect).isEqualTo(20f)
+
+ assertThat(effect.applyToFlingDone).isFalse()
+ rule.onRoot().performTouchInput { up() }
+ assertThat(effect.applyToFlingDone).isTrue()
+ }
+
private fun ComposeContentTestRule.setContentWithTouchSlop(
content: @Composable () -> Unit
): Float {
@@ -481,6 +617,7 @@ class NestedDraggableTest(override val orientation: Orientation) : OrientationAw
private val onDragStopped: suspend (Float) -> Float = { it },
private val shouldConsumeNestedScroll: (Float) -> Boolean = { true },
) : NestedDraggable {
+ var shouldStartDrag = true
var onDragStartedCalled = false
var onDragCalled = false
var onDragStoppedCalled = false
@@ -490,6 +627,8 @@ class NestedDraggableTest(override val orientation: Orientation) : OrientationAw
var onDragStartedPointersDown = 0
var onDragDelta = 0f
+ override fun shouldStartDrag(change: PointerInputChange): Boolean = shouldStartDrag
+
override fun onDragStarted(
position: Offset,
sign: Float,
diff --git a/packages/SystemUI/compose/core/tests/src/com/android/compose/gesture/TestOverscrollEffect.kt b/packages/SystemUI/compose/core/tests/src/com/android/compose/gesture/TestOverscrollEffect.kt
new file mode 100644
index 000000000000..8bf9c21639f4
--- /dev/null
+++ b/packages/SystemUI/compose/core/tests/src/com/android/compose/gesture/TestOverscrollEffect.kt
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.compose.gesture
+
+import androidx.compose.foundation.OverscrollEffect
+import androidx.compose.foundation.gestures.Orientation
+import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.input.nestedscroll.NestedScrollSource
+import androidx.compose.ui.unit.Velocity
+
+class TestOverscrollEffect(
+ override val orientation: Orientation,
+ private val onPostFling: suspend (Float) -> Float = { it },
+ private val onPostScroll: (Float) -> Float,
+) : OverscrollEffect, OrientationAware {
+ override val isInProgress: Boolean = false
+ var applyToFlingDone = false
+ private set
+
+ override fun applyToScroll(
+ delta: Offset,
+ source: NestedScrollSource,
+ performScroll: (Offset) -> Offset,
+ ): Offset {
+ val consumedByScroll = performScroll(delta)
+ val available = delta - consumedByScroll
+ val consumedByEffect = onPostScroll(available.toFloat()).toOffset()
+ return consumedByScroll + consumedByEffect
+ }
+
+ override suspend fun applyToFling(
+ velocity: Velocity,
+ performFling: suspend (Velocity) -> Velocity,
+ ) {
+ val consumedByFling = performFling(velocity)
+ val available = velocity - consumedByFling
+ onPostFling(available.toFloat())
+ applyToFlingDone = true
+ }
+}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt
index beaf9631ae5a..9ab281217fbd 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt
@@ -8,7 +8,6 @@ import androidx.compose.animation.core.rememberInfiniteTransition
import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
import androidx.compose.foundation.focusable
-import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope
@@ -128,9 +127,6 @@ val sceneTransitions = transitions {
fade(Communal.Elements.Grid)
}
}
- // Disable horizontal overscroll. If the scene is overscrolled too soon after showing, this
- // can lead to inconsistent KeyguardState changes.
- overscrollDisabled(CommunalScenes.Communal, Orientation.Horizontal)
}
/**
@@ -205,7 +201,6 @@ fun CommunalContainer(
colors = colors,
content = content,
viewModel = viewModel,
- modifier = Modifier.horizontalNestedScrollToScene(),
)
}
}
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 fab0ca318fbf..9bc334391ef9 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
@@ -76,6 +76,8 @@ import androidx.compose.foundation.lazy.grid.rememberLazyGridState
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.selection.selectable
import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.foundation.text.AutoSize
+import androidx.compose.foundation.text.BasicText
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Add
@@ -1024,11 +1026,14 @@ private fun EmptyStateCta(contentPadding: PaddingValues, viewModel: BaseCommunal
horizontalAlignment = Alignment.CenterHorizontally,
) {
val titleForEmptyStateCTA = stringResource(R.string.title_for_empty_state_cta)
- Text(
+ BasicText(
text = titleForEmptyStateCTA,
- style = MaterialTheme.typography.displaySmall,
- textAlign = TextAlign.Center,
- color = colors.onPrimary,
+ style =
+ MaterialTheme.typography.displaySmall.merge(
+ color = colors.onPrimary,
+ textAlign = TextAlign.Center,
+ ),
+ autoSize = AutoSize.StepBased(maxFontSize = 36.sp, stepSize = 0.1.sp),
modifier =
Modifier.focusable().semantics(mergeDescendants = true) {
contentDescription = titleForEmptyStateCTA
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalScene.kt
index a88ad946d95b..88b651019c4a 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalScene.kt
@@ -66,7 +66,6 @@ constructor(
colors = communalColors,
content = communalContent,
viewModel = contentViewModel,
- modifier = modifier.horizontalNestedScrollToScene(),
)
}
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/Notifications.kt b/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/Notifications.kt
index b54de784a202..957fdf7bcd8f 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/Notifications.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/Notifications.kt
@@ -88,7 +88,6 @@ import com.android.compose.animation.scene.ContentKey
import com.android.compose.animation.scene.ContentScope
import com.android.compose.animation.scene.ElementKey
import com.android.compose.animation.scene.LowestZIndexContentPicker
-import com.android.compose.animation.scene.NestedScrollBehavior
import com.android.compose.animation.scene.SceneTransitionLayoutState
import com.android.compose.animation.scene.content.state.TransitionState
import com.android.compose.modifiers.thenIf
@@ -236,10 +235,7 @@ fun ContentScope.SnoozeableHeadsUpNotificationSpace(
)
}
.thenIf(isHeadsUp) {
- Modifier.verticalNestedScrollToScene(
- bottomBehavior = NestedScrollBehavior.EdgeAlways
- )
- .nestedScroll(nestedScrollConnection)
+ Modifier.nestedScroll(nestedScrollConnection)
.scrollable(orientation = Orientation.Vertical, state = scrollableState)
},
)
@@ -571,11 +567,7 @@ fun ContentScope.NotificationScrollingStack(
) {
Column(
modifier =
- Modifier.verticalNestedScrollToScene(
- topBehavior = NestedScrollBehavior.EdgeWithPreview,
- isExternalOverscrollGesture = { isCurrentGestureOverscroll.value },
- )
- .thenIf(supportNestedScrolling) {
+ Modifier.thenIf(supportNestedScrolling) {
Modifier.nestedScroll(scrimNestedScrollConnection)
}
.stackVerticalOverscroll(coroutineScope) { scrollState.canScrollForward }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeOverlay.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeOverlay.kt
index f6c5f588aa95..4a28d2862988 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeOverlay.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeOverlay.kt
@@ -202,9 +202,7 @@ fun SceneScope.QuickSettingsLayout(
)
Box(
modifier =
- Modifier.requiredHeightIn(max = GridMaxHeight)
- .verticalNestedScrollToScene()
- .verticalScroll(rememberScrollState())
+ Modifier.requiredHeightIn(max = GridMaxHeight).verticalScroll(rememberScrollState())
) {
GridAnchor()
TileGrid(viewModel = viewModel.tileGridViewModel, modifier = Modifier.fillMaxWidth())
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitions.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitions.kt
index 8907aec7fd48..ee8535eff3ae 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitions.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitions.kt
@@ -1,8 +1,6 @@
package com.android.systemui.scene.ui.composable
import androidx.compose.animation.core.spring
-import androidx.compose.foundation.gestures.Orientation
-import com.android.compose.animation.scene.ProgressConverter
import com.android.compose.animation.scene.TransitionKey
import com.android.compose.animation.scene.transitions
import com.android.systemui.notifications.ui.composable.Notifications
@@ -50,7 +48,6 @@ val SceneContainerTransitions = transitions {
interruptionHandler = SceneContainerInterruptionHandler
// Overscroll progress starts linearly with some resistance (3f) and slowly approaches 0.2f
- defaultOverscrollProgressConverter = ProgressConverter.tanh(maxProgress = 0.2f, tilt = 3f)
defaultSwipeSpec = spring(stiffness = 300f, dampingRatio = 0.8f, visibilityThreshold = 0.5f)
// Scene transitions
@@ -126,13 +123,4 @@ val SceneContainerTransitions = transitions {
from(Scenes.Lockscreen, to = Overlays.QuickSettingsShade, key = SlightlyFasterShadeCollapse) {
toQuickSettingsShadeTransition(durationScale = 0.9)
}
-
- // Scene overscroll
- // TODO(b/382477212) Remove STL Overscroll DSL
- overscrollDisabled(Scenes.Gone, Orientation.Vertical)
- overscrollDisabled(Scenes.Lockscreen, Orientation.Vertical)
- overscrollDisabled(Scenes.Bouncer, Orientation.Vertical)
- overscrollDisabled(Scenes.Shade, Orientation.Vertical)
- overscrollDisabled(Overlays.NotificationsShade, Orientation.Vertical)
- overscrollDisabled(Overlays.QuickSettingsShade, Orientation.Vertical)
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt
index 79fd1d7ddd8f..a53c6b29338f 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt
@@ -65,7 +65,6 @@ import androidx.compose.ui.zIndex
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.android.compose.animation.scene.ElementKey
import com.android.compose.animation.scene.LowestZIndexContentPicker
-import com.android.compose.animation.scene.NestedScrollBehavior
import com.android.compose.animation.scene.SceneScope
import com.android.compose.animation.scene.UserAction
import com.android.compose.animation.scene.UserActionResult
@@ -400,10 +399,6 @@ private fun SceneScope.SingleShade(
.height(navBarHeight)
// Intercepts touches, prevents the scrollable container behind from scrolling.
.clickable(interactionSource = null, indication = null) { /* do nothing */ }
- .verticalNestedScrollToScene(
- topBehavior = NestedScrollBehavior.EdgeAlways,
- isExternalOverscrollGesture = { false },
- )
) {
NotificationStackCutoffGuideline(
stackScrollView = notificationStackScrollView,
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateSharedAsState.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateSharedAsState.kt
index a4237f36ab58..8777ff924bc1 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateSharedAsState.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateSharedAsState.kt
@@ -418,15 +418,11 @@ private class AnimatedStateImpl<T, Delta>(
return fromValue
}
- val overscrollSpec = transition.currentOverscrollSpec
val progress =
- when {
- overscrollSpec == null -> {
- if (canOverflow) transition.progress
- else transition.progress.fastCoerceIn(0f, 1f)
- }
- overscrollSpec.content == transition.toContent -> 1f
- else -> 0f
+ if (canOverflow) {
+ transition.progress
+ } else {
+ transition.progress.fastCoerceIn(0f, 1f)
}
return sharedValue.type.lerp(fromValue, toValue, progress)
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt
index 141736f46ee4..6bb579d18bf9 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt
@@ -23,7 +23,7 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.round
import androidx.compose.ui.util.fastCoerceIn
import com.android.compose.animation.scene.content.Content
-import com.android.compose.animation.scene.content.state.TransitionState.DirectionProperties.Companion.DistanceUnspecified
+import com.android.compose.animation.scene.content.state.TransitionState.Companion.DistanceUnspecified
import com.android.compose.nestedscroll.OnStopScope
import com.android.compose.nestedscroll.PriorityNestedScrollConnection
import com.android.compose.nestedscroll.ScrollController
@@ -77,8 +77,6 @@ internal class DraggableHandlerImpl(
internal val layoutImpl: SceneTransitionLayoutImpl,
internal val orientation: Orientation,
) : DraggableHandler {
- internal val nestedScrollKey = Any()
-
/** The [DraggableHandler] can only have one active [DragController] at a time. */
private var dragController: DragControllerImpl? = null
@@ -464,41 +462,20 @@ internal class Swipes(val upOrLeft: Swipe.Resolved, val downOrRight: Swipe.Resol
internal class NestedScrollHandlerImpl(
private val draggableHandler: DraggableHandlerImpl,
- internal var topOrLeftBehavior: NestedScrollBehavior,
- internal var bottomOrRightBehavior: NestedScrollBehavior,
- internal var isExternalOverscrollGesture: () -> Boolean,
private val pointersInfoOwner: PointersInfoOwner,
) {
val connection: PriorityNestedScrollConnection = nestedScrollConnection()
private fun nestedScrollConnection(): PriorityNestedScrollConnection {
- // If we performed a long gesture before entering priority mode, we would have to avoid
- // moving on to the next scene.
- var canChangeScene = false
-
var lastPointersDown: PointersInfo.PointersDown? = null
- fun shouldEnableSwipes(): Boolean {
- return draggableHandler.layoutImpl
- .contentForUserActions()
- .shouldEnableSwipes(draggableHandler.orientation)
- }
-
return PriorityNestedScrollConnection(
orientation = draggableHandler.orientation,
canStartPreScroll = { _, _, _ -> false },
- canStartPostScroll = { offsetAvailable, offsetBeforeStart, _ ->
- val behavior: NestedScrollBehavior =
- when {
- offsetAvailable > 0f -> topOrLeftBehavior
- offsetAvailable < 0f -> bottomOrRightBehavior
- else -> return@PriorityNestedScrollConnection false
- }
-
- val isZeroOffset =
- if (isExternalOverscrollGesture()) false else offsetBeforeStart == 0f
+ canStartPostScroll = { offsetAvailable, _, _ ->
+ if (offsetAvailable == 0f) return@PriorityNestedScrollConnection false
- val pointersDown: PointersInfo.PointersDown? =
+ lastPointersDown =
when (val info = pointersInfoOwner.pointersInfo()) {
PointersInfo.MouseWheel -> {
// Do not support mouse wheel interactions
@@ -508,24 +485,10 @@ internal class NestedScrollHandlerImpl(
is PointersInfo.PointersDown -> info
null -> null
}
- lastPointersDown = pointersDown
- when (behavior) {
- NestedScrollBehavior.EdgeNoPreview -> {
- canChangeScene = isZeroOffset
- isZeroOffset && shouldEnableSwipes()
- }
-
- NestedScrollBehavior.EdgeWithPreview -> {
- canChangeScene = isZeroOffset
- shouldEnableSwipes()
- }
-
- NestedScrollBehavior.EdgeAlways -> {
- canChangeScene = true
- shouldEnableSwipes()
- }
- }
+ draggableHandler.layoutImpl
+ .contentForUserActions()
+ .shouldEnableSwipes(draggableHandler.orientation)
},
onStart = { firstScroll ->
scrollController(
@@ -534,7 +497,6 @@ internal class NestedScrollHandlerImpl(
pointersDown = lastPointersDown,
overSlop = firstScroll,
),
- canChangeScene = canChangeScene,
pointersInfoOwner = pointersInfoOwner,
)
},
@@ -544,7 +506,6 @@ internal class NestedScrollHandlerImpl(
private fun scrollController(
dragController: DragController,
- canChangeScene: Boolean,
pointersInfoOwner: PointersInfoOwner,
): ScrollController {
return object : ScrollController {
@@ -558,14 +519,11 @@ private fun scrollController(
}
override suspend fun OnStopScope.onStop(initialVelocity: Float): Float {
- return dragController.onStop(
- velocity = initialVelocity,
- canChangeContent = canChangeScene,
- )
+ return dragController.onStop(velocity = initialVelocity, canChangeContent = true)
}
override fun onCancel() {
- dragController.onCancel(canChangeScene)
+ dragController.onCancel(canChangeContent = true)
}
/**
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt
index 07a19d83c995..16b4322411ac 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt
@@ -388,32 +388,6 @@ internal class ElementNode(
val transition = elementState as? TransitionState.Transition
- // If this element is not supposed to be laid out now, either because it is not part of any
- // ongoing transition or the other content of its transition is overscrolling, then lay out
- // the element normally and don't place it.
- val overscrollContent = transition?.currentOverscrollSpec?.content
- if (overscrollContent != null && overscrollContent != content.key) {
- when (transition) {
- is TransitionState.Transition.ChangeScene ->
- return doNotPlace(measurable, constraints)
-
- // If we are overscrolling an overlay that does not contain an element that is in
- // the current scene, place it in that scene otherwise the element won't be placed
- // at all.
- is TransitionState.Transition.ShowOrHideOverlay,
- is TransitionState.Transition.ReplaceOverlay -> {
- if (
- content.key == transition.currentScene &&
- overscrollContent !in element.stateByContent
- ) {
- return placeNormally(measurable, constraints)
- } else {
- return doNotPlace(measurable, constraints)
- }
- }
- }
- }
-
val placeable =
measure(layoutImpl, element, transition, stateInContent, measurable, constraints)
stateInContent.lastSize = placeable.size()
@@ -1257,53 +1231,6 @@ private inline fun <T> computeValue(
}
val currentContent = currentContentState.content
- if (transition is TransitionState.DirectionProperties) {
- val overscroll = transition.currentOverscrollSpec
- if (overscroll?.content == currentContent) {
- val elementSpec =
- overscroll.transformationSpec.transformations(element.key, currentContent)
- val propertySpec = transformation(elementSpec) ?: return currentValue()
- val overscrollState =
- checkNotNull(if (currentContent == toContent) toState else fromState)
- val idleValue = contentValue(overscrollState)
- val targetValue =
- with(
- propertySpec.transformation.requireInterpolatedTransformation(
- element,
- transition,
- ) {
- "Custom transformations in overscroll specs should not be possible"
- }
- ) {
- layoutImpl.propertyTransformationScope.transform(
- currentContent,
- element.key,
- transition,
- idleValue,
- )
- }
-
- // Make sure we don't read progress if values are the same and we don't need to
- // interpolate, so we don't invalidate the phase where this is read.
- if (targetValue == idleValue) {
- return targetValue
- }
-
- // TODO(b/290184746): Make sure that we don't overflow transformations associated to a
- // range.
- val directionSign = if (transition.isUpOrLeft) -1 else 1
- val isToContent = overscroll.content == transition.toContent
- val linearProgress = transition.progress.let { if (isToContent) it - 1f else it }
- val progressConverter =
- overscroll.progressConverter
- ?: layoutImpl.state.transitions.defaultProgressConverter
- val progress = directionSign * progressConverter.convert(linearProgress)
- val rangeProgress = propertySpec.range?.progress(progress) ?: progress
-
- // Interpolate between the value at rest and the over scrolled value.
- return lerp(idleValue, targetValue, rangeProgress)
- }
- }
// The element is shared: interpolate between the value in fromContent and the value in
// toContent.
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MovableElement.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MovableElement.kt
index 17510c732e65..388456e8893a 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MovableElement.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MovableElement.kt
@@ -196,13 +196,7 @@ private fun shouldComposeMovableElement(
is TransitionState.Transition -> {
// During transitions, always compose movable elements in the scene picked by their
// content picker.
- shouldComposeMoveableElement(
- layoutImpl,
- content,
- element,
- elementState,
- element.contentPicker.contents,
- )
+ shouldComposeMoveableElement(layoutImpl, content, element, elementState)
}
}
}
@@ -212,26 +206,7 @@ private fun shouldComposeMoveableElement(
content: ContentKey,
elementKey: ElementKey,
transition: TransitionState.Transition,
- containingContents: Set<ContentKey>,
): Boolean {
- val overscrollContent = transition.currentOverscrollSpec?.content
- if (overscrollContent != null) {
- return when (transition) {
- // If we are overscrolling between scenes, only place/compose the element in the
- // overscrolling scene.
- is TransitionState.Transition.ChangeScene -> content == overscrollContent
-
- // If we are overscrolling an overlay, place/compose the element if [content] is the
- // overscrolling content or if [content] is the current scene and the overscrolling
- // overlay does not contain the element.
- is TransitionState.Transition.ReplaceOverlay,
- is TransitionState.Transition.ShowOrHideOverlay ->
- content == overscrollContent ||
- (content == transition.currentScene &&
- !containingContents.contains(overscrollContent))
- }
- }
-
val scenePicker = elementKey.contentPicker
val pickedScene =
scenePicker.contentDuringTransition(
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/NestedScrollToScene.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/NestedScrollToScene.kt
deleted file mode 100644
index 9622fc151bb7..000000000000
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/NestedScrollToScene.kt
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.compose.animation.scene
-
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.geometry.Offset
-import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
-import androidx.compose.ui.input.nestedscroll.NestedScrollSource
-import androidx.compose.ui.input.nestedscroll.nestedScrollModifierNode
-import androidx.compose.ui.node.DelegatingNode
-import androidx.compose.ui.node.ModifierNodeElement
-import androidx.compose.ui.platform.InspectorInfo
-
-/**
- * Defines the behavior of the [SceneTransitionLayout] when a scrollable component is scrolled.
- *
- * By default, scrollable elements within the scene have priority during the user's gesture and are
- * not consumed by the [SceneTransitionLayout] unless specifically requested via
- * [nestedScrollToScene].
- */
-enum class NestedScrollBehavior {
- /**
- * Overscroll will only be used by the [SceneTransitionLayout] to move to the next scene if the
- * gesture begins at the edge of the scrollable component (so that a scroll in that direction
- * can no longer be consumed). If the gesture is partially consumed by the scrollable component,
- * there will be NO preview of the next scene.
- *
- * In addition, during scene transitions, scroll events are consumed by the
- * [SceneTransitionLayout] instead of the scrollable component.
- */
- EdgeNoPreview,
-
- /**
- * Overscroll will only be used by the [SceneTransitionLayout] to move to the next scene if the
- * gesture begins at the edge of the scrollable component. If the gesture is partially consumed
- * by the scrollable component, there will be a preview of the next scene.
- *
- * In addition, during scene transitions, scroll events are consumed by the
- * [SceneTransitionLayout] instead of the scrollable component.
- */
- @Deprecated("This will be removed, see b/378470603") EdgeWithPreview,
-
- /**
- * Any overscroll will be used by the [SceneTransitionLayout] to move to the next scene.
- *
- * In addition, during scene transitions, scroll events are consumed by the
- * [SceneTransitionLayout] instead of the scrollable component.
- */
- EdgeAlways;
-
- companion object {
- val Default = EdgeNoPreview
- }
-}
-
-internal fun Modifier.nestedScrollToScene(
- draggableHandler: DraggableHandlerImpl,
- topOrLeftBehavior: NestedScrollBehavior,
- bottomOrRightBehavior: NestedScrollBehavior,
- isExternalOverscrollGesture: () -> Boolean,
-) =
- this then
- NestedScrollToSceneElement(
- draggableHandler = draggableHandler,
- topOrLeftBehavior = topOrLeftBehavior,
- bottomOrRightBehavior = bottomOrRightBehavior,
- isExternalOverscrollGesture = isExternalOverscrollGesture,
- )
-
-private data class NestedScrollToSceneElement(
- private val draggableHandler: DraggableHandlerImpl,
- private val topOrLeftBehavior: NestedScrollBehavior,
- private val bottomOrRightBehavior: NestedScrollBehavior,
- private val isExternalOverscrollGesture: () -> Boolean,
-) : ModifierNodeElement<NestedScrollToSceneNode>() {
- override fun create() =
- NestedScrollToSceneNode(
- draggableHandler = draggableHandler,
- topOrLeftBehavior = topOrLeftBehavior,
- bottomOrRightBehavior = bottomOrRightBehavior,
- isExternalOverscrollGesture = isExternalOverscrollGesture,
- )
-
- override fun update(node: NestedScrollToSceneNode) {
- node.update(
- draggableHandler = draggableHandler,
- topOrLeftBehavior = topOrLeftBehavior,
- bottomOrRightBehavior = bottomOrRightBehavior,
- isExternalOverscrollGesture = isExternalOverscrollGesture,
- )
- }
-
- override fun InspectorInfo.inspectableProperties() {
- name = "nestedScrollToScene"
- properties["draggableHandler"] = draggableHandler
- properties["topOrLeftBehavior"] = topOrLeftBehavior
- properties["bottomOrRightBehavior"] = bottomOrRightBehavior
- }
-}
-
-private class NestedScrollToSceneNode(
- private var draggableHandler: DraggableHandlerImpl,
- private var topOrLeftBehavior: NestedScrollBehavior,
- private var bottomOrRightBehavior: NestedScrollBehavior,
- private var isExternalOverscrollGesture: () -> Boolean,
-) : DelegatingNode() {
- private var scrollBehaviorOwner: ScrollBehaviorOwner? = null
-
- private fun findScrollBehaviorOwner(): ScrollBehaviorOwner? {
- return scrollBehaviorOwner
- ?: findScrollBehaviorOwner(draggableHandler).also { scrollBehaviorOwner = it }
- }
-
- private val updateScrollBehaviorsConnection =
- object : NestedScrollConnection {
- /**
- * When using [NestedScrollConnection.onPostScroll], we can specify the desired behavior
- * before our parent components. This gives them the option to override our behavior if
- * they choose.
- *
- * The behavior can be communicated at every scroll gesture to ensure that the hierarchy
- * is respected, even if one of our descendant nodes changes behavior after we set it.
- */
- override fun onPostScroll(
- consumed: Offset,
- available: Offset,
- source: NestedScrollSource,
- ): Offset {
- // If we have some remaining scroll, that scroll can be used to initiate a
- // transition between scenes. We can assume that the behavior is only needed if
- // there is some remaining amount.
- if (available != Offset.Zero) {
- findScrollBehaviorOwner()
- ?.updateScrollBehaviors(
- topOrLeftBehavior = topOrLeftBehavior,
- bottomOrRightBehavior = bottomOrRightBehavior,
- isExternalOverscrollGesture = isExternalOverscrollGesture,
- )
- }
-
- return Offset.Zero
- }
- }
-
- init {
- delegate(nestedScrollModifierNode(updateScrollBehaviorsConnection, dispatcher = null))
- }
-
- override fun onDetach() {
- scrollBehaviorOwner = null
- }
-
- fun update(
- draggableHandler: DraggableHandlerImpl,
- topOrLeftBehavior: NestedScrollBehavior,
- bottomOrRightBehavior: NestedScrollBehavior,
- isExternalOverscrollGesture: () -> Boolean,
- ) {
- this.draggableHandler = draggableHandler
- this.topOrLeftBehavior = topOrLeftBehavior
- this.bottomOrRightBehavior = bottomOrRightBehavior
- this.isExternalOverscrollGesture = isExternalOverscrollGesture
- }
-}
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt
index bf7e8e823658..ce385abea627 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt
@@ -26,7 +26,6 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
-import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
import androidx.compose.ui.input.pointer.PointerType
import androidx.compose.ui.layout.LookaheadScope
import androidx.compose.ui.platform.LocalDensity
@@ -233,32 +232,6 @@ interface BaseContentScope : ElementStateScope {
)
/**
- * Adds a [NestedScrollConnection] to intercept scroll events not handled by the scrollable
- * component.
- *
- * @param leftBehavior when we should perform the overscroll animation at the left.
- * @param rightBehavior when we should perform the overscroll animation at the right.
- */
- fun Modifier.horizontalNestedScrollToScene(
- leftBehavior: NestedScrollBehavior = NestedScrollBehavior.Default,
- rightBehavior: NestedScrollBehavior = NestedScrollBehavior.Default,
- isExternalOverscrollGesture: () -> Boolean = { false },
- ): Modifier
-
- /**
- * Adds a [NestedScrollConnection] to intercept scroll events not handled by the scrollable
- * component.
- *
- * @param topBehavior when we should perform the overscroll animation at the top.
- * @param bottomBehavior when we should perform the overscroll animation at the bottom.
- */
- fun Modifier.verticalNestedScrollToScene(
- topBehavior: NestedScrollBehavior = NestedScrollBehavior.Default,
- bottomBehavior: NestedScrollBehavior = NestedScrollBehavior.Default,
- isExternalOverscrollGesture: () -> Boolean = { false },
- ): Modifier
-
- /**
* Don't resize during transitions. This can for instance be used to make sure that scrollable
* lists keep a constant size during transitions even if its elements are growing/shrinking.
*/
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt
index d7bac147d8f2..e1cecc750d3d 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt
@@ -558,15 +558,7 @@ private class LayoutNode(var layoutImpl: SceneTransitionLayoutImpl) :
width = fromSize.width
height = fromSize.height
} else {
- val overscrollSpec = transition.currentOverscrollSpec
- val progress =
- when {
- overscrollSpec == null -> transition.progress
- overscrollSpec.content == transition.toScene -> 1f
- else -> 0f
- }
-
- val size = lerp(fromSize, toSize, progress)
+ val size = lerp(fromSize, toSize, transition.progress)
width = size.width.coerceAtLeast(0)
height = size.height.coerceAtLeast(0)
}
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt
index e8b2b09da377..568a358e4a7e 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt
@@ -382,7 +382,6 @@ internal class MutableSceneTransitionLayoutStateImpl(
// Compute the [TransformationSpec] when the transition starts.
val fromContent = transition.fromContent
val toContent = transition.toContent
- val orientation = (transition as? TransitionState.DirectionProperties)?.orientation
// Update the transition specs.
transition.transformationSpec =
@@ -393,14 +392,6 @@ internal class MutableSceneTransitionLayoutStateImpl(
transitions
.transitionSpec(fromContent, toContent, key = transition.key)
.previewTransformationSpec(transition)
- if (orientation != null) {
- transition.updateOverscrollSpecs(
- fromSpec = transitions.overscrollSpec(fromContent, orientation),
- toSpec = transitions.overscrollSpec(toContent, orientation),
- )
- } else {
- transition.updateOverscrollSpecs(fromSpec = null, toSpec = null)
- }
}
private fun startTransitionInternal(transition: TransitionState.Transition, chain: Boolean) {
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitions.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitions.kt
index 8df3f2d932b3..6479e69a2aac 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitions.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitions.kt
@@ -21,7 +21,6 @@ import androidx.compose.animation.core.Spring
import androidx.compose.animation.core.SpringSpec
import androidx.compose.animation.core.snap
import androidx.compose.animation.core.spring
-import androidx.compose.foundation.gestures.Orientation
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.util.fastForEach
@@ -36,9 +35,7 @@ class SceneTransitions
internal constructor(
internal val defaultSwipeSpec: SpringSpec<Float>,
internal val transitionSpecs: List<TransitionSpecImpl>,
- internal val overscrollSpecs: List<OverscrollSpecImpl>,
internal val interruptionHandler: InterruptionHandler,
- internal val defaultProgressConverter: ProgressConverter,
) {
private val transitionCache =
mutableMapOf<
@@ -46,9 +43,6 @@ internal constructor(
MutableMap<ContentKey, MutableMap<TransitionKey?, TransitionSpecImpl>>,
>()
- private val overscrollCache =
- mutableMapOf<ContentKey, MutableMap<Orientation, OverscrollSpecImpl?>>()
-
internal fun transitionSpec(
from: ContentKey,
to: ContentKey,
@@ -119,28 +113,6 @@ internal constructor(
private fun defaultTransition(from: ContentKey, to: ContentKey) =
TransitionSpecImpl(key = null, from, to, null, null, TransformationSpec.EmptyProvider)
- internal fun overscrollSpec(scene: ContentKey, orientation: Orientation): OverscrollSpecImpl? =
- overscrollCache
- .getOrPut(scene) { mutableMapOf() }
- .getOrPut(orientation) { overscroll(scene, orientation) { it.content == scene } }
-
- private fun overscroll(
- scene: ContentKey,
- orientation: Orientation,
- filter: (OverscrollSpecImpl) -> Boolean,
- ): OverscrollSpecImpl? {
- var match: OverscrollSpecImpl? = null
- overscrollSpecs.fastForEach { spec ->
- if (spec.orientation == orientation && filter(spec)) {
- if (match != null) {
- error("Found multiple overscroll specs for overscroll $scene")
- }
- match = spec
- }
- }
- return match
- }
-
companion object {
internal val DefaultSwipeSpec =
spring(
@@ -153,9 +125,7 @@ internal constructor(
SceneTransitions(
defaultSwipeSpec = DefaultSwipeSpec,
transitionSpecs = emptyList(),
- overscrollSpecs = emptyList(),
interruptionHandler = DefaultInterruptionHandler,
- defaultProgressConverter = ProgressConverter.Default,
)
}
}
@@ -286,36 +256,6 @@ internal class TransitionSpecImpl(
): TransformationSpecImpl? = previewTransformationSpec?.invoke(transition)
}
-/** The definition of the overscroll behavior of the [content]. */
-internal interface OverscrollSpec {
- /** The scene we are over scrolling. */
- val content: ContentKey
-
- /** The orientation of this [OverscrollSpec]. */
- val orientation: Orientation
-
- /** The [TransformationSpec] associated to this [OverscrollSpec]. */
- val transformationSpec: TransformationSpec
-
- /**
- * Function that takes a linear overscroll progress value ranging from 0 to +/- infinity and
- * outputs the desired **overscroll progress value**.
- *
- * When the progress value is:
- * - 0, the user is not overscrolling.
- * - 1, the user overscrolled by exactly the [OverscrollBuilder.distance].
- * - Greater than 1, the user overscrolled more than the [OverscrollBuilder.distance].
- */
- val progressConverter: ProgressConverter?
-}
-
-internal class OverscrollSpecImpl(
- override val content: ContentKey,
- override val orientation: Orientation,
- override val transformationSpec: TransformationSpecImpl,
- override val progressConverter: ProgressConverter?,
-) : OverscrollSpec
-
/**
* An implementation of [TransformationSpec] that allows the quick retrieval of an element
* [ElementTransformations].
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SharedElement.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SharedElement.kt
index 167928b38e90..9de297f3ad5a 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SharedElement.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SharedElement.kt
@@ -56,24 +56,6 @@ internal fun shouldPlaceSharedElement(
return element.shouldBeRenderedBy(content)
}
- val overscrollContent = transition.currentOverscrollSpec?.content
- if (overscrollContent != null) {
- return when (transition) {
- // If we are overscrolling between scenes, only place/compose the element in the
- // overscrolling scene.
- is TransitionState.Transition.ChangeScene -> content == overscrollContent
-
- // If we are overscrolling an overlay, place/compose the element if [content] is the
- // overscrolling content or if [content] is the current scene and the overscrolling
- // overlay does not contain the element.
- is TransitionState.Transition.ReplaceOverlay,
- is TransitionState.Transition.ShowOrHideOverlay ->
- content == overscrollContent ||
- (content == transition.currentScene &&
- overscrollContent !in element.stateByContent)
- }
- }
-
val scenePicker = elementKey.contentPicker
val pickedScene =
scenePicker.contentDuringTransition(
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeAnimation.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeAnimation.kt
index 47daa76b61d0..607e4fadc256 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeAnimation.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeAnimation.kt
@@ -25,7 +25,7 @@ import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import com.android.compose.animation.scene.content.state.TransitionState
-import com.android.compose.animation.scene.content.state.TransitionState.DirectionProperties.Companion.DistanceUnspecified
+import com.android.compose.animation.scene.content.state.TransitionState.Companion.DistanceUnspecified
import kotlin.math.absoluteValue
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.launch
@@ -116,7 +116,6 @@ private fun createSwipeAnimation(
val fromScene = layoutState.currentScene
val toScene = result.toScene
ChangeSceneSwipeTransition(
- layoutState = layoutState,
swipeAnimation = swipeAnimation(fromContent = fromScene, toContent = toScene),
key = result.transitionKey,
replacedTransition = null,
@@ -127,10 +126,9 @@ private fun createSwipeAnimation(
val fromScene = layoutState.currentScene
val overlay = result.overlay
ShowOrHideOverlaySwipeTransition(
- layoutState = layoutState,
- fromOrToScene = fromScene,
- overlay = overlay,
swipeAnimation = swipeAnimation(fromContent = fromScene, toContent = overlay),
+ overlay = overlay,
+ fromOrToScene = fromScene,
key = result.transitionKey,
replacedTransition = null,
)
@@ -140,10 +138,9 @@ private fun createSwipeAnimation(
val toScene = layoutState.currentScene
val overlay = result.overlay
ShowOrHideOverlaySwipeTransition(
- layoutState = layoutState,
- fromOrToScene = toScene,
- overlay = overlay,
swipeAnimation = swipeAnimation(fromContent = overlay, toContent = toScene),
+ overlay = overlay,
+ fromOrToScene = toScene,
key = result.transitionKey,
replacedTransition = null,
)
@@ -159,7 +156,6 @@ private fun createSwipeAnimation(
val toOverlay = result.overlay
ReplaceOverlaySwipeTransition(
- layoutState = layoutState,
swipeAnimation =
swipeAnimation(fromContent = fromOverlay, toContent = toOverlay),
key = result.transitionKey,
@@ -170,34 +166,18 @@ private fun createSwipeAnimation(
}
}
-internal fun createSwipeAnimation(old: SwipeAnimation<*>): SwipeAnimation<*> {
- return when (val transition = old.contentTransition) {
- is TransitionState.Transition.ChangeScene -> {
- ChangeSceneSwipeTransition(transition as ChangeSceneSwipeTransition).swipeAnimation
- }
- is TransitionState.Transition.ShowOrHideOverlay -> {
- ShowOrHideOverlaySwipeTransition(transition as ShowOrHideOverlaySwipeTransition)
- .swipeAnimation
- }
- is TransitionState.Transition.ReplaceOverlay -> {
- ReplaceOverlaySwipeTransition(transition as ReplaceOverlaySwipeTransition)
- .swipeAnimation
- }
- }
-}
-
/** A helper class that contains the main logic for swipe transitions. */
internal class SwipeAnimation<T : ContentKey>(
val layoutState: MutableSceneTransitionLayoutStateImpl,
val fromContent: T,
val toContent: T,
- override val orientation: Orientation,
- override val isUpOrLeft: Boolean,
+ val orientation: Orientation,
+ val isUpOrLeft: Boolean,
val requiresFullDistanceSwipe: Boolean,
private val distance: (SwipeAnimation<T>) -> Float,
currentContent: T = fromContent,
dragOffset: Float = 0f,
-) : TransitionState.DirectionProperties {
+) {
/** The [TransitionState.Transition] whose implementation delegates to this [SwipeAnimation]. */
lateinit var contentTransition: TransitionState.Transition
@@ -264,8 +244,6 @@ internal class SwipeAnimation<T : ContentKey>(
val isInPreviewStage: Boolean
get() = contentTransition.previewTransformationSpec != null && currentContent == fromContent
- override var bouncingContent: ContentKey? = null
-
/** The current offset caused by the drag gesture. */
var dragOffset by mutableFloatStateOf(dragOffset)
@@ -276,23 +254,6 @@ internal class SwipeAnimation<T : ContentKey>(
val isUserInputOngoing: Boolean
get() = offsetAnimation == null
- override val absoluteDistance: Float
- get() = distance().absoluteValue
-
- constructor(
- other: SwipeAnimation<T>
- ) : this(
- layoutState = other.layoutState,
- fromContent = other.fromContent,
- toContent = other.toContent,
- orientation = other.orientation,
- isUpOrLeft = other.isUpOrLeft,
- requiresFullDistanceSwipe = other.requiresFullDistanceSwipe,
- distance = other.distance,
- currentContent = other.currentContent,
- dragOffset = other.offsetAnimation?.value ?: other.dragOffset,
- )
-
suspend fun run() {
// This animation will first be driven by finger, then when the user lift their finger we
// start an animation to the target offset (progress = 1f or progress = 0f). We await() for
@@ -401,10 +362,6 @@ internal class SwipeAnimation<T : ContentKey>(
return 0f
}
- val isTargetGreater = targetOffset > animatable.value
- val startedWhenOvercrollingTargetContent =
- if (targetContent == fromContent) initialProgress < 0f else initialProgress > 1f
-
val swipeSpec =
spec
?: contentTransition.transformationSpec.swipeSpec
@@ -419,34 +376,13 @@ internal class SwipeAnimation<T : ContentKey>(
animationSpec = swipeSpec,
initialVelocity = initialVelocity,
) {
- if (bouncingContent == null) {
- val isBouncing =
- if (isTargetGreater) {
- if (startedWhenOvercrollingTargetContent) {
- value >= targetOffset
- } else {
- value > targetOffset
- }
- } else {
- if (startedWhenOvercrollingTargetContent) {
- value <= targetOffset
- } else {
- value < targetOffset
- }
- }
-
- if (isBouncing) {
- bouncingContent = targetContent
-
- // Immediately stop this transition if we are bouncing on a content that
- // does not bounce.
- if (!contentTransition.isWithinProgressRange(progress)) {
- // We are no longer able to consume the velocity, the rest can be
- // consumed by another component in the hierarchy.
- velocityConsumed.complete(initialVelocity - velocity)
- throw SnapException()
- }
- }
+ // Immediately stop this transition if we are bouncing on a content that
+ // does not bounce.
+ if (!contentTransition.isWithinProgressRange(progress)) {
+ // We are no longer able to consume the velocity, the rest can be
+ // consumed by another component in the hierarchy.
+ velocityConsumed.complete(initialVelocity - velocity)
+ throw SnapException()
}
}
} catch (_: SnapException) {
@@ -514,7 +450,6 @@ private object DefaultSwipeDistance : UserActionDistance {
}
private class ChangeSceneSwipeTransition(
- val layoutState: MutableSceneTransitionLayoutStateImpl,
val swipeAnimation: SwipeAnimation<SceneKey>,
override val key: TransitionKey?,
replacedTransition: ChangeSceneSwipeTransition?,
@@ -523,17 +458,7 @@ private class ChangeSceneSwipeTransition(
swipeAnimation.fromContent,
swipeAnimation.toContent,
replacedTransition,
- ),
- TransitionState.DirectionProperties by swipeAnimation {
-
- constructor(
- other: ChangeSceneSwipeTransition
- ) : this(
- layoutState = other.layoutState,
- swipeAnimation = SwipeAnimation(other.swipeAnimation),
- key = other.key,
- replacedTransition = other,
- )
+ ) {
init {
swipeAnimation.contentTransition = this
@@ -572,7 +497,6 @@ private class ChangeSceneSwipeTransition(
}
private class ShowOrHideOverlaySwipeTransition(
- val layoutState: MutableSceneTransitionLayoutStateImpl,
val swipeAnimation: SwipeAnimation<ContentKey>,
overlay: OverlayKey,
fromOrToScene: SceneKey,
@@ -585,18 +509,7 @@ private class ShowOrHideOverlaySwipeTransition(
swipeAnimation.fromContent,
swipeAnimation.toContent,
replacedTransition,
- ),
- TransitionState.DirectionProperties by swipeAnimation {
- constructor(
- other: ShowOrHideOverlaySwipeTransition
- ) : this(
- layoutState = other.layoutState,
- swipeAnimation = SwipeAnimation(other.swipeAnimation),
- overlay = other.overlay,
- fromOrToScene = other.fromOrToScene,
- key = other.key,
- replacedTransition = other,
- )
+ ) {
init {
swipeAnimation.contentTransition = this
@@ -635,7 +548,6 @@ private class ShowOrHideOverlaySwipeTransition(
}
private class ReplaceOverlaySwipeTransition(
- val layoutState: MutableSceneTransitionLayoutStateImpl,
val swipeAnimation: SwipeAnimation<OverlayKey>,
override val key: TransitionKey?,
replacedTransition: ReplaceOverlaySwipeTransition?,
@@ -644,16 +556,7 @@ private class ReplaceOverlaySwipeTransition(
swipeAnimation.fromContent,
swipeAnimation.toContent,
replacedTransition,
- ),
- TransitionState.DirectionProperties by swipeAnimation {
- constructor(
- other: ReplaceOverlaySwipeTransition
- ) : this(
- layoutState = other.layoutState,
- swipeAnimation = SwipeAnimation(other.swipeAnimation),
- key = other.key,
- replacedTransition = other,
- )
+ ) {
init {
swipeAnimation.contentTransition = this
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeToScene.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeToScene.kt
index 6ef8b86cf72a..c5b3df222855 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeToScene.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeToScene.kt
@@ -23,12 +23,9 @@ import androidx.compose.ui.input.nestedscroll.NestedScrollDispatcher
import androidx.compose.ui.input.nestedscroll.nestedScrollModifierNode
import androidx.compose.ui.input.pointer.PointerEvent
import androidx.compose.ui.input.pointer.PointerEventPass
-import androidx.compose.ui.node.DelegatableNode
import androidx.compose.ui.node.DelegatingNode
import androidx.compose.ui.node.ModifierNodeElement
import androidx.compose.ui.node.PointerInputModifierNode
-import androidx.compose.ui.node.TraversableNode
-import androidx.compose.ui.node.findNearestAncestor
import androidx.compose.ui.unit.IntSize
import com.android.compose.animation.scene.content.Content
@@ -165,15 +162,11 @@ private class SwipeToSceneNode(
private val nestedScrollHandlerImpl =
NestedScrollHandlerImpl(
draggableHandler = draggableHandler,
- topOrLeftBehavior = NestedScrollBehavior.Default,
- bottomOrRightBehavior = NestedScrollBehavior.Default,
- isExternalOverscrollGesture = { false },
pointersInfoOwner = { multiPointerDraggableNode.pointersInfo() },
)
init {
delegate(nestedScrollModifierNode(nestedScrollHandlerImpl.connection, dispatcher))
- delegate(ScrollBehaviorOwnerNode(draggableHandler.nestedScrollKey, nestedScrollHandlerImpl))
}
private fun onFirstPointerDown() {
@@ -198,40 +191,3 @@ private class SwipeToSceneNode(
override fun onCancelPointerInput() = multiPointerDraggableNode.onCancelPointerInput()
}
-
-/** Find the [ScrollBehaviorOwner] for the current orientation. */
-internal fun DelegatableNode.findScrollBehaviorOwner(
- draggableHandler: DraggableHandlerImpl
-): ScrollBehaviorOwner? {
- // If there are no scenes in a particular orientation, the corresponding ScrollBehaviorOwnerNode
- // is removed from the composition.
- return findNearestAncestor(draggableHandler.nestedScrollKey) as? ScrollBehaviorOwner
-}
-
-internal fun interface ScrollBehaviorOwner {
- fun updateScrollBehaviors(
- topOrLeftBehavior: NestedScrollBehavior,
- bottomOrRightBehavior: NestedScrollBehavior,
- isExternalOverscrollGesture: () -> Boolean,
- )
-}
-
-/**
- * We need a node that receives the desired behavior.
- *
- * TODO(b/353234530) move this logic into [SwipeToSceneNode]
- */
-private class ScrollBehaviorOwnerNode(
- override val traverseKey: Any,
- val nestedScrollHandlerImpl: NestedScrollHandlerImpl,
-) : Modifier.Node(), TraversableNode, ScrollBehaviorOwner {
- override fun updateScrollBehaviors(
- topOrLeftBehavior: NestedScrollBehavior,
- bottomOrRightBehavior: NestedScrollBehavior,
- isExternalOverscrollGesture: () -> Boolean,
- ) {
- nestedScrollHandlerImpl.topOrLeftBehavior = topOrLeftBehavior
- nestedScrollHandlerImpl.bottomOrRightBehavior = bottomOrRightBehavior
- nestedScrollHandlerImpl.isExternalOverscrollGesture = isExternalOverscrollGesture
- }
-}
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDsl.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDsl.kt
index 952668ab49ff..8794df0cf884 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDsl.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDsl.kt
@@ -20,9 +20,7 @@ import androidx.compose.animation.core.AnimationSpec
import androidx.compose.animation.core.Easing
import androidx.compose.animation.core.LinearEasing
import androidx.compose.animation.core.SpringSpec
-import androidx.compose.foundation.gestures.Orientation
import androidx.compose.ui.geometry.Offset
-import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import com.android.compose.animation.scene.content.state.TransitionState
@@ -51,12 +49,6 @@ interface SceneTransitionsBuilder {
var interruptionHandler: InterruptionHandler
/**
- * Default [ProgressConverter] used during overscroll. It lets you change a linear progress into
- * a function of your choice. Defaults to [ProgressConverter.Default].
- */
- var defaultOverscrollProgressConverter: ProgressConverter
-
- /**
* Define the default animation to be played when transitioning [to] the specified content, from
* any content. For the animation specification to apply only when transitioning between two
* specific contents, use [from] instead.
@@ -103,28 +95,6 @@ interface SceneTransitionsBuilder {
reversePreview: (TransitionBuilder.() -> Unit)? = null,
builder: TransitionBuilder.() -> Unit = {},
)
-
- /**
- * Define the animation to be played when the [content] is overscrolled in the given
- * [orientation].
- *
- * The overscroll animation always starts from a progress of 0f, and reaches 1f when moving the
- * [distance] down/right, -1f when moving in the opposite direction.
- */
- @Deprecated(
- "Use verticalOverscrollEffect (or horizontalOverscrollEffect) directly from SceneScope."
- )
- fun overscroll(
- content: ContentKey,
- orientation: Orientation,
- builder: OverscrollBuilder.() -> Unit,
- )
-
- /**
- * Prevents overscroll the [content] in the given [orientation], allowing ancestors to
- * eventually consume the remaining gesture.
- */
- fun overscrollDisabled(content: ContentKey, orientation: Orientation)
}
interface BaseTransitionBuilder : PropertyTransformationBuilder {
@@ -228,35 +198,6 @@ interface TransitionBuilder : BaseTransitionBuilder {
fun reversed(builder: TransitionBuilder.() -> Unit)
}
-@TransitionDsl
-interface OverscrollBuilder : BaseTransitionBuilder {
- /**
- * Function that takes a linear overscroll progress value ranging from 0 to +/- infinity and
- * outputs the desired **overscroll progress value**.
- *
- * When the progress value is:
- * - 0, the user is not overscrolling.
- * - 1, the user overscrolled by exactly the [distance].
- * - Greater than 1, the user overscrolled more than the [distance].
- */
- var progressConverter: ProgressConverter?
-
- /** Translate the element(s) matching [matcher] by ([x], [y]) pixels. */
- fun translate(
- matcher: ElementMatcher,
- x: OverscrollScope.() -> Float = { 0f },
- y: OverscrollScope.() -> Float = { 0f },
- )
-}
-
-interface OverscrollScope : Density {
- /**
- * Return the absolute distance between fromScene and toScene, if available, otherwise
- * [DistanceUnspecified].
- */
- val absoluteDistance: Float
-}
-
/**
* An interface to decide where we should draw shared Elements or compose MovableElements.
*
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDslImpl.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDslImpl.kt
index 6742b3200ac4..a1649964ec13 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDslImpl.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDslImpl.kt
@@ -22,9 +22,7 @@ import androidx.compose.animation.core.Easing
import androidx.compose.animation.core.Spring
import androidx.compose.animation.core.SpringSpec
import androidx.compose.animation.core.VectorConverter
-import androidx.compose.animation.core.snap
import androidx.compose.animation.core.spring
-import androidx.compose.foundation.gestures.Orientation
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.unit.Dp
import com.android.compose.animation.scene.content.state.TransitionState
@@ -33,7 +31,6 @@ import com.android.compose.animation.scene.transformation.AnchoredTranslate
import com.android.compose.animation.scene.transformation.DrawScale
import com.android.compose.animation.scene.transformation.EdgeTranslate
import com.android.compose.animation.scene.transformation.Fade
-import com.android.compose.animation.scene.transformation.OverscrollTranslate
import com.android.compose.animation.scene.transformation.ScaleSize
import com.android.compose.animation.scene.transformation.SharedElementTransformation
import com.android.compose.animation.scene.transformation.Transformation
@@ -43,22 +40,14 @@ import com.android.compose.animation.scene.transformation.Translate
internal fun transitionsImpl(builder: SceneTransitionsBuilder.() -> Unit): SceneTransitions {
val impl = SceneTransitionsBuilderImpl().apply(builder)
- return SceneTransitions(
- impl.defaultSwipeSpec,
- impl.transitionSpecs,
- impl.transitionOverscrollSpecs,
- impl.interruptionHandler,
- impl.defaultOverscrollProgressConverter,
- )
+ return SceneTransitions(impl.defaultSwipeSpec, impl.transitionSpecs, impl.interruptionHandler)
}
private class SceneTransitionsBuilderImpl : SceneTransitionsBuilder {
override var defaultSwipeSpec: SpringSpec<Float> = SceneTransitions.DefaultSwipeSpec
override var interruptionHandler: InterruptionHandler = DefaultInterruptionHandler
- override var defaultOverscrollProgressConverter: ProgressConverter = ProgressConverter.Default
val transitionSpecs = mutableListOf<TransitionSpecImpl>()
- val transitionOverscrollSpecs = mutableListOf<OverscrollSpecImpl>()
override fun to(
to: ContentKey,
@@ -81,45 +70,6 @@ private class SceneTransitionsBuilderImpl : SceneTransitionsBuilder {
transition(from = from, to = to, key = key, preview, reversePreview, builder)
}
- override fun overscroll(
- content: ContentKey,
- orientation: Orientation,
- builder: OverscrollBuilder.() -> Unit,
- ) {
- val impl = OverscrollBuilderImpl().apply(builder)
- check(impl.transformationMatchers.isNotEmpty()) {
- "This method does not allow empty transformations. " +
- "Use overscrollDisabled($content, $orientation) instead."
- }
- overscrollSpec(content, orientation, impl)
- }
-
- override fun overscrollDisabled(content: ContentKey, orientation: Orientation) {
- overscrollSpec(content, orientation, OverscrollBuilderImpl())
- }
-
- private fun overscrollSpec(
- content: ContentKey,
- orientation: Orientation,
- impl: OverscrollBuilderImpl,
- ): OverscrollSpec {
- val spec =
- OverscrollSpecImpl(
- content = content,
- orientation = orientation,
- transformationSpec =
- TransformationSpecImpl(
- progressSpec = snap(),
- swipeSpec = null,
- distance = impl.distance,
- transformationMatchers = impl.transformationMatchers,
- ),
- progressConverter = impl.progressConverter,
- )
- transitionOverscrollSpecs.add(spec)
- return spec
- }
-
private fun transition(
from: ContentKey?,
to: ContentKey?,
@@ -295,15 +245,3 @@ internal class TransitionBuilderImpl(override val transition: TransitionState.Tr
fractionRange(start, end, easing, builder)
}
}
-
-internal open class OverscrollBuilderImpl : BaseTransitionBuilderImpl(), OverscrollBuilder {
- override var progressConverter: ProgressConverter? = null
-
- override fun translate(
- matcher: ElementMatcher,
- x: OverscrollScope.() -> Float,
- y: OverscrollScope.() -> Float,
- ) {
- addTransformation(matcher, OverscrollTranslate.Factory(x, y))
- }
-}
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/Content.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/Content.kt
index 152f05eb5cc7..3716df5b5a35 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/Content.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/Content.kt
@@ -42,7 +42,6 @@ import com.android.compose.animation.scene.ElementStateScope
import com.android.compose.animation.scene.MovableElement
import com.android.compose.animation.scene.MovableElementContentScope
import com.android.compose.animation.scene.MovableElementKey
-import com.android.compose.animation.scene.NestedScrollBehavior
import com.android.compose.animation.scene.SceneTransitionLayoutForTesting
import com.android.compose.animation.scene.SceneTransitionLayoutImpl
import com.android.compose.animation.scene.SceneTransitionLayoutScope
@@ -57,7 +56,6 @@ import com.android.compose.animation.scene.effect.OffsetOverscrollEffect
import com.android.compose.animation.scene.effect.VisualEffect
import com.android.compose.animation.scene.element
import com.android.compose.animation.scene.modifiers.noResizeDuringTransitions
-import com.android.compose.animation.scene.nestedScrollToScene
import com.android.compose.modifiers.thenIf
import com.android.compose.ui.graphics.ContainerState
import com.android.compose.ui.graphics.container
@@ -173,32 +171,6 @@ internal class ContentScopeImpl(
)
}
- override fun Modifier.horizontalNestedScrollToScene(
- leftBehavior: NestedScrollBehavior,
- rightBehavior: NestedScrollBehavior,
- isExternalOverscrollGesture: () -> Boolean,
- ): Modifier {
- return nestedScrollToScene(
- draggableHandler = layoutImpl.horizontalDraggableHandler,
- topOrLeftBehavior = leftBehavior,
- bottomOrRightBehavior = rightBehavior,
- isExternalOverscrollGesture = isExternalOverscrollGesture,
- )
- }
-
- override fun Modifier.verticalNestedScrollToScene(
- topBehavior: NestedScrollBehavior,
- bottomBehavior: NestedScrollBehavior,
- isExternalOverscrollGesture: () -> Boolean,
- ): Modifier {
- return nestedScrollToScene(
- draggableHandler = layoutImpl.verticalDraggableHandler,
- topOrLeftBehavior = topBehavior,
- bottomOrRightBehavior = bottomBehavior,
- isExternalOverscrollGesture = isExternalOverscrollGesture,
- )
- }
-
override fun Modifier.noResizeDuringTransitions(): Modifier {
return noResizeDuringTransitions(layoutState = layoutImpl.state)
}
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/state/TransitionState.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/state/TransitionState.kt
index 29be445e82bb..e7ca51114b93 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/state/TransitionState.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/state/TransitionState.kt
@@ -20,15 +20,12 @@ import androidx.compose.animation.core.Animatable
import androidx.compose.animation.core.AnimationVector1D
import androidx.compose.animation.core.Spring
import androidx.compose.animation.core.spring
-import androidx.compose.foundation.gestures.Orientation
import androidx.compose.runtime.Stable
-import androidx.compose.runtime.State
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import com.android.compose.animation.scene.ContentKey
import com.android.compose.animation.scene.MutableSceneTransitionLayoutState
import com.android.compose.animation.scene.OverlayKey
-import com.android.compose.animation.scene.OverscrollSpecImpl
import com.android.compose.animation.scene.ProgressVisibilityThreshold
import com.android.compose.animation.scene.SceneKey
import com.android.compose.animation.scene.SceneTransitionLayoutImpl
@@ -254,40 +251,13 @@ sealed interface TransitionState {
internal open val isInPreviewStage: Boolean = false
/**
- * The current [TransformationSpecImpl] and [OverscrollSpecImpl] associated to this
- * transition.
+ * The current [TransformationSpecImpl] associated to this transition.
*
* Important: These will be set exactly once, when this transition is
* [started][MutableSceneTransitionLayoutStateImpl.startTransition].
*/
internal var transformationSpec: TransformationSpecImpl = TransformationSpec.Empty
internal var previewTransformationSpec: TransformationSpecImpl? = null
- private var fromOverscrollSpec: OverscrollSpecImpl? = null
- private var toOverscrollSpec: OverscrollSpecImpl? = null
-
- /**
- * The current [OverscrollSpecImpl], if this transition is currently overscrolling.
- *
- * Note: This is backed by a State<OverscrollSpecImpl?> because the overscroll spec is
- * derived from progress, and we don't want readers of currentOverscrollSpec to recompose
- * every time progress is changed.
- */
- private val _currentOverscrollSpec: State<OverscrollSpecImpl?>? =
- if (this !is DirectionProperties) {
- null
- } else {
- derivedStateOf {
- val progress = progress
- val bouncingContent = bouncingContent
- when {
- progress < 0f || bouncingContent == fromContent -> fromOverscrollSpec
- progress > 1f || bouncingContent == toContent -> toOverscrollSpec
- else -> null
- }
- }
- }
- internal val currentOverscrollSpec: OverscrollSpecImpl?
- get() = _currentOverscrollSpec?.value
/**
* An animatable that animates from 1f to 0f. This will be used to nicely animate the sudden
@@ -395,27 +365,13 @@ sealed interface TransitionState {
}
}
- internal fun updateOverscrollSpecs(
- fromSpec: OverscrollSpecImpl?,
- toSpec: OverscrollSpecImpl?,
- ) {
- fromOverscrollSpec = fromSpec
- toOverscrollSpec = toSpec
- }
-
- /** Returns if the [progress] value of this transition can go beyond range `[0; 1]` */
+ /**
+ * Checks if the given [progress] value is within the valid range for this transition.
+ *
+ * The valid range is between 0f and 1f, inclusive.
+ */
internal fun isWithinProgressRange(progress: Float): Boolean {
- // If the properties are missing we assume that every [Transition] can overscroll
- if (this !is DirectionProperties) return true
- // [OverscrollSpec] for the current scene, even if it hasn't started overscrolling yet.
- val specForCurrentScene =
- when {
- progress <= 0f -> fromOverscrollSpec
- progress >= 1f -> toOverscrollSpec
- else -> null
- } ?: return true
-
- return specForCurrentScene.transformationSpec.transformationMatchers.isNotEmpty()
+ return progress >= 0f && progress <= 1f
}
internal open fun interruptionProgress(layoutImpl: SceneTransitionLayoutImpl): Float {
@@ -444,36 +400,7 @@ sealed interface TransitionState {
}
}
- interface DirectionProperties {
- /**
- * The position of the [Transition.toContent].
- *
- * Used to understand the direction of the overscroll.
- */
- val isUpOrLeft: Boolean
-
- /**
- * The relative orientation between [Transition.fromContent] and [Transition.toContent].
- *
- * Used to understand the orientation of the overscroll.
- */
- val orientation: Orientation
-
- /**
- * Return the absolute distance between fromScene and toScene, if available, otherwise
- * [DistanceUnspecified].
- */
- val absoluteDistance: Float
-
- /**
- * The content (scene or overlay) around which the transition is currently bouncing. When
- * not `null`, this transition is currently oscillating around this content and will soon
- * settle to that content.
- */
- val bouncingContent: ContentKey?
-
- companion object {
- const val DistanceUnspecified = 0f
- }
+ companion object {
+ const val DistanceUnspecified = 0f
}
}
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/reveal/ContainerReveal.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/reveal/ContainerReveal.kt
index 944bd85991c9..7c4dbf153013 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/reveal/ContainerReveal.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/reveal/ContainerReveal.kt
@@ -156,12 +156,7 @@ private class VerticalContainerRevealSizeTransformation(
// implement HasOverscrollProperties if the transition is triggered and not gesture based.
val idleSize = checkNotNull(element.targetSize(content))
val userActionDistance = idleSize.height
- val progress =
- when ((transition as? TransitionState.DirectionProperties)?.bouncingContent) {
- null -> transition.progressTo(content)
- content -> 1f
- else -> 0f
- }
+ val progress = transition.progressTo(content)
val distance = (progress * userActionDistance).fastCoerceAtLeast(0f)
val threshold = distanceThreshold.toPx()
@@ -256,19 +251,7 @@ private class ContainerRevealAlphaTransformation(
private fun targetAlpha(transition: TransitionState.Transition, content: ContentKey): Float {
if (transition.isUserInputOngoing) {
- if (transition !is TransitionState.DirectionProperties) {
- error(
- "Unsupported transition driven by user input but that does not have " +
- "overscroll properties: $transition"
- )
- }
-
- val bouncingContent = transition.bouncingContent
- return if (bouncingContent != null) {
- if (bouncingContent == content) 1f else 0f
- } else {
- if (transition.progressTo(content) > 0f) 1f else 0f
- }
+ return if (transition.progressTo(content) > 0f) 1f else 0f
}
// The transition was committed (the user released their finger), so the alpha depends on
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Translate.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Translate.kt
index 432add38385a..30d2de61d9bb 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Translate.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Translate.kt
@@ -17,11 +17,9 @@
package com.android.compose.animation.scene.transformation
import androidx.compose.ui.geometry.Offset
-import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.Dp
import com.android.compose.animation.scene.ContentKey
import com.android.compose.animation.scene.ElementKey
-import com.android.compose.animation.scene.OverscrollScope
import com.android.compose.animation.scene.content.state.TransitionState
internal class Translate private constructor(private val x: Dp, private val y: Dp) :
@@ -41,71 +39,3 @@ internal class Translate private constructor(private val x: Dp, private val y: D
override fun create(): Transformation = Translate(x, y)
}
}
-
-internal class OverscrollTranslate
-private constructor(
- private val x: OverscrollScope.() -> Float,
- private val y: OverscrollScope.() -> Float,
-) : InterpolatedPropertyTransformation<Offset> {
- override val property = PropertyTransformation.Property.Offset
-
- private val cachedOverscrollScope = CachedOverscrollScope()
-
- override fun PropertyTransformationScope.transform(
- content: ContentKey,
- element: ElementKey,
- transition: TransitionState.Transition,
- value: Offset,
- ): Offset {
- // As this object is created by OverscrollBuilderImpl and we retrieve the current
- // OverscrollSpec only when the transition implements HasOverscrollProperties, we can assume
- // that this method was invoked after performing this check.
- val overscrollProperties = transition as TransitionState.DirectionProperties
- val overscrollScope =
- cachedOverscrollScope.getFromCacheOrCompute(density = this, overscrollProperties)
-
- return Offset(x = value.x + overscrollScope.x(), y = value.y + overscrollScope.y())
- }
-
- class Factory(
- private val x: OverscrollScope.() -> Float,
- private val y: OverscrollScope.() -> Float,
- ) : Transformation.Factory {
- override fun create(): Transformation = OverscrollTranslate(x, y)
- }
-}
-
-/**
- * A helper class to cache a [OverscrollScope] given a [Density] and
- * [TransitionState.DirectionProperties]. This helps avoid recreating a scope every frame whenever
- * an overscroll transition is computed.
- */
-private class CachedOverscrollScope {
- private var previousScope: OverscrollScope? = null
- private var previousDensity: Density? = null
- private var previousOverscrollProperties: TransitionState.DirectionProperties? = null
-
- fun getFromCacheOrCompute(
- density: Density,
- overscrollProperties: TransitionState.DirectionProperties,
- ): OverscrollScope {
- if (
- previousScope == null ||
- density != previousDensity ||
- previousOverscrollProperties != overscrollProperties
- ) {
- val scope =
- object : OverscrollScope, Density by density {
- override val absoluteDistance: Float
- get() = overscrollProperties.absoluteDistance
- }
-
- previousScope = scope
- previousDensity = density
- previousOverscrollProperties = overscrollProperties
- return scope
- }
-
- return checkNotNull(previousScope)
- }
-}
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/AnimatedSharedAsStateTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/AnimatedSharedAsStateTest.kt
index 2fd1d8d8573a..62ec2215ca14 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/AnimatedSharedAsStateTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/AnimatedSharedAsStateTest.kt
@@ -19,15 +19,12 @@ package com.android.compose.animation.scene
import androidx.compose.animation.core.LinearEasing
import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
-import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
@@ -447,59 +444,6 @@ class AnimatedSharedAsStateTest {
}
@Test
- fun animatedValueDoesNotOverscrollWhenOverscrollIsSpecified() {
- val state =
- rule.runOnUiThread {
- MutableSceneTransitionLayoutStateImpl(
- SceneA,
- transitions { overscrollDisabled(SceneB, Orientation.Horizontal) },
- )
- }
-
- val key = ValueKey("foo")
- val lastValues = mutableMapOf<ContentKey, Float>()
-
- @Composable
- fun ContentScope.animateFloat(value: Float, key: ValueKey) {
- val animatedValue = animateContentFloatAsState(value, key)
- LaunchedEffect(animatedValue) {
- snapshotFlow { animatedValue.value }.collect { lastValues[contentKey] = it }
- }
- }
-
- val scope =
- rule.setContentAndCreateMainScope {
- SceneTransitionLayout(state) {
- scene(SceneA) { animateFloat(0f, key) }
- scene(SceneB) { animateFloat(100f, key) }
- }
- }
-
- // Overscroll on A at -100%: value should be interpolated given that there is no overscroll
- // defined for scene A.
- var progress by mutableStateOf(-1f)
- scope.launch {
- state.startTransition(transition(from = SceneA, to = SceneB, progress = { progress }))
- }
- rule.waitForIdle()
- assertThat(lastValues[SceneA]).isWithin(0.001f).of(-100f)
- assertThat(lastValues[SceneB]).isWithin(0.001f).of(-100f)
-
- // Middle of the transition.
- progress = 0.5f
- rule.waitForIdle()
- assertThat(lastValues[SceneA]).isWithin(0.001f).of(50f)
- assertThat(lastValues[SceneB]).isWithin(0.001f).of(50f)
-
- // Overscroll on B at 200%: value should not be interpolated given that there is an
- // overscroll defined for scene B.
- progress = 2f
- rule.waitForIdle()
- assertThat(lastValues[SceneA]).isWithin(0.001f).of(100f)
- assertThat(lastValues[SceneB]).isWithin(0.001f).of(100f)
- }
-
- @Test
fun interpolatedColor() {
val a = Color.Red
val b = Color.Green
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt
index 6985644579f6..5a35d11c0b29 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt
@@ -18,7 +18,6 @@ package com.android.compose.animation.scene
import androidx.compose.animation.core.Spring
import androidx.compose.animation.core.spring
-import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.overscroll
import androidx.compose.material3.Text
import androidx.compose.ui.Modifier
@@ -31,9 +30,6 @@ import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.Velocity
import androidx.test.ext.junit.runners.AndroidJUnit4
-import com.android.compose.animation.scene.NestedScrollBehavior.EdgeAlways
-import com.android.compose.animation.scene.NestedScrollBehavior.EdgeNoPreview
-import com.android.compose.animation.scene.NestedScrollBehavior.EdgeWithPreview
import com.android.compose.animation.scene.TestOverlays.OverlayA
import com.android.compose.animation.scene.TestOverlays.OverlayB
import com.android.compose.animation.scene.TestScenes.SceneA
@@ -141,15 +137,9 @@ class DraggableHandlerTest {
var pointerInfoOwner: () -> PointersInfo = { pointersDown() }
- fun nestedScrollConnection(
- nestedScrollBehavior: NestedScrollBehavior,
- isExternalOverscrollGesture: Boolean = false,
- ) =
+ fun nestedScrollConnection() =
NestedScrollHandlerImpl(
draggableHandler = draggableHandler,
- topOrLeftBehavior = nestedScrollBehavior,
- bottomOrRightBehavior = nestedScrollBehavior,
- isExternalOverscrollGesture = { isExternalOverscrollGesture },
pointersInfoOwner = { pointerInfoOwner() },
)
.connection
@@ -270,13 +260,12 @@ class DraggableHandlerTest {
velocity: Float,
canChangeScene: Boolean = true,
onAnimationStart: () -> Unit,
- expectedConsumedVelocity: Float,
) =
onDragStoppedAnimateNow(
velocity = velocity,
canChangeScene = canChangeScene,
onAnimationStart = onAnimationStart,
- onAnimationEnd = { assertThat(it).isEqualTo(expectedConsumedVelocity) },
+ onAnimationEnd = {},
)
fun DragController.onDragStoppedAnimateLater(
@@ -358,7 +347,6 @@ class DraggableHandlerTest {
dragController.onDragStoppedAnimateNow(
velocity = velocityThreshold - 0.01f,
onAnimationStart = { assertTransition(currentScene = SceneA) },
- expectedConsumedVelocity = velocityThreshold - 0.01f,
)
assertIdle(currentScene = SceneA)
@@ -386,7 +374,6 @@ class DraggableHandlerTest {
progress = 0f,
)
},
- expectedConsumedVelocity = velocityThreshold - 0.01f,
)
assertIdle(currentScene = SceneA)
@@ -400,7 +387,6 @@ class DraggableHandlerTest {
dragController.onDragStoppedAnimateNow(
velocity = velocityThreshold,
onAnimationStart = { assertTransition(currentScene = SceneC) },
- expectedConsumedVelocity = velocityThreshold,
)
assertIdle(currentScene = SceneC)
}
@@ -413,7 +399,6 @@ class DraggableHandlerTest {
dragController.onDragStoppedAnimateNow(
velocity = 0f,
onAnimationStart = { assertTransition(currentScene = SceneA) },
- expectedConsumedVelocity = 0f,
)
assertIdle(currentScene = SceneA)
}
@@ -462,13 +447,11 @@ class DraggableHandlerTest {
)
// Reverse drag direction, it does not replace the previous transition.
- dragController.onDragDelta(pixels = down(fractionOfScreen = 0.5f))
- assertTransition(
- currentScene = SceneA,
- fromScene = SceneA,
- toScene = SceneB,
- progress = -0.3f,
+ dragController.onDragDelta(
+ pixels = down(fractionOfScreen = 0.5f),
+ expectedConsumed = down(0.2f),
)
+ assertTransition(currentScene = SceneA, fromScene = SceneA, toScene = SceneB, progress = 0f)
}
@Test
@@ -515,7 +498,6 @@ class DraggableHandlerTest {
onAnimationStart = {
assertTransition(currentScene = SceneC, fromScene = SceneA, toScene = SceneC)
},
- expectedConsumedVelocity = 0f,
)
assertIdle(currentScene = SceneC)
}
@@ -535,7 +517,6 @@ class DraggableHandlerTest {
onAnimationStart = {
assertTransition(fromScene = SceneA, toScene = SceneB, progress = 0.2f)
},
- expectedConsumedVelocity = down(fractionOfScreen = 0.1f),
)
assertIdle(SceneA)
@@ -575,293 +556,6 @@ class DraggableHandlerTest {
}
@Test
- fun onInitialPreScroll_EdgeWithOverscroll_doNotChangeState() = runGestureTest {
- val nestedScroll = nestedScrollConnection(nestedScrollBehavior = EdgeWithPreview)
- nestedScroll.onPreScroll(
- available = downOffset(fractionOfScreen = 0.1f),
- source = UserInput,
- )
- assertIdle(currentScene = SceneA)
- }
-
- @Test
- fun onPostScrollWithNothingAvailable_EdgeWithOverscroll_doNotChangeState() = runGestureTest {
- val nestedScroll = nestedScrollConnection(nestedScrollBehavior = EdgeWithPreview)
- val consumed =
- nestedScroll.onPostScroll(
- consumed = Offset.Zero,
- available = Offset.Zero,
- source = UserInput,
- )
-
- assertIdle(currentScene = SceneA)
- assertThat(consumed).isEqualTo(Offset.Zero)
- }
-
- @Test
- fun onPostScrollWithSomethingAvailable_startSceneTransition() = runGestureTest {
- val nestedScroll = nestedScrollConnection(nestedScrollBehavior = EdgeWithPreview)
- val consumed =
- nestedScroll.onPostScroll(
- consumed = Offset.Zero,
- available = downOffset(fractionOfScreen = 0.1f),
- source = UserInput,
- )
-
- assertTransition(currentScene = SceneA)
- assertThat(progress).isEqualTo(0.1f)
- assertThat(consumed).isEqualTo(downOffset(fractionOfScreen = 0.1f))
- }
-
- @Test
- fun afterSceneTransitionIsStarted_interceptPreScrollEvents() = runGestureTest {
- val nestedScroll = nestedScrollConnection(nestedScrollBehavior = EdgeWithPreview)
- nestedScroll.scroll(available = downOffset(fractionOfScreen = 0.1f))
- assertTransition(currentScene = SceneA)
-
- assertThat(progress).isEqualTo(0.1f)
-
- // start intercept preScroll
- val consumed =
- nestedScroll.onPreScroll(
- available = downOffset(fractionOfScreen = 0.1f),
- source = UserInput,
- )
- assertThat(progress).isEqualTo(0.2f)
-
- // do nothing on postScroll
- nestedScroll.onPostScroll(consumed = consumed, available = Offset.Zero, source = UserInput)
- assertThat(progress).isEqualTo(0.2f)
-
- nestedScroll.scroll(available = downOffset(fractionOfScreen = 0.1f))
- assertThat(progress).isEqualTo(0.3f)
- assertTransition(currentScene = SceneA)
- }
-
- private fun TestGestureScope.preScrollAfterSceneTransition(
- firstScroll: Float,
- secondScroll: Float,
- ) {
- val nestedScroll = nestedScrollConnection(nestedScrollBehavior = EdgeWithPreview)
- // start scene transition
- nestedScroll.scroll(available = Offset(0f, firstScroll))
-
- // stop scene transition (start the "stop animation")
- nestedScroll.preFling(available = Velocity.Zero)
-
- // a pre scroll event, that could be intercepted by DraggableHandlerImpl
- nestedScroll.onPreScroll(available = Offset(0f, secondScroll), source = UserInput)
- }
-
- @Test
- fun scrollAndFling_scrollMoreThanInterceptable_goToIdleOnNextScene() = runGestureTest {
- val firstScroll = -(1f - transitionInterceptionThreshold + 0.0001f) * SCREEN_SIZE
- val secondScroll = -0.01f
-
- preScrollAfterSceneTransition(firstScroll = firstScroll, secondScroll = secondScroll)
-
- advanceUntilIdle()
- assertIdle(SceneB)
- }
-
- @Test
- fun duringATransition_aNewScrollGesture_shouldTakeControl() = runGestureTest {
- val nestedScroll = nestedScrollConnection(nestedScrollBehavior = EdgeWithPreview)
- // First gesture
- nestedScroll.scroll(available = downOffset(fractionOfScreen = 0.1f))
- assertTransition(currentScene = SceneA)
- nestedScroll.preFling(available = Velocity.Zero)
- assertTransition(currentScene = SceneA)
-
- // Second gesture, it starts during onStop() animation
- nestedScroll.scroll(downOffset(0.1f))
- assertTransition(currentScene = SceneA)
-
- // Allows onStop() to complete or cancel
- advanceUntilIdle()
-
- // Second gesture continues
- nestedScroll.scroll(downOffset(0.1f))
- assertTransition(currentScene = SceneA)
-
- // Second gesture ends
- nestedScroll.preFling(available = Velocity.Zero)
- assertTransition(currentScene = SceneA)
-
- advanceUntilIdle()
- assertIdle(currentScene = SceneA)
- }
-
- @Test
- fun onPreFling_velocityLowerThanThreshold_remainSameScene() = runGestureTest {
- val nestedScroll = nestedScrollConnection(nestedScrollBehavior = EdgeWithPreview)
- nestedScroll.scroll(available = downOffset(fractionOfScreen = 0.1f))
- assertTransition(currentScene = SceneA)
-
- nestedScroll.preFling(available = Velocity.Zero)
- assertTransition(currentScene = SceneA)
-
- // wait for the stop animation
- advanceUntilIdle()
- assertIdle(currentScene = SceneA)
- }
-
- private fun TestGestureScope.flingAfterScroll(
- use: NestedScrollBehavior,
- idleAfterScroll: Boolean,
- ) {
- val nestedScroll = nestedScrollConnection(nestedScrollBehavior = use)
- nestedScroll.scroll(available = downOffset(fractionOfScreen = 0.1f))
- if (idleAfterScroll) assertIdle(SceneA) else assertTransition(SceneA)
-
- nestedScroll.preFling(available = Velocity(0f, velocityThreshold))
- }
-
- @Test
- fun flingAfterScroll_EdgeNoOverscroll_goToNextScene() = runGestureTest {
- flingAfterScroll(use = EdgeNoPreview, idleAfterScroll = false)
-
- assertTransition(currentScene = SceneC)
-
- // wait for the stop animation
- advanceUntilIdle()
- assertIdle(currentScene = SceneC)
- }
-
- @Test
- fun flingAfterScroll_EdgeWithOverscroll_goToNextScene() = runGestureTest {
- flingAfterScroll(use = EdgeWithPreview, idleAfterScroll = false)
-
- assertTransition(currentScene = SceneC)
-
- // wait for the stop animation
- advanceUntilIdle()
- assertIdle(currentScene = SceneC)
- }
-
- @Test
- fun flingAfterScroll_Always_goToNextScene() = runGestureTest {
- flingAfterScroll(use = EdgeAlways, idleAfterScroll = false)
-
- assertTransition(currentScene = SceneC)
-
- // wait for the stop animation
- advanceUntilIdle()
- assertIdle(currentScene = SceneC)
- }
-
- /** we started the scroll in the scene, then fling with the velocityThreshold */
- private fun TestGestureScope.flingAfterScrollStartedInScene(
- use: NestedScrollBehavior,
- idleAfterScroll: Boolean,
- ) {
- val nestedScroll = nestedScrollConnection(nestedScrollBehavior = use)
- // scroll consumed in child
- nestedScroll.scroll(
- available = downOffset(fractionOfScreen = 0.1f),
- consumedByScroll = downOffset(fractionOfScreen = 0.1f),
- )
-
- // scroll offsetY10 is all available for parents
- nestedScroll.scroll(available = downOffset(fractionOfScreen = 0.1f))
- if (idleAfterScroll) assertIdle(SceneA) else assertTransition(SceneA)
-
- nestedScroll.preFling(available = Velocity(0f, velocityThreshold))
- }
-
- @Test
- fun flingAfterScrollStartedInScene_EdgeNoOverscroll_doNothing() = runGestureTest {
- flingAfterScrollStartedInScene(use = EdgeNoPreview, idleAfterScroll = true)
-
- assertIdle(currentScene = SceneA)
- }
-
- @Test
- fun flingAfterScrollStartedInScene_EdgeWithOverscroll_doOverscrollAnimation() = runGestureTest {
- flingAfterScrollStartedInScene(use = EdgeWithPreview, idleAfterScroll = false)
-
- assertTransition(currentScene = SceneA)
-
- // wait for the stop animation
- advanceUntilIdle()
- assertIdle(currentScene = SceneA)
- }
-
- @Test
- fun flingAfterScrollStartedInScene_Always_goToNextScene() = runGestureTest {
- flingAfterScrollStartedInScene(use = EdgeAlways, idleAfterScroll = false)
-
- assertTransition(currentScene = SceneC)
-
- // wait for the stop animation
- advanceUntilIdle()
- assertIdle(currentScene = SceneC)
- }
-
- @Test
- fun flingAfterScrollStartedByExternalOverscrollGesture() = runGestureTest {
- val nestedScroll =
- nestedScrollConnection(
- nestedScrollBehavior = EdgeWithPreview,
- isExternalOverscrollGesture = true,
- )
-
- // scroll not consumed in child
- nestedScroll.scroll(available = downOffset(fractionOfScreen = 0.1f))
-
- // scroll offsetY10 is all available for parents
- nestedScroll.scroll(available = downOffset(fractionOfScreen = 0.1f))
- assertTransition(SceneA)
-
- nestedScroll.preFling(available = Velocity(0f, velocityThreshold))
- }
-
- @Test
- fun beforeNestedScrollStart_stop_shouldBeIgnored() = runGestureTest {
- val nestedScroll = nestedScrollConnection(nestedScrollBehavior = EdgeWithPreview)
- nestedScroll.preFling(available = Velocity(0f, velocityThreshold))
- assertIdle(currentScene = SceneA)
- }
-
- @Test
- fun startNestedScrollWhileDragging() = runGestureTest {
- val nestedScroll = nestedScrollConnection(nestedScrollBehavior = EdgeAlways)
-
- val offsetY10 = downOffset(fractionOfScreen = 0.1f)
-
- // Start a drag and then stop it, given that
- val dragController = onDragStarted(overSlop = up(0.1f))
-
- assertTransition(currentScene = SceneA)
- assertThat(progress).isEqualTo(0.1f)
-
- // now we can intercept the scroll events
- nestedScroll.scroll(available = -offsetY10)
- assertThat(progress).isEqualTo(0.1f)
-
- // this should be ignored, we are scrolling now!
- dragController.onDragStoppedAnimateNow(
- velocity = -velocityThreshold,
- onAnimationStart = { assertTransition(currentScene = SceneA) },
- expectedConsumedVelocity = 0f,
- )
- assertTransition(currentScene = SceneA)
-
- nestedScroll.scroll(available = -offsetY10)
- assertThat(progress).isEqualTo(0.2f)
-
- nestedScroll.scroll(available = -offsetY10)
- assertThat(progress).isEqualTo(0.3f)
-
- nestedScroll.preFling(available = Velocity(0f, -velocityThreshold))
- assertTransition(currentScene = SceneB)
-
- // wait for the stop animation
- advanceUntilIdle()
- assertIdle(currentScene = SceneB)
- }
-
- @Test
fun freezeAndAnimateToCurrentState() = runGestureTest {
// Start at scene C.
navigateToSceneC()
@@ -893,7 +587,6 @@ class DraggableHandlerTest {
dragController.onDragStoppedAnimateNow(
velocity = -velocityThreshold,
onAnimationStart = { assertTransition(fromScene = SceneA, toScene = SceneB) },
- expectedConsumedVelocity = -velocityThreshold,
)
assertIdle(SceneA)
}
@@ -901,7 +594,6 @@ class DraggableHandlerTest {
@Test
fun blockTransition_animated() = runGestureTest {
assertIdle(SceneA)
- layoutState.transitions = transitions { overscrollDisabled(SceneB, Orientation.Vertical) }
// Swipe up to scene B. Overscroll 50%.
val dragController = onDragStarted(overSlop = up(1.5f), expectedConsumedOverSlop = up(1.0f))
@@ -916,7 +608,7 @@ class DraggableHandlerTest {
assertTransition(currentScene = SceneA, fromScene = SceneA, toScene = SceneB, progress = 1f)
val consumed = velocityConsumed.await()
- assertThat(consumed).isEqualTo(-velocityThreshold)
+ assertThat(consumed).isNotEqualTo(0f)
assertIdle(SceneA)
}
@@ -924,7 +616,7 @@ class DraggableHandlerTest {
fun nestedScrollUseFromSourceInfo() = runGestureTest {
// Start at scene C.
navigateToSceneC()
- val nestedScroll = nestedScrollConnection(nestedScrollBehavior = EdgeAlways)
+ val nestedScroll = nestedScrollConnection()
// Drag from the **top** of the screen
pointerInfoOwner = { pointersDown() }
@@ -961,7 +653,7 @@ class DraggableHandlerTest {
fun ignoreMouseWheel() = runGestureTest {
// Start at scene C.
navigateToSceneC()
- val nestedScroll = nestedScrollConnection(nestedScrollBehavior = EdgeAlways)
+ val nestedScroll = nestedScrollConnection()
// Use mouse wheel
pointerInfoOwner = { PointersInfo.MouseWheel }
@@ -983,40 +675,7 @@ class DraggableHandlerTest {
}
@Test
- fun emptyOverscrollImmediatelyAbortsSettleAnimationWhenOverProgress() = runGestureTest {
- // Overscrolling on scene B does nothing.
- layoutState.transitions = transitions { overscrollDisabled(SceneB, Orientation.Vertical) }
-
- // Swipe up to scene B at progress = 200%.
- val middle = pointersDown(startedPosition = Offset(SCREEN_SIZE / 2f, SCREEN_SIZE / 2f))
- val dragController =
- onDragStarted(
- pointersInfo = middle,
- overSlop = up(2f),
- // Overscroll is disabled, it will scroll up to 100%
- expectedConsumedOverSlop = up(1f),
- )
-
- // The progress value is coerced in `[0..1]`
- assertTransition(fromScene = SceneA, toScene = SceneB, progress = 1f)
-
- // Release the finger.
- dragController.onDragStoppedAnimateNow(
- velocity = -velocityThreshold,
- onAnimationStart = {
- // Given that we are at progress >= 100% and that the overscroll on scene B is doing
- // nothing, we are already idle.
- assertIdle(SceneB)
- },
- expectedConsumedVelocity = 0f,
- )
- }
-
- @Test
fun emptyOverscrollAbortsSettleAnimationAndExposeTheConsumedVelocity() = runGestureTest {
- // Overscrolling on scene B does nothing.
- layoutState.transitions = transitions { overscrollDisabled(SceneB, Orientation.Vertical) }
-
// Swipe up to scene B at progress = 200%.
val middle = pointersDown(startedPosition = Offset(SCREEN_SIZE / 2f, SCREEN_SIZE / 2f))
val dragController = onDragStarted(pointersInfo = middle, overSlop = up(0.99f))
@@ -1027,7 +686,7 @@ class DraggableHandlerTest {
velocity = -velocityThreshold,
onAnimationStart = { assertTransition(fromScene = SceneA, toScene = SceneB) },
onAnimationEnd = { consumedVelocity ->
- // Our progress value was 0.99f and it is coerced in `[0..1]` (overscrollDisabled).
+ // Our progress value was 0.99f and it is coerced in `[0..1]`.
// Some of the velocity will be used for animation, but not all of it.
assertThat(consumedVelocity).isLessThan(0f)
assertThat(consumedVelocity).isGreaterThan(-velocityThreshold)
@@ -1037,9 +696,7 @@ class DraggableHandlerTest {
@Test
fun scrollKeepPriorityEvenIfWeCanNoLongerScrollOnThatDirection() = runGestureTest {
- // Overscrolling on scene B does nothing.
- layoutState.transitions = transitions { overscrollDisabled(SceneB, Orientation.Vertical) }
- val nestedScroll = nestedScrollConnection(nestedScrollBehavior = EdgeAlways)
+ val nestedScroll = nestedScrollConnection()
// Overscroll is disabled, it will scroll up to 100%
nestedScroll.scroll(available = upOffset(fractionOfScreen = 2f))
@@ -1061,7 +718,6 @@ class DraggableHandlerTest {
layoutState.transitions = transitions {
defaultSwipeSpec = spring(dampingRatio = Spring.DampingRatioNoBouncy)
from(SceneA, to = SceneB) {}
- overscroll(SceneB, Orientation.Vertical) { fade(TestElements.Foo) }
}
val middle = pointersDown(startedPosition = Offset(SCREEN_SIZE / 2f, SCREEN_SIZE / 2f))
@@ -1078,13 +734,11 @@ class DraggableHandlerTest {
onAnimationStart = {
assertTransition(fromScene = SceneA, toScene = SceneB, progress = 0.5f)
},
- expectedConsumedVelocity = -velocityThreshold,
)
// We didn't overscroll at the end of the transition.
assertIdle(SceneB)
assertThat(transition).hasProgress(1f)
- assertThat(transition).hasNoOverscrollSpec()
}
@Test
@@ -1093,7 +747,6 @@ class DraggableHandlerTest {
layoutState.transitions = transitions {
defaultSwipeSpec = spring(dampingRatio = Spring.DampingRatioNoBouncy)
from(SceneA, to = SceneC) {}
- overscroll(SceneC, Orientation.Vertical) { fade(TestElements.Foo) }
}
val middle = pointersDown(startedPosition = Offset(SCREEN_SIZE / 2f, SCREEN_SIZE / 2f))
@@ -1110,13 +763,11 @@ class DraggableHandlerTest {
onAnimationStart = {
assertTransition(fromScene = SceneA, toScene = SceneC, progress = 0.5f)
},
- expectedConsumedVelocity = velocityThreshold,
)
// We didn't overscroll at the end of the transition.
assertIdle(SceneC)
assertThat(transition).hasProgress(1f)
- assertThat(transition).hasNoOverscrollSpec()
}
@Test
@@ -1124,31 +775,33 @@ class DraggableHandlerTest {
// Make scene B overscrollable.
layoutState.transitions = transitions {
from(SceneA, to = SceneB) { spec = spring(dampingRatio = Spring.DampingRatioNoBouncy) }
- overscroll(SceneB, Orientation.Vertical) { fade(TestElements.Foo) }
}
val middle = pointersDown(startedPosition = Offset(SCREEN_SIZE / 2f, SCREEN_SIZE / 2f))
- val dragController = onDragStarted(pointersInfo = middle, overSlop = up(1.5f))
+ val dragController =
+ onDragStarted(
+ pointersInfo = middle,
+ overSlop = up(1.5f),
+ expectedConsumedOverSlop = up(1f),
+ )
val transition = assertThat(transitionState).isSceneTransition()
assertThat(transition).hasFromScene(SceneA)
assertThat(transition).hasToScene(SceneB)
- assertThat(transition).hasProgress(1.5f)
+ assertThat(transition).hasProgress(1f)
// Release to B.
dragController.onDragStoppedAnimateNow(
velocity = 0f,
onAnimationStart = {
- assertTransition(fromScene = SceneA, toScene = SceneB, progress = 1.5f)
+ assertTransition(fromScene = SceneA, toScene = SceneB, progress = 1f)
},
- expectedConsumedVelocity = 0f,
)
// We kept the overscroll at 100% so that the placement logic didn't change at the end of
// the animation.
assertIdle(SceneB)
assertThat(transition).hasProgress(1f)
- assertThat(transition).hasOverscrollSpec()
}
@Test
@@ -1156,31 +809,33 @@ class DraggableHandlerTest {
// Make scene C overscrollable.
layoutState.transitions = transitions {
from(SceneA, to = SceneC) { spec = spring(dampingRatio = Spring.DampingRatioNoBouncy) }
- overscroll(SceneC, Orientation.Vertical) { fade(TestElements.Foo) }
}
val middle = pointersDown(startedPosition = Offset(SCREEN_SIZE / 2f, SCREEN_SIZE / 2f))
- val dragController = onDragStarted(pointersInfo = middle, overSlop = down(1.5f))
+ val dragController =
+ onDragStarted(
+ pointersInfo = middle,
+ overSlop = down(1.5f),
+ expectedConsumedOverSlop = down(1f),
+ )
val transition = assertThat(transitionState).isSceneTransition()
assertThat(transition).hasFromScene(SceneA)
assertThat(transition).hasToScene(SceneC)
- assertThat(transition).hasProgress(1.5f)
+ assertThat(transition).hasProgress(1f)
// Release to C.
dragController.onDragStoppedAnimateNow(
velocity = 0f,
onAnimationStart = {
- assertTransition(fromScene = SceneA, toScene = SceneC, progress = 1.5f)
+ assertTransition(fromScene = SceneA, toScene = SceneC, progress = 1f)
},
- expectedConsumedVelocity = 0f,
)
// We kept the overscroll at 100% so that the placement logic didn't change at the end of
// the animation.
assertIdle(SceneC)
assertThat(transition).hasProgress(1f)
- assertThat(transition).hasOverscrollSpec()
}
@Test
@@ -1196,7 +851,6 @@ class DraggableHandlerTest {
onAnimationStart = {
assertTransition(fromScene = SceneA, toScene = SceneB, progress = 0.9f)
},
- expectedConsumedVelocity = 0f,
)
assertIdle(SceneA)
@@ -1207,7 +861,6 @@ class DraggableHandlerTest {
onAnimationStart = {
assertTransition(fromScene = SceneA, toScene = SceneB, progress = 1f)
},
- expectedConsumedVelocity = 0f,
)
assertIdle(SceneB)
}
@@ -1234,7 +887,6 @@ class DraggableHandlerTest {
controller.onDragStoppedAnimateNow(
velocity = velocityThreshold,
onAnimationStart = { assertThat(transition).hasCurrentOverlays(OverlayA) },
- expectedConsumedVelocity = velocityThreshold,
)
assertThat(layoutState.transitionState).isIdle()
assertThat(layoutState.transitionState).hasCurrentScene(SceneA)
@@ -1264,7 +916,6 @@ class DraggableHandlerTest {
controller.onDragStoppedAnimateNow(
velocity = -velocityThreshold,
onAnimationStart = { assertThat(transition).hasCurrentOverlays(/* empty */ ) },
- expectedConsumedVelocity = -velocityThreshold,
)
assertThat(layoutState.transitionState).isIdle()
assertThat(layoutState.transitionState).hasCurrentScene(SceneA)
@@ -1294,7 +945,6 @@ class DraggableHandlerTest {
controller.onDragStoppedAnimateNow(
velocity = velocityThreshold,
onAnimationStart = { assertThat(transition).hasCurrentOverlays(OverlayB) },
- expectedConsumedVelocity = velocityThreshold,
)
assertThat(layoutState.transitionState).isIdle()
assertThat(layoutState.transitionState).hasCurrentScene(SceneA)
@@ -1313,7 +963,7 @@ class DraggableHandlerTest {
// Swipe down to replace overlay A by overlay B.
- val nestedScroll = nestedScrollConnection(nestedScrollBehavior = EdgeWithPreview)
+ val nestedScroll = nestedScrollConnection()
nestedScroll.scroll(downOffset(0.1f))
val transition = assertThat(layoutState.transitionState).isReplaceOverlayTransition()
assertThat(transition).hasCurrentScene(SceneA)
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ElementTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ElementTest.kt
index ffba63988cfc..c69129b38bdd 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ElementTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ElementTest.kt
@@ -17,8 +17,6 @@
package com.android.compose.animation.scene
import androidx.compose.animation.core.LinearEasing
-import androidx.compose.animation.core.Spring
-import androidx.compose.animation.core.spring
import androidx.compose.animation.core.tween
import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.gestures.rememberScrollableState
@@ -33,7 +31,6 @@ import androidx.compose.foundation.layout.size
import androidx.compose.foundation.overscroll
import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.PagerState
-import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.SideEffect
@@ -57,7 +54,6 @@ import androidx.compose.ui.test.assertPositionInRootIsEqualTo
import androidx.compose.ui.test.assertTopPositionInRootIsEqualTo
import androidx.compose.ui.test.hasParent
import androidx.compose.ui.test.hasTestTag
-import androidx.compose.ui.test.hasText
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.onRoot
@@ -74,7 +70,6 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.compose.animation.scene.TestScenes.SceneA
import com.android.compose.animation.scene.TestScenes.SceneB
import com.android.compose.animation.scene.TestScenes.SceneC
-import com.android.compose.animation.scene.content.state.TransitionState
import com.android.compose.animation.scene.effect.OffsetOverscrollEffect
import com.android.compose.animation.scene.subjects.assertThat
import com.android.compose.test.assertSizeIsEqualTo
@@ -653,122 +648,6 @@ class ElementTest {
rule.onNode(isElement(TestElements.Foo)).assertSizeIsEqualTo(20.dp, 20.dp)
}
- private fun setupOverscrollScenario(
- layoutWidth: Dp,
- layoutHeight: Dp,
- sceneTransitions: SceneTransitionsBuilder.() -> Unit,
- firstScroll: Float,
- animatedFloatRange: ClosedFloatingPointRange<Float>,
- onAnimatedFloat: (Float) -> Unit,
- ): MutableSceneTransitionLayoutStateImpl {
- // The draggable touch slop, i.e. the min px distance a touch pointer must move before it is
- // detected as a drag event.
- var touchSlop = 0f
-
- val state =
- rule.runOnUiThread {
- MutableSceneTransitionLayoutState(
- initialScene = SceneA,
- transitions = transitions(sceneTransitions),
- )
- as MutableSceneTransitionLayoutStateImpl
- }
-
- rule.setContent {
- touchSlop = LocalViewConfiguration.current.touchSlop
- SceneTransitionLayout(
- state = state,
- modifier = Modifier.size(layoutWidth, layoutHeight),
- ) {
- scene(key = SceneA, userActions = mapOf(Swipe.Down to SceneB)) {
- animateContentFloatAsState(
- value = animatedFloatRange.start,
- key = TestValues.Value1,
- false,
- )
- Spacer(Modifier.fillMaxSize())
- }
- scene(SceneB) {
- val animatedFloat by
- animateContentFloatAsState(
- value = animatedFloatRange.endInclusive,
- key = TestValues.Value1,
- canOverflow = false,
- )
- Spacer(Modifier.element(TestElements.Foo).fillMaxSize())
- LaunchedEffect(Unit) {
- snapshotFlow { animatedFloat }.collect { onAnimatedFloat(it) }
- }
- }
- }
- }
-
- assertThat(state.transitionState).isIdle()
-
- // Swipe by half of verticalSwipeDistance.
- rule.onRoot().performTouchInput {
- val middleTop = Offset((layoutWidth / 2).toPx(), 0f)
- down(middleTop)
- val firstScrollHeight = layoutHeight.toPx() * firstScroll
- moveBy(Offset(0f, touchSlop + firstScrollHeight), delayMillis = 1_000)
- }
- return state
- }
-
- @Test
- fun elementTransitionDuringOverscrollWithOverscrollDSL() {
- val layoutWidth = 200.dp
- val layoutHeight = 400.dp
- val overscrollTranslateY = 10.dp
- var animatedFloat = 0f
-
- val state =
- setupOverscrollScenario(
- layoutWidth = layoutWidth,
- layoutHeight = layoutHeight,
- sceneTransitions = {
- overscroll(SceneB, Orientation.Vertical) {
- progressConverter = ProgressConverter.linear()
- // On overscroll 100% -> Foo should translate by overscrollTranslateY
- translate(TestElements.Foo, y = overscrollTranslateY)
- }
- },
- firstScroll = 0.5f, // Scroll 50%
- animatedFloatRange = 0f..100f,
- onAnimatedFloat = { animatedFloat = it },
- )
-
- val fooElement = rule.onNodeWithTag(TestElements.Foo.testTag)
- fooElement.assertTopPositionInRootIsEqualTo(0.dp)
- val transition = assertThat(state.transitionState).isSceneTransition()
- assertThat(transition).isNotNull()
- assertThat(transition).hasProgress(0.5f)
- assertThat(animatedFloat).isEqualTo(50f)
-
- rule.onRoot().performTouchInput {
- // Scroll another 100%
- moveBy(Offset(0f, layoutHeight.toPx()), delayMillis = 1_000)
- }
-
- // Scroll 150% (Scene B overscroll by 50%)
- assertThat(transition).hasProgress(1.5f)
- assertThat(transition).hasOverscrollSpec()
- fooElement.assertTopPositionInRootIsEqualTo(overscrollTranslateY * 0.5f)
- // animatedFloat cannot overflow (canOverflow = false)
- assertThat(animatedFloat).isEqualTo(100f)
-
- rule.onRoot().performTouchInput {
- // Scroll another 100%
- moveBy(Offset(0f, layoutHeight.toPx()), delayMillis = 1_000)
- }
-
- // Scroll 250% (Scene B overscroll by 150%)
- assertThat(transition).hasProgress(2.5f)
- assertThat(transition).hasOverscrollSpec()
- fooElement.assertTopPositionInRootIsEqualTo(overscrollTranslateY * 1.5f)
- assertThat(animatedFloat).isEqualTo(100f)
- }
-
private fun expectedOffset(currentOffset: Dp, density: Density): Dp {
return with(density) {
OffsetOverscrollEffect.computeOffset(density, currentOffset.toPx()).toDp()
@@ -784,13 +663,7 @@ class ElementTest {
// The draggable touch slop, i.e. the min px distance a touch pointer must move before it is
// detected as a drag event.
var touchSlop = 0f
- val state =
- rule.runOnUiThread {
- MutableSceneTransitionLayoutState(
- initialScene = SceneA,
- transitions = transitions { overscrollDisabled(SceneB, Orientation.Vertical) },
- )
- }
+ val state = rule.runOnUiThread { MutableSceneTransitionLayoutState(initialScene = SceneA) }
rule.setContent {
density = LocalDensity.current
touchSlop = LocalViewConfiguration.current.touchSlop
@@ -845,17 +718,7 @@ class ElementTest {
// The draggable touch slop, i.e. the min px distance a touch pointer must move before it is
// detected as a drag event.
var touchSlop = 0f
- val state =
- rule.runOnUiThread {
- MutableSceneTransitionLayoutState(
- initialScene = SceneA,
- transitions =
- transitions {
- overscrollDisabled(SceneA, Orientation.Vertical)
- overscrollDisabled(SceneB, Orientation.Vertical)
- },
- )
- }
+ val state = rule.runOnUiThread { MutableSceneTransitionLayoutState(initialScene = SceneA) }
rule.setContent {
density = LocalDensity.current
touchSlop = LocalViewConfiguration.current.touchSlop
@@ -950,17 +813,7 @@ class ElementTest {
// The draggable touch slop, i.e. the min px distance a touch pointer must move before it is
// detected as a drag event.
var touchSlop = 0f
- val state =
- rule.runOnUiThread {
- MutableSceneTransitionLayoutState(
- initialScene = SceneA,
- transitions =
- transitions {
- defaultOverscrollProgressConverter = ProgressConverter.linear()
- overscrollDisabled(SceneB, Orientation.Vertical)
- },
- )
- }
+ val state = rule.runOnUiThread { MutableSceneTransitionLayoutState(initialScene = SceneA) }
rule.setContent {
density = LocalDensity.current
touchSlop = LocalViewConfiguration.current.touchSlop
@@ -1013,13 +866,7 @@ class ElementTest {
val layoutWidth = 200.dp
val layoutHeight = 400.dp
- val state =
- rule.runOnUiThread {
- MutableSceneTransitionLayoutState(
- initialScene = SceneA,
- transitions = transitions { overscrollDisabled(SceneB, Orientation.Vertical) },
- )
- }
+ val state = rule.runOnUiThread { MutableSceneTransitionLayoutState(initialScene = SceneA) }
rule.setContent {
density = LocalDensity.current
@@ -1146,262 +993,6 @@ class ElementTest {
}
@Test
- fun elementTransitionWithDistanceDuringOverscroll() {
- val layoutWidth = 200.dp
- val layoutHeight = 400.dp
- var animatedFloat = 0f
- val state =
- setupOverscrollScenario(
- layoutWidth = layoutWidth,
- layoutHeight = layoutHeight,
- sceneTransitions = {
- overscroll(SceneB, Orientation.Vertical) {
- progressConverter = ProgressConverter.linear()
- // On overscroll 100% -> Foo should translate by layoutHeight
- translate(TestElements.Foo, y = { absoluteDistance })
- }
- },
- firstScroll = 1f, // 100% scroll
- animatedFloatRange = 0f..100f,
- onAnimatedFloat = { animatedFloat = it },
- )
-
- val fooElement = rule.onNodeWithTag(TestElements.Foo.testTag)
- fooElement.assertTopPositionInRootIsEqualTo(0.dp)
- assertThat(animatedFloat).isEqualTo(100f)
-
- rule.onRoot().performTouchInput {
- // Scroll another 50%
- moveBy(Offset(0f, layoutHeight.toPx() * 0.5f), delayMillis = 1_000)
- }
-
- val transition = assertThat(state.transitionState).isSceneTransition()
- assertThat(animatedFloat).isEqualTo(100f)
-
- // Scroll 150% (100% scroll + 50% overscroll)
- assertThat(transition).hasProgress(1.5f)
- assertThat(transition).hasOverscrollSpec()
- fooElement.assertTopPositionInRootIsEqualTo(layoutHeight * 0.5f)
- assertThat(animatedFloat).isEqualTo(100f)
-
- rule.onRoot().performTouchInput {
- // Scroll another 100%
- moveBy(Offset(0f, layoutHeight.toPx()), delayMillis = 1_000)
- }
-
- // Scroll 250% (100% scroll + 150% overscroll)
- assertThat(transition).hasProgress(2.5f)
- assertThat(transition).hasOverscrollSpec()
- fooElement.assertTopPositionInRootIsEqualTo(layoutHeight * 1.5f)
- assertThat(animatedFloat).isEqualTo(100f)
- }
-
- @Test
- fun elementTransitionWithDistanceDuringOverscrollWithDefaultProgressConverter() {
- val layoutWidth = 200.dp
- val layoutHeight = 400.dp
- var animatedFloat = 0f
- val state =
- setupOverscrollScenario(
- layoutWidth = layoutWidth,
- layoutHeight = layoutHeight,
- sceneTransitions = {
- // Overscroll progress will be halved
- defaultOverscrollProgressConverter = ProgressConverter { it / 2f }
-
- overscroll(SceneB, Orientation.Vertical) {
- // On overscroll 100% -> Foo should translate by layoutHeight
- translate(TestElements.Foo, y = { absoluteDistance })
- }
- },
- firstScroll = 1f, // 100% scroll
- animatedFloatRange = 0f..100f,
- onAnimatedFloat = { animatedFloat = it },
- )
-
- val fooElement = rule.onNodeWithTag(TestElements.Foo.testTag)
- fooElement.assertTopPositionInRootIsEqualTo(0.dp)
- assertThat(animatedFloat).isEqualTo(100f)
-
- rule.onRoot().performTouchInput {
- // Scroll another 100%
- moveBy(Offset(0f, layoutHeight.toPx()), delayMillis = 1_000)
- }
-
- val transition = assertThat(state.transitionState).isSceneTransition()
- assertThat(animatedFloat).isEqualTo(100f)
-
- // Scroll 200% (100% scroll + 100% overscroll)
- assertThat(transition).hasProgress(2f)
- assertThat(transition).hasOverscrollSpec()
-
- // Overscroll progress is halved, we are at 50% of the overscroll progress.
- fooElement.assertTopPositionInRootIsEqualTo(layoutHeight * 0.5f)
- assertThat(animatedFloat).isEqualTo(100f)
- }
-
- @Test
- fun elementTransitionWithDistanceDuringOverscrollWithOverrideDefaultProgressConverter() {
- val layoutWidth = 200.dp
- val layoutHeight = 400.dp
- var animatedFloat = 0f
- val state =
- setupOverscrollScenario(
- layoutWidth = layoutWidth,
- layoutHeight = layoutHeight,
- sceneTransitions = {
- // Overscroll progress will be linear (by default)
- defaultOverscrollProgressConverter = ProgressConverter.linear()
-
- overscroll(SceneB, Orientation.Vertical) {
- // This override the defaultOverscrollProgressConverter
- // Overscroll progress will be halved
- progressConverter = ProgressConverter { it / 2f }
- // On overscroll 100% -> Foo should translate by layoutHeight
- translate(TestElements.Foo, y = { absoluteDistance })
- }
- },
- firstScroll = 1f, // 100% scroll
- animatedFloatRange = 0f..100f,
- onAnimatedFloat = { animatedFloat = it },
- )
-
- val fooElement = rule.onNodeWithTag(TestElements.Foo.testTag)
- fooElement.assertTopPositionInRootIsEqualTo(0.dp)
- assertThat(animatedFloat).isEqualTo(100f)
-
- rule.onRoot().performTouchInput {
- // Scroll another 100%
- moveBy(Offset(0f, layoutHeight.toPx()), delayMillis = 1_000)
- }
-
- val transition = assertThat(state.transitionState).isSceneTransition()
- assertThat(animatedFloat).isEqualTo(100f)
-
- // Scroll 200% (100% scroll + 100% overscroll)
- assertThat(transition).hasProgress(2f)
- assertThat(transition).hasOverscrollSpec()
-
- // Overscroll progress is halved, we are at 50% of the overscroll progress.
- fooElement.assertTopPositionInRootIsEqualTo(layoutHeight * 0.5f)
- assertThat(animatedFloat).isEqualTo(100f)
- }
-
- @Test
- fun elementTransitionWithDistanceDuringOverscrollWithProgressConverter() {
- val layoutWidth = 200.dp
- val layoutHeight = 400.dp
- var animatedFloat = 0f
- val state =
- setupOverscrollScenario(
- layoutWidth = layoutWidth,
- layoutHeight = layoutHeight,
- sceneTransitions = {
- overscroll(SceneB, Orientation.Vertical) {
- // Overscroll progress will be halved
- progressConverter = ProgressConverter { it / 2f }
-
- // On overscroll 100% -> Foo should translate by layoutHeight
- translate(TestElements.Foo, y = { absoluteDistance })
- }
- },
- firstScroll = 1f, // 100% scroll
- animatedFloatRange = 0f..100f,
- onAnimatedFloat = { animatedFloat = it },
- )
-
- val fooElement = rule.onNodeWithTag(TestElements.Foo.testTag)
- fooElement.assertTopPositionInRootIsEqualTo(0.dp)
- assertThat(animatedFloat).isEqualTo(100f)
-
- rule.onRoot().performTouchInput {
- // Scroll another 100%
- moveBy(Offset(0f, layoutHeight.toPx()), delayMillis = 1_000)
- }
-
- val transition = assertThat(state.transitionState).isSceneTransition()
- assertThat(animatedFloat).isEqualTo(100f)
-
- // Scroll 200% (100% scroll + 100% overscroll)
- assertThat(transition).hasProgress(2f)
- assertThat(transition).hasOverscrollSpec()
-
- // Overscroll progress is halved, we are at 50% of the overscroll progress.
- fooElement.assertTopPositionInRootIsEqualTo(layoutHeight * 0.5f)
- assertThat(animatedFloat).isEqualTo(100f)
-
- rule.onRoot().performTouchInput {
- // Scroll another 100%
- moveBy(Offset(0f, layoutHeight.toPx()), delayMillis = 1_000)
- }
-
- // Scroll 300% (100% scroll + 200% overscroll)
- assertThat(transition).hasProgress(3f)
- assertThat(transition).hasOverscrollSpec()
-
- // Overscroll progress is halved, we are at 100% of the overscroll progress.
- fooElement.assertTopPositionInRootIsEqualTo(layoutHeight)
- assertThat(animatedFloat).isEqualTo(100f)
- }
-
- @Test
- fun elementTransitionWithDistanceDuringOverscrollBouncing() {
- val layoutWidth = 200.dp
- val layoutHeight = 400.dp
- var animatedFloat = 0f
- val state =
- setupOverscrollScenario(
- layoutWidth = layoutWidth,
- layoutHeight = layoutHeight,
- sceneTransitions = {
- defaultSwipeSpec =
- spring(
- dampingRatio = Spring.DampingRatioMediumBouncy,
- stiffness = Spring.StiffnessLow,
- )
-
- overscroll(SceneB, Orientation.Vertical) {
- progressConverter = ProgressConverter.linear()
- // On overscroll 100% -> Foo should translate by layoutHeight
- translate(TestElements.Foo, y = { absoluteDistance })
- }
- },
- firstScroll = 1f, // 100% scroll
- animatedFloatRange = 0f..100f,
- onAnimatedFloat = { animatedFloat = it },
- )
-
- val fooElement = rule.onNodeWithTag(TestElements.Foo.testTag)
- fooElement.assertTopPositionInRootIsEqualTo(0.dp)
- assertThat(animatedFloat).isEqualTo(100f)
-
- rule.onRoot().performTouchInput {
- // Scroll another 50%
- moveBy(Offset(0f, layoutHeight.toPx() * 0.5f), delayMillis = 1_000)
- }
-
- val transition = assertThat(state.transitionState).isSceneTransition()
-
- // Scroll 150% (100% scroll + 50% overscroll)
- assertThat(transition).hasProgress(1.5f)
- assertThat(transition).hasOverscrollSpec()
- fooElement.assertTopPositionInRootIsEqualTo(layoutHeight * (transition.progress - 1f))
- assertThat(animatedFloat).isEqualTo(100f)
-
- // finger raised
- rule.onRoot().performTouchInput { up() }
-
- // The target value is 1f, but the spring (defaultSwipeSpec) allows you to go to a lower
- // value.
- rule.waitUntil(timeoutMillis = 10_000) { transition.progress < 1f }
-
- assertThat(transition.progress).isLessThan(1f)
- assertThat(transition).hasOverscrollSpec()
- assertThat(transition).hasBouncingContent(transition.toContent)
- assertThat(animatedFloat).isEqualTo(100f)
- }
-
- @Test
fun elementIsUsingLastTransition() {
// 4 frames of animation.
val duration = 4 * 16
@@ -1848,13 +1439,7 @@ class ElementTest {
@Test
fun targetStateIsSetEvenWhenNotPlaced() {
// Start directly at A => B but with progress < 0f to overscroll on A.
- val state =
- rule.runOnUiThread {
- MutableSceneTransitionLayoutStateImpl(
- SceneA,
- transitions { overscrollDisabled(SceneA, Orientation.Horizontal) },
- )
- }
+ val state = rule.runOnUiThread { MutableSceneTransitionLayoutStateImpl(SceneA) }
lateinit var layoutImpl: SceneTransitionLayoutImpl
val scope =
@@ -1870,14 +1455,7 @@ class ElementTest {
}
scope.launch {
- state.startTransition(
- transition(
- from = SceneA,
- to = SceneB,
- progress = { -1f },
- orientation = Orientation.Horizontal,
- )
- )
+ state.startTransition(transition(from = SceneA, to = SceneB, progress = { -1f }))
}
rule.waitForIdle()
@@ -2004,204 +1582,6 @@ class ElementTest {
}
@Test
- fun sharedElementIsOnlyPlacedInOverscrollingScene() {
- val state =
- rule.runOnUiThread {
- MutableSceneTransitionLayoutStateImpl(
- SceneA,
- transitions {
- overscrollDisabled(SceneA, Orientation.Horizontal)
- overscrollDisabled(SceneB, Orientation.Horizontal)
- },
- )
- }
-
- @Composable
- fun ContentScope.Foo() {
- Box(Modifier.element(TestElements.Foo).size(10.dp))
- }
-
- val scope =
- rule.setContentAndCreateMainScope {
- SceneTransitionLayout(state) {
- scene(SceneA) { Foo() }
- scene(SceneB) { Foo() }
- }
- }
-
- rule.onNode(isElement(TestElements.Foo, SceneA)).assertIsDisplayed()
- rule.onNode(isElement(TestElements.Foo, SceneB)).assertDoesNotExist()
-
- // A => B while overscrolling at scene B.
- var progress by mutableStateOf(2f)
- scope.launch {
- state.startTransition(transition(from = SceneA, to = SceneB, progress = { progress }))
- }
- rule.waitForIdle()
-
- // Foo should only be placed in scene B.
- rule.onNode(isElement(TestElements.Foo, SceneA)).assertExists().assertIsNotDisplayed()
- rule.onNode(isElement(TestElements.Foo, SceneB)).assertIsDisplayed()
-
- // Overscroll at scene A.
- progress = -1f
- rule.waitForIdle()
-
- // Foo should only be placed in scene A.
- rule.onNode(isElement(TestElements.Foo, SceneA)).assertIsDisplayed()
- rule.onNode(isElement(TestElements.Foo, SceneB)).assertExists().assertIsNotDisplayed()
- }
-
- @Test
- fun sharedMovableElementIsOnlyComposedInOverscrollingScene() {
- val state =
- rule.runOnUiThread {
- MutableSceneTransitionLayoutStateImpl(
- SceneA,
- transitions {
- overscrollDisabled(SceneA, Orientation.Horizontal)
- overscrollDisabled(SceneB, Orientation.Horizontal)
- },
- )
- }
-
- val fooInA = "fooInA"
- val fooInB = "fooInB"
-
- val key = MovableElementKey("Foo", contents = setOf(SceneA, SceneB))
-
- @Composable
- fun ContentScope.MovableFoo(text: String, modifier: Modifier = Modifier) {
- MovableElement(key, modifier) { content { Text(text) } }
- }
-
- val scope =
- rule.setContentAndCreateMainScope {
- SceneTransitionLayout(state) {
- scene(SceneA) { MovableFoo(text = fooInA) }
- scene(SceneB) { MovableFoo(text = fooInB) }
- }
- }
-
- rule.onNode(hasText(fooInA)).assertIsDisplayed()
- rule.onNode(hasText(fooInB)).assertDoesNotExist()
-
- // A => B while overscrolling at scene B.
- var progress by mutableStateOf(2f)
- scope.launch {
- state.startTransition(transition(from = SceneA, to = SceneB, progress = { progress }))
- }
- rule.waitForIdle()
-
- // Foo content should only be composed in scene B.
- rule.onNode(hasText(fooInA)).assertDoesNotExist()
- rule.onNode(hasText(fooInB)).assertIsDisplayed()
-
- // Overscroll at scene A.
- progress = -1f
- rule.waitForIdle()
-
- // Foo content should only be composed in scene A.
- rule.onNode(hasText(fooInA)).assertIsDisplayed()
- rule.onNode(hasText(fooInB)).assertDoesNotExist()
- }
-
- @Test
- fun interruptionThenOverscroll() {
- val state =
- rule.runOnUiThread {
- MutableSceneTransitionLayoutStateImpl(
- SceneA,
- transitions {
- overscroll(SceneB, Orientation.Vertical) {
- progressConverter = ProgressConverter.linear()
- translate(TestElements.Foo, y = 15.dp)
- }
- },
- )
- }
-
- @Composable
- fun ContentScope.SceneWithFoo(offset: DpOffset, modifier: Modifier = Modifier) {
- Box(modifier.fillMaxSize()) {
- Box(Modifier.offset(offset.x, offset.y).element(TestElements.Foo).size(100.dp))
- }
- }
-
- val scope =
- rule.setContentAndCreateMainScope {
- SceneTransitionLayout(state, Modifier.size(200.dp)) {
- scene(SceneA) { SceneWithFoo(offset = DpOffset.Zero) }
- scene(SceneB) { SceneWithFoo(offset = DpOffset(x = 40.dp, y = 0.dp)) }
- scene(SceneC) { SceneWithFoo(offset = DpOffset(x = 40.dp, y = 40.dp)) }
- }
- }
-
- // Start A => B at 75%.
- scope.launch {
- state.startTransition(
- transition(
- from = SceneA,
- to = SceneB,
- progress = { 0.75f },
- onFreezeAndAnimate = { /* never finish */ },
- )
- )
- }
-
- // Foo should be at offset (30dp, 0dp) and placed in scene B.
- rule.onNode(isElement(TestElements.Foo, SceneA)).assertIsNotDisplayed()
- rule.onNode(isElement(TestElements.Foo, SceneB)).assertPositionInRootIsEqualTo(30.dp, 0.dp)
- rule.onNode(isElement(TestElements.Foo, SceneC)).assertIsNotDisplayed()
-
- // Interrupt A => B with B => C at 0%.
- var progress by mutableStateOf(0f)
- var interruptionProgress by mutableStateOf(1f)
- scope.launch {
- state.startTransition(
- transition(
- from = SceneB,
- to = SceneC,
- progress = { progress },
- interruptionProgress = { interruptionProgress },
- orientation = Orientation.Vertical,
- onFreezeAndAnimate = { /* never finish */ },
- )
- )
- }
-
- // Because interruption progress is at 100M, Foo should still be at offset (30dp, 0dp) but
- // placed in scene C.
- rule.onNode(isElement(TestElements.Foo, SceneA)).assertIsNotDisplayed()
- rule.onNode(isElement(TestElements.Foo, SceneB)).assertIsNotDisplayed()
- rule.onNode(isElement(TestElements.Foo, SceneC)).assertPositionInRootIsEqualTo(30.dp, 0.dp)
-
- // Overscroll B => C on scene B at -100%. Because overscrolling on B => C translates Foo
- // vertically by -15dp and that interruptionProgress is still 100%, we should now be at
- // (30dp, -15dp)
- progress = -1f
- rule.onNode(isElement(TestElements.Foo, SceneA)).assertIsNotDisplayed()
- rule
- .onNode(isElement(TestElements.Foo, SceneB))
- .assertPositionInRootIsEqualTo(30.dp, -15.dp)
- rule.onNode(isElement(TestElements.Foo, SceneC)).assertIsNotDisplayed()
-
- // Finish the interruption, we should now be at (40dp, -15dp), still on scene B.
- interruptionProgress = 0f
- rule.onNode(isElement(TestElements.Foo, SceneA)).assertIsNotDisplayed()
- rule
- .onNode(isElement(TestElements.Foo, SceneB))
- .assertPositionInRootIsEqualTo(40.dp, -15.dp)
- rule.onNode(isElement(TestElements.Foo, SceneC)).assertIsNotDisplayed()
-
- // Finish the transition, we should be at the final position (40dp, 40dp) on scene C.
- progress = 1f
- rule.onNode(isElement(TestElements.Foo, SceneA)).assertIsNotDisplayed()
- rule.onNode(isElement(TestElements.Foo, SceneB)).assertIsNotDisplayed()
- rule.onNode(isElement(TestElements.Foo, SceneC)).assertPositionInRootIsEqualTo(40.dp, 40.dp)
- }
-
- @Test
fun lastPlacementValuesAreClearedOnNestedElements() {
val state = rule.runOnIdle { MutableSceneTransitionLayoutStateImpl(SceneA) }
@@ -2397,53 +1777,6 @@ class ElementTest {
}
@Test
- fun lastSizeIsUnspecifiedWhenOverscrollingOtherScene() {
- val state =
- rule.runOnIdle {
- MutableSceneTransitionLayoutStateImpl(
- SceneA,
- transitions { overscrollDisabled(SceneA, Orientation.Horizontal) },
- )
- }
-
- @Composable
- fun ContentScope.Foo() {
- Box(Modifier.element(TestElements.Foo).size(10.dp))
- }
-
- lateinit var layoutImpl: SceneTransitionLayoutImpl
- val scope =
- rule.setContentAndCreateMainScope {
- SceneTransitionLayoutForTesting(state, onLayoutImpl = { layoutImpl = it }) {
- scene(SceneA) { Foo() }
- scene(SceneB) { Foo() }
- }
- }
-
- // Overscroll A => B on A.
- scope.launch {
- state.startTransition(
- transition(
- from = SceneA,
- to = SceneB,
- progress = { -1f },
- onFreezeAndAnimate = { /* never finish */ },
- )
- )
- }
- rule.waitForIdle()
-
- assertThat(
- layoutImpl.elements
- .getValue(TestElements.Foo)
- .stateByContent
- .getValue(SceneB)
- .lastSize
- )
- .isEqualTo(Element.SizeUnspecified)
- }
-
- @Test
fun transparentElementIsNotImpactingInterruption() {
val state =
rule.runOnIdle {
@@ -2853,7 +2186,6 @@ class ElementTest {
// Start an overscrollable transition driven by progress.
var progress by mutableFloatStateOf(0f)
val transition = transition(from = SceneA, to = SceneB, progress = { progress })
- assertThat(transition).isInstanceOf(TransitionState.DirectionProperties::class.java)
scope.launch { state.startTransition(transition) }
// Reset the counters after the first animation frame.
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/NestedScrollToSceneTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/NestedScrollToSceneTest.kt
deleted file mode 100644
index 37dae39f935d..000000000000
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/NestedScrollToSceneTest.kt
+++ /dev/null
@@ -1,318 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.compose.animation.scene
-
-import androidx.compose.foundation.gestures.Orientation.Vertical
-import androidx.compose.foundation.gestures.rememberScrollableState
-import androidx.compose.foundation.gestures.scrollable
-import androidx.compose.foundation.layout.Spacer
-import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.foundation.layout.size
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.setValue
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.geometry.Offset
-import androidx.compose.ui.platform.LocalViewConfiguration
-import androidx.compose.ui.test.junit4.createComposeRule
-import androidx.compose.ui.test.onRoot
-import androidx.compose.ui.test.performTouchInput
-import androidx.compose.ui.unit.Dp
-import androidx.compose.ui.unit.dp
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import com.android.compose.animation.scene.TestScenes.SceneA
-import com.android.compose.animation.scene.TestScenes.SceneB
-import com.android.compose.animation.scene.subjects.assertThat
-import org.junit.Rule
-import org.junit.Test
-import org.junit.runner.RunWith
-
-@RunWith(AndroidJUnit4::class)
-class NestedScrollToSceneTest {
- @get:Rule val rule = createComposeRule()
-
- private var touchSlop = 0f
- private val layoutWidth: Dp = 200.dp
- private val layoutHeight = 400.dp
-
- private fun setup2ScenesAndScrollTouchSlop(
- modifierSceneA: @Composable ContentScope.() -> Modifier = { Modifier }
- ): MutableSceneTransitionLayoutState {
- val state =
- rule.runOnUiThread {
- MutableSceneTransitionLayoutState(SceneA, transitions = EmptyTestTransitions)
- }
-
- rule.setContent {
- touchSlop = LocalViewConfiguration.current.touchSlop
- SceneTransitionLayout(
- state = state,
- modifier = Modifier.size(layoutWidth, layoutHeight),
- ) {
- scene(SceneA, userActions = mapOf(Swipe.Up to SceneB)) {
- Spacer(modifierSceneA().fillMaxSize())
- }
- scene(SceneB, userActions = mapOf(Swipe.Down to SceneA)) {
- Spacer(Modifier.fillMaxSize())
- }
- }
- }
-
- pointerDownAndScrollTouchSlop()
-
- assertThat(state.transitionState).isIdle()
-
- return state
- }
-
- private fun pointerDownAndScrollTouchSlop() {
- rule.onRoot().performTouchInput {
- val middleTop = Offset((layoutWidth / 2).toPx(), 0f)
- down(middleTop)
- // Scroll touchSlop
- moveBy(Offset(0f, touchSlop), delayMillis = 1_000)
- }
- }
-
- private fun scrollDown(percent: Float = 1f) {
- rule.onRoot().performTouchInput {
- moveBy(Offset(0f, layoutHeight.toPx() * percent), delayMillis = 1_000)
- }
- }
-
- private fun scrollUp(percent: Float = 1f) = scrollDown(-percent)
-
- private fun pointerUp() {
- rule.onRoot().performTouchInput { up() }
- }
-
- @Test
- fun scrollableElementsInSTL_shouldHavePriority() {
- val state = setup2ScenesAndScrollTouchSlop {
- Modifier
- // A scrollable that consumes the scroll gesture
- .scrollable(rememberScrollableState { it }, Vertical)
- }
-
- scrollUp(percent = 0.5f)
-
- // Consumed by the scrollable element
- assertThat(state.transitionState).isIdle()
- }
-
- @Test
- fun unconsumedScrollEvents_canBeConsumedBySTLByDefault() {
- val state = setup2ScenesAndScrollTouchSlop {
- Modifier
- // A scrollable that does not consume the scroll gesture
- .scrollable(rememberScrollableState { 0f }, Vertical)
- }
-
- scrollUp(percent = 0.5f)
- // STL will start a transition with the remaining scroll
- val transition = assertThat(state.transitionState).isSceneTransition()
- assertThat(transition).hasProgress(0.5f)
-
- scrollUp(percent = 1f)
- assertThat(transition).hasProgress(1.5f)
- }
-
- @Test
- fun customizeStlNestedScrollBehavior_EdgeNoPreview() {
- var canScroll = true
- val state = setup2ScenesAndScrollTouchSlop {
- Modifier.verticalNestedScrollToScene(
- bottomBehavior = NestedScrollBehavior.EdgeNoPreview
- )
- .scrollable(rememberScrollableState { if (canScroll) it else 0f }, Vertical)
- }
-
- scrollUp(percent = 0.5f)
- assertThat(state.transitionState).isIdle()
-
- // Reach the end of the scrollable element
- canScroll = false
- scrollUp(percent = 0.5f)
- assertThat(state.transitionState).isIdle()
-
- pointerUp()
- assertThat(state.transitionState).isIdle()
-
- // Start a new gesture
- pointerDownAndScrollTouchSlop()
- scrollUp(percent = 0.5f)
- val transition = assertThat(state.transitionState).isSceneTransition()
- assertThat(transition).hasProgress(0.5f)
-
- pointerUp()
- rule.waitForIdle()
- assertThat(state.transitionState).isIdle()
- assertThat(state.transitionState).hasCurrentScene(SceneB)
- }
-
- @Test
- fun customizeStlNestedScrollBehavior_EdgeWithPreview() {
- var canScroll = true
- val state = setup2ScenesAndScrollTouchSlop {
- Modifier.verticalNestedScrollToScene(
- bottomBehavior = NestedScrollBehavior.EdgeWithPreview
- )
- .scrollable(rememberScrollableState { if (canScroll) it else 0f }, Vertical)
- }
-
- scrollUp(percent = 0.5f)
- assertThat(state.transitionState).isIdle()
-
- // Reach the end of the scrollable element
- canScroll = false
- scrollUp(percent = 0.5f)
- val transition1 = assertThat(state.transitionState).isSceneTransition()
- assertThat(transition1).hasProgress(0.5f)
-
- pointerUp()
- rule.waitForIdle()
- assertThat(state.transitionState).isIdle()
- assertThat(state.transitionState).hasCurrentScene(SceneA)
-
- // Start a new gesture
- pointerDownAndScrollTouchSlop()
- scrollUp(percent = 0.5f)
- val transition2 = assertThat(state.transitionState).isSceneTransition()
- assertThat(transition2).hasProgress(0.5f)
-
- pointerUp()
- rule.waitForIdle()
- assertThat(state.transitionState).isIdle()
- assertThat(state.transitionState).hasCurrentScene(SceneB)
- }
-
- @Test
- fun customizeStlNestedScrollBehavior_EdgeAlways() {
- var canScroll = true
- val state = setup2ScenesAndScrollTouchSlop {
- Modifier.verticalNestedScrollToScene(bottomBehavior = NestedScrollBehavior.EdgeAlways)
- .scrollable(rememberScrollableState { if (canScroll) it else 0f }, Vertical)
- }
-
- scrollUp(percent = 0.5f)
- assertThat(state.transitionState).isIdle()
-
- // Reach the end of the scrollable element
- canScroll = false
- scrollUp(percent = 0.5f)
- val transition = assertThat(state.transitionState).isSceneTransition()
- assertThat(transition).hasProgress(0.5f)
-
- pointerUp()
- rule.waitForIdle()
- assertThat(state.transitionState).isIdle()
- assertThat(state.transitionState).hasCurrentScene(SceneB)
- }
-
- @Test
- fun stlNotConsumeUnobservedGesture() {
- val state =
- rule.runOnUiThread {
- MutableSceneTransitionLayoutState(SceneA, transitions = EmptyTestTransitions)
- }
-
- rule.setContent {
- touchSlop = LocalViewConfiguration.current.touchSlop
- SceneTransitionLayout(
- state = state,
- modifier = Modifier.size(layoutWidth, layoutHeight),
- ) {
- scene(SceneA) {
- Spacer(
- Modifier.verticalNestedScrollToScene()
- // This scrollable will not consume the gesture.
- .scrollable(rememberScrollableState { 0f }, Vertical)
- .fillMaxSize()
- )
- }
- }
- }
-
- rule.onRoot().performTouchInput {
- down(Offset.Zero)
- // There is no vertical scene.
- moveBy(Offset(0f, layoutWidth.toPx()), delayMillis = 1_000)
- }
-
- rule.waitForIdle()
- assertThat(state.transitionState).isIdle()
- }
-
- @Test
- fun customizeStlNestedScrollBehavior_multipleRequests() {
- var canScroll = true
- val state = setup2ScenesAndScrollTouchSlop {
- Modifier
- // This verticalNestedScrollToScene is closer the STL (an ancestor node)
- .verticalNestedScrollToScene(bottomBehavior = NestedScrollBehavior.EdgeAlways)
- // Another verticalNestedScrollToScene modifier
- .verticalNestedScrollToScene(bottomBehavior = NestedScrollBehavior.EdgeNoPreview)
- .scrollable(rememberScrollableState { if (canScroll) it else 0f }, Vertical)
- }
-
- scrollUp(percent = 0.5f)
- assertThat(state.transitionState).isIdle()
-
- // Reach the end of the scrollable element
- canScroll = false
-
- scrollUp(percent = 0.5f)
- // EdgeAlways always consume the remaining scroll, EdgeNoPreview does not.
- val transition = assertThat(state.transitionState).isSceneTransition()
- assertThat(transition).hasProgress(0.5f)
- }
-
- @Test
- fun resetScrollTracking_afterMissingPointerUpEvent() {
- var canScroll = true
- var hasScrollable by mutableStateOf(true)
- val state = setup2ScenesAndScrollTouchSlop {
- if (hasScrollable) {
- Modifier.scrollable(rememberScrollableState { if (canScroll) it else 0f }, Vertical)
- } else {
- Modifier
- }
- }
-
- // The gesture is consumed by the component in the scene.
- scrollUp(percent = 0.2f)
-
- // STL keeps track of the scroll consumed. The scene remains in Idle.
- assertThat(state.transitionState).isIdle()
-
- // The scrollable component disappears, and does not send the signal (pointer up) to reset
- // the consumed amount.
- hasScrollable = false
- pointerUp()
-
- // A new scrollable component appears and allows the scene to consume the scroll.
- hasScrollable = true
- canScroll = false
- pointerDownAndScrollTouchSlop()
- scrollUp(percent = 0.2f)
-
- // STL can only start the transition if it has reset the amount of scroll consumed.
- val transition = assertThat(state.transitionState).isSceneTransition()
- assertThat(transition).hasProgress(0.2f)
- }
-}
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/OverlayTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/OverlayTest.kt
index 7ea414d6b8cd..bad4c6298e6b 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/OverlayTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/OverlayTest.kt
@@ -19,7 +19,6 @@ package com.android.compose.animation.scene
import androidx.compose.animation.core.LinearEasing
import androidx.compose.animation.core.tween
import androidx.compose.foundation.ScrollState
-import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.size
@@ -46,7 +45,6 @@ import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.onRoot
import androidx.compose.ui.test.performTouchInput
import androidx.compose.ui.test.swipe
-import androidx.compose.ui.test.swipeUp
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -56,7 +54,6 @@ import com.android.compose.animation.scene.TestScenes.SceneA
import com.android.compose.animation.scene.subjects.assertThat
import com.android.compose.test.assertSizeIsEqualTo
import com.android.compose.test.setContentAndCreateMainScope
-import com.android.compose.test.subjects.assertThat
import com.android.compose.test.transition
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.CoroutineScope
@@ -745,18 +742,7 @@ class OverlayTest {
@Test
fun overscrollingOverlay_movableElementNotInOverlay() {
- val state =
- rule.runOnUiThread {
- MutableSceneTransitionLayoutStateImpl(
- SceneA,
- transitions {
- // Make OverlayA overscrollable.
- overscroll(OverlayA, orientation = Orientation.Horizontal) {
- translate(ElementKey("elementThatDoesNotExist"), x = 10.dp)
- }
- },
- )
- }
+ val state = rule.runOnUiThread { MutableSceneTransitionLayoutStateImpl(SceneA) }
val key = MovableElementKey("Foo", contents = setOf(SceneA))
val movableElementChildTag = "movableElementChildTag"
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutStateTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutStateTest.kt
index 3b7d661ba91a..d1bd52b56ddd 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutStateTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutStateTest.kt
@@ -17,8 +17,6 @@
package com.android.compose.animation.scene
import android.util.Log
-import androidx.compose.foundation.gestures.Orientation
-import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.compose.animation.scene.TestScenes.SceneA
@@ -27,7 +25,6 @@ import com.android.compose.animation.scene.TestScenes.SceneC
import com.android.compose.animation.scene.content.state.TransitionState
import com.android.compose.animation.scene.subjects.assertThat
import com.android.compose.animation.scene.transition.seekToScene
-import com.android.compose.test.MonotonicClockTestScope
import com.android.compose.test.TestSceneTransition
import com.android.compose.test.runMonotonicClockTest
import com.android.compose.test.transition
@@ -166,115 +163,6 @@ class SceneTransitionLayoutStateTest {
assertThat(state.currentTransition?.transformationSpec?.transformationMatchers).hasSize(2)
}
- private fun MonotonicClockTestScope.startOverscrollableTransistionFromAtoB(
- progress: () -> Float,
- sceneTransitions: SceneTransitions,
- ): MutableSceneTransitionLayoutStateImpl {
- val state = MutableSceneTransitionLayoutStateImpl(SceneA, sceneTransitions)
- state.startTransitionImmediately(
- animationScope = backgroundScope,
- transition(
- from = SceneA,
- to = SceneB,
- progress = progress,
- orientation = Orientation.Vertical,
- ),
- )
- assertThat(state.isTransitioning()).isTrue()
- return state
- }
-
- @Test
- fun overscrollDsl_definedForToScene() = runMonotonicClockTest {
- val progress = mutableStateOf(0f)
- val state =
- startOverscrollableTransistionFromAtoB(
- progress = { progress.value },
- sceneTransitions =
- transitions {
- overscroll(SceneB, Orientation.Vertical) { fade(TestElements.Foo) }
- },
- )
- val transition = assertThat(state.transitionState).isSceneTransition()
- assertThat(transition).hasNoOverscrollSpec()
-
- // overscroll for SceneA is NOT defined
- progress.value = -0.1f
- assertThat(transition).hasNoOverscrollSpec()
-
- // scroll from SceneA to SceneB
- progress.value = 0.5f
- assertThat(transition).hasNoOverscrollSpec()
-
- progress.value = 1f
- assertThat(transition).hasNoOverscrollSpec()
-
- // overscroll for SceneB is defined
- progress.value = 1.1f
- val overscrollSpec = assertThat(transition).hasOverscrollSpec()
- assertThat(overscrollSpec.content).isEqualTo(SceneB)
- }
-
- @Test
- fun overscrollDsl_definedForFromScene() = runMonotonicClockTest {
- val progress = mutableStateOf(0f)
- val state =
- startOverscrollableTransistionFromAtoB(
- progress = { progress.value },
- sceneTransitions =
- transitions {
- overscroll(SceneA, Orientation.Vertical) { fade(TestElements.Foo) }
- },
- )
-
- val transition = assertThat(state.transitionState).isSceneTransition()
- assertThat(transition).hasNoOverscrollSpec()
-
- // overscroll for SceneA is defined
- progress.value = -0.1f
- val overscrollSpec = assertThat(transition).hasOverscrollSpec()
- assertThat(overscrollSpec.content).isEqualTo(SceneA)
-
- // scroll from SceneA to SceneB
- progress.value = 0.5f
- assertThat(transition).hasNoOverscrollSpec()
-
- progress.value = 1f
- assertThat(transition).hasNoOverscrollSpec()
-
- // overscroll for SceneB is NOT defined
- progress.value = 1.1f
- assertThat(transition).hasNoOverscrollSpec()
- }
-
- @Test
- fun overscrollDsl_notDefinedScenes() = runMonotonicClockTest {
- val progress = mutableStateOf(0f)
- val state =
- startOverscrollableTransistionFromAtoB(
- progress = { progress.value },
- sceneTransitions = transitions {},
- )
-
- val transition = assertThat(state.transitionState).isSceneTransition()
- assertThat(transition).hasNoOverscrollSpec()
-
- // overscroll for SceneA is NOT defined
- progress.value = -0.1f
- assertThat(transition).hasNoOverscrollSpec()
-
- // scroll from SceneA to SceneB
- progress.value = 0.5f
- assertThat(transition).hasNoOverscrollSpec()
-
- progress.value = 1f
- assertThat(transition).hasNoOverscrollSpec()
-
- // overscroll for SceneB is NOT defined
- progress.value = 1.1f
- assertThat(transition).hasNoOverscrollSpec()
- }
-
@Test
fun multipleTransitions() = runTest {
val frozenTransitions = mutableSetOf<TestSceneTransition>()
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutTest.kt
index b00b894b5dea..fdbd0f63292a 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutTest.kt
@@ -20,7 +20,6 @@ import androidx.compose.animation.core.FastOutSlowInEasing
import androidx.compose.animation.core.LinearEasing
import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
-import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.offset
@@ -28,7 +27,6 @@ import androidx.compose.foundation.layout.size
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
@@ -55,13 +53,11 @@ import com.android.compose.animation.scene.TestScenes.SceneB
import com.android.compose.animation.scene.TestScenes.SceneC
import com.android.compose.animation.scene.subjects.assertThat
import com.android.compose.test.assertSizeIsEqualTo
-import com.android.compose.test.setContentAndCreateMainScope
import com.android.compose.test.subjects.DpOffsetSubject
import com.android.compose.test.subjects.assertThat
import com.android.compose.test.transition
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.launch
import org.junit.Assert.assertThrows
import org.junit.Rule
import org.junit.Test
@@ -311,43 +307,6 @@ class SceneTransitionLayoutTest {
}
@Test
- fun layoutSizeDoesNotOverscrollWhenOverscrollIsSpecified() {
- val state =
- rule.runOnUiThread {
- MutableSceneTransitionLayoutStateImpl(
- SceneA,
- transitions { overscrollDisabled(SceneB, Orientation.Horizontal) },
- )
- }
-
- val layoutTag = "layout"
- val scope =
- rule.setContentAndCreateMainScope {
- SceneTransitionLayout(state, Modifier.testTag(layoutTag)) {
- scene(SceneA) { Box(Modifier.size(50.dp)) }
- scene(SceneB) { Box(Modifier.size(70.dp)) }
- }
- }
-
- // Overscroll on A at -100%: size should be interpolated given that there is no overscroll
- // defined for scene A.
- var progress by mutableStateOf(-1f)
- scope.launch {
- state.startTransition(transition(from = SceneA, to = SceneB, progress = { progress }))
- }
- rule.onNodeWithTag(layoutTag).assertSizeIsEqualTo(30.dp)
-
- // Middle of the transition.
- progress = 0.5f
- rule.onNodeWithTag(layoutTag).assertSizeIsEqualTo(60.dp)
-
- // Overscroll on B at 200%: size should not be interpolated given that there is an
- // overscroll defined for scene B.
- progress = 2f
- rule.onNodeWithTag(layoutTag).assertSizeIsEqualTo(70.dp)
- }
-
- @Test
fun multipleTransitionsWillComposeMultipleScenes() {
val duration = 10 * 16L
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SwipeToSceneTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SwipeToSceneTest.kt
index fe7b5b6bf4da..9135fdd15b3a 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SwipeToSceneTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SwipeToSceneTest.kt
@@ -35,9 +35,6 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
-import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
-import androidx.compose.ui.input.nestedscroll.NestedScrollSource
-import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.input.pointer.PointerType
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.platform.LocalViewConfiguration
@@ -735,46 +732,6 @@ class SwipeToSceneTest {
}
@Test
- fun overscrollScopeExtendsDensity() {
- val swipeDistance = 100.dp
- val state =
- rule.runOnUiThread {
- MutableSceneTransitionLayoutState(
- SceneA,
- transitions {
- from(SceneA, to = SceneB) { distance = FixedDistance(swipeDistance) }
-
- overscroll(SceneB, Orientation.Vertical) {
- progressConverter = ProgressConverter.linear()
- translate(TestElements.Foo, x = { 20.dp.toPx() }, y = { 30.dp.toPx() })
- }
- },
- )
- }
- val layoutSize = 200.dp
- var touchSlop = 0f
- rule.setContent {
- touchSlop = LocalViewConfiguration.current.touchSlop
- SceneTransitionLayout(state, Modifier.size(layoutSize)) {
- scene(SceneA, userActions = mapOf(Swipe.Down to SceneB)) {
- Box(Modifier.fillMaxSize())
- }
- scene(SceneB) { Box(Modifier.element(TestElements.Foo).fillMaxSize()) }
- }
- }
-
- // Swipe down by twice the swipe distance so that we are at 100% overscrolling on scene B.
- rule.onRoot().performTouchInput {
- val middle = (layoutSize / 2).toPx()
- down(Offset(middle, middle))
- moveBy(Offset(0f, touchSlop + (swipeDistance * 2).toPx()), delayMillis = 1_000)
- }
-
- // Foo should be translated by (20dp, 30dp).
- rule.onNode(isElement(TestElements.Foo)).assertPositionInRootIsEqualTo(20.dp, 30.dp)
- }
-
- @Test
fun startEnd_ltrLayout() {
val state =
rule.runOnUiThread {
@@ -923,128 +880,6 @@ class SwipeToSceneTest {
}
@Test
- fun whenOverscrollIsDisabled_dragGestureShouldNotBeConsumed() {
- val swipeDistance = 100.dp
-
- var availableOnPostScroll = Float.MIN_VALUE
- val connection =
- object : NestedScrollConnection {
- override fun onPostScroll(
- consumed: Offset,
- available: Offset,
- source: NestedScrollSource,
- ): Offset {
- availableOnPostScroll = available.y
- return super.onPostScroll(consumed, available, source)
- }
- }
- val state =
- rule.runOnUiThread {
- MutableSceneTransitionLayoutState(
- SceneA,
- transitions {
- from(SceneA, to = SceneB) { distance = FixedDistance(swipeDistance) }
- overscrollDisabled(SceneB, Orientation.Vertical)
- },
- )
- }
- val layoutSize = 200.dp
- var touchSlop = 0f
- rule.setContent {
- touchSlop = LocalViewConfiguration.current.touchSlop
- SceneTransitionLayout(state, Modifier.size(layoutSize).nestedScroll(connection)) {
- scene(SceneA, userActions = mapOf(Swipe.Down to SceneB)) {
- Box(Modifier.fillMaxSize())
- }
- scene(SceneB) { Box(Modifier.element(TestElements.Foo).fillMaxSize()) }
- }
- }
-
- // Swipe down by the swipe distance so that we are on scene B.
- rule.onRoot().performTouchInput {
- val middle = (layoutSize / 2).toPx()
- down(Offset(middle, middle))
- moveBy(Offset(0f, touchSlop + (swipeDistance).toPx()), delayMillis = 1_000)
- }
- val transition = state.currentTransition
- assertThat(transition).isNotNull()
- assertThat(transition!!.progress).isEqualTo(1f)
- assertThat(availableOnPostScroll).isEqualTo(0f)
-
- // Overscrolling on Scene B
- val ovescrollPx = 100f
- rule.onRoot().performTouchInput { moveBy(Offset(0f, ovescrollPx), delayMillis = 1_000) }
- // Overscroll is disabled on Scene B
- assertThat(transition.progress).isEqualTo(1f)
- assertThat(availableOnPostScroll).isEqualTo(ovescrollPx)
- }
-
- @Test
- fun scrollKeepPriorityEvenIfWeCanNoLongerScrollOnThatDirection() {
- val swipeDistance = 100.dp
- val state =
- rule.runOnUiThread {
- MutableSceneTransitionLayoutState(
- SceneA,
- transitions {
- from(SceneA, to = SceneB) { distance = FixedDistance(swipeDistance) }
- from(SceneB, to = SceneC) { distance = FixedDistance(swipeDistance) }
- overscrollDisabled(SceneB, Orientation.Vertical)
- },
- )
- }
- val layoutSize = 200.dp
- var touchSlop = 0f
- rule.setContent {
- touchSlop = LocalViewConfiguration.current.touchSlop
- SceneTransitionLayout(state, Modifier.size(layoutSize)) {
- scene(SceneA, userActions = mapOf(Swipe.Down to SceneB, Swipe.Right to SceneC)) {
- Box(
- Modifier.fillMaxSize()
- // A scrollable that does not consume the scroll gesture
- .scrollable(rememberScrollableState { 0f }, Orientation.Vertical)
- )
- }
- scene(SceneB, userActions = mapOf(Swipe.Right to SceneC)) {
- Box(Modifier.element(TestElements.Foo).fillMaxSize())
- }
- scene(SceneC) { Box(Modifier.fillMaxSize()) }
- }
- }
-
- fun assertTransition(from: SceneKey, to: SceneKey, progress: Float) {
- val transition = assertThat(state.transitionState).isSceneTransition()
- assertThat(transition).hasFromScene(from)
- assertThat(transition).hasToScene(to)
- assertThat(transition.progress).isEqualTo(progress)
- }
-
- // Vertical scroll 100%
- rule.onRoot().performTouchInput {
- val middle = (layoutSize / 2).toPx()
- down(Offset(middle, middle))
- moveBy(Offset(0f, y = touchSlop + swipeDistance.toPx()), delayMillis = 1_000)
- }
- assertTransition(from = SceneA, to = SceneB, progress = 1f)
-
- // Continue vertical scroll, should be ignored (overscrollDisabled)
- rule.onRoot().performTouchInput { moveBy(Offset(0f, y = touchSlop), delayMillis = 1_000) }
- assertTransition(from = SceneA, to = SceneB, progress = 1f)
-
- // Horizontal scroll, should be ignored
- rule.onRoot().performTouchInput {
- moveBy(Offset(x = touchSlop + swipeDistance.toPx(), 0f), delayMillis = 1_000)
- }
- assertTransition(from = SceneA, to = SceneB, progress = 1f)
-
- // Vertical scroll, in the opposite direction
- rule.onRoot().performTouchInput {
- moveBy(Offset(0f, -swipeDistance.toPx()), delayMillis = 1_000)
- }
- assertTransition(from = SceneA, to = SceneB, progress = 0f)
- }
-
- @Test
fun sceneWithoutSwipesDoesNotConsumeGestures() {
val buttonTag = "button"
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/TransitionDslTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/TransitionDslTest.kt
index 70f2ff80f9d7..cb87fe849a81 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/TransitionDslTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/TransitionDslTest.kt
@@ -21,7 +21,6 @@ import androidx.compose.animation.core.SpringSpec
import androidx.compose.animation.core.TweenSpec
import androidx.compose.animation.core.spring
import androidx.compose.animation.core.tween
-import androidx.compose.foundation.gestures.Orientation
import androidx.compose.ui.unit.IntSize
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.compose.animation.scene.TestScenes.SceneA
@@ -29,7 +28,6 @@ import com.android.compose.animation.scene.TestScenes.SceneB
import com.android.compose.animation.scene.TestScenes.SceneC
import com.android.compose.animation.scene.content.state.TransitionState
import com.android.compose.animation.scene.transformation.CustomPropertyTransformation
-import com.android.compose.animation.scene.transformation.OverscrollTranslate
import com.android.compose.animation.scene.transformation.PropertyTransformation
import com.android.compose.animation.scene.transformation.PropertyTransformationScope
import com.android.compose.animation.scene.transformation.TransformationMatcher
@@ -308,34 +306,6 @@ class TransitionDslTest {
}
@Test
- fun overscrollSpec() {
- val transitions = transitions {
- overscroll(SceneA, Orientation.Vertical) {
- translate(TestElements.Bar, x = { 1f }, y = { 2f })
- }
- }
-
- val overscrollSpec = transitions.overscrollSpecs.single()
- val transformation =
- overscrollSpec.transformationSpec.transformationMatchers.single().factory.create()
- assertThat(transformation).isInstanceOf(OverscrollTranslate::class.java)
- }
-
- @Test
- fun overscrollSpec_for_overscrollDisabled() {
- val transitions = transitions { overscrollDisabled(SceneA, Orientation.Vertical) }
- val overscrollSpec = transitions.overscrollSpecs.single()
- assertThat(overscrollSpec.transformationSpec.transformationMatchers).isEmpty()
- }
-
- @Test
- fun overscrollSpec_throwIfTransformationsIsEmpty() {
- assertThrows(IllegalStateException::class.java) {
- transitions { overscroll(SceneA, Orientation.Vertical) {} }
- }
- }
-
- @Test
fun transitionIsPassedToBuilder() = runTest {
var transitionPassedToBuilder: TransitionState.Transition? = null
val state =
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/subjects/TransitionStateSubject.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/subjects/TransitionStateSubject.kt
index 9a2af640c46f..6db98a874787 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/subjects/TransitionStateSubject.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/subjects/TransitionStateSubject.kt
@@ -16,9 +16,7 @@
package com.android.compose.animation.scene.subjects
-import com.android.compose.animation.scene.ContentKey
import com.android.compose.animation.scene.OverlayKey
-import com.android.compose.animation.scene.OverscrollSpec
import com.android.compose.animation.scene.SceneKey
import com.android.compose.animation.scene.content.state.TransitionState
import com.google.common.truth.Fact.simpleFact
@@ -156,26 +154,6 @@ abstract class BaseTransitionSubject<T : TransitionState.Transition>(
fun hasIsUserInputOngoing(isUserInputOngoing: Boolean) {
check("isUserInputOngoing").that(actual.isUserInputOngoing).isEqualTo(isUserInputOngoing)
}
-
- internal fun hasOverscrollSpec(): OverscrollSpec {
- check("currentOverscrollSpec").that(actual.currentOverscrollSpec).isNotNull()
- return actual.currentOverscrollSpec!!
- }
-
- fun hasNoOverscrollSpec() {
- check("currentOverscrollSpec").that(actual.currentOverscrollSpec).isNull()
- }
-
- fun hasBouncingContent(content: ContentKey) {
- val actual = actual
- if (actual !is TransitionState.DirectionProperties) {
- failWithActual(simpleFact("expected to be ContentState.HasOverscrollProperties"))
- }
-
- check("bouncingContent")
- .that((actual as TransitionState.DirectionProperties).bouncingContent)
- .isEqualTo(content)
- }
}
class SceneTransitionSubject
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/nestedscroll/LargeTopAppBarNestedScrollConnectionTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/nestedscroll/LargeTopAppBarNestedScrollConnectionTest.kt
index c8fb2cb8474f..53bb14fec22f 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/nestedscroll/LargeTopAppBarNestedScrollConnectionTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/nestedscroll/LargeTopAppBarNestedScrollConnectionTest.kt
@@ -19,7 +19,6 @@ package com.android.compose.nestedscroll
import androidx.compose.foundation.gestures.FlingBehavior
import androidx.compose.foundation.gestures.ScrollScope
import androidx.compose.ui.geometry.Offset
-import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
import androidx.compose.ui.input.nestedscroll.NestedScrollSource
import com.google.common.truth.Truth.assertThat
import org.junit.Test
@@ -48,15 +47,6 @@ class LargeTopAppBarNestedScrollConnectionTest(testCase: TestCase) {
flingBehavior = customFlingBehavior,
)
- private fun NestedScrollConnection.scroll(
- available: Offset,
- consumedByScroll: Offset = Offset.Zero,
- ) {
- val consumedByPreScroll = onPreScroll(available = available, source = scrollSource)
- val consumed = consumedByPreScroll + consumedByScroll
- onPostScroll(consumed = consumed, available = available - consumed, source = scrollSource)
- }
-
@Test
fun onScrollUp_consumeHeightFirst() {
val scrollConnection = buildScrollConnection(heightRange = 0f..2f)
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/test/TestOverlayTransition.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/test/TestOverlayTransition.kt
index 6015479d8e21..b9d01c2eaa3b 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/test/TestOverlayTransition.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/test/TestOverlayTransition.kt
@@ -16,12 +16,9 @@
package com.android.compose.test
-import androidx.compose.foundation.gestures.Orientation
-import com.android.compose.animation.scene.ContentKey
import com.android.compose.animation.scene.OverlayKey
import com.android.compose.animation.scene.SceneKey
import com.android.compose.animation.scene.SceneTransitionLayoutImpl
-import com.android.compose.animation.scene.content.state.TransitionState
import com.android.compose.animation.scene.content.state.TransitionState.Transition
import kotlinx.coroutines.CompletableDeferred
@@ -63,15 +60,10 @@ fun transition(
interruptionProgress: () -> Float = { 0f },
isInitiatedByUserInput: Boolean = false,
isUserInputOngoing: Boolean = false,
- isUpOrLeft: Boolean = false,
- bouncingContent: ContentKey? = null,
- orientation: Orientation = Orientation.Horizontal,
onFreezeAndAnimate: ((TestOverlayTransition) -> Unit)? = null,
replacedTransition: Transition? = null,
): TestOverlayTransition {
- return object :
- TestOverlayTransition(fromScene, overlay, replacedTransition),
- TransitionState.DirectionProperties {
+ return object : TestOverlayTransition(fromScene, overlay, replacedTransition) {
override val isEffectivelyShown: Boolean
get() = isEffectivelyShown()
@@ -92,10 +84,6 @@ fun transition(
override val isInitiatedByUserInput: Boolean = isInitiatedByUserInput
override val isUserInputOngoing: Boolean = isUserInputOngoing
- override val isUpOrLeft: Boolean = isUpOrLeft
- override val bouncingContent: ContentKey? = bouncingContent
- override val orientation: Orientation = orientation
- override val absoluteDistance = 0f
override fun freezeAndAnimateToCurrentState() {
if (onFreezeAndAnimate != null) {
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/test/TestReplaceOverlayTransition.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/test/TestReplaceOverlayTransition.kt
index bd2118dd8395..983c429aa58e 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/test/TestReplaceOverlayTransition.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/test/TestReplaceOverlayTransition.kt
@@ -16,11 +16,8 @@
package com.android.compose.test
-import androidx.compose.foundation.gestures.Orientation
-import com.android.compose.animation.scene.ContentKey
import com.android.compose.animation.scene.OverlayKey
import com.android.compose.animation.scene.SceneTransitionLayoutImpl
-import com.android.compose.animation.scene.content.state.TransitionState
import com.android.compose.animation.scene.content.state.TransitionState.Transition
import kotlinx.coroutines.CompletableDeferred
@@ -60,15 +57,10 @@ fun transition(
interruptionProgress: () -> Float = { 0f },
isInitiatedByUserInput: Boolean = false,
isUserInputOngoing: Boolean = false,
- isUpOrLeft: Boolean = false,
- bouncingContent: ContentKey? = null,
- orientation: Orientation = Orientation.Horizontal,
onFreezeAndAnimate: ((TestReplaceOverlayTransition) -> Unit)? = null,
replacedTransition: Transition? = null,
): TestReplaceOverlayTransition {
- return object :
- TestReplaceOverlayTransition(from, to, replacedTransition),
- TransitionState.DirectionProperties {
+ return object : TestReplaceOverlayTransition(from, to, replacedTransition) {
override val effectivelyShownOverlay: OverlayKey
get() = effectivelyShownOverlay()
@@ -89,10 +81,6 @@ fun transition(
override val isInitiatedByUserInput: Boolean = isInitiatedByUserInput
override val isUserInputOngoing: Boolean = isUserInputOngoing
- override val isUpOrLeft: Boolean = isUpOrLeft
- override val bouncingContent: ContentKey? = bouncingContent
- override val orientation: Orientation = orientation
- override val absoluteDistance = 0f
override fun freezeAndAnimateToCurrentState() {
if (onFreezeAndAnimate != null) {
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/test/TestSceneTransition.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/test/TestSceneTransition.kt
index 1d27e3a3f191..d11951ee4b24 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/test/TestSceneTransition.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/test/TestSceneTransition.kt
@@ -16,11 +16,8 @@
package com.android.compose.test
-import androidx.compose.foundation.gestures.Orientation
-import com.android.compose.animation.scene.ContentKey
import com.android.compose.animation.scene.SceneKey
import com.android.compose.animation.scene.SceneTransitionLayoutImpl
-import com.android.compose.animation.scene.content.state.TransitionState
import com.android.compose.animation.scene.content.state.TransitionState.Transition
import kotlinx.coroutines.CompletableDeferred
@@ -55,14 +52,10 @@ fun transition(
interruptionProgress: () -> Float = { 0f },
isInitiatedByUserInput: Boolean = false,
isUserInputOngoing: Boolean = false,
- isUpOrLeft: Boolean = false,
- bouncingContent: ContentKey? = null,
- orientation: Orientation = Orientation.Horizontal,
onFreezeAndAnimate: ((TestSceneTransition) -> Unit)? = null,
replacedTransition: Transition? = null,
): TestSceneTransition {
- return object :
- TestSceneTransition(from, to, replacedTransition), TransitionState.DirectionProperties {
+ return object : TestSceneTransition(from, to, replacedTransition) {
override val currentScene: SceneKey
get() = current()
@@ -83,10 +76,6 @@ fun transition(
override val isInitiatedByUserInput: Boolean = isInitiatedByUserInput
override val isUserInputOngoing: Boolean = isUserInputOngoing
- override val isUpOrLeft: Boolean = isUpOrLeft
- override val bouncingContent: ContentKey? = bouncingContent
- override val orientation: Orientation = orientation
- override val absoluteDistance = 0f
override fun freezeAndAnimateToCurrentState() {
if (onFreezeAndAnimate != null) {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/external/TileServiceRequestControllerTestComposeOn.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/external/TileServiceRequestControllerTestComposeOn.kt
index f02856c2f5ae..f48027beef12 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/external/TileServiceRequestControllerTestComposeOn.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/external/TileServiceRequestControllerTestComposeOn.kt
@@ -148,7 +148,7 @@ class TileServiceRequestControllerTestComposeOn : SysuiTestCase() {
@Test
fun showAllUsers_set() =
kosmos.runTest {
- val dialog = runOnMainThreadAndWaitForIdleSync {
+ val dialog = createDialog {
underTest.requestTileAdd(
TEST_UID,
TEST_COMPONENT,
@@ -158,7 +158,6 @@ class TileServiceRequestControllerTestComposeOn : SysuiTestCase() {
Callback(),
)!!
}
- onTeardown { dialog.cancel() }
assertThat(dialog.isShowForAllUsers).isTrue()
}
@@ -166,7 +165,7 @@ class TileServiceRequestControllerTestComposeOn : SysuiTestCase() {
@Test
fun cancelOnTouchOutside_set() =
kosmos.runTest {
- val dialog = runOnMainThreadAndWaitForIdleSync {
+ val dialog = createDialog {
underTest.requestTileAdd(
TEST_UID,
TEST_COMPONENT,
@@ -176,11 +175,16 @@ class TileServiceRequestControllerTestComposeOn : SysuiTestCase() {
Callback(),
)!!
}
- onTeardown { dialog.cancel() }
assertThat(dialog.isCancelOnTouchOutside).isTrue()
}
+ fun <T : DialogInterface> createDialog(constructor: () -> T): T {
+ val dialog = runOnMainThreadAndWaitForIdleSync { constructor() }
+ onTeardown { runOnMainThreadAndWaitForIdleSync { dialog.cancel() } }
+ return dialog
+ }
+
@Test
fun positiveAction_tileAdded() =
kosmos.runTest {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ShadeDisplayChangeLatencyTrackerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ShadeDisplayChangeLatencyTrackerTest.kt
new file mode 100644
index 000000000000..56356b4489f8
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ShadeDisplayChangeLatencyTrackerTest.kt
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.shade
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.internal.logging.latencyTracker
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.common.ui.data.repository.fakeConfigurationRepository
+import com.android.systemui.common.ui.view.fakeChoreographerUtils
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.kosmos.useUnconfinedTestDispatcher
+import com.android.systemui.testKosmos
+import kotlin.test.Test
+import kotlin.time.Duration.Companion.seconds
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.advanceTimeBy
+import kotlinx.coroutines.test.runTest
+import org.junit.runner.RunWith
+import org.mockito.Mockito.never
+import org.mockito.Mockito.times
+import org.mockito.Mockito.verify
+import org.mockito.kotlin.any
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class ShadeDisplayChangeLatencyTrackerTest : SysuiTestCase() {
+ private val kosmos = testKosmos().useUnconfinedTestDispatcher()
+ private val configurationRepository = kosmos.fakeConfigurationRepository
+ private val latencyTracker = kosmos.latencyTracker
+ private val testScope = kosmos.testScope
+ private val choreographerUtils = kosmos.fakeChoreographerUtils
+
+ private val underTest = kosmos.shadeDisplayChangeLatencyTracker
+
+ @Test
+ fun onShadeDisplayChanging_afterMovedToDisplayAndDoFrameCompleted_atomReported() =
+ testScope.runTest {
+ underTest.onShadeDisplayChanging(1)
+
+ verify(latencyTracker).onActionStart(any())
+ verify(latencyTracker, never()).onActionEnd(any())
+
+ sendOnMovedToDisplay(1)
+ choreographerUtils.completeDoFrame()
+
+ verify(latencyTracker).onActionEnd(any())
+ }
+
+ @OptIn(ExperimentalCoroutinesApi::class)
+ @Test
+ fun onChange_doFrameTimesOut_previousCancelled() =
+ testScope.runTest {
+ underTest.onShadeDisplayChanging(1)
+
+ verify(latencyTracker).onActionStart(any())
+ verify(latencyTracker, never()).onActionEnd(any())
+
+ sendOnMovedToDisplay(1)
+ advanceTimeBy(100.seconds)
+
+ verify(latencyTracker, never()).onActionEnd(any())
+ verify(latencyTracker).onActionCancel(any())
+ }
+
+ @OptIn(ExperimentalCoroutinesApi::class)
+ @Test
+ fun onChange_onMovedToDisplayTimesOut_cancelled() =
+ testScope.runTest {
+ underTest.onShadeDisplayChanging(1)
+
+ verify(latencyTracker).onActionStart(any())
+
+ choreographerUtils.completeDoFrame()
+ advanceTimeBy(100.seconds)
+
+ verify(latencyTracker).onActionCancel(any())
+ }
+
+ @Test
+ fun onChange_whilePreviousWasInProgress_previousCancelledAndNewStarted() =
+ testScope.runTest {
+ underTest.onShadeDisplayChanging(1)
+
+ verify(latencyTracker).onActionStart(any())
+
+ underTest.onShadeDisplayChanging(2)
+
+ verify(latencyTracker).onActionCancel(any())
+ verify(latencyTracker, times(2)).onActionStart(any())
+ }
+
+ @Test
+ fun onChange_multiple_multipleReported() =
+ testScope.runTest {
+ underTest.onShadeDisplayChanging(1)
+ verify(latencyTracker).onActionStart(any())
+
+ sendOnMovedToDisplay(1)
+ choreographerUtils.completeDoFrame()
+
+ verify(latencyTracker).onActionEnd(any())
+
+ underTest.onShadeDisplayChanging(0)
+
+ sendOnMovedToDisplay(0)
+ choreographerUtils.completeDoFrame()
+
+ verify(latencyTracker, times(2)).onActionStart(any())
+ verify(latencyTracker, times(2)).onActionEnd(any())
+ }
+
+ private fun sendOnMovedToDisplay(displayId: Int) {
+ configurationRepository.onMovedToDisplay(displayId)
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractorTest.kt
index e93d0effe742..a98d1a2ea4a5 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractorTest.kt
@@ -45,6 +45,7 @@ class ShadeDisplaysInteractorTest : SysuiTestCase() {
private val positionRepository = kosmos.fakeShadeDisplaysRepository
private val shadeContext = kosmos.mockedWindowContext
private val resources = kosmos.mockResources
+ private val latencyTracker = kosmos.mockedShadeDisplayChangeLatencyTracker
private val configuration = mock<Configuration>()
private val display = mock<Display>()
@@ -81,4 +82,14 @@ class ShadeDisplaysInteractorTest : SysuiTestCase() {
verify(shadeContext).reparentToDisplay(eq(1))
}
+
+ @Test
+ fun start_shadeInWrongPosition_logsStartToLatencyTracker() {
+ whenever(display.displayId).thenReturn(0)
+ positionRepository.setDisplayId(1)
+
+ underTest.start()
+
+ verify(latencyTracker).onShadeDisplayChanging(eq(1))
+ }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/system/QuickStepContractTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/system/QuickStepContractTest.kt
index ef03fab95778..d92781a5f3ce 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/system/QuickStepContractTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/system/QuickStepContractTest.kt
@@ -16,8 +16,10 @@
package com.android.systemui.shared.system
+import android.platform.test.annotations.DisableFlags
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
+import com.android.systemui.Flags.FLAG_GLANCEABLE_HUB_BACK_ACTION
import com.android.systemui.SysuiTestCase
import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BOUNCER_SHOWING
import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_COMMUNAL_HUB_SHOWING
@@ -30,6 +32,7 @@ import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class QuickStepContractTest : SysuiTestCase() {
@Test
+ @DisableFlags(FLAG_GLANCEABLE_HUB_BACK_ACTION)
fun isBackGestureDisabled_hubShowing() {
val sysuiStateFlags = SYSUI_STATE_COMMUNAL_HUB_SHOWING
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/featurepods/media/domain/interactor/MediaControlChipInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/featurepods/media/domain/interactor/MediaControlChipInteractorTest.kt
new file mode 100644
index 000000000000..dd81b75e180e
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/featurepods/media/domain/interactor/MediaControlChipInteractorTest.kt
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.featurepods.media.domain.interactor
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.kosmos.collectLastValue
+import com.android.systemui.kosmos.runTest
+import com.android.systemui.kosmos.useUnconfinedTestDispatcher
+import com.android.systemui.media.controls.data.repository.mediaFilterRepository
+import com.android.systemui.media.controls.shared.model.MediaData
+import com.android.systemui.media.controls.shared.model.MediaDataLoadingModel
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class MediaControlChipInteractorTest : SysuiTestCase() {
+
+ private val kosmos = testKosmos().useUnconfinedTestDispatcher()
+ private val underTest = kosmos.mediaControlChipInteractor
+
+ @Test
+ fun mediaControlModel_noActiveMedia_null() =
+ kosmos.runTest {
+ val model by collectLastValue(underTest.mediaControlModel)
+
+ assertThat(model).isNull()
+ }
+
+ @Test
+ fun mediaControlModel_activeMedia_notNull() =
+ kosmos.runTest {
+ val model by collectLastValue(underTest.mediaControlModel)
+
+ val userMedia = MediaData(active = true)
+ val instanceId = userMedia.instanceId
+
+ mediaFilterRepository.addSelectedUserMediaEntry(userMedia)
+ mediaFilterRepository.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(instanceId))
+
+ assertThat(model).isNotNull()
+ }
+
+ @Test
+ fun mediaControlModel_mediaRemoved_null() =
+ kosmos.runTest {
+ val model by collectLastValue(underTest.mediaControlModel)
+
+ val userMedia = MediaData(active = true)
+ val instanceId = userMedia.instanceId
+
+ mediaFilterRepository.addSelectedUserMediaEntry(userMedia)
+ mediaFilterRepository.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(instanceId))
+
+ assertThat(model).isNotNull()
+
+ assertThat(mediaFilterRepository.removeSelectedUserMediaEntry(instanceId, userMedia))
+ .isTrue()
+ mediaFilterRepository.addMediaDataLoadingState(
+ MediaDataLoadingModel.Removed(instanceId)
+ )
+
+ assertThat(model).isNull()
+ }
+
+ @Test
+ fun mediaControlModel_songNameChanged_emitsUpdatedModel() =
+ kosmos.runTest {
+ val model by collectLastValue(underTest.mediaControlModel)
+
+ val initialSongName = "Initial Song"
+ val newSongName = "New Song"
+ val userMedia = MediaData(active = true, song = initialSongName)
+ val instanceId = userMedia.instanceId
+
+ mediaFilterRepository.addSelectedUserMediaEntry(userMedia)
+ mediaFilterRepository.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(instanceId))
+
+ assertThat(model).isNotNull()
+ assertThat(model?.songName).isEqualTo(initialSongName)
+
+ val updatedUserMedia = userMedia.copy(song = newSongName)
+ mediaFilterRepository.addSelectedUserMediaEntry(updatedUserMedia)
+
+ assertThat(model?.songName).isEqualTo(newSongName)
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorImplTest.kt
index 3359db0a22e6..26c6eb5dc47a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorImplTest.kt
@@ -20,6 +20,7 @@ import android.app.Notification
import android.app.Notification.BigPictureStyle
import android.app.Notification.BigTextStyle
import android.app.Notification.CallStyle
+import android.app.Notification.FLAG_PROMOTED_ONGOING
import android.app.Notification.MessagingStyle
import android.app.Notification.ProgressStyle
import android.app.Notification.ProgressStyle.Segment
@@ -46,9 +47,6 @@ import org.junit.runner.RunWith
class PromotedNotificationContentExtractorImplTest : SysuiTestCase() {
private val kosmos = testKosmos()
- private val provider =
- FakePromotedNotificationsProvider().also { kosmos.promotedNotificationsProvider = it }
-
private val underTest = kosmos.promotedNotificationContentExtractor
@Test
@@ -87,7 +85,7 @@ class PromotedNotificationContentExtractorImplTest : SysuiTestCase() {
@Test
@EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
- fun shouldNotExtract_providerDidNotPromote() {
+ fun shouldNotExtract_becauseNotPromoted() {
val entry = createEntry(promoted = false)
val content = extractContent(entry)
assertThat(content).isNull()
@@ -231,9 +229,10 @@ class PromotedNotificationContentExtractorImplTest : SysuiTestCase() {
builderBlock: Notification.Builder.() -> Unit = {},
): NotificationEntry {
val notif = Notification.Builder(context, "channel").also(builderBlock).build()
- return NotificationEntryBuilder().setNotification(notif).build().also {
- provider.shouldPromoteForEntry[it] = promoted
+ if (promoted) {
+ notif.flags = FLAG_PROMOTED_ONGOING
}
+ return NotificationEntryBuilder().setNotification(notif).build()
}
companion object {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationsProviderTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationsProviderTest.kt
deleted file mode 100644
index a9dbe63e8f07..000000000000
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationsProviderTest.kt
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.notification.promoted
-
-import android.app.Notification
-import android.app.Notification.FLAG_PROMOTED_ONGOING
-import android.platform.test.annotations.DisableFlags
-import android.platform.test.annotations.EnableFlags
-import androidx.test.filters.SmallTest
-import com.android.systemui.SysuiTestCase
-import com.android.systemui.statusbar.notification.collection.NotificationEntry
-import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
-import com.android.systemui.testKosmos
-import com.google.common.truth.Truth.assertThat
-import kotlin.test.Test
-
-@SmallTest
-class PromotedNotificationsProviderTest : SysuiTestCase() {
- private val kosmos = testKosmos()
-
- private val underTest = kosmos.promotedNotificationsProvider
-
- @Test
- @DisableFlags(PromotedNotificationUi.FLAG_NAME)
- fun shouldPromote_uiFlagOff_false() {
- val entry = createNotification(FLAG_PROMOTED_ONGOING)
-
- assertThat(underTest.shouldPromote(entry)).isFalse()
- }
-
- @Test
- @EnableFlags(PromotedNotificationUi.FLAG_NAME)
- fun shouldPromote_uiFlagOn_notifDoesNotHaveFlag_false() {
- val entry = createNotification(flag = null)
-
- assertThat(underTest.shouldPromote(entry)).isFalse()
- }
-
- @Test
- @EnableFlags(PromotedNotificationUi.FLAG_NAME)
- fun shouldPromote_uiFlagOn_notifHasFlag_true() {
- val entry = createNotification(FLAG_PROMOTED_ONGOING)
-
- assertThat(underTest.shouldPromote(entry)).isTrue()
- }
-
- private fun createNotification(flag: Int? = null): NotificationEntry {
- val n = Notification.Builder(context, "a")
- if (flag != null) {
- n.setFlag(flag, true)
- }
-
- return NotificationEntryBuilder().setNotification(n.build()).build()
- }
-}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicyTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicyTest.kt
index 83600422bda4..e1589b6ad4bd 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicyTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicyTest.kt
@@ -219,6 +219,7 @@ class PhoneStatusBarPolicyTest : SysuiTestCase() {
@Test
fun testAppTransitionFinished_doesNotShowManagedProfileIcon() {
+ whenever(userManager.isProfile(anyInt())).thenReturn(true)
whenever(userManager.getUserStatusBarIconResId(anyInt())).thenReturn(0 /* ID_NULL */)
whenever(keyguardStateController.isShowing).thenReturn(false)
statusBarPolicy.appTransitionFinished(0)
@@ -232,6 +233,7 @@ class PhoneStatusBarPolicyTest : SysuiTestCase() {
@Test
fun testAppTransitionFinished_showsManagedProfileIcon() {
+ whenever(userManager.isProfile(anyInt())).thenReturn(true)
whenever(userManager.getUserStatusBarIconResId(anyInt())).thenReturn(100)
whenever(keyguardStateController.isShowing).thenReturn(false)
statusBarPolicy.appTransitionFinished(0)
diff --git a/packages/SystemUI/src/com/android/systemui/common/ui/view/ChoreographerUtils.kt b/packages/SystemUI/src/com/android/systemui/common/ui/view/ChoreographerUtils.kt
new file mode 100644
index 000000000000..cc7a7bfda58e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/common/ui/view/ChoreographerUtils.kt
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.common.ui.view
+
+import android.view.Choreographer
+import android.view.View
+import com.android.app.tracing.coroutines.TrackTracer
+import kotlin.coroutines.resume
+import kotlinx.coroutines.suspendCancellableCoroutine
+
+/** utilities related to [Choreographer]. */
+interface ChoreographerUtils {
+ /**
+ * Waits until the next [view] doFrame is completed.
+ *
+ * Note that this is expected to work properly when called from any thread. If called during a
+ * doFrame, it waits for the next one to be completed.
+ *
+ * This differs from [kotlinx.coroutines.android.awaitFrame] as it uses
+ * [Handler.postAtFrontOfQueue] instead of [Handler.post] when called from a thread different
+ * than the UI thread for that view. Using [Handler.post] might lead to posting the runnable
+ * after a few frame, effectively missing the "next do frame".
+ */
+ suspend fun waitUntilNextDoFrameDone(view: View)
+}
+
+object ChoreographerUtilsImpl : ChoreographerUtils {
+ private val t = TrackTracer("ChoreographerUtils")
+
+ override suspend fun waitUntilNextDoFrameDone(view: View) {
+ t.traceAsync("waitUntilNextDoFrameDone") { waitUntilNextDoFrameDoneTraced(view) }
+ }
+
+ suspend fun waitUntilNextDoFrameDoneTraced(view: View) {
+ suspendCancellableCoroutine { cont ->
+ val frameCallback =
+ Choreographer.FrameCallback {
+ t.instant { "We're in doFrame, waiting for it to end." }
+ view.handler.postAtFrontOfQueue {
+ t.instant { "DoFrame ended." }
+ cont.resume(Unit)
+ }
+ }
+ view.runOnUiThreadUrgently {
+ t.instant { "Waiting for next doFrame" }
+ val choreographer = Choreographer.getInstance()
+ cont.invokeOnCancellation { choreographer.removeFrameCallback(frameCallback) }
+ choreographer.postFrameCallback(frameCallback)
+ }
+ }
+ }
+
+ /**
+ * Execute [r] on the view UI thread, taking priority over everything else scheduled there. Runs
+ * directly if we're already in the correct thread.
+ */
+ private fun View.runOnUiThreadUrgently(r: () -> Unit) {
+ if (handler.looper.isCurrentThread) {
+ r()
+ } else {
+ handler.postAtFrontOfQueue(r)
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/common/ui/view/FakeChoreographerUtils.kt b/packages/SystemUI/src/com/android/systemui/common/ui/view/FakeChoreographerUtils.kt
new file mode 100644
index 000000000000..2f097b1a9279
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/common/ui/view/FakeChoreographerUtils.kt
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.common.ui.view
+
+import android.view.View
+import kotlinx.coroutines.CompletableDeferred
+
+class FakeChoreographerUtils : ChoreographerUtils {
+
+ private var pendingDeferred: CompletableDeferred<Unit>? = null
+
+ override suspend fun waitUntilNextDoFrameDone(view: View) {
+ getDeferred().await()
+ clearDeferred()
+ }
+
+ /**
+ * Called from tests when it's time to complete the doFrame. It works also if it's called before
+ * [waitUntilNextDoFrameDone].
+ */
+ fun completeDoFrame() {
+ getDeferred().complete(Unit)
+ }
+
+ @Synchronized
+ private fun getDeferred(): CompletableDeferred<Unit> {
+ if (pendingDeferred == null) {
+ pendingDeferred = CompletableDeferred()
+ }
+ return pendingDeferred!!
+ }
+
+ @Synchronized
+ private fun clearDeferred() {
+ pendingDeferred = null
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
index 0d9474e07ce7..85306e67994c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
@@ -37,6 +37,7 @@ import com.android.systemui.keyguard.shared.model.DozeStateModel.Companion.isDoz
import com.android.systemui.keyguard.shared.model.DozeTransitionModel
import com.android.systemui.keyguard.shared.model.Edge
import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.keyguard.shared.model.KeyguardState.ALTERNATE_BOUNCER
import com.android.systemui.keyguard.shared.model.KeyguardState.AOD
import com.android.systemui.keyguard.shared.model.KeyguardState.DOZING
import com.android.systemui.keyguard.shared.model.KeyguardState.GLANCEABLE_HUB
@@ -93,6 +94,8 @@ constructor(
private val fromGoneTransitionInteractor: Provider<FromGoneTransitionInteractor>,
private val fromLockscreenTransitionInteractor: Provider<FromLockscreenTransitionInteractor>,
private val fromOccludedTransitionInteractor: Provider<FromOccludedTransitionInteractor>,
+ private val fromAlternateBouncerTransitionInteractor:
+ Provider<FromAlternateBouncerTransitionInteractor>,
@Application applicationScope: CoroutineScope,
) {
// TODO(b/296118689): move to a repository
@@ -526,6 +529,8 @@ constructor(
when (keyguardTransitionInteractor.transitionState.value.to) {
LOCKSCREEN -> fromLockscreenTransitionInteractor.get().dismissKeyguard()
OCCLUDED -> fromOccludedTransitionInteractor.get().dismissFromOccluded()
+ ALTERNATE_BOUNCER ->
+ fromAlternateBouncerTransitionInteractor.get().dismissAlternateBouncer()
else -> Log.v(TAG, "Keyguard was dismissed, no direct transition call needed")
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/settings/UserTracker.kt b/packages/SystemUI/src/com/android/systemui/settings/UserTracker.kt
index bbb13d5c1dfe..e1631ccdcb06 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/UserTracker.kt
+++ b/packages/SystemUI/src/com/android/systemui/settings/UserTracker.kt
@@ -61,17 +61,8 @@ interface UserTracker : UserContentResolverProvider, UserContextProvider {
/** Callback for notifying of changes. */
@WeaklyReferencedCallback
interface Callback {
- /**
- * Same as {@link onBeforeUserSwitching(Int, Runnable)} but the callback will be called
- * automatically after the completion of this method.
- */
- fun onBeforeUserSwitching(newUser: Int) {}
-
/** Notifies that the current user will be changed. */
- fun onBeforeUserSwitching(newUser: Int, resultCallback: Runnable) {
- onBeforeUserSwitching(newUser)
- resultCallback.run()
- }
+ fun onBeforeUserSwitching(newUser: Int) {}
/**
* Same as {@link onUserChanging(Int, Context, Runnable)} but the callback will be called
diff --git a/packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt b/packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt
index 42d83637ec1a..b7a3aedc565e 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt
@@ -196,9 +196,8 @@ internal constructor(
private fun registerUserSwitchObserver() {
iActivityManager.registerUserSwitchObserver(
object : UserSwitchObserver() {
- override fun onBeforeUserSwitching(newUserId: Int, reply: IRemoteCallback?) {
+ override fun onBeforeUserSwitching(newUserId: Int) {
handleBeforeUserSwitching(newUserId)
- reply?.sendResult(null)
}
override fun onUserSwitching(newUserId: Int, reply: IRemoteCallback?) {
@@ -237,7 +236,8 @@ internal constructor(
setUserIdInternal(newUserId)
notifySubscribers { callback, resultCallback ->
- callback.onBeforeUserSwitching(newUserId, resultCallback)
+ callback.onBeforeUserSwitching(newUserId)
+ resultCallback.run()
}
.await()
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java
index 69b3cc8cf4f4..e4cd7ea098af 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java
@@ -27,6 +27,7 @@ import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.graphics.Region;
+import android.os.IBinder;
import android.os.RemoteException;
import android.os.Trace;
import android.os.UserHandle;
@@ -252,6 +253,19 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW
if (mCurrentState.shadeOrQsExpanded != isExpanded) {
mCurrentState.shadeOrQsExpanded = isExpanded;
apply(mCurrentState);
+
+ final IBinder token;
+ if (com.android.window.flags.Flags.schedulingForNotificationShade()
+ && (token = mWindowRootView.getWindowToken()) != null) {
+ mBackgroundExecutor.execute(() -> {
+ try {
+ WindowManagerGlobal.getWindowManagerService()
+ .onNotificationShadeExpanded(token, isExpanded);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to call onNotificationShadeExpanded", e);
+ }
+ });
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayAwareModule.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayAwareModule.kt
index 61b9f0819f56..63e8ba8f65cd 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayAwareModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayAwareModule.kt
@@ -30,6 +30,8 @@ import com.android.systemui.common.ui.data.repository.ConfigurationRepository
import com.android.systemui.common.ui.data.repository.ConfigurationRepositoryImpl
import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor
import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractorImpl
+import com.android.systemui.common.ui.view.ChoreographerUtils
+import com.android.systemui.common.ui.view.ChoreographerUtilsImpl
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.res.R
@@ -260,6 +262,12 @@ object ShadeDisplayAwareModule {
}
}
+ /**
+ * Provided for making classes easier to test. In tests, a custom method to wait for the next
+ * frame can be easily provided.
+ */
+ @Provides fun provideChoreographerUtils(): ChoreographerUtils = ChoreographerUtilsImpl
+
@Provides
@ShadeOnDefaultDisplayWhenLocked
fun provideShadeOnDefaultDisplayWhenLocked(): Boolean = true
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayChangeLatencyTracker.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayChangeLatencyTracker.kt
new file mode 100644
index 000000000000..4d35d0eba178
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayChangeLatencyTracker.kt
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.shade
+
+import android.util.Log
+import android.view.Display
+import com.android.app.tracing.coroutines.TrackTracer
+import com.android.internal.util.LatencyTracker
+import com.android.systemui.common.ui.data.repository.ConfigurationRepository
+import com.android.systemui.common.ui.view.ChoreographerUtils
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.scene.ui.view.WindowRootView
+import com.android.systemui.shade.ShadeDisplayChangeLatencyTracker.Companion.TIMEOUT
+import com.android.systemui.shade.data.repository.ShadeDisplaysRepository
+import com.android.systemui.util.kotlin.getOrNull
+import java.util.Optional
+import java.util.concurrent.CancellationException
+import javax.inject.Inject
+import kotlin.time.Duration.Companion.seconds
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.cancel
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.filter
+import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withTimeout
+
+/**
+ * Tracks the time it takes to move the shade from one display to another.
+ * - The start event is when [ShadeDisplaysRepository] propagates the new display ID.
+ * - The end event is one frame after the shade configuration controller receives a new
+ * configuration change.
+ *
+ * Note that even in the unlikely case the configuration of the new display is the same,
+ * onConfigurationChange is called anyway as is is triggered by
+ * [NotificationShadeWindowView.onMovedToDisplay].
+ */
+@SysUISingleton
+class ShadeDisplayChangeLatencyTracker
+@Inject
+constructor(
+ optionalShadeRootView: Optional<WindowRootView>,
+ @ShadeDisplayAware private val configurationRepository: ConfigurationRepository,
+ private val latencyTracker: LatencyTracker,
+ @Background private val bgScope: CoroutineScope,
+ private val choreographerUtils: ChoreographerUtils,
+) {
+
+ private val shadeRootView =
+ optionalShadeRootView.getOrNull()
+ ?: error(
+ """
+ ShadeRootView must be provided for ShadeDisplayChangeLatencyTracker to work.
+ If it is not, it means this is being instantiated in a SystemUI variant that shouldn't.
+ """
+ .trimIndent()
+ )
+ /**
+ * We need to keep this always up to date eagerly to avoid delays receiving the new display ID.
+ */
+ private val onMovedToDisplayFlow: StateFlow<Int> =
+ configurationRepository.onMovedToDisplay.stateIn(
+ bgScope,
+ SharingStarted.Eagerly,
+ Display.DEFAULT_DISPLAY,
+ )
+
+ private var previousJob: Job? = null
+
+ /**
+ * Called before the display change begins.
+ *
+ * It is guaranteed that context and resources are still associated to the "old" display id, and
+ * that onMovedToDisplay has not been received yet on the notification shade window root view.
+ *
+ * IMPORTANT: this shouldn't be refactored to use [ShadePositionRepository], otherwise there is
+ * no guarantees of event order (as the shade could be reparented before the event is propagated
+ * to this class, breaking the assumption that [onMovedToDisplayFlow] didn't emit with the new
+ * display id yet.
+ */
+ @Synchronized
+ fun onShadeDisplayChanging(displayId: Int) {
+ previousJob?.cancel(CancellationException("New shade move in progress"))
+ previousJob = bgScope.launch { onShadeDisplayChangingAsync(displayId) }
+ }
+
+ private suspend fun onShadeDisplayChangingAsync(displayId: Int) {
+ try {
+ latencyTracker.onActionStart(SHADE_MOVE_ACTION)
+ waitForOnMovedToDisplayDispatchedToView(displayId)
+ waitUntilNextDoFrameDone()
+ latencyTracker.onActionEnd(SHADE_MOVE_ACTION)
+ } catch (e: Exception) {
+ val reason =
+ when (e) {
+ is CancellationException ->
+ "Shade move cancelled as a new move is being done " +
+ "before the previous one finished."
+
+ else -> "Shade move cancelled."
+ }
+ Log.e(TAG, reason, e)
+ latencyTracker.onActionCancel(SHADE_MOVE_ACTION)
+ }
+ }
+
+ private suspend fun waitForOnMovedToDisplayDispatchedToView(newDisplayId: Int) {
+ t.traceAsync({ "waitForOnMovedToDisplayDispatchedToView(newDisplayId=$newDisplayId)" }) {
+ withTimeout(TIMEOUT) { onMovedToDisplayFlow.filter { it == newDisplayId }.first() }
+ t.instant { "onMovedToDisplay received with $newDisplayId" }
+ }
+ }
+
+ private suspend fun waitUntilNextDoFrameDone(): Unit =
+ t.traceAsync("waitUntilNextDoFrameDone") {
+ withTimeout(TIMEOUT) { choreographerUtils.waitUntilNextDoFrameDone(shadeRootView) }
+ }
+
+ private companion object {
+ const val TAG = "ShadeDisplayLatency"
+ val t = TrackTracer(trackName = TAG)
+ val TIMEOUT = 3.seconds
+ const val SHADE_MOVE_ACTION = LatencyTracker.ACTION_SHADE_WINDOW_DISPLAY_CHANGE
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeTraceLogger.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeTraceLogger.kt
index 45161331c0d9..a36c56eafbfc 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeTraceLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeTraceLogger.kt
@@ -17,45 +17,35 @@
package com.android.systemui.shade
import android.content.res.Configuration
-import android.os.Trace
-import com.android.app.tracing.TraceUtils.traceAsync
+import com.android.app.tracing.coroutines.TrackTracer
/**
* Centralized logging for shade-related events to a dedicated Perfetto track.
*
- * Used by shade components to log events to a track named [TAG]. This consolidates shade-specific
- * events into a single track for easier analysis in Perfetto, rather than scattering them across
- * various threads' logs.
+ * Used by shade components to log events to a track named [TRACK_NAME]. This consolidates
+ * shade-specific events into a single track for easier analysis in Perfetto, rather than scattering
+ * them across various threads' logs.
*/
object ShadeTraceLogger {
- private const val TAG = "ShadeTraceLogger"
+ private val t = TrackTracer(trackName = "ShadeTraceLogger")
@JvmStatic
fun logOnMovedToDisplay(displayId: Int, config: Configuration) {
- if (!Trace.isEnabled()) return
- Trace.instantForTrack(
- Trace.TRACE_TAG_APP,
- TAG,
- "onMovedToDisplay(displayId=$displayId, dpi=" + config.densityDpi + ")",
- )
+ t.instant { "onMovedToDisplay(displayId=$displayId, dpi=${config.densityDpi})" }
}
@JvmStatic
fun logOnConfigChanged(config: Configuration) {
- if (!Trace.isEnabled()) return
- Trace.instantForTrack(
- Trace.TRACE_TAG_APP,
- TAG,
- "onConfigurationChanged(dpi=" + config.densityDpi + ")",
- )
+ t.instant { "onConfigurationChanged(dpi=${config.densityDpi})" }
}
+ @JvmStatic
fun logMoveShadeWindowTo(displayId: Int) {
- if (!Trace.isEnabled()) return
- Trace.instantForTrack(Trace.TRACE_TAG_APP, TAG, "moveShadeWindowTo(displayId=$displayId)")
+ t.instant { "moveShadeWindowTo(displayId=$displayId)" }
}
+ @JvmStatic
fun traceReparenting(r: () -> Unit) {
- traceAsync(TAG, { "reparenting" }) { r() }
+ t.traceAsync({ "reparenting" }) { r() }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractor.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractor.kt
index 8d536accaf76..be561b178136 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractor.kt
@@ -25,14 +25,13 @@ import com.android.systemui.CoreStartable
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
-import com.android.systemui.scene.ui.view.WindowRootView
import com.android.systemui.shade.ShadeDisplayAware
+import com.android.systemui.shade.ShadeDisplayChangeLatencyTracker
import com.android.systemui.shade.ShadeTraceLogger.logMoveShadeWindowTo
import com.android.systemui.shade.ShadeTraceLogger.traceReparenting
import com.android.systemui.shade.data.repository.ShadeDisplaysRepository
import com.android.systemui.shade.shared.flag.ShadeWindowGoesAround
-import com.android.systemui.util.kotlin.getOrNull
-import java.util.Optional
+import com.android.window.flags.Flags
import javax.inject.Inject
import kotlin.coroutines.CoroutineContext
import kotlinx.coroutines.CoroutineScope
@@ -43,23 +42,13 @@ import kotlinx.coroutines.withContext
class ShadeDisplaysInteractor
@Inject
constructor(
- optionalShadeRootView: Optional<WindowRootView>,
private val shadePositionRepository: ShadeDisplaysRepository,
@ShadeDisplayAware private val shadeContext: WindowContext,
@Background private val bgScope: CoroutineScope,
@Main private val mainThreadContext: CoroutineContext,
+ private val shadeDisplayChangeLatencyTracker: ShadeDisplayChangeLatencyTracker,
) : CoreStartable {
- private val shadeRootView =
- optionalShadeRootView.getOrNull()
- ?: error(
- """
- ShadeRootView must be provided for this ShadeDisplayInteractor to work.
- If it is not, it means this is being instantiated in a SystemUI variant that shouldn't.
- """
- .trimIndent()
- )
-
override fun start() {
ShadeWindowGoesAround.isUnexpectedlyInLegacyMode()
bgScope.launchTraced(TAG) {
@@ -87,7 +76,11 @@ constructor(
}
try {
withContext(mainThreadContext) {
- traceReparenting { reparentToDisplayId(id = destinationId) }
+ traceReparenting {
+ shadeDisplayChangeLatencyTracker.onShadeDisplayChanging(destinationId)
+ reparentToDisplayId(id = destinationId)
+ }
+ checkContextDisplayMatchesExpected(destinationId)
}
} catch (e: IllegalStateException) {
Log.e(
@@ -98,6 +91,18 @@ constructor(
}
}
+ private fun checkContextDisplayMatchesExpected(destinationId: Int) {
+ if (shadeContext.displayId != destinationId) {
+ Log.wtf(
+ TAG,
+ "Shade context display id doesn't match the expected one after the move. " +
+ "actual=${shadeContext.displayId} expected=$destinationId. " +
+ "This means something wrong happened while trying to move the shade. " +
+ "Flag reparentWindowTokenApi=${Flags.reparentWindowTokenApi()}",
+ )
+ }
+ }
+
@UiThread
private fun reparentToDisplayId(id: Int) {
traceSection({ "reparentToDisplayId(id=$id)" }) { shadeContext.reparentToDisplay(id) }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/media/domain/interactor/MediaControlChipInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/media/domain/interactor/MediaControlChipInteractor.kt
new file mode 100644
index 000000000000..85c67f5b55a2
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/media/domain/interactor/MediaControlChipInteractor.kt
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.featurepods.media.domain.interactor
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.media.controls.data.repository.MediaFilterRepository
+import com.android.systemui.media.controls.shared.model.MediaCommonModel
+import com.android.systemui.media.controls.shared.model.MediaData
+import com.android.systemui.statusbar.featurepods.media.shared.model.MediaControlChipModel
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
+
+/**
+ * Interactor for managing the state of the media control chip in the status bar.
+ *
+ * Provides a [StateFlow] of [MediaControlChipModel] representing the current state of the media
+ * control chip. Emits a new [MediaControlChipModel] when there is an active media session and the
+ * corresponding user preference is found, otherwise emits null.
+ */
+@SysUISingleton
+class MediaControlChipInteractor
+@Inject
+constructor(
+ @Background private val applicationScope: CoroutineScope,
+ mediaFilterRepository: MediaFilterRepository,
+) {
+ private val currentMediaControls: StateFlow<List<MediaCommonModel.MediaControl>> =
+ mediaFilterRepository.currentMedia
+ .map { mediaList -> mediaList.filterIsInstance<MediaCommonModel.MediaControl>() }
+ .stateIn(
+ scope = applicationScope,
+ started = SharingStarted.WhileSubscribed(),
+ initialValue = emptyList(),
+ )
+
+ /** The currently active [MediaControlChipModel] */
+ val mediaControlModel: StateFlow<MediaControlChipModel?> =
+ combine(currentMediaControls, mediaFilterRepository.selectedUserEntries) {
+ mediaControls,
+ userEntries ->
+ mediaControls
+ .mapNotNull { userEntries[it.mediaLoadedModel.instanceId] }
+ .firstOrNull { it.active }
+ ?.toMediaControlChipModel()
+ }
+ .stateIn(
+ scope = applicationScope,
+ started = SharingStarted.WhileSubscribed(),
+ initialValue = null,
+ )
+}
+
+private fun MediaData.toMediaControlChipModel(): MediaControlChipModel {
+ return MediaControlChipModel(appIcon = this.appIcon, appName = this.app, songName = this.song)
+}
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/test/Selectors.kt b/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/media/shared/model/MediaControlChipModel.kt
index d6f64bfe4974..403566749e03 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/test/Selectors.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/featurepods/media/shared/model/MediaControlChipModel.kt
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,14 +14,13 @@
* limitations under the License.
*/
-package com.android.compose.test
+package com.android.systemui.statusbar.featurepods.media.shared.model
-import androidx.compose.ui.test.SemanticsNodeInteraction
-import androidx.compose.ui.test.SemanticsNodeInteractionCollection
+import android.graphics.drawable.Icon
-/** Assert [assert] on each element of [this] [SemanticsNodeInteractionCollection]. */
-fun SemanticsNodeInteractionCollection.onEach(assert: SemanticsNodeInteraction.() -> Unit) {
- for (i in 0 until this.fetchSemanticsNodes().size) {
- get(i).assert()
- }
-}
+/** Model used to display a media control chip in the status bar. */
+data class MediaControlChipModel(
+ val appIcon: Icon?,
+ val appName: String?,
+ val songName: CharSequence?,
+)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.kt
index 46d4560ff102..df0cde51e8ba 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.kt
@@ -23,6 +23,7 @@ import com.android.systemui.statusbar.notification.collection.SortBySectionTimeF
import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner
import com.android.systemui.statusbar.notification.collection.provider.SectionStyleProvider
+import com.android.systemui.statusbar.notification.promoted.AutomaticPromotionCoordinator
import com.android.systemui.statusbar.notification.shared.NotificationMinimalism
import com.android.systemui.statusbar.notification.shared.NotificationsLiveDataStoreRefactor
import com.android.systemui.statusbar.notification.shared.PriorityPeopleSection
@@ -69,6 +70,7 @@ constructor(
dismissibilityCoordinator: DismissibilityCoordinator,
statsLoggerCoordinator: NotificationStatsLoggerCoordinator,
bundleCoordinator: BundleCoordinator,
+ automaticPromotionCoordinator: AutomaticPromotionCoordinator,
) : NotifCoordinators {
private val mCoreCoordinators: MutableList<CoreCoordinator> = ArrayList()
@@ -110,6 +112,7 @@ constructor(
mCoordinators.add(preparationCoordinator)
mCoordinators.add(remoteInputCoordinator)
mCoordinators.add(dismissibilityCoordinator)
+ mCoordinators.add(automaticPromotionCoordinator)
if (NotificationsLiveDataStoreRefactor.isEnabled) {
mCoordinators.add(statsLoggerCoordinator)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/dagger/CoordinatorsModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/dagger/ReferenceCoordinatorsModule.kt
index c00bb93ff66e..1829c2c5d548 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/dagger/CoordinatorsModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/dagger/ReferenceCoordinatorsModule.kt
@@ -20,6 +20,7 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.statusbar.notification.collection.coordinator.NotifCoordinators
import com.android.systemui.statusbar.notification.collection.coordinator.NotifCoordinatorsImpl
import com.android.systemui.statusbar.notification.collection.coordinator.SensitiveContentCoordinatorModule
+import com.android.systemui.statusbar.notification.promoted.ReferenceAutomaticPromotionModule
import dagger.Binds
import dagger.Module
import dagger.Provides
@@ -28,12 +29,12 @@ import javax.inject.Qualifier
import javax.inject.Scope
@Module(subcomponents = [CoordinatorsSubcomponent::class])
-object CoordinatorsModule {
+object ReferenceCoordinatorsModule {
@SysUISingleton
@JvmStatic
@Provides
fun notifCoordinators(factory: CoordinatorsSubcomponent.Factory): NotifCoordinators =
- factory.create().notifCoordinators
+ factory.create().notifCoordinators
}
@CoordinatorScope
@@ -47,9 +48,9 @@ interface CoordinatorsSubcomponent {
}
}
-@Module(includes = [
- SensitiveContentCoordinatorModule::class,
-])
+@Module(
+ includes = [SensitiveContentCoordinatorModule::class, ReferenceAutomaticPromotionModule::class]
+)
abstract class InternalCoordinatorsModule {
@Binds
@Internal
@@ -61,7 +62,4 @@ abstract class InternalCoordinatorsModule {
@Retention(AnnotationRetention.RUNTIME)
private annotation class Internal
-@Scope
-@MustBeDocumented
-@Retention(AnnotationRetention.RUNTIME)
-annotation class CoordinatorScope
+@Scope @MustBeDocumented @Retention(AnnotationRetention.RUNTIME) annotation class CoordinatorScope
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
index aa010cf63d5b..ea48fb4ffd92 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
@@ -41,7 +41,6 @@ import com.android.systemui.statusbar.notification.collection.NotifLiveDataStore
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
import com.android.systemui.statusbar.notification.collection.NotifPipelineChoreographerModule;
import com.android.systemui.statusbar.notification.collection.coordinator.ShadeEventCoordinator;
-import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorsModule;
import com.android.systemui.statusbar.notification.collection.inflation.BindEventManager;
import com.android.systemui.statusbar.notification.collection.inflation.BindEventManagerImpl;
import com.android.systemui.statusbar.notification.collection.inflation.NotifInflater;
@@ -110,7 +109,6 @@ import javax.inject.Provider;
* Dagger Module for classes found within the com.android.systemui.statusbar.notification package.
*/
@Module(includes = {
- CoordinatorsModule.class,
FooterViewModelModule.class,
KeyguardNotificationVisibilityProviderModule.class,
NotificationDataLayerModule.class,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/ReferenceNotificationsModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/ReferenceNotificationsModule.kt
index 4c2512988f4d..6c2c5937f669 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/ReferenceNotificationsModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/ReferenceNotificationsModule.kt
@@ -16,7 +16,7 @@
package com.android.systemui.statusbar.notification.dagger
-import com.android.systemui.statusbar.notification.promoted.PromotedNotificationsModule
+import com.android.systemui.statusbar.notification.collection.coordinator.dagger.ReferenceCoordinatorsModule
import com.android.systemui.statusbar.notification.row.NotificationRowModule
import dagger.Module
@@ -29,7 +29,7 @@ import dagger.Module
[
NotificationsModule::class,
NotificationRowModule::class,
- PromotedNotificationsModule::class,
+ ReferenceCoordinatorsModule::class,
]
)
object ReferenceNotificationsModule
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/promoted/FakePromotedNotificationsProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/AutomaticPromotionCoordinator.kt
index ea7b41d43871..bb164848320e 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/promoted/FakePromotedNotificationsProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/AutomaticPromotionCoordinator.kt
@@ -16,21 +16,16 @@
package com.android.systemui.statusbar.notification.promoted
-import com.android.systemui.statusbar.notification.collection.NotificationEntry
-import org.junit.Assert
+import com.android.systemui.statusbar.notification.collection.NotifPipeline
+import com.android.systemui.statusbar.notification.collection.coordinator.Coordinator
+import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope
+import javax.inject.Inject
-class FakePromotedNotificationsProvider : PromotedNotificationsProvider {
- val promotedEntries = mutableSetOf<NotificationEntry>()
- val shouldPromoteForEntry = mutableMapOf<NotificationEntry, Boolean>()
+/** A coordinator that may automatically promote certain notifications. */
+interface AutomaticPromotionCoordinator : Coordinator
- override fun shouldPromote(entry: NotificationEntry): Boolean {
- if (shouldPromoteForEntry.isEmpty()) {
- // If *no* entries are set, just return false for everything.
- return false
- } else {
- // If entries *are* set, fail on unexpected ones.
- Assert.assertTrue(shouldPromoteForEntry.containsKey(entry))
- return shouldPromoteForEntry[entry] ?: false
- }
- }
+/** A default implementation of [AutomaticPromotionCoordinator] that doesn't promote anything. */
+@CoordinatorScope
+class EmptyAutomaticPromotionCoordinator @Inject constructor() : AutomaticPromotionCoordinator {
+ override fun attach(pipeline: NotifPipeline) {}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractor.kt
index 4e9e3336b86f..7d2827666227 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractor.kt
@@ -24,10 +24,12 @@ import android.app.Notification.EXTRA_CHRONOMETER_COUNT_DOWN
import android.app.Notification.EXTRA_SUB_TEXT
import android.app.Notification.EXTRA_TEXT
import android.app.Notification.EXTRA_TITLE
+import android.app.Notification.FLAG_PROMOTED_ONGOING
import android.app.Notification.ProgressStyle
import android.content.Context
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.shade.ShadeDisplayAware
+import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel
import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel.Style
@@ -45,7 +47,6 @@ interface PromotedNotificationContentExtractor {
class PromotedNotificationContentExtractorImpl
@Inject
constructor(
- private val promotedNotificationsProvider: PromotedNotificationsProvider,
@ShadeDisplayAware private val context: Context,
private val logger: PromotedNotificationLogger,
) : PromotedNotificationContentExtractor {
@@ -58,17 +59,22 @@ constructor(
return null
}
- if (!promotedNotificationsProvider.shouldPromote(entry)) {
- logger.logExtractionSkipped(entry, "shouldPromote returned false")
- return null
- }
-
val notification = entry.sbn.notification
if (notification == null) {
logger.logExtractionFailed(entry, "entry.sbn.notification is null")
return null
}
+ // Notification.isPromotedOngoing checks the ui_rich_ongoing flag, but we want the status
+ // bar chip to be ready before all the features behind the ui_rich_ongoing flag are ready.
+ val isPromotedForStatusBarChip =
+ StatusBarNotifChips.isEnabled && (notification.flags and FLAG_PROMOTED_ONGOING) != 0
+ val isPromoted = notification.isPromotedOngoing() || isPromotedForStatusBarChip
+ if (!isPromoted) {
+ logger.logExtractionSkipped(entry, "isPromotedOngoing returned false")
+ return null
+ }
+
val contentBuilder = PromotedNotificationContentModel.Builder(entry.key)
// TODO: Pitch a fit if style is unsupported or mandatory fields are missing once
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationsProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationsProvider.kt
deleted file mode 100644
index 947d9e3e9547..000000000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationsProvider.kt
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.notification.promoted
-
-import android.app.Notification.FLAG_PROMOTED_ONGOING
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.statusbar.notification.collection.NotificationEntry
-import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel
-import javax.inject.Inject
-
-/** A provider for making decisions on which notifications should be promoted. */
-interface PromotedNotificationsProvider {
- /** Returns true if the given notification should be promoted and false otherwise. */
- fun shouldPromote(entry: NotificationEntry): Boolean
-}
-
-@SysUISingleton
-open class PromotedNotificationsProviderImpl @Inject constructor() : PromotedNotificationsProvider {
- override fun shouldPromote(entry: NotificationEntry): Boolean {
- if (!PromotedNotificationContentModel.featureFlagEnabled()) {
- return false
- }
- return (entry.sbn.notification.flags and FLAG_PROMOTED_ONGOING) != 0
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationsModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/ReferenceAutomaticPromotionModule.kt
index 4be12bd44a29..6a9bd3f748df 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationsModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/ReferenceAutomaticPromotionModule.kt
@@ -16,15 +16,15 @@
package com.android.systemui.statusbar.notification.promoted
-import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope
import dagger.Binds
import dagger.Module
@Module
-abstract class PromotedNotificationsModule {
+abstract class ReferenceAutomaticPromotionModule {
@Binds
- @SysUISingleton
- abstract fun bindPromotedNotificationsProvider(
- impl: PromotedNotificationsProviderImpl
- ): PromotedNotificationsProvider
+ @CoordinatorScope
+ abstract fun bindAutomaticPromotionCoordinator(
+ impl: EmptyAutomaticPromotionCoordinator
+ ): AutomaticPromotionCoordinator
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
index f8eae3607f6a..a2b4e7b474a0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -617,7 +617,8 @@ public class PhoneStatusBarPolicy
mUiBgExecutor.execute(() -> {
try {
final int userId = ActivityTaskManager.getService().getLastResumedActivityUserId();
- final int iconResId = mUserManager.getUserStatusBarIconResId(userId);
+ final int iconResId = mUserManager.isProfile(userId) ?
+ mUserManager.getUserStatusBarIconResId(userId) : Resources.ID_NULL;
mMainExecutor.execute(() -> {
final boolean showIcon;
if (iconResId != Resources.ID_NULL && (!mKeyguardStateController.isShowing()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/FullscreenMagnificationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/FullscreenMagnificationControllerTest.java
index 5e9f2a2fbe97..9d9fb9c23a73 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/FullscreenMagnificationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/FullscreenMagnificationControllerTest.java
@@ -56,6 +56,7 @@ import android.view.animation.Interpolator;
import android.window.InputTransferToken;
import androidx.annotation.NonNull;
+import androidx.test.filters.FlakyTest;
import androidx.test.filters.SmallTest;
import com.android.systemui.Flags;
@@ -77,6 +78,7 @@ import java.util.function.Supplier;
@SmallTest
@TestableLooper.RunWithLooper
@RunWith(AndroidTestingRunner.class)
+@FlakyTest(bugId = 385115361)
public class FullscreenMagnificationControllerTest extends SysuiTestCase {
private static final long ANIMATION_DURATION_MS = 100L;
private static final long WAIT_TIMEOUT_S = 5L * HW_TIMEOUT_MULTIPLIER;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/settings/UserTrackerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/settings/UserTrackerImplTest.kt
index f695c13a9e62..a0ecb802dd61 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/settings/UserTrackerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/settings/UserTrackerImplTest.kt
@@ -76,8 +76,6 @@ class UserTrackerImplTest : SysuiTestCase() {
@Mock private lateinit var iActivityManager: IActivityManager
- @Mock private lateinit var beforeUserSwitchingReply: IRemoteCallback
-
@Mock private lateinit var userSwitchingReply: IRemoteCallback
@Mock(stubOnly = true) private lateinit var dumpManager: DumpManager
@@ -201,10 +199,9 @@ class UserTrackerImplTest : SysuiTestCase() {
val captor = ArgumentCaptor.forClass(IUserSwitchObserver::class.java)
verify(iActivityManager).registerUserSwitchObserver(capture(captor), anyString())
- captor.value.onBeforeUserSwitching(newID, beforeUserSwitchingReply)
+ captor.value.onBeforeUserSwitching(newID)
captor.value.onUserSwitching(newID, userSwitchingReply)
runCurrent()
- verify(beforeUserSwitchingReply).sendResult(any())
verify(userSwitchingReply).sendResult(any())
verify(userManager).getProfiles(newID)
@@ -344,11 +341,10 @@ class UserTrackerImplTest : SysuiTestCase() {
val captor = ArgumentCaptor.forClass(IUserSwitchObserver::class.java)
verify(iActivityManager).registerUserSwitchObserver(capture(captor), anyString())
- captor.value.onBeforeUserSwitching(newID, beforeUserSwitchingReply)
+ captor.value.onBeforeUserSwitching(newID)
captor.value.onUserSwitching(newID, userSwitchingReply)
runCurrent()
- verify(beforeUserSwitchingReply).sendResult(any())
verify(userSwitchingReply).sendResult(any())
assertThat(callback.calledOnUserChanging).isEqualTo(1)
assertThat(callback.lastUser).isEqualTo(newID)
@@ -399,7 +395,7 @@ class UserTrackerImplTest : SysuiTestCase() {
val captor = ArgumentCaptor.forClass(IUserSwitchObserver::class.java)
verify(iActivityManager).registerUserSwitchObserver(capture(captor), anyString())
- captor.value.onBeforeUserSwitching(newID, any())
+ captor.value.onBeforeUserSwitching(newID)
captor.value.onUserSwitchComplete(newID)
runCurrent()
@@ -457,10 +453,8 @@ class UserTrackerImplTest : SysuiTestCase() {
val captor = ArgumentCaptor.forClass(IUserSwitchObserver::class.java)
verify(iActivityManager).registerUserSwitchObserver(capture(captor), anyString())
- captor.value.onBeforeUserSwitching(newID, beforeUserSwitchingReply)
captor.value.onUserSwitching(newID, userSwitchingReply)
runCurrent()
- verify(beforeUserSwitchingReply).sendResult(any())
verify(userSwitchingReply).sendResult(any())
captor.value.onUserSwitchComplete(newID)
@@ -494,7 +488,6 @@ class UserTrackerImplTest : SysuiTestCase() {
}
private class TestCallback : UserTracker.Callback {
- var calledOnBeforeUserChanging = 0
var calledOnUserChanging = 0
var calledOnUserChanged = 0
var calledOnProfilesChanged = 0
@@ -502,11 +495,6 @@ class UserTrackerImplTest : SysuiTestCase() {
var lastUserContext: Context? = null
var lastUserProfiles = emptyList<UserInfo>()
- override fun onBeforeUserSwitching(newUser: Int) {
- calledOnBeforeUserChanging++
- lastUser = newUser
- }
-
override fun onUserChanging(newUser: Int, userContext: Context) {
calledOnUserChanging++
lastUser = newUser
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationsProviderKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/common/ui/view/ChoreographerUtilsKosmos.kt
index 580f617a3cdf..266cb31d4756 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationsProviderKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/common/ui/view/ChoreographerUtilsKosmos.kt
@@ -14,9 +14,9 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar.notification.promoted
+package com.android.systemui.common.ui.view
import com.android.systemui.kosmos.Kosmos
-var Kosmos.promotedNotificationsProvider: PromotedNotificationsProvider by
- Kosmos.Fixture { PromotedNotificationsProviderImpl() }
+val Kosmos.fakeChoreographerUtils: FakeChoreographerUtils by
+ Kosmos.Fixture { FakeChoreographerUtils() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorFactory.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorFactory.kt
index 4a6e27331efc..3de809308702 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorFactory.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorFactory.kt
@@ -54,6 +54,7 @@ object KeyguardInteractorFactory {
fromGoneTransitionInteractor: FromGoneTransitionInteractor = mock(),
fromLockscreenTransitionInteractor: FromLockscreenTransitionInteractor = mock(),
fromOccludedTransitionInteractor: FromOccludedTransitionInteractor = mock(),
+ fromAlternateBouncerTransitionInteractor: FromAlternateBouncerTransitionInteractor = mock(),
powerInteractor: PowerInteractor = PowerInteractorFactory.create().powerInteractor,
testScope: CoroutineScope = TestScope(),
): WithDependencies {
@@ -84,6 +85,9 @@ object KeyguardInteractorFactory {
fromGoneTransitionInteractor = { fromGoneTransitionInteractor },
fromLockscreenTransitionInteractor = { fromLockscreenTransitionInteractor },
fromOccludedTransitionInteractor = { fromOccludedTransitionInteractor },
+ fromAlternateBouncerTransitionInteractor = {
+ fromAlternateBouncerTransitionInteractor
+ },
applicationScope = testScope,
),
)
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorKosmos.kt
index da261bfb9805..f5f8ef75065f 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorKosmos.kt
@@ -38,6 +38,7 @@ val Kosmos.keyguardInteractor: KeyguardInteractor by
fromGoneTransitionInteractor = { fromGoneTransitionInteractor },
fromLockscreenTransitionInteractor = { fromLockscreenTransitionInteractor },
fromOccludedTransitionInteractor = { fromOccludedTransitionInteractor },
+ fromAlternateBouncerTransitionInteractor = { fromAlternateBouncerTransitionInteractor },
applicationScope = testScope.backgroundScope,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ShadeDisplayChangeLatencyTrackerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ShadeDisplayChangeLatencyTrackerKosmos.kt
new file mode 100644
index 000000000000..67dd0ad896d5
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ShadeDisplayChangeLatencyTrackerKosmos.kt
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.shade
+
+import com.android.internal.logging.latencyTracker
+import com.android.systemui.common.ui.data.repository.configurationRepository
+import com.android.systemui.common.ui.view.fakeChoreographerUtils
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.scene.ui.view.mockShadeRootView
+import java.util.Optional
+
+val Kosmos.shadeDisplayChangeLatencyTracker by Fixture {
+ ShadeDisplayChangeLatencyTracker(
+ Optional.of(mockShadeRootView),
+ configurationRepository,
+ latencyTracker,
+ testScope.backgroundScope,
+ fakeChoreographerUtils,
+ )
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractorKosmos.kt
index f2af619a4ad7..4af5e7d9d725 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractorKosmos.kt
@@ -20,22 +20,23 @@ import android.content.mockedContext
import android.window.WindowContext
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.testScope
-import com.android.systemui.scene.ui.view.mockShadeRootView
+import com.android.systemui.shade.ShadeDisplayChangeLatencyTracker
import com.android.systemui.shade.ShadeWindowLayoutParams
import com.android.systemui.shade.data.repository.fakeShadeDisplaysRepository
-import java.util.Optional
import org.mockito.kotlin.mock
val Kosmos.shadeLayoutParams by Kosmos.Fixture { ShadeWindowLayoutParams.create(mockedContext) }
val Kosmos.mockedWindowContext by Kosmos.Fixture { mock<WindowContext>() }
+val Kosmos.mockedShadeDisplayChangeLatencyTracker by
+ Kosmos.Fixture { mock<ShadeDisplayChangeLatencyTracker>() }
val Kosmos.shadeDisplaysInteractor by
Kosmos.Fixture {
ShadeDisplaysInteractor(
- Optional.of(mockShadeRootView),
fakeShadeDisplaysRepository,
mockedWindowContext,
testScope.backgroundScope,
testScope.backgroundScope.coroutineContext,
+ mockedShadeDisplayChangeLatencyTracker,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/featurepods/media/domain/interactor/MediaControlChipInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/featurepods/media/domain/interactor/MediaControlChipInteractorKosmos.kt
new file mode 100644
index 000000000000..0025ad42ba53
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/featurepods/media/domain/interactor/MediaControlChipInteractorKosmos.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.featurepods.media.domain.interactor
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.media.controls.data.repository.mediaFilterRepository
+
+val Kosmos.mediaControlChipInteractor: MediaControlChipInteractor by
+ Kosmos.Fixture {
+ MediaControlChipInteractor(
+ applicationScope = applicationCoroutineScope,
+ mediaFilterRepository = mediaFilterRepository,
+ )
+ }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorKosmos.kt
index 52c17c82fb12..912d5027c494 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorKosmos.kt
@@ -21,9 +21,5 @@ import com.android.systemui.kosmos.Kosmos
var Kosmos.promotedNotificationContentExtractor by
Kosmos.Fixture {
- PromotedNotificationContentExtractorImpl(
- promotedNotificationsProvider,
- applicationContext,
- promotedNotificationLogger,
- )
+ PromotedNotificationContentExtractorImpl(applicationContext, promotedNotificationLogger)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowBuilder.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowBuilder.kt
index e739e82aa8a8..3fddd47c25f0 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowBuilder.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowBuilder.kt
@@ -67,7 +67,6 @@ import com.android.systemui.statusbar.notification.icon.IconManager
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier
import com.android.systemui.statusbar.notification.promoted.PromotedNotificationContentExtractorImpl
import com.android.systemui.statusbar.notification.promoted.PromotedNotificationLogger
-import com.android.systemui.statusbar.notification.promoted.PromotedNotificationsProviderImpl
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow.CoordinateOnClickListener
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow.ExpandableNotificationRowLogger
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow.OnExpandClickListener
@@ -224,7 +223,6 @@ class ExpandableNotificationRowBuilder(
)
val promotedNotificationContentExtractor =
PromotedNotificationContentExtractorImpl(
- PromotedNotificationsProviderImpl(),
context,
PromotedNotificationLogger(logcatLogBuffer("PromotedNotifLog")),
)
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 70f2a8e1dd1b..c31b9ef60bd2 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -160,7 +160,6 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
-import java.util.function.BiConsumer;
import java.util.function.Consumer;
/**
@@ -177,9 +176,6 @@ import java.util.function.Consumer;
class UserController implements Handler.Callback {
private static final String TAG = TAG_WITH_CLASS_NAME ? "UserController" : TAG_AM;
- // Amount of time we wait for observers to handle onBeforeUserSwitching, before crashing system.
- static final int DEFAULT_BEFORE_USER_SWITCH_TIMEOUT_MS = 20 * 1000;
-
// Amount of time we wait for observers to handle a user switch before
// giving up on them and dismissing the user switching dialog.
static final int DEFAULT_USER_SWITCH_TIMEOUT_MS = 3 * 1000;
@@ -1924,14 +1920,8 @@ class UserController implements Handler.Callback {
return false;
}
- final Runnable continueStartUserInternal = () -> continueStartUserInternal(userInfo,
- oldUserId, userStartMode, unlockListener, callingUid, callingPid);
- if (foreground) {
- mHandler.post(() -> dispatchOnBeforeUserSwitching(userId, () ->
- mHandler.post(continueStartUserInternal)));
- } else {
- continueStartUserInternal.run();
- }
+ mHandler.post(() -> startUserInternalOnHandler(userId, oldUserId, userStartMode,
+ unlockListener, callingUid, callingPid));
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -1939,11 +1929,11 @@ class UserController implements Handler.Callback {
return true;
}
- private void continueStartUserInternal(UserInfo userInfo, int oldUserId, int userStartMode,
+ private void startUserInternalOnHandler(int userId, int oldUserId, int userStartMode,
IProgressListener unlockListener, int callingUid, int callingPid) {
final TimingsTraceAndSlog t = new TimingsTraceAndSlog();
final boolean foreground = userStartMode == USER_START_MODE_FOREGROUND;
- final int userId = userInfo.id;
+ final UserInfo userInfo = getUserInfo(userId);
boolean needStart = false;
boolean updateUmState = false;
@@ -2005,6 +1995,7 @@ class UserController implements Handler.Callback {
// it should be moved outside, but for now it's not as there are many calls to
// external components here afterwards
updateProfileRelatedCaches();
+ dispatchOnBeforeUserSwitching(userId);
mInjector.getWindowManager().setCurrentUser(userId);
mInjector.reportCurWakefulnessUsageEvent();
// Once the internal notion of the active user has switched, we lock the device
@@ -2305,40 +2296,25 @@ class UserController implements Handler.Callback {
mUserSwitchObservers.finishBroadcast();
}
- private void dispatchOnBeforeUserSwitching(@UserIdInt int newUserId, Runnable onComplete) {
+ private void dispatchOnBeforeUserSwitching(@UserIdInt int newUserId) {
final TimingsTraceAndSlog t = new TimingsTraceAndSlog();
t.traceBegin("dispatchOnBeforeUserSwitching-" + newUserId);
- final AtomicBoolean isSuccessful = new AtomicBoolean(false);
- startTimeoutForOnBeforeUserSwitching(isSuccessful);
- informUserSwitchObservers((observer, callback) -> {
+ final int observerCount = mUserSwitchObservers.beginBroadcast();
+ for (int i = 0; i < observerCount; i++) {
+ final String name = "#" + i + " " + mUserSwitchObservers.getBroadcastCookie(i);
+ t.traceBegin("onBeforeUserSwitching-" + name);
try {
- observer.onBeforeUserSwitching(newUserId, callback);
+ mUserSwitchObservers.getBroadcastItem(i).onBeforeUserSwitching(newUserId);
} catch (RemoteException e) {
- // ignore
+ // Ignore
+ } finally {
+ t.traceEnd();
}
- }, () -> {
- isSuccessful.set(true);
- onComplete.run();
- }, "onBeforeUserSwitching");
+ }
+ mUserSwitchObservers.finishBroadcast();
t.traceEnd();
}
- private void startTimeoutForOnBeforeUserSwitching(AtomicBoolean isSuccessful) {
- mHandler.postDelayed(() -> {
- if (isSuccessful.get()) {
- return;
- }
- String unresponsiveObservers;
- synchronized (mLock) {
- unresponsiveObservers = String.join(", ", mCurWaitingUserSwitchCallbacks);
- }
- throw new RuntimeException("Timeout on dispatchOnBeforeUserSwitching. "
- + "These UserSwitchObservers did not respond in "
- + DEFAULT_BEFORE_USER_SWITCH_TIMEOUT_MS + "ms: " + unresponsiveObservers + ".");
- }, DEFAULT_BEFORE_USER_SWITCH_TIMEOUT_MS);
- }
-
-
/** Called on handler thread */
@VisibleForTesting
void dispatchUserSwitchComplete(@UserIdInt int oldUserId, @UserIdInt int newUserId) {
@@ -2551,76 +2527,70 @@ class UserController implements Handler.Callback {
t.traceBegin("dispatchUserSwitch-" + oldUserId + "-to-" + newUserId);
EventLog.writeEvent(EventLogTags.UC_DISPATCH_USER_SWITCH, oldUserId, newUserId);
- uss.switching = true;
- informUserSwitchObservers((observer, callback) -> {
- try {
- observer.onUserSwitching(newUserId, callback);
- } catch (RemoteException e) {
- // ignore
- }
- }, () -> {
- synchronized (mLock) {
- sendContinueUserSwitchLU(uss, oldUserId, newUserId);
- }
- }, "onUserSwitching");
- t.traceEnd();
- }
- void informUserSwitchObservers(BiConsumer<IUserSwitchObserver, IRemoteCallback> consumer,
- final Runnable onComplete, String trace) {
final int observerCount = mUserSwitchObservers.beginBroadcast();
- if (observerCount == 0) {
- onComplete.run();
- mUserSwitchObservers.finishBroadcast();
- return;
- }
- final ArraySet<String> curWaitingUserSwitchCallbacks = new ArraySet<>();
- synchronized (mLock) {
- mCurWaitingUserSwitchCallbacks = curWaitingUserSwitchCallbacks;
- }
- final AtomicInteger waitingCallbacksCount = new AtomicInteger(observerCount);
- final long userSwitchTimeoutMs = getUserSwitchTimeoutMs();
- final long dispatchStartedTime = SystemClock.elapsedRealtime();
- for (int i = 0; i < observerCount; i++) {
- final long dispatchStartedTimeForObserver = SystemClock.elapsedRealtime();
- // Prepend with unique prefix to guarantee that keys are unique
- final String name = "#" + i + " " + mUserSwitchObservers.getBroadcastCookie(i);
+ if (observerCount > 0) {
+ final ArraySet<String> curWaitingUserSwitchCallbacks = new ArraySet<>();
synchronized (mLock) {
- curWaitingUserSwitchCallbacks.add(name);
- }
- final IRemoteCallback callback = new IRemoteCallback.Stub() {
- @Override
- public void sendResult(Bundle data) throws RemoteException {
- asyncTraceEnd(trace + "-" + name, 0);
+ uss.switching = true;
+ mCurWaitingUserSwitchCallbacks = curWaitingUserSwitchCallbacks;
+ }
+ final AtomicInteger waitingCallbacksCount = new AtomicInteger(observerCount);
+ final long userSwitchTimeoutMs = getUserSwitchTimeoutMs();
+ final long dispatchStartedTime = SystemClock.elapsedRealtime();
+ for (int i = 0; i < observerCount; i++) {
+ final long dispatchStartedTimeForObserver = SystemClock.elapsedRealtime();
+ try {
+ // Prepend with unique prefix to guarantee that keys are unique
+ final String name = "#" + i + " " + mUserSwitchObservers.getBroadcastCookie(i);
synchronized (mLock) {
- long delayForObserver = SystemClock.elapsedRealtime()
- - dispatchStartedTimeForObserver;
- if (delayForObserver > LONG_USER_SWITCH_OBSERVER_WARNING_TIME_MS) {
- Slogf.w(TAG, "User switch slowed down by observer " + name
- + ": result took " + delayForObserver
- + " ms to process. " + trace);
- }
- long totalDelay = SystemClock.elapsedRealtime() - dispatchStartedTime;
- if (totalDelay > userSwitchTimeoutMs) {
- Slogf.e(TAG, "User switch timeout: observer " + name
- + "'s result was received " + totalDelay
- + " ms after dispatchUserSwitch. " + trace);
- }
- curWaitingUserSwitchCallbacks.remove(name);
- // Continue switching if all callbacks have been notified and
- // user switching session is still valid
- if (waitingCallbacksCount.decrementAndGet() == 0
- && (curWaitingUserSwitchCallbacks
- == mCurWaitingUserSwitchCallbacks)) {
- onComplete.run();
- }
+ curWaitingUserSwitchCallbacks.add(name);
}
+ final IRemoteCallback callback = new IRemoteCallback.Stub() {
+ @Override
+ public void sendResult(Bundle data) throws RemoteException {
+ asyncTraceEnd("onUserSwitching-" + name, newUserId);
+ synchronized (mLock) {
+ long delayForObserver = SystemClock.elapsedRealtime()
+ - dispatchStartedTimeForObserver;
+ if (delayForObserver > LONG_USER_SWITCH_OBSERVER_WARNING_TIME_MS) {
+ Slogf.w(TAG, "User switch slowed down by observer " + name
+ + ": result took " + delayForObserver
+ + " ms to process.");
+ }
+
+ long totalDelay = SystemClock.elapsedRealtime()
+ - dispatchStartedTime;
+ if (totalDelay > userSwitchTimeoutMs) {
+ Slogf.e(TAG, "User switch timeout: observer " + name
+ + "'s result was received " + totalDelay
+ + " ms after dispatchUserSwitch.");
+ }
+
+ curWaitingUserSwitchCallbacks.remove(name);
+ // Continue switching if all callbacks have been notified and
+ // user switching session is still valid
+ if (waitingCallbacksCount.decrementAndGet() == 0
+ && (curWaitingUserSwitchCallbacks
+ == mCurWaitingUserSwitchCallbacks)) {
+ sendContinueUserSwitchLU(uss, oldUserId, newUserId);
+ }
+ }
+ }
+ };
+ asyncTraceBegin("onUserSwitching-" + name, newUserId);
+ mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(newUserId, callback);
+ } catch (RemoteException e) {
+ // Ignore
}
- };
- asyncTraceBegin(trace + "-" + name, 0);
- consumer.accept(mUserSwitchObservers.getBroadcastItem(i), callback);
+ }
+ } else {
+ synchronized (mLock) {
+ sendContinueUserSwitchLU(uss, oldUserId, newUserId);
+ }
}
mUserSwitchObservers.finishBroadcast();
+ t.traceEnd(); // end dispatchUserSwitch-
}
@GuardedBy("mLock")
diff --git a/services/core/java/com/android/server/display/BrightnessRangeController.java b/services/core/java/com/android/server/display/BrightnessRangeController.java
index 50d650855b05..4fd92751d498 100644
--- a/services/core/java/com/android/server/display/BrightnessRangeController.java
+++ b/services/core/java/com/android/server/display/BrightnessRangeController.java
@@ -17,7 +17,6 @@
package com.android.server.display;
import android.annotation.Nullable;
-import android.hardware.display.BrightnessInfo;
import android.os.Handler;
import android.os.IBinder;
@@ -121,8 +120,11 @@ class BrightnessRangeController {
}
void onBrightnessChanged(float brightness, float unthrottledBrightness,
- @BrightnessInfo.BrightnessMaxReason int throttlingReason) {
- mHbmController.onBrightnessChanged(brightness, unthrottledBrightness, throttlingReason);
+ DisplayBrightnessState state) {
+ mHbmController.onHdrBoostApplied(
+ state.getHdrBrightness() != DisplayBrightnessState.BRIGHTNESS_NOT_SET);
+ mHbmController.onBrightnessChanged(brightness, unthrottledBrightness,
+ state.getBrightnessMaxReason());
}
float getCurrentBrightnessMin() {
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 2f82b2ac464a..92f5cab10c2a 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -1638,7 +1638,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
// brightness sources (such as an app override) are not saved to the setting, but should be
// reflected in HBM calculations.
mBrightnessRangeController.onBrightnessChanged(brightnessState, unthrottledBrightnessState,
- clampedState.getBrightnessMaxReason());
+ clampedState);
// Animate the screen brightness when the screen is on or dozing.
// Skip the animation when the screen is off or suspended.
diff --git a/services/core/java/com/android/server/display/HighBrightnessModeController.java b/services/core/java/com/android/server/display/HighBrightnessModeController.java
index 6be0c123d262..0334aa5bca8f 100644
--- a/services/core/java/com/android/server/display/HighBrightnessModeController.java
+++ b/services/core/java/com/android/server/display/HighBrightnessModeController.java
@@ -102,7 +102,8 @@ class HighBrightnessModeController {
BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE;
private int mHbmMode = BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF;
- private boolean mIsHdrLayerPresent = false;
+ @VisibleForTesting
+ boolean mIsHdrLayerPresent = false;
// mMaxDesiredHdrSdrRatio should only be applied when there is a valid backlight->nits mapping
private float mMaxDesiredHdrSdrRatio = DEFAULT_MAX_DESIRED_HDR_SDR_RATIO;
private boolean mForceHbmChangeCallback = false;
@@ -387,6 +388,18 @@ class HighBrightnessModeController {
mHdrBoostDisabled = true;
unregisterHdrListener();
}
+ /**
+ * Hdr boost can be applied by
+ * {@link com.android.server.display.brightness.clamper.HdrBrightnessModifier}, in this case
+ * HBMController should not consume HBM time budget
+ */
+ void onHdrBoostApplied(boolean applied) {
+ // We need to update mIsHdrLayerPresent flag only if HDR boost is controlled by other
+ // component and disabled here
+ if (mHdrBoostDisabled) {
+ mIsHdrLayerPresent = applied;
+ }
+ }
private long calculateRemainingTime(long currentTime) {
if (!deviceSupportsHbm()) {
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index ec0f25169d75..17b712de3be6 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -191,7 +191,6 @@ import android.service.dreams.IDreamManager;
import android.service.vr.IPersistentVrStateCallbacks;
import android.speech.RecognizerIntent;
import android.telecom.TelecomManager;
-import android.util.ArraySet;
import android.util.Log;
import android.util.MathUtils;
import android.util.MutableBoolean;
@@ -725,23 +724,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
private final boolean mVisibleBackgroundUsersEnabled = isVisibleBackgroundUsersEnabled();
- // Key codes that should be ignored for visible background users in MUMD environment.
- private static final Set<Integer> KEY_CODES_IGNORED_FOR_VISIBLE_BACKGROUND_USERS =
- new ArraySet<>(Arrays.asList(
- KeyEvent.KEYCODE_POWER,
- KeyEvent.KEYCODE_SLEEP,
- KeyEvent.KEYCODE_WAKEUP,
- KeyEvent.KEYCODE_CALL,
- KeyEvent.KEYCODE_ENDCALL,
- KeyEvent.KEYCODE_ASSIST,
- KeyEvent.KEYCODE_VOICE_ASSIST,
- KeyEvent.KEYCODE_MUTE,
- KeyEvent.KEYCODE_VOLUME_MUTE,
- KeyEvent.KEYCODE_RECENT_APPS,
- KeyEvent.KEYCODE_APP_SWITCH,
- KeyEvent.KEYCODE_NOTIFICATION
- ));
-
private static final int MSG_DISPATCH_MEDIA_KEY_WITH_WAKE_LOCK = 3;
private static final int MSG_DISPATCH_MEDIA_KEY_REPEAT_WITH_WAKE_LOCK = 4;
private static final int MSG_KEYGUARD_DRAWN_COMPLETE = 5;
@@ -5127,7 +5109,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// There are key events that perform the operation as the current user,
// and these should be ignored for visible background users.
if (mVisibleBackgroundUsersEnabled
- && KEY_CODES_IGNORED_FOR_VISIBLE_BACKGROUND_USERS.contains(keyCode)
+ && !KeyEvent.isVisibleBackgroundUserAllowedKey(keyCode)
&& !isKeyEventForCurrentUser(event.getDisplayId(), keyCode, null)) {
return 0;
}
diff --git a/services/core/java/com/android/server/powerstats/PowerStatsLogger.java b/services/core/java/com/android/server/powerstats/PowerStatsLogger.java
index e80a86d73f90..4fd026a6dc52 100644
--- a/services/core/java/com/android/server/powerstats/PowerStatsLogger.java
+++ b/services/core/java/com/android/server/powerstats/PowerStatsLogger.java
@@ -285,14 +285,20 @@ public final class PowerStatsLogger extends Handler {
}
private void updateCacheFile(String cacheFilename, byte[] data) {
+ AtomicFile atomicCachedFile = null;
+ FileOutputStream fos = null;
try {
- final AtomicFile atomicCachedFile =
+ atomicCachedFile =
new AtomicFile(new File(mDataStoragePath, cacheFilename));
- final FileOutputStream fos = atomicCachedFile.startWrite();
+ fos = atomicCachedFile.startWrite();
fos.write(data);
atomicCachedFile.finishWrite(fos);
} catch (IOException e) {
Slog.e(TAG, "Failed to write current data to cached file", e);
+ if (fos != null) {
+ atomicCachedFile.failWrite(fos);
+ }
+ return;
}
}
diff --git a/services/core/java/com/android/server/security/intrusiondetection/NetworkLogSource.java b/services/core/java/com/android/server/security/intrusiondetection/NetworkLogSource.java
index 083b1fd61c46..f303a588d30c 100644
--- a/services/core/java/com/android/server/security/intrusiondetection/NetworkLogSource.java
+++ b/services/core/java/com/android/server/security/intrusiondetection/NetworkLogSource.java
@@ -129,7 +129,8 @@ public class NetworkLogSource implements DataSource {
timestamp);
dnsEvent.setId(mId);
incrementEventID();
- mDataAggregator.addSingleData(new IntrusionDetectionEvent(dnsEvent));
+ mDataAggregator.addSingleData(
+ IntrusionDetectionEvent.createForDnsEvent(dnsEvent));
}
@Override
@@ -141,7 +142,8 @@ public class NetworkLogSource implements DataSource {
new ConnectEvent(ipAddr, port, mPm.getNameForUid(uid), timestamp);
connectEvent.setId(mId);
incrementEventID();
- mDataAggregator.addSingleData(new IntrusionDetectionEvent(connectEvent));
+ mDataAggregator.addSingleData(
+ IntrusionDetectionEvent.createForConnectEvent(connectEvent));
}
};
}
diff --git a/services/core/java/com/android/server/security/intrusiondetection/SecurityLogSource.java b/services/core/java/com/android/server/security/intrusiondetection/SecurityLogSource.java
index 5611905bf270..142094c9d9f4 100644
--- a/services/core/java/com/android/server/security/intrusiondetection/SecurityLogSource.java
+++ b/services/core/java/com/android/server/security/intrusiondetection/SecurityLogSource.java
@@ -89,7 +89,7 @@ public class SecurityLogSource implements DataSource {
List<IntrusionDetectionEvent> intrusionDetectionEvents =
events.stream()
.filter(event -> event != null)
- .map(event -> new IntrusionDetectionEvent(event))
+ .map(event -> IntrusionDetectionEvent.createForSecurityEvent(event))
.collect(Collectors.toList());
mDataAggregator.addBatchData(intrusionDetectionEvents);
}
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 290f155bb4cd..2971e8edef43 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -438,10 +438,13 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
/** It is set from keyguard-going-away to set-keyguard-shown. */
static final int DEMOTE_TOP_REASON_DURING_UNLOCKING = 1;
+ /** It is set when notification shade occludes the foreground app. */
+ static final int DEMOTE_TOP_REASON_EXPANDED_NOTIFICATION_SHADE = 1 << 1;
@Retention(RetentionPolicy.SOURCE)
@IntDef({
DEMOTE_TOP_REASON_DURING_UNLOCKING,
+ DEMOTE_TOP_REASON_EXPANDED_NOTIFICATION_SHADE,
})
@interface DemoteTopReason {}
@@ -5247,6 +5250,12 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
: mRootWindowContainer.getTopResumedActivity();
mTopApp = top != null ? top.app : null;
if (mTopApp == mPreviousProcess) mPreviousProcess = null;
+
+ final int demoteReasons = mDemoteTopAppReasons;
+ if ((demoteReasons & DEMOTE_TOP_REASON_EXPANDED_NOTIFICATION_SHADE) != 0) {
+ Trace.instant(TRACE_TAG_WINDOW_MANAGER, "cancel-demote-top-for-ns-switch");
+ mDemoteTopAppReasons = demoteReasons & ~DEMOTE_TOP_REASON_EXPANDED_NOTIFICATION_SHADE;
+ }
}
/**
diff --git a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
index 852a0ac054f4..89d756ca5aaf 100644
--- a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
+++ b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
@@ -1091,11 +1091,6 @@ public class BackgroundActivityStartController {
// don't abort if the callingUid has SYSTEM_ALERT_WINDOW permission
if (mService.hasSystemAlertWindowPermission(state.mCallingUid, state.mCallingPid,
state.mCallingPackage)) {
- Slog.w(
- TAG,
- "Background activity start for "
- + state.mCallingPackage
- + " allowed because SYSTEM_ALERT_WINDOW permission is granted.");
return new BalVerdict(BAL_ALLOW_SAW_PERMISSION,
/*background*/ true, "SYSTEM_ALERT_WINDOW permission is granted");
}
@@ -1167,18 +1162,9 @@ public class BackgroundActivityStartController {
}
// don't abort if the realCallingUid has SYSTEM_ALERT_WINDOW permission
- Slog.i(TAG, "hasSystemAlertWindowPermission(" + state.mRealCallingUid + ", "
- + state.mRealCallingPid + ", " + state.mRealCallingPackage + ") "
- + balStartModeToString(
- state.mCheckedOptions.getPendingIntentBackgroundActivityStartMode()));
if (allowAlways
&& mService.hasSystemAlertWindowPermission(state.mRealCallingUid,
state.mRealCallingPid, state.mRealCallingPackage)) {
- Slog.w(
- TAG,
- "Background activity start for "
- + state.mRealCallingPackage
- + " allowed because SYSTEM_ALERT_WINDOW permission is granted.");
return new BalVerdict(BAL_ALLOW_SAW_PERMISSION,
/*background*/ true, "SYSTEM_ALERT_WINDOW permission is granted");
}
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 4dd950ba6ee9..5c3fbdfcff0e 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -440,7 +440,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
private boolean mSandboxDisplayApis = true;
/** Whether {@link #setIgnoreOrientationRequest} is called to override the default policy. */
- @VisibleForTesting
boolean mHasSetIgnoreOrientationRequest;
/**
diff --git a/services/core/java/com/android/server/wm/DisplayWindowSettings.java b/services/core/java/com/android/server/wm/DisplayWindowSettings.java
index f0ba822c37c5..4ae100857f55 100644
--- a/services/core/java/com/android/server/wm/DisplayWindowSettings.java
+++ b/services/core/java/com/android/server/wm/DisplayWindowSettings.java
@@ -376,6 +376,9 @@ class DisplayWindowSettings {
if (settings.mIgnoreOrientationRequest != null) {
dc.setIgnoreOrientationRequest(settings.mIgnoreOrientationRequest);
+ } else if (dc.mHasSetIgnoreOrientationRequest) {
+ // Null entry is default behavior, i.e. do not ignore.
+ dc.setIgnoreOrientationRequest(false);
}
dc.getDisplayRotation().resetAllowAllRotations();
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 04650b9e0150..793f18992109 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -121,6 +121,7 @@ import static com.android.server.LockGuard.INDEX_WINDOW;
import static com.android.server.LockGuard.installLock;
import static com.android.server.policy.PhoneWindowManager.TRACE_WAIT_FOR_ALL_WINDOWS_DRAWN_METHOD;
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
+import static com.android.server.wm.ActivityTaskManagerService.DEMOTE_TOP_REASON_EXPANDED_NOTIFICATION_SHADE;
import static com.android.server.wm.ActivityTaskManagerService.POWER_MODE_REASON_CHANGE_DISPLAY;
import static com.android.server.wm.AppCompatConfiguration.LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND;
import static com.android.server.wm.AppCompatConfiguration.LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING;
@@ -7845,6 +7846,37 @@ public class WindowManagerService extends IWindowManager.Stub
}
@Override
+ public void onNotificationShadeExpanded(IBinder token, boolean expanded) {
+ synchronized (mGlobalLock) {
+ final WindowState w = mWindowMap.get(token);
+ if (w == null || w != w.mDisplayContent.getDisplayPolicy().getNotificationShade()) {
+ return;
+ }
+ final WindowProcessController topApp = mAtmService.mTopApp;
+ // Demotes the priority of top app if notification shade is expanded to occlude the app.
+ // So the notification shade may have more capacity to draw and animate.
+ final int demoteTopAppReasons = mAtmService.mDemoteTopAppReasons;
+ if (expanded && mAtmService.mTopProcessState == ActivityManager.PROCESS_STATE_TOP
+ && (demoteTopAppReasons & DEMOTE_TOP_REASON_EXPANDED_NOTIFICATION_SHADE) == 0) {
+ mAtmService.mDemoteTopAppReasons =
+ demoteTopAppReasons | DEMOTE_TOP_REASON_EXPANDED_NOTIFICATION_SHADE;
+ Trace.instant(TRACE_TAG_WINDOW_MANAGER, "demote-top-for-ns");
+ if (topApp != null) {
+ topApp.scheduleUpdateOomAdj();
+ }
+ } else if (!expanded
+ && (demoteTopAppReasons & DEMOTE_TOP_REASON_EXPANDED_NOTIFICATION_SHADE) != 0) {
+ mAtmService.mDemoteTopAppReasons =
+ demoteTopAppReasons & ~DEMOTE_TOP_REASON_EXPANDED_NOTIFICATION_SHADE;
+ Trace.instant(TRACE_TAG_WINDOW_MANAGER, "cancel-demote-top-for-ns");
+ if (topApp != null) {
+ topApp.scheduleUpdateOomAdj();
+ }
+ }
+ }
+ }
+
+ @Override
public void registerShortcutKey(long shortcutCode, IShortcutService shortcutKeyReceiver)
throws RemoteException {
if (!checkCallingPermission(REGISTER_WINDOW_MANAGER_LISTENERS, "registerShortcutKey")) {
diff --git a/services/permission/java/com/android/server/permission/access/appop/AppOpService.kt b/services/permission/java/com/android/server/permission/access/appop/AppOpService.kt
index 161a8168d993..b356b830a5c4 100644
--- a/services/permission/java/com/android/server/permission/access/appop/AppOpService.kt
+++ b/services/permission/java/com/android/server/permission/access/appop/AppOpService.kt
@@ -119,6 +119,10 @@ class AppOpService(private val service: AccessCheckingService) : AppOpsCheckingS
val permissions = service.getState { with(permissionPolicy) { getPermissions() } }
for (appOpCode in 0 until AppOpsManager._NUM_OP) {
+ // Ops that default to MODE_FOREGROUND are foregroundable.
+ if (AppOpsManager.opToDefaultMode(appOpCode) == AppOpsManager.MODE_FOREGROUND) {
+ foregroundableOps[appOpCode] = true
+ }
AppOpsManager.opToPermission(appOpCode)?.let { permissionName ->
// Multiple ops might map to a single permission but only one is considered the
// runtime appop calculations.
diff --git a/services/tests/displayservicetests/src/com/android/server/display/HighBrightnessModeControllerTest.java b/services/tests/displayservicetests/src/com/android/server/display/HighBrightnessModeControllerTest.java
index cde87b9b89b2..255d236186b6 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/HighBrightnessModeControllerTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/HighBrightnessModeControllerTest.java
@@ -720,6 +720,25 @@ public class HighBrightnessModeControllerTest {
.DISPLAY_HBM_STATE_CHANGED__REASON__HBM_SV_OFF_LOW_REQUESTED_BRIGHTNESS));
}
+ @Test
+ public void testDoesNotAcceptExternalHdrLayerUpdates_hdrBoostEnabled() {
+ final HighBrightnessModeController hbmc = createDefaultHbm();
+ assertFalse(hbmc.mIsHdrLayerPresent);
+
+ hbmc.onHdrBoostApplied(true);
+ assertFalse(hbmc.mIsHdrLayerPresent);
+ }
+
+ @Test
+ public void testAcceptsExternalHdrLayerUpdates_hdrBoostDisabled() {
+ final HighBrightnessModeController hbmc = createDefaultHbm();
+ hbmc.disableHdrBoost();
+ assertFalse(hbmc.mIsHdrLayerPresent);
+
+ hbmc.onHdrBoostApplied(true);
+ assertTrue(hbmc.mIsHdrLayerPresent);
+ }
+
private void assertState(HighBrightnessModeController hbmc,
float brightnessMin, float brightnessMax, int hbmMode) {
assertEquals(brightnessMin, hbmc.getCurrentBrightnessMin(), EPSILON);
diff --git a/services/tests/security/intrusiondetection/src/com/android/server/security/intrusiondetection/IntrusionDetectionServiceTest.java b/services/tests/security/intrusiondetection/src/com/android/server/security/intrusiondetection/IntrusionDetectionServiceTest.java
index 5cba6b2c3e67..298d27e2e8c4 100644
--- a/services/tests/security/intrusiondetection/src/com/android/server/security/intrusiondetection/IntrusionDetectionServiceTest.java
+++ b/services/tests/security/intrusiondetection/src/com/android/server/security/intrusiondetection/IntrusionDetectionServiceTest.java
@@ -350,15 +350,17 @@ public class IntrusionDetectionServiceTest {
mDataAggregator.setHandler(mLooperOfDataAggregator, mockThread);
SecurityEvent securityEvent = new SecurityEvent(0, new byte[0]);
- IntrusionDetectionEvent eventOne = new IntrusionDetectionEvent(securityEvent);
+ IntrusionDetectionEvent eventOne =
+ IntrusionDetectionEvent.createForSecurityEvent(securityEvent);
ConnectEvent connectEvent = new ConnectEvent(
"127.0.0.1", 80, null, 0);
- IntrusionDetectionEvent eventTwo = new IntrusionDetectionEvent(connectEvent);
+ IntrusionDetectionEvent eventTwo =
+ IntrusionDetectionEvent.createForConnectEvent(connectEvent);
DnsEvent dnsEvent = new DnsEvent(
null, new String[] {"127.0.0.1"}, 1, null, 0);
- IntrusionDetectionEvent eventThree = new IntrusionDetectionEvent(dnsEvent);
+ IntrusionDetectionEvent eventThree = IntrusionDetectionEvent.createForDnsEvent(dnsEvent);
List<IntrusionDetectionEvent> events = new ArrayList<>();
events.add(eventOne);
@@ -581,7 +583,8 @@ public class IntrusionDetectionServiceTest {
// call the methods on the transport object
IntrusionDetectionEvent event =
- new IntrusionDetectionEvent(new SecurityEvent(123, new byte[15]));
+ IntrusionDetectionEvent.createForSecurityEvent(
+ new SecurityEvent(123, new byte[15]));
List<IntrusionDetectionEvent> events = new ArrayList<>();
events.add(event);
assertTrue(transport.initialize());
diff --git a/services/tests/servicestests/assets/shortcut/dumpsys_expected.txt b/services/tests/servicestests/assets/shortcut/dumpsys_expected.txt
index eed2087f80ef..029ada3f5118 100644
--- a/services/tests/servicestests/assets/shortcut/dumpsys_expected.txt
+++ b/services/tests/servicestests/assets/shortcut/dumpsys_expected.txt
@@ -1,7 +1,7 @@
{
"shortcut": [
{
- "userId": 0,
+ "userId": 10,
"launchers": [
{
"name": "com.android.launcher.1"
@@ -55,7 +55,7 @@
]
},
{
- "userId": 10,
+ "userId": 11,
"launchers": [
{
"name": "com.android.launcher.1"
diff --git a/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java b/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java
index 7dbbff22a537..2fe6918630f6 100644
--- a/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java
@@ -33,7 +33,6 @@ import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentat
import static com.android.server.am.UserController.CLEAR_USER_JOURNEY_SESSION_MSG;
import static com.android.server.am.UserController.COMPLETE_USER_SWITCH_MSG;
import static com.android.server.am.UserController.CONTINUE_USER_SWITCH_MSG;
-import static com.android.server.am.UserController.DEFAULT_BEFORE_USER_SWITCH_TIMEOUT_MS;
import static com.android.server.am.UserController.REPORT_LOCKED_BOOT_COMPLETE_MSG;
import static com.android.server.am.UserController.REPORT_USER_SWITCH_COMPLETE_MSG;
import static com.android.server.am.UserController.REPORT_USER_SWITCH_MSG;
@@ -95,7 +94,6 @@ import android.os.Looper;
import android.os.Message;
import android.os.PowerManagerInternal;
import android.os.RemoteException;
-import android.os.SystemClock;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.storage.IStorageManager;
@@ -183,12 +181,14 @@ public class UserControllerTest {
Intent.ACTION_USER_STARTING);
private static final Set<Integer> START_FOREGROUND_USER_MESSAGE_CODES = newHashSet(
+ 0, // for startUserInternalOnHandler
REPORT_USER_SWITCH_MSG,
USER_SWITCH_TIMEOUT_MSG,
USER_START_MSG,
USER_CURRENT_MSG);
private static final Set<Integer> START_BACKGROUND_USER_MESSAGE_CODES = newHashSet(
+ 0, // for startUserInternalOnHandler
USER_START_MSG,
REPORT_LOCKED_BOOT_COMPLETE_MSG);
@@ -376,7 +376,7 @@ public class UserControllerTest {
// and the cascade effect goes on...). In fact, a better approach would to not assert the
// binder calls, but their side effects (in this case, that the user is stopped right away)
assertWithMessage("wrong binder message calls").that(mInjector.mHandler.getMessageCodes())
- .containsExactly(USER_START_MSG);
+ .containsExactly(/* for startUserInternalOnHandler */ 0, USER_START_MSG);
}
private void startUserAssertions(
@@ -419,12 +419,17 @@ public class UserControllerTest {
@Test
public void testDispatchUserSwitch() throws RemoteException {
// Prepare mock observer and register it
- IUserSwitchObserver observer = registerUserSwitchObserver(
- /* replyToOnBeforeUserSwitchingCallback= */ true,
- /* replyToOnUserSwitchingCallback= */ true);
+ IUserSwitchObserver observer = mock(IUserSwitchObserver.class);
+ when(observer.asBinder()).thenReturn(new Binder());
+ doAnswer(invocation -> {
+ IRemoteCallback callback = (IRemoteCallback) invocation.getArguments()[1];
+ callback.sendResult(null);
+ return null;
+ }).when(observer).onUserSwitching(anyInt(), any());
+ mUserController.registerUserSwitchObserver(observer, "mock");
// Start user -- this will update state of mUserController
mUserController.startUser(TEST_USER_ID, USER_START_MODE_FOREGROUND);
- verify(observer, times(1)).onBeforeUserSwitching(eq(TEST_USER_ID), any());
+ verify(observer, times(1)).onBeforeUserSwitching(eq(TEST_USER_ID));
Message reportMsg = mInjector.mHandler.getMessageForCode(REPORT_USER_SWITCH_MSG);
assertNotNull(reportMsg);
UserState userState = (UserState) reportMsg.obj;
@@ -448,26 +453,14 @@ public class UserControllerTest {
}
@Test
- public void testShouldCrashWhenOnBeforeUserSwitchingTimeouts() throws RemoteException {
- IUserSwitchObserver observer = registerUserSwitchObserver(
- /* replyToOnBeforeUserSwitchingCallback= */ false,
- /* replyToOnUserSwitchingCallback= */ true);
- mUserController.startUser(TEST_USER_ID, USER_START_MODE_FOREGROUND);
- verify(observer, times(1)).onBeforeUserSwitching(eq(TEST_USER_ID), any());
- assertThrows("Should have crashed when observers don't reply to onBeforeUserSwitching in "
- + DEFAULT_BEFORE_USER_SWITCH_TIMEOUT_MS + " ms", RuntimeException.class,
- mInjector.mHandler::runPendingCallbacks);
- }
-
- @Test
public void testDispatchUserSwitchBadReceiver() throws RemoteException {
- // Prepare mock observer which doesn't notify the onUserSwitching callback and register it
- IUserSwitchObserver observer = registerUserSwitchObserver(
- /* replyToOnBeforeUserSwitchingCallback= */ true,
- /* replyToOnUserSwitchingCallback= */ false);
+ // Prepare mock observer which doesn't notify the callback and register it
+ IUserSwitchObserver observer = mock(IUserSwitchObserver.class);
+ when(observer.asBinder()).thenReturn(new Binder());
+ mUserController.registerUserSwitchObserver(observer, "mock");
// Start user -- this will update state of mUserController
mUserController.startUser(TEST_USER_ID, USER_START_MODE_FOREGROUND);
- verify(observer, times(1)).onBeforeUserSwitching(eq(TEST_USER_ID), any());
+ verify(observer, times(1)).onBeforeUserSwitching(eq(TEST_USER_ID));
Message reportMsg = mInjector.mHandler.getMessageForCode(REPORT_USER_SWITCH_MSG);
assertNotNull(reportMsg);
UserState userState = (UserState) reportMsg.obj;
@@ -558,6 +551,7 @@ public class UserControllerTest {
expectedCodes.add(REPORT_USER_SWITCH_COMPLETE_MSG);
if (backgroundUserStopping) {
expectedCodes.add(CLEAR_USER_JOURNEY_SESSION_MSG);
+ expectedCodes.add(0); // this is for directly posting in stopping.
}
if (expectScheduleBackgroundUserStopping) {
expectedCodes.add(SCHEDULED_STOP_BACKGROUND_USER_MSG);
@@ -573,9 +567,9 @@ public class UserControllerTest {
@Test
public void testDispatchUserSwitchComplete() throws RemoteException {
// Prepare mock observer and register it
- IUserSwitchObserver observer = registerUserSwitchObserver(
- /* replyToOnBeforeUserSwitchingCallback= */ true,
- /* replyToOnUserSwitchingCallback= */ true);
+ IUserSwitchObserver observer = mock(IUserSwitchObserver.class);
+ when(observer.asBinder()).thenReturn(new Binder());
+ mUserController.registerUserSwitchObserver(observer, "mock");
// Start user -- this will update state of mUserController
mUserController.startUser(TEST_USER_ID, USER_START_MODE_FOREGROUND);
Message reportMsg = mInjector.mHandler.getMessageForCode(REPORT_USER_SWITCH_MSG);
@@ -1758,29 +1752,6 @@ public class UserControllerTest {
verify(mInjector, never()).onSystemUserVisibilityChanged(anyBoolean());
}
- private IUserSwitchObserver registerUserSwitchObserver(
- boolean replyToOnBeforeUserSwitchingCallback, boolean replyToOnUserSwitchingCallback)
- throws RemoteException {
- IUserSwitchObserver observer = mock(IUserSwitchObserver.class);
- when(observer.asBinder()).thenReturn(new Binder());
- if (replyToOnBeforeUserSwitchingCallback) {
- doAnswer(invocation -> {
- IRemoteCallback callback = (IRemoteCallback) invocation.getArguments()[1];
- callback.sendResult(null);
- return null;
- }).when(observer).onBeforeUserSwitching(anyInt(), any());
- }
- if (replyToOnUserSwitchingCallback) {
- doAnswer(invocation -> {
- IRemoteCallback callback = (IRemoteCallback) invocation.getArguments()[1];
- callback.sendResult(null);
- return null;
- }).when(observer).onUserSwitching(anyInt(), any());
- }
- mUserController.registerUserSwitchObserver(observer, "mock");
- return observer;
- }
-
// Should be public to allow mocking
private static class TestInjector extends UserController.Injector {
public final TestHandler mHandler;
@@ -1986,7 +1957,6 @@ public class UserControllerTest {
* fix this, but in the meantime, this is your warning.
*/
private final List<Message> mMessages = new ArrayList<>();
- private final List<Runnable> mPendingCallbacks = new ArrayList<>();
TestHandler(Looper looper) {
super(looper);
@@ -2019,24 +1989,14 @@ public class UserControllerTest {
@Override
public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
- if (msg.getCallback() == null) {
- Message copy = new Message();
- copy.copyFrom(msg);
- mMessages.add(copy);
- } else {
- if (SystemClock.uptimeMillis() >= uptimeMillis) {
- msg.getCallback().run();
- } else {
- mPendingCallbacks.add(msg.getCallback());
- }
+ Message copy = new Message();
+ copy.copyFrom(msg);
+ mMessages.add(copy);
+ if (msg.getCallback() != null) {
+ msg.getCallback().run();
msg.setCallback(null);
}
return super.sendMessageAtTime(msg, uptimeMillis);
}
-
- private void runPendingCallbacks() {
- mPendingCallbacks.forEach(Runnable::run);
- mPendingCallbacks.clear();
- }
}
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
index 2c1e37beda26..0b2a2cdd26b9 100644
--- a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
@@ -721,54 +721,56 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
protected static final String SYSTEM_PACKAGE_NAME = "android";
protected static final String CALLING_PACKAGE_1 = "com.android.test.1";
- protected static final int CALLING_UID_1 = 10001;
+ protected static final int CALLING_UID_1 = 1000001;
protected static final String CALLING_PACKAGE_2 = "com.android.test.2";
- protected static final int CALLING_UID_2 = 10002;
+ protected static final int CALLING_UID_2 = 1000002;
protected static final String CALLING_PACKAGE_3 = "com.android.test.3";
- protected static final int CALLING_UID_3 = 10003;
+ protected static final int CALLING_UID_3 = 1000003;
protected static final String CALLING_PACKAGE_4 = "com.android.test.4";
- protected static final int CALLING_UID_4 = 10004;
+ protected static final int CALLING_UID_4 = 1000004;
protected static final String LAUNCHER_1 = "com.android.launcher.1";
- protected static final int LAUNCHER_UID_1 = 10011;
+ protected static final int LAUNCHER_UID_1 = 1000011;
protected static final String LAUNCHER_2 = "com.android.launcher.2";
- protected static final int LAUNCHER_UID_2 = 10012;
+ protected static final int LAUNCHER_UID_2 = 1000012;
protected static final String LAUNCHER_3 = "com.android.launcher.3";
- protected static final int LAUNCHER_UID_3 = 10013;
+ protected static final int LAUNCHER_UID_3 = 1000013;
protected static final String LAUNCHER_4 = "com.android.launcher.4";
- protected static final int LAUNCHER_UID_4 = 10014;
+ protected static final int LAUNCHER_UID_4 = 1000014;
protected static final String CHOOSER_ACTIVITY_PACKAGE = "com.android.intentresolver";
- protected static final int CHOOSER_ACTIVITY_UID = 10015;
+ protected static final int CHOOSER_ACTIVITY_UID = 1000015;
- protected static final int USER_0 = UserHandle.USER_SYSTEM;
+ // Shifting primary user to 10 to support HSUM
protected static final int USER_10 = 10;
protected static final int USER_11 = 11;
+ protected static final int USER_12 = 12;
protected static final int USER_P0 = 20; // profile of user 0 (MANAGED_PROFILE *not* set)
protected static final int USER_P1 = 21; // another profile of user 0 (MANAGED_PROFILE set)
- protected static final UserHandle HANDLE_USER_0 = UserHandle.of(USER_0);
protected static final UserHandle HANDLE_USER_10 = UserHandle.of(USER_10);
protected static final UserHandle HANDLE_USER_11 = UserHandle.of(USER_11);
+ protected static final UserHandle HANDLE_USER_12 = UserHandle.of(USER_12);
protected static final UserHandle HANDLE_USER_P0 = UserHandle.of(USER_P0);
protected static final UserHandle HANDLE_USER_P1 = UserHandle.of(USER_P1);
- protected static final UserInfo USER_INFO_0 = withProfileGroupId(
- new UserInfo(USER_0, "user0",
- UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY | UserInfo.FLAG_INITIALIZED), 0);
-
- protected static final UserInfo USER_INFO_10 =
- new UserInfo(USER_10, "user10", UserInfo.FLAG_INITIALIZED);
+ protected static final UserInfo USER_INFO_10 = withProfileGroupId(
+ new UserInfo(USER_10, "user10",
+ UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY | UserInfo.FLAG_INITIALIZED),
+ USER_10);
protected static final UserInfo USER_INFO_11 =
new UserInfo(USER_11, "user11", UserInfo.FLAG_INITIALIZED);
+ protected static final UserInfo USER_INFO_12 =
+ new UserInfo(USER_12, "user12", UserInfo.FLAG_INITIALIZED);
+
/*
* Cheat: USER_P0 is a sub profile of USER_0, but it doesn't have the MANAGED_PROFILE flag set.
* Due to a change made to LauncherApps (b/34340531), work profile apps a no longer able
@@ -778,11 +780,11 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
* can't access main profile's shortcuts.)
*/
protected static final UserInfo USER_INFO_P0 = withProfileGroupId(
- new UserInfo(USER_P0, "userP0", UserInfo.FLAG_INITIALIZED), 0);
+ new UserInfo(USER_P0, "userP0", UserInfo.FLAG_INITIALIZED), USER_10);
protected static final UserInfo USER_INFO_P1 = withProfileGroupId(
new UserInfo(USER_P1, "userP1",
- UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_MANAGED_PROFILE), 0);
+ UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_MANAGED_PROFILE), USER_10);
protected static final UserProperties USER_PROPERTIES_0 =
new UserProperties.Builder().setItemsRestrictedOnHomeScreen(false).build();
@@ -925,14 +927,14 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
deleteAllSavedFiles();
// Set up users.
- mUserInfos.put(USER_0, USER_INFO_0);
mUserInfos.put(USER_10, USER_INFO_10);
mUserInfos.put(USER_11, USER_INFO_11);
+ mUserInfos.put(USER_12, USER_INFO_12);
mUserInfos.put(USER_P0, USER_INFO_P0);
mUserInfos.put(USER_P1, USER_INFO_P1);
- mUserProperties.put(USER_0, USER_PROPERTIES_0);
- mUserProperties.put(USER_10, USER_PROPERTIES_10);
- mUserProperties.put(USER_11, USER_PROPERTIES_11);
+ mUserProperties.put(USER_10, USER_PROPERTIES_0);
+ mUserProperties.put(USER_11, USER_PROPERTIES_10);
+ mUserProperties.put(USER_12, USER_PROPERTIES_11);
when(mMockUserManagerInternal.isUserUnlockingOrUnlocked(anyInt()))
.thenAnswer(inv -> {
@@ -994,16 +996,16 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
mUserInfos.values().toArray(new UserInfo[0]));
// User 0 and P0 are always running
- mRunningUsers.put(USER_0, true);
- mRunningUsers.put(USER_10, false);
+ mRunningUsers.put(USER_10, true);
mRunningUsers.put(USER_11, false);
+ mRunningUsers.put(USER_12, false);
mRunningUsers.put(USER_P0, true);
mRunningUsers.put(USER_P1, true);
// Unlock all users by default.
- mUnlockedUsers.put(USER_0, true);
mUnlockedUsers.put(USER_10, true);
mUnlockedUsers.put(USER_11, true);
+ mUnlockedUsers.put(USER_12, true);
mUnlockedUsers.put(USER_P0, true);
mUnlockedUsers.put(USER_P1, true);
@@ -1391,7 +1393,7 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
}
protected void setCaller(String packageName) {
- setCaller(packageName, UserHandle.USER_SYSTEM);
+ setCaller(packageName, USER_10);
}
protected String getCallingPackage() {
@@ -2223,7 +2225,7 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
dumpsysOnLogcat("Before backup");
- final byte[] payload = mService.getBackupPayload(USER_0);
+ final byte[] payload = mService.getBackupPayload(USER_10);
if (ENABLE_DUMP) {
final String xml = new String(payload);
Log.v(TAG, "Backup payload:");
@@ -2233,7 +2235,7 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
}
// Before doing anything else, uninstall all packages.
- for (int userId : list(USER_0, USER_P0)) {
+ for (int userId : list(USER_10, USER_P0)) {
for (String pkg : list(CALLING_PACKAGE_1, CALLING_PACKAGE_2, CALLING_PACKAGE_3,
LAUNCHER_1, LAUNCHER_2, LAUNCHER_3)) {
uninstallPackage(userId, pkg);
@@ -2245,11 +2247,11 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
deleteAllSavedFiles();
initService();
- mService.applyRestore(payload, USER_0);
+ mService.applyRestore(payload, USER_10);
// handleUnlockUser will perform the gone package check, but it shouldn't remove
// shadow information.
- mService.handleUnlockUser(USER_0);
+ mService.handleUnlockUser(USER_10);
dumpsysOnLogcat("After restore");
@@ -2257,24 +2259,24 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
}
protected void prepareCrossProfileDataSet() {
- mRunningUsers.put(USER_10, true); // this test needs user 10.
+ mRunningUsers.put(USER_11, true); // this test needs user 10.
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"),
makeShortcut("s4"), makeShortcut("s5"), makeShortcut("s6"))));
});
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"),
makeShortcut("s4"), makeShortcut("s5"), makeShortcut("s6"))));
});
- runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_3, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"),
makeShortcut("s4"), makeShortcut("s5"), makeShortcut("s6"))));
});
- runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_4, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(list()));
});
runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
@@ -2282,79 +2284,79 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"),
makeShortcut("s4"), makeShortcut("s5"), makeShortcut("s6"))));
});
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("x1"), makeShortcut("x2"), makeShortcut("x3"),
makeShortcut("x4"), makeShortcut("x5"), makeShortcut("x6"))));
});
- runWithCaller(LAUNCHER_1, USER_0, () -> {
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s1"), HANDLE_USER_0);
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list("s1", "s2"), HANDLE_USER_0);
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_3, list("s1", "s2", "s3"), HANDLE_USER_0);
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s1"), HANDLE_USER_10);
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list("s1", "s2"), HANDLE_USER_10);
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_3, list("s1", "s2", "s3"), HANDLE_USER_10);
mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s1", "s4"), HANDLE_USER_P0);
});
- runWithCaller(LAUNCHER_2, USER_0, () -> {
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s2"), HANDLE_USER_0);
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list("s2", "s3"), HANDLE_USER_0);
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_3, list("s2", "s3", "s4"), HANDLE_USER_0);
+ runWithCaller(LAUNCHER_2, USER_10, () -> {
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s2"), HANDLE_USER_10);
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list("s2", "s3"), HANDLE_USER_10);
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_3, list("s2", "s3", "s4"), HANDLE_USER_10);
mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s2", "s5"), HANDLE_USER_P0);
});
// Note LAUNCHER_3 has allowBackup=false.
- runWithCaller(LAUNCHER_3, USER_0, () -> {
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s3"), HANDLE_USER_0);
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list("s3", "s4"), HANDLE_USER_0);
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_3, list("s3", "s4", "s5"), HANDLE_USER_0);
+ runWithCaller(LAUNCHER_3, USER_10, () -> {
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s3"), HANDLE_USER_10);
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list("s3", "s4"), HANDLE_USER_10);
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_3, list("s3", "s4", "s5"), HANDLE_USER_10);
mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s3", "s6"), HANDLE_USER_P0);
});
- runWithCaller(LAUNCHER_4, USER_0, () -> {
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list(), HANDLE_USER_0);
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list(), HANDLE_USER_0);
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_3, list(), HANDLE_USER_0);
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_4, list(), HANDLE_USER_0);
+ runWithCaller(LAUNCHER_4, USER_10, () -> {
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list(), HANDLE_USER_10);
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list(), HANDLE_USER_10);
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_3, list(), HANDLE_USER_10);
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_4, list(), HANDLE_USER_10);
});
// Launcher on a managed profile is referring ot user 0!
runWithCaller(LAUNCHER_1, USER_P0, () -> {
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s3", "s4"), HANDLE_USER_0);
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list("s3", "s4", "s5"), HANDLE_USER_0);
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s3", "s4"), HANDLE_USER_10);
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list("s3", "s4", "s5"), HANDLE_USER_10);
mLauncherApps.pinShortcuts(CALLING_PACKAGE_3, list("s3", "s4", "s5", "s6"),
- HANDLE_USER_0);
+ HANDLE_USER_10);
mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s4", "s1"), HANDLE_USER_P0);
});
- runWithCaller(LAUNCHER_1, USER_10, () -> {
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("x4", "x5"), HANDLE_USER_10);
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list("x4", "x5", "x6"), HANDLE_USER_10);
+ runWithCaller(LAUNCHER_1, USER_11, () -> {
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("x4", "x5"), HANDLE_USER_11);
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list("x4", "x5", "x6"), HANDLE_USER_11);
mLauncherApps.pinShortcuts(CALLING_PACKAGE_3, list("x4", "x5", "x6", "x1"),
- HANDLE_USER_10);
+ HANDLE_USER_11);
});
// Then remove some dynamic shortcuts.
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
});
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
});
- runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_3, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
});
- runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_4, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(list()));
});
runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
});
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("x1"), makeShortcut("x2"), makeShortcut("x3"))));
});
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
index d70ffd2ec050..c01283a236c4 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
@@ -285,7 +285,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
}
public void SetDynamicShortcuts() {
- setCaller(CALLING_PACKAGE_1, USER_0);
+ setCaller(CALLING_PACKAGE_1, USER_10);
final Icon icon1 = Icon.createWithResource(getTestContext(), R.drawable.icon1);
final Icon icon2 = Icon.createWithBitmap(BitmapFactory.decodeResource(
@@ -338,7 +338,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
dumpsysOnLogcat();
mInjectedCurrentTimeMillis++; // Need to advance the clock for reset to work.
- mService.resetThrottlingInner(UserHandle.USER_SYSTEM);
+ mService.resetThrottlingInner(USER_10);
dumpsysOnLogcat();
@@ -347,15 +347,15 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
// TODO Check max number
- mRunningUsers.put(USER_10, true);
+ mRunningUsers.put(USER_11, true);
- runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_11, () -> {
assertTrue(mManager.setDynamicShortcuts(list(makeShortcut("s1"))));
});
}
public void AddDynamicShortcuts() {
- setCaller(CALLING_PACKAGE_1, USER_0);
+ setCaller(CALLING_PACKAGE_1, USER_10);
final ShortcutInfo si1 = makeShortcut("shortcut1");
final ShortcutInfo si2 = makeShortcut("shortcut2");
@@ -395,9 +395,9 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
// TODO Check fields.
- mRunningUsers.put(USER_10, true);
+ mRunningUsers.put(USER_11, true);
- runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_11, () -> {
assertTrue(mManager.addDynamicShortcuts(list(makeShortcut("s1"))));
});
}
@@ -406,7 +406,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
// Change the max number of shortcuts.
mService.updateConfigurationLocked(ConfigConstants.KEY_MAX_SHORTCUTS + "=5,"
+ ShortcutService.ConfigConstants.KEY_SAVE_DELAY_MILLIS + "=1");
- setCaller(CALLING_PACKAGE_1, USER_0);
+ setCaller(CALLING_PACKAGE_1, USER_10);
final ShortcutInfo s1 = makeShortcut("s1");
final ShortcutInfo s2 = makeShortcut("s2");
@@ -420,10 +420,11 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
// Test push as first shortcut
mManager.pushDynamicShortcut(s1);
+ setCaller(CALLING_PACKAGE_1, USER_10);
assertShortcutIds(assertAllNotKeyFieldsOnly(mManager.getDynamicShortcuts()), "s1");
assertEquals(0, getCallerShortcut("s1").getRank());
verify(mMockUsageStatsManagerInternal, times(1)).reportShortcutUsage(
- eq(CALLING_PACKAGE_1), eq("s1"), eq(USER_0));
+ eq(CALLING_PACKAGE_1), eq("s1"), eq(USER_10));
// Test push when other shortcuts exist
Mockito.reset(mMockUsageStatsManagerInternal);
@@ -436,11 +437,11 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertEquals(1, getCallerShortcut("s1").getRank());
assertEquals(2, getCallerShortcut("s2").getRank());
verify(mMockUsageStatsManagerInternal, times(0)).reportShortcutUsage(
- eq(CALLING_PACKAGE_1), eq("s1"), eq(USER_0));
+ eq(CALLING_PACKAGE_1), eq("s1"), eq(USER_10));
verify(mMockUsageStatsManagerInternal, times(0)).reportShortcutUsage(
- eq(CALLING_PACKAGE_1), eq("s2"), eq(USER_0));
+ eq(CALLING_PACKAGE_1), eq("s2"), eq(USER_10));
verify(mMockUsageStatsManagerInternal, times(1)).reportShortcutUsage(
- eq(CALLING_PACKAGE_1), eq("s3"), eq(USER_0));
+ eq(CALLING_PACKAGE_1), eq("s3"), eq(USER_10));
mInjectedCurrentTimeMillis += INTERVAL; // reset
@@ -451,7 +452,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertEquals(2, getCallerShortcut("s4").getRank());
assertEquals(3, getCallerShortcut("s2").getRank());
verify(mMockUsageStatsManagerInternal, times(1)).reportShortcutUsage(
- eq(CALLING_PACKAGE_1), eq("s4"), eq(USER_0));
+ eq(CALLING_PACKAGE_1), eq("s4"), eq(USER_10));
// Push existing shortcut with set rank
Mockito.reset(mMockUsageStatsManagerInternal);
@@ -461,7 +462,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertEquals(2, getCallerShortcut("s2").getRank());
assertEquals(3, getCallerShortcut("s4").getRank());
verify(mMockUsageStatsManagerInternal, times(1)).reportShortcutUsage(
- eq(CALLING_PACKAGE_1), eq("s4"), eq(USER_0));
+ eq(CALLING_PACKAGE_1), eq("s4"), eq(USER_10));
mInjectedCurrentTimeMillis += INTERVAL; // reset
@@ -476,7 +477,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertEquals(3, getCallerShortcut("s2").getRank());
assertEquals(4, getCallerShortcut("s4").getRank());
verify(mMockUsageStatsManagerInternal, times(1)).reportShortcutUsage(
- eq(CALLING_PACKAGE_1), eq("s5"), eq(USER_0));
+ eq(CALLING_PACKAGE_1), eq("s5"), eq(USER_10));
// Push when max has already reached
Mockito.reset(mMockUsageStatsManagerInternal);
@@ -487,7 +488,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertEquals(1, getCallerShortcut("s5").getRank());
assertEquals(4, getCallerShortcut("s2").getRank());
verify(mMockUsageStatsManagerInternal, times(1)).reportShortcutUsage(
- eq(CALLING_PACKAGE_1), eq("s6"), eq(USER_0));
+ eq(CALLING_PACKAGE_1), eq("s6"), eq(USER_10));
mInjectedCurrentTimeMillis += INTERVAL; // reset
@@ -499,7 +500,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
getCallerShortcut("s7").getActivity());
assertEquals(0, getCallerShortcut("s7").getRank());
verify(mMockUsageStatsManagerInternal, times(1)).reportShortcutUsage(
- eq(CALLING_PACKAGE_1), eq("s7"), eq(USER_0));
+ eq(CALLING_PACKAGE_1), eq("s7"), eq(USER_10));
// Push to update shortcut with different activity
Mockito.reset(mMockUsageStatsManagerInternal);
@@ -514,7 +515,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertEquals(2, getCallerShortcut("s3").getRank());
assertEquals(3, getCallerShortcut("s2").getRank());
verify(mMockUsageStatsManagerInternal, times(1)).reportShortcutUsage(
- eq(CALLING_PACKAGE_1), eq("s1"), eq(USER_0));
+ eq(CALLING_PACKAGE_1), eq("s1"), eq(USER_10));
mInjectedCurrentTimeMillis += INTERVAL; // reset
@@ -524,12 +525,12 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
s8.setRank(100);
mManager.pushDynamicShortcut(s8);
assertEquals(4, getCallerShortcut("s8").getRank());
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mInjectCheckAccessShortcutsPermission = true;
- mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s8"), HANDLE_USER_0,
+ mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s8"), HANDLE_USER_10,
CACHE_OWNER_0);
verify(mMockUsageStatsManagerInternal, times(1)).reportShortcutUsage(
- eq(CALLING_PACKAGE_1), eq("s8"), eq(USER_0));
+ eq(CALLING_PACKAGE_1), eq("s8"), eq(USER_10));
});
Mockito.reset(mMockUsageStatsManagerInternal);
@@ -540,7 +541,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertShortcutIds(mManager.getShortcuts(ShortcutManager.FLAG_MATCH_CACHED),
"s8");
verify(mMockUsageStatsManagerInternal, times(1)).reportShortcutUsage(
- eq(CALLING_PACKAGE_1), eq("s9"), eq(USER_0));
+ eq(CALLING_PACKAGE_1), eq("s9"), eq(USER_10));
}
public void PushDynamicShortcut_CallsToUsageStatsManagerAreThrottled()
@@ -549,13 +550,13 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
ShortcutService.ConfigConstants.KEY_SAVE_DELAY_MILLIS + "=500");
// Verify calls to UsageStatsManagerInternal#reportShortcutUsage are throttled.
- setCaller(CALLING_PACKAGE_1, USER_0);
+ setCaller(CALLING_PACKAGE_1, USER_10);
{
final ShortcutInfo si = makeShortcut("s0");
mManager.pushDynamicShortcut(si);
}
verify(mMockUsageStatsManagerInternal, times(1)).reportShortcutUsage(
- eq(CALLING_PACKAGE_1), eq("s0"), eq(USER_0));
+ eq(CALLING_PACKAGE_1), eq("s0"), eq(USER_10));
Mockito.reset(mMockUsageStatsManagerInternal);
for (int i = 2; i <= 10; i++) {
final ShortcutInfo si = makeShortcut("s" + i);
@@ -565,13 +566,13 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
any(), any(), anyInt());
// Verify pkg2 isn't blocked by pkg1, but consecutive calls from pkg2 are throttled as well.
- setCaller(CALLING_PACKAGE_2, USER_0);
+ setCaller(CALLING_PACKAGE_2, USER_10);
{
final ShortcutInfo si = makeShortcut("s1");
mManager.pushDynamicShortcut(si);
}
verify(mMockUsageStatsManagerInternal, times(1)).reportShortcutUsage(
- eq(CALLING_PACKAGE_2), eq("s1"), eq(USER_0));
+ eq(CALLING_PACKAGE_2), eq("s1"), eq(USER_10));
Mockito.reset(mMockUsageStatsManagerInternal);
for (int i = 2; i <= 10; i++) {
final ShortcutInfo si = makeShortcut("s" + i);
@@ -584,18 +585,18 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
// Let time passes which resets the throttle
Thread.sleep(505);
// Verify UsageStatsManagerInternal#reportShortcutUsed can be called again
- setCaller(CALLING_PACKAGE_1, USER_0);
+ setCaller(CALLING_PACKAGE_1, USER_10);
mManager.pushDynamicShortcut(makeShortcut("s10"));
- setCaller(CALLING_PACKAGE_2, USER_0);
+ setCaller(CALLING_PACKAGE_2, USER_10);
mManager.pushDynamicShortcut(makeShortcut("s10"));
verify(mMockUsageStatsManagerInternal, times(1)).reportShortcutUsage(
- eq(CALLING_PACKAGE_1), any(), eq(USER_0));
+ eq(CALLING_PACKAGE_1), any(), eq(USER_10));
verify(mMockUsageStatsManagerInternal, times(1)).reportShortcutUsage(
- eq(CALLING_PACKAGE_2), any(), eq(USER_0));
+ eq(CALLING_PACKAGE_2), any(), eq(USER_10));
}
public void UnlimitedCalls() {
- setCaller(CALLING_PACKAGE_1, USER_0);
+ setCaller(CALLING_PACKAGE_1, USER_10);
final ShortcutInfo si1 = makeShortcut("shortcut1");
@@ -628,9 +629,9 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
public void PublishWithNoActivity() {
// If activity is not explicitly set, use the default one.
- mRunningUsers.put(USER_10, true);
+ mRunningUsers.put(USER_11, true);
- runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_11, () -> {
// s1 and s3 has no activities.
final ShortcutInfo si1 = new ShortcutInfo.Builder(mClientContext, "si1")
.setShortLabel("label1")
@@ -732,9 +733,9 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
}
public void PublishWithNoActivity_noMainActivityInPackage() {
- mRunningUsers.put(USER_10, true);
+ mRunningUsers.put(USER_11, true);
- runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_11, () -> {
final ShortcutInfo si1 = new ShortcutInfo.Builder(mClientContext, "si1")
.setShortLabel("label1")
.setIntent(new Intent("action1"))
@@ -905,35 +906,35 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
setCaller(LAUNCHER_1);
// Check hasIconResource()/hasIconFile().
assertShortcutIds(assertAllHaveIconResId(
- list(getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "res32x32", USER_0))),
+ list(getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "res32x32", USER_10))),
"res32x32");
assertShortcutIds(assertAllHaveIconResId(
- list(getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "res64x64", USER_0))),
+ list(getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "res64x64", USER_10))),
"res64x64");
assertShortcutIds(assertAllHaveIconFile(
- list(getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "bmp32x32", USER_0))),
+ list(getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "bmp32x32", USER_10))),
"bmp32x32");
assertShortcutIds(assertAllHaveIconFile(
- list(getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "bmp64x64", USER_0))),
+ list(getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "bmp64x64", USER_10))),
"bmp64x64");
assertShortcutIds(assertAllHaveIconFile(
- list(getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "bmp512x512", USER_0))),
+ list(getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "bmp512x512", USER_10))),
"bmp512x512");
assertShortcutIds(assertAllHaveIconUri(
- list(getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "uri32x32", USER_0))),
+ list(getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "uri32x32", USER_10))),
"uri32x32");
assertShortcutIds(assertAllHaveIconUri(
- list(getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "uri64x64", USER_0))),
+ list(getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "uri64x64", USER_10))),
"uri64x64");
assertShortcutIds(assertAllHaveIconUri(
- list(getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "uri512x512", USER_0))),
+ list(getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "uri512x512", USER_10))),
"uri512x512");
assertShortcutIds(assertAllHaveIconResId(
@@ -947,36 +948,36 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertEquals(
R.drawable.black_32x32,
mLauncherApps.getShortcutIconResId(
- getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "res32x32", USER_0)));
+ getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "res32x32", USER_10)));
assertEquals(
R.drawable.black_64x64,
mLauncherApps.getShortcutIconResId(
- getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "res64x64", USER_0)));
+ getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "res64x64", USER_10)));
assertEquals(
0, // because it's not a resource
mLauncherApps.getShortcutIconResId(
- getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "bmp32x32", USER_0)));
+ getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "bmp32x32", USER_10)));
assertEquals(
0, // because it's not a resource
mLauncherApps.getShortcutIconResId(
- getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "bmp64x64", USER_0)));
+ getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "bmp64x64", USER_10)));
assertEquals(
0, // because it's not a resource
mLauncherApps.getShortcutIconResId(
- getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "bmp512x512", USER_0)));
+ getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "bmp512x512", USER_10)));
bmp = pfdToBitmap(mLauncherApps.getShortcutIconFd(
- getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "bmp32x32", USER_0)));
+ getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "bmp32x32", USER_10)));
assertBitmapSize(32, 32, bmp);
bmp = pfdToBitmap(mLauncherApps.getShortcutIconFd(
- getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "bmp64x64", USER_0)));
+ getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "bmp64x64", USER_10)));
assertBitmapSize(64, 64, bmp);
bmp = pfdToBitmap(mLauncherApps.getShortcutIconFd(
- getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "bmp512x512", USER_0)));
+ getShortcutInfoAsLauncher(CALLING_PACKAGE_1, "bmp512x512", USER_10)));
assertBitmapSize(128, 128, bmp);
assertEquals(
@@ -991,10 +992,10 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
// Also check the overload APIs too.
assertEquals(
R.drawable.black_32x32,
- mLauncherApps.getShortcutIconResId(CALLING_PACKAGE_1, "res32x32", HANDLE_USER_0));
+ mLauncherApps.getShortcutIconResId(CALLING_PACKAGE_1, "res32x32", HANDLE_USER_10));
assertEquals(
R.drawable.black_64x64,
- mLauncherApps.getShortcutIconResId(CALLING_PACKAGE_1, "res64x64", HANDLE_USER_0));
+ mLauncherApps.getShortcutIconResId(CALLING_PACKAGE_1, "res64x64", HANDLE_USER_10));
assertEquals(
R.drawable.black_512x512,
mLauncherApps.getShortcutIconResId(CALLING_PACKAGE_1, "res32x32", HANDLE_USER_P0));
@@ -1035,14 +1036,14 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
}
public void CleanupDanglingBitmaps() throws Exception {
- assertBitmapDirectories(USER_0, EMPTY_STRINGS);
assertBitmapDirectories(USER_10, EMPTY_STRINGS);
+ assertBitmapDirectories(USER_11, EMPTY_STRINGS);
// Make some shortcuts with bitmap icons.
final Icon bmp32x32 = Icon.createWithBitmap(BitmapFactory.decodeResource(
getTestContext().getResources(), R.drawable.black_32x32));
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
mManager.setDynamicShortcuts(list(
makeShortcutWithIcon("s1", bmp32x32),
makeShortcutWithIcon("s2", bmp32x32),
@@ -1053,7 +1054,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
// Increment the time (which actually we don't have to), which is used for filenames.
mInjectedCurrentTimeMillis++;
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
mManager.setDynamicShortcuts(list(
makeShortcutWithIcon("s4", bmp32x32),
makeShortcutWithIcon("s5", bmp32x32),
@@ -1064,29 +1065,29 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
// Increment the time, which is used for filenames.
mInjectedCurrentTimeMillis++;
- runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_3, USER_10, () -> {
mManager.setDynamicShortcuts(list(
));
});
// For USER-10, let's try without updating the times.
- mRunningUsers.put(USER_10, true);
+ mRunningUsers.put(USER_11, true);
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
mManager.setDynamicShortcuts(list(
makeShortcutWithIcon("10s1", bmp32x32),
makeShortcutWithIcon("10s2", bmp32x32),
makeShortcutWithIcon("10s3", bmp32x32)
));
});
- runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_11, () -> {
mManager.setDynamicShortcuts(list(
makeShortcutWithIcon("10s4", bmp32x32),
makeShortcutWithIcon("10s5", bmp32x32),
makeShortcutWithIcon("10s6", bmp32x32)
));
});
- runWithCaller(CALLING_PACKAGE_3, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_3, USER_11, () -> {
mManager.setDynamicShortcuts(list(
));
});
@@ -1096,102 +1097,102 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
mService.waitForBitmapSavesForTest();
// Check files and directories.
// Package 3 has no bitmaps, so we don't create a directory.
- assertBitmapDirectories(USER_0, CALLING_PACKAGE_1, CALLING_PACKAGE_2);
assertBitmapDirectories(USER_10, CALLING_PACKAGE_1, CALLING_PACKAGE_2);
+ assertBitmapDirectories(USER_11, CALLING_PACKAGE_1, CALLING_PACKAGE_2);
- assertBitmapFiles(USER_0, CALLING_PACKAGE_1,
- getBitmapFilename(USER_0, CALLING_PACKAGE_1, "s1"),
- getBitmapFilename(USER_0, CALLING_PACKAGE_1, "s2"),
- getBitmapFilename(USER_0, CALLING_PACKAGE_1, "s3")
+ assertBitmapFiles(USER_10, CALLING_PACKAGE_1,
+ getBitmapFilename(USER_10, CALLING_PACKAGE_1, "s1"),
+ getBitmapFilename(USER_10, CALLING_PACKAGE_1, "s2"),
+ getBitmapFilename(USER_10, CALLING_PACKAGE_1, "s3")
);
- assertBitmapFiles(USER_0, CALLING_PACKAGE_2,
- getBitmapFilename(USER_0, CALLING_PACKAGE_2, "s4"),
- getBitmapFilename(USER_0, CALLING_PACKAGE_2, "s5"),
- getBitmapFilename(USER_0, CALLING_PACKAGE_2, "s6")
+ assertBitmapFiles(USER_10, CALLING_PACKAGE_2,
+ getBitmapFilename(USER_10, CALLING_PACKAGE_2, "s4"),
+ getBitmapFilename(USER_10, CALLING_PACKAGE_2, "s5"),
+ getBitmapFilename(USER_10, CALLING_PACKAGE_2, "s6")
);
- assertBitmapFiles(USER_0, CALLING_PACKAGE_3,
+ assertBitmapFiles(USER_10, CALLING_PACKAGE_3,
EMPTY_STRINGS
);
- assertBitmapFiles(USER_10, CALLING_PACKAGE_1,
- getBitmapFilename(USER_10, CALLING_PACKAGE_1, "10s1"),
- getBitmapFilename(USER_10, CALLING_PACKAGE_1, "10s2"),
- getBitmapFilename(USER_10, CALLING_PACKAGE_1, "10s3")
+ assertBitmapFiles(USER_11, CALLING_PACKAGE_1,
+ getBitmapFilename(USER_11, CALLING_PACKAGE_1, "10s1"),
+ getBitmapFilename(USER_11, CALLING_PACKAGE_1, "10s2"),
+ getBitmapFilename(USER_11, CALLING_PACKAGE_1, "10s3")
);
- assertBitmapFiles(USER_10, CALLING_PACKAGE_2,
- getBitmapFilename(USER_10, CALLING_PACKAGE_2, "10s4"),
- getBitmapFilename(USER_10, CALLING_PACKAGE_2, "10s5"),
- getBitmapFilename(USER_10, CALLING_PACKAGE_2, "10s6")
+ assertBitmapFiles(USER_11, CALLING_PACKAGE_2,
+ getBitmapFilename(USER_11, CALLING_PACKAGE_2, "10s4"),
+ getBitmapFilename(USER_11, CALLING_PACKAGE_2, "10s5"),
+ getBitmapFilename(USER_11, CALLING_PACKAGE_2, "10s6")
);
- assertBitmapFiles(USER_10, CALLING_PACKAGE_3,
+ assertBitmapFiles(USER_11, CALLING_PACKAGE_3,
EMPTY_STRINGS
);
// Then create random directories and files.
- makeFile(mService.getUserBitmapFilePath(USER_0), "a.b.c").mkdir();
- makeFile(mService.getUserBitmapFilePath(USER_0), "d.e.f").mkdir();
- makeFile(mService.getUserBitmapFilePath(USER_0), "d.e.f", "123").createNewFile();
- makeFile(mService.getUserBitmapFilePath(USER_0), "d.e.f", "456").createNewFile();
+ makeFile(mService.getUserBitmapFilePath(USER_10), "a.b.c").mkdir();
+ makeFile(mService.getUserBitmapFilePath(USER_10), "d.e.f").mkdir();
+ makeFile(mService.getUserBitmapFilePath(USER_10), "d.e.f", "123").createNewFile();
+ makeFile(mService.getUserBitmapFilePath(USER_10), "d.e.f", "456").createNewFile();
- makeFile(mService.getUserBitmapFilePath(USER_0), CALLING_PACKAGE_3).mkdir();
+ makeFile(mService.getUserBitmapFilePath(USER_10), CALLING_PACKAGE_3).mkdir();
- makeFile(mService.getUserBitmapFilePath(USER_0), CALLING_PACKAGE_1, "1").createNewFile();
- makeFile(mService.getUserBitmapFilePath(USER_0), CALLING_PACKAGE_1, "2").createNewFile();
- makeFile(mService.getUserBitmapFilePath(USER_0), CALLING_PACKAGE_1, "3").createNewFile();
- makeFile(mService.getUserBitmapFilePath(USER_0), CALLING_PACKAGE_1, "4").createNewFile();
+ makeFile(mService.getUserBitmapFilePath(USER_10), CALLING_PACKAGE_1, "1").createNewFile();
+ makeFile(mService.getUserBitmapFilePath(USER_10), CALLING_PACKAGE_1, "2").createNewFile();
+ makeFile(mService.getUserBitmapFilePath(USER_10), CALLING_PACKAGE_1, "3").createNewFile();
+ makeFile(mService.getUserBitmapFilePath(USER_10), CALLING_PACKAGE_1, "4").createNewFile();
- makeFile(mService.getUserBitmapFilePath(USER_10), "10a.b.c").mkdir();
- makeFile(mService.getUserBitmapFilePath(USER_10), "10d.e.f").mkdir();
- makeFile(mService.getUserBitmapFilePath(USER_10), "10d.e.f", "123").createNewFile();
- makeFile(mService.getUserBitmapFilePath(USER_10), "10d.e.f", "456").createNewFile();
+ makeFile(mService.getUserBitmapFilePath(USER_11), "10a.b.c").mkdir();
+ makeFile(mService.getUserBitmapFilePath(USER_11), "10d.e.f").mkdir();
+ makeFile(mService.getUserBitmapFilePath(USER_11), "10d.e.f", "123").createNewFile();
+ makeFile(mService.getUserBitmapFilePath(USER_11), "10d.e.f", "456").createNewFile();
- makeFile(mService.getUserBitmapFilePath(USER_10), CALLING_PACKAGE_2, "1").createNewFile();
- makeFile(mService.getUserBitmapFilePath(USER_10), CALLING_PACKAGE_2, "2").createNewFile();
- makeFile(mService.getUserBitmapFilePath(USER_10), CALLING_PACKAGE_2, "3").createNewFile();
- makeFile(mService.getUserBitmapFilePath(USER_10), CALLING_PACKAGE_2, "4").createNewFile();
+ makeFile(mService.getUserBitmapFilePath(USER_11), CALLING_PACKAGE_2, "1").createNewFile();
+ makeFile(mService.getUserBitmapFilePath(USER_11), CALLING_PACKAGE_2, "2").createNewFile();
+ makeFile(mService.getUserBitmapFilePath(USER_11), CALLING_PACKAGE_2, "3").createNewFile();
+ makeFile(mService.getUserBitmapFilePath(USER_11), CALLING_PACKAGE_2, "4").createNewFile();
mService.waitForBitmapSavesForTest();
- assertBitmapDirectories(USER_0, CALLING_PACKAGE_1, CALLING_PACKAGE_2, CALLING_PACKAGE_3,
+ assertBitmapDirectories(USER_10, CALLING_PACKAGE_1, CALLING_PACKAGE_2, CALLING_PACKAGE_3,
"a.b.c", "d.e.f");
// Save and load. When a user is loaded, we do the cleanup.
mService.saveDirtyInfo();
initService();
- mService.handleUnlockUser(USER_0);
mService.handleUnlockUser(USER_10);
+ mService.handleUnlockUser(USER_11);
mService.handleUnlockUser(20); // Make sure the logic will still work for nonexistent user.
// The below check is the same as above, except this time USER_0 use the CALLING_PACKAGE_3
// directory.
mService.waitForBitmapSavesForTest();
- assertBitmapDirectories(USER_0, CALLING_PACKAGE_1, CALLING_PACKAGE_2, CALLING_PACKAGE_3);
- assertBitmapDirectories(USER_10, CALLING_PACKAGE_1, CALLING_PACKAGE_2);
+ assertBitmapDirectories(USER_10, CALLING_PACKAGE_1, CALLING_PACKAGE_2, CALLING_PACKAGE_3);
+ assertBitmapDirectories(USER_11, CALLING_PACKAGE_1, CALLING_PACKAGE_2);
- assertBitmapFiles(USER_0, CALLING_PACKAGE_1,
- getBitmapFilename(USER_0, CALLING_PACKAGE_1, "s1"),
- getBitmapFilename(USER_0, CALLING_PACKAGE_1, "s2"),
- getBitmapFilename(USER_0, CALLING_PACKAGE_1, "s3")
+ assertBitmapFiles(USER_10, CALLING_PACKAGE_1,
+ getBitmapFilename(USER_10, CALLING_PACKAGE_1, "s1"),
+ getBitmapFilename(USER_10, CALLING_PACKAGE_1, "s2"),
+ getBitmapFilename(USER_10, CALLING_PACKAGE_1, "s3")
);
- assertBitmapFiles(USER_0, CALLING_PACKAGE_2,
- getBitmapFilename(USER_0, CALLING_PACKAGE_2, "s4"),
- getBitmapFilename(USER_0, CALLING_PACKAGE_2, "s5"),
- getBitmapFilename(USER_0, CALLING_PACKAGE_2, "s6")
+ assertBitmapFiles(USER_10, CALLING_PACKAGE_2,
+ getBitmapFilename(USER_10, CALLING_PACKAGE_2, "s4"),
+ getBitmapFilename(USER_10, CALLING_PACKAGE_2, "s5"),
+ getBitmapFilename(USER_10, CALLING_PACKAGE_2, "s6")
);
- assertBitmapFiles(USER_0, CALLING_PACKAGE_3,
+ assertBitmapFiles(USER_10, CALLING_PACKAGE_3,
EMPTY_STRINGS
);
- assertBitmapFiles(USER_10, CALLING_PACKAGE_1,
- getBitmapFilename(USER_10, CALLING_PACKAGE_1, "10s1"),
- getBitmapFilename(USER_10, CALLING_PACKAGE_1, "10s2"),
- getBitmapFilename(USER_10, CALLING_PACKAGE_1, "10s3")
+ assertBitmapFiles(USER_11, CALLING_PACKAGE_1,
+ getBitmapFilename(USER_11, CALLING_PACKAGE_1, "10s1"),
+ getBitmapFilename(USER_11, CALLING_PACKAGE_1, "10s2"),
+ getBitmapFilename(USER_11, CALLING_PACKAGE_1, "10s3")
);
- assertBitmapFiles(USER_10, CALLING_PACKAGE_2,
- getBitmapFilename(USER_10, CALLING_PACKAGE_2, "10s4"),
- getBitmapFilename(USER_10, CALLING_PACKAGE_2, "10s5"),
- getBitmapFilename(USER_10, CALLING_PACKAGE_2, "10s6")
+ assertBitmapFiles(USER_11, CALLING_PACKAGE_2,
+ getBitmapFilename(USER_11, CALLING_PACKAGE_2, "10s4"),
+ getBitmapFilename(USER_11, CALLING_PACKAGE_2, "10s5"),
+ getBitmapFilename(USER_11, CALLING_PACKAGE_2, "10s6")
);
- assertBitmapFiles(USER_10, CALLING_PACKAGE_3,
+ assertBitmapFiles(USER_11, CALLING_PACKAGE_3,
EMPTY_STRINGS
);
}
@@ -1301,7 +1302,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
}
public void UpdateShortcuts() {
- runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s1"),
makeShortcut("s2"),
@@ -1310,7 +1311,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
makeShortcut("s5")
)));
});
- runWithCaller(CALLING_PACKAGE_2, UserHandle.USER_SYSTEM, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s1"),
makeShortcut("s2"),
@@ -1319,22 +1320,22 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
makeShortcut("s5")
)));
});
- runWithCaller(LAUNCHER_1, UserHandle.USER_SYSTEM, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s2", "s3"),
getCallingUser());
mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list("s4", "s5"),
getCallingUser());
});
- runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
mManager.removeDynamicShortcuts(list("s1"));
mManager.removeDynamicShortcuts(list("s2"));
});
- runWithCaller(CALLING_PACKAGE_2, UserHandle.USER_SYSTEM, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
mManager.removeDynamicShortcuts(list("s1"));
mManager.removeDynamicShortcuts(list("s3"));
mManager.removeDynamicShortcuts(list("s5"));
});
- runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertShortcutIds(assertAllDynamic(
mManager.getDynamicShortcuts()),
"s3", "s4", "s5");
@@ -1342,7 +1343,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
mManager.getPinnedShortcuts()),
"s2", "s3");
});
- runWithCaller(CALLING_PACKAGE_2, UserHandle.USER_SYSTEM, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
assertShortcutIds(assertAllDynamic(
mManager.getDynamicShortcuts()),
"s2", "s4");
@@ -1351,7 +1352,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
"s4", "s5");
});
- runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
ShortcutInfo s2 = makeShortcutBuilder()
.setId("s2")
.setIcon(Icon.createWithResource(getTestContext(), R.drawable.black_32x32))
@@ -1364,7 +1365,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
mManager.updateShortcuts(list(s2, s4));
});
- runWithCaller(CALLING_PACKAGE_2, UserHandle.USER_SYSTEM, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
ShortcutInfo s2 = makeShortcutBuilder()
.setId("s2")
.setIntent(makeIntent(Intent.ACTION_ANSWER, ShortcutActivity.class,
@@ -1379,7 +1380,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
mManager.updateShortcuts(list(s2, s4));
});
- runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertShortcutIds(assertAllDynamic(
mManager.getDynamicShortcuts()),
"s3", "s4", "s5");
@@ -1398,7 +1399,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertEquals(0, s.getIconResourceId());
assertEquals("new title", s.getTitle());
});
- runWithCaller(CALLING_PACKAGE_2, UserHandle.USER_SYSTEM, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
assertShortcutIds(assertAllDynamic(
mManager.getDynamicShortcuts()),
"s2", "s4");
@@ -1424,15 +1425,15 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
// TODO Check bitmap removal too.
- mRunningUsers.put(USER_11, true);
+ mRunningUsers.put(USER_12, true);
- runWithCaller(CALLING_PACKAGE_2, USER_11, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_12, () -> {
mManager.updateShortcuts(list());
});
}
public void UpdateShortcuts_icons() {
- runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s1")
)));
@@ -1533,26 +1534,26 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
R.xml.shortcut_3);
updatePackageVersion(CALLING_PACKAGE_1, 1);
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
makeLongLivedShortcut("s1"), makeLongLivedShortcut("s2"), makeShortcut("s3"))));
});
// Pin 2 and 3
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("ms2", "ms3", "s2", "s3"),
- HANDLE_USER_0);
+ HANDLE_USER_10);
});
// Cache 1 and 2
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mInjectCheckAccessShortcutsPermission = true;
mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s1"),
- HANDLE_USER_0, CACHE_OWNER_0);
+ HANDLE_USER_10, CACHE_OWNER_0);
mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s2"),
- HANDLE_USER_0, CACHE_OWNER_1);
+ HANDLE_USER_10, CACHE_OWNER_1);
});
setCaller(CALLING_PACKAGE_1);
@@ -1617,7 +1618,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
}
public void CachedShortcuts() {
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(list(makeShortcut("s1"),
makeLongLivedShortcut("s2"), makeLongLivedShortcut("s3"),
makeLongLivedShortcut("s4"), makeLongLivedShortcut("s5"),
@@ -1625,20 +1626,20 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
// Pin s2
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s2"),
- HANDLE_USER_0);
+ HANDLE_USER_10);
});
// Cache some, but non long lived shortcuts will be ignored.
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mInjectCheckAccessShortcutsPermission = true;
mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s1", "s2"),
- HANDLE_USER_0, CACHE_OWNER_0);
+ HANDLE_USER_10, CACHE_OWNER_0);
mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s2", "s4", "s5"),
- HANDLE_USER_0, CACHE_OWNER_1);
+ HANDLE_USER_10, CACHE_OWNER_1);
mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s5", "s6"),
- HANDLE_USER_0, CACHE_OWNER_2);
+ HANDLE_USER_10, CACHE_OWNER_2);
});
setCaller(CALLING_PACKAGE_1);
@@ -1660,32 +1661,32 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertShortcutIds(mManager.getShortcuts(ShortcutManager.FLAG_MATCH_CACHED),
"s2", "s4", "s5", "s6");
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mLauncherApps.uncacheShortcuts(CALLING_PACKAGE_1, list("s2", "s4"),
- HANDLE_USER_0, CACHE_OWNER_0);
+ HANDLE_USER_10, CACHE_OWNER_0);
});
// s2 still cached by owner1. s4 wasn't cached by owner0 so didn't get removed.
assertShortcutIds(mManager.getShortcuts(ShortcutManager.FLAG_MATCH_CACHED),
"s2", "s4", "s5", "s6");
// uncache a non-dynamic shortcut. Should be removed.
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mLauncherApps.uncacheShortcuts(CALLING_PACKAGE_1, list("s4"),
- HANDLE_USER_0, CACHE_OWNER_1);
+ HANDLE_USER_10, CACHE_OWNER_1);
});
// uncache s6 by its only owner. s5 still cached by owner1
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mLauncherApps.uncacheShortcuts(CALLING_PACKAGE_1, list("s5", "s6"),
- HANDLE_USER_0, CACHE_OWNER_2);
+ HANDLE_USER_10, CACHE_OWNER_2);
});
assertShortcutIds(mManager.getShortcuts(ShortcutManager.FLAG_MATCH_CACHED),
"s2", "s5");
// Cache another shortcut
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s3"),
- HANDLE_USER_0, CACHE_OWNER_0);
+ HANDLE_USER_10, CACHE_OWNER_0);
});
assertShortcutIds(mManager.getShortcuts(ShortcutManager.FLAG_MATCH_CACHED),
"s2", "s3", "s5");
@@ -1701,24 +1702,24 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
}
public void CachedShortcuts_accessShortcutsPermission() {
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(list(makeShortcut("s1"),
makeLongLivedShortcut("s2"), makeLongLivedShortcut("s3"),
makeLongLivedShortcut("s4"))));
});
// s1 is not long lived and will be ignored.
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mInjectCheckAccessShortcutsPermission = false;
assertExpectException(
SecurityException.class, "Caller can't access shortcut information", () -> {
mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s1", "s2", "s3"),
- HANDLE_USER_0, CACHE_OWNER_0);
+ HANDLE_USER_10, CACHE_OWNER_0);
});
// Give ACCESS_SHORTCUTS permission to LAUNCHER_1
mInjectCheckAccessShortcutsPermission = true;
mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s1", "s2", "s3"),
- HANDLE_USER_0, CACHE_OWNER_0);
+ HANDLE_USER_10, CACHE_OWNER_0);
});
setCaller(CALLING_PACKAGE_1);
@@ -1726,17 +1727,17 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
// Get cached shortcuts
assertShortcutIds(mManager.getShortcuts(ShortcutManager.FLAG_MATCH_CACHED), "s2", "s3");
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mInjectCheckAccessShortcutsPermission = false;
assertExpectException(
SecurityException.class, "Caller can't access shortcut information", () -> {
mLauncherApps.uncacheShortcuts(CALLING_PACKAGE_1, list("s2", "s4"),
- HANDLE_USER_0, CACHE_OWNER_0);
+ HANDLE_USER_10, CACHE_OWNER_0);
});
// Give ACCESS_SHORTCUTS permission to LAUNCHER_1
mInjectCheckAccessShortcutsPermission = true;
mLauncherApps.uncacheShortcuts(CALLING_PACKAGE_1, list("s2", "s4"),
- HANDLE_USER_0, CACHE_OWNER_0);
+ HANDLE_USER_10, CACHE_OWNER_0);
});
assertShortcutIds(mManager.getShortcuts(ShortcutManager.FLAG_MATCH_CACHED), "s3");
@@ -1746,17 +1747,17 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
// Change the max number of shortcuts.
mService.updateConfigurationLocked(ConfigConstants.KEY_MAX_SHORTCUTS + "=4");
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(list(makeLongLivedShortcut("s1"),
makeLongLivedShortcut("s2"), makeLongLivedShortcut("s3"),
makeLongLivedShortcut("s4"))));
});
// Cache All
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mInjectCheckAccessShortcutsPermission = true;
mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s1", "s2", "s3", "s4"),
- HANDLE_USER_0, CACHE_OWNER_0);
+ HANDLE_USER_10, CACHE_OWNER_0);
});
setCaller(CALLING_PACKAGE_1);
@@ -2004,17 +2005,17 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
R.xml.shortcut_3);
updatePackageVersion(CALLING_PACKAGE_1, 1);
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
});
// Pin 2 and 3
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("ms2", "ms3", "s2", "s3"),
- HANDLE_USER_0);
+ HANDLE_USER_10);
});
// Remove ms3 and s3
@@ -2023,15 +2024,15 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
R.xml.shortcut_2);
updatePackageVersion(CALLING_PACKAGE_1, 1);
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s1"), makeShortcut("s2"))));
});
// Check their status.
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertWith(getCallerShortcuts())
.haveIds("ms1", "ms2", "ms3", "s1", "s2", "s3")
@@ -2071,45 +2072,45 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
// Finally, actual tests.
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
assertWith(mLauncherApps.getShortcuts(
- buildQueryWithFlags(ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0))
+ buildQueryWithFlags(ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_10))
.haveIds("s1", "s2");
assertWith(mLauncherApps.getShortcuts(
- buildQueryWithFlags(ShortcutQuery.FLAG_GET_MANIFEST), HANDLE_USER_0))
+ buildQueryWithFlags(ShortcutQuery.FLAG_GET_MANIFEST), HANDLE_USER_10))
.haveIds("ms1", "ms2");
assertWith(mLauncherApps.getShortcuts(
- buildQueryWithFlags(ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0))
+ buildQueryWithFlags(ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_10))
.haveIds("s2", "s3", "ms2", "ms3");
assertWith(mLauncherApps.getShortcuts(
buildQueryWithFlags(
ShortcutQuery.FLAG_GET_DYNAMIC | ShortcutQuery.FLAG_GET_PINNED
- ), HANDLE_USER_0))
+ ), HANDLE_USER_10))
.haveIds("s1", "s2", "s3", "ms2", "ms3");
assertWith(mLauncherApps.getShortcuts(
buildQueryWithFlags(
ShortcutQuery.FLAG_GET_MANIFEST | ShortcutQuery.FLAG_GET_PINNED
- ), HANDLE_USER_0))
+ ), HANDLE_USER_10))
.haveIds("ms1", "s2", "s3", "ms2", "ms3");
assertWith(mLauncherApps.getShortcuts(
buildQueryWithFlags(
ShortcutQuery.FLAG_GET_DYNAMIC | ShortcutQuery.FLAG_GET_MANIFEST
- ), HANDLE_USER_0))
+ ), HANDLE_USER_10))
.haveIds("ms1", "ms2", "s1", "s2");
assertWith(mLauncherApps.getShortcuts(
buildQueryWithFlags(
ShortcutQuery.FLAG_GET_ALL_KINDS
- ), HANDLE_USER_0))
+ ), HANDLE_USER_10))
.haveIds("ms1", "ms2", "ms3", "s1", "s2", "s3");
});
}
public void GetShortcuts_resolveStrings() throws Exception {
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
ShortcutInfo si = new ShortcutInfo.Builder(mClientContext)
.setId("id")
.setActivity(new ComponentName(mClientContext, "dummy"))
@@ -2132,17 +2133,17 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
mManager.setDynamicShortcuts(list(si));
});
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
final ShortcutQuery q = new ShortcutQuery();
q.setQueryFlags(ShortcutQuery.FLAG_GET_DYNAMIC);
// USER 0
List<ShortcutInfo> ret = assertShortcutIds(
- assertAllStringsResolved(mLauncherApps.getShortcuts(q, HANDLE_USER_0)),
+ assertAllStringsResolved(mLauncherApps.getShortcuts(q, HANDLE_USER_10)),
"id");
- assertEquals("string-com.android.test.1-user:0-res:10/en", ret.get(0).getTitle());
- assertEquals("string-com.android.test.1-user:0-res:11/en", ret.get(0).getText());
- assertEquals("string-com.android.test.1-user:0-res:12/en",
+ assertEquals("string-com.android.test.1-user:10-res:10/en", ret.get(0).getTitle());
+ assertEquals("string-com.android.test.1-user:10-res:11/en", ret.get(0).getText());
+ assertEquals("string-com.android.test.1-user:10-res:12/en",
ret.get(0).getDisabledMessage());
// USER P0
@@ -2280,27 +2281,27 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
}
public void PinShortcutAndGetPinnedShortcuts() {
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
final ShortcutInfo s1_1 = makeShortcutWithTimestamp("s1", 1000);
final ShortcutInfo s1_2 = makeShortcutWithTimestamp("s2", 2000);
assertTrue(mManager.setDynamicShortcuts(list(s1_1, s1_2)));
});
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
final ShortcutInfo s2_2 = makeShortcutWithTimestamp("s2", 1500);
final ShortcutInfo s2_3 = makeShortcutWithTimestamp("s3", 3000);
final ShortcutInfo s2_4 = makeShortcutWithTimestamp("s4", 500);
assertTrue(mManager.setDynamicShortcuts(list(s2_2, s2_3, s2_4)));
});
- runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_3, USER_10, () -> {
final ShortcutInfo s3_2 = makeShortcutWithTimestamp("s2", 1000);
assertTrue(mManager.setDynamicShortcuts(list(s3_2)));
});
// Pin some.
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
list("s2", "s3"), getCallingUser());
@@ -2312,7 +2313,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
// Delete some.
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertShortcutIds(mManager.getPinnedShortcuts(), "s2");
mManager.removeDynamicShortcuts(list("s2"));
assertShortcutIds(mManager.getPinnedShortcuts(), "s2");
@@ -2320,7 +2321,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertShortcutIds(mManager.getDynamicShortcuts(), "s1");
});
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
assertShortcutIds(mManager.getPinnedShortcuts(), "s3", "s4");
mManager.removeDynamicShortcuts(list("s3"));
assertShortcutIds(mManager.getPinnedShortcuts(), "s3", "s4");
@@ -2328,7 +2329,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertShortcutIds(mManager.getDynamicShortcuts(), "s2", "s4");
});
- runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_3, USER_10, () -> {
assertShortcutIds(mManager.getPinnedShortcuts() /* none */);
mManager.removeDynamicShortcuts(list("s2"));
assertShortcutIds(mManager.getPinnedShortcuts() /* none */);
@@ -2337,7 +2338,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
// Get pinned shortcuts from launcher
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
// CALLING_PACKAGE_1 deleted s2, but it's pinned, so it still exists.
assertShortcutIds(assertAllPinned(assertAllNotKeyFieldsOnly(assertAllEnabled(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
@@ -2361,27 +2362,27 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
* does "enable".
*/
public void DisableAndEnableShortcuts() {
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
final ShortcutInfo s1_1 = makeShortcutWithTimestamp("s1", 1000);
final ShortcutInfo s1_2 = makeShortcutWithTimestamp("s2", 2000);
assertTrue(mManager.setDynamicShortcuts(list(s1_1, s1_2)));
});
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
final ShortcutInfo s2_2 = makeShortcutWithTimestamp("s2", 1500);
final ShortcutInfo s2_3 = makeShortcutWithTimestamp("s3", 3000);
final ShortcutInfo s2_4 = makeShortcutWithTimestamp("s4", 500);
assertTrue(mManager.setDynamicShortcuts(list(s2_2, s2_3, s2_4)));
});
- runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_3, USER_10, () -> {
final ShortcutInfo s3_2 = makeShortcutWithTimestamp("s2", 1000);
assertTrue(mManager.setDynamicShortcuts(list(s3_2)));
});
// Pin some.
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
list("s2", "s3"), getCallingUser());
@@ -2393,7 +2394,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
// Disable some.
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertShortcutIds(mManager.getPinnedShortcuts(), "s2");
mManager.updateShortcuts(list(
@@ -2406,7 +2407,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertShortcutIds(mManager.getDynamicShortcuts(), "s1");
});
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
assertShortcutIds(mManager.getPinnedShortcuts(), "s3", "s4");
// disable should work even if a shortcut is not dynamic, so try calling "remove" first
@@ -2418,7 +2419,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertShortcutIds(mManager.getDynamicShortcuts(), "s2", "s4");
});
- runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_3, USER_10, () -> {
assertShortcutIds(mManager.getPinnedShortcuts() /* none */);
mManager.disableShortcuts(list("s2"));
@@ -2430,7 +2431,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
// Get pinned shortcuts from launcher
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
// CALLING_PACKAGE_1 deleted s2, but it's pinned, so it still exists, and disabled.
assertWith(mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
/* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), getCallingUser()))
@@ -2442,7 +2443,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
.areAllPinned()
.areAllNotWithKeyFieldsOnly()
.areAllDisabled();
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_0,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_10,
ActivityNotFoundException.class);
// Here, s4 is still enabled and launchable, but s3 is disabled.
@@ -2459,9 +2460,9 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
.selectByIds("s4")
.areAllEnabled();
- assertStartShortcutThrowsException(CALLING_PACKAGE_2, "s3", USER_0,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_2, "s3", USER_10,
ActivityNotFoundException.class);
- assertShortcutLaunchable(CALLING_PACKAGE_2, "s4", USER_0);
+ assertShortcutLaunchable(CALLING_PACKAGE_2, "s4", USER_10);
assertShortcutIds(assertAllPinned(assertAllNotKeyFieldsOnly(assertAllEnabled(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_3,
@@ -2469,30 +2470,30 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
/* none */);
});
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
mManager.enableShortcuts(list("s2"));
assertShortcutIds(mManager.getPinnedShortcuts(), "s2");
assertShortcutIds(mManager.getDynamicShortcuts(), "s1");
});
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
// CALLING_PACKAGE_1 deleted s2, but it's pinned, so it still exists.
assertShortcutIds(assertAllPinned(assertAllNotKeyFieldsOnly(assertAllEnabled(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
/* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), getCallingUser())))),
"s2");
- assertShortcutLaunchable(CALLING_PACKAGE_1, "s2", USER_0);
+ assertShortcutLaunchable(CALLING_PACKAGE_1, "s2", USER_10);
});
}
public void DisableShortcuts_thenRepublish() {
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mLauncherApps.pinShortcuts(
- CALLING_PACKAGE_1, list("s1", "s2", "s3"), HANDLE_USER_0);
+ CALLING_PACKAGE_1, list("s1", "s2", "s3"), HANDLE_USER_10);
});
mManager.disableShortcuts(list("s1", "s2", "s3"));
@@ -2557,12 +2558,12 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
public void PinShortcutAndGetPinnedShortcuts_multi() {
// Create some shortcuts.
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
});
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
});
@@ -2570,7 +2571,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
dumpsysOnLogcat();
// Pin some.
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
list("s3", "s4"), getCallingUser());
@@ -2581,7 +2582,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
dumpsysOnLogcat();
// Delete some.
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertShortcutIds(mManager.getPinnedShortcuts(), "s3");
mManager.removeDynamicShortcuts(list("s3"));
assertShortcutIds(mManager.getPinnedShortcuts(), "s3");
@@ -2589,7 +2590,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
dumpsysOnLogcat();
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
assertShortcutIds(mManager.getPinnedShortcuts(), "s1", "s2");
mManager.removeDynamicShortcuts(list("s1"));
mManager.removeDynamicShortcuts(list("s3"));
@@ -2599,7 +2600,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
dumpsysOnLogcat();
// Get pinned shortcuts from launcher
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
assertShortcutIds(assertAllPinned(assertAllNotKeyFieldsOnly(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
/* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), getCallingUser()))),
@@ -2625,7 +2626,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
dumpsysOnLogcat("Before launcher 2");
- runWithCaller(LAUNCHER_2, USER_0, () -> {
+ runWithCaller(LAUNCHER_2, USER_10, () -> {
// Launcher2 still has no pinned ones.
assertShortcutIds(assertAllPinned(assertAllNotKeyFieldsOnly(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
@@ -2698,10 +2699,10 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
initService();
// Load from file.
- mService.handleUnlockUser(USER_0);
+ mService.handleUnlockUser(USER_10);
// Make sure package info is restored too.
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
assertShortcutIds(assertAllPinned(assertAllNotKeyFieldsOnly(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
/* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), getCallingUser()))),
@@ -2711,7 +2712,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
/* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), getCallingUser()))),
"s1", "s2");
});
- runWithCaller(LAUNCHER_2, USER_0, () -> {
+ runWithCaller(LAUNCHER_2, USER_10, () -> {
assertShortcutIds(assertAllDynamic(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
/* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED
@@ -2725,20 +2726,20 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
// Delete all dynamic.
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
mManager.removeAllDynamicShortcuts();
assertEquals(0, mManager.getDynamicShortcuts().size());
assertShortcutIds(assertAllPinned(mManager.getPinnedShortcuts()), "s1", "s2", "s3");
});
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
mManager.removeAllDynamicShortcuts();
assertEquals(0, mManager.getDynamicShortcuts().size());
assertShortcutIds(assertAllPinned(mManager.getPinnedShortcuts()), "s2", "s1");
});
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
assertShortcutIds(assertAllPinned(assertAllNotKeyFieldsOnly(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
/* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), getCallingUser()))),
@@ -2766,13 +2767,13 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
"s3");
});
// Re-publish s1.
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.addDynamicShortcuts(list(makeShortcut("s1"))));
assertShortcutIds(assertAllDynamic(mManager.getDynamicShortcuts()), "s1");
assertShortcutIds(assertAllPinned(mManager.getPinnedShortcuts()), "s1", "s2", "s3");
});
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
assertShortcutIds(assertAllPinned(assertAllNotKeyFieldsOnly(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
/* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), getCallingUser()))),
@@ -2789,7 +2790,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
// Now clear pinned shortcuts. First, from launcher 1.
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list(), getCallingUser());
mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list(), getCallingUser());
@@ -2800,17 +2801,17 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
/* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), getCallingUser()).size());
});
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertShortcutIds(assertAllDynamic(mManager.getDynamicShortcuts()), "s1");
assertShortcutIds(assertAllPinned(mManager.getPinnedShortcuts()), "s1", "s2");
});
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
assertEquals(0, mManager.getDynamicShortcuts().size());
assertShortcutIds(assertAllPinned(mManager.getPinnedShortcuts()), "s2");
});
// Clear all pins from launcher 2.
- runWithCaller(LAUNCHER_2, USER_0, () -> {
+ runWithCaller(LAUNCHER_2, USER_10, () -> {
mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list(), getCallingUser());
mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list(), getCallingUser());
@@ -2821,11 +2822,11 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
/* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), getCallingUser()).size());
});
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertShortcutIds(assertAllDynamic(mManager.getDynamicShortcuts()), "s1");
assertEquals(0, mManager.getPinnedShortcuts().size());
});
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
assertEquals(0, mManager.getDynamicShortcuts().size());
assertEquals(0, mManager.getPinnedShortcuts().size());
});
@@ -2833,74 +2834,74 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
public void PinShortcutAndGetPinnedShortcuts_assistant() {
// Create some shortcuts.
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
});
// Pin some.
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
list("s3", "s4"), getCallingUser());
});
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s1"))));
});
- runWithCaller(LAUNCHER_2, USER_0, () -> {
+ runWithCaller(LAUNCHER_2, USER_10, () -> {
final ShortcutQuery allPinned = new ShortcutQuery().setQueryFlags(
ShortcutQuery.FLAG_MATCH_PINNED_BY_ANY_LAUNCHER);
- assertWith(mLauncherApps.getShortcuts(allPinned, HANDLE_USER_0))
+ assertWith(mLauncherApps.getShortcuts(allPinned, HANDLE_USER_10))
.isEmpty();
- assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_0);
- assertShortcutNotLaunched(CALLING_PACKAGE_1, "s3", USER_0);
- assertShortcutNotLaunched(CALLING_PACKAGE_1, "s4", USER_0);
+ assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_10);
+ assertShortcutNotLaunched(CALLING_PACKAGE_1, "s3", USER_10);
+ assertShortcutNotLaunched(CALLING_PACKAGE_1, "s4", USER_10);
// Make it the assistant app.
- mInternal.setShortcutHostPackage("assistant", LAUNCHER_2, USER_0);
- assertWith(mLauncherApps.getShortcuts(allPinned, HANDLE_USER_0))
+ mInternal.setShortcutHostPackage("assistant", LAUNCHER_2, USER_10);
+ assertWith(mLauncherApps.getShortcuts(allPinned, HANDLE_USER_10))
.haveIds("s3");
- assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_0);
- assertShortcutLaunchable(CALLING_PACKAGE_1, "s3", USER_0);
- assertShortcutNotLaunched(CALLING_PACKAGE_1, "s4", USER_0);
+ assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_10);
+ assertShortcutLaunchable(CALLING_PACKAGE_1, "s3", USER_10);
+ assertShortcutNotLaunched(CALLING_PACKAGE_1, "s4", USER_10);
- mInternal.setShortcutHostPackage("another-type", LAUNCHER_3, USER_0);
- assertWith(mLauncherApps.getShortcuts(allPinned, HANDLE_USER_0))
+ mInternal.setShortcutHostPackage("another-type", LAUNCHER_3, USER_10);
+ assertWith(mLauncherApps.getShortcuts(allPinned, HANDLE_USER_10))
.haveIds("s3");
- mInternal.setShortcutHostPackage("assistant", null, USER_0);
- assertWith(mLauncherApps.getShortcuts(allPinned, HANDLE_USER_0))
+ mInternal.setShortcutHostPackage("assistant", null, USER_10);
+ assertWith(mLauncherApps.getShortcuts(allPinned, HANDLE_USER_10))
.isEmpty();
- mInternal.setShortcutHostPackage("assistant", LAUNCHER_2, USER_0);
- assertWith(mLauncherApps.getShortcuts(allPinned, HANDLE_USER_0))
+ mInternal.setShortcutHostPackage("assistant", LAUNCHER_2, USER_10);
+ assertWith(mLauncherApps.getShortcuts(allPinned, HANDLE_USER_10))
.haveIds("s3");
- mInternal.setShortcutHostPackage("assistant", LAUNCHER_1, USER_0);
- assertWith(mLauncherApps.getShortcuts(allPinned, HANDLE_USER_0))
+ mInternal.setShortcutHostPackage("assistant", LAUNCHER_1, USER_10);
+ assertWith(mLauncherApps.getShortcuts(allPinned, HANDLE_USER_10))
.isEmpty();
});
}
public void PinShortcutAndGetPinnedShortcuts_crossProfile_plusLaunch() {
// Create some shortcuts.
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
});
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
});
- mRunningUsers.put(USER_10, true);
+ mRunningUsers.put(USER_11, true);
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"),
makeShortcut("s4"), makeShortcut("s5"), makeShortcut("s6"))));
@@ -2908,33 +2909,33 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
// Pin some shortcuts and see the result.
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
- list("s1"), HANDLE_USER_0);
+ list("s1"), HANDLE_USER_10);
mLauncherApps.pinShortcuts(CALLING_PACKAGE_2,
- list("s1", "s2", "s3"), HANDLE_USER_0);
+ list("s1", "s2", "s3"), HANDLE_USER_10);
});
runWithCaller(LAUNCHER_1, USER_P0, () -> {
mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
- list("s2"), HANDLE_USER_0);
+ list("s2"), HANDLE_USER_10);
mLauncherApps.pinShortcuts(CALLING_PACKAGE_2,
- list("s2", "s3"), HANDLE_USER_0);
+ list("s2", "s3"), HANDLE_USER_10);
});
runWithCaller(LAUNCHER_2, USER_P0, () -> {
mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
- list("s3"), HANDLE_USER_0);
+ list("s3"), HANDLE_USER_10);
mLauncherApps.pinShortcuts(CALLING_PACKAGE_2,
- list("s3"), HANDLE_USER_0);
+ list("s3"), HANDLE_USER_10);
});
- runWithCaller(LAUNCHER_2, USER_10, () -> {
+ runWithCaller(LAUNCHER_2, USER_11, () -> {
mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
- list("s1", "s2", "s3"), HANDLE_USER_10);
+ list("s1", "s2", "s3"), HANDLE_USER_11);
});
// First, make sure managed profile can't see other profiles.
@@ -2945,540 +2946,540 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
| ShortcutQuery.FLAG_MATCH_MANIFEST);
// No shortcuts are visible.
- assertWith(mLauncherApps.getShortcuts(q, HANDLE_USER_0)).isEmpty();
+ assertWith(mLauncherApps.getShortcuts(q, HANDLE_USER_10)).isEmpty();
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s1"), HANDLE_USER_0);
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s1"), HANDLE_USER_10);
// Should have no effects.
- assertWith(mLauncherApps.getShortcuts(q, HANDLE_USER_0)).isEmpty();
+ assertWith(mLauncherApps.getShortcuts(q, HANDLE_USER_10)).isEmpty();
- assertShortcutNotLaunched(CALLING_PACKAGE_1, "s1", USER_0);
+ assertShortcutNotLaunched(CALLING_PACKAGE_1, "s1", USER_10);
});
// Cross profile pinning.
final int PIN_AND_DYNAMIC = ShortcutQuery.FLAG_GET_PINNED | ShortcutQuery.FLAG_GET_DYNAMIC;
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
assertShortcutIds(assertAllPinned(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
- /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_10)),
"s1");
assertShortcutIds(assertAllDynamic(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
- /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_10)),
"s1", "s2", "s3");
assertShortcutIds(assertAllDynamicOrPinned(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
- /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
+ /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_10)),
"s1", "s2", "s3");
assertShortcutIds(assertAllPinned(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
- /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_10)),
"s1", "s2", "s3");
assertShortcutIds(assertAllDynamic(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
- /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_10)),
"s1", "s2", "s3");
assertShortcutIds(assertAllDynamicOrPinned(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
- /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
+ /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_10)),
"s1", "s2", "s3");
- assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_0);
- assertShortcutLaunchable(CALLING_PACKAGE_1, "s2", USER_0);
- assertShortcutLaunchable(CALLING_PACKAGE_1, "s3", USER_0);
+ assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_10);
+ assertShortcutLaunchable(CALLING_PACKAGE_1, "s2", USER_10);
+ assertShortcutLaunchable(CALLING_PACKAGE_1, "s3", USER_10);
- assertShortcutLaunchable(CALLING_PACKAGE_2, "s1", USER_0);
- assertShortcutLaunchable(CALLING_PACKAGE_2, "s2", USER_0);
- assertShortcutLaunchable(CALLING_PACKAGE_2, "s3", USER_0);
+ assertShortcutLaunchable(CALLING_PACKAGE_2, "s1", USER_10);
+ assertShortcutLaunchable(CALLING_PACKAGE_2, "s2", USER_10);
+ assertShortcutLaunchable(CALLING_PACKAGE_2, "s3", USER_10);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s1", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s1", USER_11,
SecurityException.class);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_11,
SecurityException.class);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_11,
SecurityException.class);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s4", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s4", USER_11,
SecurityException.class);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s5", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s5", USER_11,
SecurityException.class);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s6", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s6", USER_11,
SecurityException.class);
});
runWithCaller(LAUNCHER_1, USER_P0, () -> {
assertShortcutIds(assertAllPinned(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
- /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_10)),
"s2");
assertShortcutIds(assertAllDynamic(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
- /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_10)),
"s1", "s2", "s3");
assertShortcutIds(assertAllDynamicOrPinned(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
- /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
+ /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_10)),
"s1", "s2", "s3");
assertShortcutIds(assertAllPinned(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
- /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_10)),
"s2", "s3");
assertShortcutIds(assertAllDynamic(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
- /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_10)),
"s1", "s2", "s3");
assertShortcutIds(assertAllDynamicOrPinned(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
- /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
+ /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_10)),
"s1", "s2", "s3");
- assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_0);
- assertShortcutLaunchable(CALLING_PACKAGE_1, "s2", USER_0);
- assertShortcutLaunchable(CALLING_PACKAGE_1, "s3", USER_0);
+ assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_10);
+ assertShortcutLaunchable(CALLING_PACKAGE_1, "s2", USER_10);
+ assertShortcutLaunchable(CALLING_PACKAGE_1, "s3", USER_10);
- assertShortcutLaunchable(CALLING_PACKAGE_2, "s1", USER_0);
- assertShortcutLaunchable(CALLING_PACKAGE_2, "s2", USER_0);
- assertShortcutLaunchable(CALLING_PACKAGE_2, "s3", USER_0);
+ assertShortcutLaunchable(CALLING_PACKAGE_2, "s1", USER_10);
+ assertShortcutLaunchable(CALLING_PACKAGE_2, "s2", USER_10);
+ assertShortcutLaunchable(CALLING_PACKAGE_2, "s3", USER_10);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s1", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s1", USER_11,
SecurityException.class);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_11,
SecurityException.class);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_11,
SecurityException.class);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s4", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s4", USER_11,
SecurityException.class);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s5", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s5", USER_11,
SecurityException.class);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s6", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s6", USER_11,
SecurityException.class);
});
runWithCaller(LAUNCHER_2, USER_P0, () -> {
assertShortcutIds(assertAllPinned(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
- /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_10)),
"s3");
assertShortcutIds(assertAllDynamic(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
- /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_10)),
"s1", "s2", "s3");
assertShortcutIds(assertAllDynamicOrPinned(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
- /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
+ /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_10)),
"s1", "s2", "s3");
assertShortcutIds(assertAllPinned(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
- /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_10)),
"s3");
assertShortcutIds(assertAllDynamic(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
- /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_10)),
"s1", "s2", "s3");
assertShortcutIds(assertAllDynamicOrPinned(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
- /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
+ /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_10)),
"s1", "s2", "s3");
- assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_0);
- assertShortcutLaunchable(CALLING_PACKAGE_1, "s2", USER_0);
- assertShortcutLaunchable(CALLING_PACKAGE_1, "s3", USER_0);
+ assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_10);
+ assertShortcutLaunchable(CALLING_PACKAGE_1, "s2", USER_10);
+ assertShortcutLaunchable(CALLING_PACKAGE_1, "s3", USER_10);
- assertShortcutLaunchable(CALLING_PACKAGE_2, "s1", USER_0);
- assertShortcutLaunchable(CALLING_PACKAGE_2, "s2", USER_0);
- assertShortcutLaunchable(CALLING_PACKAGE_2, "s3", USER_0);
+ assertShortcutLaunchable(CALLING_PACKAGE_2, "s1", USER_10);
+ assertShortcutLaunchable(CALLING_PACKAGE_2, "s2", USER_10);
+ assertShortcutLaunchable(CALLING_PACKAGE_2, "s3", USER_10);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s1", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s1", USER_11,
SecurityException.class);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_11,
SecurityException.class);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_11,
SecurityException.class);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s4", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s4", USER_11,
SecurityException.class);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s5", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s5", USER_11,
SecurityException.class);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s6", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s6", USER_11,
SecurityException.class);
});
- runWithCaller(LAUNCHER_2, USER_10, () -> {
+ runWithCaller(LAUNCHER_2, USER_11, () -> {
assertShortcutIds(assertAllPinned(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
- /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_10)),
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_11)),
"s1", "s2", "s3");
assertShortcutIds(assertAllDynamic(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
- /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_10)),
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_11)),
"s1", "s2", "s3", "s4", "s5", "s6");
assertShortcutIds(assertAllDynamicOrPinned(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
- /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_10)),
+ /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_11)),
"s1", "s2", "s3", "s4", "s5", "s6");
});
// Remove some dynamic shortcuts.
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s1"))));
});
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s1"))));
});
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s1"))));
});
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
assertShortcutIds(assertAllPinned(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
- /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_10)),
"s1");
assertShortcutIds(assertAllDynamic(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
- /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_10)),
"s1");
assertShortcutIds(assertAllDynamicOrPinned(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
- /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
+ /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_10)),
"s1");
assertShortcutIds(assertAllPinned(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
- /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_10)),
"s1", "s2", "s3");
assertShortcutIds(assertAllDynamic(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
- /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_10)),
"s1");
assertShortcutIds(assertAllDynamicOrPinned(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
- /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
+ /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_10)),
"s1", "s2", "s3");
- assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_0);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_0,
+ assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_10);
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_10,
ActivityNotFoundException.class);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_0,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_10,
ActivityNotFoundException.class);
- assertShortcutLaunchable(CALLING_PACKAGE_2, "s1", USER_0);
- assertShortcutLaunchable(CALLING_PACKAGE_2, "s2", USER_0);
- assertShortcutLaunchable(CALLING_PACKAGE_2, "s3", USER_0);
+ assertShortcutLaunchable(CALLING_PACKAGE_2, "s1", USER_10);
+ assertShortcutLaunchable(CALLING_PACKAGE_2, "s2", USER_10);
+ assertShortcutLaunchable(CALLING_PACKAGE_2, "s3", USER_10);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s1", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s1", USER_11,
SecurityException.class);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_11,
SecurityException.class);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_11,
SecurityException.class);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s4", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s4", USER_11,
SecurityException.class);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s5", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s5", USER_11,
SecurityException.class);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s6", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s6", USER_11,
SecurityException.class);
});
runWithCaller(LAUNCHER_1, USER_P0, () -> {
assertShortcutIds(assertAllPinned(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
- /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_10)),
"s2");
assertShortcutIds(assertAllDynamic(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
- /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_10)),
"s1");
assertShortcutIds(assertAllDynamicOrPinned(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
- /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
+ /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_10)),
"s1", "s2");
assertShortcutIds(assertAllPinned(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
- /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_10)),
"s2", "s3");
assertShortcutIds(assertAllDynamic(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
- /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_10)),
"s1");
assertShortcutIds(assertAllDynamicOrPinned(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
- /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
+ /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_10)),
"s1", "s2", "s3");
- assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_0);
- assertShortcutLaunchable(CALLING_PACKAGE_1, "s2", USER_0);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_0,
+ assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_10);
+ assertShortcutLaunchable(CALLING_PACKAGE_1, "s2", USER_10);
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_10,
ActivityNotFoundException.class);
- assertShortcutLaunchable(CALLING_PACKAGE_2, "s1", USER_0);
- assertShortcutLaunchable(CALLING_PACKAGE_2, "s2", USER_0);
- assertShortcutLaunchable(CALLING_PACKAGE_2, "s3", USER_0);
+ assertShortcutLaunchable(CALLING_PACKAGE_2, "s1", USER_10);
+ assertShortcutLaunchable(CALLING_PACKAGE_2, "s2", USER_10);
+ assertShortcutLaunchable(CALLING_PACKAGE_2, "s3", USER_10);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s1", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s1", USER_11,
SecurityException.class);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_11,
SecurityException.class);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_11,
SecurityException.class);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s4", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s4", USER_11,
SecurityException.class);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s5", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s5", USER_11,
SecurityException.class);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s6", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s6", USER_11,
SecurityException.class);
});
runWithCaller(LAUNCHER_2, USER_P0, () -> {
assertShortcutIds(assertAllPinned(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
- /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_10)),
"s3");
assertShortcutIds(assertAllDynamic(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
- /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_10)),
"s1");
assertShortcutIds(assertAllDynamicOrPinned(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
- /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
+ /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_10)),
"s1", "s3");
assertShortcutIds(assertAllPinned(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
- /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_10)),
"s3");
assertShortcutIds(assertAllDynamic(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
- /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_10)),
"s1");
assertShortcutIds(assertAllDynamicOrPinned(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
- /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
+ /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_10)),
"s1", "s3");
- assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_0);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_0,
+ assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_10);
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_10,
ActivityNotFoundException.class);
- assertShortcutLaunchable(CALLING_PACKAGE_1, "s3", USER_0);
+ assertShortcutLaunchable(CALLING_PACKAGE_1, "s3", USER_10);
- assertShortcutLaunchable(CALLING_PACKAGE_2, "s1", USER_0);
- assertStartShortcutThrowsException(CALLING_PACKAGE_2, "s2", USER_0,
+ assertShortcutLaunchable(CALLING_PACKAGE_2, "s1", USER_10);
+ assertStartShortcutThrowsException(CALLING_PACKAGE_2, "s2", USER_10,
ActivityNotFoundException.class);
- assertShortcutLaunchable(CALLING_PACKAGE_2, "s3", USER_0);
+ assertShortcutLaunchable(CALLING_PACKAGE_2, "s3", USER_10);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s1", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s1", USER_11,
SecurityException.class);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_11,
SecurityException.class);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_11,
SecurityException.class);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s4", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s4", USER_11,
SecurityException.class);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s5", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s5", USER_11,
SecurityException.class);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s6", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s6", USER_11,
SecurityException.class);
});
- runWithCaller(LAUNCHER_2, USER_10, () -> {
+ runWithCaller(LAUNCHER_2, USER_11, () -> {
assertShortcutIds(assertAllPinned(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
- /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_10)),
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_11)),
"s1", "s2", "s3");
assertShortcutIds(assertAllDynamic(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
- /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_10)),
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_11)),
"s1");
assertShortcutIds(assertAllDynamicOrPinned(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
- /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_10)),
+ /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_11)),
"s1", "s2", "s3");
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s1", USER_0,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s1", USER_10,
SecurityException.class);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_0,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_10,
SecurityException.class);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_0,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_10,
SecurityException.class);
- assertStartShortcutThrowsException(CALLING_PACKAGE_2, "s1", USER_0,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_2, "s1", USER_10,
SecurityException.class);
- assertStartShortcutThrowsException(CALLING_PACKAGE_2, "s2", USER_0,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_2, "s2", USER_10,
SecurityException.class);
- assertStartShortcutThrowsException(CALLING_PACKAGE_2, "s3", USER_0,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_2, "s3", USER_10,
SecurityException.class);
- assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_10);
- assertShortcutLaunchable(CALLING_PACKAGE_1, "s2", USER_10);
- assertShortcutLaunchable(CALLING_PACKAGE_1, "s3", USER_10);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s4", USER_10,
+ assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_11);
+ assertShortcutLaunchable(CALLING_PACKAGE_1, "s2", USER_11);
+ assertShortcutLaunchable(CALLING_PACKAGE_1, "s3", USER_11);
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s4", USER_11,
ActivityNotFoundException.class);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s5", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s5", USER_11,
ActivityNotFoundException.class);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s6", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s6", USER_11,
ActivityNotFoundException.class);
});
// Save & load and make sure we still have the same information.
mService.saveDirtyInfo();
initService();
- mService.handleUnlockUser(USER_0);
+ mService.handleUnlockUser(USER_10);
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
assertShortcutIds(assertAllPinned(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
- /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_10)),
"s1");
assertShortcutIds(assertAllDynamic(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
- /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_10)),
"s1");
assertShortcutIds(assertAllDynamicOrPinned(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
- /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
+ /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_10)),
"s1");
assertShortcutIds(assertAllPinned(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
- /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_10)),
"s1", "s2", "s3");
assertShortcutIds(assertAllDynamic(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
- /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_10)),
"s1");
assertShortcutIds(assertAllDynamicOrPinned(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
- /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
+ /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_10)),
"s1", "s2", "s3");
- assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_0);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_0,
+ assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_10);
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_10,
ActivityNotFoundException.class);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_0,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_10,
ActivityNotFoundException.class);
- assertShortcutLaunchable(CALLING_PACKAGE_2, "s1", USER_0);
- assertShortcutLaunchable(CALLING_PACKAGE_2, "s2", USER_0);
- assertShortcutLaunchable(CALLING_PACKAGE_2, "s3", USER_0);
+ assertShortcutLaunchable(CALLING_PACKAGE_2, "s1", USER_10);
+ assertShortcutLaunchable(CALLING_PACKAGE_2, "s2", USER_10);
+ assertShortcutLaunchable(CALLING_PACKAGE_2, "s3", USER_10);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s1", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s1", USER_11,
SecurityException.class);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_11,
SecurityException.class);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_11,
SecurityException.class);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s4", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s4", USER_11,
SecurityException.class);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s5", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s5", USER_11,
SecurityException.class);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s6", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s6", USER_11,
SecurityException.class);
});
runWithCaller(LAUNCHER_1, USER_P0, () -> {
assertShortcutIds(assertAllPinned(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
- /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_10)),
"s2");
assertShortcutIds(assertAllDynamic(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
- /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_10)),
"s1");
assertShortcutIds(assertAllDynamicOrPinned(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
- /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
+ /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_10)),
"s1", "s2");
assertShortcutIds(assertAllPinned(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
- /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_10)),
"s2", "s3");
assertShortcutIds(assertAllDynamic(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
- /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_10)),
"s1");
assertShortcutIds(assertAllDynamicOrPinned(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
- /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
+ /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_10)),
"s1", "s2", "s3");
- assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_0);
- assertShortcutLaunchable(CALLING_PACKAGE_1, "s2", USER_0);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_0,
+ assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_10);
+ assertShortcutLaunchable(CALLING_PACKAGE_1, "s2", USER_10);
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_10,
ActivityNotFoundException.class);
- assertShortcutLaunchable(CALLING_PACKAGE_2, "s1", USER_0);
- assertShortcutLaunchable(CALLING_PACKAGE_2, "s2", USER_0);
- assertShortcutLaunchable(CALLING_PACKAGE_2, "s3", USER_0);
+ assertShortcutLaunchable(CALLING_PACKAGE_2, "s1", USER_10);
+ assertShortcutLaunchable(CALLING_PACKAGE_2, "s2", USER_10);
+ assertShortcutLaunchable(CALLING_PACKAGE_2, "s3", USER_10);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s1", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s1", USER_11,
SecurityException.class);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_11,
SecurityException.class);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_11,
SecurityException.class);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s4", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s4", USER_11,
SecurityException.class);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s5", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s5", USER_11,
SecurityException.class);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s6", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s6", USER_11,
SecurityException.class);
});
runWithCaller(LAUNCHER_2, USER_P0, () -> {
assertShortcutIds(assertAllPinned(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
- /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_10)),
"s3");
assertShortcutIds(assertAllDynamic(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
- /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_10)),
"s1");
assertShortcutIds(assertAllDynamicOrPinned(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
- /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
+ /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_10)),
"s1", "s3");
assertShortcutIds(assertAllPinned(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
- /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_0)),
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), HANDLE_USER_10)),
"s3");
assertShortcutIds(assertAllDynamic(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
- /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_0)),
+ /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), HANDLE_USER_10)),
"s1");
assertShortcutIds(assertAllDynamicOrPinned(
mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2,
- /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_0)),
+ /* activity =*/ null, PIN_AND_DYNAMIC), HANDLE_USER_10)),
"s1", "s3");
- assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_0);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_0,
+ assertShortcutLaunchable(CALLING_PACKAGE_1, "s1", USER_10);
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_10,
ActivityNotFoundException.class);
- assertShortcutLaunchable(CALLING_PACKAGE_1, "s3", USER_0);
+ assertShortcutLaunchable(CALLING_PACKAGE_1, "s3", USER_10);
- assertShortcutLaunchable(CALLING_PACKAGE_2, "s1", USER_0);
- assertStartShortcutThrowsException(CALLING_PACKAGE_2, "s2", USER_0,
+ assertShortcutLaunchable(CALLING_PACKAGE_2, "s1", USER_10);
+ assertStartShortcutThrowsException(CALLING_PACKAGE_2, "s2", USER_10,
ActivityNotFoundException.class);
- assertShortcutLaunchable(CALLING_PACKAGE_2, "s3", USER_0);
+ assertShortcutLaunchable(CALLING_PACKAGE_2, "s3", USER_10);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s1", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s1", USER_11,
SecurityException.class);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s2", USER_11,
SecurityException.class);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s3", USER_11,
SecurityException.class);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s4", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s4", USER_11,
SecurityException.class);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s5", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s5", USER_11,
SecurityException.class);
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s6", USER_10,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s6", USER_11,
SecurityException.class);
});
}
public void StartShortcut() {
// Create some shortcuts.
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
final ShortcutInfo s1_1 = makeShortcut(
"s1",
"Title 1",
@@ -3503,7 +3504,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertTrue(mManager.setDynamicShortcuts(list(s1_1, s1_2, s1_3)));
});
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
final ShortcutInfo s2_1 = makeShortcut(
"s1",
"ABC",
@@ -3516,7 +3517,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
// Pin some.
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
list("s1", "s2"), getCallingUser());
@@ -3525,12 +3526,12 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
// Just to make it complicated, delete some.
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
mManager.removeDynamicShortcuts(list("s2"));
});
- runWithCaller(LAUNCHER_1, USER_0, () -> {
- final Intent[] intents = launchShortcutAndGetIntents(CALLING_PACKAGE_1, "s1", USER_0);
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
+ final Intent[] intents = launchShortcutAndGetIntents(CALLING_PACKAGE_1, "s1", USER_10);
assertEquals(ShortcutActivity2.class.getName(),
intents[0].getComponent().getClassName());
assertEquals(Intent.ACTION_ASSIST,
@@ -3545,25 +3546,25 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertEquals(
ShortcutActivity3.class.getName(),
- launchShortcutAndGetIntent(CALLING_PACKAGE_1, "s2", USER_0)
+ launchShortcutAndGetIntent(CALLING_PACKAGE_1, "s2", USER_10)
.getComponent().getClassName());
assertEquals(
ShortcutActivity.class.getName(),
- launchShortcutAndGetIntent(CALLING_PACKAGE_2, "s1", USER_0)
+ launchShortcutAndGetIntent(CALLING_PACKAGE_2, "s1", USER_10)
.getComponent().getClassName());
- assertShortcutLaunchable(CALLING_PACKAGE_1, "s3", USER_0);
+ assertShortcutLaunchable(CALLING_PACKAGE_1, "s3", USER_10);
- assertShortcutNotLaunched("no-such-package", "s2", USER_0);
- assertShortcutNotLaunched(CALLING_PACKAGE_1, "xxxx", USER_0);
+ assertShortcutNotLaunched("no-such-package", "s2", USER_10);
+ assertShortcutNotLaunched(CALLING_PACKAGE_1, "xxxx", USER_10);
});
// LAUNCHER_1 is no longer the default launcher
setDefaultLauncherChecker((pkg, userId) -> false);
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
// Not the default launcher, but pinned shortcuts are still lauchable.
- final Intent[] intents = launchShortcutAndGetIntents(CALLING_PACKAGE_1, "s1", USER_0);
+ final Intent[] intents = launchShortcutAndGetIntents(CALLING_PACKAGE_1, "s1", USER_10);
assertEquals(ShortcutActivity2.class.getName(),
intents[0].getComponent().getClassName());
assertEquals(Intent.ACTION_ASSIST,
@@ -3577,24 +3578,24 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
intents[1].getFlags());
assertEquals(
ShortcutActivity3.class.getName(),
- launchShortcutAndGetIntent(CALLING_PACKAGE_1, "s2", USER_0)
+ launchShortcutAndGetIntent(CALLING_PACKAGE_1, "s2", USER_10)
.getComponent().getClassName());
assertEquals(
ShortcutActivity.class.getName(),
- launchShortcutAndGetIntent(CALLING_PACKAGE_2, "s1", USER_0)
+ launchShortcutAndGetIntent(CALLING_PACKAGE_2, "s1", USER_10)
.getComponent().getClassName());
// Not pinned, so not lauchable.
});
// Test inner errors.
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
// Not launchable.
doReturn(ActivityManager.START_CLASS_NOT_FOUND)
.when(mMockActivityTaskManagerInternal).startActivitiesAsPackage(
anyStringOrNull(), anyStringOrNull(), anyInt(),
anyOrNull(Intent[].class), anyOrNull(Bundle.class));
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s1", USER_0,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s1", USER_10,
ActivityNotFoundException.class);
// Still not launchable.
@@ -3603,7 +3604,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
.startActivitiesAsPackage(
anyStringOrNull(), anyStringOrNull(), anyInt(),
anyOrNull(Intent[].class), anyOrNull(Bundle.class));
- assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s1", USER_0,
+ assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s1", USER_10,
ActivityNotFoundException.class);
});
@@ -3618,34 +3619,34 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
+ ConfigConstants.KEY_MAX_SHORTCUTS + "=99999999"
);
- setCaller(LAUNCHER_1, USER_0);
+ setCaller(LAUNCHER_1, USER_10);
assertForLauncherCallback(mLauncherApps, () -> {
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
});
- }).assertCallbackCalledForPackageAndUser(CALLING_PACKAGE_1, HANDLE_USER_0)
+ }).assertCallbackCalledForPackageAndUser(CALLING_PACKAGE_1, HANDLE_USER_10)
.haveIds("s1", "s2", "s3")
.areAllWithKeyFieldsOnly()
.areAllDynamic();
// From different package.
assertForLauncherCallback(mLauncherApps, () -> {
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
});
- }).assertCallbackCalledForPackageAndUser(CALLING_PACKAGE_2, HANDLE_USER_0)
+ }).assertCallbackCalledForPackageAndUser(CALLING_PACKAGE_2, HANDLE_USER_10)
.haveIds("s1", "s2", "s3")
.areAllWithKeyFieldsOnly()
.areAllDynamic();
- mRunningUsers.put(USER_10, true);
+ mRunningUsers.put(USER_11, true);
// Different user, callback shouldn't be called.
assertForLauncherCallback(mLauncherApps, () -> {
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
});
@@ -3654,31 +3655,31 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
// Test for addDynamicShortcuts.
assertForLauncherCallback(mLauncherApps, () -> {
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.addDynamicShortcuts(list(makeShortcut("s4"))));
});
- }).assertCallbackCalledForPackageAndUser(CALLING_PACKAGE_1, HANDLE_USER_0)
+ }).assertCallbackCalledForPackageAndUser(CALLING_PACKAGE_1, HANDLE_USER_10)
.haveIds("s1", "s2", "s3", "s4")
.areAllWithKeyFieldsOnly()
.areAllDynamic();
// Test for remove
assertForLauncherCallback(mLauncherApps, () -> {
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
mManager.removeDynamicShortcuts(list("s1"));
});
- }).assertCallbackCalledForPackageAndUser(CALLING_PACKAGE_1, HANDLE_USER_0)
+ }).assertCallbackCalledForPackageAndUser(CALLING_PACKAGE_1, HANDLE_USER_10)
.haveIds("s2", "s3", "s4")
.areAllWithKeyFieldsOnly()
.areAllDynamic();
// Test for update
assertForLauncherCallback(mLauncherApps, () -> {
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.updateShortcuts(list(
makeShortcut("s1"), makeShortcut("s2"))));
});
- }).assertCallbackCalledForPackageAndUser(CALLING_PACKAGE_1, HANDLE_USER_0)
+ }).assertCallbackCalledForPackageAndUser(CALLING_PACKAGE_1, HANDLE_USER_10)
// All remaining shortcuts will be passed regardless of what's been updated.
.haveIds("s2", "s3", "s4")
.areAllWithKeyFieldsOnly()
@@ -3686,10 +3687,10 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
// Test for deleteAll
assertForLauncherCallback(mLauncherApps, () -> {
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
mManager.removeAllDynamicShortcuts();
});
- }).assertCallbackCalledForPackageAndUser(CALLING_PACKAGE_1, HANDLE_USER_0)
+ }).assertCallbackCalledForPackageAndUser(CALLING_PACKAGE_1, HANDLE_USER_10)
.isEmpty();
// Update package1 with manifest shortcuts
@@ -3699,24 +3700,24 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
R.xml.shortcut_2);
updatePackageVersion(CALLING_PACKAGE_1, 1);
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
- }).assertCallbackCalledForPackageAndUser(CALLING_PACKAGE_1, HANDLE_USER_0)
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
+ }).assertCallbackCalledForPackageAndUser(CALLING_PACKAGE_1, HANDLE_USER_10)
.areAllManifest()
.areAllWithKeyFieldsOnly()
.haveIds("ms1", "ms2");
// Make sure pinned shortcuts are passed too.
// 1. Add dynamic shortcuts.
- runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s1"), makeShortcut("s2"))));
});
// 2. Pin some.
- runWithCaller(LAUNCHER_1, UserHandle.USER_SYSTEM, () -> {
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("ms2", "s2"), HANDLE_USER_0);
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("ms2", "s2"), HANDLE_USER_10);
});
- runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertWith(getCallerShortcuts())
.haveIds("ms1", "ms2", "s1", "s2")
.areAllEnabled()
@@ -3736,10 +3737,10 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
R.xml.shortcut_0);
updatePackageVersion(CALLING_PACKAGE_1, 1);
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
assertForLauncherCallback(mLauncherApps, () -> {
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
mManager.removeDynamicShortcuts(list("s2"));
assertWith(getCallerShortcuts())
@@ -3764,16 +3765,16 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
.areAllEnabled()
;
});
- }).assertCallbackCalledForPackageAndUser(CALLING_PACKAGE_1, HANDLE_USER_0)
+ }).assertCallbackCalledForPackageAndUser(CALLING_PACKAGE_1, HANDLE_USER_10)
.haveIds("ms2", "s1", "s2")
.areAllWithKeyFieldsOnly();
// Remove CALLING_PACKAGE_2
assertForLauncherCallback(mLauncherApps, () -> {
- uninstallPackage(USER_0, CALLING_PACKAGE_2);
- mService.cleanUpPackageLocked(CALLING_PACKAGE_2, USER_0, USER_0,
+ uninstallPackage(USER_10, CALLING_PACKAGE_2);
+ mService.cleanUpPackageLocked(CALLING_PACKAGE_2, USER_10, USER_10,
/* appStillExists = */ false);
- }).assertCallbackCalledForPackageAndUser(CALLING_PACKAGE_2, HANDLE_USER_0)
+ }).assertCallbackCalledForPackageAndUser(CALLING_PACKAGE_2, HANDLE_USER_10)
.isEmpty();
}
@@ -3798,35 +3799,35 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
setDefaultLauncherChecker((pkg, userId) -> {
switch (userId) {
- case USER_0:
+ case USER_10:
return LAUNCHER_2.equals(pkg);
case USER_P0:
return LAUNCHER_1.equals(pkg);
case USER_P1:
return LAUNCHER_1.equals(pkg);
- case USER_10:
- return LAUNCHER_1.equals(pkg);
case USER_11:
return LAUNCHER_1.equals(pkg);
+ case USER_12:
+ return LAUNCHER_1.equals(pkg);
default:
return false;
}
});
- runWithCaller(LAUNCHER_1, USER_0, () -> mLauncherApps.registerCallback(c0_1, h));
- runWithCaller(LAUNCHER_2, USER_0, () -> mLauncherApps.registerCallback(c0_2, h));
- runWithCaller(LAUNCHER_3, USER_0, () -> mLauncherApps.registerCallback(c0_3, h));
- runWithCaller(LAUNCHER_4, USER_0, () -> mLauncherApps.registerCallback(c0_4, h));
+ runWithCaller(LAUNCHER_1, USER_10, () -> mLauncherApps.registerCallback(c0_1, h));
+ runWithCaller(LAUNCHER_2, USER_10, () -> mLauncherApps.registerCallback(c0_2, h));
+ runWithCaller(LAUNCHER_3, USER_10, () -> mLauncherApps.registerCallback(c0_3, h));
+ runWithCaller(LAUNCHER_4, USER_10, () -> mLauncherApps.registerCallback(c0_4, h));
runWithCaller(LAUNCHER_1, USER_P0, () -> mLauncherApps.registerCallback(cP0_1, h));
runWithCaller(LAUNCHER_1, USER_P1, () -> mLauncherApps.registerCallback(cP1_1, h));
- runWithCaller(LAUNCHER_1, USER_10, () -> mLauncherApps.registerCallback(c10_1, h));
- runWithCaller(LAUNCHER_2, USER_10, () -> mLauncherApps.registerCallback(c10_2, h));
- runWithCaller(LAUNCHER_1, USER_11, () -> mLauncherApps.registerCallback(c11_1, h));
+ runWithCaller(LAUNCHER_1, USER_11, () -> mLauncherApps.registerCallback(c10_1, h));
+ runWithCaller(LAUNCHER_2, USER_11, () -> mLauncherApps.registerCallback(c10_2, h));
+ runWithCaller(LAUNCHER_1, USER_12, () -> mLauncherApps.registerCallback(c11_1, h));
// User 0.
resetAll(all);
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
mManager.removeDynamicShortcuts(list());
});
waitOnMainThread();
@@ -3837,14 +3838,14 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertCallbackNotReceived(c10_1);
assertCallbackNotReceived(c10_2);
assertCallbackNotReceived(c11_1);
- assertCallbackReceived(c0_2, HANDLE_USER_0, CALLING_PACKAGE_1, "s1", "s2", "s3");
- assertCallbackReceived(cP0_1, HANDLE_USER_0, CALLING_PACKAGE_1, "s1", "s2", "s3", "s4");
+ assertCallbackReceived(c0_2, HANDLE_USER_10, CALLING_PACKAGE_1, "s1", "s2", "s3");
+ assertCallbackReceived(cP0_1, HANDLE_USER_10, CALLING_PACKAGE_1, "s1", "s2", "s3", "s4");
assertCallbackNotReceived(cP1_1);
// User 0, different package.
resetAll(all);
- runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_3, USER_10, () -> {
mManager.removeDynamicShortcuts(list());
});
waitOnMainThread();
@@ -3855,8 +3856,8 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertCallbackNotReceived(c10_1);
assertCallbackNotReceived(c10_2);
assertCallbackNotReceived(c11_1);
- assertCallbackReceived(c0_2, HANDLE_USER_0, CALLING_PACKAGE_3, "s1", "s2", "s3", "s4");
- assertCallbackReceived(cP0_1, HANDLE_USER_0, CALLING_PACKAGE_3,
+ assertCallbackReceived(c0_2, HANDLE_USER_10, CALLING_PACKAGE_3, "s1", "s2", "s3", "s4");
+ assertCallbackReceived(cP0_1, HANDLE_USER_10, CALLING_PACKAGE_3,
"s1", "s2", "s3", "s4", "s5", "s6");
assertCallbackNotReceived(cP1_1);
@@ -3878,10 +3879,10 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertCallbackNotReceived(cP1_1);
// Normal secondary user.
- mRunningUsers.put(USER_10, true);
+ mRunningUsers.put(USER_11, true);
resetAll(all);
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
mManager.removeDynamicShortcuts(list());
});
waitOnMainThread();
@@ -3893,7 +3894,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertCallbackNotReceived(cP0_1);
assertCallbackNotReceived(c10_2);
assertCallbackNotReceived(c11_1);
- assertCallbackReceived(c10_1, HANDLE_USER_10, CALLING_PACKAGE_1,
+ assertCallbackReceived(c10_1, HANDLE_USER_11, CALLING_PACKAGE_1,
"x1", "x2", "x3", "x4", "x5");
assertCallbackNotReceived(cP1_1);
}
@@ -3905,7 +3906,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
Log.i(TAG, "Saved state");
dumpsysOnLogcat();
- dumpUserFile(0);
+ dumpUserFile(USER_10);
// Restore.
mService.saveDirtyInfo();
@@ -3919,7 +3920,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
*/
public void SaveAndLoadUser() {
// First, create some shortcuts and save.
- runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
final Icon icon1 = Icon.createWithResource(getTestContext(), R.drawable.black_64x16);
final Icon icon2 = Icon.createWithBitmap(BitmapFactory.decodeResource(
getTestContext().getResources(), R.drawable.icon2));
@@ -3946,7 +3947,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime());
assertEquals(2, mManager.getRemainingCallCount());
});
- runWithCaller(CALLING_PACKAGE_2, UserHandle.USER_SYSTEM, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
final Icon icon1 = Icon.createWithResource(getTestContext(), R.drawable.black_16x64);
final Icon icon2 = Icon.createWithBitmap(BitmapFactory.decodeResource(
getTestContext().getResources(), R.drawable.icon2));
@@ -3974,9 +3975,9 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertEquals(2, mManager.getRemainingCallCount());
});
- mRunningUsers.put(USER_10, true);
+ mRunningUsers.put(USER_11, true);
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
final Icon icon1 = Icon.createWithResource(getTestContext(), R.drawable.black_64x64);
final Icon icon2 = Icon.createWithBitmap(BitmapFactory.decodeResource(
getTestContext().getResources(), R.drawable.icon2));
@@ -4012,12 +4013,12 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertEquals(0, mService.getShortcutsForTest().size());
// this will pre-load the per-user info.
- mService.handleUnlockUser(UserHandle.USER_SYSTEM);
+ mService.handleUnlockUser(USER_10);
// Now it's loaded.
assertEquals(1, mService.getShortcutsForTest().size());
- runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertShortcutIds(assertAllDynamic(assertAllHaveIntents(assertAllHaveIcon(
mManager.getDynamicShortcuts()))), "s1", "s2");
assertEquals(2, mManager.getRemainingCallCount());
@@ -4025,7 +4026,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertEquals("title1-1", getCallerShortcut("s1").getTitle());
assertEquals("title1-2", getCallerShortcut("s2").getTitle());
});
- runWithCaller(CALLING_PACKAGE_2, UserHandle.USER_SYSTEM, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
assertShortcutIds(assertAllDynamic(assertAllHaveIntents(assertAllHaveIcon(
mManager.getDynamicShortcuts()))), "s1", "s2");
assertEquals(2, mManager.getRemainingCallCount());
@@ -4035,12 +4036,12 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
// Start another user
- mService.handleUnlockUser(USER_10);
+ mService.handleUnlockUser(USER_11);
// Now the size is 2.
assertEquals(2, mService.getShortcutsForTest().size());
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
assertShortcutIds(assertAllDynamic(assertAllHaveIntents(assertAllHaveIcon(
mManager.getDynamicShortcuts()))), "s1", "s2");
assertEquals(2, mManager.getRemainingCallCount());
@@ -4050,7 +4051,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
// Try stopping the user
- mService.handleStopUser(USER_10);
+ mService.handleStopUser(USER_11);
// Now it's unloaded.
assertEquals(1, mService.getShortcutsForTest().size());
@@ -4074,7 +4075,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
public void SaveCorruptAndLoadUser() throws Exception {
// First, create some shortcuts and save.
- runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
final Icon icon1 = Icon.createWithResource(getTestContext(), R.drawable.black_64x16);
final Icon icon2 = Icon.createWithBitmap(BitmapFactory.decodeResource(
getTestContext().getResources(), R.drawable.icon2));
@@ -4101,7 +4102,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime());
assertEquals(2, mManager.getRemainingCallCount());
});
- runWithCaller(CALLING_PACKAGE_2, UserHandle.USER_SYSTEM, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
final Icon icon1 = Icon.createWithResource(getTestContext(), R.drawable.black_16x64);
final Icon icon2 = Icon.createWithBitmap(BitmapFactory.decodeResource(
getTestContext().getResources(), R.drawable.icon2));
@@ -4129,9 +4130,9 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertEquals(2, mManager.getRemainingCallCount());
});
- mRunningUsers.put(USER_10, true);
+ mRunningUsers.put(USER_11, true);
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
final Icon icon1 = Icon.createWithResource(getTestContext(), R.drawable.black_64x64);
final Icon icon2 = Icon.createWithBitmap(BitmapFactory.decodeResource(
getTestContext().getResources(), R.drawable.icon2));
@@ -4162,14 +4163,14 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
// Save and corrupt the primary files.
mService.saveDirtyInfo();
try (Writer os = new FileWriter(
- mService.getUserFile(UserHandle.USER_SYSTEM).getBaseFile())) {
+ mService.getUserFile(USER_10).getBaseFile())) {
os.write("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
+ "<user locales=\"en\" last-app-scan-time2=\"14400000");
}
- try (Writer os = new FileWriter(mService.getUserFile(USER_10).getBaseFile())) {
+ try (Writer os = new FileWriter(mService.getUserFile(USER_11).getBaseFile())) {
os.write("<?xml version='1.0' encoding='utf");
}
- ShortcutPackage sp = mService.getUserShortcutsLocked(USER_0).getPackageShortcutsIfExists(
+ ShortcutPackage sp = mService.getUserShortcutsLocked(USER_10).getPackageShortcutsIfExists(
CALLING_PACKAGE_1);
try (Writer os = new FileWriter(sp.getShortcutPackageItemFile().getPath())) {
os.write("<?xml version='1.0' encoding='utf");
@@ -4182,12 +4183,12 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertEquals(0, mService.getShortcutsForTest().size());
// this will pre-load the per-user info.
- mService.handleUnlockUser(UserHandle.USER_SYSTEM);
+ mService.handleUnlockUser(USER_10);
// Now it's loaded.
assertEquals(1, mService.getShortcutsForTest().size());
- runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertShortcutIds(assertAllDynamic(assertAllHaveIntents(assertAllHaveIcon(
mManager.getDynamicShortcuts()))), "s1", "s2");
assertEquals(2, mManager.getRemainingCallCount());
@@ -4195,7 +4196,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertEquals("title1-1", getCallerShortcut("s1").getTitle());
assertEquals("title1-2", getCallerShortcut("s2").getTitle());
});
- runWithCaller(CALLING_PACKAGE_2, UserHandle.USER_SYSTEM, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
assertShortcutIds(assertAllDynamic(assertAllHaveIntents(assertAllHaveIcon(
mManager.getDynamicShortcuts()))), "s1", "s2");
assertEquals(2, mManager.getRemainingCallCount());
@@ -4205,12 +4206,12 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
// Start another user
- mService.handleUnlockUser(USER_10);
+ mService.handleUnlockUser(USER_11);
// Now the size is 2.
assertEquals(2, mService.getShortcutsForTest().size());
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
assertShortcutIds(assertAllDynamic(assertAllHaveIntents(assertAllHaveIcon(
mManager.getDynamicShortcuts()))), "s1", "s2");
assertEquals(2, mManager.getRemainingCallCount());
@@ -4220,7 +4221,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
// Try stopping the user
- mService.handleStopUser(USER_10);
+ mService.handleStopUser(USER_11);
// Now it's unloaded.
assertEquals(1, mService.getShortcutsForTest().size());
@@ -4229,72 +4230,72 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
}
public void CleanupPackage() {
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s0_1"))));
});
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s0_2"))));
});
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s0_1"),
- HANDLE_USER_0);
+ HANDLE_USER_10);
mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list("s0_2"),
- HANDLE_USER_0);
+ HANDLE_USER_10);
});
- runWithCaller(LAUNCHER_2, USER_0, () -> {
+ runWithCaller(LAUNCHER_2, USER_10, () -> {
mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s0_1"),
- HANDLE_USER_0);
+ HANDLE_USER_10);
mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list("s0_2"),
- HANDLE_USER_0);
+ HANDLE_USER_10);
});
- mRunningUsers.put(USER_10, true);
+ mRunningUsers.put(USER_11, true);
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s10_1"))));
});
- runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_11, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s10_2"))));
});
- runWithCaller(LAUNCHER_1, USER_10, () -> {
+ runWithCaller(LAUNCHER_1, USER_11, () -> {
mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s10_1"),
- HANDLE_USER_10);
+ HANDLE_USER_11);
mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list("s10_2"),
- HANDLE_USER_10);
+ HANDLE_USER_11);
});
- runWithCaller(LAUNCHER_2, USER_10, () -> {
+ runWithCaller(LAUNCHER_2, USER_11, () -> {
mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s10_1"),
- HANDLE_USER_10);
+ HANDLE_USER_11);
mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list("s10_2"),
- HANDLE_USER_10);
+ HANDLE_USER_11);
});
// Remove all dynamic shortcuts; now all shortcuts are just pinned.
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
mManager.removeAllDynamicShortcuts();
});
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
mManager.removeAllDynamicShortcuts();
});
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
mManager.removeAllDynamicShortcuts();
});
- runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_11, () -> {
mManager.removeAllDynamicShortcuts();
});
final SparseArray<ShortcutUser> users = mService.getShortcutsForTest();
assertEquals(2, users.size());
- assertEquals(USER_0, users.keyAt(0));
- assertEquals(USER_10, users.keyAt(1));
+ assertEquals(USER_10, users.keyAt(0));
+ assertEquals(USER_11, users.keyAt(1));
- final ShortcutUser user0 = users.get(USER_0);
- final ShortcutUser user10 = users.get(USER_10);
+ final ShortcutUser user0 = users.get(USER_10);
+ final ShortcutUser user10 = users.get(USER_11);
// Check the registered packages.
@@ -4304,31 +4305,31 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertEquals(set(CALLING_PACKAGE_1, CALLING_PACKAGE_2),
hashSet(user10.getAllPackagesForTest().keySet()));
assertEquals(
- set(UserPackage.of(USER_0, LAUNCHER_1),
- UserPackage.of(USER_0, LAUNCHER_2)),
- hashSet(user0.getAllLaunchersForTest().keySet()));
- assertEquals(
set(UserPackage.of(USER_10, LAUNCHER_1),
UserPackage.of(USER_10, LAUNCHER_2)),
+ hashSet(user0.getAllLaunchersForTest().keySet()));
+ assertEquals(
+ set(UserPackage.of(USER_11, LAUNCHER_1),
+ UserPackage.of(USER_11, LAUNCHER_2)),
hashSet(user10.getAllLaunchersForTest().keySet()));
- assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_1, USER_0),
+ assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_1, USER_10),
"s0_1", "s0_2");
- assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_2, USER_0),
+ assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_2, USER_10),
"s0_1", "s0_2");
- assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_1, USER_10),
+ assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_1, USER_11),
"s10_1", "s10_2");
- assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_2, USER_10),
+ assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_2, USER_11),
"s10_1", "s10_2");
- assertShortcutExists(CALLING_PACKAGE_1, "s0_1", USER_0);
- assertShortcutExists(CALLING_PACKAGE_2, "s0_2", USER_0);
- assertShortcutExists(CALLING_PACKAGE_1, "s10_1", USER_10);
- assertShortcutExists(CALLING_PACKAGE_2, "s10_2", USER_10);
+ assertShortcutExists(CALLING_PACKAGE_1, "s0_1", USER_10);
+ assertShortcutExists(CALLING_PACKAGE_2, "s0_2", USER_10);
+ assertShortcutExists(CALLING_PACKAGE_1, "s10_1", USER_11);
+ assertShortcutExists(CALLING_PACKAGE_2, "s10_2", USER_11);
mService.saveDirtyInfo();
// Nonexistent package.
- uninstallPackage(USER_0, "abc");
- mService.cleanUpPackageLocked("abc", USER_0, USER_0, /* appStillExists = */ false);
+ uninstallPackage(USER_10, "abc");
+ mService.cleanUpPackageLocked("abc", USER_10, USER_10, /* appStillExists = */ false);
// No changes.
assertEquals(set(CALLING_PACKAGE_1, CALLING_PACKAGE_2),
@@ -4336,31 +4337,31 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertEquals(set(CALLING_PACKAGE_1, CALLING_PACKAGE_2),
hashSet(user10.getAllPackagesForTest().keySet()));
assertEquals(
- set(UserPackage.of(USER_0, LAUNCHER_1),
- UserPackage.of(USER_0, LAUNCHER_2)),
- hashSet(user0.getAllLaunchersForTest().keySet()));
- assertEquals(
set(UserPackage.of(USER_10, LAUNCHER_1),
UserPackage.of(USER_10, LAUNCHER_2)),
+ hashSet(user0.getAllLaunchersForTest().keySet()));
+ assertEquals(
+ set(UserPackage.of(USER_11, LAUNCHER_1),
+ UserPackage.of(USER_11, LAUNCHER_2)),
hashSet(user10.getAllLaunchersForTest().keySet()));
- assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_1, USER_0),
+ assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_1, USER_10),
"s0_1", "s0_2");
- assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_2, USER_0),
+ assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_2, USER_10),
"s0_1", "s0_2");
- assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_1, USER_10),
+ assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_1, USER_11),
"s10_1", "s10_2");
- assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_2, USER_10),
+ assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_2, USER_11),
"s10_1", "s10_2");
- assertShortcutExists(CALLING_PACKAGE_1, "s0_1", USER_0);
- assertShortcutExists(CALLING_PACKAGE_2, "s0_2", USER_0);
- assertShortcutExists(CALLING_PACKAGE_1, "s10_1", USER_10);
- assertShortcutExists(CALLING_PACKAGE_2, "s10_2", USER_10);
+ assertShortcutExists(CALLING_PACKAGE_1, "s0_1", USER_10);
+ assertShortcutExists(CALLING_PACKAGE_2, "s0_2", USER_10);
+ assertShortcutExists(CALLING_PACKAGE_1, "s10_1", USER_11);
+ assertShortcutExists(CALLING_PACKAGE_2, "s10_2", USER_11);
mService.saveDirtyInfo();
// Remove a package.
- uninstallPackage(USER_0, CALLING_PACKAGE_1);
- mService.cleanUpPackageLocked(CALLING_PACKAGE_1, USER_0, USER_0,
+ uninstallPackage(USER_10, CALLING_PACKAGE_1);
+ mService.cleanUpPackageLocked(CALLING_PACKAGE_1, USER_10, USER_10,
/* appStillExists = */ false);
assertEquals(set(CALLING_PACKAGE_2),
@@ -4368,59 +4369,59 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertEquals(set(CALLING_PACKAGE_1, CALLING_PACKAGE_2),
hashSet(user10.getAllPackagesForTest().keySet()));
assertEquals(
- set(UserPackage.of(USER_0, LAUNCHER_1),
- UserPackage.of(USER_0, LAUNCHER_2)),
- hashSet(user0.getAllLaunchersForTest().keySet()));
- assertEquals(
set(UserPackage.of(USER_10, LAUNCHER_1),
UserPackage.of(USER_10, LAUNCHER_2)),
+ hashSet(user0.getAllLaunchersForTest().keySet()));
+ assertEquals(
+ set(UserPackage.of(USER_11, LAUNCHER_1),
+ UserPackage.of(USER_11, LAUNCHER_2)),
hashSet(user10.getAllLaunchersForTest().keySet()));
- assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_1, USER_0),
+ assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_1, USER_10),
"s0_2");
- assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_2, USER_0),
+ assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_2, USER_10),
"s0_2");
- assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_1, USER_10),
+ assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_1, USER_11),
"s10_1", "s10_2");
- assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_2, USER_10),
+ assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_2, USER_11),
"s10_1", "s10_2");
- assertShortcutNotExists(CALLING_PACKAGE_1, "s0_1", USER_0);
- assertShortcutExists(CALLING_PACKAGE_2, "s0_2", USER_0);
- assertShortcutExists(CALLING_PACKAGE_1, "s10_1", USER_10);
- assertShortcutExists(CALLING_PACKAGE_2, "s10_2", USER_10);
+ assertShortcutNotExists(CALLING_PACKAGE_1, "s0_1", USER_10);
+ assertShortcutExists(CALLING_PACKAGE_2, "s0_2", USER_10);
+ assertShortcutExists(CALLING_PACKAGE_1, "s10_1", USER_11);
+ assertShortcutExists(CALLING_PACKAGE_2, "s10_2", USER_11);
mService.saveDirtyInfo();
// Remove a launcher.
- uninstallPackage(USER_10, LAUNCHER_1);
- mService.cleanUpPackageLocked(LAUNCHER_1, USER_10, USER_10, /* appStillExists = */ false);
+ uninstallPackage(USER_11, LAUNCHER_1);
+ mService.cleanUpPackageLocked(LAUNCHER_1, USER_11, USER_11, /* appStillExists = */ false);
assertEquals(set(CALLING_PACKAGE_2),
hashSet(user0.getAllPackagesForTest().keySet()));
assertEquals(set(CALLING_PACKAGE_1, CALLING_PACKAGE_2),
hashSet(user10.getAllPackagesForTest().keySet()));
assertEquals(
- set(UserPackage.of(USER_0, LAUNCHER_1),
- UserPackage.of(USER_0, LAUNCHER_2)),
+ set(UserPackage.of(USER_10, LAUNCHER_1),
+ UserPackage.of(USER_10, LAUNCHER_2)),
hashSet(user0.getAllLaunchersForTest().keySet()));
assertEquals(
- set(UserPackage.of(USER_10, LAUNCHER_2)),
+ set(UserPackage.of(USER_11, LAUNCHER_2)),
hashSet(user10.getAllLaunchersForTest().keySet()));
- assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_1, USER_0),
- "s0_2");
- assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_2, USER_0),
+ assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_1, USER_10),
"s0_2");
assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_2, USER_10),
+ "s0_2");
+ assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_2, USER_11),
"s10_1", "s10_2");
- assertShortcutNotExists(CALLING_PACKAGE_1, "s0_1", USER_0);
- assertShortcutExists(CALLING_PACKAGE_2, "s0_2", USER_0);
- assertShortcutExists(CALLING_PACKAGE_1, "s10_1", USER_10);
- assertShortcutExists(CALLING_PACKAGE_2, "s10_2", USER_10);
+ assertShortcutNotExists(CALLING_PACKAGE_1, "s0_1", USER_10);
+ assertShortcutExists(CALLING_PACKAGE_2, "s0_2", USER_10);
+ assertShortcutExists(CALLING_PACKAGE_1, "s10_1", USER_11);
+ assertShortcutExists(CALLING_PACKAGE_2, "s10_2", USER_11);
mService.saveDirtyInfo();
// Remove a package.
- uninstallPackage(USER_10, CALLING_PACKAGE_2);
- mService.cleanUpPackageLocked(CALLING_PACKAGE_2, USER_10, USER_10,
+ uninstallPackage(USER_11, CALLING_PACKAGE_2);
+ mService.cleanUpPackageLocked(CALLING_PACKAGE_2, USER_11, USER_11,
/* appStillExists = */ false);
assertEquals(set(CALLING_PACKAGE_2),
@@ -4428,28 +4429,28 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertEquals(set(CALLING_PACKAGE_1),
hashSet(user10.getAllPackagesForTest().keySet()));
assertEquals(
- set(UserPackage.of(USER_0, LAUNCHER_1),
- UserPackage.of(USER_0, LAUNCHER_2)),
+ set(UserPackage.of(USER_10, LAUNCHER_1),
+ UserPackage.of(USER_10, LAUNCHER_2)),
hashSet(user0.getAllLaunchersForTest().keySet()));
assertEquals(
- set(UserPackage.of(USER_10, LAUNCHER_2)),
+ set(UserPackage.of(USER_11, LAUNCHER_2)),
hashSet(user10.getAllLaunchersForTest().keySet()));
- assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_1, USER_0),
- "s0_2");
- assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_2, USER_0),
+ assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_1, USER_10),
"s0_2");
assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_2, USER_10),
+ "s0_2");
+ assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_2, USER_11),
"s10_1");
- assertShortcutNotExists(CALLING_PACKAGE_1, "s0_1", USER_0);
- assertShortcutExists(CALLING_PACKAGE_2, "s0_2", USER_0);
- assertShortcutExists(CALLING_PACKAGE_1, "s10_1", USER_10);
- assertShortcutNotExists(CALLING_PACKAGE_2, "s10_2", USER_10);
+ assertShortcutNotExists(CALLING_PACKAGE_1, "s0_1", USER_10);
+ assertShortcutExists(CALLING_PACKAGE_2, "s0_2", USER_10);
+ assertShortcutExists(CALLING_PACKAGE_1, "s10_1", USER_11);
+ assertShortcutNotExists(CALLING_PACKAGE_2, "s10_2", USER_11);
mService.saveDirtyInfo();
// Remove the other launcher from user 10 too.
- uninstallPackage(USER_10, LAUNCHER_2);
- mService.cleanUpPackageLocked(LAUNCHER_2, USER_10, USER_10,
+ uninstallPackage(USER_11, LAUNCHER_2);
+ mService.cleanUpPackageLocked(LAUNCHER_2, USER_11, USER_11,
/* appStillExists = */ false);
assertEquals(set(CALLING_PACKAGE_2),
@@ -4457,28 +4458,28 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertEquals(set(CALLING_PACKAGE_1),
hashSet(user10.getAllPackagesForTest().keySet()));
assertEquals(
- set(UserPackage.of(USER_0, LAUNCHER_1),
- UserPackage.of(USER_0, LAUNCHER_2)),
+ set(UserPackage.of(USER_10, LAUNCHER_1),
+ UserPackage.of(USER_10, LAUNCHER_2)),
hashSet(user0.getAllLaunchersForTest().keySet()));
assertEquals(
set(),
hashSet(user10.getAllLaunchersForTest().keySet()));
- assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_1, USER_0),
+ assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_1, USER_10),
"s0_2");
- assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_2, USER_0),
+ assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_2, USER_10),
"s0_2");
// Note the pinned shortcuts on user-10 no longer referred, so they should both be removed.
- assertShortcutNotExists(CALLING_PACKAGE_1, "s0_1", USER_0);
- assertShortcutExists(CALLING_PACKAGE_2, "s0_2", USER_0);
- assertShortcutNotExists(CALLING_PACKAGE_1, "s10_1", USER_10);
- assertShortcutNotExists(CALLING_PACKAGE_2, "s10_2", USER_10);
+ assertShortcutNotExists(CALLING_PACKAGE_1, "s0_1", USER_10);
+ assertShortcutExists(CALLING_PACKAGE_2, "s0_2", USER_10);
+ assertShortcutNotExists(CALLING_PACKAGE_1, "s10_1", USER_11);
+ assertShortcutNotExists(CALLING_PACKAGE_2, "s10_2", USER_11);
mService.saveDirtyInfo();
// More remove.
- uninstallPackage(USER_10, CALLING_PACKAGE_1);
- mService.cleanUpPackageLocked(CALLING_PACKAGE_1, USER_10, USER_10,
+ uninstallPackage(USER_11, CALLING_PACKAGE_1);
+ mService.cleanUpPackageLocked(CALLING_PACKAGE_1, USER_11, USER_11,
/* appStillExists = */ false);
assertEquals(set(CALLING_PACKAGE_2),
@@ -4486,21 +4487,21 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertEquals(set(),
hashSet(user10.getAllPackagesForTest().keySet()));
assertEquals(
- set(UserPackage.of(USER_0, LAUNCHER_1),
- UserPackage.of(USER_0, LAUNCHER_2)),
+ set(UserPackage.of(USER_10, LAUNCHER_1),
+ UserPackage.of(USER_10, LAUNCHER_2)),
hashSet(user0.getAllLaunchersForTest().keySet()));
assertEquals(set(),
hashSet(user10.getAllLaunchersForTest().keySet()));
- assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_1, USER_0),
+ assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_1, USER_10),
"s0_2");
- assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_2, USER_0),
+ assertShortcutIds(getLauncherPinnedShortcuts(LAUNCHER_2, USER_10),
"s0_2");
// Note the pinned shortcuts on user-10 no longer referred, so they should both be removed.
- assertShortcutNotExists(CALLING_PACKAGE_1, "s0_1", USER_0);
- assertShortcutExists(CALLING_PACKAGE_2, "s0_2", USER_0);
- assertShortcutNotExists(CALLING_PACKAGE_1, "s10_1", USER_10);
- assertShortcutNotExists(CALLING_PACKAGE_2, "s10_2", USER_10);
+ assertShortcutNotExists(CALLING_PACKAGE_1, "s0_1", USER_10);
+ assertShortcutExists(CALLING_PACKAGE_2, "s0_2", USER_10);
+ assertShortcutNotExists(CALLING_PACKAGE_1, "s10_1", USER_11);
+ assertShortcutNotExists(CALLING_PACKAGE_2, "s10_2", USER_11);
mService.saveDirtyInfo();
}
@@ -4511,15 +4512,15 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
R.xml.shortcut_2);
updatePackageVersion(CALLING_PACKAGE_1, 1);
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
});
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
- list("s2", "s3", "ms1", "ms2"), HANDLE_USER_0);
+ list("s2", "s3", "ms1", "ms2"), HANDLE_USER_10);
});
// Remove ms2 from manifest.
@@ -4528,9 +4529,9 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
R.xml.shortcut_1);
updatePackageVersion(CALLING_PACKAGE_1, 1);
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s1"), makeShortcut("s2"))));
@@ -4564,9 +4565,9 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
// Clean up + re-publish manifests.
- mService.cleanUpPackageLocked(CALLING_PACKAGE_1, USER_0, USER_0,
+ mService.cleanUpPackageLocked(CALLING_PACKAGE_1, USER_10, USER_10,
/* appStillExists = */ true);
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertWith(getCallerShortcuts())
.haveIds("ms1")
.areAllManifest();
@@ -4575,7 +4576,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
public void HandleGonePackage_crossProfile() {
// Create some shortcuts.
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
});
@@ -4583,253 +4584,253 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
});
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
});
- mRunningUsers.put(USER_10, true);
+ mRunningUsers.put(USER_11, true);
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
});
- assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_0));
- assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_0));
- assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_0));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_10));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_10));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_10));
assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_P0));
assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_P0));
assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_P0));
- assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s1", USER_0));
- assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s2", USER_0));
- assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s3", USER_0));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s1", USER_10));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s2", USER_10));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s3", USER_10));
- assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_10));
- assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_10));
- assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_10));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_11));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_11));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_11));
// Pin some.
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
- list("s1"), HANDLE_USER_0);
+ list("s1"), HANDLE_USER_10);
mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
list("s2"), UserHandle.of(USER_P0));
mLauncherApps.pinShortcuts(CALLING_PACKAGE_2,
- list("s3"), HANDLE_USER_0);
+ list("s3"), HANDLE_USER_10);
});
runWithCaller(LAUNCHER_1, USER_P0, () -> {
mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
- list("s2"), HANDLE_USER_0);
+ list("s2"), HANDLE_USER_10);
mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
list("s3"), UserHandle.of(USER_P0));
mLauncherApps.pinShortcuts(CALLING_PACKAGE_2,
- list("s1"), HANDLE_USER_0);
+ list("s1"), HANDLE_USER_10);
});
- runWithCaller(LAUNCHER_1, USER_10, () -> {
+ runWithCaller(LAUNCHER_1, USER_11, () -> {
mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
- list("s3"), HANDLE_USER_10);
+ list("s3"), HANDLE_USER_11);
});
// Check the state.
- assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_0));
- assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_0));
- assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_0));
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_10));
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_10));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_10));
assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_P0));
assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_P0));
assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_P0));
- assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_2, "s1", USER_0));
- assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s2", USER_0));
- assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_2, "s3", USER_0));
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_2, "s1", USER_10));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s2", USER_10));
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_2, "s3", USER_10));
- assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_10));
- assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_10));
- assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_10));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_11));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_11));
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_11));
// Make sure all the information is persisted.
mService.saveDirtyInfo();
initService();
- mService.handleUnlockUser(USER_0);
- mService.handleUnlockUser(USER_P0);
mService.handleUnlockUser(USER_10);
+ mService.handleUnlockUser(USER_P0);
+ mService.handleUnlockUser(USER_11);
- assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_0));
- assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_0));
- assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_0));
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_10));
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_10));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_10));
assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_P0));
assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_P0));
assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_P0));
- assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_2, "s1", USER_0));
- assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s2", USER_0));
- assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_2, "s3", USER_0));
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_2, "s1", USER_10));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s2", USER_10));
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_2, "s3", USER_10));
- assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_10));
- assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_10));
- assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_10));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_11));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_11));
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_11));
// Start uninstalling.
- uninstallPackage(USER_10, LAUNCHER_1);
- mService.checkPackageChanges(USER_10);
+ uninstallPackage(USER_11, LAUNCHER_1);
+ mService.checkPackageChanges(USER_11);
- assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_0));
- assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_0));
- assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_0));
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_10));
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_10));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_10));
assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_P0));
assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_P0));
assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_P0));
- assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_2, "s1", USER_0));
- assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s2", USER_0));
- assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_2, "s3", USER_0));
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_2, "s1", USER_10));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s2", USER_10));
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_2, "s3", USER_10));
- assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_10));
- assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_10));
- assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_10));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_11));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_11));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_11));
// Uninstall.
- uninstallPackage(USER_10, CALLING_PACKAGE_1);
- mService.checkPackageChanges(USER_10);
+ uninstallPackage(USER_11, CALLING_PACKAGE_1);
+ mService.checkPackageChanges(USER_11);
- assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_0));
- assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_0));
- assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_0));
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_10));
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_10));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_10));
assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_P0));
assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_P0));
assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_P0));
- assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_2, "s1", USER_0));
- assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s2", USER_0));
- assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_2, "s3", USER_0));
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_2, "s1", USER_10));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s2", USER_10));
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_2, "s3", USER_10));
- assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_10));
- assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_10));
- assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_10));
+ assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_11));
+ assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_11));
+ assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_11));
uninstallPackage(USER_P0, LAUNCHER_1);
- mService.checkPackageChanges(USER_0);
+ mService.checkPackageChanges(USER_10);
- assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_0));
- assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_0));
- assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_0));
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_10));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_10));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_10));
assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_P0));
assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_P0));
assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_P0));
- assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s1", USER_0));
- assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s2", USER_0));
- assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_2, "s3", USER_0));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s1", USER_10));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s2", USER_10));
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_2, "s3", USER_10));
- assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_10));
- assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_10));
- assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_10));
+ assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_11));
+ assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_11));
+ assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_11));
mService.checkPackageChanges(USER_P0);
- assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_0));
- assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_0));
- assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_0));
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_10));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_10));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_10));
assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_P0));
assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_P0));
assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_P0));
- assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s1", USER_0));
- assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s2", USER_0));
- assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_2, "s3", USER_0));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s1", USER_10));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s2", USER_10));
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_2, "s3", USER_10));
- assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_10));
- assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_10));
- assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_10));
+ assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_11));
+ assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_11));
+ assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_11));
uninstallPackage(USER_P0, CALLING_PACKAGE_1);
mService.saveDirtyInfo();
initService();
- mService.handleUnlockUser(USER_0);
- mService.handleUnlockUser(USER_P0);
mService.handleUnlockUser(USER_10);
+ mService.handleUnlockUser(USER_P0);
+ mService.handleUnlockUser(USER_11);
- assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_0));
- assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_0));
- assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_0));
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_10));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_10));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_10));
assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_P0));
assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_P0));
assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_P0));
- assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s1", USER_0));
- assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s2", USER_0));
- assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_2, "s3", USER_0));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s1", USER_10));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s2", USER_10));
+ assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_2, "s3", USER_10));
- assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_10));
- assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_10));
- assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_10));
+ assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_11));
+ assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_11));
+ assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_11));
// Uninstall
- uninstallPackage(USER_0, LAUNCHER_1);
+ uninstallPackage(USER_10, LAUNCHER_1);
mService.saveDirtyInfo();
initService();
- mService.handleUnlockUser(USER_0);
- mService.handleUnlockUser(USER_P0);
mService.handleUnlockUser(USER_10);
+ mService.handleUnlockUser(USER_P0);
+ mService.handleUnlockUser(USER_11);
- assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_0));
- assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_0));
- assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_0));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_10));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_10));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_10));
assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_P0));
assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_P0));
assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_P0));
- assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s1", USER_0));
- assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s2", USER_0));
- assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s3", USER_0));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s1", USER_10));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s2", USER_10));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_2, "s3", USER_10));
- assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_10));
- assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_10));
- assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_10));
+ assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_11));
+ assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_11));
+ assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_11));
- uninstallPackage(USER_0, CALLING_PACKAGE_2);
+ uninstallPackage(USER_10, CALLING_PACKAGE_2);
mService.saveDirtyInfo();
initService();
- mService.handleUnlockUser(USER_0);
- mService.handleUnlockUser(USER_P0);
mService.handleUnlockUser(USER_10);
+ mService.handleUnlockUser(USER_P0);
+ mService.handleUnlockUser(USER_11);
- assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_0));
- assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_0));
- assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_0));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_10));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_10));
+ assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_10));
assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_P0));
assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_P0));
assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_P0));
- assertNull(getPackageShortcut(CALLING_PACKAGE_2, "s1", USER_0));
- assertNull(getPackageShortcut(CALLING_PACKAGE_2, "s2", USER_0));
- assertNull(getPackageShortcut(CALLING_PACKAGE_2, "s3", USER_0));
+ assertNull(getPackageShortcut(CALLING_PACKAGE_2, "s1", USER_10));
+ assertNull(getPackageShortcut(CALLING_PACKAGE_2, "s2", USER_10));
+ assertNull(getPackageShortcut(CALLING_PACKAGE_2, "s3", USER_10));
- assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_10));
- assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_10));
- assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_10));
+ assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_11));
+ assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_11));
+ assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_11));
}
protected void checkCanRestoreTo(int expected, ShortcutPackageInfo spi,
@@ -4854,11 +4855,11 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
pi -> pi.applicationInfo.flags &= ~ApplicationInfo.FLAG_ALLOW_BACKUP);
final ShortcutPackageInfo spi1 = ShortcutPackageInfo.generateForInstalledPackageForTest(
- mService, CALLING_PACKAGE_1, USER_0);
+ mService, CALLING_PACKAGE_1, USER_10);
final ShortcutPackageInfo spi2 = ShortcutPackageInfo.generateForInstalledPackageForTest(
- mService, CALLING_PACKAGE_2, USER_0);
+ mService, CALLING_PACKAGE_2, USER_10);
final ShortcutPackageInfo spi3 = ShortcutPackageInfo.generateForInstalledPackageForTest(
- mService, CALLING_PACKAGE_3, USER_0);
+ mService, CALLING_PACKAGE_3, USER_10);
checkCanRestoreTo(DISABLED_REASON_NOT_DISABLED, spi1, false, 10, true, "sig1");
checkCanRestoreTo(DISABLED_REASON_NOT_DISABLED, spi1, false, 10, true, "x", "sig1");
@@ -4927,7 +4928,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
private void checkHandlePackageDeleteInner(BiConsumer<Integer, String> remover) {
final Icon bmp32x32 = Icon.createWithBitmap(BitmapFactory.decodeResource(
getTestContext().getResources(), R.drawable.black_32x32));
- setCaller(CALLING_PACKAGE_1, USER_0);
+ setCaller(CALLING_PACKAGE_1, USER_10);
assertTrue(mManager.addDynamicShortcuts(list(
makeShortcutWithIcon("s1", bmp32x32), makeShortcutWithIcon("s2", bmp32x32)
)));
@@ -4937,8 +4938,8 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
R.xml.shortcut_1);
updatePackageVersion(CALLING_PACKAGE_1, 1);
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertWith(getCallerShortcuts())
.haveIds("s1", "s2", "ms1")
@@ -4946,187 +4947,187 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
.haveIds("ms1");
});
- setCaller(CALLING_PACKAGE_2, USER_0);
+ setCaller(CALLING_PACKAGE_2, USER_10);
assertTrue(mManager.addDynamicShortcuts(list(makeShortcutWithIcon("s1", bmp32x32))));
- setCaller(CALLING_PACKAGE_3, USER_0);
+ setCaller(CALLING_PACKAGE_3, USER_10);
assertTrue(mManager.addDynamicShortcuts(list(makeShortcutWithIcon("s1", bmp32x32))));
- mRunningUsers.put(USER_10, true);
+ mRunningUsers.put(USER_11, true);
- setCaller(CALLING_PACKAGE_1, USER_10);
+ setCaller(CALLING_PACKAGE_1, USER_11);
assertTrue(mManager.addDynamicShortcuts(list(makeShortcutWithIcon("s1", bmp32x32))));
- setCaller(CALLING_PACKAGE_2, USER_10);
+ setCaller(CALLING_PACKAGE_2, USER_11);
assertTrue(mManager.addDynamicShortcuts(list(makeShortcutWithIcon("s1", bmp32x32))));
- setCaller(CALLING_PACKAGE_3, USER_10);
+ setCaller(CALLING_PACKAGE_3, USER_11);
assertTrue(mManager.addDynamicShortcuts(list(makeShortcutWithIcon("s1", bmp32x32))));
- assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_0));
- assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_0));
- assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_0));
assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_10));
assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_10));
assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_10));
+ assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_11));
+ assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_11));
+ assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_11));
- assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_0));
- assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_0));
- assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_0));
assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_10));
assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_10));
assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_10));
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_11));
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_11));
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_11));
- remover.accept(USER_0, CALLING_PACKAGE_1);
+ remover.accept(USER_10, CALLING_PACKAGE_1);
- assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_0));
- assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_0));
- assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_0));
- assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_10));
+ assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_10));
assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_10));
assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_10));
+ assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_11));
+ assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_11));
+ assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_11));
- assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_0));
- assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_0));
- assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_0));
- assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_10));
+ assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_10));
assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_10));
assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_10));
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_11));
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_11));
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_11));
- mRunningUsers.put(USER_10, true);
+ mRunningUsers.put(USER_11, true);
- remover.accept(USER_10, CALLING_PACKAGE_2);
+ remover.accept(USER_11, CALLING_PACKAGE_2);
- assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_0));
- assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_0));
- assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_0));
- assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_10));
- assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_10));
+ assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_10));
+ assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_10));
assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_10));
+ assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_11));
+ assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_11));
+ assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_11));
- assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_0));
- assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_0));
- assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_0));
- assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_10));
- assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_10));
+ assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_10));
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_10));
assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_10));
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_11));
+ assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_11));
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_11));
mInjectedPackages.remove(CALLING_PACKAGE_1);
mInjectedPackages.remove(CALLING_PACKAGE_3);
- mService.checkPackageChanges(USER_0);
+ mService.checkPackageChanges(USER_10);
- assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_0));
- assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_0));
- assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_0)); // ---------------
- assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_10));
- assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_10));
- assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_10));
+ assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_10));
+ assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_10));
+ assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_10)); // ---------------
+ assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_11));
+ assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_11));
+ assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_11));
- assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_0));
- assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_0));
- assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_0));
- assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_10));
- assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_10));
- assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_10));
+ assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_10));
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_10));
+ assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_10));
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_11));
+ assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_11));
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_11));
- mService.checkPackageChanges(USER_10);
+ mService.checkPackageChanges(USER_11);
- assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_0));
- assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_0));
- assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_0));
assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_10));
- assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_10));
+ assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_10));
assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_10));
+ assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_11));
+ assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_11));
+ assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_11));
- assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_0));
- assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_0));
- assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_0));
assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_10));
- assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_10));
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_10));
assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_10));
+ assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_11));
+ assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_11));
+ assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_11));
}
/** Almost ame as testHandlePackageDelete, except it doesn't uninstall packages. */
public void HandlePackageClearData() {
final Icon bmp32x32 = Icon.createWithBitmap(BitmapFactory.decodeResource(
getTestContext().getResources(), R.drawable.black_32x32));
- setCaller(CALLING_PACKAGE_1, USER_0);
+ setCaller(CALLING_PACKAGE_1, USER_10);
assertTrue(mManager.addDynamicShortcuts(list(
makeShortcutWithIcon("s1", bmp32x32), makeShortcutWithIcon("s2", bmp32x32)
)));
- setCaller(CALLING_PACKAGE_2, USER_0);
+ setCaller(CALLING_PACKAGE_2, USER_10);
assertTrue(mManager.addDynamicShortcuts(list(makeShortcutWithIcon("s1", bmp32x32))));
- setCaller(CALLING_PACKAGE_3, USER_0);
+ setCaller(CALLING_PACKAGE_3, USER_10);
assertTrue(mManager.addDynamicShortcuts(list(makeShortcutWithIcon("s1", bmp32x32))));
- mRunningUsers.put(USER_10, true);
+ mRunningUsers.put(USER_11, true);
- setCaller(CALLING_PACKAGE_1, USER_10);
+ setCaller(CALLING_PACKAGE_1, USER_11);
assertTrue(mManager.addDynamicShortcuts(list(makeShortcutWithIcon("s1", bmp32x32))));
- setCaller(CALLING_PACKAGE_2, USER_10);
+ setCaller(CALLING_PACKAGE_2, USER_11);
assertTrue(mManager.addDynamicShortcuts(list(makeShortcutWithIcon("s1", bmp32x32))));
- setCaller(CALLING_PACKAGE_3, USER_10);
+ setCaller(CALLING_PACKAGE_3, USER_11);
assertTrue(mManager.addDynamicShortcuts(list(makeShortcutWithIcon("s1", bmp32x32))));
- assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_0));
- assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_0));
- assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_0));
assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_10));
assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_10));
assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_10));
+ assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_11));
+ assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_11));
+ assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_11));
- assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_0));
- assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_0));
- assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_0));
assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_10));
assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_10));
assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_10));
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_11));
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_11));
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_11));
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageDataClear(CALLING_PACKAGE_1, USER_0));
+ genPackageDataClear(CALLING_PACKAGE_1, USER_10));
- assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_0));
- assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_0));
- assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_0));
- assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_10));
+ assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_10));
assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_10));
assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_10));
+ assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_11));
+ assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_11));
+ assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_11));
- assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_0));
- assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_0));
- assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_0));
- assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_10));
+ assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_10));
assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_10));
assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_10));
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_11));
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_11));
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_11));
- mRunningUsers.put(USER_10, true);
+ mRunningUsers.put(USER_11, true);
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageDataClear(CALLING_PACKAGE_2, USER_10));
+ genPackageDataClear(CALLING_PACKAGE_2, USER_11));
- assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_0));
- assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_0));
- assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_0));
- assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_10));
- assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_10));
+ assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_10));
+ assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_10));
assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_10));
+ assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_11));
+ assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_11));
+ assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_3, "s1", USER_11));
- assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_0));
- assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_0));
- assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_0));
- assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_10));
- assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_10));
+ assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_10));
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_10));
assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_10));
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_1, USER_11));
+ assertFalse(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_11));
+ assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_11));
}
public void HandlePackageClearData_manifestRepublished() {
- mRunningUsers.put(USER_10, true);
+ mRunningUsers.put(USER_11, true);
// Add two manifests and two dynamics.
addManifestShortcutResource(
@@ -5134,17 +5135,17 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
R.xml.shortcut_2);
updatePackageVersion(CALLING_PACKAGE_1, 1);
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_11));
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
assertTrue(mManager.addDynamicShortcuts(list(
makeShortcut("s1"), makeShortcut("s2"))));
});
- runWithCaller(LAUNCHER_1, USER_10, () -> {
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("ms2", "s2"), HANDLE_USER_10);
+ runWithCaller(LAUNCHER_1, USER_11, () -> {
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("ms2", "s2"), HANDLE_USER_11);
});
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
assertWith(getCallerShortcuts())
.haveIds("ms1", "ms2", "s1", "s2")
.areAllEnabled()
@@ -5155,10 +5156,10 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
// Clear data
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageDataClear(CALLING_PACKAGE_1, USER_10));
+ genPackageDataClear(CALLING_PACKAGE_1, USER_11));
// Only manifest shortcuts will remain, and are no longer pinned.
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
assertWith(getCallerShortcuts())
.haveIds("ms1", "ms2")
.areAllEnabled()
@@ -5173,31 +5174,31 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
final Icon bmp32x32 = Icon.createWithBitmap(BitmapFactory.decodeResource(
getTestContext().getResources(), R.drawable.black_32x32));
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s1"),
makeShortcutWithIcon("s2", res32x32),
makeShortcutWithIcon("s3", res32x32),
makeShortcutWithIcon("s4", bmp32x32))));
});
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s1"),
makeShortcutWithIcon("s2", bmp32x32))));
});
- runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_3, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcutWithIcon("s1", res32x32))));
});
- mRunningUsers.put(USER_10, true);
+ mRunningUsers.put(USER_11, true);
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcutWithIcon("s1", res32x32),
makeShortcutWithIcon("s2", res32x32))));
});
- runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_11, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcutWithIcon("s1", bmp32x32),
makeShortcutWithIcon("s2", bmp32x32))));
@@ -5206,10 +5207,10 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
LauncherApps.Callback c0 = mock(LauncherApps.Callback.class);
LauncherApps.Callback c10 = mock(LauncherApps.Callback.class);
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mLauncherApps.registerCallback(c0, new Handler(Looper.getMainLooper()));
});
- runWithCaller(LAUNCHER_1, USER_10, () -> {
+ runWithCaller(LAUNCHER_1, USER_11, () -> {
mLauncherApps.registerCallback(c10, new Handler(Looper.getMainLooper()));
});
@@ -5224,7 +5225,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
// Then send the broadcast, to only user-0.
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageUpdateIntent(CALLING_PACKAGE_1, USER_0));
+ genPackageUpdateIntent(CALLING_PACKAGE_1, USER_10));
waitOnMainThread();
@@ -5233,7 +5234,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
verify(c0).onShortcutsChanged(
eq(CALLING_PACKAGE_1),
shortcuts.capture(),
- eq(HANDLE_USER_0));
+ eq(HANDLE_USER_10));
// User-10 shouldn't yet get the notification.
verify(c10, times(0)).onShortcutsChanged(
@@ -5254,14 +5255,14 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
// notification to the launcher.
mInjectedCurrentTimeMillis = START_TIME + 200;
- mRunningUsers.put(USER_10, true);
- mUnlockedUsers.put(USER_10, true);
+ mRunningUsers.put(USER_11, true);
+ mUnlockedUsers.put(USER_11, true);
reset(c0);
reset(c10);
setPackageLastUpdateTime(CALLING_PACKAGE_1, mInjectedCurrentTimeMillis);
- mService.handleUnlockUser(USER_10);
- mService.checkPackageChanges(USER_10);
+ mService.handleUnlockUser(USER_11);
+ mService.checkPackageChanges(USER_11);
waitOnMainThread();
@@ -5274,7 +5275,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
verify(c10).onShortcutsChanged(
eq(CALLING_PACKAGE_1),
shortcuts.capture(),
- eq(HANDLE_USER_10));
+ eq(HANDLE_USER_11));
assertShortcutIds(shortcuts.getValue(), "s1", "s2");
assertEquals(START_TIME + 200,
@@ -5292,7 +5293,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
// Then send the broadcast, to only user-0.
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageUpdateIntent(CALLING_PACKAGE_2, USER_0));
+ genPackageUpdateIntent(CALLING_PACKAGE_2, USER_10));
waitOnMainThread();
@@ -5315,8 +5316,8 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
// Then send the broadcast, to only user-0.
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageUpdateIntent(CALLING_PACKAGE_3, USER_0));
- mService.checkPackageChanges(USER_10);
+ genPackageUpdateIntent(CALLING_PACKAGE_3, USER_10));
+ mService.checkPackageChanges(USER_11);
waitOnMainThread();
@@ -5324,7 +5325,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
verify(c0).onShortcutsChanged(
eq(CALLING_PACKAGE_3),
shortcuts.capture(),
- eq(HANDLE_USER_0));
+ eq(HANDLE_USER_10));
// User 10 doesn't have package 3, so no callback.
verify(c10, times(0)).onShortcutsChanged(
@@ -5345,7 +5346,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
final Icon icon2 = Icon.createWithResource(getTestContext(), /* res ID */ 1001);
// Set up shortcuts.
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
// Note resource strings are not officially supported (they're hidden), but
// should work.
@@ -5371,7 +5372,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
// Verify.
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
final ShortcutInfo s1 = getCallerShortcut("s1");
final ShortcutInfo s2 = getCallerShortcut("s2");
@@ -5397,9 +5398,9 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
// Update the package.
updatePackageVersion(CALLING_PACKAGE_1, 1);
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageUpdateIntent(CALLING_PACKAGE_1, USER_0));
+ genPackageUpdateIntent(CALLING_PACKAGE_1, USER_10));
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
final ShortcutInfo s1 = getCallerShortcut("s1");
final ShortcutInfo s2 = getCallerShortcut("s2");
@@ -5422,20 +5423,20 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
mSystemPackages.add(CALLING_PACKAGE_1);
// Initial state: no shortcuts.
- mService.checkPackageChanges(USER_0);
+ mService.checkPackageChanges(USER_10);
assertEquals(mInjectedCurrentTimeMillis,
- mService.getUserShortcutsLocked(USER_0).getLastAppScanTime());
+ mService.getUserShortcutsLocked(USER_10).getLastAppScanTime());
assertEquals(mInjectedBuildFingerprint,
- mService.getUserShortcutsLocked(USER_0).getLastAppScanOsFingerprint());
+ mService.getUserShortcutsLocked(USER_10).getLastAppScanOsFingerprint());
// They have no shortcuts.
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertWith(getCallerShortcuts())
.isEmpty();
});
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
assertWith(getCallerShortcuts())
.isEmpty();
});
@@ -5451,13 +5452,13 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
new ComponentName(CALLING_PACKAGE_2, ShortcutActivity.class.getName()),
R.xml.shortcut_1);
mInjectedCurrentTimeMillis += 1000;
- mService.checkPackageChanges(USER_0);
+ mService.checkPackageChanges(USER_10);
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertWith(getCallerShortcuts())
.isEmpty();
});
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
assertWith(getCallerShortcuts())
.isEmpty();
});
@@ -5466,13 +5467,13 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
// Update the build finger print. All apps will be scanned now.
mInjectedBuildFingerprint = "update1";
mInjectedCurrentTimeMillis += 1000;
- mService.checkPackageChanges(USER_0);
+ mService.checkPackageChanges(USER_10);
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertWith(getCallerShortcuts())
.haveIds("ms1");
});
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
assertWith(getCallerShortcuts())
.haveIds("ms1");
});
@@ -5486,14 +5487,14 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
new ComponentName(CALLING_PACKAGE_2, ShortcutActivity.class.getName()),
R.xml.shortcut_2);
mInjectedCurrentTimeMillis += 1000;
- mService.checkPackageChanges(USER_0);
+ mService.checkPackageChanges(USER_10);
// Fingerprint hasn't changed, so there packages weren't scanned.
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertWith(getCallerShortcuts())
.haveIds("ms1");
});
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
assertWith(getCallerShortcuts())
.haveIds("ms1");
});
@@ -5502,13 +5503,13 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
// all apps anyway.
mInjectedBuildFingerprint = "update2";
mInjectedCurrentTimeMillis += 1000;
- mService.checkPackageChanges(USER_0);
+ mService.checkPackageChanges(USER_10);
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertWith(getCallerShortcuts())
.haveIds("ms1", "ms2");
});
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
assertWith(getCallerShortcuts())
.haveIds("ms1", "ms2");
});
@@ -5516,9 +5517,9 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
// Make sure getLastAppScanTime / getLastAppScanOsFingerprint are persisted.
initService();
assertEquals(mInjectedCurrentTimeMillis,
- mService.getUserShortcutsLocked(USER_0).getLastAppScanTime());
+ mService.getUserShortcutsLocked(USER_10).getLastAppScanTime());
assertEquals(mInjectedBuildFingerprint,
- mService.getUserShortcutsLocked(USER_0).getLastAppScanOsFingerprint());
+ mService.getUserShortcutsLocked(USER_10).getLastAppScanOsFingerprint());
}
public void HandlePackageChanged() {
@@ -5528,23 +5529,23 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
addManifestShortcutResource(ACTIVITY1, R.xml.shortcut_1);
addManifestShortcutResource(ACTIVITY2, R.xml.shortcut_1_alt);
- mRunningUsers.put(USER_10, true);
+ mRunningUsers.put(USER_11, true);
updatePackageVersion(CALLING_PACKAGE_1, 1);
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_11));
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
assertTrue(mManager.addDynamicShortcuts(list(
makeShortcutWithActivity("s1", ACTIVITY1),
makeShortcutWithActivity("s2", ACTIVITY2)
)));
});
- runWithCaller(LAUNCHER_1, USER_10, () -> {
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("ms1-alt", "s2"), HANDLE_USER_10);
+ runWithCaller(LAUNCHER_1, USER_11, () -> {
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("ms1-alt", "s2"), HANDLE_USER_11);
});
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
assertWith(getCallerShortcuts())
.haveIds("ms1", "ms1-alt", "s1", "s2")
.areAllEnabled()
@@ -5564,9 +5565,9 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
// First, no changes.
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageChangedIntent(CALLING_PACKAGE_1, USER_10));
+ genPackageChangedIntent(CALLING_PACKAGE_1, USER_11));
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
assertWith(getCallerShortcuts())
.haveIds("ms1", "ms1-alt", "s1", "s2")
.areAllEnabled()
@@ -5587,9 +5588,9 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
// Disable activity 1
mEnabledActivityChecker = (activity, userId) -> !ACTIVITY1.equals(activity);
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageChangedIntent(CALLING_PACKAGE_1, USER_10));
+ genPackageChangedIntent(CALLING_PACKAGE_1, USER_11));
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
assertWith(getCallerShortcuts())
.haveIds("ms1-alt", "s2")
.areAllEnabled()
@@ -5607,9 +5608,9 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
// Manifest shortcuts will be re-published, but dynamic ones are not.
mEnabledActivityChecker = (activity, userId) -> true;
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageChangedIntent(CALLING_PACKAGE_1, USER_10));
+ genPackageChangedIntent(CALLING_PACKAGE_1, USER_11));
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
assertWith(getCallerShortcuts())
.haveIds("ms1", "ms1-alt", "s2")
.areAllEnabled()
@@ -5631,9 +5632,9 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
// Because "ms1-alt" and "s2" are both pinned, they will remain, but disabled.
mEnabledActivityChecker = (activity, userId) -> !ACTIVITY2.equals(activity);
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageChangedIntent(CALLING_PACKAGE_1, USER_10));
+ genPackageChangedIntent(CALLING_PACKAGE_1, USER_11));
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
assertWith(getCallerShortcuts())
.haveIds("ms1", "ms1-alt", "s2")
@@ -5652,7 +5653,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
}
public void HandlePackageUpdate_activityNoLongerMain() throws Throwable {
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcutWithActivity("s1a",
new ComponentName(getCallingPackage(), "act1")),
@@ -5671,12 +5672,12 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
.haveIds("s1a", "s1b", "s2a", "s2b", "s3a", "s3b")
.areAllDynamic();
});
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
list("s1b", "s2b", "s3b"),
- HANDLE_USER_0);
+ HANDLE_USER_10);
});
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertWith(getCallerShortcuts())
.haveIds("s1a", "s1b", "s2a", "s2b", "s3a", "s3b")
.areAllDynamic()
@@ -5690,17 +5691,17 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
return activity.getClassName().equals("act1");
};
- setCaller(LAUNCHER_1, USER_0);
+ setCaller(LAUNCHER_1, USER_10);
assertForLauncherCallback(mLauncherApps, () -> {
updatePackageVersion(CALLING_PACKAGE_1, 1);
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageUpdateIntent(CALLING_PACKAGE_1, USER_0));
- }).assertCallbackCalledForPackageAndUser(CALLING_PACKAGE_1, HANDLE_USER_0)
+ genPackageUpdateIntent(CALLING_PACKAGE_1, USER_10));
+ }).assertCallbackCalledForPackageAndUser(CALLING_PACKAGE_1, HANDLE_USER_10)
// Make sure the launcher gets callbacks.
.haveIds("s1a", "s1b", "s2b", "s3b")
.areAllWithKeyFieldsOnly();
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
// s2a and s3a are gone, but s2b and s3b will remain because they're pinned, and
// disabled.
assertWith(getCallerShortcuts())
@@ -5800,24 +5801,24 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertEquals(0, userP0.getAllLaunchersForTest().size());
// Make sure only "allowBackup" apps are restored, and are shadow.
- final ShortcutUser user0 = mService.getUserShortcutsLocked(USER_0);
+ final ShortcutUser user0 = mService.getUserShortcutsLocked(USER_10);
assertExistsAndShadow(user0.getAllPackagesForTest().get(CALLING_PACKAGE_1));
assertExistsAndShadow(user0.getAllPackagesForTest().get(CALLING_PACKAGE_2));
assertExistsAndShadow(user0.getAllPackagesForTest().get(CALLING_PACKAGE_3));
assertExistsAndShadow(user0.getAllLaunchersForTest().get(
- UserPackage.of(USER_0, LAUNCHER_1)));
+ UserPackage.of(USER_10, LAUNCHER_1)));
assertExistsAndShadow(user0.getAllLaunchersForTest().get(
- UserPackage.of(USER_0, LAUNCHER_2)));
+ UserPackage.of(USER_10, LAUNCHER_2)));
- assertNull(user0.getAllLaunchersForTest().get(UserPackage.of(USER_0, LAUNCHER_3)));
+ assertNull(user0.getAllLaunchersForTest().get(UserPackage.of(USER_10, LAUNCHER_3)));
assertNull(user0.getAllLaunchersForTest().get(UserPackage.of(USER_P0, LAUNCHER_1)));
doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(any(byte[].class),
anyString());
- installPackage(USER_0, CALLING_PACKAGE_1);
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ installPackage(USER_10, CALLING_PACKAGE_1);
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertWith(getCallerVisibleShortcuts())
.selectDynamic()
.isEmpty()
@@ -5828,25 +5829,25 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
.areAllEnabled();
});
- installPackage(USER_0, LAUNCHER_1);
- runWithCaller(LAUNCHER_1, USER_0, () -> {
- assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
+ installPackage(USER_10, LAUNCHER_1);
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
+ assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_10))
.areAllPinned()
.haveIds("s1")
.areAllEnabled();
- assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
+ assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_10))
.isEmpty();
- assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
+ assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_10))
.isEmpty();
assertWith(mLauncherApps.getShortcuts(QUERY_ALL, HANDLE_USER_P0))
.isEmpty();
});
- installPackage(USER_0, CALLING_PACKAGE_2);
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ installPackage(USER_10, CALLING_PACKAGE_2);
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
assertWith(getCallerVisibleShortcuts())
.selectDynamic()
.isEmpty()
@@ -5857,18 +5858,18 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
.areAllEnabled();
});
- runWithCaller(LAUNCHER_1, USER_0, () -> {
- assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
+ assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_10))
.areAllPinned()
.haveIds("s1")
.areAllEnabled();
- assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
+ assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_10))
.areAllPinned()
.haveIds("s1", "s2")
.areAllEnabled();
- assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
+ assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_10))
.isEmpty();
assertWith(mLauncherApps.getShortcuts(QUERY_ALL, HANDLE_USER_P0))
@@ -5876,19 +5877,19 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
// 3 shouldn't be backed up, so no pinned shortcuts.
- installPackage(USER_0, CALLING_PACKAGE_3);
- runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
+ installPackage(USER_10, CALLING_PACKAGE_3);
+ runWithCaller(CALLING_PACKAGE_3, USER_10, () -> {
assertWith(getCallerVisibleShortcuts())
.isEmpty();
});
// Launcher on a different profile shouldn't be restored.
runWithCaller(LAUNCHER_1, USER_P0, () -> {
- assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
+ assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_10))
.isEmpty();
- assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
+ assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_10))
.isEmpty();
- assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
+ assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_10))
.isEmpty();
});
@@ -5900,21 +5901,21 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
// Restore launcher 2 on user 0.
- installPackage(USER_0, LAUNCHER_2);
- runWithCaller(LAUNCHER_2, USER_0, () -> {
- assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
+ installPackage(USER_10, LAUNCHER_2);
+ runWithCaller(LAUNCHER_2, USER_10, () -> {
+ assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_10))
.areAllPinned()
.haveIds("s2")
.areAllEnabled();
- assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
+ assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_10))
.areAllPinned()
.haveIds("s2", "s3")
.areAllEnabled();
if (firstRestore) {
assertWith(
- mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
+ mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_10))
.haveIds("s2", "s3", "s4")
.areAllDisabled()
.areAllPinned()
@@ -5923,7 +5924,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
ShortcutInfo.DISABLED_REASON_BACKUP_NOT_SUPPORTED);
} else {
assertWith(
- mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
+ mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_10))
.isEmpty();
}
@@ -5934,28 +5935,28 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
// Restoration of launcher2 shouldn't affect other packages; so do the same checks and
// make sure they still have the same result.
- installPackage(USER_0, CALLING_PACKAGE_1);
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ installPackage(USER_10, CALLING_PACKAGE_1);
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertWith(getCallerVisibleShortcuts())
.areAllPinned()
.haveIds("s1", "s2");
});
- installPackage(USER_0, LAUNCHER_1);
- runWithCaller(LAUNCHER_1, USER_0, () -> {
- assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
+ installPackage(USER_10, LAUNCHER_1);
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
+ assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_10))
.areAllPinned()
.haveIds("s1")
.areAllEnabled();
- assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
+ assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_10))
.areAllPinned()
.haveIds("s1", "s2")
.areAllEnabled();
if (firstRestore) {
assertWith(
- mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
+ mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_10))
.haveIds("s1", "s2", "s3")
.areAllDisabled()
.areAllPinned()
@@ -5963,7 +5964,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
.areAllWithDisabledReason(ShortcutInfo.DISABLED_REASON_BACKUP_NOT_SUPPORTED);
} else {
assertWith(
- mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
+ mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_10))
.isEmpty();
}
@@ -5971,8 +5972,8 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
.isEmpty();
});
- installPackage(USER_0, CALLING_PACKAGE_2);
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ installPackage(USER_10, CALLING_PACKAGE_2);
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
assertWith(getCallerVisibleShortcuts())
.areAllPinned()
.haveIds("s1", "s2", "s3")
@@ -6004,30 +6005,30 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
mMockPackageManagerInternal).isDataRestoreSafe(any(byte[].class),
eq(CALLING_PACKAGE_1));
- installPackage(USER_0, CALLING_PACKAGE_1);
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ installPackage(USER_10, CALLING_PACKAGE_1);
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertEquals(0, mManager.getDynamicShortcuts().size());
assertEquals(0, mManager.getPinnedShortcuts().size());
});
- assertFalse(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, USER_0)
+ assertFalse(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, USER_10)
.getPackageInfo().isShadow());
doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(
any(byte[].class), anyString());
- installPackage(USER_0, CALLING_PACKAGE_2);
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ installPackage(USER_10, CALLING_PACKAGE_2);
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
assertEquals(0, mManager.getDynamicShortcuts().size());
assertShortcutIds(assertAllPinned(
mManager.getPinnedShortcuts()),
"s1", "s2", "s3");
});
- assertFalse(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, USER_0)
+ assertFalse(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, USER_10)
.getPackageInfo().isShadow());
- installPackage(USER_0, LAUNCHER_1);
- runWithCaller(LAUNCHER_1, USER_0, () -> {
- assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
+ installPackage(USER_10, LAUNCHER_1);
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
+ assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_10))
.haveIds("s1")
.areAllPinned()
.areAllDisabled()
@@ -6055,61 +6056,61 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
fail("Unhandled disabled reason: " + package1DisabledReason);
}
});
- assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
+ assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_10))
.haveIds("s1", "s2")
.areAllPinned()
.areAllEnabled();
- assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
+ assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_10))
.isEmpty();
});
- installPackage(USER_0, LAUNCHER_2);
- runWithCaller(LAUNCHER_2, USER_0, () -> {
- assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
+ installPackage(USER_10, LAUNCHER_2);
+ runWithCaller(LAUNCHER_2, USER_10, () -> {
+ assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_10))
.haveIds("s2")
.areAllPinned()
.areAllDisabled()
.areAllWithDisabledReason(package1DisabledReason);
- assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
+ assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_10))
.haveIds("s2", "s3")
.areAllPinned()
.areAllEnabled();
- assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
+ assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_10))
.isEmpty();
});
- installPackage(USER_0, CALLING_PACKAGE_3);
- runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
+ installPackage(USER_10, CALLING_PACKAGE_3);
+ runWithCaller(CALLING_PACKAGE_3, USER_10, () -> {
assertEquals(0, mManager.getDynamicShortcuts().size());
assertEquals(0, mManager.getPinnedShortcuts().size());
});
- runWithCaller(LAUNCHER_1, USER_0, () -> {
- assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
+ assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_10))
.haveIds("s1")
.areAllPinned()
.areAllDisabled()
.areAllWithDisabledReason(package1DisabledReason);
- assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
+ assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_10))
.haveIds("s1", "s2")
.areAllPinned()
.areAllEnabled();
- assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
+ assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_10))
.haveIds("s1", "s2", "s3")
.areAllPinned()
.areAllDisabled()
.areAllWithDisabledReason(ShortcutInfo.DISABLED_REASON_BACKUP_NOT_SUPPORTED);
});
- runWithCaller(LAUNCHER_2, USER_0, () -> {
- assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
+ runWithCaller(LAUNCHER_2, USER_10, () -> {
+ assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_10))
.haveIds("s2")
.areAllPinned()
.areAllDisabled()
.areAllWithDisabledReason(package1DisabledReason);
- assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
+ assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_10))
.haveIds("s2", "s3")
.areAllPinned()
.areAllEnabled();
- assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
+ assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_10))
.haveIds("s2", "s3", "s4")
.areAllPinned()
.areAllDisabled()
@@ -6147,8 +6148,8 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(
any(byte[].class), anyString());
- installPackage(USER_0, CALLING_PACKAGE_1);
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ installPackage(USER_10, CALLING_PACKAGE_1);
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertEquals(0, mManager.getDynamicShortcuts().size());
// s1 was pinned by launcher 1, which is not restored, yet, so we still see "s1" here.
@@ -6157,8 +6158,8 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
"s1", "s2");
});
- installPackage(USER_0, CALLING_PACKAGE_2);
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ installPackage(USER_10, CALLING_PACKAGE_2);
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
assertEquals(0, mManager.getDynamicShortcuts().size());
assertShortcutIds(assertAllPinned(
mManager.getPinnedShortcuts()),
@@ -6170,22 +6171,22 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
// Now we try to restore launcher 1. Then we realize it's not restorable, so L1 has no pinned
// shortcuts.
- installPackage(USER_0, LAUNCHER_1);
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ installPackage(USER_10, LAUNCHER_1);
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
assertShortcutIds(assertAllPinned(
- mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
+ mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_10))
/* empty */);
assertShortcutIds(assertAllPinned(
- mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
+ mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_10))
/* empty */);
assertShortcutIds(assertAllPinned(
- mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
+ mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_10))
/* empty */);
});
- assertFalse(mService.getLauncherShortcutForTest(LAUNCHER_1, USER_0)
+ assertFalse(mService.getLauncherShortcutForTest(LAUNCHER_1, USER_10)
.getPackageInfo().isShadow());
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertEquals(0, mManager.getDynamicShortcuts().size());
// Now CALLING_PACKAGE_1 realizes "s1" is no longer pinned.
@@ -6197,44 +6198,44 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(
any(byte[].class), anyString());
- installPackage(USER_0, LAUNCHER_2);
- runWithCaller(LAUNCHER_2, USER_0, () -> {
+ installPackage(USER_10, LAUNCHER_2);
+ runWithCaller(LAUNCHER_2, USER_10, () -> {
assertShortcutIds(assertAllPinned(
- mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0)),
+ mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_10)),
"s2");
assertShortcutIds(assertAllPinned(
- mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0)),
+ mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_10)),
"s2", "s3");
assertShortcutIds(assertAllPinned(
- mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
+ mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_10))
/* empty */);
});
- assertFalse(mService.getLauncherShortcutForTest(LAUNCHER_2, USER_0)
+ assertFalse(mService.getLauncherShortcutForTest(LAUNCHER_2, USER_10)
.getPackageInfo().isShadow());
- installPackage(USER_0, CALLING_PACKAGE_3);
- runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
+ installPackage(USER_10, CALLING_PACKAGE_3);
+ runWithCaller(CALLING_PACKAGE_3, USER_10, () -> {
assertEquals(0, mManager.getDynamicShortcuts().size());
assertEquals(0, mManager.getPinnedShortcuts().size());
});
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
assertShortcutIds(assertAllPinned(
- mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
+ mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_10))
/* empty */);
assertShortcutIds(assertAllPinned(
- mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
+ mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_10))
/* empty */);
assertShortcutIds(assertAllPinned(
- mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
+ mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_10))
/* empty */);
});
- runWithCaller(LAUNCHER_2, USER_0, () -> {
+ runWithCaller(LAUNCHER_2, USER_10, () -> {
assertShortcutIds(assertAllPinned(
- mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0)),
+ mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_10)),
"s2");
assertShortcutIds(assertAllPinned(
- mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0)),
+ mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_10)),
"s2", "s3");
});
}
@@ -6254,80 +6255,80 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
protected void checkBackupAndRestore_publisherAndLauncherNotRestored() {
doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(any(byte[].class),
anyString());
- installPackage(USER_0, CALLING_PACKAGE_1);
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ installPackage(USER_10, CALLING_PACKAGE_1);
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertEquals(0, mManager.getDynamicShortcuts().size());
assertEquals(0, mManager.getPinnedShortcuts().size());
});
- installPackage(USER_0, CALLING_PACKAGE_2);
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ installPackage(USER_10, CALLING_PACKAGE_2);
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
assertEquals(0, mManager.getDynamicShortcuts().size());
assertShortcutIds(assertAllPinned(
mManager.getPinnedShortcuts()),
"s1", "s2", "s3");
});
- installPackage(USER_0, LAUNCHER_1);
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ installPackage(USER_10, LAUNCHER_1);
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
assertShortcutIds(assertAllPinned(
- mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
+ mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_10))
/* empty */);
assertShortcutIds(assertAllPinned(
- mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
+ mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_10))
/* empty */);
assertShortcutIds(assertAllPinned(
- mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
+ mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_10))
/* empty */);
});
- installPackage(USER_0, LAUNCHER_2);
- runWithCaller(LAUNCHER_2, USER_0, () -> {
- assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
+ installPackage(USER_10, LAUNCHER_2);
+ runWithCaller(LAUNCHER_2, USER_10, () -> {
+ assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_10))
.areAllPinned()
.haveIds("s2")
.areAllDisabled();
- assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
+ assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_10))
.areAllPinned()
.haveIds("s2", "s3");
- assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
+ assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_10))
.isEmpty();
});
// Because launcher 1 wasn't restored, "s1" is no longer pinned.
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
assertEquals(0, mManager.getDynamicShortcuts().size());
assertShortcutIds(assertAllPinned(
mManager.getPinnedShortcuts()),
"s2", "s3");
});
- installPackage(USER_0, CALLING_PACKAGE_3);
- runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
+ installPackage(USER_10, CALLING_PACKAGE_3);
+ runWithCaller(CALLING_PACKAGE_3, USER_10, () -> {
assertEquals(0, mManager.getDynamicShortcuts().size());
assertEquals(0, mManager.getPinnedShortcuts().size());
});
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
assertShortcutIds(assertAllPinned(
- mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
+ mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_10))
/* empty */);
assertShortcutIds(assertAllPinned(
- mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
+ mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_10))
/* empty */);
assertShortcutIds(assertAllPinned(
- mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
+ mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_10))
/* empty */);
});
- runWithCaller(LAUNCHER_2, USER_0, () -> {
- assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
+ runWithCaller(LAUNCHER_2, USER_10, () -> {
+ assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_10))
.areAllPinned()
.haveIds("s2")
.areAllDisabled();
- assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
+ assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_10))
.areAllPinned()
.haveIds("s2", "s3");
assertWith(
- mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
+ mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_10))
.haveIds("s2", "s3", "s4")
.areAllDisabled()
.areAllPinned()
@@ -6341,7 +6342,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
prepareCrossProfileDataSet();
// Before doing backup & restore, disable s1.
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
mManager.disableShortcuts(list("s1"));
});
@@ -6355,23 +6356,23 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertEquals(0, userP0.getAllLaunchersForTest().size());
// Make sure only "allowBackup" apps are restored, and are shadow.
- final ShortcutUser user0 = mService.getUserShortcutsLocked(USER_0);
+ final ShortcutUser user0 = mService.getUserShortcutsLocked(USER_10);
assertExistsAndShadow(user0.getAllPackagesForTest().get(CALLING_PACKAGE_1));
assertExistsAndShadow(user0.getAllPackagesForTest().get(CALLING_PACKAGE_2));
assertExistsAndShadow(user0.getAllPackagesForTest().get(CALLING_PACKAGE_3));
assertExistsAndShadow(user0.getAllLaunchersForTest().get(
- UserPackage.of(USER_0, LAUNCHER_1)));
+ UserPackage.of(USER_10, LAUNCHER_1)));
assertExistsAndShadow(user0.getAllLaunchersForTest().get(
- UserPackage.of(USER_0, LAUNCHER_2)));
+ UserPackage.of(USER_10, LAUNCHER_2)));
- assertNull(user0.getAllLaunchersForTest().get(UserPackage.of(USER_0, LAUNCHER_3)));
+ assertNull(user0.getAllLaunchersForTest().get(UserPackage.of(USER_10, LAUNCHER_3)));
assertNull(user0.getAllLaunchersForTest().get(UserPackage.of(USER_P0, LAUNCHER_1)));
doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(any(byte[].class),
anyString());
- installPackage(USER_0, CALLING_PACKAGE_1);
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ installPackage(USER_10, CALLING_PACKAGE_1);
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertWith(getCallerVisibleShortcuts())
.areAllEnabled() // disabled shortcuts shouldn't be restored.
@@ -6384,16 +6385,16 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
.haveIds("s2");
});
- installPackage(USER_0, LAUNCHER_1);
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ installPackage(USER_10, LAUNCHER_1);
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
// Note, s1 was pinned by launcher 1, but was disabled, so isn't restored.
- assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0))
+ assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_10))
.isEmpty();
- assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0))
+ assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_10))
.isEmpty();
- assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
+ assertWith(mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_10))
.isEmpty();
assertWith(mLauncherApps.getShortcuts(QUERY_ALL, HANDLE_USER_P0))
@@ -6409,17 +6410,17 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
R.xml.shortcut_2);
updatePackageVersion(CALLING_PACKAGE_1, 1);
mService.mPackageMonitor.onReceive(mServiceContext,
- genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
});
// Pin from launcher 1.
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
- list("ms1", "ms2", "s1", "s2"), HANDLE_USER_0);
+ list("ms1", "ms2", "s1", "s2"), HANDLE_USER_10);
});
// Update and now ms2 is gone -> disabled.
@@ -6428,10 +6429,10 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
R.xml.shortcut_1);
updatePackageVersion(CALLING_PACKAGE_1, 1);
mService.mPackageMonitor.onReceive(mServiceContext,
- genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
// Make sure the manifest shortcuts have been published.
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertWith(getCallerShortcuts())
.selectManifest()
.haveIds("ms1")
@@ -6461,11 +6462,11 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
// When re-installing the app, the manifest shortcut should be re-published.
mService.mPackageMonitor.onReceive(mServiceContext,
- genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
mService.mPackageMonitor.onReceive(mServiceContext,
- genPackageAddIntent(LAUNCHER_1, USER_0));
+ genPackageAddIntent(LAUNCHER_1, USER_10));
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertWith(getCallerVisibleShortcuts())
.selectPinned()
// ms2 was disabled, so not restored.
@@ -6502,17 +6503,17 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
R.xml.shortcut_2);
updatePackageVersion(CALLING_PACKAGE_1, 1);
mService.mPackageMonitor.onReceive(mServiceContext,
- genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
});
// Pin from launcher 1.
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
- list("ms1", "ms2", "s1", "s2"), HANDLE_USER_0);
+ list("ms1", "ms2", "s1", "s2"), HANDLE_USER_10);
});
// Update and now ms2 is gone -> disabled.
@@ -6521,7 +6522,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
R.xml.shortcut_1);
updatePackageVersion(CALLING_PACKAGE_1, 1);
mService.mPackageMonitor.onReceive(mServiceContext,
- genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
// Set up shortcuts for package 3, which won't be backed up / restored.
addManifestShortcutResource(
@@ -6529,15 +6530,15 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
R.xml.shortcut_1);
updatePackageVersion(CALLING_PACKAGE_3, 1);
mService.mPackageMonitor.onReceive(mServiceContext,
- genPackageAddIntent(CALLING_PACKAGE_3, USER_0));
+ genPackageAddIntent(CALLING_PACKAGE_3, USER_10));
- runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_3, USER_10, () -> {
assertTrue(getManager().setDynamicShortcuts(list(
makeShortcut("s1"))));
});
// Make sure the manifest shortcuts have been published.
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertWith(getCallerShortcuts())
.selectManifest()
.haveIds("ms1")
@@ -6561,7 +6562,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
.areAllDisabled();
});
- runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_3, USER_10, () -> {
assertWith(getCallerShortcuts())
.haveIds("s1", "ms1");
});
@@ -6575,7 +6576,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
dumpsysOnLogcat("Before backup");
- final byte[] payload = mService.getBackupPayload(USER_0);
+ final byte[] payload = mService.getBackupPayload(USER_10);
if (ENABLE_DUMP) {
final String xml = new String(payload);
Log.v(TAG, "Backup payload:");
@@ -6583,7 +6584,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
Log.v(TAG, line);
}
}
- mService.applyRestore(payload, USER_0);
+ mService.applyRestore(payload, USER_10);
dumpsysOnLogcat("After restore");
@@ -6591,7 +6592,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
}
// The check is also the same as testBackupAndRestore_manifestRePublished().
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertWith(getCallerVisibleShortcuts())
.selectPinned()
// ms2 was disabled, so not restored.
@@ -6609,7 +6610,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
// Package 3 still has the same shortcuts.
- runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_3, USER_10, () -> {
assertWith(getCallerShortcuts())
.haveIds("s1", "ms1");
});
@@ -6627,31 +6628,31 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(
any(byte[].class), anyString());
- runWithSystemUid(() -> mService.applyRestore(payload, USER_0));
+ runWithSystemUid(() -> mService.applyRestore(payload, USER_10));
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertWith(getCallerShortcuts())
.areAllPinned()
.haveIds("s1")
.areAllEnabled();
});
- runWithCaller(LAUNCHER_1, USER_0, () -> {
- assertWith(getShortcutAsLauncher(USER_0))
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
+ assertWith(getShortcutAsLauncher(USER_10))
.areAllPinned()
.haveIds("s1")
.areAllEnabled();
});
// Make sure getBackupSourceVersionCode and isBackupSourceBackupAllowed
// are correct. We didn't have them in the old format.
- assertEquals(8, mService.getPackageShortcutForTest(CALLING_PACKAGE_1, USER_0)
+ assertEquals(8, mService.getPackageShortcutForTest(CALLING_PACKAGE_1, USER_10)
.getPackageInfo().getBackupSourceVersionCode());
- assertTrue(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, USER_0)
+ assertTrue(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, USER_10)
.getPackageInfo().isBackupSourceBackupAllowed());
- assertEquals(9, mService.getLauncherShortcutForTest(LAUNCHER_1, USER_0)
+ assertEquals(9, mService.getLauncherShortcutForTest(LAUNCHER_1, USER_10)
.getPackageInfo().getBackupSourceVersionCode());
- assertTrue(mService.getLauncherShortcutForTest(LAUNCHER_1, USER_0)
+ assertTrue(mService.getLauncherShortcutForTest(LAUNCHER_1, USER_10)
.getPackageInfo().isBackupSourceBackupAllowed());
}
@@ -6664,25 +6665,25 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
mService.saveDirtyInfo();
initService();
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertShortcutIds(assertAllDynamic(mManager.getDynamicShortcuts()),
"s1", "s2", "s3");
assertShortcutIds(assertAllPinned(mManager.getPinnedShortcuts()),
"s1", "s2", "s3", "s4");
});
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
assertShortcutIds(assertAllDynamic(mManager.getDynamicShortcuts()),
"s1", "s2", "s3");
assertShortcutIds(assertAllPinned(mManager.getPinnedShortcuts()),
"s1", "s2", "s3", "s4", "s5");
});
- runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_3, USER_10, () -> {
assertShortcutIds(assertAllDynamic(mManager.getDynamicShortcuts()),
"s1", "s2", "s3");
assertShortcutIds(assertAllPinned(mManager.getPinnedShortcuts()),
"s1", "s2", "s3", "s4", "s5", "s6");
});
- runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_4, USER_10, () -> {
assertShortcutIds(assertAllDynamic(mManager.getDynamicShortcuts())
/* empty */);
assertShortcutIds(assertAllPinned(mManager.getPinnedShortcuts())
@@ -6700,24 +6701,24 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertShortcutIds(assertAllPinned(mManager.getPinnedShortcuts())
/* empty */);
});
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
assertShortcutIds(assertAllDynamic(mManager.getDynamicShortcuts()),
"x1", "x2", "x3");
assertShortcutIds(assertAllPinned(mManager.getPinnedShortcuts()),
"x4", "x5");
});
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
assertShortcutIds(
- mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_1), HANDLE_USER_0),
+ mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_1), HANDLE_USER_10),
"s1");
assertShortcutIds(
- mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_2), HANDLE_USER_0),
+ mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_2), HANDLE_USER_10),
"s1", "s2");
assertShortcutIds(
- mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_3), HANDLE_USER_0),
+ mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_3), HANDLE_USER_10),
"s1", "s2", "s3");
assertShortcutIds(
- mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_4), HANDLE_USER_0)
+ mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_4), HANDLE_USER_10)
/* empty */);
assertShortcutIds(
mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_1), HANDLE_USER_P0),
@@ -6728,21 +6729,21 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertExpectException(
SecurityException.class, "", () -> {
mLauncherApps.getShortcuts(
- buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_10);
+ buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_11);
});
});
- runWithCaller(LAUNCHER_2, USER_0, () -> {
+ runWithCaller(LAUNCHER_2, USER_10, () -> {
assertShortcutIds(
- mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_1), HANDLE_USER_0),
+ mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_1), HANDLE_USER_10),
"s2");
assertShortcutIds(
- mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_2), HANDLE_USER_0),
+ mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_2), HANDLE_USER_10),
"s2", "s3");
assertShortcutIds(
- mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_3), HANDLE_USER_0),
+ mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_3), HANDLE_USER_10),
"s2", "s3", "s4");
assertShortcutIds(
- mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_4), HANDLE_USER_0)
+ mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_4), HANDLE_USER_10)
/* empty */);
assertShortcutIds(
mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_1), HANDLE_USER_P0),
@@ -6751,18 +6752,18 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_2), HANDLE_USER_P0)
/* empty */);
});
- runWithCaller(LAUNCHER_3, USER_0, () -> {
+ runWithCaller(LAUNCHER_3, USER_10, () -> {
assertShortcutIds(
- mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_1), HANDLE_USER_0),
+ mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_1), HANDLE_USER_10),
"s3");
assertShortcutIds(
- mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_2), HANDLE_USER_0),
+ mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_2), HANDLE_USER_10),
"s3", "s4");
assertShortcutIds(
- mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_3), HANDLE_USER_0),
+ mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_3), HANDLE_USER_10),
"s3", "s4", "s5");
assertShortcutIds(
- mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_4), HANDLE_USER_0)
+ mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_4), HANDLE_USER_10)
/* empty */);
assertShortcutIds(
mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_1), HANDLE_USER_P0),
@@ -6771,18 +6772,18 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_2), HANDLE_USER_P0)
/* empty */);
});
- runWithCaller(LAUNCHER_4, USER_0, () -> {
+ runWithCaller(LAUNCHER_4, USER_10, () -> {
assertShortcutIds(
- mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_1), HANDLE_USER_0)
+ mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_1), HANDLE_USER_10)
/* empty */);
assertShortcutIds(
- mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_2), HANDLE_USER_0)
+ mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_2), HANDLE_USER_10)
/* empty */);
assertShortcutIds(
- mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_3), HANDLE_USER_0)
+ mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_3), HANDLE_USER_10)
/* empty */);
assertShortcutIds(
- mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_4), HANDLE_USER_0)
+ mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_4), HANDLE_USER_10)
/* empty */);
assertShortcutIds(
mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_1), HANDLE_USER_P0)
@@ -6793,13 +6794,13 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
runWithCaller(LAUNCHER_1, USER_P0, () -> {
assertShortcutIds(
- mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_1), HANDLE_USER_0),
+ mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_1), HANDLE_USER_10),
"s3", "s4");
assertShortcutIds(
- mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_2), HANDLE_USER_0),
+ mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_2), HANDLE_USER_10),
"s3", "s4", "s5");
assertShortcutIds(
- mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_3), HANDLE_USER_0),
+ mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_3), HANDLE_USER_10),
"s3", "s4", "s5", "s6");
assertShortcutIds(
mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_1), HANDLE_USER_P0),
@@ -6807,23 +6808,23 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertExpectException(
SecurityException.class, "unrelated profile", () -> {
mLauncherApps.getShortcuts(
- buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_10);
+ buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_11);
});
});
- runWithCaller(LAUNCHER_1, USER_10, () -> {
+ runWithCaller(LAUNCHER_1, USER_11, () -> {
assertShortcutIds(
- mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_1), HANDLE_USER_10),
+ mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_1), HANDLE_USER_11),
"x4", "x5");
assertShortcutIds(
- mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_2), HANDLE_USER_10)
+ mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_2), HANDLE_USER_11)
/* empty */);
assertShortcutIds(
- mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_3), HANDLE_USER_10)
+ mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_3), HANDLE_USER_11)
/* empty */);
assertExpectException(
SecurityException.class, "unrelated profile", () -> {
mLauncherApps.getShortcuts(
- buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0);
+ buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_10);
});
assertExpectException(
SecurityException.class, "unrelated profile", () -> {
@@ -6832,11 +6833,11 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
});
// Check the user-IDs.
- assertEquals(USER_0,
- mService.getUserShortcutsLocked(USER_0).getPackageShortcuts(CALLING_PACKAGE_1)
+ assertEquals(USER_10,
+ mService.getUserShortcutsLocked(USER_10).getPackageShortcuts(CALLING_PACKAGE_1)
.getOwnerUserId());
- assertEquals(USER_0,
- mService.getUserShortcutsLocked(USER_0).getPackageShortcuts(CALLING_PACKAGE_1)
+ assertEquals(USER_10,
+ mService.getUserShortcutsLocked(USER_10).getPackageShortcuts(CALLING_PACKAGE_1)
.getPackageUserId());
assertEquals(USER_P0,
mService.getUserShortcutsLocked(USER_P0).getPackageShortcuts(CALLING_PACKAGE_1)
@@ -6845,27 +6846,27 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
mService.getUserShortcutsLocked(USER_P0).getPackageShortcuts(CALLING_PACKAGE_1)
.getPackageUserId());
- assertEquals(USER_0,
- mService.getUserShortcutsLocked(USER_0).getLauncherShortcuts(LAUNCHER_1, USER_0)
+ assertEquals(USER_10,
+ mService.getUserShortcutsLocked(USER_10).getLauncherShortcuts(LAUNCHER_1, USER_10)
.getOwnerUserId());
- assertEquals(USER_0,
- mService.getUserShortcutsLocked(USER_0).getLauncherShortcuts(LAUNCHER_1, USER_0)
+ assertEquals(USER_10,
+ mService.getUserShortcutsLocked(USER_10).getLauncherShortcuts(LAUNCHER_1, USER_10)
.getPackageUserId());
assertEquals(USER_P0,
- mService.getUserShortcutsLocked(USER_P0).getLauncherShortcuts(LAUNCHER_1, USER_0)
+ mService.getUserShortcutsLocked(USER_P0).getLauncherShortcuts(LAUNCHER_1, USER_10)
.getOwnerUserId());
- assertEquals(USER_0,
- mService.getUserShortcutsLocked(USER_P0).getLauncherShortcuts(LAUNCHER_1, USER_0)
+ assertEquals(USER_10,
+ mService.getUserShortcutsLocked(USER_P0).getLauncherShortcuts(LAUNCHER_1, USER_10)
.getPackageUserId());
}
public void OnApplicationActive_permission() {
assertExpectException(SecurityException.class, "Missing permission", () ->
- mManager.onApplicationActive(CALLING_PACKAGE_1, USER_0));
+ mManager.onApplicationActive(CALLING_PACKAGE_1, USER_10));
// Has permission, now it should pass.
mCallerPermissions.add(permission.RESET_SHORTCUT_MANAGER_THROTTLING);
- mManager.onApplicationActive(CALLING_PACKAGE_1, USER_0);
+ mManager.onApplicationActive(CALLING_PACKAGE_1, USER_10);
}
public void GetShareTargets_permission() {
@@ -6881,7 +6882,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
mCallerPermissions.add(permission.MANAGE_APP_PREDICTIONS);
mManager.getShareTargets(filter);
- runWithCaller(CHOOSER_ACTIVITY_PACKAGE, USER_0, () -> {
+ runWithCaller(CHOOSER_ACTIVITY_PACKAGE, USER_10, () -> {
// Access is allowed when called from the configured system ChooserActivity
mManager.getShareTargets(filter);
});
@@ -6897,13 +6898,13 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
}
public void isSharingShortcut_permission() throws IntentFilter.MalformedMimeTypeException {
- setCaller(LAUNCHER_1, USER_0);
+ setCaller(LAUNCHER_1, USER_10);
IntentFilter filter_any = new IntentFilter();
filter_any.addDataType("*/*");
assertExpectException(SecurityException.class, "Missing permission", () ->
- mInternal.isSharingShortcut(USER_0, LAUNCHER_1, CALLING_PACKAGE_1, "s1", USER_0,
+ mInternal.isSharingShortcut(USER_10, LAUNCHER_1, CALLING_PACKAGE_1, "s1", USER_10,
filter_any));
// Has permission, now it should pass.
@@ -6935,23 +6936,23 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
// Unlock user-0.
mInjectedCurrentTimeMillis += 100;
- mService.handleUnlockUser(USER_0);
+ mService.handleUnlockUser(USER_10);
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
mManager.getManifestShortcuts()))),
"ms1");
assertEmpty(mManager.getPinnedShortcuts());
});
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
mManager.getManifestShortcuts()))),
"ms1", "ms2");
assertEmpty(mManager.getPinnedShortcuts());
});
- runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_3, USER_10, () -> {
assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
mManager.getManifestShortcuts()))),
"ms1", "ms2", "ms3", "ms4", "ms5");
@@ -6959,27 +6960,27 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
// Try on another user, with some packages uninstalled.
- mRunningUsers.put(USER_10, true);
+ mRunningUsers.put(USER_11, true);
- uninstallPackage(USER_10, CALLING_PACKAGE_1);
- uninstallPackage(USER_10, CALLING_PACKAGE_3);
+ uninstallPackage(USER_11, CALLING_PACKAGE_1);
+ uninstallPackage(USER_11, CALLING_PACKAGE_3);
mInjectedCurrentTimeMillis += 100;
- mService.handleUnlockUser(USER_10);
+ mService.handleUnlockUser(USER_11);
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
assertEmpty(mManager.getManifestShortcuts());
assertEmpty(mManager.getPinnedShortcuts());
});
- runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_11, () -> {
assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
mManager.getManifestShortcuts()))),
"ms1", "ms2");
assertEmpty(mManager.getPinnedShortcuts());
});
- runWithCaller(CALLING_PACKAGE_3, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_3, USER_11, () -> {
assertEmpty(mManager.getManifestShortcuts());
assertEmpty(mManager.getPinnedShortcuts());
});
@@ -6999,23 +7000,23 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
R.xml.shortcut_1);
initService();
- mService.handleUnlockUser(USER_0);
+ mService.handleUnlockUser(USER_10);
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled( // FAIL
mManager.getManifestShortcuts()))),
"ms1");
assertEmpty(mManager.getPinnedShortcuts());
});
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
mManager.getManifestShortcuts()))),
"ms1", "ms2");
assertEmpty(mManager.getPinnedShortcuts());
});
- runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_3, USER_10, () -> {
assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
mManager.getManifestShortcuts()))),
"ms1", "ms2", "ms3", "ms4", "ms5");
@@ -7031,23 +7032,23 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
updatePackageLastUpdateTime(CALLING_PACKAGE_3, 1);
initService();
- mService.handleUnlockUser(USER_0);
+ mService.handleUnlockUser(USER_10);
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
mManager.getManifestShortcuts()))),
"ms1", "ms2", "ms3", "ms4", "ms5");
assertEmpty(mManager.getPinnedShortcuts());
});
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
mManager.getManifestShortcuts()))),
"ms1", "ms2");
assertEmpty(mManager.getPinnedShortcuts());
});
- runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_3, USER_10, () -> {
assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
mManager.getManifestShortcuts()))),
"ms1");
@@ -7055,12 +7056,12 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
// Next, try removing all shortcuts, with some of them pinned.
- runWithCaller(LAUNCHER_1, USER_0, () -> {
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("ms3"), HANDLE_USER_0);
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list("ms2"), HANDLE_USER_0);
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_3, list("ms1"), HANDLE_USER_0);
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("ms3"), HANDLE_USER_10);
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list("ms2"), HANDLE_USER_10);
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_3, list("ms1"), HANDLE_USER_10);
});
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
mManager.getManifestShortcuts()))),
"ms1", "ms2", "ms3", "ms4", "ms5");
@@ -7069,7 +7070,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
"ms3");
});
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
mManager.getManifestShortcuts()))),
"ms1", "ms2");
@@ -7078,7 +7079,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
"ms2");
});
- runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_3, USER_10, () -> {
assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
mManager.getManifestShortcuts()))),
"ms1");
@@ -7106,16 +7107,16 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
updatePackageVersion(CALLING_PACKAGE_3, 1);
initService();
- mService.handleUnlockUser(USER_0);
+ mService.handleUnlockUser(USER_10);
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertEmpty(mManager.getManifestShortcuts());
assertShortcutIds(assertAllImmutable(assertAllPinned(assertAllNotManifest(
assertAllDisabled(mManager.getPinnedShortcuts())))),
"ms3");
});
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
mManager.getManifestShortcuts()))),
"ms1");
@@ -7124,7 +7125,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
"ms2");
});
- runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_3, USER_10, () -> {
assertEmpty(mManager.getManifestShortcuts());
assertShortcutIds(assertAllImmutable(assertAllPinned(assertAllNotManifest(
assertAllDisabled(mManager.getPinnedShortcuts())))),
@@ -7132,38 +7133,38 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
// Make sure we don't have ShortcutPackage for packages that don't have shortcuts.
- assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_4, USER_0));
- assertNull(mService.getPackageShortcutForTest(LAUNCHER_1, USER_0));
+ assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_4, USER_10));
+ assertNull(mService.getPackageShortcutForTest(LAUNCHER_1, USER_10));
}
public void ManifestShortcut_publishOnBroadcast() {
// First, no packages are installed.
- uninstallPackage(USER_0, CALLING_PACKAGE_1);
- uninstallPackage(USER_0, CALLING_PACKAGE_2);
- uninstallPackage(USER_0, CALLING_PACKAGE_3);
- uninstallPackage(USER_0, CALLING_PACKAGE_4);
uninstallPackage(USER_10, CALLING_PACKAGE_1);
uninstallPackage(USER_10, CALLING_PACKAGE_2);
uninstallPackage(USER_10, CALLING_PACKAGE_3);
uninstallPackage(USER_10, CALLING_PACKAGE_4);
+ uninstallPackage(USER_11, CALLING_PACKAGE_1);
+ uninstallPackage(USER_11, CALLING_PACKAGE_2);
+ uninstallPackage(USER_11, CALLING_PACKAGE_3);
+ uninstallPackage(USER_11, CALLING_PACKAGE_4);
- mService.handleUnlockUser(USER_0);
-
- mRunningUsers.put(USER_10, true);
mService.handleUnlockUser(USER_10);
+ mRunningUsers.put(USER_11, true);
+ mService.handleUnlockUser(USER_11);
+
// Originally no manifest shortcuts.
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertEmpty(mManager.getManifestShortcuts());
assertEmpty(mManager.getPinnedShortcuts());
});
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
assertEmpty(mManager.getManifestShortcuts());
assertEmpty(mManager.getPinnedShortcuts());
});
- runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_3, USER_10, () -> {
assertEmpty(mManager.getManifestShortcuts());
assertEmpty(mManager.getPinnedShortcuts());
});
@@ -7174,16 +7175,16 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
R.xml.shortcut_1);
updatePackageVersion(CALLING_PACKAGE_1, 1);
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
mManager.getManifestShortcuts()))),
"ms1");
assertEmpty(mManager.getPinnedShortcuts());
});
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
assertEmpty(mManager.getManifestShortcuts());
assertEmpty(mManager.getPinnedShortcuts());
});
@@ -7195,16 +7196,16 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
R.xml.shortcut_5_altalt);
updatePackageVersion(CALLING_PACKAGE_2, 1);
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageAddIntent(CALLING_PACKAGE_2, USER_0));
+ genPackageAddIntent(CALLING_PACKAGE_2, USER_10));
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
mManager.getManifestShortcuts()))),
"ms1");
assertEmpty(mManager.getPinnedShortcuts());
});
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
mManager.getManifestShortcuts()))),
"ms1", "ms2", "ms3", "ms4", "ms5");
@@ -7221,8 +7222,8 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
dumpsysOnLogcat("Before pinning");
// Also pin some.
- runWithCaller(LAUNCHER_1, USER_0, () -> {
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list("ms2", "ms3"), HANDLE_USER_0);
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list("ms2", "ms3"), HANDLE_USER_10);
});
dumpsysOnLogcat("After pinning");
@@ -7232,18 +7233,18 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
R.xml.shortcut_2);
updatePackageLastUpdateTime(CALLING_PACKAGE_2, 1);
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageAddIntent(CALLING_PACKAGE_2, USER_0));
+ genPackageAddIntent(CALLING_PACKAGE_2, USER_10));
dumpsysOnLogcat("After updating package 2");
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
mManager.getManifestShortcuts()))),
"ms1");
assertEmpty(mManager.getPinnedShortcuts());
});
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
mManager.getManifestShortcuts()))),
"ms1", "ms2");
@@ -7267,10 +7268,10 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
// Make sure the launcher see the correct disabled reason.
- runWithCaller(LAUNCHER_1, USER_0, () -> {
- assertWith(getShortcutAsLauncher(USER_0))
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
+ assertWith(getShortcutAsLauncher(USER_10))
.forShortcutWithId("ms3", si -> {
- assertEquals("string-com.android.test.2-user:0-res:"
+ assertEquals("string-com.android.test.2-user:10-res:"
+ R.string.shortcut_disabled_message3 + "/en",
si.getDisabledMessage());
});
@@ -7278,18 +7279,18 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
// Package 2 on user 10 has no shortcuts yet.
- runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_11, () -> {
assertEmpty(mManager.getManifestShortcuts());
assertEmpty(mManager.getPinnedShortcuts());
});
// Send add broadcast, but the user is not running, so should be ignored.
- mService.handleStopUser(USER_10);
- mRunningUsers.put(USER_10, false);
- mUnlockedUsers.put(USER_10, false);
+ mService.handleStopUser(USER_11);
+ mRunningUsers.put(USER_11, false);
+ mUnlockedUsers.put(USER_11, false);
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageAddIntent(CALLING_PACKAGE_2, USER_10));
- runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
+ genPackageAddIntent(CALLING_PACKAGE_2, USER_11));
+ runWithCaller(CALLING_PACKAGE_2, USER_11, () -> {
// Don't use the mManager APIs to get shortcuts, because they'll trigger the package
// update check.
// So look the internal data directly using getCallerShortcuts().
@@ -7297,10 +7298,10 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
// Try again, but the user is locked, so still ignored.
- mRunningUsers.put(USER_10, true);
+ mRunningUsers.put(USER_11, true);
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageAddIntent(CALLING_PACKAGE_2, USER_10));
- runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
+ genPackageAddIntent(CALLING_PACKAGE_2, USER_11));
+ runWithCaller(CALLING_PACKAGE_2, USER_11, () -> {
// Don't use the mManager APIs to get shortcuts, because they'll trigger the package
// update check.
// So look the internal data directly using getCallerShortcuts().
@@ -7308,13 +7309,13 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
// Unlock the user, now it should work.
- mUnlockedUsers.put(USER_10, true);
+ mUnlockedUsers.put(USER_11, true);
// Send PACKAGE_ADD broadcast to have Package 2 on user-10 publish manifest shortcuts.
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageAddIntent(CALLING_PACKAGE_2, USER_10));
+ genPackageAddIntent(CALLING_PACKAGE_2, USER_11));
- runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_11, () -> {
assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
mManager.getManifestShortcuts()))),
"ms1", "ms2");
@@ -7326,7 +7327,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
// But it shouldn't affect user-0.
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
mManager.getManifestShortcuts()))),
"ms1", "ms2");
@@ -7353,9 +7354,9 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
updatePackageLastUpdateTime(CALLING_PACKAGE_2, 1);
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageAddIntent(CALLING_PACKAGE_2, USER_0));
+ genPackageAddIntent(CALLING_PACKAGE_2, USER_10));
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
mManager.getManifestShortcuts()))),
"ms1", "ms2", "ms3", "ms4", "ms5",
@@ -7381,10 +7382,10 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
R.xml.shortcut_0);
updatePackageLastUpdateTime(CALLING_PACKAGE_2, 1);
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageAddIntent(CALLING_PACKAGE_2, USER_0));
+ genPackageAddIntent(CALLING_PACKAGE_2, USER_10));
// No manifest shortcuts, and pinned ones are disabled.
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
assertEmpty(mManager.getManifestShortcuts());
assertShortcutIds(assertAllImmutable(assertAllPinned(assertAllDisabled(
mManager.getPinnedShortcuts()))),
@@ -7394,15 +7395,15 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
public void ManifestShortcuts_missingMandatoryFields() {
// Start with no apps installed.
- uninstallPackage(USER_0, CALLING_PACKAGE_1);
- uninstallPackage(USER_0, CALLING_PACKAGE_2);
- uninstallPackage(USER_0, CALLING_PACKAGE_3);
- uninstallPackage(USER_0, CALLING_PACKAGE_4);
+ uninstallPackage(USER_10, CALLING_PACKAGE_1);
+ uninstallPackage(USER_10, CALLING_PACKAGE_2);
+ uninstallPackage(USER_10, CALLING_PACKAGE_3);
+ uninstallPackage(USER_10, CALLING_PACKAGE_4);
- mService.handleUnlockUser(USER_0);
+ mService.handleUnlockUser(USER_10);
// Make sure no manifest shortcuts.
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertEmpty(mManager.getManifestShortcuts());
});
@@ -7412,10 +7413,10 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
R.xml.shortcut_error_1);
updatePackageVersion(CALLING_PACKAGE_1, 1);
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
// Only the valid one is published.
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertWith(getCallerShortcuts())
.areAllManifest()
.areAllImmutable()
@@ -7429,10 +7430,10 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
R.xml.shortcut_error_2);
updatePackageVersion(CALLING_PACKAGE_1, 1);
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
// Only the valid one is published.
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertWith(getCallerShortcuts())
.areAllManifest()
.areAllImmutable()
@@ -7446,10 +7447,10 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
R.xml.shortcut_error_3);
updatePackageVersion(CALLING_PACKAGE_1, 1);
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
// Only the valid one is published.
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertWith(getCallerShortcuts())
.areAllManifest()
.areAllImmutable()
@@ -7467,9 +7468,9 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
R.xml.shortcut_error_4);
updatePackageVersion(CALLING_PACKAGE_1, 1);
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
// Make sure invalid ones are not published.
// Note that at this point disabled ones don't show up because they weren't pinned.
assertWith(getCallerShortcuts())
@@ -7525,9 +7526,9 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
R.xml.shortcut_5);
updatePackageVersion(CALLING_PACKAGE_1, 1);
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
// Make sure 5 manifest shortcuts are published.
assertWith(getCallerShortcuts())
.haveIds("ms1", "ms2", "ms3", "ms4", "ms5")
@@ -7538,13 +7539,13 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
.areAllEnabled();
});
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
- list("ms3", "ms4", "ms5"), HANDLE_USER_0);
+ list("ms3", "ms4", "ms5"), HANDLE_USER_10);
});
// Make sure they're pinned.
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertWith(getCallerShortcuts())
.haveIds("ms1", "ms2", "ms3", "ms4", "ms5")
.selectByIds("ms1", "ms2")
@@ -7563,10 +7564,10 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
R.xml.shortcut_error_4);
updatePackageVersion(CALLING_PACKAGE_1, 1);
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
// Make sure 3, 4 and 5 still exist but disabled.
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertWith(getCallerShortcuts())
.haveIds("ms1", "ms2", "ms3", "ms4", "ms5")
.areAllNotDynamic()
@@ -7604,7 +7605,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
}
public void ManifestShortcuts_checkAllFields() {
- mService.handleUnlockUser(USER_0);
+ mService.handleUnlockUser(USER_10);
// Package 1 updated, which has one valid manifest shortcut and one invalid.
addManifestShortcutResource(
@@ -7612,10 +7613,10 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
R.xml.shortcut_5);
updatePackageVersion(CALLING_PACKAGE_1, 1);
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
// Only the valid one is published.
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertWith(getCallerShortcuts())
.haveIds("ms1", "ms2", "ms3", "ms4", "ms5")
.areAllManifest()
@@ -7709,7 +7710,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
}
public void ManifestShortcuts_localeChange() throws InterruptedException {
- mService.handleUnlockUser(USER_0);
+ mService.handleUnlockUser(USER_10);
// Package 1 updated, which has one valid manifest shortcut and one invalid.
addManifestShortcutResource(
@@ -7717,9 +7718,9 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
R.xml.shortcut_2);
updatePackageVersion(CALLING_PACKAGE_1, 1);
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
mManager.setDynamicShortcuts(list(makeShortcutWithTitle("s1", "title")));
assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
@@ -7730,11 +7731,11 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
ShortcutInfo si = getCallerShortcut("ms1");
assertEquals("ms1", si.getId());
- assertEquals("string-com.android.test.1-user:0-res:" + R.string.shortcut_title1 + "/en",
+ assertEquals("string-com.android.test.1-user:10-res:" + R.string.shortcut_title1 + "/en",
si.getTitle());
- assertEquals("string-com.android.test.1-user:0-res:" + R.string.shortcut_text1 + "/en",
+ assertEquals("string-com.android.test.1-user:10-res:" + R.string.shortcut_text1 + "/en",
si.getText());
- assertEquals("string-com.android.test.1-user:0-res:"
+ assertEquals("string-com.android.test.1-user:10-res:"
+ R.string.shortcut_disabled_message1 + "/en",
si.getDisabledMessage());
assertEquals(START_TIME, si.getLastChangedTimestamp());
@@ -7743,11 +7744,11 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
si = getCallerShortcut("ms2");
assertEquals("ms2", si.getId());
- assertEquals("string-com.android.test.1-user:0-res:" + R.string.shortcut_title2 + "/en",
+ assertEquals("string-com.android.test.1-user:10-res:" + R.string.shortcut_title2 + "/en",
si.getTitle());
- assertEquals("string-com.android.test.1-user:0-res:" + R.string.shortcut_text2 + "/en",
+ assertEquals("string-com.android.test.1-user:10-res:" + R.string.shortcut_text2 + "/en",
si.getText());
- assertEquals("string-com.android.test.1-user:0-res:"
+ assertEquals("string-com.android.test.1-user:10-res:"
+ R.string.shortcut_disabled_message2 + "/en",
si.getDisabledMessage());
assertEquals(START_TIME, si.getLastChangedTimestamp());
@@ -7767,23 +7768,23 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
// Change the locale and send the broadcast, make sure the launcher gets a callback too.
mInjectedLocale = Locale.JAPANESE;
- setCaller(LAUNCHER_1, USER_0);
+ setCaller(LAUNCHER_1, USER_10);
assertForLauncherCallback(mLauncherApps, () -> {
mService.mReceiver.onReceive(mServiceContext, new Intent(Intent.ACTION_LOCALE_CHANGED));
- }).assertCallbackCalledForPackageAndUser(CALLING_PACKAGE_1, HANDLE_USER_0)
+ }).assertCallbackCalledForPackageAndUser(CALLING_PACKAGE_1, HANDLE_USER_10)
.haveIds("ms1", "ms2", "s1");
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
// check first shortcut.
ShortcutInfo si = getCallerShortcut("ms1");
assertEquals("ms1", si.getId());
- assertEquals("string-com.android.test.1-user:0-res:" + R.string.shortcut_title1 + "/ja",
+ assertEquals("string-com.android.test.1-user:10-res:" + R.string.shortcut_title1 + "/ja",
si.getTitle());
- assertEquals("string-com.android.test.1-user:0-res:" + R.string.shortcut_text1 + "/ja",
+ assertEquals("string-com.android.test.1-user:10-res:" + R.string.shortcut_text1 + "/ja",
si.getText());
- assertEquals("string-com.android.test.1-user:0-res:"
+ assertEquals("string-com.android.test.1-user:10-res:"
+ R.string.shortcut_disabled_message1 + "/ja",
si.getDisabledMessage());
assertEquals(START_TIME + 1, si.getLastChangedTimestamp());
@@ -7792,11 +7793,11 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
si = getCallerShortcut("ms2");
assertEquals("ms2", si.getId());
- assertEquals("string-com.android.test.1-user:0-res:" + R.string.shortcut_title2 + "/ja",
+ assertEquals("string-com.android.test.1-user:10-res:" + R.string.shortcut_title2 + "/ja",
si.getTitle());
- assertEquals("string-com.android.test.1-user:0-res:" + R.string.shortcut_text2 + "/ja",
+ assertEquals("string-com.android.test.1-user:10-res:" + R.string.shortcut_text2 + "/ja",
si.getText());
- assertEquals("string-com.android.test.1-user:0-res:"
+ assertEquals("string-com.android.test.1-user:10-res:"
+ R.string.shortcut_disabled_message2 + "/ja",
si.getDisabledMessage());
assertEquals(START_TIME + 1, si.getLastChangedTimestamp());
@@ -7813,7 +7814,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
}
public void ManifestShortcuts_updateAndDisabled_notPinned() {
- mService.handleUnlockUser(USER_0);
+ mService.handleUnlockUser(USER_10);
// First, just publish a manifest shortcut.
addManifestShortcutResource(
@@ -7821,10 +7822,10 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
R.xml.shortcut_1);
updatePackageVersion(CALLING_PACKAGE_1, 1);
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
// Only the valid one is published.
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
mManager.getManifestShortcuts()))),
"ms1");
@@ -7840,10 +7841,10 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
R.xml.shortcut_1_disable);
updatePackageVersion(CALLING_PACKAGE_1, 1);
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
// Because shortcut 1 wasn't pinned, it'll just go away.
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertEmpty(mManager.getManifestShortcuts());
assertEmpty(mManager.getPinnedShortcuts());
@@ -7853,7 +7854,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
}
public void ManifestShortcuts_updateAndDisabled_pinned() {
- mService.handleUnlockUser(USER_0);
+ mService.handleUnlockUser(USER_10);
// First, just publish a manifest shortcut.
addManifestShortcutResource(
@@ -7861,10 +7862,10 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
R.xml.shortcut_1);
updatePackageVersion(CALLING_PACKAGE_1, 1);
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
// Only the valid one is published.
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
mManager.getManifestShortcuts()))),
"ms1");
@@ -7874,8 +7875,8 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertShortcutIds(getCallerShortcuts(), "ms1");
});
- runWithCaller(LAUNCHER_1, USER_0, () -> {
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("ms1"), HANDLE_USER_0);
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("ms1"), HANDLE_USER_10);
});
// Now upgrade, the manifest shortcut is disabled now.
@@ -7884,10 +7885,10 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
R.xml.shortcut_1_disable);
updatePackageVersion(CALLING_PACKAGE_1, 1);
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
// Because shortcut 1 was pinned, it'll still exist as pinned, but disabled.
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertEmpty(mManager.getManifestShortcuts());
assertShortcutIds(assertAllNotManifest(assertAllImmutable(assertAllDisabled(
mManager.getPinnedShortcuts()))),
@@ -7909,7 +7910,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
}
public void ManifestShortcuts_duplicateInSingleActivity() {
- mService.handleUnlockUser(USER_0);
+ mService.handleUnlockUser(USER_10);
// The XML has two shortcuts with the same ID.
addManifestShortcutResource(
@@ -7917,9 +7918,9 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
R.xml.shortcut_2_duplicate);
updatePackageVersion(CALLING_PACKAGE_1, 1);
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
mManager.getManifestShortcuts()))),
"ms1");
@@ -7934,7 +7935,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
}
public void ManifestShortcuts_duplicateInTwoActivities() {
- mService.handleUnlockUser(USER_0);
+ mService.handleUnlockUser(USER_10);
// ShortcutActivity has shortcut ms1
addManifestShortcutResource(
@@ -7947,9 +7948,9 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
R.xml.shortcut_5);
updatePackageVersion(CALLING_PACKAGE_1, 1);
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertShortcutIds(assertAllManifest(assertAllImmutable(assertAllEnabled(
mManager.getManifestShortcuts()))),
"ms1", "ms2", "ms3", "ms4", "ms5");
@@ -7986,11 +7987,11 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
* Manifest shortcuts cannot override shortcuts that were published via the APIs.
*/
public void ManifestShortcuts_cannotOverrideNonManifest() {
- mService.handleUnlockUser(USER_0);
+ mService.handleUnlockUser(USER_10);
// Create a non-pinned dynamic shortcut and a non-dynamic pinned shortcut.
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
mManager.setDynamicShortcuts(list(
makeShortcut("ms1", "title1",
new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
@@ -8000,11 +8001,11 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
/* icon */ null, new Intent("action1"), /* rank */ 0)));
});
- runWithCaller(LAUNCHER_1, USER_0, () -> {
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("ms2"), HANDLE_USER_0);
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("ms2"), HANDLE_USER_10);
});
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
mManager.removeDynamicShortcuts(list("ms2"));
assertShortcutIds(mManager.getDynamicShortcuts(), "ms1");
@@ -8019,9 +8020,9 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
R.xml.shortcut_5);
updatePackageVersion(CALLING_PACKAGE_1, 1);
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertShortcutIds(assertAllNotManifest(mManager.getDynamicShortcuts()), "ms1");
assertShortcutIds(assertAllNotManifest(mManager.getPinnedShortcuts()), "ms2");
assertShortcutIds(assertAllManifest(mManager.getManifestShortcuts()),
@@ -8037,7 +8038,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
}
protected void checkManifestShortcuts_immutable_verify() {
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertShortcutIds(assertAllNotManifest(assertAllEnabled(
mManager.getDynamicShortcuts())),
"s1");
@@ -8059,7 +8060,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
* Make sure the APIs won't work on manifest shortcuts.
*/
public void ManifestShortcuts_immutable() {
- mService.handleUnlockUser(USER_0);
+ mService.handleUnlockUser(USER_10);
// Create a non-pinned manifest shortcut, a pinned shortcut that was originally
// a manifest shortcut, as well as a dynamic shortcut.
@@ -8069,10 +8070,10 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
R.xml.shortcut_2);
updatePackageVersion(CALLING_PACKAGE_1, 1);
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
- runWithCaller(LAUNCHER_1, USER_0, () -> {
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("ms2"), HANDLE_USER_0);
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("ms2"), HANDLE_USER_10);
});
addManifestShortcutResource(
@@ -8080,9 +8081,9 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
R.xml.shortcut_1);
updatePackageVersion(CALLING_PACKAGE_1, 1);
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
mManager.addDynamicShortcuts(list(makeShortcutWithTitle("s1", "t1")));
});
@@ -8091,7 +8092,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
// Note that even though the first argument is not immutable and only the second one
// is immutable, the first argument should not be executed either.
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertCannotUpdateImmutable(() -> {
mManager.setDynamicShortcuts(list(makeShortcut("xx"), makeShortcut("ms1")));
});
@@ -8101,7 +8102,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
checkManifestShortcuts_immutable_verify();
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertCannotUpdateImmutable(() -> {
mManager.addDynamicShortcuts(list(makeShortcut("xx"), makeShortcut("ms1")));
});
@@ -8112,7 +8113,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
checkManifestShortcuts_immutable_verify();
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertCannotUpdateImmutable(() -> {
mManager.updateShortcuts(list(makeShortcut("s1"), makeShortcut("ms1")));
});
@@ -8122,7 +8123,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
checkManifestShortcuts_immutable_verify();
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertCannotUpdateImmutable(() -> {
mManager.removeDynamicShortcuts(list("s1", "ms1"));
});
@@ -8132,14 +8133,14 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
checkManifestShortcuts_immutable_verify();
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertCannotUpdateImmutable(() -> {
mManager.disableShortcuts(list("s1", "ms1"));
});
});
checkManifestShortcuts_immutable_verify();
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertCannotUpdateImmutable(() -> {
mManager.enableShortcuts(list("s1", "ms2"));
});
@@ -8155,16 +8156,16 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
// Change the max number of shortcuts.
mService.updateConfigurationLocked(ConfigConstants.KEY_MAX_SHORTCUTS + "=3");
- mService.handleUnlockUser(USER_0);
+ mService.handleUnlockUser(USER_10);
addManifestShortcutResource(
new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
R.xml.shortcut_5);
updatePackageVersion(CALLING_PACKAGE_1, 1);
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
// Only the first 3 should be published.
assertShortcutIds(mManager.getManifestShortcuts(), "ms1", "ms2", "ms3");
});
@@ -8174,7 +8175,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
// Change the max number of shortcuts.
mService.updateConfigurationLocked(ConfigConstants.KEY_MAX_SHORTCUTS + "=3");
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
final ComponentName a1 = new ComponentName(mClientContext, ShortcutActivity.class);
final ComponentName a2 = new ComponentName(mClientContext, ShortcutActivity2.class);
final ShortcutInfo s1_1 = makeShortcutWithActivity("s11", a1);
@@ -8232,7 +8233,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
R.xml.shortcut_2);
updatePackageVersion(CALLING_PACKAGE_1, 1);
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
assertEquals(2, mManager.getManifestShortcuts().size());
// Setting 1 to activity 1 will work.
@@ -8255,7 +8256,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
// Change the max number of shortcuts.
mService.updateConfigurationLocked(ConfigConstants.KEY_MAX_SHORTCUTS + "=3");
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
final ComponentName a1 = new ComponentName(mClientContext, ShortcutActivity.class);
final ComponentName a2 = new ComponentName(mClientContext, ShortcutActivity2.class);
final ShortcutInfo s1_1 = makeShortcutWithActivity("s11", a1);
@@ -8305,9 +8306,9 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
// Make sure pinned shortcuts won't affect.
// - Pin s11 - s13, and remove all dynamic.
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s11", "s12", "s13"),
- HANDLE_USER_0);
+ HANDLE_USER_10);
});
mManager.removeAllDynamicShortcuts();
@@ -8358,7 +8359,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
R.xml.shortcut_2);
updatePackageVersion(CALLING_PACKAGE_1, 1);
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
assertEquals(2, mManager.getManifestShortcuts().size());
@@ -8382,7 +8383,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
// Change the max number of shortcuts.
mService.updateConfigurationLocked(ConfigConstants.KEY_MAX_SHORTCUTS + "=3");
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
final ComponentName a1 = new ComponentName(mClientContext, ShortcutActivity.class);
final ComponentName a2 = new ComponentName(mClientContext, ShortcutActivity2.class);
final ShortcutInfo s1_1 = makeShortcutWithActivity("s11", a1);
@@ -8431,9 +8432,9 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
"s11", "s12", "s13", "s21", "s22", "s23");
// Pin some to have more shortcuts for a1.
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s11", "s12", "s13"),
- HANDLE_USER_0);
+ HANDLE_USER_10);
});
mManager.setDynamicShortcuts(list(s1_4, s1_5, s2_1, s2_2, s2_3));
assertShortcutIds(mManager.getDynamicShortcuts(),
@@ -8473,7 +8474,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
// Change the max number of shortcuts.
mService.updateConfigurationLocked(ConfigConstants.KEY_MAX_SHORTCUTS + "=3");
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
final ComponentName a1 = new ComponentName(mClientContext, ShortcutActivity.class);
final ComponentName a2 = new ComponentName(mClientContext, ShortcutActivity2.class);
final ShortcutInfo s1_1 = makeShortcutWithActivityAndRank("s11", a1, 4);
@@ -8489,9 +8490,9 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
// Initial state.
mManager.setDynamicShortcuts(list(s1_1, s1_2, s1_3, s2_1, s2_2, s2_3));
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s11", "s12", "s21", "s22"),
- HANDLE_USER_0);
+ HANDLE_USER_10);
});
mManager.setDynamicShortcuts(list(s1_2, s1_3, s1_4, s2_2, s2_3, s2_4));
assertShortcutIds(assertAllEnabled(mManager.getDynamicShortcuts()),
@@ -8507,7 +8508,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
R.xml.shortcut_1);
updatePackageVersion(CALLING_PACKAGE_1, 1);
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
assertEquals(1, mManager.getManifestShortcuts().size());
// s12 removed.
@@ -8527,7 +8528,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
R.xml.shortcut_1_alt);
updatePackageVersion(CALLING_PACKAGE_1, 1);
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
assertEquals(3, mManager.getManifestShortcuts().size());
// Note the ones with the highest rank values (== least important) will be removed.
@@ -8547,7 +8548,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
R.xml.shortcut_5_alt); // manifest has 5, but max is 3, so a2 will have 3.
updatePackageVersion(CALLING_PACKAGE_1, 1);
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
assertEquals(5, mManager.getManifestShortcuts().size());
assertShortcutIds(assertAllEnabled(mManager.getDynamicShortcuts()),
@@ -8566,7 +8567,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
R.xml.shortcut_0);
updatePackageVersion(CALLING_PACKAGE_1, 1);
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
assertEquals(0, mManager.getManifestShortcuts().size());
assertShortcutIds(assertAllEnabled(mManager.getDynamicShortcuts()),
@@ -8584,9 +8585,9 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
R.xml.shortcut_1);
updatePackageVersion(CALLING_PACKAGE_1, 1);
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertWith(mManager.getManifestShortcuts())
.haveIds("ms1")
.forAllShortcuts(si -> assertTrue(si.isReturnedByServer()));
@@ -8599,21 +8600,21 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
// Pin them.
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
list("ms1", "s1"), getCallingUser());
- assertWith(getShortcutAsLauncher(USER_0))
+ assertWith(getShortcutAsLauncher(USER_10))
.haveIds("ms1", "s1")
.forAllShortcuts(si -> assertTrue(si.isReturnedByServer()));
});
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertWith(mManager.getPinnedShortcuts())
.haveIds("ms1", "s1")
.forAllShortcuts(si -> assertTrue(si.isReturnedByServer()));
});
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
// This shows a warning log, but should still work.
assertTrue(mManager.setDynamicShortcuts(mManager.getDynamicShortcuts()));
@@ -8624,9 +8625,10 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
}
public void IsForegroundDefaultLauncher_true() {
- final int uid = 1024;
+ // random uid in the USER_10 range.
+ final int uid = 1000024;
- setDefaultLauncher(UserHandle.USER_SYSTEM, "default");
+ setDefaultLauncher(USER_10, "default");
makeUidForeground(uid);
assertTrue(mInternal.isForegroundDefaultLauncher("default", uid));
@@ -8634,18 +8636,20 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
public void IsForegroundDefaultLauncher_defaultButNotForeground() {
- final int uid = 1024;
+ // random uid in the USER_10 range.
+ final int uid = 1000024;
- setDefaultLauncher(UserHandle.USER_SYSTEM, "default");
+ setDefaultLauncher(USER_10, "default");
makeUidBackground(uid);
assertFalse(mInternal.isForegroundDefaultLauncher("default", uid));
}
public void IsForegroundDefaultLauncher_foregroundButNotDefault() {
- final int uid = 1024;
+ // random uid in the USER_10 range.
+ final int uid = 1000024;
- setDefaultLauncher(UserHandle.USER_SYSTEM, "default");
+ setDefaultLauncher(USER_10, "default");
makeUidForeground(uid);
assertFalse(mInternal.isForegroundDefaultLauncher("another", uid));
@@ -8670,7 +8674,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
R.xml.shortcut_share_targets);
updatePackageVersion(CALLING_PACKAGE_1, 1);
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
List<ShareTargetInfo> shareTargets = getCallerShareTargets();
@@ -8775,9 +8779,9 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
R.xml.shortcut_share_targets);
updatePackageVersion(CALLING_PACKAGE_1, 1);
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
- setCaller(CALLING_PACKAGE_1, USER_0);
+ setCaller(CALLING_PACKAGE_1, USER_10);
final ShortcutInfo s1 = makeShortcutWithCategory("s1",
set("com.test.category.CATEGORY1", "com.test.category.CATEGORY2"));
@@ -8796,26 +8800,26 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
IntentFilter filter_any = new IntentFilter();
filter_any.addDataType("*/*");
- setCaller(LAUNCHER_1, USER_0);
+ setCaller(LAUNCHER_1, USER_10);
mCallerPermissions.add(permission.MANAGE_APP_PREDICTIONS);
- assertTrue(mInternal.isSharingShortcut(USER_0, LAUNCHER_1, CALLING_PACKAGE_1, "s1", USER_0,
+ assertTrue(mInternal.isSharingShortcut(USER_10, LAUNCHER_1, CALLING_PACKAGE_1, "s1", USER_10,
filter_cat1));
- assertFalse(mInternal.isSharingShortcut(USER_0, LAUNCHER_1, CALLING_PACKAGE_1, "s1", USER_0,
+ assertFalse(mInternal.isSharingShortcut(USER_10, LAUNCHER_1, CALLING_PACKAGE_1, "s1", USER_10,
filter_cat5));
- assertTrue(mInternal.isSharingShortcut(USER_0, LAUNCHER_1, CALLING_PACKAGE_1, "s1", USER_0,
+ assertTrue(mInternal.isSharingShortcut(USER_10, LAUNCHER_1, CALLING_PACKAGE_1, "s1", USER_10,
filter_any));
- assertFalse(mInternal.isSharingShortcut(USER_0, LAUNCHER_1, CALLING_PACKAGE_1, "s2", USER_0,
+ assertFalse(mInternal.isSharingShortcut(USER_10, LAUNCHER_1, CALLING_PACKAGE_1, "s2", USER_10,
filter_cat1));
- assertTrue(mInternal.isSharingShortcut(USER_0, LAUNCHER_1, CALLING_PACKAGE_1, "s2", USER_0,
+ assertTrue(mInternal.isSharingShortcut(USER_10, LAUNCHER_1, CALLING_PACKAGE_1, "s2", USER_10,
filter_cat5));
- assertTrue(mInternal.isSharingShortcut(USER_0, LAUNCHER_1, CALLING_PACKAGE_1, "s2", USER_0,
+ assertTrue(mInternal.isSharingShortcut(USER_10, LAUNCHER_1, CALLING_PACKAGE_1, "s2", USER_10,
filter_any));
- assertFalse(mInternal.isSharingShortcut(USER_0, LAUNCHER_1, CALLING_PACKAGE_1, "s3", USER_0,
+ assertFalse(mInternal.isSharingShortcut(USER_10, LAUNCHER_1, CALLING_PACKAGE_1, "s3", USER_10,
filter_any));
- assertFalse(mInternal.isSharingShortcut(USER_0, LAUNCHER_1, CALLING_PACKAGE_1, "s4", USER_0,
+ assertFalse(mInternal.isSharingShortcut(USER_10, LAUNCHER_1, CALLING_PACKAGE_1, "s4", USER_10,
filter_any));
}
@@ -8826,7 +8830,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
R.xml.shortcut_share_targets);
updatePackageVersion(CALLING_PACKAGE_1, 1);
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
final ShortcutInfo s1 = makeShortcutWithCategory("s1",
set("com.test.category.CATEGORY1", "com.test.category.CATEGORY2"));
@@ -8837,7 +8841,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
s1.setLongLived();
s2.setLongLived();
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(list(s1, s2, s3)));
assertShortcutIds(assertAllNotKeyFieldsOnly(mManager.getDynamicShortcuts()),
"s1", "s2", "s3");
@@ -8846,33 +8850,33 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
IntentFilter filter_any = new IntentFilter();
filter_any.addDataType("*/*");
- setCaller(LAUNCHER_1, USER_0);
+ setCaller(LAUNCHER_1, USER_10);
mCallerPermissions.add(permission.MANAGE_APP_PREDICTIONS);
// Assert all are sharing shortcuts
- assertTrue(mInternal.isSharingShortcut(USER_0, LAUNCHER_1, CALLING_PACKAGE_1, "s1", USER_0,
+ assertTrue(mInternal.isSharingShortcut(USER_10, LAUNCHER_1, CALLING_PACKAGE_1, "s1", USER_10,
filter_any));
- assertTrue(mInternal.isSharingShortcut(USER_0, LAUNCHER_1, CALLING_PACKAGE_1, "s2", USER_0,
+ assertTrue(mInternal.isSharingShortcut(USER_10, LAUNCHER_1, CALLING_PACKAGE_1, "s2", USER_10,
filter_any));
- assertTrue(mInternal.isSharingShortcut(USER_0, LAUNCHER_1, CALLING_PACKAGE_1, "s3", USER_0,
+ assertTrue(mInternal.isSharingShortcut(USER_10, LAUNCHER_1, CALLING_PACKAGE_1, "s3", USER_10,
filter_any));
mInjectCheckAccessShortcutsPermission = true;
- mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s1", "s2"), HANDLE_USER_0,
+ mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s1", "s2"), HANDLE_USER_10,
CACHE_OWNER_0);
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s3"), HANDLE_USER_0);
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s3"), HANDLE_USER_10);
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
// Remove one cached shortcut, and leave one cached-only and pinned-only shortcuts.
mManager.removeLongLivedShortcuts(list("s1"));
mManager.removeDynamicShortcuts(list("s2, s3"));
});
- assertFalse(mInternal.isSharingShortcut(USER_0, LAUNCHER_1, CALLING_PACKAGE_1, "s1", USER_0,
+ assertFalse(mInternal.isSharingShortcut(USER_10, LAUNCHER_1, CALLING_PACKAGE_1, "s1", USER_10,
filter_any));
- assertTrue(mInternal.isSharingShortcut(USER_0, LAUNCHER_1, CALLING_PACKAGE_1, "s2", USER_0,
+ assertTrue(mInternal.isSharingShortcut(USER_10, LAUNCHER_1, CALLING_PACKAGE_1, "s2", USER_10,
filter_any));
- assertTrue(mInternal.isSharingShortcut(USER_0, LAUNCHER_1, CALLING_PACKAGE_1, "s3", USER_0,
+ assertTrue(mInternal.isSharingShortcut(USER_10, LAUNCHER_1, CALLING_PACKAGE_1, "s3", USER_10,
filter_any));
}
@@ -8881,17 +8885,17 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
final ShortcutInfo s2 = makeShortcutExcludedFromLauncher("s2");
final ShortcutInfo s3 = makeShortcutExcludedFromLauncher("s3");
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(list(s1, s2, s3)));
assertEmpty(mManager.getDynamicShortcuts());
});
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.addDynamicShortcuts(list(s1, s2, s3)));
assertEmpty(mManager.getDynamicShortcuts());
});
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
mManager.pushDynamicShortcut(s1);
assertEmpty(mManager.getDynamicShortcuts());
});
@@ -8902,7 +8906,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
final ShortcutInfo s2 = makeShortcut("s2");
final ShortcutInfo s3 = makeShortcut("s3");
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(list(s1, s2, s3)));
assertThrown(IllegalArgumentException.class, () -> {
mManager.updateShortcuts(list(makeShortcutExcludedFromLauncher("s1")));
@@ -8911,7 +8915,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
}
public void PinHiddenShortcuts_ThrowsException() {
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertThrown(IllegalArgumentException.class, () -> {
mManager.requestPinShortcut(makeShortcutExcludedFromLauncher("s1"), null);
});
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest10.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest10.java
index 57ada9b9c499..748f0a5dc949 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest10.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest10.java
@@ -28,7 +28,6 @@ import android.content.pm.LauncherActivityInfo;
import android.content.pm.LauncherApps.PinItemRequest;
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutManager;
-import android.os.Process;
import android.platform.test.annotations.Presubmit;
import androidx.test.filters.SmallTest;
@@ -56,7 +55,7 @@ public class ShortcutManagerTest10 extends BaseShortcutManagerTest {
}
public void testCreateShortcutResult_validResult() {
- setDefaultLauncher(USER_0, LAUNCHER_1);
+ setDefaultLauncher(USER_10, LAUNCHER_1);
runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
ShortcutInfo s1 = makeShortcut("s1");
@@ -64,20 +63,20 @@ public class ShortcutManagerTest10 extends BaseShortcutManagerTest {
mRequest = verifyAndGetCreateShortcutResult(intent);
});
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
assertTrue(mRequest.isValid());
assertTrue(mRequest.accept());
});
}
public void testCreateShortcutResult_alreadyPinned() {
- setDefaultLauncher(USER_0, LAUNCHER_1);
+ setDefaultLauncher(USER_10, LAUNCHER_1);
runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
assertTrue(mManager.setDynamicShortcuts(list(makeShortcut("s1"))));
});
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s1"), HANDLE_USER_P0);
});
@@ -87,7 +86,7 @@ public class ShortcutManagerTest10 extends BaseShortcutManagerTest {
mRequest = verifyAndGetCreateShortcutResult(intent);
});
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
assertTrue(mRequest.isValid());
assertTrue(mRequest.getShortcutInfo().isPinned());
assertTrue(mRequest.accept());
@@ -100,18 +99,18 @@ public class ShortcutManagerTest10 extends BaseShortcutManagerTest {
});
// Initially all launchers have the shortcut permission, until we call setDefaultLauncher().
- runWithCaller(LAUNCHER_2, USER_0, () -> {
+ runWithCaller(LAUNCHER_2, USER_10, () -> {
mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s1"), HANDLE_USER_P0);
});
- setDefaultLauncher(USER_0, LAUNCHER_1);
+ setDefaultLauncher(USER_10, LAUNCHER_1);
runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
ShortcutInfo s1 = makeShortcut("s1");
Intent intent = mManager.createShortcutResultIntent(s1);
mRequest = verifyAndGetCreateShortcutResult(intent);
});
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
assertTrue(mRequest.isValid());
assertFalse(mRequest.getShortcutInfo().isPinned());
assertTrue(mRequest.accept());
@@ -119,7 +118,7 @@ public class ShortcutManagerTest10 extends BaseShortcutManagerTest {
}
public void testCreateShortcutResult_defaultLauncherChanges() {
- setDefaultLauncher(USER_0, LAUNCHER_1);
+ setDefaultLauncher(USER_10, LAUNCHER_1);
runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
ShortcutInfo s1 = makeShortcut("s1");
@@ -127,15 +126,15 @@ public class ShortcutManagerTest10 extends BaseShortcutManagerTest {
mRequest = verifyAndGetCreateShortcutResult(intent);
});
- setDefaultLauncher(USER_0, LAUNCHER_2);
+ setDefaultLauncher(USER_10, LAUNCHER_2);
// Verify that other launcher can't use this request
- runWithCaller(LAUNCHER_2, USER_0, () -> {
+ runWithCaller(LAUNCHER_2, USER_10, () -> {
assertFalse(mRequest.isValid());
assertExpectException(SecurityException.class, "Calling uid mismatch",
mRequest::accept);
});
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
// Set some random caller UID.
mInjectedCallingUid = 12345;
@@ -144,7 +143,7 @@ public class ShortcutManagerTest10 extends BaseShortcutManagerTest {
mRequest::accept);
});
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
assertTrue(mRequest.isValid());
assertTrue(mRequest.accept());
});
@@ -157,23 +156,23 @@ public class ShortcutManagerTest10 extends BaseShortcutManagerTest {
LauncherActivityInfo info = mock(LauncherActivityInfo.class);
when(info.getComponentName()).thenReturn(
new ComponentName(getTestContext(), "a.ShortcutConfigActivity"));
- when(info.getUser()).thenReturn(Process.myUserHandle());
+ when(info.getUser()).thenReturn(HANDLE_USER_10);
return info;
}
public void testStartConfigActivity_defaultLauncher() {
LauncherActivityInfo info = setupMockActivityInfo();
prepareIntentActivities(info.getComponentName());
- setDefaultLauncher(USER_0, LAUNCHER_1);
- runWithCaller(LAUNCHER_1, USER_0, () ->
+ setDefaultLauncher(USER_10, LAUNCHER_1);
+ runWithCaller(LAUNCHER_1, USER_10, () ->
assertNotNull(mLauncherApps.getShortcutConfigActivityIntent(info))
);
}
public void testStartConfigActivity_nonDefaultLauncher() {
LauncherActivityInfo info = setupMockActivityInfo();
- setDefaultLauncher(USER_0, LAUNCHER_1);
- runWithCaller(LAUNCHER_2, USER_0, () ->
+ setDefaultLauncher(USER_10, LAUNCHER_1);
+ runWithCaller(LAUNCHER_2, USER_10, () ->
assertExpectException(SecurityException.class, null, () ->
mLauncherApps.getShortcutConfigActivityIntent(info))
);
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest11.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest11.java
index 98fa2d68fb73..676558ddcf6c 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest11.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest11.java
@@ -56,12 +56,12 @@ public class ShortcutManagerTest11 extends BaseShortcutManagerTest {
public void testShortcutChangeCallback_setDynamicShortcuts() {
ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class);
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL,
mTestLooper.getNewExecutor());
});
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(makeShortcuts("s1", "s2")));
});
@@ -69,7 +69,7 @@ public class ShortcutManagerTest11 extends BaseShortcutManagerTest {
ArgumentCaptor<List> shortcuts = ArgumentCaptor.forClass(List.class);
verify(callback, times(1)).onShortcutsAddedOrUpdated(
- eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_0));
+ eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_10));
verify(callback, times(0)).onShortcutsRemoved(any(), any(), any());
assertWith(shortcuts.getValue())
@@ -78,17 +78,17 @@ public class ShortcutManagerTest11 extends BaseShortcutManagerTest {
}
public void testShortcutChangeCallback_setDynamicShortcuts_replaceSameId() {
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(makeShortcuts("s1", "s2")));
});
ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class);
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL,
mTestLooper.getNewExecutor());
});
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(makeShortcuts("s2", "s3")));
});
@@ -96,11 +96,11 @@ public class ShortcutManagerTest11 extends BaseShortcutManagerTest {
ArgumentCaptor<List> changedShortcuts = ArgumentCaptor.forClass(List.class);
verify(callback, times(1)).onShortcutsAddedOrUpdated(
- eq(CALLING_PACKAGE_1), changedShortcuts.capture(), eq(HANDLE_USER_0));
+ eq(CALLING_PACKAGE_1), changedShortcuts.capture(), eq(HANDLE_USER_10));
ArgumentCaptor<List> removedShortcuts = ArgumentCaptor.forClass(List.class);
verify(callback, times(1)).onShortcutsRemoved(
- eq(CALLING_PACKAGE_1), removedShortcuts.capture(), eq(HANDLE_USER_0));
+ eq(CALLING_PACKAGE_1), removedShortcuts.capture(), eq(HANDLE_USER_10));
assertWith(changedShortcuts.getValue())
.areAllWithKeyFieldsOnly()
@@ -112,25 +112,25 @@ public class ShortcutManagerTest11 extends BaseShortcutManagerTest {
}
public void testShortcutChangeCallback_setDynamicShortcuts_pinnedAndCached() {
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(
list(makeShortcut("s1"), makeLongLivedShortcut("s2"))));
});
- runWithCaller(LAUNCHER_1, USER_0, () -> {
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s1"), HANDLE_USER_0);
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s1"), HANDLE_USER_10);
mInjectCheckAccessShortcutsPermission = true;
- mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s2"), HANDLE_USER_0,
+ mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s2"), HANDLE_USER_10,
CACHE_OWNER_0);
});
ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class);
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL,
mTestLooper.getNewExecutor());
});
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(makeShortcuts("s3", "s4")));
});
@@ -138,7 +138,7 @@ public class ShortcutManagerTest11 extends BaseShortcutManagerTest {
ArgumentCaptor<List> changedShortcuts = ArgumentCaptor.forClass(List.class);
verify(callback, times(1)).onShortcutsAddedOrUpdated(
- eq(CALLING_PACKAGE_1), changedShortcuts.capture(), eq(HANDLE_USER_0));
+ eq(CALLING_PACKAGE_1), changedShortcuts.capture(), eq(HANDLE_USER_10));
verify(callback, times(0)).onShortcutsRemoved(any(), any(), any());
assertWith(changedShortcuts.getValue())
@@ -147,22 +147,22 @@ public class ShortcutManagerTest11 extends BaseShortcutManagerTest {
}
public void testShortcutChangeCallback_pinShortcuts() {
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(makeShortcuts("s1", "s2")));
});
ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class);
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL,
mTestLooper.getNewExecutor());
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s1"), HANDLE_USER_0);
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s1"), HANDLE_USER_10);
});
mTestLooper.dispatchAll();
ArgumentCaptor<List> shortcuts = ArgumentCaptor.forClass(List.class);
verify(callback, times(1)).onShortcutsAddedOrUpdated(
- eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_0));
+ eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_10));
verify(callback, times(0)).onShortcutsRemoved(any(), any(), any());
assertWith(shortcuts.getValue())
@@ -171,34 +171,34 @@ public class ShortcutManagerTest11 extends BaseShortcutManagerTest {
}
public void testShortcutChangeCallback_pinShortcuts_unpinOthers() {
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(makeShortcuts("s1", "s2", "s3")));
});
- runWithCaller(LAUNCHER_1, USER_0, () -> {
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s1", "s2"), HANDLE_USER_0);
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s1", "s2"), HANDLE_USER_10);
});
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
mManager.removeDynamicShortcuts(list("s1", "s2"));
});
ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class);
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL,
mTestLooper.getNewExecutor());
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s2", "s3"), HANDLE_USER_0);
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s2", "s3"), HANDLE_USER_10);
});
mTestLooper.dispatchAll();
ArgumentCaptor<List> changedShortcuts = ArgumentCaptor.forClass(List.class);
verify(callback, times(1)).onShortcutsAddedOrUpdated(
- eq(CALLING_PACKAGE_1), changedShortcuts.capture(), eq(HANDLE_USER_0));
+ eq(CALLING_PACKAGE_1), changedShortcuts.capture(), eq(HANDLE_USER_10));
ArgumentCaptor<List> removedShortcuts = ArgumentCaptor.forClass(List.class);
verify(callback, times(1)).onShortcutsRemoved(
- eq(CALLING_PACKAGE_1), removedShortcuts.capture(), eq(HANDLE_USER_0));
+ eq(CALLING_PACKAGE_1), removedShortcuts.capture(), eq(HANDLE_USER_10));
assertWith(changedShortcuts.getValue())
.areAllWithKeyFieldsOnly()
@@ -210,19 +210,19 @@ public class ShortcutManagerTest11 extends BaseShortcutManagerTest {
}
public void testShortcutChangeCallback_cacheShortcuts() {
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(list(makeLongLivedShortcut("s1"),
makeLongLivedShortcut("s2"), makeLongLivedShortcut("s3"))));
});
ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class);
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL,
mTestLooper.getNewExecutor());
mInjectCheckAccessShortcutsPermission = true;
- mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s1", "s3"), HANDLE_USER_0,
+ mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s1", "s3"), HANDLE_USER_10,
CACHE_OWNER_0);
- mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s1", "s3"), HANDLE_USER_0,
+ mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s1", "s3"), HANDLE_USER_10,
CACHE_OWNER_1);
});
@@ -230,7 +230,7 @@ public class ShortcutManagerTest11 extends BaseShortcutManagerTest {
ArgumentCaptor<List> shortcuts = ArgumentCaptor.forClass(List.class);
verify(callback, times(2)).onShortcutsAddedOrUpdated(
- eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_0));
+ eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_10));
verify(callback, times(0)).onShortcutsRemoved(any(), any(), any());
assertWith(shortcuts.getValue())
@@ -239,23 +239,23 @@ public class ShortcutManagerTest11 extends BaseShortcutManagerTest {
}
public void testShortcutChangeCallback_cacheShortcuts_alreadyCached() {
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(list(makeLongLivedShortcut("s1"),
makeLongLivedShortcut("s2"), makeLongLivedShortcut("s3"))));
});
ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class);
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mInjectCheckAccessShortcutsPermission = true;
- mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s1", "s3"), HANDLE_USER_0,
+ mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s1", "s3"), HANDLE_USER_10,
CACHE_OWNER_0);
mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL,
mTestLooper.getNewExecutor());
// Should not cause any callback events
- mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s1", "s3"), HANDLE_USER_0,
+ mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s1", "s3"), HANDLE_USER_10,
CACHE_OWNER_0);
// Should cause a change event
- mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s1", "s3"), HANDLE_USER_0,
+ mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s1", "s3"), HANDLE_USER_10,
CACHE_OWNER_1);
});
@@ -263,7 +263,7 @@ public class ShortcutManagerTest11 extends BaseShortcutManagerTest {
ArgumentCaptor<List> shortcuts = ArgumentCaptor.forClass(List.class);
verify(callback, times(1)).onShortcutsAddedOrUpdated(
- eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_0));
+ eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_10));
verify(callback, times(0)).onShortcutsRemoved(any(), any(), any());
assertWith(shortcuts.getValue())
@@ -272,19 +272,19 @@ public class ShortcutManagerTest11 extends BaseShortcutManagerTest {
}
public void testShortcutChangeCallback_uncacheShortcuts() {
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(list(makeLongLivedShortcut("s1"),
makeLongLivedShortcut("s2"), makeLongLivedShortcut("s3"))));
});
ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class);
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mInjectCheckAccessShortcutsPermission = true;
- mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s1", "s2"), HANDLE_USER_0,
+ mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s1", "s2"), HANDLE_USER_10,
CACHE_OWNER_0);
mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL,
mTestLooper.getNewExecutor());
- mLauncherApps.uncacheShortcuts(CALLING_PACKAGE_1, list("s2"), HANDLE_USER_0,
+ mLauncherApps.uncacheShortcuts(CALLING_PACKAGE_1, list("s2"), HANDLE_USER_10,
CACHE_OWNER_0);
});
@@ -292,7 +292,7 @@ public class ShortcutManagerTest11 extends BaseShortcutManagerTest {
ArgumentCaptor<List> shortcuts = ArgumentCaptor.forClass(List.class);
verify(callback, times(1)).onShortcutsAddedOrUpdated(
- eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_0));
+ eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_10));
verify(callback, times(0)).onShortcutsRemoved(any(), any(), any());
assertWith(shortcuts.getValue())
@@ -301,41 +301,41 @@ public class ShortcutManagerTest11 extends BaseShortcutManagerTest {
}
public void testShortcutChangeCallback_uncacheShortcuts_causeDeletion() {
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(list(makeLongLivedShortcut("s1"),
makeLongLivedShortcut("s2"), makeLongLivedShortcut("s3"))));
});
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mInjectCheckAccessShortcutsPermission = true;
- mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s1", "s2", "s3"), HANDLE_USER_0,
+ mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s1", "s2", "s3"), HANDLE_USER_10,
CACHE_OWNER_0);
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s2"), HANDLE_USER_0);
- mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s1"), HANDLE_USER_0,
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s2"), HANDLE_USER_10);
+ mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s1"), HANDLE_USER_10,
CACHE_OWNER_1);
});
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
mManager.removeDynamicShortcuts(list("s2", "s3"));
});
ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class);
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL,
mTestLooper.getNewExecutor());
- mLauncherApps.uncacheShortcuts(CALLING_PACKAGE_1, list("s1", "s2", "s3"), HANDLE_USER_0,
- CACHE_OWNER_0);
+ mLauncherApps.uncacheShortcuts(CALLING_PACKAGE_1, list("s1", "s2", "s3"),
+ HANDLE_USER_10, CACHE_OWNER_0);
});
mTestLooper.dispatchAll();
ArgumentCaptor<List> changedShortcuts = ArgumentCaptor.forClass(List.class);
verify(callback, times(1)).onShortcutsAddedOrUpdated(
- eq(CALLING_PACKAGE_1), changedShortcuts.capture(), eq(HANDLE_USER_0));
+ eq(CALLING_PACKAGE_1), changedShortcuts.capture(), eq(HANDLE_USER_10));
ArgumentCaptor<List> removedShortcuts = ArgumentCaptor.forClass(List.class);
verify(callback, times(1)).onShortcutsRemoved(
- eq(CALLING_PACKAGE_1), removedShortcuts.capture(), eq(HANDLE_USER_0));
+ eq(CALLING_PACKAGE_1), removedShortcuts.capture(), eq(HANDLE_USER_10));
// s1 is still cached for owner1, s2 is pinned.
assertWith(changedShortcuts.getValue())
@@ -348,19 +348,19 @@ public class ShortcutManagerTest11 extends BaseShortcutManagerTest {
}
public void testShortcutChangeCallback_updateShortcuts() {
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(list(makeShortcut("s1"),
makeShortcutWithActivity("s2", new ComponentName(CALLING_PACKAGE_1, "test")))));
});
ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class);
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL,
mTestLooper.getNewExecutor());
});
final ComponentName updatedCn = new ComponentName(CALLING_PACKAGE_1, "updated activity");
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.updateShortcuts(list(makeShortcutWithActivity("s2", updatedCn))));
});
@@ -368,7 +368,7 @@ public class ShortcutManagerTest11 extends BaseShortcutManagerTest {
ArgumentCaptor<List> shortcuts = ArgumentCaptor.forClass(List.class);
verify(callback, times(1)).onShortcutsAddedOrUpdated(
- eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_0));
+ eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_10));
verify(callback, times(0)).onShortcutsRemoved(any(), any(), any());
assertWith(shortcuts.getValue())
@@ -378,17 +378,17 @@ public class ShortcutManagerTest11 extends BaseShortcutManagerTest {
}
public void testShortcutChangeCallback_addDynamicShortcuts() {
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(makeShortcuts("s1")));
});
ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class);
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL,
mTestLooper.getNewExecutor());
});
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.addDynamicShortcuts(makeShortcuts("s1", "s2")));
});
@@ -396,7 +396,7 @@ public class ShortcutManagerTest11 extends BaseShortcutManagerTest {
ArgumentCaptor<List> shortcuts = ArgumentCaptor.forClass(List.class);
verify(callback, times(1)).onShortcutsAddedOrUpdated(
- eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_0));
+ eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_10));
verify(callback, times(0)).onShortcutsRemoved(any(), any(), any());
assertWith(shortcuts.getValue())
@@ -406,12 +406,12 @@ public class ShortcutManagerTest11 extends BaseShortcutManagerTest {
public void testShortcutChangeCallback_pushDynamicShortcut() {
ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class);
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL,
mTestLooper.getNewExecutor());
});
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
mManager.pushDynamicShortcut(makeShortcut("s1"));
});
@@ -419,7 +419,7 @@ public class ShortcutManagerTest11 extends BaseShortcutManagerTest {
ArgumentCaptor<List> shortcuts = ArgumentCaptor.forClass(List.class);
verify(callback, times(1)).onShortcutsAddedOrUpdated(
- eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_0));
+ eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_10));
verify(callback, times(0)).onShortcutsRemoved(any(), any(), any());
assertWith(shortcuts.getValue())
@@ -431,17 +431,17 @@ public class ShortcutManagerTest11 extends BaseShortcutManagerTest {
// Change the max number of shortcuts.
mService.updateConfigurationLocked(ConfigConstants.KEY_MAX_SHORTCUTS + "=3");
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts((makeShortcuts("s1", "s2", "s3"))));
});
ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class);
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL,
mTestLooper.getNewExecutor());
});
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
mManager.pushDynamicShortcut(makeShortcut("s2"));
});
@@ -449,7 +449,7 @@ public class ShortcutManagerTest11 extends BaseShortcutManagerTest {
ArgumentCaptor<List> shortcuts = ArgumentCaptor.forClass(List.class);
verify(callback, times(1)).onShortcutsAddedOrUpdated(
- eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_0));
+ eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_10));
verify(callback, times(0)).onShortcutsRemoved(any(), any(), any());
assertWith(shortcuts.getValue())
@@ -461,17 +461,17 @@ public class ShortcutManagerTest11 extends BaseShortcutManagerTest {
// Change the max number of shortcuts.
mService.updateConfigurationLocked(ConfigConstants.KEY_MAX_SHORTCUTS + "=3");
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts((makeShortcuts("s1", "s2", "s3"))));
});
ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class);
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL,
mTestLooper.getNewExecutor());
});
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
mManager.pushDynamicShortcut(makeShortcut("s4"));
});
@@ -479,11 +479,11 @@ public class ShortcutManagerTest11 extends BaseShortcutManagerTest {
ArgumentCaptor<List> changedShortcuts = ArgumentCaptor.forClass(List.class);
verify(callback, times(1)).onShortcutsAddedOrUpdated(
- eq(CALLING_PACKAGE_1), changedShortcuts.capture(), eq(HANDLE_USER_0));
+ eq(CALLING_PACKAGE_1), changedShortcuts.capture(), eq(HANDLE_USER_10));
ArgumentCaptor<List> removedShortcuts = ArgumentCaptor.forClass(List.class);
verify(callback, times(1)).onShortcutsRemoved(
- eq(CALLING_PACKAGE_1), removedShortcuts.capture(), eq(HANDLE_USER_0));
+ eq(CALLING_PACKAGE_1), removedShortcuts.capture(), eq(HANDLE_USER_10));
assertWith(changedShortcuts.getValue())
.areAllWithKeyFieldsOnly()
@@ -498,7 +498,7 @@ public class ShortcutManagerTest11 extends BaseShortcutManagerTest {
// Change the max number of shortcuts.
mService.updateConfigurationLocked(ConfigConstants.KEY_MAX_SHORTCUTS + "=3");
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts((makeShortcuts("s1", "s2"))));
ShortcutInfo s3 = makeLongLivedShortcut("s3");
s3.setRank(3);
@@ -506,15 +506,15 @@ public class ShortcutManagerTest11 extends BaseShortcutManagerTest {
});
ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class);
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mInjectCheckAccessShortcutsPermission = true;
- mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s3"), HANDLE_USER_0,
+ mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s3"), HANDLE_USER_10,
CACHE_OWNER_0);
mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL,
mTestLooper.getNewExecutor());
});
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
mManager.pushDynamicShortcut(makeShortcut("s4"));
});
@@ -522,7 +522,7 @@ public class ShortcutManagerTest11 extends BaseShortcutManagerTest {
ArgumentCaptor<List> shortcuts = ArgumentCaptor.forClass(List.class);
verify(callback, times(1)).onShortcutsAddedOrUpdated(
- eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_0));
+ eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_10));
verify(callback, times(0)).onShortcutsRemoved(any(), any(), any());
assertWith(shortcuts.getValue())
@@ -532,17 +532,17 @@ public class ShortcutManagerTest11 extends BaseShortcutManagerTest {
public void testShortcutChangeCallback_disableShortcuts() {
updatePackageVersion(CALLING_PACKAGE_1, 1);
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(makeShortcuts("s1", "s2")));
});
ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class);
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL,
mTestLooper.getNewExecutor());
});
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
mManager.disableShortcuts(list("s2"));
});
@@ -552,7 +552,7 @@ public class ShortcutManagerTest11 extends BaseShortcutManagerTest {
ArgumentCaptor<List> shortcuts = ArgumentCaptor.forClass(List.class);
verify(callback, times(1)).onShortcutsRemoved(
- eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_0));
+ eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_10));
assertWith(shortcuts.getValue())
.areAllWithKeyFieldsOnly()
@@ -560,22 +560,22 @@ public class ShortcutManagerTest11 extends BaseShortcutManagerTest {
}
public void testShortcutChangeCallback_disableShortcuts_pinnedAndCached() {
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(
list(makeShortcut("s1"), makeLongLivedShortcut("s2"), makeShortcut("s3"))));
});
ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class);
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mInjectCheckAccessShortcutsPermission = true;
- mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s2"), HANDLE_USER_0,
+ mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s2"), HANDLE_USER_10,
CACHE_OWNER_0);
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s3"), HANDLE_USER_0);
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s3"), HANDLE_USER_10);
mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL,
mTestLooper.getNewExecutor());
});
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
mManager.disableShortcuts(list("s1", "s2", "s3"));
});
@@ -583,11 +583,11 @@ public class ShortcutManagerTest11 extends BaseShortcutManagerTest {
ArgumentCaptor<List> changedShortcuts = ArgumentCaptor.forClass(List.class);
verify(callback, times(1)).onShortcutsAddedOrUpdated(
- eq(CALLING_PACKAGE_1), changedShortcuts.capture(), eq(HANDLE_USER_0));
+ eq(CALLING_PACKAGE_1), changedShortcuts.capture(), eq(HANDLE_USER_10));
ArgumentCaptor<List> removedShortcuts = ArgumentCaptor.forClass(List.class);
verify(callback, times(1)).onShortcutsRemoved(
- eq(CALLING_PACKAGE_1), removedShortcuts.capture(), eq(HANDLE_USER_0));
+ eq(CALLING_PACKAGE_1), removedShortcuts.capture(), eq(HANDLE_USER_10));
assertWith(changedShortcuts.getValue())
.areAllWithKeyFieldsOnly()
@@ -599,29 +599,29 @@ public class ShortcutManagerTest11 extends BaseShortcutManagerTest {
}
public void testShortcutChangeCallback_enableShortcuts() {
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(
list(makeShortcut("s1"), makeLongLivedShortcut("s2"), makeShortcut("s3"))));
});
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mInjectCheckAccessShortcutsPermission = true;
- mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s2"), HANDLE_USER_0,
+ mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s2"), HANDLE_USER_10,
CACHE_OWNER_0);
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s3"), HANDLE_USER_0);
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s3"), HANDLE_USER_10);
});
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
mManager.disableShortcuts(list("s1", "s2", "s3"));
});
ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class);
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL,
mTestLooper.getNewExecutor());
});
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
mManager.enableShortcuts(list("s1", "s2", "s3"));
});
@@ -629,7 +629,7 @@ public class ShortcutManagerTest11 extends BaseShortcutManagerTest {
ArgumentCaptor<List> shortcuts = ArgumentCaptor.forClass(List.class);
verify(callback, times(1)).onShortcutsAddedOrUpdated(
- eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_0));
+ eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_10));
verify(callback, times(0)).onShortcutsRemoved(any(), any(), any());
assertWith(shortcuts.getValue())
@@ -639,17 +639,17 @@ public class ShortcutManagerTest11 extends BaseShortcutManagerTest {
public void testShortcutChangeCallback_removeDynamicShortcuts() {
updatePackageVersion(CALLING_PACKAGE_1, 1);
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(makeShortcuts("s1", "s2")));
});
ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class);
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL,
mTestLooper.getNewExecutor());
});
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
mManager.removeDynamicShortcuts(list("s2"));
});
@@ -659,7 +659,7 @@ public class ShortcutManagerTest11 extends BaseShortcutManagerTest {
ArgumentCaptor<List> shortcuts = ArgumentCaptor.forClass(List.class);
verify(callback, times(1)).onShortcutsRemoved(
- eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_0));
+ eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_10));
assertWith(shortcuts.getValue())
.areAllWithKeyFieldsOnly()
@@ -667,22 +667,22 @@ public class ShortcutManagerTest11 extends BaseShortcutManagerTest {
}
public void testShortcutChangeCallback_removeDynamicShortcuts_pinnedAndCached() {
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(list(makeShortcut("s1"),
makeLongLivedShortcut("s2"), makeShortcut("s3"), makeShortcut("s4"))));
});
ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class);
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mInjectCheckAccessShortcutsPermission = true;
- mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s2"), HANDLE_USER_0,
+ mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s2"), HANDLE_USER_10,
CACHE_OWNER_0);
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s3"), HANDLE_USER_0);
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s3"), HANDLE_USER_10);
mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL,
mTestLooper.getNewExecutor());
});
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
mManager.removeDynamicShortcuts(list("s1", "s2", "s3"));
});
@@ -690,11 +690,11 @@ public class ShortcutManagerTest11 extends BaseShortcutManagerTest {
ArgumentCaptor<List> changedShortcuts = ArgumentCaptor.forClass(List.class);
verify(callback, times(1)).onShortcutsAddedOrUpdated(
- eq(CALLING_PACKAGE_1), changedShortcuts.capture(), eq(HANDLE_USER_0));
+ eq(CALLING_PACKAGE_1), changedShortcuts.capture(), eq(HANDLE_USER_10));
ArgumentCaptor<List> removedShortcuts = ArgumentCaptor.forClass(List.class);
verify(callback, times(1)).onShortcutsRemoved(
- eq(CALLING_PACKAGE_1), removedShortcuts.capture(), eq(HANDLE_USER_0));
+ eq(CALLING_PACKAGE_1), removedShortcuts.capture(), eq(HANDLE_USER_10));
assertWith(changedShortcuts.getValue())
.areAllWithKeyFieldsOnly()
@@ -707,17 +707,17 @@ public class ShortcutManagerTest11 extends BaseShortcutManagerTest {
public void testShortcutChangeCallback_removeAllDynamicShortcuts() {
updatePackageVersion(CALLING_PACKAGE_1, 1);
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(makeShortcuts("s1", "s2")));
});
ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class);
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL,
mTestLooper.getNewExecutor());
});
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
mManager.removeAllDynamicShortcuts();
});
@@ -727,7 +727,7 @@ public class ShortcutManagerTest11 extends BaseShortcutManagerTest {
ArgumentCaptor<List> shortcuts = ArgumentCaptor.forClass(List.class);
verify(callback, times(1)).onShortcutsRemoved(
- eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_0));
+ eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_10));
assertWith(shortcuts.getValue())
.areAllWithKeyFieldsOnly()
@@ -735,22 +735,22 @@ public class ShortcutManagerTest11 extends BaseShortcutManagerTest {
}
public void testShortcutChangeCallback_removeAllDynamicShortcuts_pinnedAndCached() {
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(
list(makeShortcut("s1"), makeLongLivedShortcut("s2"), makeShortcut("s3"))));
});
ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class);
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mInjectCheckAccessShortcutsPermission = true;
- mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s2"), HANDLE_USER_0,
+ mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s2"), HANDLE_USER_10,
CACHE_OWNER_0);
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s3"), HANDLE_USER_0);
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s3"), HANDLE_USER_10);
mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL,
mTestLooper.getNewExecutor());
});
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
mManager.removeAllDynamicShortcuts();
});
@@ -758,11 +758,11 @@ public class ShortcutManagerTest11 extends BaseShortcutManagerTest {
ArgumentCaptor<List> changedShortcuts = ArgumentCaptor.forClass(List.class);
verify(callback, times(1)).onShortcutsAddedOrUpdated(
- eq(CALLING_PACKAGE_1), changedShortcuts.capture(), eq(HANDLE_USER_0));
+ eq(CALLING_PACKAGE_1), changedShortcuts.capture(), eq(HANDLE_USER_10));
ArgumentCaptor<List> removedShortcuts = ArgumentCaptor.forClass(List.class);
verify(callback, times(1)).onShortcutsRemoved(
- eq(CALLING_PACKAGE_1), removedShortcuts.capture(), eq(HANDLE_USER_0));
+ eq(CALLING_PACKAGE_1), removedShortcuts.capture(), eq(HANDLE_USER_10));
assertWith(changedShortcuts.getValue())
.areAllWithKeyFieldsOnly()
@@ -775,18 +775,18 @@ public class ShortcutManagerTest11 extends BaseShortcutManagerTest {
public void testShortcutChangeCallback_removeLongLivedShortcuts_notCached() {
updatePackageVersion(CALLING_PACKAGE_1, 1);
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(list(makeShortcut("s1"),
makeLongLivedShortcut("s2"), makeShortcut("s3"))));
});
ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class);
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL,
mTestLooper.getNewExecutor());
});
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
mManager.removeLongLivedShortcuts(list("s1", "s2"));
});
@@ -796,7 +796,7 @@ public class ShortcutManagerTest11 extends BaseShortcutManagerTest {
ArgumentCaptor<List> shortcuts = ArgumentCaptor.forClass(List.class);
verify(callback, times(1)).onShortcutsRemoved(
- eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_0));
+ eq(CALLING_PACKAGE_1), shortcuts.capture(), eq(HANDLE_USER_10));
assertWith(shortcuts.getValue())
.areAllWithKeyFieldsOnly()
@@ -804,22 +804,22 @@ public class ShortcutManagerTest11 extends BaseShortcutManagerTest {
}
public void testShortcutChangeCallback_removeLongLivedShortcuts_pinnedAndCached() {
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(list(makeShortcut("s1"),
makeLongLivedShortcut("s2"), makeShortcut("s3"), makeShortcut("s4"))));
});
ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class);
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mInjectCheckAccessShortcutsPermission = true;
- mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s2"), HANDLE_USER_0,
+ mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s2"), HANDLE_USER_10,
CACHE_OWNER_0);
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s3"), HANDLE_USER_0);
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s3"), HANDLE_USER_10);
mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL,
mTestLooper.getNewExecutor());
});
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
mManager.removeLongLivedShortcuts(list("s1", "s2", "s3"));
});
@@ -827,11 +827,11 @@ public class ShortcutManagerTest11 extends BaseShortcutManagerTest {
ArgumentCaptor<List> changedShortcuts = ArgumentCaptor.forClass(List.class);
verify(callback, times(1)).onShortcutsAddedOrUpdated(
- eq(CALLING_PACKAGE_1), changedShortcuts.capture(), eq(HANDLE_USER_0));
+ eq(CALLING_PACKAGE_1), changedShortcuts.capture(), eq(HANDLE_USER_10));
ArgumentCaptor<List> removedShortcuts = ArgumentCaptor.forClass(List.class);
verify(callback, times(1)).onShortcutsRemoved(
- eq(CALLING_PACKAGE_1), removedShortcuts.capture(), eq(HANDLE_USER_0));
+ eq(CALLING_PACKAGE_1), removedShortcuts.capture(), eq(HANDLE_USER_10));
assertWith(changedShortcuts.getValue())
.areAllWithKeyFieldsOnly()
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest12.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest12.java
index 78bcf0c692b8..10e8bf039627 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest12.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest12.java
@@ -50,21 +50,21 @@ public class ShortcutManagerTest12 extends BaseShortcutManagerTest {
@Override
protected void tearDown() throws Exception {
if (mService.isAppSearchEnabled()) {
- setCaller(CALLING_PACKAGE_1, USER_0);
- mService.getPackageShortcutForTest(CALLING_PACKAGE_1, USER_0)
+ setCaller(CALLING_PACKAGE_1, USER_10);
+ mService.getPackageShortcutForTest(CALLING_PACKAGE_1, USER_10)
.removeAllShortcutsAsync();
}
super.tearDown();
}
public void testGetShortcutIntents_ReturnsMutablePendingIntents() throws RemoteException {
- setDefaultLauncher(USER_0, LAUNCHER_1);
+ setDefaultLauncher(USER_10, LAUNCHER_1);
- runWithCaller(CALLING_PACKAGE_1, USER_0, () ->
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () ->
assertTrue(mManager.setDynamicShortcuts(list(makeShortcut("s1"))))
);
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
final PendingIntent intent = mLauncherApps.getShortcutIntent(
CALLING_PACKAGE_1, "s1", null, UserHandle.SYSTEM);
assertNotNull(intent);
@@ -75,7 +75,7 @@ public class ShortcutManagerTest12 extends BaseShortcutManagerTest {
if (!mService.isAppSearchEnabled()) {
return;
}
- setCaller(CALLING_PACKAGE_1, USER_0);
+ setCaller(CALLING_PACKAGE_1, USER_10);
// Verifies setDynamicShortcuts persists shortcuts into AppSearch
mManager.setDynamicShortcuts(list(
makeShortcut("s1"),
@@ -102,7 +102,7 @@ public class ShortcutManagerTest12 extends BaseShortcutManagerTest {
if (!mService.isAppSearchEnabled()) {
return;
}
- setCaller(CALLING_PACKAGE_1, USER_0);
+ setCaller(CALLING_PACKAGE_1, USER_10);
mManager.setDynamicShortcuts(list(
makeShortcut("s1"),
makeShortcut("s2"),
@@ -126,7 +126,7 @@ public class ShortcutManagerTest12 extends BaseShortcutManagerTest {
if (!mService.isAppSearchEnabled()) {
return;
}
- setCaller(CALLING_PACKAGE_1, USER_0);
+ setCaller(CALLING_PACKAGE_1, USER_10);
mManager.setDynamicShortcuts(list(
makeShortcut("s1"),
makeShortcut("s2"),
@@ -168,7 +168,7 @@ public class ShortcutManagerTest12 extends BaseShortcutManagerTest {
if (!mService.isAppSearchEnabled()) {
return;
}
- setCaller(CALLING_PACKAGE_1, USER_0);
+ setCaller(CALLING_PACKAGE_1, USER_10);
mManager.setDynamicShortcuts(list(
makeShortcut("s1"),
makeShortcut("s2"),
@@ -194,7 +194,7 @@ public class ShortcutManagerTest12 extends BaseShortcutManagerTest {
if (!mService.isAppSearchEnabled()) {
return;
}
- setCaller(CALLING_PACKAGE_1, USER_0);
+ setCaller(CALLING_PACKAGE_1, USER_10);
mManager.setDynamicShortcuts(list(
makeShortcut("s1"),
makeShortcut("s2"),
@@ -218,7 +218,7 @@ public class ShortcutManagerTest12 extends BaseShortcutManagerTest {
if (!mService.isAppSearchEnabled()) {
return;
}
- setCaller(CALLING_PACKAGE_1, USER_0);
+ setCaller(CALLING_PACKAGE_1, USER_10);
mManager.setDynamicShortcuts(list(
makeShortcut("s1"),
makeShortcut("s2"),
@@ -243,7 +243,7 @@ public class ShortcutManagerTest12 extends BaseShortcutManagerTest {
if (!mService.isAppSearchEnabled()) {
return;
}
- setCaller(CALLING_PACKAGE_1, USER_0);
+ setCaller(CALLING_PACKAGE_1, USER_10);
mManager.setDynamicShortcuts(list(
makeShortcut("s1"),
makeShortcut("s2"),
@@ -266,7 +266,7 @@ public class ShortcutManagerTest12 extends BaseShortcutManagerTest {
if (!mService.isAppSearchEnabled()) {
return;
}
- setCaller(CALLING_PACKAGE_1, USER_0);
+ setCaller(CALLING_PACKAGE_1, USER_10);
mManager.setDynamicShortcuts(list(
makeShortcutExcludedFromLauncher("s1"),
makeShortcutExcludedFromLauncher("s2"),
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
index 1cfaf7c83584..9528467f7ad1 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
@@ -238,15 +238,15 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
}
public void testShortcutInfoParcel() {
- setCaller(CALLING_PACKAGE_1, USER_10);
+ setCaller(CALLING_PACKAGE_1, USER_11);
ShortcutInfo si = parceled(new ShortcutInfo.Builder(mClientContext)
.setId("id")
.setTitle("title")
.setIntent(makeIntent("action", ShortcutActivity.class))
.build());
assertEquals(mClientContext.getPackageName(), si.getPackage());
- assertEquals(USER_10, si.getUserId());
- assertEquals(HANDLE_USER_10, si.getUserHandle());
+ assertEquals(USER_11, si.getUserId());
+ assertEquals(HANDLE_USER_11, si.getUserHandle());
assertEquals("id", si.getId());
assertEquals("title", si.getTitle());
assertEquals("action", si.getIntent().getAction());
@@ -325,7 +325,7 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
}
public void testShortcutInfoParcel_resId() {
- setCaller(CALLING_PACKAGE_1, USER_10);
+ setCaller(CALLING_PACKAGE_1, USER_11);
ShortcutInfo si;
PersistableBundle pb = new PersistableBundle();
@@ -379,7 +379,7 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
}
public void testShortcutInfoClone() {
- setCaller(CALLING_PACKAGE_1, USER_11);
+ setCaller(CALLING_PACKAGE_1, USER_12);
PersistableBundle pb = new PersistableBundle();
pb.putInt("k", 1);
@@ -406,8 +406,8 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
ShortcutInfo si = sorig.clone(/* clone flags*/ 0);
- assertEquals(USER_11, si.getUserId());
- assertEquals(HANDLE_USER_11, si.getUserHandle());
+ assertEquals(USER_12, si.getUserId());
+ assertEquals(HANDLE_USER_12, si.getUserHandle());
assertEquals(mClientContext.getPackageName(), si.getPackage());
assertEquals("id", si.getId());
assertEquals(new ComponentName("a", "b"), si.getActivity());
@@ -527,7 +527,7 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
}
public void testShortcutInfoClone_resId() {
- setCaller(CALLING_PACKAGE_1, USER_11);
+ setCaller(CALLING_PACKAGE_1, USER_12);
PersistableBundle pb = new PersistableBundle();
pb.putInt("k", 1);
@@ -552,8 +552,8 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
ShortcutInfo si = sorig.clone(/* clone flags*/ 0);
- assertEquals(USER_11, si.getUserId());
- assertEquals(HANDLE_USER_11, si.getUserHandle());
+ assertEquals(USER_12, si.getUserId());
+ assertEquals(HANDLE_USER_12, si.getUserHandle());
assertEquals(mClientContext.getPackageName(), si.getPackage());
assertEquals("id", si.getId());
assertEquals(new ComponentName("a", "b"), si.getActivity());
@@ -953,9 +953,9 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
}
public void testShortcutInfoSaveAndLoad() throws InterruptedException {
- mRunningUsers.put(USER_10, true);
+ mRunningUsers.put(USER_11, true);
- setCaller(CALLING_PACKAGE_1, USER_10);
+ setCaller(CALLING_PACKAGE_1, USER_11);
final Icon bmp32x32 = Icon.createWithBitmap(BitmapFactory.decodeResource(
getTestContext().getResources(), R.drawable.black_32x32));
@@ -1010,16 +1010,16 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
// Save and load.
mService.saveDirtyInfo();
initService();
- mService.handleUnlockUser(USER_10);
+ mService.handleUnlockUser(USER_11);
- dumpUserFile(USER_10);
+ dumpUserFile(USER_11);
dumpsysOnLogcat("after load");
ShortcutInfo si;
- si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id", USER_10);
+ si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id", USER_11);
- assertEquals(USER_10, si.getUserId());
- assertEquals(HANDLE_USER_10, si.getUserHandle());
+ assertEquals(USER_11, si.getUserId());
+ assertEquals(HANDLE_USER_11, si.getUserHandle());
assertEquals(CALLING_PACKAGE_1, si.getPackage());
assertEquals("id", si.getId());
assertEquals(ShortcutActivity2.class.getName(), si.getActivity().getClassName());
@@ -1056,19 +1056,19 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
// Make sure ranks are saved too. Because of the auto-adjusting, we need two shortcuts
// to test it.
- si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id2", USER_10);
+ si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id2", USER_11);
assertEquals(1, si.getRank());
assertEquals(2, si.getPersons().length);
assertEquals("personUri2", si.getPersons()[1].getUri());
assertEquals("6.7.8.9", si.getLocusId().getId());
- dumpUserFile(USER_10);
+ dumpUserFile(USER_11);
}
public void testShortcutInfoSaveAndLoad_maskableBitmap() throws InterruptedException {
- mRunningUsers.put(USER_10, true);
+ mRunningUsers.put(USER_11, true);
- setCaller(CALLING_PACKAGE_1, USER_10);
+ setCaller(CALLING_PACKAGE_1, USER_11);
final Icon bmp32x32 = Icon.createWithAdaptiveBitmap(BitmapFactory.decodeResource(
getTestContext().getResources(), R.drawable.black_32x32));
@@ -1100,16 +1100,16 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
// Save and load.
mService.saveDirtyInfo();
initService();
- mService.handleUnlockUser(USER_10);
+ mService.handleUnlockUser(USER_11);
- dumpUserFile(USER_10);
+ dumpUserFile(USER_11);
dumpsysOnLogcat("after load");
ShortcutInfo si;
- si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id", USER_10);
+ si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id", USER_11);
- assertEquals(USER_10, si.getUserId());
- assertEquals(HANDLE_USER_10, si.getUserHandle());
+ assertEquals(USER_11, si.getUserId());
+ assertEquals(HANDLE_USER_11, si.getUserHandle());
assertEquals(CALLING_PACKAGE_1, si.getPackage());
assertEquals("id", si.getId());
assertEquals(ShortcutActivity2.class.getName(), si.getActivity().getClassName());
@@ -1131,13 +1131,13 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
assertNull(si.getIconUri());
assertTrue(si.getLastChangedTimestamp() < now);
- dumpUserFile(USER_10);
+ dumpUserFile(USER_11);
}
public void testShortcutInfoSaveAndLoad_resId() throws InterruptedException {
- mRunningUsers.put(USER_10, true);
+ mRunningUsers.put(USER_11, true);
- setCaller(CALLING_PACKAGE_1, USER_10);
+ setCaller(CALLING_PACKAGE_1, USER_11);
final Icon res32x32 = Icon.createWithResource(mClientContext, R.drawable.black_32x32);
@@ -1175,13 +1175,13 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
// Save and load.
mService.saveDirtyInfo();
initService();
- mService.handleUnlockUser(USER_10);
+ mService.handleUnlockUser(USER_11);
ShortcutInfo si;
- si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id", USER_10);
+ si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id", USER_11);
- assertEquals(USER_10, si.getUserId());
- assertEquals(HANDLE_USER_10, si.getUserHandle());
+ assertEquals(USER_11, si.getUserId());
+ assertEquals(HANDLE_USER_11, si.getUserHandle());
assertEquals(CALLING_PACKAGE_1, si.getPackage());
assertEquals("id", si.getId());
assertEquals(ShortcutActivity2.class.getName(), si.getActivity().getClassName());
@@ -1207,14 +1207,14 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
// Make sure ranks are saved too. Because of the auto-adjusting, we need two shortcuts
// to test it.
- si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id2", USER_10);
+ si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id2", USER_11);
assertEquals(1, si.getRank());
}
public void testShortcutInfoSaveAndLoad_uri() throws InterruptedException {
- mRunningUsers.put(USER_10, true);
+ mRunningUsers.put(USER_11, true);
- setCaller(CALLING_PACKAGE_1, USER_10);
+ setCaller(CALLING_PACKAGE_1, USER_11);
final Icon uriIcon = Icon.createWithContentUri("test_uri");
@@ -1255,13 +1255,13 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
// Save and load.
mService.saveDirtyInfo();
initService();
- mService.handleUnlockUser(USER_10);
+ mService.handleUnlockUser(USER_11);
ShortcutInfo si;
- si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id", USER_10);
+ si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id", USER_11);
- assertEquals(USER_10, si.getUserId());
- assertEquals(HANDLE_USER_10, si.getUserHandle());
+ assertEquals(USER_11, si.getUserId());
+ assertEquals(HANDLE_USER_11, si.getUserHandle());
assertEquals(CALLING_PACKAGE_1, si.getPackage());
assertEquals("id", si.getId());
assertEquals(ShortcutActivity2.class.getName(), si.getActivity().getClassName());
@@ -1288,7 +1288,7 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
// Make sure ranks are saved too. Because of the auto-adjusting, we need two shortcuts
// to test it.
- si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id2", USER_10);
+ si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id2", USER_11);
assertEquals(1, si.getRank());
assertEquals(ShortcutInfo.FLAG_DYNAMIC | ShortcutInfo.FLAG_HAS_ICON_URI
| ShortcutInfo.FLAG_STRINGS_RESOLVED | ShortcutInfo.FLAG_ADAPTIVE_BITMAP,
@@ -1300,7 +1300,7 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
}
public void testShortcutInfoSaveAndLoad_forBackup() {
- setCaller(CALLING_PACKAGE_1, USER_0);
+ setCaller(CALLING_PACKAGE_1, USER_10);
final Icon bmp32x32 = Icon.createWithBitmap(BitmapFactory.decodeResource(
getTestContext().getResources(), R.drawable.black_32x32));
@@ -1332,16 +1332,16 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
mManager.addDynamicShortcuts(list(sorig, sorig2));
// Dynamic shortcuts won't be backed up, so we need to pin it.
- setCaller(LAUNCHER_1, USER_0);
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("id", "id2"), HANDLE_USER_0);
+ setCaller(LAUNCHER_1, USER_10);
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("id", "id2"), HANDLE_USER_10);
// Do backup & restore.
backupAndRestore();
- mService.handleUnlockUser(USER_0); // Load user-0.
+ mService.handleUnlockUser(USER_10); // Load user-0.
ShortcutInfo si;
- si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id", USER_0);
+ si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id", USER_10);
assertEquals(CALLING_PACKAGE_1, si.getPackage());
assertEquals("id", si.getId());
@@ -1364,12 +1364,12 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
assertNull(si.getIconUri());
// Note when restored from backup, it's no longer dynamic, so shouldn't have a rank.
- si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id2", USER_0);
+ si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id2", USER_10);
assertEquals(0, si.getRank());
}
public void testShortcutInfoSaveAndLoad_forBackup_resId() {
- setCaller(CALLING_PACKAGE_1, USER_0);
+ setCaller(CALLING_PACKAGE_1, USER_10);
final Icon res32x32 = Icon.createWithResource(mClientContext, R.drawable.black_32x32);
@@ -1399,16 +1399,16 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
mManager.addDynamicShortcuts(list(sorig, sorig2));
// Dynamic shortcuts won't be backed up, so we need to pin it.
- setCaller(LAUNCHER_1, USER_0);
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("id", "id2"), HANDLE_USER_0);
+ setCaller(LAUNCHER_1, USER_10);
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("id", "id2"), HANDLE_USER_10);
// Do backup & restore.
backupAndRestore();
- mService.handleUnlockUser(USER_0); // Load user-0.
+ mService.handleUnlockUser(USER_10); // Load user-0.
ShortcutInfo si;
- si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id", USER_0);
+ si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id", USER_10);
assertEquals(CALLING_PACKAGE_1, si.getPackage());
assertEquals("id", si.getId());
@@ -1434,12 +1434,12 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
assertNull(si.getIconUri());
// Note when restored from backup, it's no longer dynamic, so shouldn't have a rank.
- si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id2", USER_0);
+ si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id2", USER_10);
assertEquals(0, si.getRank());
}
public void testShortcutInfoSaveAndLoad_forBackup_uri() {
- setCaller(CALLING_PACKAGE_1, USER_0);
+ setCaller(CALLING_PACKAGE_1, USER_10);
final Icon uriIcon = Icon.createWithContentUri("test_uri");
@@ -1469,16 +1469,16 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
mManager.addDynamicShortcuts(list(sorig, sorig2));
// Dynamic shortcuts won't be backed up, so we need to pin it.
- setCaller(LAUNCHER_1, USER_0);
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("id", "id2"), HANDLE_USER_0);
+ setCaller(LAUNCHER_1, USER_10);
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("id", "id2"), HANDLE_USER_10);
// Do backup & restore.
backupAndRestore();
- mService.handleUnlockUser(USER_0); // Load user-0.
+ mService.handleUnlockUser(USER_10); // Load user-0.
ShortcutInfo si;
- si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id", USER_0);
+ si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id", USER_10);
assertEquals(CALLING_PACKAGE_1, si.getPackage());
assertEquals("id", si.getId());
@@ -1504,7 +1504,7 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
assertNull(si.getIconUri());
// Note when restored from backup, it's no longer dynamic, so shouldn't have a rank.
- si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id2", USER_0);
+ si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id2", USER_10);
assertEquals(0, si.getRank());
}
@@ -1512,7 +1512,7 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcutWithIntent("s1", intent))));
initService();
- mService.handleUnlockUser(USER_0);
+ mService.handleUnlockUser(USER_10);
assertWith(getCallerShortcuts())
.haveIds("s1")
@@ -1528,7 +1528,7 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcutWithIntents("s1", intents))));
initService();
- mService.handleUnlockUser(USER_0);
+ mService.handleUnlockUser(USER_10);
assertWith(getCallerShortcuts())
.haveIds("s1")
@@ -1804,35 +1804,35 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
// but it will work for other users too because we check the locale change at any
// API entry point.
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertEquals(3, mManager.getRemainingCallCount());
});
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
assertEquals(3, mManager.getRemainingCallCount());
});
- runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_3, USER_10, () -> {
assertEquals(3, mManager.getRemainingCallCount());
});
- runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_4, USER_10, () -> {
assertEquals(3, mManager.getRemainingCallCount());
});
runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
assertEquals(3, mManager.getRemainingCallCount());
});
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
assertEquals(3, mManager.getRemainingCallCount());
});
// Make sure even if we receive ACTION_LOCALE_CHANGED, if the locale hasn't actually
// changed, we don't reset throttling.
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
mManager.updateShortcuts(list());
assertEquals(2, mManager.getRemainingCallCount());
});
mService.mReceiver.onReceive(mServiceContext, new Intent(Intent.ACTION_LOCALE_CHANGED));
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertEquals(2, mManager.getRemainingCallCount()); // Still 2.
});
@@ -1842,7 +1842,7 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
// The locale should be persisted, so it still shouldn't reset throttling.
mService.mReceiver.onReceive(mServiceContext, new Intent(Intent.ACTION_LOCALE_CHANGED));
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertEquals(2, mManager.getRemainingCallCount()); // Still 2.
});
}
@@ -1861,22 +1861,22 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
// First, all packages have less than 3 (== initial value) remaining calls.
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
});
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
});
- runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_3, USER_10, () -> {
MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
});
- runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_4, USER_10, () -> {
MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
});
runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
});
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
});
@@ -1886,22 +1886,22 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
mService.mUidObserver.onUidStateChanged(
CALLING_UID_1, ActivityManager.PROCESS_STATE_TOP_SLEEPING, 0,
ActivityManager.PROCESS_CAPABILITY_NONE);
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
});
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
});
- runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_3, USER_10, () -> {
MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
});
- runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_4, USER_10, () -> {
MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
});
runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
});
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
});
@@ -1911,22 +1911,22 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
mService.mUidObserver.onUidStateChanged(
CALLING_UID_1, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0,
ActivityManager.PROCESS_CAPABILITY_NONE);
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertEquals(3, mManager.getRemainingCallCount());
});
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
});
- runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_3, USER_10, () -> {
MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
});
- runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_4, USER_10, () -> {
MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
});
runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
});
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
});
mService.mUidObserver.onUidStateChanged(
@@ -1944,22 +1944,22 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
CALLING_UID_2, ActivityManager.PROCESS_STATE_TOP_SLEEPING, 0,
ActivityManager.PROCESS_CAPABILITY_NONE);
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertEquals(3, mManager.getRemainingCallCount());
});
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
assertEquals(3, mManager.getRemainingCallCount());
});
- runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_3, USER_10, () -> {
MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
});
- runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_4, USER_10, () -> {
MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
});
runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
});
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
});
@@ -1967,7 +1967,7 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
// Do the same thing one more time. This would catch the bug with mixuing up
// the current time and the elapsed time.
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
mManager.updateShortcuts(list(makeShortcut("s")));
MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
});
@@ -1979,22 +1979,22 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
CALLING_UID_2, ActivityManager.PROCESS_STATE_TOP_SLEEPING, 0,
ActivityManager.PROCESS_CAPABILITY_NONE);
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertEquals(3, mManager.getRemainingCallCount());
});
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
assertEquals(3, mManager.getRemainingCallCount());
});
- runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_3, USER_10, () -> {
MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
});
- runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_4, USER_10, () -> {
MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
});
runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
});
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
});
@@ -2003,10 +2003,10 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
// Package 1 on user-10 comes to foreground.
// Now, also try calling some APIs and make sure foreground apps don't get throttled.
mService.mUidObserver.onUidStateChanged(
- UserHandle.getUid(USER_10, CALLING_UID_1),
+ UserHandle.getUid(USER_11, CALLING_UID_1),
ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0,
ActivityManager.PROCESS_CAPABILITY_NONE);
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertEquals(3, mManager.getRemainingCallCount());
assertFalse(mManager.isRateLimitingActive());
@@ -2025,7 +2025,7 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
assertEquals(0, mManager.getRemainingCallCount());
assertTrue(mManager.isRateLimitingActive());
});
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
assertEquals(3, mManager.getRemainingCallCount());
mManager.setDynamicShortcuts(list(makeShortcut("s")));
@@ -2035,7 +2035,7 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
assertEquals(0, mManager.getRemainingCallCount());
assertTrue(mManager.isRateLimitingActive());
});
- runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_3, USER_10, () -> {
MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
mManager.setDynamicShortcuts(list(makeShortcut("s")));
@@ -2045,7 +2045,7 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
assertEquals(0, mManager.getRemainingCallCount());
assertTrue(mManager.isRateLimitingActive());
});
- runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_4, USER_10, () -> {
MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
mManager.setDynamicShortcuts(list(makeShortcut("s")));
@@ -2065,7 +2065,7 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
assertEquals(0, mManager.getRemainingCallCount());
assertTrue(mManager.isRateLimitingActive());
});
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
assertEquals(3, mManager.getRemainingCallCount());
mManager.setDynamicShortcuts(list(makeShortcut("s")));
@@ -2088,95 +2088,95 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
// First, all packages have less than 3 (== initial value) remaining calls.
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
});
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
});
- runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_3, USER_10, () -> {
MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
});
- runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_4, USER_10, () -> {
MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
});
runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
});
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
});
// Simulate a call from sys UI.
mCallerPermissions.add(permission.RESET_SHORTCUT_MANAGER_THROTTLING);
- mManager.onApplicationActive(CALLING_PACKAGE_1, USER_0);
+ mManager.onApplicationActive(CALLING_PACKAGE_1, USER_10);
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertEquals(3, mManager.getRemainingCallCount());
});
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
});
- runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_3, USER_10, () -> {
MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
});
- runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_4, USER_10, () -> {
MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
});
runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
});
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
});
- mManager.onApplicationActive(CALLING_PACKAGE_3, USER_0);
+ mManager.onApplicationActive(CALLING_PACKAGE_3, USER_10);
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertEquals(3, mManager.getRemainingCallCount());
});
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
});
- runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_3, USER_10, () -> {
assertEquals(3, mManager.getRemainingCallCount());
});
- runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_4, USER_10, () -> {
MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
});
runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
});
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
});
- mManager.onApplicationActive(CALLING_PACKAGE_1, USER_10);
+ mManager.onApplicationActive(CALLING_PACKAGE_1, USER_11);
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertEquals(3, mManager.getRemainingCallCount());
});
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
});
- runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_3, USER_10, () -> {
assertEquals(3, mManager.getRemainingCallCount());
});
- runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_4, USER_10, () -> {
MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
});
runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
});
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
assertEquals(3, mManager.getRemainingCallCount());
});
}
public void testReportShortcutUsed() {
- mRunningUsers.put(USER_10, true);
+ mRunningUsers.put(USER_11, true);
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
reset(mMockUsageStatsManagerInternal);
// Report with an nonexistent shortcut.
@@ -2192,9 +2192,9 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
mManager.reportShortcutUsed("s2");
verify(mMockUsageStatsManagerInternal, times(1)).reportShortcutUsage(
- eq(CALLING_PACKAGE_1), eq("s2"), eq(USER_10));
+ eq(CALLING_PACKAGE_1), eq("s2"), eq(USER_11));
});
- runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_11, () -> {
// Try with a different package.
reset(mMockUsageStatsManagerInternal);
@@ -2211,7 +2211,7 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
mManager.reportShortcutUsed("s3");
verify(mMockUsageStatsManagerInternal, times(1)).reportShortcutUsage(
- eq(CALLING_PACKAGE_2), eq("s3"), eq(USER_10));
+ eq(CALLING_PACKAGE_2), eq("s3"), eq(USER_11));
});
}
@@ -2333,7 +2333,7 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
final Icon bmp64x64 = Icon.createWithBitmap(BitmapFactory.decodeResource(
getTestContext().getResources(), R.drawable.black_64x64));
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcutWithIcon("res32x32", res32x32),
makeShortcutWithIcon("res64x64", res64x64),
@@ -2342,9 +2342,9 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
});
// We can't predict the compressed bitmap sizes, so get the real sizes here.
- final long bitmapTotal =
- new File(getBitmapAbsPath(USER_0, CALLING_PACKAGE_2, "bmp32x32")).length() +
- new File(getBitmapAbsPath(USER_0, CALLING_PACKAGE_2, "bmp64x64")).length();
+ final long bitmapTotal = new File(getBitmapAbsPath(
+ USER_10, CALLING_PACKAGE_2, "bmp32x32")).length() + new File(
+ getBitmapAbsPath(USER_10, CALLING_PACKAGE_2, "bmp64x64")).length();
// Read the expected output and inject the bitmap size.
final String expected = readTestAsset("shortcut/dumpsys_expected.txt")
@@ -2358,15 +2358,15 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
* can still be read.
*/
public void testLoadLegacySavedFile() throws Exception {
- final File path = mService.getUserFile(USER_0).getBaseFile();
+ final File path = mService.getUserFile(USER_10).getBaseFile();
path.getParentFile().mkdirs();
try (Writer w = new FileWriter(path)) {
w.write(readTestAsset("shortcut/shortcut_legacy_file.xml"));
};
initService();
- mService.handleUnlockUser(USER_0);
+ mService.handleUnlockUser(USER_10);
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertWith(getCallerShortcuts())
.haveIds("manifest-shortcut-storage")
.forShortcutWithId("manifest-shortcut-storage", si -> {
@@ -2381,58 +2381,58 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
mRunningUsers.clear();
mUnlockedUsers.clear();
- assertFalse(mService.isUserUnlockedL(USER_0));
assertFalse(mService.isUserUnlockedL(USER_10));
+ assertFalse(mService.isUserUnlockedL(USER_11));
// Start user 0, still locked.
- mRunningUsers.put(USER_0, true);
- assertFalse(mService.isUserUnlockedL(USER_0));
+ mRunningUsers.put(USER_10, true);
assertFalse(mService.isUserUnlockedL(USER_10));
+ assertFalse(mService.isUserUnlockedL(USER_11));
// Unlock user.
- mUnlockedUsers.put(USER_0, true);
- assertTrue(mService.isUserUnlockedL(USER_0));
- assertFalse(mService.isUserUnlockedL(USER_10));
+ mUnlockedUsers.put(USER_10, true);
+ assertTrue(mService.isUserUnlockedL(USER_10));
+ assertFalse(mService.isUserUnlockedL(USER_11));
// Clear again.
mRunningUsers.clear();
mUnlockedUsers.clear();
// Directly call the lifecycle event. Now also locked.
- mService.handleUnlockUser(USER_0);
- assertTrue(mService.isUserUnlockedL(USER_0));
- assertFalse(mService.isUserUnlockedL(USER_10));
+ mService.handleUnlockUser(USER_10);
+ assertTrue(mService.isUserUnlockedL(USER_10));
+ assertFalse(mService.isUserUnlockedL(USER_11));
// Directly call the stop lifecycle event. Goes back to the initial state.
- mService.handleStopUser(USER_0);
- assertFalse(mService.isUserUnlockedL(USER_0));
+ mService.handleStopUser(USER_10);
assertFalse(mService.isUserUnlockedL(USER_10));
+ assertFalse(mService.isUserUnlockedL(USER_11));
}
public void testEphemeralApp() {
- mRunningUsers.put(USER_10, true); // this test needs user 10.
+ mRunningUsers.put(USER_11, true); // this test needs user 10.
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertWith(mManager.getDynamicShortcuts()).isEmpty();
});
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
assertWith(mManager.getDynamicShortcuts()).isEmpty();
});
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
assertWith(mManager.getDynamicShortcuts()).isEmpty();
});
// Make package 1 ephemeral.
- mEphemeralPackages.add(UserPackage.of(USER_0, CALLING_PACKAGE_1));
+ mEphemeralPackages.add(UserPackage.of(USER_10, CALLING_PACKAGE_1));
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertExpectException(IllegalStateException.class, "Ephemeral apps", () -> {
mManager.getDynamicShortcuts();
});
});
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
assertWith(mManager.getDynamicShortcuts()).isEmpty();
});
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
assertWith(mManager.getDynamicShortcuts()).isEmpty();
});
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest3.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest3.java
index 43e527c3d706..aad06c6d6c0e 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest3.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest3.java
@@ -70,14 +70,14 @@ public class ShortcutManagerTest3 extends BaseShortcutManagerTest {
+ ConfigConstants.KEY_MAX_SHORTCUTS + "=99999999"
);
- setCaller(CALLING_PACKAGE, USER_0);
+ setCaller(CALLING_PACKAGE, USER_10);
}
private void publishManifestShortcuts(ComponentName activity, int resId) {
addManifestShortcutResource(activity, resId);
updatePackageVersion(CALLING_PACKAGE, 1);
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageAddIntent(CALLING_PACKAGE, USER_0));
+ genPackageAddIntent(CALLING_PACKAGE, USER_10));
}
public void testSetDynamicShortcuts_noManifestShortcuts() {
@@ -299,8 +299,8 @@ public class ShortcutManagerTest3 extends BaseShortcutManagerTest {
.isEmpty();
- runWithCaller(LAUNCHER_1, USER_0, () -> {
- mLauncherApps.pinShortcuts(CALLING_PACKAGE, list("s2", "s4", "x2"), HANDLE_USER_0);
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE, list("s2", "s4", "x2"), HANDLE_USER_10);
});
// Still same order.
assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
@@ -408,9 +408,9 @@ public class ShortcutManagerTest3 extends BaseShortcutManagerTest {
assertWith(getCallerShortcuts()).selectDynamic().selectByChangedSince(lastApiTime)
.isEmpty();
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mLauncherApps.pinShortcuts(
- CALLING_PACKAGE, list("s2", "s4", "x1", "x2"), HANDLE_USER_0);
+ CALLING_PACKAGE, list("s2", "s4", "x1", "x2"), HANDLE_USER_10);
});
// Still same order.
@@ -483,8 +483,8 @@ public class ShortcutManagerTest3 extends BaseShortcutManagerTest {
assertWith(getCallerShortcuts()).selectDynamic().selectByChangedSince(lastApiTime)
.haveIds("s2", "s4");
- runWithCaller(LAUNCHER_1, USER_0, () -> {
- mLauncherApps.pinShortcuts(CALLING_PACKAGE, list("s2", "s4", "x2"), HANDLE_USER_0);
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE, list("s2", "s4", "x2"), HANDLE_USER_10);
});
// Still same order.
assertWith(getCallerShortcuts()).selectDynamic().selectByActivity(A1)
@@ -518,7 +518,7 @@ public class ShortcutManagerTest3 extends BaseShortcutManagerTest {
R.xml.shortcut_share_targets);
updatePackageVersion(CALLING_PACKAGE_1, 1);
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
// There are two valid <share-target> definitions in the test manifest with two different
// categories: {"com.test.category.CATEGORY1", "com.test.category.CATEGORY2"} and
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest4.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest4.java
index 11a2a8a39a46..42c1767023f1 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest4.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest4.java
@@ -116,7 +116,7 @@ public class ShortcutManagerTest4 extends BaseShortcutManagerTest {
final Intent intent = new Intent(Intent.ACTION_MAIN)
.putExtras(sIntentExtras);
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcutWithExtras("s1", intent, sShortcutExtras),
makeShortcut("s{\u0000}{\u0001}{\uD800\uDC00}x[\uD801][\uDC01]")
@@ -125,9 +125,9 @@ public class ShortcutManagerTest4 extends BaseShortcutManagerTest {
// Make sure save & load works fine. (i.e. shouldn't crash even with invalid characters.)
initService();
- mService.handleUnlockUser(USER_0);
+ mService.handleUnlockUser(USER_10);
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertWith(getCallerShortcuts())
.haveIds("s1", "s{\u0000}{\u0001}{\uD800\uDC00}x[?][?]")
.forShortcutWithId("s1", si -> {
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest6.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest6.java
index 6c10bfd274da..7f7a4ae13245 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest6.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest6.java
@@ -28,59 +28,59 @@ import androidx.test.filters.SmallTest;
public class ShortcutManagerTest6 extends BaseShortcutManagerTest {
public void testHasShortcutHostPermissionInner_with3pLauncher_complicated() {
// Set the default launcher.
- prepareGetRoleHoldersAsUser(CALLING_PACKAGE_2, USER_0);
- assertFalse(mService.hasShortcutHostPermissionInner(PACKAGE_SYSTEM_LAUNCHER, USER_0));
- assertFalse(mService.hasShortcutHostPermissionInner(PACKAGE_FALLBACK_LAUNCHER, USER_0));
- assertFalse(mService.hasShortcutHostPermissionInner(CALLING_PACKAGE_1, USER_0));
- assertTrue(mService.hasShortcutHostPermissionInner(CALLING_PACKAGE_2, USER_0));
+ prepareGetRoleHoldersAsUser(CALLING_PACKAGE_2, USER_10);
+ assertFalse(mService.hasShortcutHostPermissionInner(PACKAGE_SYSTEM_LAUNCHER, USER_10));
+ assertFalse(mService.hasShortcutHostPermissionInner(PACKAGE_FALLBACK_LAUNCHER, USER_10));
+ assertFalse(mService.hasShortcutHostPermissionInner(CALLING_PACKAGE_1, USER_10));
+ assertTrue(mService.hasShortcutHostPermissionInner(CALLING_PACKAGE_2, USER_10));
// Last known launcher should be set.
assertEquals(CALLING_PACKAGE_2,
- mService.getUserShortcutsLocked(USER_0).getCachedLauncher());
+ mService.getUserShortcutsLocked(USER_10).getCachedLauncher());
// Now the default launcher has changed.
- prepareGetRoleHoldersAsUser(CALLING_PACKAGE_1, USER_0);
+ prepareGetRoleHoldersAsUser(CALLING_PACKAGE_1, USER_10);
- assertTrue(mService.hasShortcutHostPermissionInner(CALLING_PACKAGE_1, USER_0));
+ assertTrue(mService.hasShortcutHostPermissionInner(CALLING_PACKAGE_1, USER_10));
// Last known launcher should be set.
assertEquals(CALLING_PACKAGE_1,
- mService.getUserShortcutsLocked(USER_0).getCachedLauncher());
+ mService.getUserShortcutsLocked(USER_10).getCachedLauncher());
// Change the default launcher again.
prepareGetRoleHoldersAsUser(
- getSystemLauncher().activityInfo.getComponentName().getPackageName(), USER_0);
+ getSystemLauncher().activityInfo.getComponentName().getPackageName(), USER_10);
- assertTrue(mService.hasShortcutHostPermissionInner(PACKAGE_SYSTEM_LAUNCHER, USER_0));
- assertFalse(mService.hasShortcutHostPermissionInner(CALLING_PACKAGE_1, USER_0));
+ assertTrue(mService.hasShortcutHostPermissionInner(PACKAGE_SYSTEM_LAUNCHER, USER_10));
+ assertFalse(mService.hasShortcutHostPermissionInner(CALLING_PACKAGE_1, USER_10));
// Last known launcher should be set to default.
assertEquals(PACKAGE_SYSTEM_LAUNCHER,
- mService.getUserShortcutsLocked(USER_0).getCachedLauncher());
+ mService.getUserShortcutsLocked(USER_10).getCachedLauncher());
}
public void testHasShortcutHostPermissionInner_multiUser() {
- mRunningUsers.put(USER_10, true);
+ mRunningUsers.put(USER_11, true);
- prepareGetRoleHoldersAsUser(PACKAGE_FALLBACK_LAUNCHER, USER_0);
- prepareGetRoleHoldersAsUser(CALLING_PACKAGE_2, USER_10);
+ prepareGetRoleHoldersAsUser(PACKAGE_FALLBACK_LAUNCHER, USER_10);
+ prepareGetRoleHoldersAsUser(CALLING_PACKAGE_2, USER_11);
- assertFalse(mService.hasShortcutHostPermissionInner(PACKAGE_SYSTEM_LAUNCHER, USER_0));
- assertTrue(mService.hasShortcutHostPermissionInner(PACKAGE_FALLBACK_LAUNCHER, USER_0));
- assertFalse(mService.hasShortcutHostPermissionInner(CALLING_PACKAGE_1, USER_0));
- assertFalse(mService.hasShortcutHostPermissionInner(CALLING_PACKAGE_2, USER_0));
+ assertFalse(mService.hasShortcutHostPermissionInner(PACKAGE_SYSTEM_LAUNCHER, USER_10));
+ assertTrue(mService.hasShortcutHostPermissionInner(PACKAGE_FALLBACK_LAUNCHER, USER_10));
+ assertFalse(mService.hasShortcutHostPermissionInner(CALLING_PACKAGE_1, USER_10));
+ assertFalse(mService.hasShortcutHostPermissionInner(CALLING_PACKAGE_2, USER_10));
// Last known launcher should be set.
assertEquals(PACKAGE_FALLBACK_LAUNCHER,
- mService.getUserShortcutsLocked(USER_0).getCachedLauncher());
+ mService.getUserShortcutsLocked(USER_10).getCachedLauncher());
- assertFalse(mService.hasShortcutHostPermissionInner(PACKAGE_SYSTEM_LAUNCHER, USER_10));
- assertFalse(mService.hasShortcutHostPermissionInner(PACKAGE_FALLBACK_LAUNCHER, USER_10));
- assertFalse(mService.hasShortcutHostPermissionInner(CALLING_PACKAGE_1, USER_10));
- assertTrue(mService.hasShortcutHostPermissionInner(CALLING_PACKAGE_2, USER_10));
+ assertFalse(mService.hasShortcutHostPermissionInner(PACKAGE_SYSTEM_LAUNCHER, USER_11));
+ assertFalse(mService.hasShortcutHostPermissionInner(PACKAGE_FALLBACK_LAUNCHER, USER_11));
+ assertFalse(mService.hasShortcutHostPermissionInner(CALLING_PACKAGE_1, USER_11));
+ assertTrue(mService.hasShortcutHostPermissionInner(CALLING_PACKAGE_2, USER_11));
// Last known launcher should be set.
assertEquals(CALLING_PACKAGE_2,
- mService.getUserShortcutsLocked(USER_10).getCachedLauncher());
+ mService.getUserShortcutsLocked(USER_11).getCachedLauncher());
}
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest7.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest7.java
index 161b18c80e77..86bde837bfe1 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest7.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest7.java
@@ -131,20 +131,20 @@ public class ShortcutManagerTest7 extends BaseShortcutManagerTest {
public void testResetThrottling() throws Exception {
prepareCrossProfileDataSet();
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.getRemainingCallCount() < 3);
});
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
assertTrue(mManager.getRemainingCallCount() < 3);
});
mInjectedCallingUid = Process.SHELL_UID;
- assertSuccess(callShellCommand("reset-throttling"));
+ assertSuccess(callShellCommand("reset-throttling", "--user", "10"));
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertEquals(3, mManager.getRemainingCallCount());
});
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
assertTrue(mManager.getRemainingCallCount() < 3);
});
}
@@ -152,27 +152,27 @@ public class ShortcutManagerTest7 extends BaseShortcutManagerTest {
public void testResetThrottling_user_not_running() throws Exception {
prepareCrossProfileDataSet();
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.getRemainingCallCount() < 3);
});
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
assertTrue(mManager.getRemainingCallCount() < 3);
});
mInjectedCallingUid = Process.SHELL_UID;
- mRunningUsers.put(USER_10, false);
+ mRunningUsers.put(USER_11, false);
assertTrue(resultContains(
- callShellCommand("reset-throttling", "--user", "10"),
- "User (with userId=10) is not running or locked"));
+ callShellCommand("reset-throttling", "--user", "11"),
+ "User (with userId=11) is not running or locked"));
- mRunningUsers.put(USER_10, true);
+ mRunningUsers.put(USER_11, true);
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.getRemainingCallCount() < 3);
});
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
assertTrue(mManager.getRemainingCallCount() < 3);
});
}
@@ -180,23 +180,23 @@ public class ShortcutManagerTest7 extends BaseShortcutManagerTest {
public void testResetThrottling_user_running() throws Exception {
prepareCrossProfileDataSet();
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.getRemainingCallCount() < 3);
});
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
assertTrue(mManager.getRemainingCallCount() < 3);
});
- mRunningUsers.put(USER_10, true);
- mUnlockedUsers.put(USER_10, true);
+ mRunningUsers.put(USER_11, true);
+ mUnlockedUsers.put(USER_11, true);
mInjectedCallingUid = Process.SHELL_UID;
- assertSuccess(callShellCommand("reset-throttling", "--user", "10"));
+ assertSuccess(callShellCommand("reset-throttling", "--user", "11"));
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.getRemainingCallCount() < 3);
});
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
assertEquals(3, mManager.getRemainingCallCount());
});
}
@@ -204,81 +204,81 @@ public class ShortcutManagerTest7 extends BaseShortcutManagerTest {
public void testResetAllThrottling() throws Exception {
prepareCrossProfileDataSet();
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.getRemainingCallCount() < 3);
});
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
assertTrue(mManager.getRemainingCallCount() < 3);
});
mInjectedCallingUid = Process.SHELL_UID;
assertSuccess(callShellCommand("reset-all-throttling"));
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertEquals(3, mManager.getRemainingCallCount());
});
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
assertEquals(3, mManager.getRemainingCallCount());
});
}
// This command is deprecated. Will remove the test later.
public void testLauncherCommands() throws Exception {
- prepareGetRoleHoldersAsUser(getSystemLauncher().activityInfo.packageName, USER_0);
+ prepareGetRoleHoldersAsUser(getSystemLauncher().activityInfo.packageName, USER_10);
prepareGetHomeActivitiesAsUser(
/* preferred */ getSystemLauncher().activityInfo.getComponentName(),
list(getSystemLauncher(), getFallbackLauncher()),
- USER_0);
+ USER_10);
- prepareGetRoleHoldersAsUser(CALLING_PACKAGE_2, USER_10);
+ prepareGetRoleHoldersAsUser(CALLING_PACKAGE_2, USER_11);
prepareGetHomeActivitiesAsUser(
/* preferred */ cn(CALLING_PACKAGE_2, "name"),
list(getSystemLauncher(), getFallbackLauncher(),
ri(CALLING_PACKAGE_1, "name", false, 0),
ri(CALLING_PACKAGE_2, "name", false, 0)
),
- USER_10);
+ USER_11);
// First, test "get".
- mRunningUsers.put(USER_10, true);
- mUnlockedUsers.put(USER_10, true);
+ mRunningUsers.put(USER_11, true);
+ mUnlockedUsers.put(USER_11, true);
mInjectedCallingUid = Process.SHELL_UID;
assertContains(
- assertSuccess(callShellCommand("get-default-launcher")),
+ assertSuccess(callShellCommand("get-default-launcher", "--user", "10")),
"Launcher: ComponentInfo{com.android.systemlauncher/systemlauncher_name}");
assertContains(
- assertSuccess(callShellCommand("get-default-launcher", "--user", "10")),
+ assertSuccess(callShellCommand("get-default-launcher", "--user", "11")),
"Launcher: ComponentInfo{com.android.test.2/name}");
// Change user-0's launcher.
- prepareGetRoleHoldersAsUser(CALLING_PACKAGE_1, USER_0);
+ prepareGetRoleHoldersAsUser(CALLING_PACKAGE_1, USER_10);
prepareGetHomeActivitiesAsUser(
/* preferred */ cn(CALLING_PACKAGE_1, "name"),
list(ri(CALLING_PACKAGE_1, "name", false, 0)),
- USER_0);
+ USER_10);
assertContains(
- assertSuccess(callShellCommand("get-default-launcher")),
+ assertSuccess(callShellCommand("get-default-launcher", "--user", "10")),
"Launcher: ComponentInfo{com.android.test.1/name}");
}
public void testUnloadUser() throws Exception {
prepareCrossProfileDataSet();
- assertNotNull(mService.getShortcutsForTest().get(USER_10));
+ assertNotNull(mService.getShortcutsForTest().get(USER_11));
- mRunningUsers.put(USER_10, true);
- mUnlockedUsers.put(USER_10, true);
+ mRunningUsers.put(USER_11, true);
+ mUnlockedUsers.put(USER_11, true);
mInjectedCallingUid = Process.SHELL_UID;
- assertSuccess(callShellCommand("unload-user", "--user", "10"));
+ assertSuccess(callShellCommand("unload-user", "--user", "11"));
- assertNull(mService.getShortcutsForTest().get(USER_10));
+ assertNull(mService.getShortcutsForTest().get(USER_11));
}
public void testClearShortcuts() throws Exception {
- mRunningUsers.put(USER_10, true);
+ mRunningUsers.put(USER_11, true);
// Add two manifests and two dynamics.
addManifestShortcutResource(
@@ -286,17 +286,17 @@ public class ShortcutManagerTest7 extends BaseShortcutManagerTest {
R.xml.shortcut_2);
updatePackageVersion(CALLING_PACKAGE_1, 1);
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_11));
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
assertTrue(mManager.addDynamicShortcuts(list(
makeShortcut("s1"), makeShortcut("s2"))));
});
- runWithCaller(LAUNCHER_1, USER_10, () -> {
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("ms2", "s2"), HANDLE_USER_10);
+ runWithCaller(LAUNCHER_1, USER_11, () -> {
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("ms2", "s2"), HANDLE_USER_11);
});
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
assertWith(getCallerShortcuts())
.haveIds("ms1", "ms2", "s1", "s2")
.areAllEnabled()
@@ -307,14 +307,14 @@ public class ShortcutManagerTest7 extends BaseShortcutManagerTest {
// First, call for a different package.
- mRunningUsers.put(USER_10, true);
- mUnlockedUsers.put(USER_10, true);
+ mRunningUsers.put(USER_11, true);
+ mUnlockedUsers.put(USER_11, true);
mInjectedCallingUid = Process.SHELL_UID;
- assertSuccess(callShellCommand("clear-shortcuts", "--user", "10", CALLING_PACKAGE_2));
+ assertSuccess(callShellCommand("clear-shortcuts", "--user", "11", CALLING_PACKAGE_2));
// Shouldn't be cleared yet.
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
assertWith(getCallerShortcuts())
.haveIds("ms1", "ms2", "s1", "s2")
.areAllEnabled()
@@ -324,10 +324,10 @@ public class ShortcutManagerTest7 extends BaseShortcutManagerTest {
});
mInjectedCallingUid = Process.SHELL_UID;
- assertSuccess(callShellCommand("clear-shortcuts", "--user", "10", CALLING_PACKAGE_1));
+ assertSuccess(callShellCommand("clear-shortcuts", "--user", "11", CALLING_PACKAGE_1));
// Only manifest shortcuts will remain, and are no longer pinned.
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
assertWith(getCallerShortcuts())
.haveIds("ms1", "ms2")
.areAllEnabled()
@@ -337,7 +337,7 @@ public class ShortcutManagerTest7 extends BaseShortcutManagerTest {
public void testGetShortcuts() throws Exception {
- mRunningUsers.put(USER_10, true);
+ mRunningUsers.put(USER_11, true);
// Add two manifests and two dynamics.
addManifestShortcutResource(
@@ -345,20 +345,20 @@ public class ShortcutManagerTest7 extends BaseShortcutManagerTest {
R.xml.shortcut_2);
updatePackageVersion(CALLING_PACKAGE_1, 1);
mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageAddIntent(CALLING_PACKAGE_1, USER_10));
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_11));
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
assertTrue(mManager.addDynamicShortcuts(list(
makeLongLivedShortcut("s1"), makeShortcut("s2"))));
});
- runWithCaller(LAUNCHER_1, USER_10, () -> {
+ runWithCaller(LAUNCHER_1, USER_11, () -> {
mInjectCheckAccessShortcutsPermission = true;
- mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s1"), HANDLE_USER_10,
+ mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s1"), HANDLE_USER_11,
CACHE_OWNER);
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("ms2", "s2"), HANDLE_USER_10);
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("ms2", "s2"), HANDLE_USER_11);
});
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
assertWith(getCallerShortcuts())
.haveIds("ms1", "ms2", "s1", "s2")
.areAllEnabled()
@@ -368,33 +368,33 @@ public class ShortcutManagerTest7 extends BaseShortcutManagerTest {
});
- mRunningUsers.put(USER_10, true);
- mUnlockedUsers.put(USER_10, true);
+ mRunningUsers.put(USER_11, true);
+ mUnlockedUsers.put(USER_11, true);
mInjectedCallingUid = Process.SHELL_UID;
- assertHaveIds(callShellCommand("get-shortcuts", "--user", "10", "--flags",
+ assertHaveIds(callShellCommand("get-shortcuts", "--user", "11", "--flags",
Integer.toString(ShortcutManager.FLAG_MATCH_CACHED), CALLING_PACKAGE_1),
"s1");
- assertHaveIds(callShellCommand("get-shortcuts", "--user", "10", "--flags",
+ assertHaveIds(callShellCommand("get-shortcuts", "--user", "11", "--flags",
Integer.toString(ShortcutManager.FLAG_MATCH_DYNAMIC), CALLING_PACKAGE_1),
"s1", "s2");
- assertHaveIds(callShellCommand("get-shortcuts", "--user", "10", "--flags",
+ assertHaveIds(callShellCommand("get-shortcuts", "--user", "11", "--flags",
Integer.toString(ShortcutManager.FLAG_MATCH_MANIFEST), CALLING_PACKAGE_1),
"ms1", "ms2");
- assertHaveIds(callShellCommand("get-shortcuts", "--user", "10", "--flags",
+ assertHaveIds(callShellCommand("get-shortcuts", "--user", "11", "--flags",
Integer.toString(ShortcutManager.FLAG_MATCH_PINNED), CALLING_PACKAGE_1),
"ms2", "s2");
- assertHaveIds(callShellCommand("get-shortcuts", "--user", "10", "--flags",
+ assertHaveIds(callShellCommand("get-shortcuts", "--user", "11", "--flags",
Integer.toString(ShortcutManager.FLAG_MATCH_DYNAMIC
| ShortcutManager.FLAG_MATCH_PINNED), CALLING_PACKAGE_1),
"ms2", "s1", "s2");
- assertHaveIds(callShellCommand("get-shortcuts", "--user", "10", "--flags",
+ assertHaveIds(callShellCommand("get-shortcuts", "--user", "11", "--flags",
Integer.toString(ShortcutManager.FLAG_MATCH_MANIFEST
| ShortcutManager.FLAG_MATCH_CACHED), CALLING_PACKAGE_1),
"ms1", "ms2", "s1");
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest8.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest8.java
index a85c7227b954..9b02a3abf14b 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest8.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest8.java
@@ -85,32 +85,32 @@ public class ShortcutManagerTest8 extends BaseShortcutManagerTest {
}
public void testGetParentOrSelfUserId() {
- assertEquals(USER_0, mService.getParentOrSelfUserId(USER_0));
assertEquals(USER_10, mService.getParentOrSelfUserId(USER_10));
assertEquals(USER_11, mService.getParentOrSelfUserId(USER_11));
- assertEquals(USER_0, mService.getParentOrSelfUserId(USER_P0));
+ assertEquals(USER_12, mService.getParentOrSelfUserId(USER_12));
+ assertEquals(USER_10, mService.getParentOrSelfUserId(USER_P0));
}
public void testIsRequestPinShortcutSupported() {
- setDefaultLauncher(USER_0, LAUNCHER_1);
- setDefaultLauncher(USER_10, LAUNCHER_2);
+ setDefaultLauncher(USER_10, LAUNCHER_1);
+ setDefaultLauncher(USER_11, LAUNCHER_2);
Pair<ComponentName, Integer> actual;
// User 0
- actual = mProcessor.getRequestPinConfirmationActivity(USER_0,
+ actual = mProcessor.getRequestPinConfirmationActivity(USER_10,
PinItemRequest.REQUEST_TYPE_SHORTCUT);
assertEquals(LAUNCHER_1, actual.first.getPackageName());
assertEquals(PIN_CONFIRM_ACTIVITY_CLASS, actual.first.getClassName());
- assertEquals(USER_0, (int) actual.second);
+ assertEquals(USER_10, (int) actual.second);
// User 10
- actual = mProcessor.getRequestPinConfirmationActivity(USER_10,
+ actual = mProcessor.getRequestPinConfirmationActivity(USER_11,
PinItemRequest.REQUEST_TYPE_SHORTCUT);
assertEquals(LAUNCHER_2, actual.first.getPackageName());
assertEquals(PIN_CONFIRM_ACTIVITY_CLASS, actual.first.getClassName());
- assertEquals(USER_10, (int) actual.second);
+ assertEquals(USER_11, (int) actual.second);
// User P0 -> managed profile, return user-0's launcher.
actual = mProcessor.getRequestPinConfirmationActivity(USER_P0,
@@ -118,16 +118,16 @@ public class ShortcutManagerTest8 extends BaseShortcutManagerTest {
assertEquals(LAUNCHER_1, actual.first.getPackageName());
assertEquals(PIN_CONFIRM_ACTIVITY_CLASS, actual.first.getClassName());
- assertEquals(USER_0, (int) actual.second);
+ assertEquals(USER_10, (int) actual.second);
// Check from the public API.
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertTrue(mManager.isRequestPinShortcutSupported());
});
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
assertTrue(mManager.isRequestPinShortcutSupported());
});
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
assertTrue(mManager.isRequestPinShortcutSupported());
});
runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
@@ -140,27 +140,27 @@ public class ShortcutManagerTest8 extends BaseShortcutManagerTest {
? null : new ComponentName(packageName, PIN_CONFIRM_ACTIVITY_CLASS);
// User 10 -- still has confirm activity.
- actual = mProcessor.getRequestPinConfirmationActivity(USER_10,
+ actual = mProcessor.getRequestPinConfirmationActivity(USER_11,
PinItemRequest.REQUEST_TYPE_SHORTCUT);
assertEquals(LAUNCHER_2, actual.first.getPackageName());
assertEquals(PIN_CONFIRM_ACTIVITY_CLASS, actual.first.getClassName());
- assertEquals(USER_10, (int) actual.second);
+ assertEquals(USER_11, (int) actual.second);
// But user-0 and user p0 no longer has a confirmation activity.
- assertNull(mProcessor.getRequestPinConfirmationActivity(USER_0,
+ assertNull(mProcessor.getRequestPinConfirmationActivity(USER_10,
PinItemRequest.REQUEST_TYPE_SHORTCUT));
assertNull(mProcessor.getRequestPinConfirmationActivity(USER_P0,
PinItemRequest.REQUEST_TYPE_SHORTCUT));
// Check from the public API.
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
assertFalse(mManager.isRequestPinShortcutSupported());
});
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
assertFalse(mManager.isRequestPinShortcutSupported());
});
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_11, () -> {
assertTrue(mManager.isRequestPinShortcutSupported());
});
runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
@@ -170,13 +170,13 @@ public class ShortcutManagerTest8 extends BaseShortcutManagerTest {
public void testRequestPinShortcut_notSupported() {
// User-0's launcher has no confirmation activity.
- setDefaultLauncher(USER_0, LAUNCHER_1);
+ setDefaultLauncher(USER_10, LAUNCHER_1);
mPinConfirmActivityFetcher = (packageName, userId) ->
!LAUNCHER_2.equals(packageName)
? null : new ComponentName(packageName, PIN_CONFIRM_ACTIVITY_CLASS);
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
ShortcutInfo s1 = makeShortcut("s1");
assertFalse(mManager.requestPinShortcut(s1,
@@ -188,7 +188,7 @@ public class ShortcutManagerTest8 extends BaseShortcutManagerTest {
.sendIntentSender(any(IntentSender.class));
});
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
ShortcutInfo s1 = makeShortcut("s1");
assertFalse(mManager.requestPinShortcut(s1,
@@ -223,7 +223,7 @@ public class ShortcutManagerTest8 extends BaseShortcutManagerTest {
}
public void testNotForeground() {
- setDefaultLauncher(USER_0, LAUNCHER_1);
+ setDefaultLauncher(USER_10, LAUNCHER_1);
runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
makeCallerBackground();
@@ -252,8 +252,8 @@ public class ShortcutManagerTest8 extends BaseShortcutManagerTest {
* - Shortcut doesn't pre-exist.
*/
private void checkRequestPinShortcut(@Nullable IntentSender resultIntent) {
- setDefaultLauncher(USER_0, LAUNCHER_1);
- setDefaultLauncher(USER_10, LAUNCHER_2);
+ setDefaultLauncher(USER_10, LAUNCHER_1);
+ setDefaultLauncher(USER_11, LAUNCHER_2);
final Icon res32x32 = Icon.createWithResource(getTestContext(), R.drawable.black_32x32);
@@ -276,11 +276,11 @@ public class ShortcutManagerTest8 extends BaseShortcutManagerTest {
.isEmpty();
});
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
// Check the intent passed to startActivityAsUser().
final ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
- verify(mServiceContext).startActivityAsUser(intent.capture(), eq(HANDLE_USER_0));
+ verify(mServiceContext).startActivityAsUser(intent.capture(), eq(HANDLE_USER_10));
assertPinItemRequestIntent(intent.getValue(), mInjectedClientPackage);
@@ -337,8 +337,8 @@ public class ShortcutManagerTest8 extends BaseShortcutManagerTest {
}
public void testRequestPinShortcut_explicitTargetActivity() {
- setDefaultLauncher(USER_0, LAUNCHER_1);
- setDefaultLauncher(USER_10, LAUNCHER_2);
+ setDefaultLauncher(USER_10, LAUNCHER_1);
+ setDefaultLauncher(USER_11, LAUNCHER_2);
runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
ShortcutInfo s1 = makeShortcutWithActivity("s1",
@@ -353,11 +353,11 @@ public class ShortcutManagerTest8 extends BaseShortcutManagerTest {
.isEmpty();
});
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
// Check the intent passed to startActivityAsUser().
final ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
- verify(mServiceContext).startActivityAsUser(intent.capture(), eq(HANDLE_USER_0));
+ verify(mServiceContext).startActivityAsUser(intent.capture(), eq(HANDLE_USER_10));
assertPinItemRequestIntent(intent.getValue(), mInjectedClientPackage);
@@ -393,7 +393,7 @@ public class ShortcutManagerTest8 extends BaseShortcutManagerTest {
}
public void testRequestPinShortcut_wrongTargetActivity() {
- setDefaultLauncher(USER_0, LAUNCHER_1);
+ setDefaultLauncher(USER_10, LAUNCHER_1);
runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
// Create dynamic shortcut
@@ -411,8 +411,8 @@ public class ShortcutManagerTest8 extends BaseShortcutManagerTest {
}
public void testRequestPinShortcut_noTargetActivity_noMainActivity() {
- setDefaultLauncher(USER_0, LAUNCHER_1);
- setDefaultLauncher(USER_10, LAUNCHER_2);
+ setDefaultLauncher(USER_10, LAUNCHER_1);
+ setDefaultLauncher(USER_11, LAUNCHER_2);
runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
/// Create a shortcut with no target activity.
@@ -435,11 +435,11 @@ public class ShortcutManagerTest8 extends BaseShortcutManagerTest {
.isEmpty();
});
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
// Check the intent passed to startActivityAsUser().
final ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
- verify(mServiceContext).startActivityAsUser(intent.capture(), eq(HANDLE_USER_0));
+ verify(mServiceContext).startActivityAsUser(intent.capture(), eq(HANDLE_USER_10));
assertPinItemRequestIntent(intent.getValue(), mInjectedClientPackage);
@@ -476,7 +476,7 @@ public class ShortcutManagerTest8 extends BaseShortcutManagerTest {
}
public void testRequestPinShortcut_dynamicExists() {
- setDefaultLauncher(USER_0, LAUNCHER_1);
+ setDefaultLauncher(USER_10, LAUNCHER_1);
final Icon res32x32 = Icon.createWithResource(getTestContext(), R.drawable.black_32x32);
@@ -497,11 +497,11 @@ public class ShortcutManagerTest8 extends BaseShortcutManagerTest {
.areAllNotPinned();
});
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
// Check the intent passed to startActivityAsUser().
final ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
- verify(mServiceContext).startActivityAsUser(intent.capture(), eq(HANDLE_USER_0));
+ verify(mServiceContext).startActivityAsUser(intent.capture(), eq(HANDLE_USER_10));
assertPinItemRequestIntent(intent.getValue(), mInjectedClientPackage);
@@ -534,7 +534,7 @@ public class ShortcutManagerTest8 extends BaseShortcutManagerTest {
}
public void testRequestPinShortcut_manifestExists() {
- setDefaultLauncher(USER_0, LAUNCHER_1);
+ setDefaultLauncher(USER_10, LAUNCHER_1);
runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
publishManifestShortcutsAsCaller(R.xml.shortcut_1);
@@ -552,11 +552,11 @@ public class ShortcutManagerTest8 extends BaseShortcutManagerTest {
.areAllNotPinned();
});
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
// Check the intent passed to startActivityAsUser().
final ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
- verify(mServiceContext).startActivityAsUser(intent.capture(), eq(HANDLE_USER_0));
+ verify(mServiceContext).startActivityAsUser(intent.capture(), eq(HANDLE_USER_10));
assertPinItemRequestIntent(intent.getValue(), mInjectedClientPackage);
@@ -591,7 +591,7 @@ public class ShortcutManagerTest8 extends BaseShortcutManagerTest {
}
public void testRequestPinShortcut_dynamicExists_alreadyPinned() {
- setDefaultLauncher(USER_0, LAUNCHER_1);
+ setDefaultLauncher(USER_10, LAUNCHER_1);
final Icon res32x32 = Icon.createWithResource(getTestContext(), R.drawable.black_32x32);
@@ -604,7 +604,7 @@ public class ShortcutManagerTest8 extends BaseShortcutManagerTest {
assertTrue(mManager.setDynamicShortcuts(list(s)));
});
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s1"), HANDLE_USER_P0);
});
@@ -633,11 +633,11 @@ public class ShortcutManagerTest8 extends BaseShortcutManagerTest {
});
// ... But the launcher will still receive the request.
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
// Check the intent passed to startActivityAsUser().
final ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
- verify(mServiceContext).startActivityAsUser(intent.capture(), eq(HANDLE_USER_0));
+ verify(mServiceContext).startActivityAsUser(intent.capture(), eq(HANDLE_USER_10));
assertPinItemRequestIntent(intent.getValue(), mInjectedClientPackage);
@@ -676,13 +676,13 @@ public class ShortcutManagerTest8 extends BaseShortcutManagerTest {
}
public void testRequestPinShortcut_manifestExists_alreadyPinned() {
- setDefaultLauncher(USER_0, LAUNCHER_1);
+ setDefaultLauncher(USER_10, LAUNCHER_1);
runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
publishManifestShortcutsAsCaller(R.xml.shortcut_1);
});
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("ms1"), HANDLE_USER_P0);
});
@@ -713,11 +713,11 @@ public class ShortcutManagerTest8 extends BaseShortcutManagerTest {
});
// ... But the launcher will still receive the request.
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
// Check the intent passed to startActivityAsUser().
final ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
- verify(mServiceContext).startActivityAsUser(intent.capture(), eq(HANDLE_USER_0));
+ verify(mServiceContext).startActivityAsUser(intent.capture(), eq(HANDLE_USER_10));
assertPinItemRequestIntent(intent.getValue(), mInjectedClientPackage);
@@ -758,13 +758,13 @@ public class ShortcutManagerTest8 extends BaseShortcutManagerTest {
}
public void testRequestPinShortcut_wasDynamic_alreadyPinned() {
- setDefaultLauncher(USER_0, LAUNCHER_1);
+ setDefaultLauncher(USER_10, LAUNCHER_1);
runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
assertTrue(mManager.setDynamicShortcuts(list(makeShortcut("s1"))));
});
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s1"), HANDLE_USER_P0);
});
@@ -786,13 +786,13 @@ public class ShortcutManagerTest8 extends BaseShortcutManagerTest {
}
public void testRequestPinShortcut_wasDynamic_disabled_alreadyPinned() {
- setDefaultLauncher(USER_0, LAUNCHER_1);
+ setDefaultLauncher(USER_10, LAUNCHER_1);
runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
assertTrue(mManager.setDynamicShortcuts(list(makeShortcut("s1"))));
});
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s1"), HANDLE_USER_P0);
});
@@ -817,13 +817,13 @@ public class ShortcutManagerTest8 extends BaseShortcutManagerTest {
}
public void testRequestPinShortcut_wasManifest_alreadyPinned() {
- setDefaultLauncher(USER_0, LAUNCHER_1);
+ setDefaultLauncher(USER_10, LAUNCHER_1);
runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
publishManifestShortcutsAsCaller(R.xml.shortcut_1);
});
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("ms1"), HANDLE_USER_P0);
});
@@ -855,11 +855,11 @@ public class ShortcutManagerTest8 extends BaseShortcutManagerTest {
assertTrue(mManager.setDynamicShortcuts(list(makeShortcut("s1"))));
});
- runWithCaller(LAUNCHER_2, USER_0, () -> {
+ runWithCaller(LAUNCHER_2, USER_10, () -> {
mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s1"), HANDLE_USER_P0);
});
- setDefaultLauncher(USER_0, LAUNCHER_1);
+ setDefaultLauncher(USER_10, LAUNCHER_1);
runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
assertWith(getCallerShortcuts())
@@ -876,11 +876,11 @@ public class ShortcutManagerTest8 extends BaseShortcutManagerTest {
verify(mServiceContext, times(0)).sendIntentSender(any(IntentSender.class));
});
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
// Check the intent passed to startActivityAsUser().
final ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
- verify(mServiceContext).startActivityAsUser(intent.capture(), eq(HANDLE_USER_0));
+ verify(mServiceContext).startActivityAsUser(intent.capture(), eq(HANDLE_USER_10));
assertPinItemRequestIntent(intent.getValue(), mInjectedClientPackage);
@@ -917,11 +917,11 @@ public class ShortcutManagerTest8 extends BaseShortcutManagerTest {
publishManifestShortcutsAsCaller(R.xml.shortcut_1);
});
- runWithCaller(LAUNCHER_2, USER_0, () -> {
+ runWithCaller(LAUNCHER_2, USER_10, () -> {
mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("ms1"), HANDLE_USER_P0);
});
- setDefaultLauncher(USER_0, LAUNCHER_1);
+ setDefaultLauncher(USER_10, LAUNCHER_1);
runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
assertWith(getCallerShortcuts())
@@ -939,11 +939,11 @@ public class ShortcutManagerTest8 extends BaseShortcutManagerTest {
verify(mServiceContext, times(0)).sendIntentSender(any(IntentSender.class));
});
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
// Check the intent passed to startActivityAsUser().
final ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
- verify(mServiceContext).startActivityAsUser(intent.capture(), eq(HANDLE_USER_0));
+ verify(mServiceContext).startActivityAsUser(intent.capture(), eq(HANDLE_USER_10));
assertPinItemRequestIntent(intent.getValue(), mInjectedClientPackage);
@@ -980,13 +980,13 @@ public class ShortcutManagerTest8 extends BaseShortcutManagerTest {
* the existing one.
*/
public void testRequestPinShortcut_launcherAlreadyHasPinned() {
- setDefaultLauncher(USER_0, LAUNCHER_1);
+ setDefaultLauncher(USER_10, LAUNCHER_1);
runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
assertTrue(mManager.setDynamicShortcuts(list(makeShortcut("s1"), makeShortcut("s2"))));
});
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s2"), HANDLE_USER_P0);
});
@@ -997,11 +997,11 @@ public class ShortcutManagerTest8 extends BaseShortcutManagerTest {
verify(mServiceContext, times(0)).sendIntentSender(any(IntentSender.class));
});
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
// Check the intent passed to startActivityAsUser().
final ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
- verify(mServiceContext).startActivityAsUser(intent.capture(), eq(HANDLE_USER_0));
+ verify(mServiceContext).startActivityAsUser(intent.capture(), eq(HANDLE_USER_10));
assertPinItemRequestIntent(intent.getValue(), mInjectedClientPackage);
@@ -1042,7 +1042,7 @@ public class ShortcutManagerTest8 extends BaseShortcutManagerTest {
* When trying to pin an existing shortcut, the new fields shouldn't override existing fields.
*/
public void testRequestPinShortcut_dynamicExists_titleWontChange() {
- setDefaultLauncher(USER_0, LAUNCHER_1);
+ setDefaultLauncher(USER_10, LAUNCHER_1);
final Icon res32x32 = Icon.createWithResource(getTestContext(), R.drawable.black_32x32);
@@ -1063,11 +1063,11 @@ public class ShortcutManagerTest8 extends BaseShortcutManagerTest {
.areAllNotPinned();
});
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
// Check the intent passed to startActivityAsUser().
final ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
- verify(mServiceContext).startActivityAsUser(intent.capture(), eq(HANDLE_USER_0));
+ verify(mServiceContext).startActivityAsUser(intent.capture(), eq(HANDLE_USER_10));
assertPinItemRequestIntent(intent.getValue(), mInjectedClientPackage);
@@ -1107,7 +1107,7 @@ public class ShortcutManagerTest8 extends BaseShortcutManagerTest {
* When trying to pin an existing shortcut, the new fields shouldn't override existing fields.
*/
public void testRequestPinShortcut_manifestExists_titleWontChange() {
- setDefaultLauncher(USER_0, LAUNCHER_1);
+ setDefaultLauncher(USER_10, LAUNCHER_1);
runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
publishManifestShortcutsAsCaller(R.xml.shortcut_1);
@@ -1125,11 +1125,11 @@ public class ShortcutManagerTest8 extends BaseShortcutManagerTest {
.areAllNotPinned();
});
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
// Check the intent passed to startActivityAsUser().
final ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
- verify(mServiceContext).startActivityAsUser(intent.capture(), eq(HANDLE_USER_0));
+ verify(mServiceContext).startActivityAsUser(intent.capture(), eq(HANDLE_USER_10));
assertPinItemRequestIntent(intent.getValue(), mInjectedClientPackage);
@@ -1174,7 +1174,7 @@ public class ShortcutManagerTest8 extends BaseShortcutManagerTest {
* has a partial shortcut, accept() should fail.
*/
public void testRequestPinShortcut_dynamicExists_thenRemoved_error() {
- setDefaultLauncher(USER_0, LAUNCHER_1);
+ setDefaultLauncher(USER_10, LAUNCHER_1);
runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
// Create dynamic shortcut
@@ -1192,11 +1192,11 @@ public class ShortcutManagerTest8 extends BaseShortcutManagerTest {
.isEmpty();
});
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
// Check the intent passed to startActivityAsUser().
final ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
- verify(mServiceContext).startActivityAsUser(intent.capture(), eq(HANDLE_USER_0));
+ verify(mServiceContext).startActivityAsUser(intent.capture(), eq(HANDLE_USER_10));
assertPinItemRequestIntent(intent.getValue(), mInjectedClientPackage);
@@ -1232,7 +1232,7 @@ public class ShortcutManagerTest8 extends BaseShortcutManagerTest {
* has all the mandatory fields, we can go ahead and still publish it.
*/
public void testRequestPinShortcut_dynamicExists_thenRemoved_okay() {
- setDefaultLauncher(USER_0, LAUNCHER_1);
+ setDefaultLauncher(USER_10, LAUNCHER_1);
runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
// Create dynamic shortcut
@@ -1250,11 +1250,11 @@ public class ShortcutManagerTest8 extends BaseShortcutManagerTest {
.isEmpty();
});
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
// Check the intent passed to startActivityAsUser().
final ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
- verify(mServiceContext).startActivityAsUser(intent.capture(), eq(HANDLE_USER_0));
+ verify(mServiceContext).startActivityAsUser(intent.capture(), eq(HANDLE_USER_10));
assertPinItemRequestIntent(intent.getValue(), mInjectedClientPackage);
@@ -1288,7 +1288,7 @@ public class ShortcutManagerTest8 extends BaseShortcutManagerTest {
* has a partial shortcut, accept() should fail.
*/
public void testRequestPinShortcut_manifestExists_thenRemoved_error() {
- setDefaultLauncher(USER_0, LAUNCHER_1);
+ setDefaultLauncher(USER_10, LAUNCHER_1);
runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
publishManifestShortcutsAsCaller(R.xml.shortcut_1);
@@ -1304,11 +1304,11 @@ public class ShortcutManagerTest8 extends BaseShortcutManagerTest {
.isEmpty();
});
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
// Check the intent passed to startActivityAsUser().
final ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
- verify(mServiceContext).startActivityAsUser(intent.capture(), eq(HANDLE_USER_0));
+ verify(mServiceContext).startActivityAsUser(intent.capture(), eq(HANDLE_USER_10));
assertPinItemRequestIntent(intent.getValue(), mInjectedClientPackage);
@@ -1345,7 +1345,7 @@ public class ShortcutManagerTest8 extends BaseShortcutManagerTest {
* has all the mandatory fields, we can go ahead and still publish it.
*/
public void testRequestPinShortcut_manifestExists_thenRemoved_okay() {
- setDefaultLauncher(USER_0, LAUNCHER_1);
+ setDefaultLauncher(USER_10, LAUNCHER_1);
runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
publishManifestShortcutsAsCaller(R.xml.shortcut_1);
@@ -1361,11 +1361,11 @@ public class ShortcutManagerTest8 extends BaseShortcutManagerTest {
.isEmpty();
});
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
// Check the intent passed to startActivityAsUser().
final ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
- verify(mServiceContext).startActivityAsUser(intent.capture(), eq(HANDLE_USER_0));
+ verify(mServiceContext).startActivityAsUser(intent.capture(), eq(HANDLE_USER_10));
assertPinItemRequestIntent(intent.getValue(), mInjectedClientPackage);
@@ -1405,7 +1405,7 @@ public class ShortcutManagerTest8 extends BaseShortcutManagerTest {
* has a partial shortcut, accept() should fail.
*/
public void testRequestPinShortcut_dynamicExists_thenDisabled_error() {
- setDefaultLauncher(USER_0, LAUNCHER_1);
+ setDefaultLauncher(USER_10, LAUNCHER_1);
runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
ShortcutInfo s1 = makeShortcut("s1");
@@ -1419,8 +1419,8 @@ public class ShortcutManagerTest8 extends BaseShortcutManagerTest {
// Then, pin by another launcher and disable it.
// We have to pin it here so that disable() won't remove it.
- setDefaultLauncher(USER_0, LAUNCHER_2);
- runWithCaller(LAUNCHER_2, USER_0, () -> {
+ setDefaultLauncher(USER_10, LAUNCHER_2);
+ runWithCaller(LAUNCHER_2, USER_10, () -> {
mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s1"), HANDLE_USER_P0);
});
runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
@@ -1431,12 +1431,12 @@ public class ShortcutManagerTest8 extends BaseShortcutManagerTest {
.areAllDisabled();
});
- setDefaultLauncher(USER_0, LAUNCHER_1);
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ setDefaultLauncher(USER_10, LAUNCHER_1);
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
// Check the intent passed to startActivityAsUser().
final ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
- verify(mServiceContext).startActivityAsUser(intent.capture(), eq(HANDLE_USER_0));
+ verify(mServiceContext).startActivityAsUser(intent.capture(), eq(HANDLE_USER_10));
assertPinItemRequestIntent(intent.getValue(), mInjectedClientPackage);
@@ -1479,7 +1479,7 @@ public class ShortcutManagerTest8 extends BaseShortcutManagerTest {
* has a partial shortcut, accept() should fail.
*/
public void testRequestPinShortcut_manifestExists_thenDisabled_error() {
- setDefaultLauncher(USER_0, LAUNCHER_1);
+ setDefaultLauncher(USER_10, LAUNCHER_1);
runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
publishManifestShortcutsAsCaller(R.xml.shortcut_1);
@@ -1492,8 +1492,8 @@ public class ShortcutManagerTest8 extends BaseShortcutManagerTest {
// Then, pin by another launcher and disable it.
// We have to pin it here so that disable() won't remove it.
- setDefaultLauncher(USER_0, LAUNCHER_2);
- runWithCaller(LAUNCHER_2, USER_0, () -> {
+ setDefaultLauncher(USER_10, LAUNCHER_2);
+ runWithCaller(LAUNCHER_2, USER_10, () -> {
mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("ms1"), HANDLE_USER_P0);
});
runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
@@ -1505,12 +1505,12 @@ public class ShortcutManagerTest8 extends BaseShortcutManagerTest {
.areAllDisabled();
});
- setDefaultLauncher(USER_0, LAUNCHER_1);
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ setDefaultLauncher(USER_10, LAUNCHER_1);
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
// Check the intent passed to startActivityAsUser().
final ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
- verify(mServiceContext).startActivityAsUser(intent.capture(), eq(HANDLE_USER_0));
+ verify(mServiceContext).startActivityAsUser(intent.capture(), eq(HANDLE_USER_10));
assertPinItemRequestIntent(intent.getValue(), mInjectedClientPackage);
@@ -1551,7 +1551,7 @@ public class ShortcutManagerTest8 extends BaseShortcutManagerTest {
}
public void testRequestPinShortcut_wrongLauncherCannotAccept() {
- setDefaultLauncher(USER_0, LAUNCHER_1);
+ setDefaultLauncher(USER_10, LAUNCHER_1);
runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
ShortcutInfo s1 = makeShortcut("s1");
@@ -1560,11 +1560,11 @@ public class ShortcutManagerTest8 extends BaseShortcutManagerTest {
});
final ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
- verify(mServiceContext).startActivityAsUser(intent.capture(), eq(HANDLE_USER_0));
+ verify(mServiceContext).startActivityAsUser(intent.capture(), eq(HANDLE_USER_10));
final PinItemRequest request = mLauncherApps.getPinItemRequest(intent.getValue());
// Verify that other launcher can't use this request
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
// Set some random caller UID.
mInjectedCallingUid = 12345;
@@ -1573,7 +1573,7 @@ public class ShortcutManagerTest8 extends BaseShortcutManagerTest {
});
// The default launcher can still use this request
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
assertTrue(request.isValid());
assertTrue(request.accept());
});
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest9.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest9.java
index 2fca3d07149e..ee1bf38a6b24 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest9.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest9.java
@@ -91,7 +91,7 @@ public class ShortcutManagerTest9 extends BaseShortcutManagerTest {
}
public void testNotForeground() {
- setDefaultLauncher(USER_0, LAUNCHER_1);
+ setDefaultLauncher(USER_10, LAUNCHER_1);
runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
makeCallerBackground();
@@ -108,8 +108,8 @@ public class ShortcutManagerTest9 extends BaseShortcutManagerTest {
}
private void checkRequestPinAppWidget(@Nullable PendingIntent resultIntent) {
- setDefaultLauncher(USER_0, LAUNCHER_1);
- setDefaultLauncher(USER_10, LAUNCHER_2);
+ setDefaultLauncher(USER_10, LAUNCHER_1);
+ setDefaultLauncher(USER_11, LAUNCHER_2);
runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
AppWidgetProviderInfo info = makeProviderInfo("c1");
@@ -120,11 +120,11 @@ public class ShortcutManagerTest9 extends BaseShortcutManagerTest {
verify(mServiceContext, times(0)).sendIntentSender(any(IntentSender.class));
});
- runWithCaller(LAUNCHER_1, USER_0, () -> {
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
// Check the intent passed to startActivityAsUser().
final ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
- verify(mServiceContext).startActivityAsUser(intent.capture(), eq(HANDLE_USER_0));
+ verify(mServiceContext).startActivityAsUser(intent.capture(), eq(HANDLE_USER_10));
assertPinItemRequestIntent(intent.getValue(), mInjectedClientPackage);
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java
index ffe38936bcc1..b1cad513ad83 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java
@@ -516,6 +516,12 @@ public class DisplayWindowSettingsTests extends WindowTestsBase {
// Verify that newly created displays are created with correct rotation settings
assertFalse(dcDontIgnoreOrientation.getIgnoreOrientationRequest());
assertTrue(dcIgnoreOrientation.getIgnoreOrientationRequest());
+
+ // Verify that once ignore-orientation-request has been set, it can be turned off by
+ // applying default value, e.g. the same display switches from large size to small size.
+ settingsEntry2.mIgnoreOrientationRequest = null;
+ mDisplayWindowSettings.applyRotationSettingsToDisplayLocked(dcIgnoreOrientation);
+ assertFalse(dcIgnoreOrientation.getIgnoreOrientationRequest());
}
@Test