summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java61
-rw-r--r--apex/jobscheduler/service/java/com/android/server/alarm/Alarm.java4
-rw-r--r--core/api/test-current.txt7
-rw-r--r--core/java/android/app/Notification.java2
-rw-r--r--core/java/android/app/admin/DevicePolicyCache.java15
-rw-r--r--core/java/android/app/admin/DevicePolicyIdentifiers.java4
-rw-r--r--core/java/android/app/admin/DevicePolicyResources.java6
-rw-r--r--core/java/android/content/pm/CrossProfileApps.java45
-rw-r--r--core/java/android/os/WorkSource.java63
-rw-r--r--core/java/android/view/IRemoteAnimationRunner.aidl2
-rw-r--r--core/java/android/view/ImeFocusController.java8
-rw-r--r--core/java/android/view/inputmethod/InputMethodManager.java65
-rw-r--r--core/java/android/view/inputmethod/TextBoundsInfo.java1
-rw-r--r--core/java/android/widget/Editor.java12
-rw-r--r--core/java/com/android/internal/accessibility/util/AccessibilityUtils.java29
-rw-r--r--core/proto/android/server/windowmanagertransitiontrace.proto4
-rw-r--r--core/res/AndroidManifest.xml2
-rw-r--r--core/res/res/values/config.xml3
-rw-r--r--core/res/res/values/strings.xml6
-rw-r--r--core/res/res/values/symbols.xml3
-rw-r--r--core/tests/coretests/Android.bp1
-rw-r--r--core/tests/coretests/jni/Android.bp24
-rw-r--r--core/tests/coretests/jni/NativePowerManagerTest.cpp172
-rw-r--r--core/tests/coretests/jni/NativeWorkSourceParcelTest.cpp156
-rw-r--r--core/tests/coretests/jni/ParcelHelper.h73
-rw-r--r--core/tests/coretests/src/android/app/activity/ActivityThreadTest.java2
-rw-r--r--core/tests/coretests/src/android/content/pm/CrossProfileAppsTest.java20
-rw-r--r--core/tests/coretests/src/android/os/PowerManagerTest.java88
-rw-r--r--core/tests/coretests/src/android/os/WorkSourceParcelTest.java138
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationRunner.java5
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityAnimation.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/back/CustomizeActivityAnimation.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java35
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java10
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java10
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/LegacyTransitions.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldBackgroundController.java10
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java8
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java12
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/BaseTest.kt2
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt12
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonConstants.kt2
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/BaseAppCompat.kt10
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/OpenAppInSizeCompatModeTest.kt10
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/RestartAppInSizeCompatModeTest.kt12
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/OpenActivityFromBubbleOnLocksreenTest.kt6
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipBySwipingDownTest.kt2
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipTransition.kt2
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt2
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTransition.kt2
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppTransition.kt2
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt2
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipOnImeVisibilityChangeTest.kt2
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTransition.kt2
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/CopyContentInSplit.kt4
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenUtils.kt6
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java7
-rw-r--r--media/java/android/media/MediaCodecInfo.java45
-rw-r--r--packages/CredentialManager/res/values/strings.xml12
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java104
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiStatusTrackerTest.java211
-rw-r--r--packages/SystemUI/Android.bp3
-rw-r--r--packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt8
-rw-r--r--packages/SystemUI/animation/src/com/android/systemui/animation/RemoteAnimationDelegate.kt2
-rw-r--r--packages/SystemUI/res-keyguard/color/numpad_key_color_secondary.xml2
-rw-r--r--packages/SystemUI/res-keyguard/drawable/kg_emergency_button_background.xml2
-rw-r--r--packages/SystemUI/res-keyguard/layout/keyguard_esim_area.xml5
-rw-r--r--packages/SystemUI/res-keyguard/layout/keyguard_security_container_view.xml5
-rw-r--r--packages/SystemUI/res-keyguard/values/styles.xml2
-rw-r--r--packages/SystemUI/res/layout/super_notification_shade.xml1
-rw-r--r--packages/SystemUI/res/values/dimens.xml2
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationRunnerCompat.java2
-rw-r--r--packages/SystemUI/src/com/android/keyguard/BouncerKeyguardMessageArea.kt6
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java20
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardSimInputView.kt7
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java54
-rw-r--r--packages/SystemUI/src/com/android/keyguard/LockIconViewController.java4
-rw-r--r--packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java25
-rw-r--r--packages/SystemUI/src/com/android/keyguard/NumPadButton.java15
-rw-r--r--packages/SystemUI/src/com/android/keyguard/NumPadKey.java4
-rw-r--r--packages/SystemUI/src/com/android/keyguard/PinShapeHintingView.java4
-rw-r--r--packages/SystemUI/src/com/android/keyguard/PinShapeNonHintingView.java5
-rw-r--r--packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/OWNERS3
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/controller/ControlsBindingControllerImpl.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManager.kt137
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/controller/PackageUpdateMonitor.kt76
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/controller/ServiceWrapper.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/ui/PanelTaskViewController.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/DreamLogger.kt30
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayAnimationsController.kt11
-rw-r--r--packages/SystemUI/src/com/android/systemui/flags/Flags.kt9
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java41
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractor.kt23
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractor.kt63
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/shared/constants/KeyguardBouncerConstants.kt11
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt9
-rw-r--r--packages/SystemUI/src/com/android/systemui/log/dagger/DreamLog.kt22
-rw-r--r--packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/log/table/LogProxy.kt67
-rw-r--r--packages/SystemUI/src/com/android/systemui/log/table/TableLogBuffer.kt47
-rw-r--r--packages/SystemUI/src/com/android/systemui/log/table/TableLogBufferFactory.kt19
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDeviceManager.kt11
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselController.kt13
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTile.java32
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/ActionIntentExecutor.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/NotificationPanelView.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/ShadeModule.kt20
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java28
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/RemoteInputController.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/TapAgainViewController.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java19
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserInteractor.kt15
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java23
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/accessibility/OWNERS1
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/accessibility/SystemActionsTest.java126
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt15
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsBindingControllerImplTest.kt10
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManagerTest.kt193
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/controls/controller/PackageUpdateMonitorTest.kt114
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/controls/ui/PanelTaskViewControllerTest.kt16
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayAnimationsControllerTest.kt7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigParameterizedStateTest.kt2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt21
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepositoryTest.kt2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt101
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/log/table/FakeLogProxy.kt56
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/log/table/LogDiffsForTableTest.kt14
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/log/table/TableLogBufferFactoryTest.kt9
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/log/table/TableLogBufferTest.kt145
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDeviceManagerTest.kt21
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselControllerTest.kt154
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java247
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java15
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherTest.kt5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionParameterizedTest.kt11
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepositoryTest.kt9
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryTest.kt28
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt20
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java2
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilitySecurityPolicy.java13
-rw-r--r--services/accessibility/java/com/android/server/accessibility/SystemActionPerformer.java7
-rw-r--r--services/autofill/java/com/android/server/autofill/Helper.java39
-rw-r--r--services/autofill/java/com/android/server/autofill/Session.java18
-rw-r--r--services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java23
-rw-r--r--services/autofill/java/com/android/server/autofill/ui/DisplayHelper.java68
-rw-r--r--services/autofill/java/com/android/server/autofill/ui/FillUi.java9
-rw-r--r--services/autofill/java/com/android/server/autofill/ui/SaveUi.java9
-rw-r--r--services/core/java/com/android/server/UiModeManagerService.java16
-rw-r--r--services/core/java/com/android/server/am/BatteryStatsService.java2
-rw-r--r--services/core/java/com/android/server/am/ContentProviderHelper.java2
-rw-r--r--services/core/java/com/android/server/display/DisplayPowerController.java126
-rw-r--r--services/core/java/com/android/server/display/DisplayPowerController2.java127
-rw-r--r--services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java4
-rwxr-xr-xservices/core/java/com/android/server/notification/NotificationManagerService.java332
-rw-r--r--services/core/java/com/android/server/notification/NotificationRecordLogger.java99
-rw-r--r--services/core/java/com/android/server/notification/NotificationRecordLoggerImpl.java85
-rw-r--r--services/core/java/com/android/server/pm/LauncherAppsService.java9
-rw-r--r--services/core/java/com/android/server/wallpaper/WallpaperManagerService.java93
-rw-r--r--services/core/java/com/android/server/wm/AbsAppSnapshotController.java12
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java4
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java6
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskManagerService.java12
-rw-r--r--services/core/java/com/android/server/wm/BackgroundActivityStartController.java4
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java8
-rw-r--r--services/core/java/com/android/server/wm/DisplayPolicy.java8
-rw-r--r--services/core/java/com/android/server/wm/DisplayRotation.java6
-rw-r--r--services/core/java/com/android/server/wm/RemoteAnimationController.java9
-rw-r--r--services/core/java/com/android/server/wm/Transition.java60
-rw-r--r--services/core/java/com/android/server/wm/TransitionController.java16
-rw-r--r--services/core/java/com/android/server/wm/TransitionTracer.java6
-rw-r--r--services/core/java/com/android/server/wm/WindowContainer.java3
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java4
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java8
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyCacheImpl.java19
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java3
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java165
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java9
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/PolicyState.java19
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java61
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/AccessibilitySecurityPolicyTest.java25
-rw-r--r--services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java19
-rwxr-xr-xservices/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java278
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordLoggerFake.java38
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java11
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java814
-rw-r--r--services/tests/wmtests/AndroidManifest.xml1
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java4
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/AssistDataRequesterTest.java4
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java13
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/PersisterQueueTests.java3
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java16
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/SurfaceAnimationRunnerTest.java1
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/SurfaceControlTests.java59
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowContainerThumbnailTest.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java11
-rw-r--r--telecomm/java/android/telecom/TelecomManager.java4
-rw-r--r--telephony/java/android/telephony/data/ApnSetting.java10
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/BaseTest.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt4
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/OpenActivityEmbeddingSecondaryToSplitTest.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt7
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt7
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppTransition.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ActivityEmbeddingAppHelper.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/helpers/AppPairsHelper.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FixedOrientationAppHelper.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/helpers/GameAppHelper.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppHelper.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeEditorPopupDialogAppHelper.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeShownOnAppStartHelper.kt4
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeStateInitializeHelper.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/helpers/LetterboxAppHelper.kt28
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/helpers/MailAppHelper.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/helpers/MultiWindowUtils.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NewTasksAppHelper.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NonResizeableAppHelper.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NotificationAppHelper.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt5
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/helpers/SeamlessRotationAppHelper.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ShowWhenLockedAppHelper.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/helpers/SimpleAppHelper.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/helpers/TwoActivitiesAppHelper.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeOnDismissPopupDialogTest.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeOnGoHomeTest.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeShownOnAppStartOnGoHomeTest.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeShownOnAppStartToAppOnPressBackTest.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeToAppOnPressBackTest.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/CommonAssertions.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowToFixedPortraitAppTest.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromOverviewTest.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromQuickSwitchTest.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppTest.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeWhileDismissingThemedPopupDialogTest.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeWhileEnteringOverviewTest.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivitiesTransitionTest.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppAfterCameraTestCfArm.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdFromIcon.kt6
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdFromIconCfArm.kt6
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt3
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTestCfArm.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLauncherTransition.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationCold.kt4
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWarm.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWithLockOverlayApp.kt6
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockTransition.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationCold.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationColdCfArm.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationWarm.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt1
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt7
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTransition.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt1
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTestCfArm.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OverrideTaskTransitionTest.kt8
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/TaskTransitionTest.kt10
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/rotation/RotationTransition.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt2
279 files changed, 5174 insertions, 1817 deletions
diff --git a/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java b/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java
index b732da29b754..9ba94c8b9d11 100644
--- a/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java
+++ b/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java
@@ -69,6 +69,8 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicReference;
/**
* Perf tests for user life cycle events.
@@ -101,7 +103,6 @@ public class UserLifecycleTests {
private static final long TIMEOUT_MAX_TEST_TIME_MS = 24 * 60_000;
private static final int TIMEOUT_IN_SECOND = 30;
- private static final int CHECK_USER_REMOVED_INTERVAL_MS = 200;
/** Name of users/profiles in the test. Users with this name may be freely removed. */
private static final String TEST_USER_NAME = "UserLifecycleTests_test_user";
@@ -1471,17 +1472,10 @@ public class UserLifecycleTests {
private void removeUser(int userId) throws RemoteException {
stopUserAfterWaitingForBroadcastIdle(userId, true);
try {
- mUm.removeUser(userId);
- final long startTime = System.currentTimeMillis();
- final long timeoutInMs = TIMEOUT_IN_SECOND * 1000;
- while (mUm.getUserInfo(userId) != null &&
- System.currentTimeMillis() - startTime < timeoutInMs) {
- TimeUnit.MILLISECONDS.sleep(CHECK_USER_REMOVED_INTERVAL_MS);
- }
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- } catch (Exception e) {
- // Ignore
+ runShellCommandWithTimeout("pm remove-user -w " + userId, TIMEOUT_IN_SECOND);
+ } catch (TimeoutException e) {
+ Log.e(TAG, String.format("Could not remove user %d in %d seconds",
+ userId, TIMEOUT_IN_SECOND), e);
}
if (mUm.getUserInfo(userId) != null) {
mUsersToRemove.add(userId);
@@ -1544,7 +1538,11 @@ public class UserLifecycleTests {
}
private void waitForBroadcastIdle() {
- ShellHelper.runShellCommand("am wait-for-broadcast-idle");
+ try {
+ runShellCommandWithTimeout("am wait-for-broadcast-idle", TIMEOUT_IN_SECOND);
+ } catch (TimeoutException e) {
+ Log.e(TAG, "Ending waitForBroadcastIdle because it is taking too long", e);
+ }
}
private void sleep(long ms) {
@@ -1560,4 +1558,41 @@ public class UserLifecycleTests {
waitForBroadcastIdle();
sleep(tenSeconds);
}
+
+ /**
+ * Runs a Shell command with a timeout, returning a trimmed response.
+ */
+ private String runShellCommandWithTimeout(String command, long timeoutInSecond)
+ throws TimeoutException {
+ AtomicReference<Exception> exception = new AtomicReference<>(null);
+ AtomicReference<String> result = new AtomicReference<>(null);
+
+ CountDownLatch latch = new CountDownLatch(1);
+
+ new Thread(() -> {
+ try {
+ result.set(ShellHelper.runShellCommandRaw(command));
+ } catch (Exception e) {
+ exception.set(e);
+ } finally {
+ latch.countDown();
+ }
+ }).start();
+
+ try {
+ if (!latch.await(timeoutInSecond, TimeUnit.SECONDS)) {
+ throw new TimeoutException("Command: '" + command + "' could not run in "
+ + timeoutInSecond + " seconds");
+ }
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
+
+ if (exception.get() != null) {
+ Log.e(TAG, "Command: '" + command + "' failed.", exception.get());
+ throw new RuntimeException(exception.get());
+ }
+
+ return result.get();
+ }
}
diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/Alarm.java b/apex/jobscheduler/service/java/com/android/server/alarm/Alarm.java
index 430a1e25e123..4d646de2e529 100644
--- a/apex/jobscheduler/service/java/com/android/server/alarm/Alarm.java
+++ b/apex/jobscheduler/service/java/com/android/server/alarm/Alarm.java
@@ -292,6 +292,10 @@ class Alarm {
return "permission";
case EXACT_ALLOW_REASON_POLICY_PERMISSION:
return "policy_permission";
+ case EXACT_ALLOW_REASON_LISTENER:
+ return "listener";
+ case EXACT_ALLOW_REASON_PRIORITIZED:
+ return "prioritized";
case EXACT_ALLOW_REASON_NOT_APPLICABLE:
return "N/A";
default:
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index ae63816945e1..332c53cb224f 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -536,6 +536,12 @@ package android.app.admin {
field @NonNull public static final android.app.admin.DeviceAdminAuthority DEVICE_ADMIN_AUTHORITY;
}
+ public final class DevicePolicyIdentifiers {
+ field public static final String PERMITTED_INPUT_METHODS_POLICY = "permittedInputMethods";
+ field public static final String PERSONAL_APPS_SUSPENDED_POLICY = "personalAppsSuspended";
+ field public static final String SCREEN_CAPTURE_DISABLED_POLICY = "screenCaptureDisabled";
+ }
+
public class DevicePolicyManager {
method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.INTERACT_ACROSS_USERS}) public void acknowledgeNewUserDisclaimer();
method @RequiresPermission(android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS) public void calculateHasIncompatibleAccounts();
@@ -3783,6 +3789,7 @@ package android.view.inputmethod {
method @NonNull @RequiresPermission(value=android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, conditional=true) public java.util.List<android.view.inputmethod.InputMethodInfo> getInputMethodListAsUser(int);
method public boolean hasActiveInputConnection(@Nullable android.view.View);
method @RequiresPermission(android.Manifest.permission.TEST_INPUT_METHOD) public boolean hasPendingImeVisibilityRequests();
+ method @RequiresPermission(android.Manifest.permission.TEST_INPUT_METHOD) public boolean isCurrentRootView(@NonNull android.view.View);
method @RequiresPermission(android.Manifest.permission.TEST_INPUT_METHOD) public boolean isInputMethodPickerShown();
method @RequiresPermission(android.Manifest.permission.TEST_INPUT_METHOD) public void setStylusWindowIdleTimeoutForTest(long);
field public static final long CLEAR_SHOW_FORCED_FLAG_WHEN_LEAVING = 214016041L; // 0xcc1a029L
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index d37576092af2..67226d0f2228 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -6994,7 +6994,7 @@ public class Notification implements Parcelable
*/
public boolean isColorized() {
return extras.getBoolean(EXTRA_COLORIZED)
- && (hasColorizedPermission() || isForegroundService());
+ && (hasColorizedPermission() || isFgsOrUij());
}
/**
diff --git a/core/java/android/app/admin/DevicePolicyCache.java b/core/java/android/app/admin/DevicePolicyCache.java
index b6e83c8bc8a1..29f657ec6ba7 100644
--- a/core/java/android/app/admin/DevicePolicyCache.java
+++ b/core/java/android/app/admin/DevicePolicyCache.java
@@ -19,8 +19,8 @@ import android.annotation.UserIdInt;
import com.android.server.LocalServices;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.Collections;
+import java.util.Map;
/**
* Stores a copy of the set of device policies maintained by {@link DevicePolicyManager} that
@@ -64,10 +64,11 @@ public abstract class DevicePolicyCache {
public abstract boolean canAdminGrantSensorsPermissions();
/**
- * Returns a list of package names for which all launcher shortcuts should be modified to be
- * launched in the managed profile and badged accordingly.
+ * Returns a map of package names to package names, for which all launcher shortcuts which
+ * match a key package name should be modified to launch the corresponding value package
+ * name in the managed profile. The overridden shortcut should be badged accordingly.
*/
- public abstract List<String> getLauncherShortcutOverrides();
+ public abstract Map<String, String> getLauncherShortcutOverrides();
/**
* Empty implementation.
@@ -95,8 +96,8 @@ public abstract class DevicePolicyCache {
return false;
}
@Override
- public List<String> getLauncherShortcutOverrides() {
- return new ArrayList<>();
+ public Map<String, String> getLauncherShortcutOverrides() {
+ return Collections.EMPTY_MAP;
}
}
}
diff --git a/core/java/android/app/admin/DevicePolicyIdentifiers.java b/core/java/android/app/admin/DevicePolicyIdentifiers.java
index 9b0a70d65d6f..aeac59b12a2e 100644
--- a/core/java/android/app/admin/DevicePolicyIdentifiers.java
+++ b/core/java/android/app/admin/DevicePolicyIdentifiers.java
@@ -17,6 +17,7 @@
package android.app.admin;
import android.annotation.NonNull;
+import android.annotation.TestApi;
import android.os.UserManager;
import java.util.Objects;
@@ -118,6 +119,7 @@ public final class DevicePolicyIdentifiers {
*
* @hide
*/
+ @TestApi
public static final String PERMITTED_INPUT_METHODS_POLICY = "permittedInputMethods";
/**
@@ -125,6 +127,7 @@ public final class DevicePolicyIdentifiers {
*
* @hide
*/
+ @TestApi
public static final String PERSONAL_APPS_SUSPENDED_POLICY = "personalAppsSuspended";
/**
@@ -132,6 +135,7 @@ public final class DevicePolicyIdentifiers {
*
* @hide
*/
+ @TestApi
public static final String SCREEN_CAPTURE_DISABLED_POLICY = "screenCaptureDisabled";
/**
diff --git a/core/java/android/app/admin/DevicePolicyResources.java b/core/java/android/app/admin/DevicePolicyResources.java
index 052f670b71bd..77ba560f29a1 100644
--- a/core/java/android/app/admin/DevicePolicyResources.java
+++ b/core/java/android/app/admin/DevicePolicyResources.java
@@ -1662,14 +1662,16 @@ public final class DevicePolicyResources {
/**
* Label returned from
* {@link android.content.pm.CrossProfileApps#getProfileSwitchingLabel(UserHandle)}
- * that calling app can show to user for the semantic of switching to work profile.
+ * that calling app can show to user for the semantic of switching to work profile, and
+ * accepts the app name as a param.
*/
public static final String SWITCH_TO_WORK_LABEL = PREFIX + "SWITCH_TO_WORK_LABEL";
/**
* Label returned from
* {@link android.content.pm.CrossProfileApps#getProfileSwitchingLabel(UserHandle)}
- * that calling app can show to user for the semantic of switching to personal profile.
+ * that calling app can show to user for the semantic of switching to personal profile,
+ * and accepts the app name as a param.
*/
public static final String SWITCH_TO_PERSONAL_LABEL =
PREFIX + "SWITCH_TO_PERSONAL_LABEL";
diff --git a/core/java/android/content/pm/CrossProfileApps.java b/core/java/android/content/pm/CrossProfileApps.java
index d6951eec904f..7ac8f37c645e 100644
--- a/core/java/android/content/pm/CrossProfileApps.java
+++ b/core/java/android/content/pm/CrossProfileApps.java
@@ -18,6 +18,7 @@ package android.content.pm;
import static android.Manifest.permission.INTERACT_ACROSS_USERS;
import static android.app.admin.DevicePolicyResources.Strings.Core.SWITCH_TO_PERSONAL_LABEL;
import static android.app.admin.DevicePolicyResources.Strings.Core.SWITCH_TO_WORK_LABEL;
+import static android.content.pm.PackageManager.MATCH_DEFAULT_ONLY;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -40,6 +41,7 @@ import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
+import android.text.TextUtils;
import com.android.internal.R;
import com.android.internal.util.UserIcons;
@@ -329,19 +331,40 @@ public class CrossProfileApps {
final boolean isManagedProfile = mUserManager.isManagedProfile(userHandle.getIdentifier());
final DevicePolicyManager dpm = mContext.getSystemService(DevicePolicyManager.class);
+ final String callingAppLabel = getCallingApplicationLabel().toString();
return dpm.getResources().getString(
getUpdatableProfileSwitchingLabelId(isManagedProfile),
- () -> getDefaultProfileSwitchingLabel(isManagedProfile));
+ () -> getDefaultProfileSwitchingLabel(isManagedProfile, callingAppLabel),
+ callingAppLabel);
+ }
+
+ private CharSequence getCallingApplicationLabel() {
+ PackageManager pm = mContext.getPackageManager();
+ // If there is a label for the launcher intent, then use that as it is typically shorter.
+ // Otherwise, just use the top-level application name.
+ Intent launchIntent = pm.getLaunchIntentForPackage(mContext.getPackageName());
+ List<ResolveInfo> infos =
+ pm.queryIntentActivities(
+ launchIntent, PackageManager.ResolveInfoFlags.of(MATCH_DEFAULT_ONLY));
+ if (infos.size() > 0) {
+ return infos.get(0).loadLabel(pm);
+ }
+ return mContext.getApplicationInfo()
+ .loadSafeLabel(
+ pm,
+ /* ellipsizeDip= */ 0,
+ TextUtils.SAFE_STRING_FLAG_SINGLE_LINE
+ | TextUtils.SAFE_STRING_FLAG_TRIM);
}
private String getUpdatableProfileSwitchingLabelId(boolean isManagedProfile) {
return isManagedProfile ? SWITCH_TO_WORK_LABEL : SWITCH_TO_PERSONAL_LABEL;
}
- private String getDefaultProfileSwitchingLabel(boolean isManagedProfile) {
+ private String getDefaultProfileSwitchingLabel(boolean isManagedProfile, String label) {
final int stringRes = isManagedProfile
- ? R.string.managed_profile_label : R.string.user_owner_label;
- return mResources.getString(stringRes);
+ ? R.string.managed_profile_app_label : R.string.user_owner_app_label;
+ return mResources.getString(stringRes, label);
}
@@ -366,10 +389,18 @@ public class CrossProfileApps {
if (isManagedProfile) {
return mContext.getPackageManager().getUserBadgeForDensityNoBackground(
userHandle, /* density= */ 0);
- } else {
- return UserIcons.getDefaultUserIcon(
- mResources, UserHandle.USER_SYSTEM, true /* light */);
}
+ Drawable personalProfileIcon = UserIcons.getDefaultUserIcon(
+ mResources, UserHandle.USER_SYSTEM, /* light= */ true);
+ // Using the same colors as the managed profile icon.
+ int colorId = mContext.getResources().getConfiguration().isNightModeActive()
+ ? R.color.profile_badge_1_dark
+ : R.color.profile_badge_1;
+ // First set the color filter to null so that it does not override
+ // the tint.
+ personalProfileIcon.setColorFilter(null);
+ personalProfileIcon.setTint(mResources.getColor(colorId, /* theme= */ null));
+ return personalProfileIcon;
}
/**
diff --git a/core/java/android/os/WorkSource.java b/core/java/android/os/WorkSource.java
index 65528e306943..bc80c8b20b86 100644
--- a/core/java/android/os/WorkSource.java
+++ b/core/java/android/os/WorkSource.java
@@ -12,11 +12,11 @@ import android.util.Log;
import android.util.proto.ProtoOutputStream;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.Preconditions;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.Objects;
/**
* Describes the source of some work that may be done by someone else.
@@ -29,9 +29,13 @@ public class WorkSource implements Parcelable {
@UnsupportedAppUsage
int mNum;
+
@UnsupportedAppUsage
- int[] mUids;
+ @NonNull
+ int[] mUids = new int[0];
+
@UnsupportedAppUsage
+ @Nullable
String[] mNames;
private ArrayList<WorkChain> mChains;
@@ -73,13 +77,8 @@ public class WorkSource implements Parcelable {
return;
}
mNum = orig.mNum;
- if (orig.mUids != null) {
- mUids = orig.mUids.clone();
- mNames = orig.mNames != null ? orig.mNames.clone() : null;
- } else {
- mUids = null;
- mNames = null;
- }
+ mUids = orig.mUids.clone();
+ mNames = orig.mNames != null ? orig.mNames.clone() : null;
if (orig.mChains != null) {
// Make a copy of all WorkChains that exist on |orig| since they are mutable.
@@ -114,7 +113,7 @@ public class WorkSource implements Parcelable {
*/
@SystemApi
public WorkSource(int uid, @NonNull String packageName) {
- Preconditions.checkNotNull(packageName, "packageName can't be null");
+ Objects.requireNonNull(packageName, "packageName can't be null");
mNum = 1;
mUids = new int[] { uid, 0 };
mNames = new String[] { packageName, null };
@@ -124,7 +123,7 @@ public class WorkSource implements Parcelable {
@UnsupportedAppUsage
WorkSource(Parcel in) {
mNum = in.readInt();
- mUids = in.createIntArray();
+ mUids = Objects.requireNonNullElse(in.createIntArray(), new int[0]);
mNames = in.createStringArray();
int numChains = in.readInt();
@@ -318,30 +317,22 @@ public class WorkSource implements Parcelable {
*/
public void set(WorkSource other) {
if (other == null) {
- mNum = 0;
- if (mChains != null) {
- mChains.clear();
- }
+ clear();
return;
}
mNum = other.mNum;
- if (other.mUids != null) {
- if (mUids != null && mUids.length >= mNum) {
- System.arraycopy(other.mUids, 0, mUids, 0, mNum);
- } else {
- mUids = other.mUids.clone();
- }
- if (other.mNames != null) {
- if (mNames != null && mNames.length >= mNum) {
- System.arraycopy(other.mNames, 0, mNames, 0, mNum);
- } else {
- mNames = other.mNames.clone();
- }
+ if (mUids.length >= mNum) { // this has more data than other
+ System.arraycopy(other.mUids, 0, mUids, 0, mNum);
+ } else {
+ mUids = other.mUids.clone();
+ }
+ if (other.mNames != null) {
+ if (mNames != null && mNames.length >= mNum) {
+ System.arraycopy(other.mNames, 0, mNames, 0, mNum);
} else {
- mNames = null;
+ mNames = other.mNames.clone();
}
} else {
- mUids = null;
mNames = null;
}
@@ -361,7 +352,7 @@ public class WorkSource implements Parcelable {
/** @hide */
public void set(int uid) {
mNum = 1;
- if (mUids == null) mUids = new int[2];
+ if (mUids.length == 0) mUids = new int[2];
mUids[0] = uid;
mNames = null;
if (mChains != null) {
@@ -375,7 +366,7 @@ public class WorkSource implements Parcelable {
throw new NullPointerException("Name can't be null");
}
mNum = 1;
- if (mUids == null) {
+ if (mUids.length == 0) {
mUids = new int[2];
mNames = new String[2];
}
@@ -727,7 +718,7 @@ public class WorkSource implements Parcelable {
if (DEBUG) Log.d(TAG, "i1=" + i1 + " i2=" + i2 + " N1=" + N1
+ ": insert " + uids2[i2]);
changed = true;
- if (uids1 == null) {
+ if (uids1.length == 0) {
uids1 = new int[4];
uids1[0] = uids2[i2];
} else if (N1 >= uids1.length) {
@@ -866,7 +857,7 @@ public class WorkSource implements Parcelable {
private void insert(int index, int uid) {
if (DEBUG) Log.d(TAG, "Insert in " + this + " @ " + index + " uid " + uid);
- if (mUids == null) {
+ if (mUids.length == 0) {
mUids = new int[4];
mUids[0] = uid;
mNum = 1;
@@ -891,7 +882,7 @@ public class WorkSource implements Parcelable {
}
private void insert(int index, int uid, String name) {
- if (mUids == null) {
+ if (mNum == 0) {
mUids = new int[4];
mUids[0] = uid;
mNames = new String[4];
@@ -1244,8 +1235,8 @@ public class WorkSource implements Parcelable {
proto.end(workSourceToken);
}
- public static final @android.annotation.NonNull Parcelable.Creator<WorkSource> CREATOR
- = new Parcelable.Creator<WorkSource>() {
+ @NonNull
+ public static final Parcelable.Creator<WorkSource> CREATOR = new Parcelable.Creator<>() {
public WorkSource createFromParcel(Parcel in) {
return new WorkSource(in);
}
diff --git a/core/java/android/view/IRemoteAnimationRunner.aidl b/core/java/android/view/IRemoteAnimationRunner.aidl
index 1981c9d66c8b..1f64fb8ca2ec 100644
--- a/core/java/android/view/IRemoteAnimationRunner.aidl
+++ b/core/java/android/view/IRemoteAnimationRunner.aidl
@@ -46,5 +46,5 @@ oneway interface IRemoteAnimationRunner {
* won't have any effect anymore.
*/
@UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
- void onAnimationCancelled(boolean isKeyguardOccluded);
+ void onAnimationCancelled();
}
diff --git a/core/java/android/view/ImeFocusController.java b/core/java/android/view/ImeFocusController.java
index 43828d58afc4..97148969e17f 100644
--- a/core/java/android/view/ImeFocusController.java
+++ b/core/java/android/view/ImeFocusController.java
@@ -86,9 +86,12 @@ public final class ImeFocusController {
void onPreWindowFocus(boolean hasWindowFocus, WindowManager.LayoutParams windowAttribute) {
mHasImeFocus = WindowManager.LayoutParams.mayUseInputMethod(windowAttribute.flags);
if (!hasWindowFocus || !mHasImeFocus || isInLocalFocusMode(windowAttribute)) {
- return;
+ if (!hasWindowFocus) {
+ getImmDelegate().onWindowLostFocus(mViewRootImpl);
+ }
+ } else {
+ getImmDelegate().onPreWindowGainedFocus(mViewRootImpl);
}
- getImmDelegate().onPreWindowGainedFocus(mViewRootImpl);
}
@UiThread
@@ -163,6 +166,7 @@ public final class ImeFocusController {
void onPreWindowGainedFocus(ViewRootImpl viewRootImpl);
void onPostWindowGainedFocus(View viewForWindowFocus,
@NonNull WindowManager.LayoutParams windowAttribute);
+ void onWindowLostFocus(@NonNull ViewRootImpl viewRootImpl);
void onViewFocusChanged(@NonNull View view, boolean hasFocus);
void onScheduledCheckFocus(@NonNull ViewRootImpl viewRootImpl);
void onViewDetachedFromWindow(View view, ViewRootImpl viewRootImpl);
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 82cf07355a56..41ef44e1ac1f 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -482,13 +482,21 @@ public final class InputMethodManager {
private View mNextServedView;
/**
- * This is the root view of the overall window that currently has input
- * method focus.
+ * The latest {@link ViewRootImpl} that has, or most recently had, input method focus.
+ *
+ * <p>This value will be cleared when it becomes inactive and no longer has window focus.
*/
+ @Nullable
@GuardedBy("mH")
ViewRootImpl mCurRootView;
/**
+ * Whether the {@link #mCurRootView} currently has window focus.
+ */
+ @GuardedBy("mH")
+ boolean mCurRootViewWindowFocused;
+
+ /**
* This is set when we are in the process of connecting, to determine
* when we have actually finished.
*/
@@ -745,6 +753,7 @@ public final class InputMethodManager {
public void onPreWindowGainedFocus(ViewRootImpl viewRootImpl) {
synchronized (mH) {
setCurrentRootViewLocked(viewRootImpl);
+ mCurRootViewWindowFocused = true;
}
}
@@ -822,6 +831,17 @@ public final class InputMethodManager {
}
@Override
+ public void onWindowLostFocus(@NonNull ViewRootImpl viewRootImpl) {
+ synchronized (mH) {
+ if (mCurRootView == viewRootImpl) {
+ mCurRootViewWindowFocused = false;
+
+ clearCurRootViewIfNeeded();
+ }
+ }
+ }
+
+ @Override
public void onViewFocusChanged(@Nullable View view, boolean hasFocus) {
onViewFocusChangedInternal(view, hasFocus);
}
@@ -1114,6 +1134,10 @@ public final class InputMethodManager {
// Note that finishComposingText() is allowed to run
// even when we are not active.
mFallbackInputConnection.finishComposingTextFromImm();
+
+ if (clearCurRootViewIfNeeded()) {
+ return;
+ }
}
// Check focus again in case that "onWindowFocus" is called before
// handling this message.
@@ -1756,8 +1780,7 @@ public final class InputMethodManager {
}
/**
- * Return true if the given view is the currently active view for the
- * input method.
+ * Return {@code true} if the given view is the currently active view for the input method.
*/
public boolean isActive(View view) {
// Re-dispatch if there is a context mismatch.
@@ -1773,7 +1796,7 @@ public final class InputMethodManager {
}
/**
- * Return true if any view is currently active in the input method.
+ * Return {@code true} if any view is currently active for the input method.
*/
public boolean isActive() {
checkFocus();
@@ -1783,6 +1806,20 @@ public final class InputMethodManager {
}
/**
+ * Returns {@code true} if the given view's {@link ViewRootImpl} is the currently active one
+ * for the {@code InputMethodManager}.
+ *
+ * @hide
+ */
+ @TestApi
+ @RequiresPermission(Manifest.permission.TEST_INPUT_METHOD)
+ public boolean isCurrentRootView(@NonNull View attachedView) {
+ synchronized (mH) {
+ return mCurRootView == attachedView.getViewRootImpl();
+ }
+ }
+
+ /**
* Return {@code true} if the currently served view is accepting full text edits.
* If {@code false}, it has no input connection, so it can only handle raw key events.
*/
@@ -1908,6 +1945,24 @@ public final class InputMethodManager {
mImeDispatcher.clear();
}
+ /**
+ * Clears the {@link #mCurRootView} if it's no longer window focused and the connection is
+ * no longer active.
+ *
+ * @return {@code} true iff it was cleared.
+ */
+ @GuardedBy("mH")
+ private boolean clearCurRootViewIfNeeded() {
+ if (!mActive && !mCurRootViewWindowFocused) {
+ finishInputLocked();
+ mDelegate.setCurrentRootViewLocked(null);
+
+ return true;
+ }
+
+ return false;
+ }
+
public void displayCompletions(View view, CompletionInfo[] completions) {
// Re-dispatch if there is a context mismatch.
final InputMethodManager fallbackImm = getFallbackInputMethodManagerIfNecessary(view);
diff --git a/core/java/android/view/inputmethod/TextBoundsInfo.java b/core/java/android/view/inputmethod/TextBoundsInfo.java
index d42d94e91933..d9f59d634295 100644
--- a/core/java/android/view/inputmethod/TextBoundsInfo.java
+++ b/core/java/android/view/inputmethod/TextBoundsInfo.java
@@ -1025,6 +1025,7 @@ public final class TextBoundsInfo implements Parcelable {
mEnd = -1;
mCharacterBounds = null;
mCharacterFlags = null;
+ mCharacterBidiLevels = null;
mLineSegmentFinder = null;
mWordSegmentFinder = null;
mGraphemeSegmentFinder = null;
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 7931d1a06d39..2dbff581fe84 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -724,7 +724,10 @@ public class Editor {
}
getPositionListener().addSubscriber(mCursorAnchorInfoNotifier, true);
- makeBlink();
+ // Call resumeBlink here instead of makeBlink to ensure that if mBlink is not null the
+ // Blink object is uncancelled. This ensures when a view is removed and added back the
+ // cursor will resume blinking.
+ resumeBlink();
}
void onDetachedFromWindow() {
@@ -1094,8 +1097,10 @@ public class Editor {
private void resumeBlink() {
if (mBlink != null) {
mBlink.uncancel();
- makeBlink();
}
+ // Moving makeBlink outside of the null check block ensures that mBlink object gets
+ // instantiated when the view is added to the window if mBlink is still null.
+ makeBlink();
}
void adjustInputType(boolean password, boolean passwordInputType,
@@ -2921,6 +2926,9 @@ public class Editor {
if (shouldBlink()) {
mShowCursor = SystemClock.uptimeMillis();
if (mBlink == null) mBlink = new Blink();
+ // Call uncancel as mBlink could have previously been cancelled and cursor will not
+ // resume blinking unless uncancelled.
+ mBlink.uncancel();
mTextView.removeCallbacks(mBlink);
mTextView.postDelayed(mBlink, BLINK);
} else {
diff --git a/core/java/com/android/internal/accessibility/util/AccessibilityUtils.java b/core/java/com/android/internal/accessibility/util/AccessibilityUtils.java
index 3a8f427d54bc..4f9fc39300ae 100644
--- a/core/java/com/android/internal/accessibility/util/AccessibilityUtils.java
+++ b/core/java/com/android/internal/accessibility/util/AccessibilityUtils.java
@@ -32,6 +32,9 @@ import android.content.pm.ResolveInfo;
import android.os.Build;
import android.os.UserHandle;
import android.provider.Settings;
+import android.telecom.TelecomManager;
+import android.telephony.Annotation;
+import android.telephony.TelephonyManager;
import android.text.ParcelableSpan;
import android.text.Spanned;
import android.text.TextUtils;
@@ -204,6 +207,32 @@ public final class AccessibilityUtils {
}
/**
+ * Intercepts the {@link AccessibilityService#GLOBAL_ACTION_KEYCODE_HEADSETHOOK} action
+ * by directly interacting with TelecomManager if a call is incoming or in progress.
+ *
+ * <p>
+ * Provided here in shared utils to be used by both the legacy and modern (SysUI)
+ * system action implementations.
+ * </p>
+ *
+ * @return True if the action was propagated to TelecomManager, otherwise false.
+ */
+ public static boolean interceptHeadsetHookForActiveCall(Context context) {
+ final TelecomManager telecomManager = context.getSystemService(TelecomManager.class);
+ @Annotation.CallState final int callState =
+ telecomManager != null ? telecomManager.getCallState()
+ : TelephonyManager.CALL_STATE_IDLE;
+ if (callState == TelephonyManager.CALL_STATE_RINGING) {
+ telecomManager.acceptRingingCall();
+ return true;
+ } else if (callState == TelephonyManager.CALL_STATE_OFFHOOK) {
+ telecomManager.endCall();
+ return true;
+ }
+ return false;
+ }
+
+ /**
* Indicates whether the current user has completed setup via the setup wizard.
* {@link android.provider.Settings.Secure#USER_SETUP_COMPLETE}
*
diff --git a/core/proto/android/server/windowmanagertransitiontrace.proto b/core/proto/android/server/windowmanagertransitiontrace.proto
index c3cbc9102b27..a776bd2a4330 100644
--- a/core/proto/android/server/windowmanagertransitiontrace.proto
+++ b/core/proto/android/server/windowmanagertransitiontrace.proto
@@ -44,6 +44,10 @@ message TransitionTraceProto {
// Additional debugging info only collected and dumped when explicitly requested to trace
repeated TransitionState transition_states = 3;
repeated TransitionInfo transition_info = 4;
+
+ /* offset between real-time clock and elapsed time clock in nanoseconds.
+ Calculated as: 1000000 * System.currentTimeMillis() - SystemClock.elapsedRealtimeNanos() */
+ optional fixed64 real_to_elapsed_time_offset_nanos = 5;
}
message Transition {
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 31220b438ac4..dd535a12d013 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -8228,6 +8228,8 @@
<service android:name="com.android.server.companion.datatransfer.contextsync.CallMetadataSyncInCallService"
android:permission="android.permission.BIND_INCALL_SERVICE"
android:exported="true">
+ <meta-data android:name="android.telecom.INCLUDE_SELF_MANAGED_CALLS"
+ android:value="true" />
<intent-filter>
<action android:name="android.telecom.InCallService"/>
</intent-filter>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index c5f7ea6501ff..12dad7eb1faa 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -558,6 +558,9 @@
docked if the dock is configured to enable the accelerometer. -->
<bool name="config_supportAutoRotation">true</bool>
+ <!-- If true, allows rotation resolver service to help resolve screen rotation. -->
+ <bool name="config_allowRotationResolver">true</bool>
+
<!-- If true, the screen can be rotated via the accelerometer in all 4
rotations as the default behavior. -->
<bool name="config_allowAllRotations">false</bool>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index c6462f15ec50..a49ea0bd55fb 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -861,6 +861,12 @@
<!-- "Switch" is a verb; it means to change user profile by tapping another user profile name. -->
<string name="managed_profile_label">Switch to work profile</string>
+ <!-- "Switch" is a verb; it means to change user profile by tapping another user profile name. -->
+ <string name="user_owner_app_label">Switch to personal <xliff:g id="app_name" example="Gmail">%1$s</xliff:g></string>
+
+ <!-- "Switch" is a verb; it means to change user profile by tapping another user profile name. -->
+ <string name="managed_profile_app_label">Switch to work <xliff:g id="app_name" example="Gmail">%1$s</xliff:g></string>
+
<!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permgrouplab_contacts">Contacts</string>
<!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index b7df6a482983..bb10f7ae7c93 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1068,7 +1068,9 @@
<java-symbol type="string" name="action_bar_home_subtitle_description_format" />
<java-symbol type="string" name="wireless_display_route_description" />
<java-symbol type="string" name="user_owner_label" />
+ <java-symbol type="string" name="user_owner_app_label" />
<java-symbol type="string" name="managed_profile_label" />
+ <java-symbol type="string" name="managed_profile_app_label" />
<java-symbol type="string" name="managed_profile_label_badge" />
<java-symbol type="string" name="managed_profile_label_badge_2" />
<java-symbol type="string" name="managed_profile_label_badge_3" />
@@ -1713,6 +1715,7 @@
<java-symbol type="integer" name="config_motionPredictionOffsetNanos" />
<java-symbol type="bool" name="config_showNavigationBar" />
<java-symbol type="bool" name="config_supportAutoRotation" />
+ <java-symbol type="bool" name="config_allowRotationResolver" />
<java-symbol type="bool" name="config_dockedStackDividerFreeSnapMode" />
<java-symbol type="dimen" name="docked_stack_divider_thickness" />
<java-symbol type="dimen" name="docked_stack_divider_insets" />
diff --git a/core/tests/coretests/Android.bp b/core/tests/coretests/Android.bp
index 34b4c5177852..67842f05165c 100644
--- a/core/tests/coretests/Android.bp
+++ b/core/tests/coretests/Android.bp
@@ -73,6 +73,7 @@ android_test {
],
jni_libs: [
"libpowermanagertest_jni",
+ "libworksourceparceltest_jni",
],
sdk_version: "core_platform",
diff --git a/core/tests/coretests/jni/Android.bp b/core/tests/coretests/jni/Android.bp
index edac8ef25fe7..7cc844ae9fc6 100644
--- a/core/tests/coretests/jni/Android.bp
+++ b/core/tests/coretests/jni/Android.bp
@@ -43,3 +43,27 @@ cc_test_library {
],
gtest: false,
}
+
+cc_test_library {
+ name: "libworksourceparceltest_jni",
+ srcs: [
+ "NativeWorkSourceParcelTest.cpp",
+ ],
+ shared_libs: [
+ "libandroid",
+ "libandroid_runtime_lazy",
+ "libbase",
+ "libbinder",
+ "liblog",
+ "libnativehelper",
+ "libpowermanager",
+ "libutils",
+ ],
+ header_libs: ["jni_headers"],
+ stl: "libc++_static",
+ cflags: [
+ "-Werror",
+ "-Wall",
+ ],
+ gtest: false,
+}
diff --git a/core/tests/coretests/jni/NativePowerManagerTest.cpp b/core/tests/coretests/jni/NativePowerManagerTest.cpp
index 5f20e4f9c407..c15c0cefcb08 100644
--- a/core/tests/coretests/jni/NativePowerManagerTest.cpp
+++ b/core/tests/coretests/jni/NativePowerManagerTest.cpp
@@ -18,6 +18,7 @@
#define LOG_TAG "NativePowerManagerTest"
#include "jni.h"
+#include "ParcelHelper.h"
#include <android_util_Binder.h>
#include <binder/IServiceManager.h>
@@ -36,21 +37,6 @@ using android::base::StringPrintf;
namespace android {
-#define FIND_CLASS(var, className) \
- var = env->FindClass(className); \
- LOG_FATAL_IF(!(var), "Unable to find class %s", className);
-
-#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
- var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
- LOG_FATAL_IF(!(var), "Unable to find field %s", fieldName);
-
-#define GET_STATIC_METHOD_ID(var, clazz, fieldName, fieldDescriptor) \
- var = env->GetStaticMethodID(clazz, fieldName, fieldDescriptor); \
- LOG_FATAL_IF(!(var), "Unable to find method %s", fieldName);
-
-static jclass gParcelClazz;
-static jfieldID gParcelDataFieldID;
-static jmethodID gParcelObtainMethodID;
static struct BatterySaverPolicyConfigFieldId {
jfieldID adjustBrightnessFactor;
jfieldID advertiseIsEnabled;
@@ -73,102 +59,6 @@ static struct BatterySaverPolicyConfigFieldId {
jfieldID soundTriggerMode;
} gBSPCFieldIds;
-static jobject nativeObtainParcel(JNIEnv* env) {
- jobject parcel = env->CallStaticObjectMethod(gParcelClazz, gParcelObtainMethodID);
- if (parcel == nullptr) {
- jniThrowException(env, "java/lang/IllegalArgumentException", "Obtain parcel failed.");
- }
- return parcel;
-}
-
-static Parcel* nativeGetParcelData(JNIEnv* env, jobject obj) {
- Parcel* parcel = reinterpret_cast<Parcel*>(env->GetLongField(obj, gParcelDataFieldID));
- if (parcel && parcel->objectsCount() != 0) {
- jniThrowException(env, "java/lang/IllegalArgumentException", "Invalid parcel object.");
- }
- parcel->setDataPosition(0);
- return parcel;
-}
-
-static jobject nativeObtainWorkSourceParcel(JNIEnv* env, jobject /* obj */, jintArray uidArray,
- jobjectArray nameArray) {
- std::vector<int32_t> uids;
- std::optional<std::vector<std::optional<String16>>> names = std::nullopt;
-
- if (uidArray != nullptr) {
- jint *ptr = env->GetIntArrayElements(uidArray, 0);
- for (jint i = 0; i < env->GetArrayLength(uidArray); i++) {
- uids.push_back(static_cast<int32_t>(ptr[i]));
- }
- }
-
- if (nameArray != nullptr) {
- std::vector<std::optional<String16>> namesVec;
- for (jint i = 0; i < env->GetArrayLength(nameArray); i++) {
- jstring string = (jstring) (env->GetObjectArrayElement(nameArray, i));
- const char *rawString = env->GetStringUTFChars(string, 0);
- namesVec.push_back(std::make_optional<String16>(String16(rawString)));
- }
- names = std::make_optional(std::move(namesVec));
- }
-
- WorkSource ws = WorkSource(uids, names);
- jobject wsParcel = nativeObtainParcel(env);
- Parcel* parcel = nativeGetParcelData(env, wsParcel);
- status_t err = ws.writeToParcel(parcel);
- if (err != OK) {
- jniThrowException(env, "java/lang/IllegalArgumentException",
- StringPrintf("WorkSource writeToParcel failed %d", err).c_str());
- }
- parcel->setDataPosition(0);
- return wsParcel;
-}
-
-static void nativeUnparcelAndVerifyWorkSource(JNIEnv* env, jobject /* obj */, jobject wsParcel,
- jintArray uidArray, jobjectArray nameArray) {
- WorkSource ws = {};
- Parcel* parcel = nativeGetParcelData(env, wsParcel);
-
- status_t err = ws.readFromParcel(parcel);
- if (err != OK) {
- ALOGE("WorkSource writeToParcel failed %d", err);
- }
-
- // Now we have a native WorkSource object, verify it.
- if (uidArray != nullptr) {
- jint *ptr = env->GetIntArrayElements(uidArray, 0);
- for (jint i = 0; i < env->GetArrayLength(uidArray); i++) {
- if (ws.getUids().at(i) != static_cast<int32_t>(ptr[i])) {
- jniThrowException(env, "java/lang/IllegalArgumentException",
- StringPrintf("WorkSource uid not equal %d %d",
- ws.getUids().at(i), static_cast<int32_t>(ptr[i])).c_str());
- }
- }
- } else {
- if (ws.getUids().size() != 0) {
- jniThrowException(env, "java/lang/IllegalArgumentException",
- StringPrintf("WorkSource parcel size not 0").c_str());
- }
- }
-
- if (nameArray != nullptr) {
- std::vector<std::optional<String16>> namesVec;
- for (jint i = 0; i < env->GetArrayLength(nameArray); i++) {
- jstring string = (jstring) (env->GetObjectArrayElement(nameArray, i));
- const char *rawString = env->GetStringUTFChars(string, 0);
- if (String16(rawString) != ws.getNames()->at(i)) {
- jniThrowException(env, "java/lang/IllegalArgumentException",
- StringPrintf("WorkSource uid not equal %s", rawString).c_str());
- }
- }
- } else {
- if (ws.getNames() != std::nullopt) {
- jniThrowException(env, "java/lang/IllegalArgumentException",
- StringPrintf("WorkSource parcel name not empty").c_str());
- }
- }
-}
-
static jobject nativeObtainPowerSaveStateParcel(JNIEnv* env, jobject /* obj */,
jboolean batterySaverEnabled, jboolean globalBatterySaverEnabled,
jint locationMode, jint soundTriggerMode, jfloat brightnessFactor) {
@@ -305,10 +195,6 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
JNIEnv* env;
const JNINativeMethod methodTable[] = {
/* name, signature, funcPtr */
- { "nativeObtainWorkSourceParcel", "([I[Ljava/lang/String;)Landroid/os/Parcel;",
- (void*) nativeObtainWorkSourceParcel },
- { "nativeUnparcelAndVerifyWorkSource", "(Landroid/os/Parcel;[I[Ljava/lang/String;)V",
- (void*) nativeUnparcelAndVerifyWorkSource },
{ "nativeObtainPowerSaveStateParcel", "(ZZIIF)Landroid/os/Parcel;",
(void*) nativeObtainPowerSaveStateParcel },
{ "nativeUnparcelAndVerifyPowerSaveState", "(Landroid/os/Parcel;ZZIIF)V",
@@ -327,34 +213,40 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
return JNI_ERR;
}
- jclass bspcClazz;
- FIND_CLASS(gParcelClazz, "android/os/Parcel");
- GET_FIELD_ID(gParcelDataFieldID, gParcelClazz, "mNativePtr", "J");
- GET_STATIC_METHOD_ID(gParcelObtainMethodID, gParcelClazz, "obtain", "()Landroid/os/Parcel;");
- FIND_CLASS(bspcClazz, "android/os/BatterySaverPolicyConfig");
- GET_FIELD_ID(gBSPCFieldIds.adjustBrightnessFactor, bspcClazz, "mAdjustBrightnessFactor", "F");
- GET_FIELD_ID(gBSPCFieldIds.advertiseIsEnabled, bspcClazz, "mAdvertiseIsEnabled", "Z");
- GET_FIELD_ID(gBSPCFieldIds.deferFullBackup, bspcClazz, "mDeferFullBackup", "Z");
- GET_FIELD_ID(gBSPCFieldIds.deferKeyValueBackup, bspcClazz, "mDeferKeyValueBackup", "Z");
- GET_FIELD_ID(gBSPCFieldIds.deviceSpecificSettings, bspcClazz, "mDeviceSpecificSettings",
- "Ljava/util/Map;");
- GET_FIELD_ID(gBSPCFieldIds.disableAnimation, bspcClazz, "mDisableAnimation", "Z");
- GET_FIELD_ID(gBSPCFieldIds.disableAod, bspcClazz, "mDisableAod", "Z");
- GET_FIELD_ID(gBSPCFieldIds.disableLaunchBoost, bspcClazz, "mDisableLaunchBoost", "Z");
- GET_FIELD_ID(gBSPCFieldIds.disableOptionalSensors, bspcClazz, "mDisableOptionalSensors", "Z");
- GET_FIELD_ID(gBSPCFieldIds.disableVibration, bspcClazz, "mDisableVibration", "Z");
- GET_FIELD_ID(gBSPCFieldIds.enableAdjustBrightness, bspcClazz, "mEnableAdjustBrightness", "Z");
- GET_FIELD_ID(gBSPCFieldIds.enableDataSaver, bspcClazz, "mEnableDataSaver", "Z");
- GET_FIELD_ID(gBSPCFieldIds.enableFirewall, bspcClazz, "mEnableFirewall", "Z");
- GET_FIELD_ID(gBSPCFieldIds.enableNightMode, bspcClazz, "mEnableNightMode", "Z");
- GET_FIELD_ID(gBSPCFieldIds.enableQuickDoze, bspcClazz, "mEnableQuickDoze", "Z");
- GET_FIELD_ID(gBSPCFieldIds.forceAllAppsStandby, bspcClazz, "mForceAllAppsStandby", "Z");
- GET_FIELD_ID(gBSPCFieldIds.forceBackgroundCheck, bspcClazz, "mForceBackgroundCheck", "Z");
- GET_FIELD_ID(gBSPCFieldIds.locationMode, bspcClazz, "mLocationMode", "I");
- GET_FIELD_ID(gBSPCFieldIds.soundTriggerMode, bspcClazz, "mSoundTriggerMode", "I");
+ loadParcelClass(env);
+
+ jclass bspcClazz = FindClassOrDie(env, "android/os/BatterySaverPolicyConfig");
+
+ gBSPCFieldIds.adjustBrightnessFactor =
+ GetFieldIDOrDie(env, bspcClazz, "mAdjustBrightnessFactor", "F");
+ gBSPCFieldIds.advertiseIsEnabled = GetFieldIDOrDie(env, bspcClazz, "mAdvertiseIsEnabled", "Z");
+ gBSPCFieldIds.deferFullBackup = GetFieldIDOrDie(env, bspcClazz, "mDeferFullBackup", "Z");
+ gBSPCFieldIds.deferKeyValueBackup =
+ GetFieldIDOrDie(env, bspcClazz, "mDeferKeyValueBackup", "Z");
+ gBSPCFieldIds.deviceSpecificSettings =
+ GetFieldIDOrDie(env, bspcClazz, "mDeviceSpecificSettings", "Ljava/util/Map;");
+ gBSPCFieldIds.disableAnimation = GetFieldIDOrDie(env, bspcClazz, "mDisableAnimation", "Z");
+ gBSPCFieldIds.disableAod = GetFieldIDOrDie(env, bspcClazz, "mDisableAod", "Z");
+ gBSPCFieldIds.disableLaunchBoost = GetFieldIDOrDie(env, bspcClazz, "mDisableLaunchBoost", "Z");
+ gBSPCFieldIds.disableOptionalSensors =
+ GetFieldIDOrDie(env, bspcClazz, "mDisableOptionalSensors", "Z");
+ gBSPCFieldIds.disableVibration = GetFieldIDOrDie(env, bspcClazz, "mDisableVibration", "Z");
+ gBSPCFieldIds.enableAdjustBrightness =
+ GetFieldIDOrDie(env, bspcClazz, "mEnableAdjustBrightness", "Z");
+ gBSPCFieldIds.enableDataSaver = GetFieldIDOrDie(env, bspcClazz, "mEnableDataSaver", "Z");
+ gBSPCFieldIds.enableFirewall = GetFieldIDOrDie(env, bspcClazz, "mEnableFirewall", "Z");
+ gBSPCFieldIds.enableNightMode = GetFieldIDOrDie(env, bspcClazz, "mEnableNightMode", "Z");
+ gBSPCFieldIds.enableQuickDoze = GetFieldIDOrDie(env, bspcClazz, "mEnableQuickDoze", "Z");
+ gBSPCFieldIds.forceAllAppsStandby =
+ GetFieldIDOrDie(env, bspcClazz, "mForceAllAppsStandby", "Z");
+ gBSPCFieldIds.forceBackgroundCheck =
+ GetFieldIDOrDie(env, bspcClazz, "mForceBackgroundCheck", "Z");
+ gBSPCFieldIds.locationMode = GetFieldIDOrDie(env, bspcClazz, "mLocationMode", "I");
+ gBSPCFieldIds.soundTriggerMode = GetFieldIDOrDie(env, bspcClazz, "mSoundTriggerMode", "I");
jniRegisterNativeMethods(env, "android/os/PowerManagerTest", methodTable,
sizeof(methodTable) / sizeof(JNINativeMethod));
+
return JNI_VERSION_1_6;
}
diff --git a/core/tests/coretests/jni/NativeWorkSourceParcelTest.cpp b/core/tests/coretests/jni/NativeWorkSourceParcelTest.cpp
new file mode 100644
index 000000000000..db1f7bde4b4f
--- /dev/null
+++ b/core/tests/coretests/jni/NativeWorkSourceParcelTest.cpp
@@ -0,0 +1,156 @@
+/*
+ * 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "NativeWorkSourceParcelTest"
+
+#include "jni.h"
+#include "ParcelHelper.h"
+
+#include <android_util_Binder.h>
+#include <nativehelper/JNIHelp.h>
+#include <nativehelper/ScopedPrimitiveArray.h>
+#include <utils/Log.h>
+
+#include <android/WorkSource.h>
+#include <android-base/stringprintf.h>
+#include <android-base/strings.h>
+
+using namespace android::os;
+using android::base::StringPrintf;
+
+namespace android {
+
+static jobject nativeObtainWorkSourceParcel(JNIEnv* env, jobject /* obj */, jintArray uidArray,
+ jobjectArray nameArray, jint parcelEndMarker) {
+ std::vector<int32_t> uids;
+ std::optional<std::vector<std::optional<String16>>> names = std::nullopt;
+
+ if (uidArray != nullptr) {
+ ScopedIntArrayRO workSourceUids(env, uidArray);
+ for (int i = 0; i < workSourceUids.size(); i++) {
+ uids.push_back(static_cast<int32_t>(workSourceUids[i]));
+ }
+ }
+
+ if (nameArray != nullptr) {
+ std::vector<std::optional<String16>> namesVec;
+ for (jint i = 0; i < env->GetArrayLength(nameArray); i++) {
+ jstring string = static_cast<jstring>(env->GetObjectArrayElement(nameArray, i));
+ const char *rawString = env->GetStringUTFChars(string, 0);
+ namesVec.push_back(std::make_optional<String16>(String16(rawString)));
+ }
+ names = std::make_optional(std::move(namesVec));
+ }
+
+ WorkSource ws = WorkSource(uids, names);
+ jobject wsParcel = nativeObtainParcel(env);
+ Parcel* parcel = nativeGetParcelData(env, wsParcel);
+
+ // write WorkSource and if no error write end marker
+ status_t err = ws.writeToParcel(parcel) ?: parcel->writeInt32(parcelEndMarker);
+
+ if (err != OK) {
+ jniThrowException(env, "java/lang/IllegalArgumentException",
+ StringPrintf("WorkSource writeToParcel failed %d", err).c_str());
+ }
+ parcel->setDataPosition(0);
+ return wsParcel;
+}
+
+static void nativeUnparcelAndVerifyWorkSource(JNIEnv* env, jobject /* obj */, jobject wsParcel,
+ jintArray uidArray, jobjectArray nameArray, jint parcelEndMarker) {
+ WorkSource ws = {};
+ Parcel* parcel = nativeGetParcelData(env, wsParcel);
+ int32_t endMarker;
+
+ // read WorkSource and if no error read end marker
+ status_t err = ws.readFromParcel(parcel) ?: parcel->readInt32(&endMarker);
+ int32_t dataAvailable = parcel->dataAvail();
+
+ if (err != OK) {
+ ALOGE("WorkSource readFromParcel failed %d", err);
+ }
+
+ // Now we have a native WorkSource object, verify it.
+ if (dataAvailable > 0) { // not all data read from the parcel
+ jniThrowException(env, "java/lang/IllegalArgumentException",
+ StringPrintf("WorkSource contains more data than native read (%d)",
+ dataAvailable).c_str());
+ } else if (endMarker != parcelEndMarker) { // more date than available read from parcel
+ jniThrowException(env, "java/lang/IllegalArgumentException",
+ StringPrintf("WorkSource contains less data than native read").c_str());
+ }
+
+ if (uidArray != nullptr) {
+ ScopedIntArrayRO workSourceUids(env, uidArray);
+ for (int i = 0; i < workSourceUids.size(); i++) {
+ if (ws.getUids().at(i) != static_cast<int32_t>(workSourceUids[i])) {
+ jniThrowException(env, "java/lang/IllegalArgumentException",
+ StringPrintf("WorkSource uid not equal %d %d",
+ ws.getUids().at(i), static_cast<int32_t>(workSourceUids[i])).c_str());
+ }
+ }
+ } else {
+ if (ws.getUids().size() != 0) {
+ jniThrowException(env, "java/lang/IllegalArgumentException",
+ StringPrintf("WorkSource parcel size not 0").c_str());
+ }
+ }
+
+ if (nameArray != nullptr) {
+ std::vector<std::optional<String16>> namesVec;
+ for (jint i = 0; i < env->GetArrayLength(nameArray); i++) {
+ jstring string = (jstring) (env->GetObjectArrayElement(nameArray, i));
+ const char *rawString = env->GetStringUTFChars(string, 0);
+ if (String16(rawString) != ws.getNames()->at(i)) {
+ jniThrowException(env, "java/lang/IllegalArgumentException",
+ StringPrintf("WorkSource uid not equal %s", rawString).c_str());
+ }
+ }
+ } else {
+ if (ws.getNames() != std::nullopt) {
+ jniThrowException(env, "java/lang/IllegalArgumentException",
+ StringPrintf("WorkSource parcel name not empty").c_str());
+ }
+ }
+}
+
+extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
+{
+ JNIEnv* env;
+
+ const JNINativeMethod workSourceMethodTable[] = {
+ /* name, signature, funcPtr */
+ { "nativeObtainWorkSourceParcel", "([I[Ljava/lang/String;I)Landroid/os/Parcel;",
+ (void*) nativeObtainWorkSourceParcel },
+ { "nativeUnparcelAndVerifyWorkSource", "(Landroid/os/Parcel;[I[Ljava/lang/String;I)V",
+ (void*) nativeUnparcelAndVerifyWorkSource },
+ };
+
+ if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
+ return JNI_ERR;
+ }
+
+ loadParcelClass(env);
+
+ jniRegisterNativeMethods(env, "android/os/WorkSourceParcelTest", workSourceMethodTable,
+ sizeof(workSourceMethodTable) / sizeof(JNINativeMethod));
+
+ return JNI_VERSION_1_6;
+}
+
+} /* namespace android */
diff --git a/core/tests/coretests/jni/ParcelHelper.h b/core/tests/coretests/jni/ParcelHelper.h
new file mode 100644
index 000000000000..1485a2a3be17
--- /dev/null
+++ b/core/tests/coretests/jni/ParcelHelper.h
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ */
+#pragma once
+
+#include <nativehelper/JNIHelp.h>
+#include <binder/Parcel.h>
+
+namespace android {
+ static jclass gParcelClazz;
+ static jfieldID gParcelDataFieldID;
+ static jmethodID gParcelObtainMethodID;
+
+ static inline jclass FindClassOrDie(JNIEnv* env, const char* class_name) {
+ jclass clazz = env->FindClass(class_name);
+ LOG_ALWAYS_FATAL_IF(clazz == NULL, "Unable to find class %s", class_name);
+ return clazz;
+ }
+
+ static inline jfieldID GetFieldIDOrDie(JNIEnv* env, jclass clazz, const char* field_name,
+ const char* field_signature) {
+ jfieldID res = env->GetFieldID(clazz, field_name, field_signature);
+ LOG_ALWAYS_FATAL_IF(res == NULL, "Unable to find field %s with signature %s", field_name,
+ field_signature);
+ return res;
+ }
+
+ static inline jmethodID GetStaticMethodIDOrDie(JNIEnv* env, jclass clazz,
+ const char* method_name,
+ const char* method_signature) {
+ jmethodID res = env->GetStaticMethodID(clazz, method_name, method_signature);
+ LOG_ALWAYS_FATAL_IF(res == NULL, "Unable to find method %s with signature %s", method_name,
+ method_signature);
+ return res;
+ }
+
+ static jobject nativeObtainParcel(JNIEnv* env) {
+ jobject parcel = env->CallStaticObjectMethod(gParcelClazz, gParcelObtainMethodID);
+ if (parcel == nullptr) {
+ jniThrowException(env, "java/lang/IllegalArgumentException", "Obtain parcel failed.");
+ }
+ return parcel;
+ }
+
+ static Parcel* nativeGetParcelData(JNIEnv* env, jobject obj) {
+ Parcel* parcel = reinterpret_cast<Parcel*>(env->GetLongField(obj, gParcelDataFieldID));
+ if (parcel && parcel->objectsCount() != 0) {
+ jniThrowException(env, "java/lang/IllegalArgumentException", "Invalid parcel object.");
+ }
+ parcel->setDataPosition(0);
+ return parcel;
+ }
+
+ static void loadParcelClass(JNIEnv* env) {
+ gParcelClazz = FindClassOrDie(env, "android/os/Parcel");
+ gParcelDataFieldID = GetFieldIDOrDie(env, gParcelClazz, "mNativePtr", "J");
+ gParcelObtainMethodID =
+ GetStaticMethodIDOrDie(env, gParcelClazz, "obtain", "()Landroid/os/Parcel;");
+ }
+
+} \ No newline at end of file
diff --git a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
index fb0f3d419002..af81957d1e03 100644
--- a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
+++ b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
@@ -62,7 +62,6 @@ import android.util.MergedConfiguration;
import android.view.Display;
import android.view.View;
-import androidx.test.filters.FlakyTest;
import androidx.test.filters.MediumTest;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.rule.ActivityTestRule;
@@ -616,7 +615,6 @@ public class ActivityThreadTest {
}
@Test
- @FlakyTest(bugId = 176134235)
public void testHandleConfigurationChanged_DoesntOverrideActivityConfig() {
final TestActivity activity = mActivityTestRule.launchActivity(new Intent());
diff --git a/core/tests/coretests/src/android/content/pm/CrossProfileAppsTest.java b/core/tests/coretests/src/android/content/pm/CrossProfileAppsTest.java
index 5e076076d2f4..661b210f3e18 100644
--- a/core/tests/coretests/src/android/content/pm/CrossProfileAppsTest.java
+++ b/core/tests/coretests/src/android/content/pm/CrossProfileAppsTest.java
@@ -20,15 +20,18 @@ import static android.app.admin.DevicePolicyResources.Strings.Core.SWITCH_TO_PER
import static android.app.admin.DevicePolicyResources.Strings.Core.SWITCH_TO_WORK_LABEL;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyFloat;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.nullable;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.admin.DevicePolicyManager;
import android.app.admin.DevicePolicyResourcesManager;
import android.content.Context;
+import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.UserHandle;
@@ -76,15 +79,21 @@ public class CrossProfileAppsTest {
private Drawable mDrawable;
@Mock
private PackageManager mPackageManager;
+
+ @Mock private ApplicationInfo mApplicationInfo;
+
+ private Configuration mConfiguration;
+
private CrossProfileApps mCrossProfileApps;
@Before
public void initCrossProfileApps() {
- mCrossProfileApps = new CrossProfileApps(mContext, mService);
+ mCrossProfileApps = spy(new CrossProfileApps(mContext, mService));
}
@Before
public void mockContext() {
+ mConfiguration = new Configuration();
when(mContext.getPackageName()).thenReturn(MY_PACKAGE);
when(mContext.getSystemServiceName(UserManager.class)).thenReturn(Context.USER_SERVICE);
when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
@@ -94,6 +103,8 @@ public class CrossProfileAppsTest {
mDevicePolicyManager);
when(mDevicePolicyManager.getResources()).thenReturn(mDevicePolicyResourcesManager);
when(mContext.getPackageManager()).thenReturn(mPackageManager);
+ when(mContext.getApplicationInfo()).thenReturn(mApplicationInfo);
+ when(mResources.getConfiguration()).thenReturn(mConfiguration);
}
@Before
@@ -115,17 +126,20 @@ public class CrossProfileAppsTest {
@Test
public void getProfileSwitchingLabel_managedProfile() {
setValidTargetProfile(MANAGED_PROFILE);
+ when(mApplicationInfo.loadSafeLabel(any(), anyFloat(), anyInt())).thenReturn("app");
mCrossProfileApps.getProfileSwitchingLabel(MANAGED_PROFILE);
- verify(mDevicePolicyResourcesManager).getString(eq(SWITCH_TO_WORK_LABEL), any());
+ verify(mDevicePolicyResourcesManager).getString(eq(SWITCH_TO_WORK_LABEL), any(), eq("app"));
}
@Test
public void getProfileSwitchingLabel_personalProfile() {
setValidTargetProfile(PERSONAL_PROFILE);
+ when(mApplicationInfo.loadSafeLabel(any(), anyFloat(), anyInt())).thenReturn("app");
mCrossProfileApps.getProfileSwitchingLabel(PERSONAL_PROFILE);
- verify(mDevicePolicyResourcesManager).getString(eq(SWITCH_TO_PERSONAL_LABEL), any());
+ verify(mDevicePolicyResourcesManager)
+ .getString(eq(SWITCH_TO_PERSONAL_LABEL), any(), eq("app"));
}
@Test(expected = SecurityException.class)
diff --git a/core/tests/coretests/src/android/os/PowerManagerTest.java b/core/tests/coretests/src/android/os/PowerManagerTest.java
index 0dfc37131f7f..9f85d6f02ec3 100644
--- a/core/tests/coretests/src/android/os/PowerManagerTest.java
+++ b/core/tests/coretests/src/android/os/PowerManagerTest.java
@@ -49,9 +49,6 @@ public class PowerManagerTest extends AndroidTestCase {
@Mock
private PowerManager.OnThermalStatusChangedListener mListener2;
private static final long CALLBACK_TIMEOUT_MILLI_SEC = 5000;
- private native Parcel nativeObtainWorkSourceParcel(int[] uids, String[] names);
- private native void nativeUnparcelAndVerifyWorkSource(Parcel parcel, int[] uids,
- String[] names);
private native Parcel nativeObtainPowerSaveStateParcel(boolean batterySaverEnabled,
boolean globalBatterySaverEnabled, int locationMode, int soundTriggerMode,
float brightnessFactor);
@@ -300,54 +297,6 @@ public class PowerManagerTest extends AndroidTestCase {
}
/**
- * Helper function to obtain a WorkSource object as parcel from native, with
- * specified uids and names and verify the WorkSource object created from the parcel.
- */
- private void unparcelWorkSourceFromNativeAndVerify(int[] uids, String[] names) {
- // Obtain WorkSource as parcel from native, with uids and names.
- Parcel wsParcel = nativeObtainWorkSourceParcel(uids, names);
- WorkSource ws = WorkSource.CREATOR.createFromParcel(wsParcel);
- if (uids == null) {
- assertEquals(ws.size(), 0);
- } else {
- assertEquals(uids.length, ws.size());
- for (int i = 0; i < ws.size(); i++) {
- assertEquals(ws.getUid(i), uids[i]);
- }
- }
- if (names != null) {
- for (int i = 0; i < names.length; i++) {
- assertEquals(ws.getName(i), names[i]);
- }
- }
- }
-
- /**
- * Helper function to send a WorkSource as parcel from java to native.
- * Native will verify the WorkSource in native is expected.
- */
- private void parcelWorkSourceToNativeAndVerify(int[] uids, String[] names) {
- WorkSource ws = new WorkSource();
- if (uids != null) {
- if (names == null) {
- for (int i = 0; i < uids.length; i++) {
- ws.add(uids[i]);
- }
- } else {
- assertEquals(uids.length, names.length);
- for (int i = 0; i < uids.length; i++) {
- ws.add(uids[i], names[i]);
- }
- }
- }
- Parcel wsParcel = Parcel.obtain();
- ws.writeToParcel(wsParcel, 0 /* flags */);
- wsParcel.setDataPosition(0);
- //Set the WorkSource as parcel to native and verify.
- nativeUnparcelAndVerifyWorkSource(wsParcel, uids, names);
- }
-
- /**
* Helper function to obtain a PowerSaveState as parcel from native, with
* specified parameters, and verify the PowerSaveState object created from the parcel.
*/
@@ -422,43 +371,6 @@ public class PowerManagerTest extends AndroidTestCase {
}
/**
- * Confirm that we can pass WorkSource from native to Java.
- *
- * @throws Exception
- */
- @Test
- public void testWorkSourceNativeToJava() {
- final int[] uids1 = {1000};
- final int[] uids2 = {1000, 2000};
- final String[] names1 = {"testWorkSource1"};
- final String[] names2 = {"testWorkSource1", "testWorkSource2"};
- unparcelWorkSourceFromNativeAndVerify(null /* uids */, null /* names */);
- unparcelWorkSourceFromNativeAndVerify(uids1, null /* names */);
- unparcelWorkSourceFromNativeAndVerify(uids2, null /* names */);
- unparcelWorkSourceFromNativeAndVerify(null /* uids */, names1);
- unparcelWorkSourceFromNativeAndVerify(uids1, names1);
- unparcelWorkSourceFromNativeAndVerify(uids2, names2);
- }
-
- /**
- * Confirm that we can pass WorkSource from Java to native.
- *
- * @throws Exception
- */
- @Test
- public void testWorkSourceJavaToNative() {
- final int[] uids1 = {1000};
- final int[] uids2 = {1000, 2000};
- final String[] names1 = {"testGetWorkSource1"};
- final String[] names2 = {"testGetWorkSource1", "testGetWorkSource2"};
- parcelWorkSourceToNativeAndVerify(null /* uids */, null /* names */);
- parcelWorkSourceToNativeAndVerify(uids1, null /* names */);
- parcelWorkSourceToNativeAndVerify(uids2, null /* names */);
- parcelWorkSourceToNativeAndVerify(uids1, names1);
- parcelWorkSourceToNativeAndVerify(uids2, names2);
- }
-
- /**
* Confirm that we can pass PowerSaveState from native to Java.
*
* @throws Exception
diff --git a/core/tests/coretests/src/android/os/WorkSourceParcelTest.java b/core/tests/coretests/src/android/os/WorkSourceParcelTest.java
new file mode 100644
index 000000000000..483160687723
--- /dev/null
+++ b/core/tests/coretests/src/android/os/WorkSourceParcelTest.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class WorkSourceParcelTest {
+ /**
+ * END_OF_PARCEL_MARKER is added at the end of Parcel on native or java side on write and
+ * then read on java or native side on read. This way we can ensure that no extra data
+ * is read from the parcel.
+ */
+ private static final int END_OF_PARCEL_MARKER = 99;
+
+ private native Parcel nativeObtainWorkSourceParcel(int[] uids, String[] names,
+ int parcelEndMarker);
+
+ private native void nativeUnparcelAndVerifyWorkSource(Parcel parcel, int[] uids,
+ String[] names, int parcelEndMarker);
+
+ static {
+ System.loadLibrary("worksourceparceltest_jni");
+ }
+ /**
+ * Confirm that we can pass WorkSource from native to Java.
+ */
+ @Test
+ public void testWorkSourceNativeToJava() {
+ final int[] uids1 = {1000};
+ final int[] uids2 = {1000, 2000};
+ final String[] names1 = {"testWorkSource1"};
+ final String[] names2 = {"testWorkSource1", "testWorkSource2"};
+ unparcelWorkSourceFromNativeAndVerify(/* uids= */ null , /* names= */ null);
+ unparcelWorkSourceFromNativeAndVerify(uids1, /* names= */ null);
+ unparcelWorkSourceFromNativeAndVerify(uids2, /* names= */ null);
+ unparcelWorkSourceFromNativeAndVerify(/* uids= */ null , names1);
+ unparcelWorkSourceFromNativeAndVerify(uids1, names1);
+ unparcelWorkSourceFromNativeAndVerify(uids2, names2);
+ }
+
+ /**
+ * Confirm that we can pass WorkSource from Java to native.
+ */
+ @Test
+ public void testWorkSourceJavaToNative() {
+ final int[] uids1 = {1000};
+ final int[] uids2 = {1000, 2000};
+ final String[] names1 = {"testGetWorkSource1"};
+ final String[] names2 = {"testGetWorkSource1", "testGetWorkSource2"};
+
+ parcelWorkSourceToNativeAndVerify(/* uids= */ null , /* names= */ null);
+ parcelWorkSourceToNativeAndVerify(uids1, /* names= */ null);
+ parcelWorkSourceToNativeAndVerify(uids2, /* names= */ null);
+ parcelWorkSourceToNativeAndVerify(uids1, names1);
+ parcelWorkSourceToNativeAndVerify(uids2, names2);
+ }
+
+ /**
+ * Helper function to obtain a WorkSource object as parcel from native, with
+ * specified uids and names and verify the WorkSource object created from the parcel.
+ */
+ private void unparcelWorkSourceFromNativeAndVerify(int[] uids, String[] names) {
+ // Obtain WorkSource as parcel from native, with uids and names.
+ // END_OF_PARCEL_MARKER is written at the end of parcel
+ Parcel wsParcel = nativeObtainWorkSourceParcel(uids, names, END_OF_PARCEL_MARKER);
+ // read WorkSource created on native side
+ WorkSource ws = WorkSource.CREATOR.createFromParcel(wsParcel);
+ // read end marker written on native side
+ int endMarker = wsParcel.readInt();
+
+ assertEquals(0, wsParcel.dataAvail()); // we have read everything
+ assertEquals(END_OF_PARCEL_MARKER, endMarker); // endMarkers match
+
+ if (uids == null) {
+ assertEquals(ws.size(), 0);
+ } else {
+ assertEquals(uids.length, ws.size());
+ for (int i = 0; i < ws.size(); i++) {
+ assertEquals(ws.getUid(i), uids[i]);
+ }
+ }
+ if (names != null) {
+ for (int i = 0; i < names.length; i++) {
+ assertEquals(ws.getPackageName(i), names[i]);
+ }
+ }
+ }
+
+ /**
+ * Helper function to send a WorkSource as parcel from java to native.
+ * Native will verify the WorkSource in native is expected.
+ */
+ private void parcelWorkSourceToNativeAndVerify(int[] uids, String[] names) {
+ WorkSource ws = new WorkSource();
+ if (uids != null) {
+ if (names == null) {
+ for (int uid : uids) {
+ ws.add(uid);
+ }
+ } else {
+ assertEquals(uids.length, names.length);
+ for (int i = 0; i < uids.length; i++) {
+ ws.add(uids[i], names[i]);
+ }
+ }
+ }
+ Parcel wsParcel = Parcel.obtain();
+ // write WorkSource on java side
+ ws.writeToParcel(wsParcel, 0 /* flags */);
+ // write end marker on java side
+ wsParcel.writeInt(END_OF_PARCEL_MARKER);
+ wsParcel.setDataPosition(0);
+ //Verify parcel and end marker on native side
+ nativeUnparcelAndVerifyWorkSource(wsParcel, uids, names, END_OF_PARCEL_MARKER);
+ }
+}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationRunner.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationRunner.java
index b917ac80256c..d9b73a8290f5 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationRunner.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationRunner.java
@@ -83,10 +83,7 @@ class TaskFragmentAnimationRunner extends IRemoteAnimationRunner.Stub {
}
@Override
- public void onAnimationCancelled(boolean isKeyguardOccluded) {
- if (TaskFragmentAnimationController.DEBUG) {
- Log.v(TAG, "onAnimationCancelled: isKeyguardOccluded=" + isKeyguardOccluded);
- }
+ public void onAnimationCancelled() {
mHandler.post(this::cancelAnimation);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityAnimation.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityAnimation.java
index 22c90153bb39..edefe9e3ab06 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityAnimation.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityAnimation.java
@@ -404,7 +404,7 @@ class CrossActivityAnimation {
}
@Override
- public void onAnimationCancelled(boolean isKeyguardOccluded) {
+ public void onAnimationCancelled() {
finishAnimation();
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CustomizeActivityAnimation.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CustomizeActivityAnimation.java
index f0c5d8b29b2f..2d6ec7547187 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CustomizeActivityAnimation.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CustomizeActivityAnimation.java
@@ -323,7 +323,7 @@ class CustomizeActivityAnimation {
}
@Override
- public void onAnimationCancelled(boolean isKeyguardOccluded) {
+ public void onAnimationCancelled() {
finishAnimation();
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
index f8f8897e41d5..b9ff5f0e820a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
@@ -282,6 +282,11 @@ public class BubbleStackView extends FrameLayout
/** Whether the expanded view has been hidden, because we are dragging out a bubble. */
private boolean mExpandedViewTemporarilyHidden = false;
+ /**
+ * Whether the last bubble is being removed when expanded, which impacts the collapse animation.
+ */
+ private boolean mRemovingLastBubbleWhileExpanded = false;
+
/** Animator for animating the expanded view's alpha (including the TaskView inside it). */
private final ValueAnimator mExpandedViewAlphaAnimator = ValueAnimator.ofFloat(0f, 1f);
@@ -765,7 +770,7 @@ public class BubbleStackView extends FrameLayout
// Update scrim
if (!mScrimAnimating) {
- showScrim(true);
+ showScrim(true, null /* runnable */);
}
}
}
@@ -880,6 +885,7 @@ public class BubbleStackView extends FrameLayout
final Runnable onBubbleAnimatedOut = () -> {
if (getBubbleCount() == 0) {
+ mExpandedViewTemporarilyHidden = false;
mBubbleController.onAllBubblesAnimatedOut();
}
};
@@ -1007,6 +1013,7 @@ public class BubbleStackView extends FrameLayout
updatePointerPosition(false /* forIme */);
mExpandedAnimationController.expandFromStack(() -> {
afterExpandedViewAnimation();
+ mExpandedViewContainer.setVisibility(VISIBLE);
showManageMenu(mShowingManage);
} /* after */);
PointF p = mPositioner.getExpandedBubbleXY(getBubbleIndex(mExpandedBubble),
@@ -1772,6 +1779,20 @@ public class BubbleStackView extends FrameLayout
if (DEBUG_BUBBLE_STACK_VIEW) {
Log.d(TAG, "removeBubble: " + bubble);
}
+ if (isExpanded() && getBubbleCount() == 1) {
+ mRemovingLastBubbleWhileExpanded = true;
+ // We're expanded while the last bubble is being removed. Let the scrim animate away
+ // and then remove our views (removing the icon view triggers the removal of the
+ // bubble window so do that at the end of the animation so we see the scrim animate).
+ showScrim(false, () -> {
+ mRemovingLastBubbleWhileExpanded = false;
+ bubble.cleanupExpandedView();
+ mBubbleContainer.removeView(bubble.getIconView());
+ bubble.cleanupViews(); // cleans up the icon view
+ updateExpandedView(); // resets state for no expanded bubble
+ });
+ return;
+ }
// Remove it from the views
for (int i = 0; i < getBubbleCount(); i++) {
View v = mBubbleContainer.getChildAt(i);
@@ -2142,7 +2163,7 @@ public class BubbleStackView extends FrameLayout
mExpandedViewAlphaAnimator.start();
}
- private void showScrim(boolean show) {
+ private void showScrim(boolean show, Runnable after) {
AnimatorListenerAdapter listener = new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
@@ -2152,6 +2173,9 @@ public class BubbleStackView extends FrameLayout
@Override
public void onAnimationEnd(Animator animation) {
mScrimAnimating = false;
+ if (after != null) {
+ after.run();
+ }
}
};
if (show) {
@@ -2178,7 +2202,7 @@ public class BubbleStackView extends FrameLayout
}
beforeExpandedViewAnimation();
- showScrim(true);
+ showScrim(true, null /* runnable */);
updateZOrder();
updateBadges(false /* setBadgeForCollapsedStack */);
mBubbleContainer.setActiveController(mExpandedAnimationController);
@@ -2302,7 +2326,10 @@ public class BubbleStackView extends FrameLayout
mIsExpanded = false;
mIsExpansionAnimating = true;
- showScrim(false);
+ if (!mRemovingLastBubbleWhileExpanded) {
+ // When we remove the last bubble it animates the scrim.
+ showScrim(false, null /* runnable */);
+ }
mBubbleContainer.cancelAllAnimations();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
index d8e2f5c4a817..2f0f56cfdfb0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
@@ -634,14 +634,8 @@ public abstract class WMShellModule {
@WMSingleton
@Provides
- static UnfoldBackgroundController provideUnfoldBackgroundController(
- RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
- Context context
- ) {
- return new UnfoldBackgroundController(
- context,
- rootTaskDisplayAreaOrganizer
- );
+ static UnfoldBackgroundController provideUnfoldBackgroundController(Context context) {
+ return new UnfoldBackgroundController(context);
}
//
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
index 2f25511a1f4d..643245943916 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
@@ -460,7 +460,7 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
}
}
@Override
- public void onAnimationCancelled(boolean isKeyguardOccluded) {
+ public void onAnimationCancelled() {
final WindowContainerTransaction evictWct = new WindowContainerTransaction();
mStageCoordinator.prepareEvictInvisibleChildTasks(evictWct);
mSyncQueue.queue(evictWct);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
index 49e8227c98f1..4c903f500651 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
@@ -483,7 +483,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
}
}
@Override
- public void onAnimationCancelled(boolean isKeyguardOccluded) {
+ public void onAnimationCancelled() {
if (isEnteringSplit) {
mMainExecutor.execute(() -> exitSplitScreen(
mSideStage.getChildCount() == 0 ? mMainStage : mSideStage,
@@ -869,7 +869,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
onRemoteAnimationFinished(apps);
t.apply();
try {
- adapter.getRunner().onAnimationCancelled(mKeyguardShowing);
+ adapter.getRunner().onAnimationCancelled();
} catch (RemoteException e) {
Slog.e(TAG, "Error starting remote animation", e);
}
@@ -1013,11 +1013,11 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
}
@Override
- public void onAnimationCancelled(boolean isKeyguardOccluded) {
+ public void onAnimationCancelled() {
onRemoteAnimationFinishedOrCancelled(evictWct);
setDividerVisibility(true, null);
try {
- adapter.getRunner().onAnimationCancelled(isKeyguardOccluded);
+ adapter.getRunner().onAnimationCancelled();
} catch (RemoteException e) {
Slog.e(TAG, "Error starting remote animation", e);
}
@@ -1038,7 +1038,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
onRemoteAnimationFinished(apps);
t.apply();
try {
- adapter.getRunner().onAnimationCancelled(mKeyguardShowing);
+ adapter.getRunner().onAnimationCancelled();
} catch (RemoteException e) {
Slog.e(TAG, "Error starting remote animation", e);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/LegacyTransitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/LegacyTransitions.java
index 61e92f355dc2..61e11e877b90 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/LegacyTransitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/LegacyTransitions.java
@@ -107,7 +107,7 @@ public class LegacyTransitions {
}
@Override
- public void onAnimationCancelled(boolean isKeyguardOccluded) throws RemoteException {
+ public void onAnimationCancelled() throws RemoteException {
mCancelled = true;
mApps = mWallpapers = mNonApps = null;
checkApply();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldBackgroundController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldBackgroundController.java
index fe0a3fb7b9dc..96657af22e37 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldBackgroundController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldBackgroundController.java
@@ -19,14 +19,12 @@ package com.android.wm.shell.unfold;
import static android.graphics.Color.blue;
import static android.graphics.Color.green;
import static android.graphics.Color.red;
-import static android.view.Display.DEFAULT_DISPLAY;
import android.annotation.NonNull;
import android.content.Context;
import android.view.SurfaceControl;
import com.android.wm.shell.R;
-import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
/**
* Controls background color layer for the unfold animations
@@ -34,15 +32,10 @@ import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
public class UnfoldBackgroundController {
private static final int BACKGROUND_LAYER_Z_INDEX = -1;
-
- private final RootTaskDisplayAreaOrganizer mRootTaskDisplayAreaOrganizer;
private final float[] mBackgroundColor;
private SurfaceControl mBackgroundLayer;
- public UnfoldBackgroundController(
- @NonNull Context context,
- @NonNull RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer) {
- mRootTaskDisplayAreaOrganizer = rootTaskDisplayAreaOrganizer;
+ public UnfoldBackgroundController(@NonNull Context context) {
mBackgroundColor = getBackgroundColor(context);
}
@@ -57,7 +50,6 @@ public class UnfoldBackgroundController {
.setName("app-unfold-background")
.setCallsite("AppUnfoldTransitionController")
.setColorLayer();
- mRootTaskDisplayAreaOrganizer.attachToDisplayArea(DEFAULT_DISPLAY, colorLayerBuilder);
mBackgroundLayer = colorLayerBuilder.build();
transaction
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
index f9fdd831a42c..836efe0347c3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
@@ -23,6 +23,7 @@ import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
+import android.content.res.TypedArray;
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Region;
@@ -95,7 +96,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
private int mWindowingPillHeight;
private int mMoreActionsPillHeight;
private int mShadowRadius;
- private int mCornerRadius;
+ private int mMenuCornerRadius;
DesktopModeWindowDecoration(
Context context,
@@ -182,6 +183,11 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
mRelayoutParams.mShadowRadiusId = shadowRadiusID;
mRelayoutParams.mApplyStartTransactionOnDraw = applyStartTransactionOnDraw;
+ final TypedArray ta = mContext.obtainStyledAttributes(
+ new int[]{android.R.attr.dialogCornerRadius});
+ mRelayoutParams.mCornerRadius = ta.getDimensionPixelSize(0, 0);
+ ta.recycle();
+
relayout(mRelayoutParams, startT, finishT, wct, oldRootView, mResult);
// After this line, mTaskInfo is up-to-date and should be used instead of taskInfo
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
index e772fc25f8cf..ac5ff2075901 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
@@ -16,6 +16,8 @@
package com.android.wm.shell.windowdecor;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+
import android.app.ActivityManager.RunningTaskInfo;
import android.content.Context;
import android.content.res.Configuration;
@@ -256,13 +258,17 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
mTmpColor[0] = (float) Color.red(backgroundColorInt) / 255.f;
mTmpColor[1] = (float) Color.green(backgroundColorInt) / 255.f;
mTmpColor[2] = (float) Color.blue(backgroundColorInt) / 255.f;
- Point taskPosition = mTaskInfo.positionInParent;
+ final Point taskPosition = mTaskInfo.positionInParent;
startT.setWindowCrop(mTaskSurface, outResult.mWidth, outResult.mHeight)
.setShadowRadius(mTaskSurface, shadowRadius)
.setColor(mTaskSurface, mTmpColor)
.show(mTaskSurface);
finishT.setPosition(mTaskSurface, taskPosition.x, taskPosition.y)
.setWindowCrop(mTaskSurface, outResult.mWidth, outResult.mHeight);
+ if (mTaskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
+ startT.setCornerRadius(mTaskSurface, params.mCornerRadius);
+ finishT.setCornerRadius(mTaskSurface, params.mCornerRadius);
+ }
if (mCaptionWindowManager == null) {
// Put caption under a container surface because ViewRootImpl sets the destination frame
@@ -414,6 +420,8 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
int mCaptionWidthId;
int mShadowRadiusId;
+ int mCornerRadius;
+
int mCaptionX;
int mCaptionY;
@@ -425,6 +433,8 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
mCaptionWidthId = Resources.ID_NULL;
mShadowRadiusId = Resources.ID_NULL;
+ mCornerRadius = 0;
+
mCaptionX = 0;
mCaptionY = 0;
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/BaseTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/BaseTest.kt
index c5ee7b722617..86edc25b64d3 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/BaseTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/BaseTest.kt
@@ -18,7 +18,7 @@ package com.android.wm.shell.flicker
import android.app.Instrumentation
import android.platform.test.annotations.Presubmit
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerBuilderProvider
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.FlickerTest
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt
index 45024f387c25..798cc95c020f 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt
@@ -20,9 +20,9 @@ package com.android.wm.shell.flicker
import android.tools.common.Rotation
import android.tools.common.datatypes.Region
-import android.tools.common.datatypes.component.IComponentMatcher
import android.tools.common.flicker.subject.layers.LayerTraceEntrySubject
import android.tools.common.flicker.subject.layers.LayersTraceSubject
+import android.tools.common.traces.component.IComponentMatcher
import android.tools.device.flicker.legacy.FlickerTest
import android.tools.device.helpers.WindowUtils
@@ -218,11 +218,11 @@ fun FlickerTest.splitAppLayerBoundsChanges(
assertLayers {
if (landscapePosLeft) {
splitAppLayerBoundsSnapToDivider(
- component,
- landscapePosLeft,
- portraitPosTop,
- scenario.endRotation
- )
+ component,
+ landscapePosLeft,
+ portraitPosTop,
+ scenario.endRotation
+ )
} else {
splitAppLayerBoundsSnapToDivider(
component,
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonConstants.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonConstants.kt
index 983640a70c4b..3bc1e2acd015 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonConstants.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonConstants.kt
@@ -18,7 +18,7 @@
package com.android.wm.shell.flicker
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
const val SYSTEM_UI_PACKAGE_NAME = "com.android.systemui"
const val LAUNCHER_UI_PACKAGE_NAME = "com.google.android.apps.nexuslauncher"
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/BaseAppCompat.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/BaseAppCompat.kt
index d01a0ee67f25..11c5951faa1f 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/BaseAppCompat.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/BaseAppCompat.kt
@@ -20,11 +20,11 @@ import android.content.Context
import android.system.helpers.CommandsHelper
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.FlickerTest
-import com.android.wm.shell.flicker.BaseTest
-import com.android.server.wm.flicker.helpers.setRotation
-import com.android.server.wm.flicker.helpers.LetterboxAppHelper
import android.tools.device.flicker.legacy.FlickerTestFactory
import android.tools.device.flicker.legacy.IFlickerTestData
+import com.android.server.wm.flicker.helpers.LetterboxAppHelper
+import com.android.server.wm.flicker.helpers.setRotation
+import com.android.wm.shell.flicker.BaseTest
import com.android.wm.shell.flicker.appWindowIsVisibleAtEnd
import com.android.wm.shell.flicker.appWindowIsVisibleAtStart
import org.junit.Assume
@@ -104,8 +104,8 @@ abstract class BaseAppCompat(flicker: FlickerTest) : BaseTest(flicker) {
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.rotationTests] for configuring screen orientation and
- * navigation modes.
+ * See [FlickerTestFactory.rotationTests] for configuring screen orientation and navigation
+ * modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/OpenAppInSizeCompatModeTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/OpenAppInSizeCompatModeTest.kt
index c57100e44c17..f212a4e0417e 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/OpenAppInSizeCompatModeTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/OpenAppInSizeCompatModeTest.kt
@@ -17,11 +17,11 @@
package com.android.wm.shell.flicker.appcompat
import android.platform.test.annotations.Postsubmit
-import androidx.test.filters.RequiresDevice
+import android.tools.common.traces.component.ComponentNameMatcher
+import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import androidx.test.filters.RequiresDevice
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
@@ -35,13 +35,13 @@ import org.junit.runners.Parameterized
* ```
* Rotate non resizable portrait only app to opposite orientation to trigger size compat mode
* ```
+ *
* Notes:
* ```
* Some default assertions (e.g., nav bar, status bar and screen covered)
* are inherited [BaseTest]
* ```
*/
-
@RequiresDevice
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@@ -86,4 +86,4 @@ class OpenAppInSizeCompatModeTest(flicker: FlickerTest) : BaseAppCompat(flicker)
.isInvisible(ComponentNameMatcher.ROTATION)
}
}
-} \ No newline at end of file
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/RestartAppInSizeCompatModeTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/RestartAppInSizeCompatModeTest.kt
index f111a8d62d83..8e75439889b2 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/RestartAppInSizeCompatModeTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/RestartAppInSizeCompatModeTest.kt
@@ -17,11 +17,11 @@
package com.android.wm.shell.flicker.appcompat
import android.platform.test.annotations.Postsubmit
-import androidx.test.filters.RequiresDevice
+import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.helpers.WindowUtils
+import androidx.test.filters.RequiresDevice
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
@@ -36,13 +36,13 @@ import org.junit.runners.Parameterized
* Rotate app to opposite orientation to trigger size compat mode
* Press restart button and wait for letterboxed app to resize
* ```
+ *
* Notes:
* ```
* Some default assertions (e.g., nav bar, status bar and screen covered)
* are inherited [BaseTest]
* ```
*/
-
@RequiresDevice
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@@ -56,9 +56,7 @@ class RestartAppInSizeCompatModeTest(flicker: FlickerTest) : BaseAppCompat(flick
teardown { letterboxApp.exit(wmHelper) }
}
- @Postsubmit
- @Test
- fun appVisibleAtStartAndEnd() = assertLetterboxAppVisibleAtStartAndEnd()
+ @Postsubmit @Test fun appVisibleAtStartAndEnd() = assertLetterboxAppVisibleAtStartAndEnd()
@Postsubmit
@Test
@@ -83,4 +81,4 @@ class RestartAppInSizeCompatModeTest(flicker: FlickerTest) : BaseAppCompat(flick
val displayBounds = WindowUtils.getDisplayBounds(flicker.scenario.endRotation)
flicker.assertLayersEnd { visibleRegion(letterboxApp).coversAtMost(displayBounds) }
}
-} \ No newline at end of file
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/OpenActivityFromBubbleOnLocksreenTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/OpenActivityFromBubbleOnLocksreenTest.kt
index 18a3aa79f6e2..889e1771593d 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/OpenActivityFromBubbleOnLocksreenTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/OpenActivityFromBubbleOnLocksreenTest.kt
@@ -18,7 +18,7 @@ package com.android.wm.shell.flicker.bubble
import android.platform.test.annotations.FlakyTest
import android.platform.test.annotations.Postsubmit
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.FlickerTest
@@ -149,9 +149,7 @@ class OpenActivityFromBubbleOnLocksreenTest(flicker: FlickerTest) : BaseBubbleSc
@Ignore("Not applicable to this CUJ. Taskbar is not shown on lock screen")
override fun taskBarWindowIsAlwaysVisible() {}
- /**
- * Checks that the [ComponentNameMatcher.TASK_BAR] is visible at the end of the transition
- */
+ /** Checks that the [ComponentNameMatcher.TASK_BAR] is visible at the end of the transition */
@Postsubmit
@Test
fun taskBarLayerIsVisibleAtEnd() {
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipBySwipingDownTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipBySwipingDownTest.kt
index 59918fb7b6a9..e6544c9f39bc 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipBySwipingDownTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipBySwipingDownTest.kt
@@ -17,7 +17,7 @@
package com.android.wm.shell.flicker.pip
import android.platform.test.annotations.Presubmit
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.FlickerTest
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipTransition.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipTransition.kt
index 36c6f7c438c4..2417c45bf9a0 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipTransition.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipTransition.kt
@@ -18,7 +18,7 @@ package com.android.wm.shell.flicker.pip
import android.platform.test.annotations.Presubmit
import android.tools.common.Rotation
-import android.tools.common.datatypes.component.ComponentNameMatcher.Companion.LAUNCHER
+import android.tools.common.traces.component.ComponentNameMatcher.Companion.LAUNCHER
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.FlickerTest
import android.tools.device.flicker.legacy.FlickerTestFactory
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt
index db18edba9cc4..4b4613704a16 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt
@@ -21,7 +21,7 @@ import android.platform.test.annotations.FlakyTest
import android.platform.test.annotations.Postsubmit
import android.platform.test.annotations.Presubmit
import android.tools.common.Rotation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.FlickerTest
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTransition.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTransition.kt
index 51f01364ec9c..bfd57786e615 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTransition.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTransition.kt
@@ -18,7 +18,7 @@ package com.android.wm.shell.flicker.pip
import android.platform.test.annotations.Presubmit
import android.tools.common.Rotation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.FlickerTest
import android.tools.device.flicker.legacy.FlickerTestFactory
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppTransition.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppTransition.kt
index 2001f484ed96..5ac9829b6c8f 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppTransition.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppTransition.kt
@@ -18,7 +18,7 @@ package com.android.wm.shell.flicker.pip
import android.platform.test.annotations.Presubmit
import android.tools.common.Rotation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.legacy.FlickerTest
import android.tools.device.flicker.legacy.FlickerTestFactory
import com.android.server.wm.flicker.helpers.SimpleAppHelper
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt
index 6deba1b68f38..bbb1c6c2ac63 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt
@@ -18,7 +18,7 @@ package com.android.wm.shell.flicker.pip
import android.platform.test.annotations.Presubmit
import android.tools.common.Rotation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.FlickerTest
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipOnImeVisibilityChangeTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipOnImeVisibilityChangeTest.kt
index a626713aaa11..6b061bbb1565 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipOnImeVisibilityChangeTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipOnImeVisibilityChangeTest.kt
@@ -18,7 +18,7 @@ package com.android.wm.shell.flicker.pip
import android.platform.test.annotations.Presubmit
import android.tools.common.Rotation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.FlickerTest
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTransition.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTransition.kt
index b30f30830156..eb1245b9ab86 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTransition.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTransition.kt
@@ -20,7 +20,7 @@ import android.app.Instrumentation
import android.content.Intent
import android.platform.test.annotations.Presubmit
import android.tools.common.Rotation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.FlickerTest
import android.tools.device.flicker.rules.RemoveAllTasksButHomeRule.Companion.removeAllTasksButHome
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/CopyContentInSplit.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/CopyContentInSplit.kt
index 0c9c16153ea3..d53eac073e6b 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/CopyContentInSplit.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/CopyContentInSplit.kt
@@ -19,8 +19,8 @@ package com.android.wm.shell.flicker.splitscreen
import android.platform.test.annotations.FlakyTest
import android.platform.test.annotations.IwTest
import android.platform.test.annotations.Presubmit
-import android.tools.common.datatypes.component.ComponentNameMatcher
-import android.tools.common.datatypes.component.EdgeExtensionComponentMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
+import android.tools.common.traces.component.EdgeExtensionComponentMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.FlickerTest
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenUtils.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenUtils.kt
index 625987a2e7ef..1063dfd8d737 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenUtils.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenUtils.kt
@@ -19,9 +19,9 @@ package com.android.wm.shell.flicker.splitscreen
import android.app.Instrumentation
import android.graphics.Point
import android.os.SystemClock
-import android.tools.common.datatypes.component.ComponentNameMatcher
-import android.tools.common.datatypes.component.IComponentMatcher
-import android.tools.common.datatypes.component.IComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
+import android.tools.common.traces.component.IComponentMatcher
+import android.tools.common.traces.component.IComponentNameMatcher
import android.tools.device.apphelpers.StandardAppHelper
import android.tools.device.traces.parsers.WindowManagerStateHelper
import android.tools.device.traces.parsers.toFlickerComponent
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java
index fc4bfd9754a0..5a2326b9c393 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java
@@ -16,6 +16,8 @@
package com.android.wm.shell.windowdecor;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+
import static com.android.wm.shell.MockSurfaceControlHelper.createMockSurfaceControlBuilder;
import static com.android.wm.shell.MockSurfaceControlHelper.createMockSurfaceControlTransaction;
@@ -86,6 +88,7 @@ import java.util.function.Supplier;
public class WindowDecorationTests extends ShellTestCase {
private static final Rect TASK_BOUNDS = new Rect(100, 300, 400, 400);
private static final Point TASK_POSITION_IN_PARENT = new Point(40, 60);
+ private static final int CORNER_RADIUS = 20;
private final WindowDecoration.RelayoutResult<TestView> mRelayoutResult =
new WindowDecoration.RelayoutResult<>();
@@ -130,6 +133,7 @@ public class WindowDecorationTests extends ShellTestCase {
mCaptionMenuShadowRadiusId = R.dimen.test_caption_menu_shadow_radius;
mCaptionMenuCornerRadiusId = R.dimen.test_caption_menu_corner_radius;
mRelayoutParams.mShadowRadiusId = R.dimen.test_window_decor_shadow_radius;
+ mRelayoutParams.mCornerRadius = CORNER_RADIUS;
doReturn(mMockSurfaceControlViewHost).when(mMockSurfaceControlViewHostFactory)
.create(any(), any(), any());
@@ -209,6 +213,7 @@ public class WindowDecorationTests extends ShellTestCase {
.setBounds(TASK_BOUNDS)
.setPositionInParent(TASK_POSITION_IN_PARENT.x, TASK_POSITION_IN_PARENT.y)
.setVisible(true)
+ .setWindowingMode(WINDOWING_MODE_FREEFORM)
.build();
taskInfo.isFocused = true;
// Density is 2. Shadow radius is 10px. Caption height is 64px.
@@ -249,6 +254,8 @@ public class WindowDecorationTests extends ShellTestCase {
.setPosition(taskSurface, TASK_POSITION_IN_PARENT.x, TASK_POSITION_IN_PARENT.y);
verify(mMockSurfaceControlFinishT)
.setWindowCrop(taskSurface, 300, 100);
+ verify(mMockSurfaceControlStartT).setCornerRadius(taskSurface, CORNER_RADIUS);
+ verify(mMockSurfaceControlFinishT).setCornerRadius(taskSurface, CORNER_RADIUS);
verify(mMockSurfaceControlStartT)
.show(taskSurface);
verify(mMockSurfaceControlStartT)
diff --git a/media/java/android/media/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java
index 193544edbf99..88b9643c12c1 100644
--- a/media/java/android/media/MediaCodecInfo.java
+++ b/media/java/android/media/MediaCodecInfo.java
@@ -934,13 +934,25 @@ public final class MediaCodecInfo {
}
}
levelCaps = createFromProfileLevel(mMime, profile, maxLevel);
- // remove profile from this format otherwise levelCaps.isFormatSupported will
- // get into this same conditon and loop forever.
- Map<String, Object> mapWithoutProfile = new HashMap<>(map);
- mapWithoutProfile.remove(MediaFormat.KEY_PROFILE);
- MediaFormat formatWithoutProfile = new MediaFormat(mapWithoutProfile);
- if (levelCaps != null && !levelCaps.isFormatSupported(formatWithoutProfile)) {
- return false;
+ // We must remove the profile from this format otherwise levelCaps.isFormatSupported
+ // will get into this same condition and loop forever. Furthermore, since levelCaps
+ // does not contain features and bitrate specific keys, keep only keys relevant for
+ // a level check.
+ Map<String, Object> levelCriticalFormatMap = new HashMap<>(map);
+ final Set<String> criticalKeys =
+ isVideo() ? VideoCapabilities.VIDEO_LEVEL_CRITICAL_FORMAT_KEYS :
+ isAudio() ? AudioCapabilities.AUDIO_LEVEL_CRITICAL_FORMAT_KEYS :
+ null;
+
+ // critical keys will always contain KEY_MIME, but should also contain others to be
+ // meaningful
+ if (criticalKeys != null && criticalKeys.size() > 1 && levelCaps != null) {
+ levelCriticalFormatMap.keySet().retainAll(criticalKeys);
+
+ MediaFormat levelCriticalFormat = new MediaFormat(levelCriticalFormatMap);
+ if (!levelCaps.isFormatSupported(levelCriticalFormat)) {
+ return false;
+ }
}
}
if (mAudioCaps != null && !mAudioCaps.supportsFormat(format)) {
@@ -1633,6 +1645,16 @@ public final class MediaCodecInfo {
}
}
+ /* package private */
+ // must not contain KEY_PROFILE
+ static final Set<String> AUDIO_LEVEL_CRITICAL_FORMAT_KEYS = Set.of(
+ // We don't set level-specific limits for audio codecs today. Key candidates would
+ // be sample rate, bit rate or channel count.
+ // MediaFormat.KEY_SAMPLE_RATE,
+ // MediaFormat.KEY_CHANNEL_COUNT,
+ // MediaFormat.KEY_BIT_RATE,
+ MediaFormat.KEY_MIME);
+
/** @hide */
public boolean supportsFormat(MediaFormat format) {
Map<String, Object> map = format.getMap();
@@ -2357,6 +2379,15 @@ public final class MediaCodecInfo {
return ok;
}
+ /* package private */
+ // must not contain KEY_PROFILE
+ static final Set<String> VIDEO_LEVEL_CRITICAL_FORMAT_KEYS = Set.of(
+ MediaFormat.KEY_WIDTH,
+ MediaFormat.KEY_HEIGHT,
+ MediaFormat.KEY_FRAME_RATE,
+ MediaFormat.KEY_BIT_RATE,
+ MediaFormat.KEY_MIME);
+
/**
* @hide
* @throws java.lang.ClassCastException */
diff --git a/packages/CredentialManager/res/values/strings.xml b/packages/CredentialManager/res/values/strings.xml
index 905e0ca92733..a3b27529d857 100644
--- a/packages/CredentialManager/res/values/strings.xml
+++ b/packages/CredentialManager/res/values/strings.xml
@@ -114,13 +114,13 @@
<!-- Strings for the get flow. -->
<!-- This appears as the title of the modal bottom sheet asking for user confirmation to use the single previously saved passkey to sign in to the app. [CHAR LIMIT=200] -->
<string name="get_dialog_title_use_passkey_for">Use your saved passkey for <xliff:g id="app_name" example="YouTube">%1$s</xliff:g>?</string>
- <!-- This appears as the title of the dialog asking for user confirmation to use the single previously saved credential to sign in to the app. [CHAR LIMIT=200] -->
- <string name="get_dialog_title_use_sign_in_for">Use your saved sign-in for <xliff:g id="app_name" example="YouTube">%1$s</xliff:g>?</string>
- <!-- This appears as the title of the dialog asking for user to make a choice from various previously saved credentials to sign in to the app. [CHAR LIMIT=200] -->
- <string name="get_dialog_title_choose_sign_in_for">Choose a saved sign-in for <xliff:g id="app_name" example="YouTube">%1$s</xliff:g></string>
- <!-- This appears as the title of the dialog asking for user to make a choice from various previously saved credentials to sign in to the app. [CHAR LIMIT=200] -->
+ <!-- This appears as the title of the dialog asking for user confirmation to use the single user credential (previously saved or to be created) to sign in to the app. [CHAR LIMIT=200] -->
+ <string name="get_dialog_title_use_sign_in_for">Use your sign-in for <xliff:g id="app_name" example="YouTube">%1$s</xliff:g>?</string>
+ <!-- This appears as the title of the dialog asking for user to make a choice from various available user credentials (previously saved or to be created) to sign in to the app. [CHAR LIMIT=200] -->
+ <string name="get_dialog_title_choose_sign_in_for">Choose a sign-in for <xliff:g id="app_name" example="YouTube">%1$s</xliff:g></string>
+ <!-- This appears as the title of the dialog asking for user to make a choice from options of available user information (e.g. driver's license, vaccination status) to pass to the app. [CHAR LIMIT=200] -->
<string name="get_dialog_title_choose_option_for">Choose an option for <xliff:g id="app_name" example="YouTube">%1$s</xliff:g>?</string>
- <!-- This appears as the title of the dialog asking user to use a previously saved credentials to sign in to the app. [CHAR LIMIT=200] -->
+ <!-- This appears as the title of the dialog asking user to send a piece of user information (e.g. driver's license, vaccination status) to the app. [CHAR LIMIT=200] -->
<string name="get_dialog_title_use_info_on">Use this info on <xliff:g id="app_name" example="YouTube">%1$s</xliff:g>?</string>
<!-- This is a label for a button that links the user to different sign-in methods . [CHAR LIMIT=80] -->
<string name="get_dialog_use_saved_passkey_for">Sign in another way</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java
index 45c0d7823e99..adaf4a1d3ab5 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java
@@ -14,7 +14,9 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL;
import static android.net.NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY;
import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
+import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
+import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
@@ -26,6 +28,8 @@ import android.net.NetworkKey;
import android.net.NetworkRequest;
import android.net.NetworkScoreManager;
import android.net.ScoredNetwork;
+import android.net.TransportInfo;
+import android.net.vcn.VcnTransportInfo;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiNetworkScoreCache;
@@ -34,8 +38,9 @@ import android.os.HandlerThread;
import android.os.Looper;
import android.provider.Settings;
+import androidx.annotation.Nullable;
+
import com.android.settingslib.R;
-import com.android.settingslib.Utils;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
@@ -46,6 +51,7 @@ import java.util.Set;
/**
* Track status of Wi-Fi for the Sys UI.
*/
+@SuppressLint("MissingPermission")
public class WifiStatusTracker {
private static final int HISTORY_SIZE = 32;
private static final SimpleDateFormat SSDF = new SimpleDateFormat("MM-dd HH:mm:ss.SSS");
@@ -66,8 +72,9 @@ public class WifiStatusTracker {
private final NetworkRequest mNetworkRequest = new NetworkRequest.Builder()
.clearCapabilities()
.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
- .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
- .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR).build();
+ .addTransportType(TRANSPORT_WIFI)
+ .addTransportType(TRANSPORT_CELLULAR)
+ .build();
private final NetworkCallback mNetworkCallback =
new NetworkCallback(NetworkCallback.FLAG_INCLUDE_LOCATION_INFO) {
// Note: onCapabilitiesChanged is guaranteed to be called "immediately" after onAvailable
@@ -75,18 +82,10 @@ public class WifiStatusTracker {
@Override
public void onCapabilitiesChanged(
Network network, NetworkCapabilities networkCapabilities) {
- boolean isVcnOverWifi = false;
- boolean isWifi = false;
- WifiInfo wifiInfo = null;
- if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
- wifiInfo = Utils.tryGetWifiInfoForVcn(networkCapabilities);
- isVcnOverWifi = (wifiInfo != null);
- } else if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
- wifiInfo = (WifiInfo) networkCapabilities.getTransportInfo();
- isWifi = true;
- }
+ WifiInfo wifiInfo = getMainOrUnderlyingWifiInfo(networkCapabilities);
+ boolean isWifi = connectionIsWifi(networkCapabilities, wifiInfo);
// As long as it is a WiFi network, we will log it in the dumpsys for debugging.
- if (isVcnOverWifi || isWifi) {
+ if (isWifi) {
String log = new StringBuilder()
.append(SSDF.format(System.currentTimeMillis())).append(",")
.append("onCapabilitiesChanged: ")
@@ -303,17 +302,8 @@ public class WifiStatusTracker {
return;
}
NetworkCapabilities networkCapabilities;
- isDefaultNetwork = false;
- if (mDefaultNetworkCapabilities != null) {
- boolean isWifi = mDefaultNetworkCapabilities.hasTransport(
- NetworkCapabilities.TRANSPORT_WIFI);
- boolean isVcnOverWifi = mDefaultNetworkCapabilities.hasTransport(
- NetworkCapabilities.TRANSPORT_CELLULAR)
- && (Utils.tryGetWifiInfoForVcn(mDefaultNetworkCapabilities) != null);
- if (isWifi || isVcnOverWifi) {
- isDefaultNetwork = true;
- }
- }
+ isDefaultNetwork = mDefaultNetworkCapabilities != null
+ && connectionIsWifi(mDefaultNetworkCapabilities);
if (isDefaultNetwork) {
// Wifi is connected and the default network.
networkCapabilities = mDefaultNetworkCapabilities;
@@ -352,6 +342,70 @@ public class WifiStatusTracker {
? null : AccessPoint.getSpeedLabel(mContext, scoredNetwork, rssi);
}
+ @Nullable
+ private WifiInfo getMainOrUnderlyingWifiInfo(NetworkCapabilities networkCapabilities) {
+ WifiInfo mainWifiInfo = getMainWifiInfo(networkCapabilities);
+ if (mainWifiInfo != null) {
+ return mainWifiInfo;
+ }
+
+ // Only CELLULAR networks may have underlying wifi information that's relevant to SysUI,
+ // so skip the underlying network check if it's not CELLULAR.
+ if (!networkCapabilities.hasTransport(TRANSPORT_CELLULAR)) {
+ return mainWifiInfo;
+ }
+
+ List<Network> underlyingNetworks = networkCapabilities.getUnderlyingNetworks();
+ if (underlyingNetworks == null) {
+ return null;
+ }
+
+ // Some connections, like VPN connections, may have underlying networks that are
+ // eventually traced to a wifi or carrier merged connection. So, check those underlying
+ // networks for possible wifi information as well. See b/225902574.
+ for (Network underlyingNetwork : underlyingNetworks) {
+ NetworkCapabilities underlyingNetworkCapabilities =
+ mConnectivityManager.getNetworkCapabilities(underlyingNetwork);
+ WifiInfo underlyingWifiInfo = getMainWifiInfo(underlyingNetworkCapabilities);
+ if (underlyingWifiInfo != null) {
+ return underlyingWifiInfo;
+ }
+ }
+
+ return null;
+ }
+
+ @Nullable
+ private WifiInfo getMainWifiInfo(NetworkCapabilities networkCapabilities) {
+ boolean canHaveWifiInfo = networkCapabilities.hasTransport(TRANSPORT_WIFI)
+ || networkCapabilities.hasTransport(TRANSPORT_CELLULAR);
+ if (!canHaveWifiInfo) {
+ return null;
+ }
+
+ TransportInfo transportInfo = networkCapabilities.getTransportInfo();
+ if (transportInfo instanceof VcnTransportInfo) {
+ // This VcnTransportInfo logic is copied from
+ // [com.android.settingslib.Utils.tryGetWifiInfoForVcn]. It's copied instead of
+ // re-used because it makes the logic here clearer.
+ return ((VcnTransportInfo) transportInfo).getWifiInfo();
+ } else if (transportInfo instanceof WifiInfo) {
+ return (WifiInfo) transportInfo;
+ } else {
+ return null;
+ }
+ }
+
+ private boolean connectionIsWifi(NetworkCapabilities networkCapabilities) {
+ return connectionIsWifi(
+ networkCapabilities,
+ getMainOrUnderlyingWifiInfo(networkCapabilities));
+ }
+
+ private boolean connectionIsWifi(NetworkCapabilities networkCapabilities, WifiInfo wifiInfo) {
+ return wifiInfo != null || networkCapabilities.hasTransport(TRANSPORT_WIFI);
+ }
+
/** Refresh the status label on Locale changed. */
public void refreshLocale() {
updateStatusLabel();
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiStatusTrackerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiStatusTrackerTest.java
index dc7e313dfcfa..6e975cf9d8f3 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiStatusTrackerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiStatusTrackerTest.java
@@ -40,6 +40,8 @@ import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
+import java.util.Arrays;
+
@RunWith(RobolectricTestRunner.class)
public class WifiStatusTrackerTest {
@Mock Context mContext;
@@ -48,13 +50,32 @@ public class WifiStatusTrackerTest {
@Mock ConnectivityManager mConnectivityManager;
@Mock Runnable mCallback;
+ private WifiStatusTracker mWifiStatusTracker;
+
private final ArgumentCaptor<ConnectivityManager.NetworkCallback>
mNetworkCallbackCaptor =
ArgumentCaptor.forClass(ConnectivityManager.NetworkCallback.class);
+ private final ArgumentCaptor<ConnectivityManager.NetworkCallback>
+ mDefaultNetworkCallbackCaptor =
+ ArgumentCaptor.forClass(ConnectivityManager.NetworkCallback.class);
+
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
+
+ mWifiStatusTracker = new WifiStatusTracker(
+ mContext,
+ mWifiManager,
+ mNetworkScoreManager,
+ mConnectivityManager,
+ mCallback);
+ mWifiStatusTracker.setListening(true);
+
+ verify(mConnectivityManager)
+ .registerNetworkCallback(any(), mNetworkCallbackCaptor.capture(), any());
+ verify(mConnectivityManager)
+ .registerDefaultNetworkCallback(mDefaultNetworkCallbackCaptor.capture(), any());
}
/**
@@ -62,13 +83,6 @@ public class WifiStatusTrackerTest {
*/
@Test
public void testWifiInfoClearedOnPrimaryNetworkLost() {
- WifiStatusTracker wifiStatusTracker = new WifiStatusTracker(mContext, mWifiManager,
- mNetworkScoreManager, mConnectivityManager, mCallback);
- wifiStatusTracker.setListening(true);
-
- verify(mConnectivityManager)
- .registerNetworkCallback(any(), mNetworkCallbackCaptor.capture(), any());
-
// Trigger a validation callback for the primary Wifi network.
WifiInfo primaryWifiInfo = Mockito.mock(WifiInfo.class);
when(primaryWifiInfo.makeCopy(anyLong())).thenReturn(primaryWifiInfo);
@@ -86,8 +100,8 @@ public class WifiStatusTrackerTest {
mNetworkCallbackCaptor.getValue().onCapabilitiesChanged(primaryNetwork, primaryCap);
// Verify primary wifi info is the one being used.
- assertThat(wifiStatusTracker.connected).isTrue();
- assertThat(wifiStatusTracker.rssi).isEqualTo(primaryRssi);
+ assertThat(mWifiStatusTracker.connected).isTrue();
+ assertThat(mWifiStatusTracker.rssi).isEqualTo(primaryRssi);
// Trigger a validation callback for the non-primary Wifi network.
WifiInfo nonPrimaryWifiInfo = Mockito.mock(WifiInfo.class);
@@ -106,20 +120,189 @@ public class WifiStatusTrackerTest {
mNetworkCallbackCaptor.getValue().onCapabilitiesChanged(nonPrimaryNetwork, nonPrimaryCap);
// Verify primary wifi info is still the one being used.
- assertThat(wifiStatusTracker.connected).isTrue();
- assertThat(wifiStatusTracker.rssi).isEqualTo(primaryRssi);
+ assertThat(mWifiStatusTracker.connected).isTrue();
+ assertThat(mWifiStatusTracker.rssi).isEqualTo(primaryRssi);
// Lose the non-primary network.
mNetworkCallbackCaptor.getValue().onLost(nonPrimaryNetwork);
// Verify primary wifi info is still the one being used.
- assertThat(wifiStatusTracker.connected).isTrue();
- assertThat(wifiStatusTracker.rssi).isEqualTo(primaryRssi);
+ assertThat(mWifiStatusTracker.connected).isTrue();
+ assertThat(mWifiStatusTracker.rssi).isEqualTo(primaryRssi);
// Lose the primary network.
mNetworkCallbackCaptor.getValue().onLost(primaryNetwork);
// Verify we aren't connected anymore.
- assertThat(wifiStatusTracker.connected).isFalse();
+ assertThat(mWifiStatusTracker.connected).isFalse();
+ }
+
+ @Test
+ public void isCarrierMerged_typicalWifi_false() {
+ WifiInfo primaryWifiInfo = Mockito.mock(WifiInfo.class);
+ when(primaryWifiInfo.isPrimary()).thenReturn(true);
+
+ NetworkCapabilities primaryCap = Mockito.mock(NetworkCapabilities.class);
+ when(primaryCap.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)).thenReturn(true);
+ when(primaryCap.getTransportInfo()).thenReturn(primaryWifiInfo);
+
+ Network primaryNetwork = Mockito.mock(Network.class);
+ int primaryNetworkId = 1;
+ when(primaryNetwork.getNetId()).thenReturn(primaryNetworkId);
+
+ mNetworkCallbackCaptor.getValue().onCapabilitiesChanged(primaryNetwork, primaryCap);
+
+ assertThat(mWifiStatusTracker.isCarrierMerged).isFalse();
+ }
+
+ @Test
+ public void isCarrierMerged_typicalCellular_false() {
+ NetworkCapabilities primaryCap = Mockito.mock(NetworkCapabilities.class);
+ when(primaryCap.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)).thenReturn(true);
+
+ Network primaryNetwork = Mockito.mock(Network.class);
+ int primaryNetworkId = 1;
+ when(primaryNetwork.getNetId()).thenReturn(primaryNetworkId);
+
+ mNetworkCallbackCaptor.getValue().onCapabilitiesChanged(primaryNetwork, primaryCap);
+
+ assertThat(mWifiStatusTracker.isCarrierMerged).isFalse();
+ }
+
+ @Test
+ public void isCarrierMerged_cellularCarrierMergedWifi_true() {
+ WifiInfo primaryWifiInfo = Mockito.mock(WifiInfo.class);
+ when(primaryWifiInfo.isPrimary()).thenReturn(true);
+ when(primaryWifiInfo.isCarrierMerged()).thenReturn(true);
+
+ NetworkCapabilities primaryCap = Mockito.mock(NetworkCapabilities.class);
+ when(primaryCap.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)).thenReturn(true);
+ when(primaryCap.getTransportInfo()).thenReturn(primaryWifiInfo);
+
+ Network primaryNetwork = Mockito.mock(Network.class);
+ int primaryNetworkId = 1;
+ when(primaryNetwork.getNetId()).thenReturn(primaryNetworkId);
+
+ mNetworkCallbackCaptor.getValue().onCapabilitiesChanged(primaryNetwork, primaryCap);
+
+ assertThat(mWifiStatusTracker.isCarrierMerged).isTrue();
+ }
+
+ /** Test for b/225902574. */
+ @Test
+ public void isCarrierMerged_cellularWithUnderlyingCarrierMergedWifi_true() {
+ WifiInfo underlyingCarrierMergedInfo = Mockito.mock(WifiInfo.class);
+ when(underlyingCarrierMergedInfo.isPrimary()).thenReturn(true);
+ when(underlyingCarrierMergedInfo.isCarrierMerged()).thenReturn(true);
+
+ NetworkCapabilities underlyingNetworkCapabilities = Mockito.mock(NetworkCapabilities.class);
+ when(underlyingNetworkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR))
+ .thenReturn(true);
+ when(underlyingNetworkCapabilities.getTransportInfo())
+ .thenReturn(underlyingCarrierMergedInfo);
+
+ Network underlyingNetwork = Mockito.mock(Network.class);
+ when(mConnectivityManager.getNetworkCapabilities(underlyingNetwork))
+ .thenReturn(underlyingNetworkCapabilities);
+
+ NetworkCapabilities mainCapabilities = Mockito.mock(NetworkCapabilities.class);
+ when(mainCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR))
+ .thenReturn(true);
+ when(mainCapabilities.getTransportInfo()).thenReturn(null);
+ when(mainCapabilities.getUnderlyingNetworks())
+ .thenReturn(Arrays.asList(underlyingNetwork));
+
+ Network primaryNetwork = Mockito.mock(Network.class);
+ int primaryNetworkId = 1;
+ when(primaryNetwork.getNetId()).thenReturn(primaryNetworkId);
+
+ mNetworkCallbackCaptor.getValue().onCapabilitiesChanged(primaryNetwork, mainCapabilities);
+
+ assertThat(mWifiStatusTracker.isCarrierMerged).isTrue();
+ }
+
+ @Test
+ public void isDefaultNetwork_typicalWifi_true() {
+ WifiInfo primaryWifiInfo = Mockito.mock(WifiInfo.class);
+ when(primaryWifiInfo.isPrimary()).thenReturn(true);
+
+ NetworkCapabilities primaryCap = Mockito.mock(NetworkCapabilities.class);
+ when(primaryCap.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)).thenReturn(true);
+ when(primaryCap.getTransportInfo()).thenReturn(primaryWifiInfo);
+
+ Network primaryNetwork = Mockito.mock(Network.class);
+ int primaryNetworkId = 1;
+ when(primaryNetwork.getNetId()).thenReturn(primaryNetworkId);
+
+ mDefaultNetworkCallbackCaptor.getValue().onCapabilitiesChanged(primaryNetwork, primaryCap);
+
+ assertThat(mWifiStatusTracker.isDefaultNetwork).isTrue();
+ }
+
+ @Test
+ public void isDefaultNetwork_typicalCellular_false() {
+ NetworkCapabilities primaryCap = Mockito.mock(NetworkCapabilities.class);
+ when(primaryCap.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)).thenReturn(true);
+
+ Network primaryNetwork = Mockito.mock(Network.class);
+ int primaryNetworkId = 1;
+ when(primaryNetwork.getNetId()).thenReturn(primaryNetworkId);
+
+ mDefaultNetworkCallbackCaptor.getValue().onCapabilitiesChanged(primaryNetwork, primaryCap);
+
+ assertThat(mWifiStatusTracker.isDefaultNetwork).isFalse();
+ }
+
+ @Test
+ public void isDefaultNetwork_cellularCarrierMergedWifi_true() {
+ WifiInfo primaryWifiInfo = Mockito.mock(WifiInfo.class);
+ when(primaryWifiInfo.isPrimary()).thenReturn(true);
+ when(primaryWifiInfo.isCarrierMerged()).thenReturn(true);
+
+ NetworkCapabilities primaryCap = Mockito.mock(NetworkCapabilities.class);
+ when(primaryCap.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)).thenReturn(true);
+ when(primaryCap.getTransportInfo()).thenReturn(primaryWifiInfo);
+
+ Network primaryNetwork = Mockito.mock(Network.class);
+ int primaryNetworkId = 1;
+ when(primaryNetwork.getNetId()).thenReturn(primaryNetworkId);
+
+ mDefaultNetworkCallbackCaptor.getValue().onCapabilitiesChanged(primaryNetwork, primaryCap);
+
+ assertThat(mWifiStatusTracker.isDefaultNetwork).isTrue();
+ }
+
+ /** Test for b/225902574. */
+ @Test
+ public void isDefaultNetwork_cellularWithUnderlyingCarrierMergedWifi_true() {
+ WifiInfo underlyingCarrierMergedInfo = Mockito.mock(WifiInfo.class);
+ when(underlyingCarrierMergedInfo.isPrimary()).thenReturn(true);
+ when(underlyingCarrierMergedInfo.isCarrierMerged()).thenReturn(true);
+
+ NetworkCapabilities underlyingNetworkCapabilities = Mockito.mock(NetworkCapabilities.class);
+ when(underlyingNetworkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR))
+ .thenReturn(true);
+ when(underlyingNetworkCapabilities.getTransportInfo())
+ .thenReturn(underlyingCarrierMergedInfo);
+
+ Network underlyingNetwork = Mockito.mock(Network.class);
+ when(mConnectivityManager.getNetworkCapabilities(underlyingNetwork))
+ .thenReturn(underlyingNetworkCapabilities);
+
+ NetworkCapabilities mainCapabilities = Mockito.mock(NetworkCapabilities.class);
+ when(mainCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR))
+ .thenReturn(true);
+ when(mainCapabilities.getTransportInfo()).thenReturn(null);
+ when(mainCapabilities.getUnderlyingNetworks())
+ .thenReturn(Arrays.asList(underlyingNetwork));
+
+ Network primaryNetwork = Mockito.mock(Network.class);
+ int primaryNetworkId = 1;
+ when(primaryNetwork.getNetId()).thenReturn(primaryNetworkId);
+
+ mDefaultNetworkCallbackCaptor.getValue()
+ .onCapabilitiesChanged(primaryNetwork, mainCapabilities);
+
+ assertThat(mWifiStatusTracker.isDefaultNetwork).isTrue();
}
}
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index b95a149eb0cc..a5908a888449 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -252,9 +252,11 @@ filegroup {
// domain
"tests/src/com/android/systemui/keyguard/domain/interactor/AlternateBouncerInteractorTest.kt",
"tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt",
+ "tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorTest.kt",
"tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt",
"tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt",
"tests/src/com/android/systemui/keyguard/domain/interactor/LightRevealScrimInteractorTest.kt",
+ "tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerCallbackInteractorTest.kt",
"tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorWithCoroutinesTest.kt",
// ui
"tests/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelTest.kt",
@@ -263,6 +265,7 @@ filegroup {
"tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModelTest.kt",
"tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelTest.kt",
"tests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelTest.kt",
+ "tests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelTest.kt",
// Keyguard helper
"tests/src/com/android/systemui/keyguard/data/quickaffordance/FakeKeyguardQuickAffordanceConfig.kt",
"tests/src/com/android/systemui/dump/LogBufferHelper.kt",
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
index 296c2ae5cf99..94b37403b232 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
@@ -436,8 +436,8 @@ class ActivityLaunchAnimator(
}
@BinderThread
- override fun onAnimationCancelled(isKeyguardOccluded: Boolean) {
- context.mainExecutor.execute { delegate.onAnimationCancelled(isKeyguardOccluded) }
+ override fun onAnimationCancelled() {
+ context.mainExecutor.execute { delegate.onAnimationCancelled() }
}
}
@@ -744,7 +744,7 @@ class ActivityLaunchAnimator(
}
@UiThread
- override fun onAnimationCancelled(isKeyguardOccluded: Boolean) {
+ override fun onAnimationCancelled() {
if (timedOut) {
return
}
@@ -754,7 +754,7 @@ class ActivityLaunchAnimator(
removeTimeout()
animation?.cancel()
- controller.onLaunchAnimationCancelled(newKeyguardOccludedState = isKeyguardOccluded)
+ controller.onLaunchAnimationCancelled()
}
private fun IRemoteAnimationFinishedCallback.invoke() {
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/RemoteAnimationDelegate.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/RemoteAnimationDelegate.kt
index 337408bb9c5d..d465962d6edf 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/RemoteAnimationDelegate.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/RemoteAnimationDelegate.kt
@@ -26,5 +26,5 @@ interface RemoteAnimationDelegate<in T : IRemoteAnimationFinishedCallback> {
)
/** Called on the UI thread when a signal is received to cancel the animation. */
- @UiThread fun onAnimationCancelled(isKeyguardOccluded: Boolean)
+ @UiThread fun onAnimationCancelled()
}
diff --git a/packages/SystemUI/res-keyguard/color/numpad_key_color_secondary.xml b/packages/SystemUI/res-keyguard/color/numpad_key_color_secondary.xml
index 08c66a24348c..47641ee64ee1 100644
--- a/packages/SystemUI/res-keyguard/color/numpad_key_color_secondary.xml
+++ b/packages/SystemUI/res-keyguard/color/numpad_key_color_secondary.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
- <item android:color="?androidprv:attr/colorAccentSecondaryVariant"/>
+ <item android:color="?androidprv:attr/materialColorSecondaryFixedDim"/>
</selector> \ No newline at end of file
diff --git a/packages/SystemUI/res-keyguard/drawable/kg_emergency_button_background.xml b/packages/SystemUI/res-keyguard/drawable/kg_emergency_button_background.xml
index 07642736869c..5e7cf3ee41fb 100644
--- a/packages/SystemUI/res-keyguard/drawable/kg_emergency_button_background.xml
+++ b/packages/SystemUI/res-keyguard/drawable/kg_emergency_button_background.xml
@@ -19,7 +19,7 @@
android:color="?attr/wallpaperTextColorSecondary">
<item android:id="@android:id/background">
<shape android:shape="rectangle">
- <solid android:color="?androidprv:attr/colorAccentTertiary"/>
+ <solid android:color="?androidprv:attr/materialColorTertiaryFixed"/>
<corners android:radius="24dp"/>
</shape>
</item>
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_esim_area.xml b/packages/SystemUI/res-keyguard/layout/keyguard_esim_area.xml
index 67fd5b9a78bd..83736e9d9473 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_esim_area.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_esim_area.xml
@@ -19,6 +19,7 @@
<!-- This contains disable eSim buttons shared by sim_pin/sim_puk screens -->
<com.android.keyguard.KeyguardEsimArea xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:id="@+id/keyguard_disable_esim"
style="@style/Keyguard.TextView"
android:layout_width="wrap_content"
@@ -26,8 +27,8 @@
android:background="@drawable/kg_bouncer_secondary_button"
android:drawablePadding="10dp"
android:drawableStart="@drawable/ic_no_sim"
- android:drawableTint="?android:attr/textColorPrimary"
+ android:drawableTint="?androidprv:attr/materialColorOnSurface"
android:text="@string/disable_carrier_button_text"
- android:textColor="?android:attr/textColorPrimary"
+ android:textColor="?androidprv:attr/materialColorOnSurface"
android:textSize="@dimen/kg_status_line_font_size"
android:visibility="gone" />
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_security_container_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_security_container_view.xml
index 426cfafb190e..751b07ae9a6e 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_security_container_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_security_container_view.xml
@@ -19,13 +19,14 @@
<com.android.keyguard.KeyguardSecurityContainer
xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:androidprv="http://schemas.android.com/apk/res-auto"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:id="@+id/keyguard_security_container"
+ android:background="?androidprv:attr/materialColorSurfaceContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
android:clipToPadding="false"
- android:paddingTop="@dimen/keyguard_lock_padding"
+ android:paddingTop="@dimen/status_bar_height"
android:importantForAccessibility="yes"> <!-- Needed because TYPE_WINDOW_STATE_CHANGED is sent
from this view when bouncer is shown -->
<com.android.keyguard.KeyguardSecurityViewFlipper
diff --git a/packages/SystemUI/res-keyguard/values/styles.xml b/packages/SystemUI/res-keyguard/values/styles.xml
index 04dffb6e8c52..4fc411eaea9d 100644
--- a/packages/SystemUI/res-keyguard/values/styles.xml
+++ b/packages/SystemUI/res-keyguard/values/styles.xml
@@ -24,7 +24,7 @@
<item name="android:textSize">@dimen/kg_status_line_font_size</item>
</style>
<style name="Keyguard.TextView.EmergencyButton" parent="Theme.SystemUI">
- <item name="android:textColor">?androidprv:attr/textColorOnAccent</item>
+ <item name="android:textColor">?androidprv:attr/materialColorOnTertiaryFixed</item>
<item name="android:textSize">16sp</item>
<item name="android:background">@drawable/kg_emergency_button_background</item>
<item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
diff --git a/packages/SystemUI/res/layout/super_notification_shade.xml b/packages/SystemUI/res/layout/super_notification_shade.xml
index fe9542b7aed6..d9fe949bb327 100644
--- a/packages/SystemUI/res/layout/super_notification_shade.xml
+++ b/packages/SystemUI/res/layout/super_notification_shade.xml
@@ -101,7 +101,6 @@
</LinearLayout>
<FrameLayout android:id="@+id/keyguard_bouncer_container"
- android:paddingTop="@dimen/status_bar_height"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:layout_weight="1"
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index a2eba81155c7..0aa880fe6d88 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -808,6 +808,8 @@
<dimen name="keyguard_lock_height">42dp</dimen>
<dimen name="keyguard_lock_padding">20dp</dimen>
+ <dimen name="keyguard_security_container_padding_top">20dp</dimen>
+
<dimen name="keyguard_indication_margin_bottom">32dp</dimen>
<dimen name="lock_icon_margin_bottom">74dp</dimen>
<dimen name="ambient_indication_margin_bottom">71dp</dimen>
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationRunnerCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationRunnerCompat.java
index 1b0dacc327c1..8dcd2aaac9ef 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationRunnerCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationRunnerCompat.java
@@ -206,7 +206,7 @@ public abstract class RemoteAnimationRunnerCompat extends IRemoteAnimationRunner
t.close();
info.releaseAllSurfaces();
if (finishRunnable == null) return;
- onAnimationCancelled(false /* isKeyguardOccluded */);
+ onAnimationCancelled();
finishRunnable.run();
}
};
diff --git a/packages/SystemUI/src/com/android/keyguard/BouncerKeyguardMessageArea.kt b/packages/SystemUI/src/com/android/keyguard/BouncerKeyguardMessageArea.kt
index f59bf8e766fe..62f4f2282e66 100644
--- a/packages/SystemUI/src/com/android/keyguard/BouncerKeyguardMessageArea.kt
+++ b/packages/SystemUI/src/com/android/keyguard/BouncerKeyguardMessageArea.kt
@@ -28,6 +28,7 @@ import android.util.AttributeSet
import android.view.View
import com.android.settingslib.Utils
import com.android.systemui.animation.Interpolators
+import com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.ColorId.TITLE
/** Displays security messages for the keyguard bouncer. */
open class BouncerKeyguardMessageArea(context: Context?, attrs: AttributeSet?) :
@@ -56,8 +57,7 @@ open class BouncerKeyguardMessageArea(context: Context?, attrs: AttributeSet?) :
}
override fun onThemeChanged() {
- val array: TypedArray =
- mContext.obtainStyledAttributes(intArrayOf(android.R.attr.textColorPrimary))
+ val array: TypedArray = mContext.obtainStyledAttributes(intArrayOf(TITLE))
val newTextColors: ColorStateList = ColorStateList.valueOf(array.getColor(0, Color.RED))
array.recycle()
mDefaultColorState = newTextColors
@@ -65,7 +65,7 @@ open class BouncerKeyguardMessageArea(context: Context?, attrs: AttributeSet?) :
}
override fun reloadColor() {
- mDefaultColorState = Utils.getColorAttr(context, android.R.attr.textColorPrimary)
+ mDefaultColorState = Utils.getColorAttr(context, TITLE)
super.reloadColor()
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index ba5a8c94dc23..b88d85c843e4 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -54,6 +54,7 @@ import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Icon;
import android.graphics.drawable.LayerDrawable;
import android.os.UserManager;
import android.provider.Settings;
@@ -333,6 +334,11 @@ public class KeyguardSecurityContainer extends ConstraintLayout {
mSpringAnimation = new SpringAnimation(this, DynamicAnimation.TRANSLATION_Y);
mViewConfiguration = ViewConfiguration.get(context);
mDoubleTapDetector = new GestureDetector(context, new DoubleTapListener());
+
+ // Add additional top padding.
+ setPadding(getPaddingLeft(), getPaddingTop() + getResources().getDimensionPixelSize(
+ R.dimen.keyguard_security_container_padding_top), getPaddingRight(),
+ getPaddingBottom());
}
void onResume(SecurityMode securityMode, boolean faceAuthEnabled) {
@@ -780,6 +786,8 @@ public class KeyguardSecurityContainer extends ConstraintLayout {
void reloadColors() {
mViewMode.reloadColors();
+ setBackgroundColor(Utils.getColorAttrDefaultColor(getContext(),
+ com.android.internal.R.attr.materialColorSurface));
}
/** Handles density or font scale changes. */
@@ -1022,11 +1030,15 @@ public class KeyguardSecurityContainer extends ConstraintLayout {
mUserSwitcherController.removeUserSwitchCallback(mUserSwitchCallback);
}
- private Drawable findUserIcon(int userId) {
+ private Drawable findLargeUserIcon(int userId) {
Bitmap userIcon = UserManager.get(mView.getContext()).getUserIcon(userId);
if (userIcon != null) {
- return CircleFramedDrawable.getInstance(mView.getContext(),
- userIcon);
+ int iconSize =
+ mResources.getDimensionPixelSize(R.dimen.bouncer_user_switcher_icon_size);
+ return CircleFramedDrawable.getInstance(
+ mView.getContext(),
+ Icon.scaleDownIfNecessary(userIcon, iconSize, iconSize)
+ );
}
return UserIcons.getDefaultUserIcon(mResources, userId, false);
@@ -1085,7 +1097,7 @@ public class KeyguardSecurityContainer extends ConstraintLayout {
return;
}
final String currentUserName = mUserSwitcherController.getCurrentUserName();
- Drawable userIcon = findUserIcon(currentUser.info.id);
+ Drawable userIcon = findLargeUserIcon(currentUser.info.id);
((ImageView) mView.findViewById(R.id.user_icon)).setImageDrawable(userIcon);
mUserSwitcher.setText(currentUserName);
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimInputView.kt b/packages/SystemUI/src/com/android/keyguard/KeyguardSimInputView.kt
index b4bfca1185f4..3fc39afe5d0f 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimInputView.kt
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimInputView.kt
@@ -20,7 +20,9 @@ import android.content.Context
import android.util.AttributeSet
import android.widget.ImageView
import androidx.core.graphics.drawable.DrawableCompat
+import com.android.settingslib.Utils
import com.android.systemui.R
+import com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.ColorId.EMERGENCY_BUTTON
abstract class KeyguardSimInputView(context: Context, attrs: AttributeSet) :
KeyguardPinBasedInputView(context, attrs) {
@@ -42,10 +44,7 @@ abstract class KeyguardSimInputView(context: Context, attrs: AttributeSet) :
override fun reloadColors() {
super.reloadColors()
- val customAttrs = intArrayOf(android.R.attr.textColorSecondary)
- val a = context.obtainStyledAttributes(customAttrs)
- val imageColor = a.getColor(0, 0)
- a.recycle()
+ val imageColor = Utils.getColorAttrDefaultColor(context, EMERGENCY_BUTTON)
simImageView?.let {
val wrappedDrawable = DrawableCompat.wrap(it.drawable)
DrawableCompat.setTint(wrappedDrawable, imageColor)
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 2c669bbb8fed..9573913e5e2f 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -396,6 +396,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
private int mFaceRunningState = BIOMETRIC_STATE_STOPPED;
private boolean mIsDreaming;
private boolean mLogoutEnabled;
+ private boolean mIsFaceEnrolled;
private int mActiveMobileDataSubscription = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
private int mPostureState = DEVICE_POSTURE_UNKNOWN;
private FingerprintInteractiveToAuthProvider mFingerprintInteractiveToAuthProvider;
@@ -2572,6 +2573,16 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
}
}
+ private void updateFaceEnrolled(int userId) {
+ final Boolean isFaceEnrolled = isFaceSupported()
+ && mBiometricEnabledForUser.get(userId)
+ && mAuthController.isFaceAuthEnrolled(userId);
+ if (mIsFaceEnrolled != isFaceEnrolled) {
+ mLogger.logFaceEnrolledUpdated(mIsFaceEnrolled, isFaceEnrolled);
+ }
+ mIsFaceEnrolled = isFaceEnrolled;
+ }
+
private boolean isFaceSupported() {
return mFaceManager != null && !mFaceSensorProperties.isEmpty();
}
@@ -2611,17 +2622,10 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
}
/**
- * @return true if there's at least one face enrolled for the given user
- */
- private boolean isFaceEnrolled(int userId) {
- return mAuthController.isFaceAuthEnrolled(userId);
- }
-
- /**
- * @return true if there's at least one face enrolled for the current user
+ * @return true if there's at least one face enrolled
*/
public boolean isFaceEnrolled() {
- return isFaceEnrolled(getCurrentUser());
+ return mIsFaceEnrolled;
}
private final UserTracker.Callback mUserChangedCallback = new UserTracker.Callback() {
@@ -3280,13 +3284,14 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
@SuppressLint("MissingPermission")
@VisibleForTesting
boolean isUnlockWithFingerprintPossible(int userId) {
- boolean newFpPossible = isFingerprintSupported()
- && !isFingerprintDisabled(userId) && mAuthController.isFingerprintEnrolled(userId);
- Boolean oldFpPossible = mIsUnlockWithFingerprintPossible.getOrDefault(userId, false);
- if (oldFpPossible != newFpPossible) {
- mLogger.logFpPossibleUpdated(userId, oldFpPossible, newFpPossible);
- }
- mIsUnlockWithFingerprintPossible.put(userId, newFpPossible);
+ // TODO (b/242022358), make this rely on onEnrollmentChanged event and update it only once.
+ boolean newFpEnrolled = isFingerprintSupported()
+ && !isFingerprintDisabled(userId) && mFpm.hasEnrolledTemplates(userId);
+ Boolean oldFpEnrolled = mIsUnlockWithFingerprintPossible.getOrDefault(userId, false);
+ if (oldFpEnrolled != newFpEnrolled) {
+ mLogger.logFpEnrolledUpdated(userId, oldFpEnrolled, newFpEnrolled);
+ }
+ mIsUnlockWithFingerprintPossible.put(userId, newFpEnrolled);
return mIsUnlockWithFingerprintPossible.get(userId);
}
@@ -3301,13 +3306,24 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
/**
* @deprecated This is being migrated to use modern architecture.
*/
- @VisibleForTesting
@Deprecated
- public boolean isUnlockWithFacePossible(int userId) {
+ private boolean isUnlockWithFacePossible(int userId) {
if (isFaceAuthInteractorEnabled()) {
return getFaceAuthInteractor().canFaceAuthRun();
}
- return isFaceSupported() && isFaceEnrolled(userId) && !isFaceDisabled(userId);
+ return isFaceAuthEnabledForUser(userId) && !isFaceDisabled(userId);
+ }
+
+ /**
+ * If face hardware is available, user has enrolled and enabled auth via setting.
+ *
+ * @deprecated This is being migrated to use modern architecture.
+ */
+ @Deprecated
+ public boolean isFaceAuthEnabledForUser(int userId) {
+ // TODO (b/242022358), make this rely on onEnrollmentChanged event and update it only once.
+ updateFaceEnrolled(userId);
+ return mIsFaceEnrolled;
}
private void stopListeningForFingerprint() {
diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
index 5f2afe8f755d..7cedecc33a02 100644
--- a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
@@ -56,6 +56,7 @@ import com.android.systemui.R;
import com.android.systemui.biometrics.AuthController;
import com.android.systemui.biometrics.AuthRippleController;
import com.android.systemui.biometrics.UdfpsController;
+import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.flags.FeatureFlags;
@@ -66,7 +67,6 @@ import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.VibratorHelper;
-import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.ViewController;
@@ -84,7 +84,7 @@ import javax.inject.Inject;
* For devices with UDFPS, the lock icon will show at the sensor location. Else, the lock
* icon will show a set distance from the bottom of the device.
*/
-@CentralSurfacesComponent.CentralSurfacesScope
+@SysUISingleton
public class LockIconViewController extends ViewController<LockIconView> implements Dumpable {
private static final String TAG = "LockIconViewController";
private static final float sDefaultDensity =
diff --git a/packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java b/packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java
index ad669099284f..c6c7113d7f9a 100644
--- a/packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java
+++ b/packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java
@@ -15,12 +15,19 @@
*/
package com.android.keyguard;
+import static com.android.settingslib.Utils.getColorAttrDefaultColor;
+import static com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.ColorId.NUM_PAD_BACKGROUND;
+import static com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.ColorId.NUM_PAD_BACKGROUND_PRESSED;
+import static com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.ColorId.NUM_PAD_BUTTON;
+import static com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.ColorId.NUM_PAD_KEY;
+import static com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.ColorId.NUM_PAD_PRESSED;
import static com.android.systemui.util.ColorUtilKt.getPrivateAttrColorIfUnset;
import android.animation.AnimatorSet;
import android.animation.ArgbEvaluator;
import android.animation.ValueAnimator;
import android.annotation.Nullable;
+import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
@@ -112,20 +119,18 @@ class NumPadAnimator {
int[] customAttrs = {android.R.attr.colorControlNormal};
ContextThemeWrapper ctw = new ContextThemeWrapper(context, mStyle);
- TypedArray a = ctw.obtainStyledAttributes(customAttrs);
+ @SuppressLint("ResourceType") TypedArray a = ctw.obtainStyledAttributes(customAttrs);
mNormalBackgroundColor = getPrivateAttrColorIfUnset(ctw, a, 0, 0,
- com.android.internal.R.attr.colorSurface);
+ NUM_PAD_BACKGROUND);
a.recycle();
- mBackground.setColor(mNormalBackgroundColor);
- mPressedBackgroundColor = context.getColor(android.R.color.system_accent1_200);
+ mPressedBackgroundColor = getColorAttrDefaultColor(context, NUM_PAD_BACKGROUND_PRESSED);
+ mTextColorPressed = getColorAttrDefaultColor(context, NUM_PAD_PRESSED);
+
+ mBackground.setColor(mNormalBackgroundColor);
mTextColorPrimary = isNumPadKey
- ? com.android.settingslib.Utils
- .getColorAttrDefaultColor(context, android.R.attr.textColorPrimary)
- : com.android.settingslib.Utils
- .getColorAttrDefaultColor(context, android.R.attr.textColorPrimaryInverse);
- mTextColorPressed = com.android.settingslib.Utils
- .getColorAttrDefaultColor(context, com.android.internal.R.attr.textColorOnAccent);
+ ? getColorAttrDefaultColor(context, NUM_PAD_KEY)
+ : getColorAttrDefaultColor(context, NUM_PAD_BUTTON);
createAnimators();
}
diff --git a/packages/SystemUI/src/com/android/keyguard/NumPadButton.java b/packages/SystemUI/src/com/android/keyguard/NumPadButton.java
index 11c329e9811d..6ae80a62891b 100644
--- a/packages/SystemUI/src/com/android/keyguard/NumPadButton.java
+++ b/packages/SystemUI/src/com/android/keyguard/NumPadButton.java
@@ -15,10 +15,12 @@
*/
package com.android.keyguard;
+import static com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.ColorId.NUM_PAD_BUTTON;
+import static com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.ColorId.NUM_PAD_KEY;
+
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.Configuration;
-import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.VectorDrawable;
@@ -27,6 +29,7 @@ import android.view.MotionEvent;
import androidx.annotation.Nullable;
+import com.android.settingslib.Utils;
import com.android.systemui.R;
/**
@@ -95,12 +98,8 @@ public class NumPadButton extends AlphaOptimizedImageButton implements NumPadAni
public void reloadColors() {
if (mAnimator != null) mAnimator.reloadColors(getContext());
- int textColorResId = mIsTransparentMode ? android.R.attr.textColorPrimary
- : android.R.attr.textColorPrimaryInverse;
- int[] customAttrs = {textColorResId};
- TypedArray a = getContext().obtainStyledAttributes(customAttrs);
- int imageColor = a.getColor(0, 0);
- a.recycle();
+ int textColorResId = mIsTransparentMode ? NUM_PAD_KEY : NUM_PAD_BUTTON;
+ int imageColor = Utils.getColorAttrDefaultColor(getContext(), textColorResId);
((VectorDrawable) getDrawable()).setTintList(ColorStateList.valueOf(imageColor));
}
@@ -119,7 +118,7 @@ public class NumPadButton extends AlphaOptimizedImageButton implements NumPadAni
public void setTransparentMode(boolean isTransparentMode) {
mIsTransparentMode = isTransparentMode;
if (isTransparentMode) {
- setBackgroundColor(android.R.color.transparent);
+ setBackgroundColor(getResources().getColor(android.R.color.transparent));
} else {
setBackground(getContext().getDrawable(R.drawable.num_pad_key_background));
}
diff --git a/packages/SystemUI/src/com/android/keyguard/NumPadKey.java b/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
index 7c7680afe368..e22fc300ede5 100644
--- a/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
+++ b/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
@@ -15,6 +15,8 @@
*/
package com.android.keyguard;
+import static com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.ColorId.NUM_PAD_KEY;
+
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.TypedArray;
@@ -150,7 +152,7 @@ public class NumPadKey extends ViewGroup implements NumPadAnimationListener {
* Reload colors from resources.
**/
public void reloadColors() {
- int textColor = Utils.getColorAttr(getContext(), android.R.attr.textColorPrimary)
+ int textColor = Utils.getColorAttr(getContext(), NUM_PAD_KEY)
.getDefaultColor();
int klondikeColor = Utils.getColorAttr(getContext(), android.R.attr.textColorSecondary)
.getDefaultColor();
diff --git a/packages/SystemUI/src/com/android/keyguard/PinShapeHintingView.java b/packages/SystemUI/src/com/android/keyguard/PinShapeHintingView.java
index fc5c254fdf29..32f06dcdbf20 100644
--- a/packages/SystemUI/src/com/android/keyguard/PinShapeHintingView.java
+++ b/packages/SystemUI/src/com/android/keyguard/PinShapeHintingView.java
@@ -16,6 +16,8 @@
package com.android.keyguard;
+import static com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.ColorId.PIN_SHAPES;
+
import android.content.Context;
import android.graphics.drawable.AnimatedVectorDrawable;
import android.graphics.drawable.Drawable;
@@ -37,7 +39,7 @@ public class PinShapeHintingView extends LinearLayout implements PinShapeInput {
private int mPinLength;
private int mDotDiameter;
- private int mColor = Utils.getColorAttr(getContext(), android.R.attr.textColorPrimary)
+ private int mColor = Utils.getColorAttr(getContext(), PIN_SHAPES)
.getDefaultColor();
private int mPosition = 0;
private static final int DEFAULT_PIN_LENGTH = 6;
diff --git a/packages/SystemUI/src/com/android/keyguard/PinShapeNonHintingView.java b/packages/SystemUI/src/com/android/keyguard/PinShapeNonHintingView.java
index 14810d9baf02..4aeab970e2f7 100644
--- a/packages/SystemUI/src/com/android/keyguard/PinShapeNonHintingView.java
+++ b/packages/SystemUI/src/com/android/keyguard/PinShapeNonHintingView.java
@@ -16,6 +16,8 @@
package com.android.keyguard;
+import static com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.ColorId.PIN_SHAPES;
+
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
@@ -45,8 +47,7 @@ import com.android.systemui.animation.Interpolators;
*/
public class PinShapeNonHintingView extends LinearLayout implements PinShapeInput {
- private int mColor = Utils.getColorAttr(getContext(),
- android.R.attr.textColorPrimary).getDefaultColor();
+ private int mColor = Utils.getColorAttr(getContext(), PIN_SHAPES).getDefaultColor();
private int mPosition = 0;
private final PinShapeAdapter mPinShapeAdapter;
private ValueAnimator mValueAnimator = ValueAnimator.ofFloat(1f, 0f);
diff --git a/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt b/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt
index fe4014575156..16618064f249 100644
--- a/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt
+++ b/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt
@@ -630,7 +630,7 @@ constructor(@KeyguardUpdateMonitorLog private val logBuffer: LogBuffer) {
)
}
- fun logFpPossibleUpdated(userId: Int, oldValue: Boolean, newValue: Boolean) {
+ fun logFpEnrolledUpdated(userId: Int, oldValue: Boolean, newValue: Boolean) {
logBuffer.log(
TAG,
DEBUG,
@@ -639,7 +639,7 @@ constructor(@KeyguardUpdateMonitorLog private val logBuffer: LogBuffer) {
bool1 = oldValue
bool2 = newValue
},
- { "Fp possible state changed for userId: $int1 old: $bool1, new: $bool2" }
+ { "Fp enrolled state changed for userId: $int1 old: $bool1, new: $bool2" }
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/OWNERS b/packages/SystemUI/src/com/android/systemui/accessibility/OWNERS
new file mode 100644
index 000000000000..1f66c91b3573
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 44215
+
+include /core/java/android/view/accessibility/OWNERS \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java b/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java
index f3c71da63594..4158390ec953 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java
@@ -45,6 +45,8 @@ import android.view.accessibility.AccessibilityManager;
import com.android.internal.R;
import com.android.internal.accessibility.dialog.AccessibilityButtonChooserActivity;
+import com.android.internal.accessibility.util.AccessibilityUtils;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ScreenshotHelper;
import com.android.systemui.CoreStartable;
import com.android.systemui.dagger.SysUISingleton;
@@ -520,8 +522,11 @@ public class SystemActions implements CoreStartable {
SCREENSHOT_ACCESSIBILITY_ACTIONS, new Handler(Looper.getMainLooper()), null);
}
- private void handleHeadsetHook() {
- sendDownAndUpKeyEvents(KeyEvent.KEYCODE_HEADSETHOOK);
+ @VisibleForTesting
+ void handleHeadsetHook() {
+ if (!AccessibilityUtils.interceptHeadsetHookForActiveCall(mContext)) {
+ sendDownAndUpKeyEvents(KeyEvent.KEYCODE_HEADSETHOOK);
+ }
}
private void handleAccessibilityButton() {
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java
index 7bfd84e4b647..155c26d9fe9d 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSettings.java
@@ -463,13 +463,17 @@ class WindowMagnificationSettings implements MagnificationGestureDetector.OnGest
if ((configDiff & ActivityInfo.CONFIG_UI_MODE) != 0
|| (configDiff & ActivityInfo.CONFIG_ASSETS_PATHS) != 0
|| (configDiff & ActivityInfo.CONFIG_FONT_SCALE) != 0
+ || (configDiff & ActivityInfo.CONFIG_LOCALE) != 0
|| (configDiff & ActivityInfo.CONFIG_DENSITY) != 0) {
// We listen to following config changes to trigger layout inflation:
// CONFIG_UI_MODE: theme change
// CONFIG_ASSETS_PATHS: wallpaper change
// CONFIG_FONT_SCALE: font size change
+ // CONFIG_LOCALE: language change
// CONFIG_DENSITY: display size change
+ mParams.accessibilityTitle = getAccessibilityWindowTitle(mContext);
+
boolean showSettingPanelAfterThemeChange = mIsVisible;
hideSettingPanel(/* resetPosition= */ false);
inflateView();
@@ -490,11 +494,6 @@ class WindowMagnificationSettings implements MagnificationGestureDetector.OnGest
+ mDraggableWindowBounds.top;
return;
}
-
- if ((configDiff & ActivityInfo.CONFIG_LOCALE) != 0) {
- updateAccessibilityWindowTitle();
- return;
- }
}
private void onWindowInsetChanged() {
@@ -515,13 +514,6 @@ class WindowMagnificationSettings implements MagnificationGestureDetector.OnGest
}
}
- private void updateAccessibilityWindowTitle() {
- mParams.accessibilityTitle = getAccessibilityWindowTitle(mContext);
- if (mIsVisible) {
- mWindowManager.updateViewLayout(mSettingView, mParams);
- }
- }
-
public void editMagnifierSizeMode(boolean enable) {
setEditMagnifierSizeMode(enable);
updateSelectedButton(MagnificationSize.NONE);
diff --git a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsBindingControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsBindingControllerImpl.kt
index 3d6d3356fb55..18bd46756660 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsBindingControllerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsBindingControllerImpl.kt
@@ -41,7 +41,8 @@ open class ControlsBindingControllerImpl @Inject constructor(
private val context: Context,
@Background private val backgroundExecutor: DelayableExecutor,
private val lazyController: Lazy<ControlsController>,
- userTracker: UserTracker
+ private val packageUpdateMonitorFactory: PackageUpdateMonitor.Factory,
+ userTracker: UserTracker,
) : ControlsBindingController {
companion object {
@@ -93,7 +94,8 @@ open class ControlsBindingControllerImpl @Inject constructor(
backgroundExecutor,
actionCallbackService,
currentUser,
- component
+ component,
+ packageUpdateMonitorFactory
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManager.kt b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManager.kt
index 217f4d89e24c..cb2476ce0ebf 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManager.kt
@@ -16,6 +16,7 @@
package com.android.systemui.controls.controller
+import android.annotation.WorkerThread
import android.content.ComponentName
import android.content.Context
import android.content.Intent
@@ -23,7 +24,6 @@ import android.content.ServiceConnection
import android.os.Binder
import android.os.Bundle
import android.os.IBinder
-import android.os.RemoteException
import android.os.UserHandle
import android.service.controls.ControlsProviderService
import android.service.controls.ControlsProviderService.CALLBACK_BUNDLE
@@ -38,6 +38,7 @@ import android.util.Log
import com.android.internal.annotations.GuardedBy
import com.android.systemui.util.concurrency.DelayableExecutor
import java.util.concurrent.TimeUnit
+import java.util.concurrent.atomic.AtomicBoolean
/**
* Manager for the lifecycle of the connection to a given [ControlsProviderService].
@@ -45,6 +46,9 @@ import java.util.concurrent.TimeUnit
* This class handles binding and unbinding and requests to the service. The class will queue
* requests until the service is connected and dispatch them then.
*
+ * If the provider app is updated, and we are currently bound to it, it will try to rebind after
+ * update is completed.
+ *
* @property context A SystemUI context for binding to the services
* @property executor A delayable executor for posting timeouts
* @property actionCallbackService a callback interface to hand the remote service for sending
@@ -59,22 +63,22 @@ class ControlsProviderLifecycleManager(
private val executor: DelayableExecutor,
private val actionCallbackService: IControlsActionCallback.Stub,
val user: UserHandle,
- val componentName: ComponentName
-) : IBinder.DeathRecipient {
+ val componentName: ComponentName,
+ packageUpdateMonitorFactory: PackageUpdateMonitor.Factory,
+) {
val token: IBinder = Binder()
private var requiresBound = false
@GuardedBy("queuedServiceMethods")
private val queuedServiceMethods: MutableSet<ServiceMethod> = ArraySet()
private var wrapper: ServiceWrapper? = null
- private var bindTryCount = 0
private val TAG = javaClass.simpleName
private var onLoadCanceller: Runnable? = null
+ private var lastForPanel = false
+
companion object {
- private const val BIND_RETRY_DELAY = 1000L // ms
private const val LOAD_TIMEOUT_SECONDS = 20L // seconds
- private const val MAX_BIND_RETRIES = 5
private const val DEBUG = true
private val BIND_FLAGS = Context.BIND_AUTO_CREATE or Context.BIND_FOREGROUND_SERVICE or
Context.BIND_NOT_PERCEPTIBLE
@@ -91,60 +95,56 @@ class ControlsProviderLifecycleManager(
})
}
+ private val packageUpdateMonitor = packageUpdateMonitorFactory.create(
+ user,
+ componentName.packageName,
+ ) {
+ if (requiresBound) {
+ // Let's unbind just in case. onBindingDied should have been called and unbound before.
+ executor.execute {
+ unbindAndCleanup("package updated")
+ bindService(true, lastForPanel)
+ }
+ }
+ }
+
private fun bindService(bind: Boolean, forPanel: Boolean = false) {
executor.execute {
- requiresBound = bind
- if (bind) {
- if (bindTryCount != MAX_BIND_RETRIES && wrapper == null) {
- if (DEBUG) {
- Log.d(TAG, "Binding service $intent")
- }
- bindTryCount++
- try {
- val flags = if (forPanel) BIND_FLAGS_PANEL else BIND_FLAGS
- val bound = context
- .bindServiceAsUser(intent, serviceConnection, flags, user)
- if (!bound) {
- context.unbindService(serviceConnection)
- }
- } catch (e: SecurityException) {
- Log.e(TAG, "Failed to bind to service", e)
- }
- }
- } else {
- if (DEBUG) {
- Log.d(TAG, "Unbinding service $intent")
- }
- bindTryCount = 0
- wrapper?.run {
- context.unbindService(serviceConnection)
- }
- wrapper = null
- }
+ bindServiceBackground(bind, forPanel)
}
}
private val serviceConnection = object : ServiceConnection {
+
+ val connected = AtomicBoolean(false)
+
override fun onServiceConnected(name: ComponentName, service: IBinder) {
if (DEBUG) Log.d(TAG, "onServiceConnected $name")
- bindTryCount = 0
wrapper = ServiceWrapper(IControlsProvider.Stub.asInterface(service))
- try {
- service.linkToDeath(this@ControlsProviderLifecycleManager, 0)
- } catch (_: RemoteException) {}
+ packageUpdateMonitor.startMonitoring()
handlePendingServiceMethods()
}
override fun onServiceDisconnected(name: ComponentName?) {
if (DEBUG) Log.d(TAG, "onServiceDisconnected $name")
wrapper = null
- bindService(false)
+ // No need to call unbind. We may get a new `onServiceConnected`
}
override fun onNullBinding(name: ComponentName?) {
if (DEBUG) Log.d(TAG, "onNullBinding $name")
wrapper = null
- context.unbindService(this)
+ executor.execute {
+ unbindAndCleanup("null binding")
+ }
+ }
+
+ override fun onBindingDied(name: ComponentName?) {
+ super.onBindingDied(name)
+ if (DEBUG) Log.d(TAG, "onBindingDied $name")
+ executor.execute {
+ unbindAndCleanup("binder died")
+ }
}
}
@@ -159,14 +159,55 @@ class ControlsProviderLifecycleManager(
}
}
- override fun binderDied() {
- if (wrapper == null) return
- wrapper = null
- if (requiresBound) {
- if (DEBUG) {
- Log.d(TAG, "binderDied")
+ @WorkerThread
+ private fun bindServiceBackground(bind: Boolean, forPanel: Boolean = true) {
+ requiresBound = bind
+ if (bind) {
+ if (wrapper == null) {
+ if (DEBUG) {
+ Log.d(TAG, "Binding service $intent")
+ }
+ try {
+ lastForPanel = forPanel
+ val flags = if (forPanel) BIND_FLAGS_PANEL else BIND_FLAGS
+ var bound = false
+ if (serviceConnection.connected.compareAndSet(false, true)) {
+ bound = context
+ .bindServiceAsUser(intent, serviceConnection, flags, user)
+ }
+ if (!bound) {
+ Log.d(TAG, "Couldn't bind to $intent")
+ doUnbind()
+ }
+ } catch (e: SecurityException) {
+ Log.e(TAG, "Failed to bind to service", e)
+ // Couldn't even bind. Let's reset the connected value
+ serviceConnection.connected.set(false)
+ }
}
- // Try rebinding some time later
+ } else {
+ unbindAndCleanup("unbind requested")
+ packageUpdateMonitor.stopMonitoring()
+ }
+ }
+
+ @WorkerThread
+ private fun unbindAndCleanup(reason: String) {
+ if (DEBUG) {
+ Log.d(TAG, "Unbinding service $intent. Reason: $reason")
+ }
+ wrapper = null
+ try {
+ doUnbind()
+ } catch (e: IllegalArgumentException) {
+ Log.e(TAG, "Failed to unbind service", e)
+ }
+ }
+
+ @WorkerThread
+ private fun doUnbind() {
+ if (serviceConnection.connected.compareAndSet(true, false)) {
+ context.unbindService(serviceConnection)
}
}
@@ -313,7 +354,7 @@ class ControlsProviderLifecycleManager(
fun run() {
if (!callWrapper()) {
queueServiceMethod(this)
- binderDied()
+ executor.execute { unbindAndCleanup("couldn't call through binder") }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/controller/PackageUpdateMonitor.kt b/packages/SystemUI/src/com/android/systemui/controls/controller/PackageUpdateMonitor.kt
new file mode 100644
index 000000000000..1973b620b34f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/controls/controller/PackageUpdateMonitor.kt
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.controls.controller
+
+import android.content.Context
+import android.os.Handler
+import android.os.UserHandle
+import com.android.internal.content.PackageMonitor
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Background
+import dagger.assisted.Assisted
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
+import java.util.concurrent.atomic.AtomicBoolean
+
+/** [PackageMonitor] that tracks when [packageName] has finished updating for user [user]. */
+class PackageUpdateMonitor
+@AssistedInject
+constructor(
+ @Assisted private val user: UserHandle,
+ @Assisted private val packageName: String,
+ @Assisted private val callback: Runnable,
+ @Background private val bgHandler: Handler,
+ @Application private val context: Context,
+) : PackageMonitor() {
+
+ private val monitoring = AtomicBoolean(false)
+
+ @AssistedFactory
+ fun interface Factory {
+ /**
+ * Create a [PackageUpdateMonitor] for a given [user] and [packageName]. It will run
+ * [callback] every time the package finishes updating.
+ */
+ fun create(user: UserHandle, packageName: String, callback: Runnable): PackageUpdateMonitor
+ }
+
+ /** Start monitoring for package updates. No-op if already monitoring. */
+ fun startMonitoring() {
+ if (monitoring.compareAndSet(/* expected */ false, /* new */ true)) {
+ register(context, user, false, bgHandler)
+ }
+ }
+
+ /** Stop monitoring for package updates. No-op if not monitoring. */
+ fun stopMonitoring() {
+ if (monitoring.compareAndSet(/* expected */ true, /* new */ false)) {
+ unregister()
+ }
+ }
+
+ /**
+ * If the package and the user match the ones for this [PackageUpdateMonitor], it will run
+ * [callback].
+ */
+ override fun onPackageUpdateFinished(packageName: String?, uid: Int) {
+ super.onPackageUpdateFinished(packageName, uid)
+ if (packageName == this.packageName && UserHandle.getUserHandleForUid(uid) == user) {
+ callback.run()
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/controller/ServiceWrapper.kt b/packages/SystemUI/src/com/android/systemui/controls/controller/ServiceWrapper.kt
index 2c717f5af8da..45cb13be361e 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/controller/ServiceWrapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/controller/ServiceWrapper.kt
@@ -16,11 +16,11 @@
package com.android.systemui.controls.controller
-import android.service.controls.actions.ControlAction
import android.service.controls.IControlsActionCallback
import android.service.controls.IControlsProvider
import android.service.controls.IControlsSubscriber
import android.service.controls.IControlsSubscription
+import android.service.controls.actions.ControlAction
import android.service.controls.actions.ControlActionWrapper
import android.util.Log
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/PanelTaskViewController.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/PanelTaskViewController.kt
index 9a231814a813..025d7e40201e 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/PanelTaskViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/PanelTaskViewController.kt
@@ -41,6 +41,10 @@ class PanelTaskViewController(
private val hide: () -> Unit = {}
) {
+ init {
+ taskView.alpha = 0f
+ }
+
private var detailTaskId = INVALID_TASK_ID
private val fillInIntent =
@@ -96,6 +100,7 @@ class PanelTaskViewController(
override fun onTaskCreated(taskId: Int, name: ComponentName?) {
detailTaskId = taskId
+ taskView.alpha = 1f
}
override fun onReleased() {
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamLogger.kt b/packages/SystemUI/src/com/android/systemui/dreams/DreamLogger.kt
new file mode 100644
index 000000000000..eb7929095a4b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamLogger.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.dreams
+
+import com.android.systemui.log.dagger.DreamLog
+import com.android.systemui.plugins.log.LogBuffer
+import com.android.systemui.plugins.log.LogLevel
+import javax.inject.Inject
+
+/** Logs dream-related stuff to a {@link LogBuffer}. */
+class DreamLogger @Inject constructor(@DreamLog private val buffer: LogBuffer) {
+ /** Logs a debug message to the buffer. */
+ fun d(tag: String, message: String) {
+ buffer.log(tag, LogLevel.DEBUG, { str1 = message }, { message })
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayAnimationsController.kt b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayAnimationsController.kt
index 5b56c04ae8aa..df46e07e0911 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayAnimationsController.kt
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayAnimationsController.kt
@@ -21,6 +21,7 @@ import android.animation.AnimatorSet
import android.animation.ValueAnimator
import android.view.View
import android.view.animation.Interpolator
+import androidx.core.animation.doOnCancel
import androidx.core.animation.doOnEnd
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.repeatOnLifecycle
@@ -65,7 +66,11 @@ constructor(
private val mDreamInTranslationYDistance: Int,
@Named(DreamOverlayModule.DREAM_IN_TRANSLATION_Y_DURATION)
private val mDreamInTranslationYDurationMs: Long,
+ private val mLogger: DreamLogger,
) {
+ companion object {
+ private const val TAG = "DreamOverlayAnimationsController"
+ }
private var mAnimator: Animator? = null
private lateinit var view: View
@@ -169,8 +174,11 @@ constructor(
doOnEnd {
mAnimator = null
mOverlayStateController.setEntryAnimationsFinished(true)
+ mLogger.d(TAG, "Dream overlay entry animations finished.")
}
+ doOnCancel { mLogger.d(TAG, "Dream overlay entry animations canceled.") }
start()
+ mLogger.d(TAG, "Dream overlay entry animations started.")
}
}
@@ -232,8 +240,11 @@ constructor(
doOnEnd {
mAnimator = null
mOverlayStateController.setExitAnimationsRunning(false)
+ mLogger.d(TAG, "Dream overlay exit animations finished.")
}
+ doOnCancel { mLogger.d(TAG, "Dream overlay exit animations canceled.") }
start()
+ mLogger.d(TAG, "Dream overlay exit animations started.")
}
mOverlayStateController.setExitAnimationsRunning(true)
return mAnimator as AnimatorSet
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index 17e66a74927b..942730344f20 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
@@ -77,6 +77,12 @@ object Flags {
// TODO(b/257315550): Tracking Bug
val NO_HUN_FOR_OLD_WHEN = releasedFlag(118, "no_hun_for_old_when")
+ /** Makes sure notification panel is updated before the user switch is complete. */
+ // TODO(b/278873737): Tracking Bug
+ @JvmField
+ val LOAD_NOTIFICATIONS_BEFORE_THE_USER_SWITCH_IS_COMPLETE =
+ unreleasedFlag(278873737, "load_notifications_before_the_user_switch_is_complete")
+
// TODO(b/277338665): Tracking Bug
@JvmField
val NOTIFICATION_SHELF_REFACTOR =
@@ -678,5 +684,6 @@ object Flags {
// TODO(b/278761837): Tracking Bug
@JvmField
- val USE_NEW_ACTIVITY_STARTER = unreleasedFlag(2801, name = "use_new_activity_starter")
+ val USE_NEW_ACTIVITY_STARTER = unreleasedFlag(2801, name = "use_new_activity_starter",
+ teamfood = true)
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
index 107e685c4482..8b6bd2486117 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
@@ -243,7 +243,7 @@ public class KeyguardService extends Service {
Slog.e(TAG, "Called mergeAnimation, but finish callback is missing");
return;
}
- runner.onAnimationCancelled(false /* isKeyguardOccluded */);
+ runner.onAnimationCancelled();
currentFinishCB.onTransitionFinished(null /* wct */, null /* t */);
} catch (RemoteException e) {
// nothing, we'll just let it finish on its own I guess.
@@ -418,7 +418,7 @@ public class KeyguardService extends Service {
}
@Override // Binder interface
- public void onAnimationCancelled(boolean isKeyguardOccluded) {
+ public void onAnimationCancelled() {
mKeyguardViewMediator.cancelKeyguardExitAnimation();
}
};
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 93ddfba5b6fc..1a126d72f9e9 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -959,20 +959,15 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
@Nullable private ValueAnimator mOccludeByDreamAnimator;
@Override
- public void onAnimationCancelled(boolean isKeyguardOccluded) {
+ public void onAnimationCancelled() {
mContext.getMainExecutor().execute(() -> {
if (mOccludeByDreamAnimator != null) {
mOccludeByDreamAnimator.cancel();
}
});
- // The value of isKeyguardOccluded here may come from mergeAnimation, which
- // isn't reliable. In all cases, after running or cancelling this animation,
- // keyguard should be occluded.
+
+ Log.d(TAG, "OccludeByDreamAnimator#onAnimationCancelled. Set occluded = true");
setOccluded(true /* isOccluded */, false /* animate */);
- if (DEBUG) {
- Log.d(TAG, "Occlude by Dream animation cancelled. Occluded state is now: "
- + mOccluded);
- }
}
@Override
@@ -984,6 +979,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
// Usually we rely on animation completion to synchronize occluded status,
// but there was no animation to play, so just update it now.
setOccluded(true /* isOccluded */, false /* animate */);
+ finishedCallback.onAnimationFinished();
}
}
@@ -991,11 +987,8 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps,
IRemoteAnimationFinishedCallback finishedCallback) throws RemoteException {
if (apps == null || apps.length == 0 || apps[0] == null) {
- if (DEBUG) {
- Log.d(TAG, "No apps provided to the OccludeByDream runner; "
- + "skipping occluding animation.");
- }
- finishedCallback.onAnimationFinished();
+ Log.d(TAG, "No apps provided to the OccludeByDream runner; "
+ + "skipping occluding animation.");
return false;
}
@@ -1005,7 +998,6 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
if (!isDream) {
Log.w(TAG, "The occluding app isn't Dream; "
+ "finishing up. Please check that the config is correct.");
- finishedCallback.onAnimationFinished();
return false;
}
@@ -1071,17 +1063,14 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
private final Matrix mUnoccludeMatrix = new Matrix();
@Override
- public void onAnimationCancelled(boolean isKeyguardOccluded) {
+ public void onAnimationCancelled() {
mContext.getMainExecutor().execute(() -> {
if (mUnoccludeAnimator != null) {
mUnoccludeAnimator.cancel();
}
});
- setOccluded(isKeyguardOccluded /* isOccluded */, false /* animate */);
- Log.d(TAG, "Unocclude animation cancelled. Occluded state is now: "
- + mOccluded);
-
+ Log.d(TAG, "Unocclude animation cancelled.");
mInteractionJankMonitor.cancel(CUJ_LOCKSCREEN_OCCLUSION);
}
@@ -3404,9 +3393,9 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
}
@Override
- public void onAnimationCancelled(boolean isKeyguardOccluded) throws RemoteException {
+ public void onAnimationCancelled() throws RemoteException {
if (mRunner != null) {
- mRunner.onAnimationCancelled(isKeyguardOccluded);
+ mRunner.onAnimationCancelled();
}
}
@@ -3452,13 +3441,9 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
}
@Override
- public void onAnimationCancelled(boolean isKeyguardOccluded) throws RemoteException {
- super.onAnimationCancelled(isKeyguardOccluded);
-
- Log.d(TAG, "Occlude animation cancelled by WM. "
- + "Setting occluded state to: " + isKeyguardOccluded);
- setOccluded(isKeyguardOccluded /* occluded */, false /* animate */);
-
+ public void onAnimationCancelled() throws RemoteException {
+ super.onAnimationCancelled();
+ Log.d(TAG, "Occlude animation cancelled by WM.");
mInteractionJankMonitor.cancel(CUJ_LOCKSCREEN_OCCLUSION);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractor.kt
index 1fbfff95ab7e..c0d5abc04e5d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractor.kt
@@ -48,6 +48,7 @@ constructor(
listenForOccludedToDreaming()
listenForOccludedToAodOrDozing()
listenForOccludedToGone()
+ listenForOccludedToAlternateBouncer()
}
private fun listenForOccludedToDreaming() {
@@ -167,6 +168,28 @@ constructor(
}
}
+ private fun listenForOccludedToAlternateBouncer() {
+ scope.launch {
+ keyguardInteractor.alternateBouncerShowing
+ .sample(keyguardTransitionInteractor.startedKeyguardTransitionStep, ::Pair)
+ .collect { (isAlternateBouncerShowing, lastStartedTransitionStep) ->
+ if (
+ isAlternateBouncerShowing &&
+ lastStartedTransitionStep.to == KeyguardState.OCCLUDED
+ ) {
+ keyguardTransitionRepository.startTransition(
+ TransitionInfo(
+ ownerName = name,
+ from = KeyguardState.OCCLUDED,
+ to = KeyguardState.ALTERNATE_BOUNCER,
+ animator = getAnimator(),
+ )
+ )
+ }
+ }
+ }
+ }
+
private fun getAnimator(duration: Duration = DEFAULT_DURATION): ValueAnimator {
return ValueAnimator().apply {
setInterpolator(Interpolators.LINEAR)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractor.kt
index 94961cbf4240..a681c43be19f 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractor.kt
@@ -48,10 +48,51 @@ constructor(
override fun start() {
listenForPrimaryBouncerToGone()
- listenForPrimaryBouncerToLockscreenAodOrDozing()
+ listenForPrimaryBouncerToAodOrDozing()
+ listenForPrimaryBouncerToLockscreenOrOccluded()
}
- private fun listenForPrimaryBouncerToLockscreenAodOrDozing() {
+ private fun listenForPrimaryBouncerToLockscreenOrOccluded() {
+ scope.launch {
+ keyguardInteractor.primaryBouncerShowing
+ .sample(
+ combine(
+ keyguardInteractor.wakefulnessModel,
+ keyguardTransitionInteractor.startedKeyguardTransitionStep,
+ keyguardInteractor.isKeyguardOccluded,
+ ::toTriple
+ ),
+ ::toQuad
+ )
+ .collect { (isBouncerShowing, wakefulnessState, lastStartedTransitionStep, occluded)
+ ->
+ if (
+ !isBouncerShowing &&
+ lastStartedTransitionStep.to == KeyguardState.PRIMARY_BOUNCER &&
+ (wakefulnessState.state == WakefulnessState.AWAKE ||
+ wakefulnessState.state == WakefulnessState.STARTING_TO_WAKE)
+ ) {
+ val to =
+ if (occluded) {
+ KeyguardState.OCCLUDED
+ } else {
+ KeyguardState.LOCKSCREEN
+ }
+
+ keyguardTransitionRepository.startTransition(
+ TransitionInfo(
+ ownerName = name,
+ from = KeyguardState.PRIMARY_BOUNCER,
+ to = to,
+ animator = getAnimator(),
+ )
+ )
+ }
+ }
+ }
+ }
+
+ private fun listenForPrimaryBouncerToAodOrDozing() {
scope.launch {
keyguardInteractor.primaryBouncerShowing
.sample(
@@ -68,21 +109,17 @@ constructor(
->
if (
!isBouncerShowing &&
- lastStartedTransitionStep.to == KeyguardState.PRIMARY_BOUNCER
+ lastStartedTransitionStep.to == KeyguardState.PRIMARY_BOUNCER &&
+ (wakefulnessState.state == WakefulnessState.STARTING_TO_SLEEP ||
+ wakefulnessState.state == WakefulnessState.ASLEEP)
) {
val to =
- if (
- wakefulnessState.state == WakefulnessState.STARTING_TO_SLEEP ||
- wakefulnessState.state == WakefulnessState.ASLEEP
- ) {
- if (isAodAvailable) {
- KeyguardState.AOD
- } else {
- KeyguardState.DOZING
- }
+ if (isAodAvailable) {
+ KeyguardState.AOD
} else {
- KeyguardState.LOCKSCREEN
+ KeyguardState.DOZING
}
+
keyguardTransitionRepository.startTransition(
TransitionInfo(
ownerName = name,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/shared/constants/KeyguardBouncerConstants.kt b/packages/SystemUI/src/com/android/systemui/keyguard/shared/constants/KeyguardBouncerConstants.kt
index 3b3ec39d0209..c45faf0ba961 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/shared/constants/KeyguardBouncerConstants.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/shared/constants/KeyguardBouncerConstants.kt
@@ -32,4 +32,15 @@ object KeyguardBouncerConstants {
* PIN hinting is enabled
*/
const val DEFAULT_PIN_LENGTH = 6
+
+ object ColorId {
+ const val TITLE = com.android.internal.R.attr.materialColorOnSurface
+ const val PIN_SHAPES = com.android.internal.R.attr.materialColorOnSurfaceVariant
+ const val NUM_PAD_BACKGROUND = com.android.internal.R.attr.materialColorSurfaceContainerHigh
+ const val NUM_PAD_BACKGROUND_PRESSED = com.android.internal.R.attr.materialColorPrimaryFixed
+ const val NUM_PAD_PRESSED = com.android.internal.R.attr.materialColorOnPrimaryFixed
+ const val NUM_PAD_KEY = com.android.internal.R.attr.materialColorOnSurface
+ const val NUM_PAD_BUTTON = com.android.internal.R.attr.materialColorOnSecondaryFixed
+ const val EMERGENCY_BUTTON = com.android.internal.R.attr.materialColorTertiaryFixed
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
index 85fb5655899f..a98a7d8f8639 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
@@ -155,8 +155,15 @@ constructor(
disposables.forEach { it.dispose() }
}
+ /**
+ * Hides or shows smartspace
+ *
+ * @param hide TRUE hides smartspace, FALSE shows smartspace
+ */
fun hideSmartspace(hide: Boolean) {
- smartSpaceView?.visibility = if (hide) View.INVISIBLE else View.VISIBLE
+ runBlocking(mainDispatcher) {
+ smartSpaceView?.visibility = if (hide) View.INVISIBLE else View.VISIBLE
+ }
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/DreamLog.kt b/packages/SystemUI/src/com/android/systemui/log/dagger/DreamLog.kt
new file mode 100644
index 000000000000..cb9913abe99b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/DreamLog.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.log.dagger
+
+import javax.inject.Qualifier
+
+/** A [com.android.systemui.log.LogBuffer] for dream-related logging. */
+@Qualifier @MustBeDocumented @Retention(AnnotationRetention.RUNTIME) annotation class DreamLog
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
index 077ee027d764..658f6a087854 100644
--- a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
@@ -440,4 +440,14 @@ public class LogModule {
public static LogBuffer provideKeyguardLogBuffer(LogBufferFactory factory) {
return factory.create("KeyguardLog", 250);
}
+
+ /**
+ * Provides a {@link LogBuffer} for dream-related logs.
+ */
+ @Provides
+ @SysUISingleton
+ @DreamLog
+ public static LogBuffer provideDreamLogBuffer(LogBufferFactory factory) {
+ return factory.create("DreamLog", 250);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/log/table/LogProxy.kt b/packages/SystemUI/src/com/android/systemui/log/table/LogProxy.kt
new file mode 100644
index 000000000000..53886aabfa72
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/log/table/LogProxy.kt
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.log.table
+
+import android.util.Log
+import javax.inject.Inject
+
+/** Dagger-friendly interface so we can inject a fake [android.util.Log] in tests */
+interface LogProxy {
+ /** verbose log */
+ fun v(tag: String, message: String)
+
+ /** debug log */
+ fun d(tag: String, message: String)
+
+ /** info log */
+ fun i(tag: String, message: String)
+
+ /** warning log */
+ fun w(tag: String, message: String)
+
+ /** error log */
+ fun e(tag: String, message: String)
+
+ /** wtf log */
+ fun wtf(tag: String, message: String)
+}
+
+class LogProxyDefault @Inject constructor() : LogProxy {
+ override fun v(tag: String, message: String) {
+ Log.v(tag, message)
+ }
+
+ override fun d(tag: String, message: String) {
+ Log.d(tag, message)
+ }
+
+ override fun i(tag: String, message: String) {
+ Log.i(tag, message)
+ }
+
+ override fun w(tag: String, message: String) {
+ Log.w(tag, message)
+ }
+
+ override fun e(tag: String, message: String) {
+ Log.e(tag, message)
+ }
+
+ override fun wtf(tag: String, message: String) {
+ Log.wtf(tag, message)
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/log/table/TableLogBuffer.kt b/packages/SystemUI/src/com/android/systemui/log/table/TableLogBuffer.kt
index faaa205b15c2..9d883cc10d6c 100644
--- a/packages/SystemUI/src/com/android/systemui/log/table/TableLogBuffer.kt
+++ b/packages/SystemUI/src/com/android/systemui/log/table/TableLogBuffer.kt
@@ -19,10 +19,17 @@ package com.android.systemui.log.table
import android.os.Trace
import com.android.systemui.Dumpable
import com.android.systemui.common.buffer.RingBuffer
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.plugins.log.LogLevel
+import com.android.systemui.plugins.log.LogcatEchoTracker
import com.android.systemui.util.time.SystemClock
import java.io.PrintWriter
import java.text.SimpleDateFormat
import java.util.Locale
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.channels.Channel
+import kotlinx.coroutines.launch
/**
* A logger that logs changes in table format.
@@ -73,12 +80,18 @@ class TableLogBuffer(
maxSize: Int,
private val name: String,
private val systemClock: SystemClock,
+ private val logcatEchoTracker: LogcatEchoTracker,
+ @Background private val bgDispatcher: CoroutineDispatcher,
+ private val coroutineScope: CoroutineScope,
+ private val localLogcat: LogProxy = LogProxyDefault(),
) : Dumpable {
init {
if (maxSize <= 0) {
throw IllegalArgumentException("maxSize must be > 0")
}
}
+ // For local logcat, send messages across this channel so the background job can process them
+ private val logMessageChannel = Channel<TableChange>(capacity = 10)
private val buffer = RingBuffer(maxSize) { TableChange() }
@@ -105,6 +118,16 @@ class TableLogBuffer(
tableLogBuffer = this,
)
+ /** Start this log buffer logging in the background */
+ internal fun init() {
+ coroutineScope.launch(bgDispatcher) {
+ while (!logMessageChannel.isClosedForReceive) {
+ val log = logMessageChannel.receive()
+ echoToDesiredEndpoints(log)
+ }
+ }
+ }
+
/**
* Log the differences between [prevVal] and [newVal].
*
@@ -189,6 +212,7 @@ class TableLogBuffer(
Trace.beginSection("TableLogBuffer#logChange(string)")
val change = obtain(timestamp, prefix, columnName, isInitial)
change.set(value)
+ tryAddMessage(change)
Trace.endSection()
}
@@ -202,6 +226,7 @@ class TableLogBuffer(
Trace.beginSection("TableLogBuffer#logChange(boolean)")
val change = obtain(timestamp, prefix, columnName, isInitial)
change.set(value)
+ tryAddMessage(change)
Trace.endSection()
}
@@ -215,9 +240,14 @@ class TableLogBuffer(
Trace.beginSection("TableLogBuffer#logChange(int)")
val change = obtain(timestamp, prefix, columnName, isInitial)
change.set(value)
+ tryAddMessage(change)
Trace.endSection()
}
+ private fun tryAddMessage(change: TableChange) {
+ logMessageChannel.trySend(change)
+ }
+
// TODO(b/259454430): Add additional change types here.
@Synchronized
@@ -258,6 +288,17 @@ class TableLogBuffer(
Trace.endSection()
}
+ private fun echoToDesiredEndpoints(change: TableChange) {
+ if (
+ logcatEchoTracker.isBufferLoggable(bufferName = name, LogLevel.DEBUG) ||
+ logcatEchoTracker.isTagLoggable(change.columnName, LogLevel.DEBUG)
+ ) {
+ if (change.hasData()) {
+ localLogcat.d(name, change.logcatRepresentation())
+ }
+ }
+ }
+
@Synchronized
override fun dump(pw: PrintWriter, args: Array<out String>) {
pw.println(HEADER_PREFIX + name)
@@ -284,6 +325,12 @@ class TableLogBuffer(
pw.println()
}
+ /** Transforms an individual [TableChange] into a String for logcat */
+ private fun TableChange.logcatRepresentation(): String {
+ val formattedTimestamp = TABLE_LOG_DATE_FORMAT.format(timestamp)
+ return "$formattedTimestamp$SEPARATOR${getName()}$SEPARATOR${getVal()}"
+ }
+
/**
* A private implementation of [TableRowLogger].
*
diff --git a/packages/SystemUI/src/com/android/systemui/log/table/TableLogBufferFactory.kt b/packages/SystemUI/src/com/android/systemui/log/table/TableLogBufferFactory.kt
index 06668d33408d..42e742db2842 100644
--- a/packages/SystemUI/src/com/android/systemui/log/table/TableLogBufferFactory.kt
+++ b/packages/SystemUI/src/com/android/systemui/log/table/TableLogBufferFactory.kt
@@ -17,10 +17,15 @@
package com.android.systemui.log.table
import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dump.DumpManager
import com.android.systemui.log.LogBufferHelper.Companion.adjustMaxSize
+import com.android.systemui.plugins.log.LogcatEchoTracker
import com.android.systemui.util.time.SystemClock
import javax.inject.Inject
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.CoroutineScope
@SysUISingleton
class TableLogBufferFactory
@@ -28,6 +33,9 @@ class TableLogBufferFactory
constructor(
private val dumpManager: DumpManager,
private val systemClock: SystemClock,
+ private val logcatEchoTracker: LogcatEchoTracker,
+ @Background private val bgDispatcher: CoroutineDispatcher,
+ @Application private val coroutineScope: CoroutineScope,
) {
private val existingBuffers = mutableMapOf<String, TableLogBuffer>()
@@ -44,8 +52,17 @@ constructor(
name: String,
maxSize: Int,
): TableLogBuffer {
- val tableBuffer = TableLogBuffer(adjustMaxSize(maxSize), name, systemClock)
+ val tableBuffer =
+ TableLogBuffer(
+ adjustMaxSize(maxSize),
+ name,
+ systemClock,
+ logcatEchoTracker,
+ bgDispatcher,
+ coroutineScope,
+ )
dumpManager.registerNormalDumpable(name, tableBuffer)
+ tableBuffer.init()
return tableBuffer
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDeviceManager.kt b/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDeviceManager.kt
index 120704c0582a..3fc3ad682bc7 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDeviceManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDeviceManager.kt
@@ -154,6 +154,7 @@ constructor(
get() = controller?.sessionToken
private var started = false
private var playbackType = PLAYBACK_TYPE_UNKNOWN
+ private var playbackVolumeControlId: String? = null
private var current: MediaDeviceData? = null
set(value) {
val sameWithoutIcon = value != null && value.equalsWithoutIcon(field)
@@ -181,6 +182,7 @@ constructor(
localMediaManager.startScan()
muteAwaitConnectionManager?.startListening()
playbackType = controller?.playbackInfo?.playbackType ?: PLAYBACK_TYPE_UNKNOWN
+ playbackVolumeControlId = controller?.playbackInfo?.volumeControlId
controller?.registerCallback(this)
updateCurrent()
started = true
@@ -209,6 +211,8 @@ constructor(
println(" current device is ${current?.name}")
val type = controller?.playbackInfo?.playbackType
println(" PlaybackType=$type (1 for local, 2 for remote) cached=$playbackType")
+ val volumeControlId = controller?.playbackInfo?.volumeControlId
+ println(" volumeControlId=$volumeControlId cached= $playbackVolumeControlId")
println(" routingSession=$routingSession")
println(" selectedRoutes=$selectedRoutes")
}
@@ -217,10 +221,15 @@ constructor(
@WorkerThread
override fun onAudioInfoChanged(info: MediaController.PlaybackInfo?) {
val newPlaybackType = info?.playbackType ?: PLAYBACK_TYPE_UNKNOWN
- if (newPlaybackType == playbackType) {
+ val newPlaybackVolumeControlId = info?.volumeControlId
+ if (
+ newPlaybackType == playbackType &&
+ newPlaybackVolumeControlId == playbackVolumeControlId
+ ) {
return
}
playbackType = newPlaybackType
+ playbackVolumeControlId = newPlaybackVolumeControlId
updateCurrent()
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselController.kt
index 0aa434976ce7..1e9a466ccdce 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselController.kt
@@ -67,6 +67,7 @@ import com.android.systemui.util.concurrency.DelayableExecutor
import com.android.systemui.util.time.SystemClock
import com.android.systemui.util.traceSection
import java.io.PrintWriter
+import java.util.Locale
import java.util.TreeMap
import javax.inject.Inject
import javax.inject.Provider
@@ -166,6 +167,8 @@ constructor(
}
}
+ private var carouselLocale: Locale? = null
+
/** Whether the media card currently has the "expanded" layout */
@VisibleForTesting
var currentlyExpanded = true
@@ -218,6 +221,15 @@ constructor(
updatePlayers(recreateMedia = false)
inflateSettingsButton()
}
+
+ override fun onLocaleListChanged() {
+ // Update players only if system primary language changes.
+ if (carouselLocale != context.resources.configuration.locales.get(0)) {
+ carouselLocale = context.resources.configuration.locales.get(0)
+ updatePlayers(recreateMedia = true)
+ inflateSettingsButton()
+ }
+ }
}
private val keyguardUpdateMonitorCallback =
@@ -262,6 +274,7 @@ constructor(
this::logSmartspaceImpression,
logger
)
+ carouselLocale = context.resources.configuration.locales.get(0)
isRtl = context.resources.configuration.layoutDirection == View.LAYOUT_DIRECTION_RTL
inflateSettingsButton()
mediaContent = mediaCarousel.requireViewById(R.id.media_carousel)
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
index 9ebc8e410013..8e014c61c641 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
@@ -126,10 +126,11 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback,
private final LocalBluetoothManager mLocalBluetoothManager;
private final ActivityStarter mActivityStarter;
private final DialogLaunchAnimator mDialogLaunchAnimator;
- private final List<MediaDevice> mGroupMediaDevices = new CopyOnWriteArrayList<>();
private final CommonNotifCollection mNotifCollection;
private final Object mMediaDevicesLock = new Object();
@VisibleForTesting
+ final List<MediaDevice> mGroupMediaDevices = new CopyOnWriteArrayList<>();
+ @VisibleForTesting
final List<MediaDevice> mMediaDevices = new CopyOnWriteArrayList<>();
final List<MediaDevice> mCachedMediaDevices = new CopyOnWriteArrayList<>();
private final List<MediaItem> mMediaItemList = new CopyOnWriteArrayList<>();
@@ -713,7 +714,7 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback,
dividerItems.forEach((key, item) -> {
finalMediaItems.add(key, item);
});
- finalMediaItems.add(new MediaItem());
+ attachConnectNewDeviceItemIfNeeded(finalMediaItems);
mMediaItemList.clear();
mMediaItemList.addAll(finalMediaItems);
}
@@ -749,7 +750,7 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback,
finalMediaItems.add(new MediaItem(device));
}
}
- finalMediaItems.add(new MediaItem());
+ attachConnectNewDeviceItemIfNeeded(finalMediaItems);
mMediaItemList.clear();
mMediaItemList.addAll(finalMediaItems);
}
@@ -760,6 +761,13 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback,
new MediaItem(title, MediaItem.MediaItemType.TYPE_GROUP_DIVIDER));
}
+ private void attachConnectNewDeviceItemIfNeeded(List<MediaItem> mediaItems) {
+ // Attach "Connect a device" item only when current output is not remote and not a group
+ if (!isCurrentConnectedDeviceRemote() && getSelectedMediaDevice().size() == 1) {
+ mediaItems.add(new MediaItem());
+ }
+ }
+
private void attachRangeInfo(List<MediaDevice> devices) {
for (MediaDevice mediaDevice : devices) {
if (mNearbyDeviceInfoMap.containsKey(mediaDevice.getId())) {
@@ -1251,7 +1259,8 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback,
return null;
}
- private final MediaController.Callback mCb = new MediaController.Callback() {
+ @VisibleForTesting
+ final MediaController.Callback mCb = new MediaController.Callback() {
@Override
public void onMetadataChanged(MediaMetadata metadata) {
mCallback.onMediaChanged();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTile.java
index f16f0dcc5dba..ffe5489d656f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTile.java
@@ -458,13 +458,28 @@ public class InternetTile extends QSTileImpl<SignalState> {
getTileSpec(), mLastTileState, arg == null ? "null" : arg.toString());
if (arg instanceof CellularCallbackInfo) {
mLastTileState = LAST_STATE_CELLULAR;
- handleUpdateCellularState(state, arg);
+ CellularCallbackInfo cb = (CellularCallbackInfo) arg;
+ CellularCallbackInfo cellularInfo = new CellularCallbackInfo();
+ synchronized (cb) {
+ cb.copyTo(cellularInfo);
+ }
+ handleUpdateCellularState(state, cellularInfo);
} else if (arg instanceof WifiCallbackInfo) {
mLastTileState = LAST_STATE_WIFI;
- handleUpdateWifiState(state, arg);
+ WifiCallbackInfo cb = (WifiCallbackInfo) arg;
+ WifiCallbackInfo wifiInfo = new WifiCallbackInfo();
+ synchronized (cb) {
+ cb.copyTo(wifiInfo);
+ }
+ handleUpdateWifiState(state, wifiInfo);
} else if (arg instanceof EthernetCallbackInfo) {
mLastTileState = LAST_STATE_ETHERNET;
- handleUpdateEthernetState(state, arg);
+ EthernetCallbackInfo cb = (EthernetCallbackInfo) arg;
+ EthernetCallbackInfo ethernetInfo = new EthernetCallbackInfo();
+ synchronized (cb) {
+ cb.copyTo(ethernetInfo);
+ }
+ handleUpdateEthernetState(state, ethernetInfo);
} else {
// handleUpdateState will be triggered when user expands the QuickSetting panel with
// arg = null, in this case the last updated CellularCallbackInfo or WifiCallbackInfo
@@ -476,11 +491,11 @@ public class InternetTile extends QSTileImpl<SignalState> {
}
handleUpdateCellularState(state, cellularInfo);
} else if (mLastTileState == LAST_STATE_WIFI) {
- WifiCallbackInfo mifiInfo = new WifiCallbackInfo();
+ WifiCallbackInfo wifiInfo = new WifiCallbackInfo();
synchronized (mSignalCallback.mWifiInfo) {
- mSignalCallback.mWifiInfo.copyTo(mifiInfo);
+ mSignalCallback.mWifiInfo.copyTo(wifiInfo);
}
- handleUpdateWifiState(state, mifiInfo);
+ handleUpdateWifiState(state, wifiInfo);
} else if (mLastTileState == LAST_STATE_ETHERNET) {
EthernetCallbackInfo ethernetInfo = new EthernetCallbackInfo();
synchronized (mSignalCallback.mEthernetInfo) {
@@ -667,11 +682,16 @@ public class InternetTile extends QSTileImpl<SignalState> {
}
@Override
+ @NonNull
public Drawable getDrawable(Context context) {
SignalDrawable d = new SignalDrawable(context);
d.setLevel(getState());
return d;
}
+ @Override
+ public String toString() {
+ return String.format("SignalIcon[mState=0x%08x]", mState);
+ }
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ActionIntentExecutor.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ActionIntentExecutor.kt
index aa8e2c039684..187019a4851d 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ActionIntentExecutor.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ActionIntentExecutor.kt
@@ -154,5 +154,5 @@ private val SCREENSHOT_REMOTE_RUNNER: IRemoteAnimationRunner.Stub =
}
}
- override fun onAnimationCancelled(isKeyguardOccluded: Boolean) {}
+ override fun onAnimationCancelled() {}
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
index c9d1da38b196..77a65b22a7f4 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
@@ -150,7 +150,7 @@ public class ScreenshotController {
}
@Override
- public void onAnimationCancelled(boolean isKeyguardOccluded) {
+ public void onAnimationCancelled() {
}
};
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelView.java
index 1cdacb93ba45..af3cc860df57 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelView.java
@@ -27,9 +27,6 @@ import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.FrameLayout;
-import com.android.systemui.R;
-import com.android.systemui.statusbar.phone.TapAgainView;
-
/** The shade view. */
public final class NotificationPanelView extends FrameLayout {
static final boolean DEBUG = false;
@@ -93,10 +90,6 @@ public final class NotificationPanelView extends FrameLayout {
mRtlChangeListener = listener;
}
- public TapAgainView getTapAgainView() {
- return findViewById(R.id.shade_falsing_tap_again);
- }
-
/** Sets the touch handler for this view. */
public void setOnTouchListener(NotificationPanelViewController.TouchHandler touchHandler) {
super.setOnTouchListener(touchHandler);
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
index ebbf1b5ac7c9..7cc257ba0a97 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
@@ -163,6 +163,7 @@ public class NotificationShadeWindowViewController {
mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
mStatusBarWindowStateController = statusBarWindowStateController;
mLockIconViewController = lockIconViewController;
+ mLockIconViewController.init();
mService = centralSurfaces;
mNotificationShadeWindowController = controller;
mKeyguardUnlockAnimationController = keyguardUnlockAnimationController;
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeModule.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeModule.kt
index 4c6673cca473..9cd8c547d1c1 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeModule.kt
@@ -17,6 +17,7 @@
package com.android.systemui.shade
import android.view.LayoutInflater
+import com.android.keyguard.LockIconView
import com.android.systemui.CoreStartable
import com.android.systemui.R
import com.android.systemui.biometrics.AuthRippleController
@@ -24,6 +25,7 @@ import com.android.systemui.biometrics.AuthRippleView
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.statusbar.LightRevealScrim
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout
+import com.android.systemui.statusbar.phone.TapAgainView
import dagger.Binds
import dagger.Module
import dagger.Provides
@@ -89,5 +91,23 @@ abstract class ShadeModule {
): AuthRippleView? {
return notificationShadeWindowView.findViewById(R.id.auth_ripple)
}
+
+ // TODO(b/277762009): Only allow this view's controller to inject the view. See above.
+ @Provides
+ @SysUISingleton
+ fun providesLockIconView(
+ notificationShadeWindowView: NotificationShadeWindowView,
+ ): LockIconView {
+ return notificationShadeWindowView.findViewById(R.id.lock_icon_view)
+ }
+
+ // TODO(b/277762009): Only allow this view's controller to inject the view. See above.
+ @Provides
+ @SysUISingleton
+ fun providesTapAgainView(
+ notificationPanelView: NotificationPanelView,
+ ): TapAgainView {
+ return notificationPanelView.findViewById(R.id.shade_falsing_tap_again)
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
index cac4251bce63..e6e3e7e4fe4c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar;
import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED;
+
import static com.android.systemui.DejankUtils.whitelistIpcs;
import android.app.KeyguardManager;
@@ -47,6 +48,8 @@ import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dump.DumpManager;
+import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.flags.Flags;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
import com.android.systemui.recents.OverviewProxyService;
@@ -59,14 +62,14 @@ import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.ListenerSet;
import com.android.systemui.util.settings.SecureSettings;
+import dagger.Lazy;
+
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
-import dagger.Lazy;
-
/**
* Handles keeping track of the current user, profiles, and various things related to hiding
* contents, redacting notifications, and the lockscreen.
@@ -99,7 +102,7 @@ public class NotificationLockscreenUserManagerImpl implements
private final BroadcastDispatcher mBroadcastDispatcher;
private final NotificationClickNotifier mClickNotifier;
private final Lazy<OverviewProxyService> mOverviewProxyServiceLazy;
-
+ private final FeatureFlags mFeatureFlags;
private boolean mShowLockscreenNotifications;
private boolean mAllowLockscreenRemoteInput;
private LockPatternUtils mLockPatternUtils;
@@ -174,6 +177,21 @@ public class NotificationLockscreenUserManagerImpl implements
new UserTracker.Callback() {
@Override
public void onUserChanged(int newUser, @NonNull Context userContext) {
+ if (!mFeatureFlags.isEnabled(
+ Flags.LOAD_NOTIFICATIONS_BEFORE_THE_USER_SWITCH_IS_COMPLETE)) {
+ handleUserChange(newUser);
+ }
+ }
+
+ @Override
+ public void onUserChanging(int newUser, @NonNull Context userContext) {
+ if (mFeatureFlags.isEnabled(
+ Flags.LOAD_NOTIFICATIONS_BEFORE_THE_USER_SWITCH_IS_COMPLETE)) {
+ handleUserChange(newUser);
+ }
+ }
+
+ private void handleUserChange(int newUser) {
mCurrentUserId = newUser;
updateCurrentProfilesCache();
@@ -216,7 +234,8 @@ public class NotificationLockscreenUserManagerImpl implements
KeyguardStateController keyguardStateController,
SecureSettings secureSettings,
DumpManager dumpManager,
- LockPatternUtils lockPatternUtils) {
+ LockPatternUtils lockPatternUtils,
+ FeatureFlags featureFlags) {
mContext = context;
mMainHandler = mainHandler;
mDevicePolicyManager = devicePolicyManager;
@@ -234,6 +253,7 @@ public class NotificationLockscreenUserManagerImpl implements
mDeviceProvisionedController = deviceProvisionedController;
mSecureSettings = secureSettings;
mKeyguardStateController = keyguardStateController;
+ mFeatureFlags = featureFlags;
dumpManager.registerDumpable(this);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/RemoteInputController.java b/packages/SystemUI/src/com/android/systemui/statusbar/RemoteInputController.java
index a37b2a9e530a..58d705417632 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/RemoteInputController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/RemoteInputController.java
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar;
+import android.annotation.Nullable;
import android.app.Notification;
import android.app.RemoteInput;
import android.content.Context;
@@ -55,6 +56,13 @@ public class RemoteInputController {
private final RemoteInputControllerLogger mLogger;
+ /**
+ * RemoteInput Active's last emitted value. It's added for debugging purpose to directly see
+ * its last emitted value. As RemoteInputController holds weak reference, isRemoteInputActive
+ * in dump may not reflect the last emitted value of Active.
+ */
+ @Nullable private Boolean mLastAppliedRemoteInputActive = null;
+
public RemoteInputController(Delegate delegate,
RemoteInputUriController remoteInputUriController,
RemoteInputControllerLogger logger) {
@@ -217,6 +225,7 @@ public class RemoteInputController {
for (int i = 0; i < N; i++) {
mCallbacks.get(i).onRemoteInputActive(remoteInputActive);
}
+ mLastAppliedRemoteInputActive = remoteInputActive;
}
/**
@@ -323,6 +332,8 @@ public class RemoteInputController {
/** dump debug info; called by {@link NotificationRemoteInputManager} */
public void dump(@NonNull IndentingPrintWriter pw) {
+ pw.print("mLastAppliedRemoteInputActive: ");
+ pw.println((Object) mLastAppliedRemoteInputActive);
pw.print("isRemoteInputActive: ");
pw.println(isRemoteInputActive()); // Note that this prunes the mOpen list, printed later.
pw.println("mOpen: " + mOpen.size());
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
index aa5aed7451f8..263566e69c88 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -1662,7 +1662,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
mShadeController.setNotificationPanelViewController(npvc);
mShadeController.setNotificationShadeWindowViewController(
mNotificationShadeWindowViewController);
- mCentralSurfacesComponent.getLockIconViewController().init();
mStackScrollerController =
mCentralSurfacesComponent.getNotificationStackScrollLayoutController();
mQsController = mCentralSurfacesComponent.getQuickSettingsController();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt
index c17366ad242c..74ab47ff27a1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt
@@ -115,7 +115,9 @@ class KeyguardLiftController @Inject constructor(
val onKeyguard = keyguardUpdateMonitor.isKeyguardVisible &&
!statusBarStateController.isDozing
- val shouldListen = (onKeyguard || bouncerVisible) && keyguardUpdateMonitor.isFaceEnrolled
+ val userId = KeyguardUpdateMonitor.getCurrentUser()
+ val isFaceEnabled = keyguardUpdateMonitor.isFaceAuthEnabledForUser(userId)
+ val shouldListen = (onKeyguard || bouncerVisible) && isFaceEnabled
if (shouldListen != isListening) {
isListening = shouldListen
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/TapAgainViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/TapAgainViewController.java
index 582afb1a23ea..a0f12161b85a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/TapAgainViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/TapAgainViewController.java
@@ -19,8 +19,8 @@ package com.android.systemui.statusbar.phone;
import static com.android.systemui.classifier.FalsingModule.DOUBLE_TAP_TIMEOUT_MS;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
import com.android.systemui.util.ViewController;
@@ -32,7 +32,7 @@ import javax.inject.Named;
/**
* Controller for {@link TapAgainView}.
*/
-@CentralSurfacesComponent.CentralSurfacesScope
+@SysUISingleton
public class TapAgainViewController extends ViewController<TapAgainView> {
private final DelayableExecutor mDelayableExecutor;
private final ConfigurationController mConfigurationController;
@@ -84,7 +84,7 @@ public class TapAgainViewController extends ViewController<TapAgainView> {
}
/** Hides the associated view, possibly animating it. */
- public void hide() {
+ private void hide() {
mHideCanceler = null;
mView.animateOut();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java
index ddb6d93e3c4e..273e78350f27 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java
@@ -20,8 +20,6 @@ import static com.android.systemui.statusbar.phone.dagger.StatusBarViewModule.ST
import static java.lang.annotation.RetentionPolicy.RUNTIME;
-import com.android.keyguard.LockIconViewController;
-import com.android.systemui.biometrics.AuthRippleController;
import com.android.systemui.shade.NotificationPanelViewController;
import com.android.systemui.shade.NotificationShadeWindowView;
import com.android.systemui.shade.NotificationShadeWindowViewController;
@@ -107,11 +105,6 @@ public interface CentralSurfacesComponent {
QuickSettingsController getQuickSettingsController();
/**
- * Creates a LockIconViewController. Must be init after creation.
- */
- LockIconViewController getLockIconViewController();
-
- /**
* Creates a StatusBarHeadsUpChangeListener.
*/
StatusBarHeadsUpChangeListener getStatusBarHeadsUpChangeListener();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java
index 1a943e79a79b..2c57a268f6b8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java
@@ -16,7 +16,6 @@
package com.android.systemui.statusbar.phone.dagger;
-import android.annotation.Nullable;
import android.content.ContentResolver;
import android.os.Handler;
import android.view.LayoutInflater;
@@ -25,7 +24,6 @@ import android.view.ViewStub;
import androidx.constraintlayout.motion.widget.MotionLayout;
import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.keyguard.LockIconView;
import com.android.systemui.R;
import com.android.systemui.battery.BatteryMeterView;
import com.android.systemui.battery.BatteryMeterViewController;
@@ -63,7 +61,6 @@ import com.android.systemui.statusbar.phone.StatusBarIconController;
import com.android.systemui.statusbar.phone.StatusBarLocationPublisher;
import com.android.systemui.statusbar.phone.StatusIconContainer;
import com.android.systemui.statusbar.phone.SystemBarAttributesListener;
-import com.android.systemui.statusbar.phone.TapAgainView;
import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragment;
import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragmentLogger;
import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentComponent;
@@ -139,15 +136,6 @@ public abstract class StatusBarViewModule {
abstract ShadeViewController bindsShadeViewController(
NotificationPanelViewController notificationPanelViewController);
- /** */
- @Provides
- @CentralSurfacesComponent.CentralSurfacesScope
- public static LockIconView getLockIconView(
- NotificationShadeWindowView notificationShadeWindowView) {
- return notificationShadeWindowView.findViewById(R.id.lock_icon_view);
- }
-
- /** */
@Provides
@Named(SHADE_HEADER)
@CentralSurfacesComponent.CentralSurfacesScope
@@ -221,13 +209,6 @@ public abstract class StatusBarViewModule {
/** */
@Provides
@CentralSurfacesComponent.CentralSurfacesScope
- public static TapAgainView getTapAgainView(NotificationPanelView npv) {
- return npv.getTapAgainView();
- }
-
- /** */
- @Provides
- @CentralSurfacesComponent.CentralSurfacesScope
public static NotificationsQuickSettingsContainer getNotificationsQuickSettingsContainer(
NotificationShadeWindowView notificationShadeWindowView) {
return notificationShadeWindowView.findViewById(R.id.notification_container_parent);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java
index 3d811cfc901d..673819b20e4b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java
@@ -240,7 +240,7 @@ public class KeyguardStateControllerImpl implements KeyguardStateController, Dum
|| (Build.IS_DEBUGGABLE && DEBUG_AUTH_WITH_ADB && mDebugUnlocked);
boolean trustManaged = mKeyguardUpdateMonitor.getUserTrustIsManaged(user);
boolean trusted = mKeyguardUpdateMonitor.getUserHasTrust(user);
- boolean faceAuthEnabled = mKeyguardUpdateMonitor.isFaceEnrolled();
+ boolean faceAuthEnabled = mKeyguardUpdateMonitor.isFaceAuthEnabledForUser(user);
boolean changed = secure != mSecure || canDismissLockScreen != mCanDismissLockScreen
|| trustManaged != mTrustManaged || mTrusted != trusted
|| mFaceAuthEnabled != faceAuthEnabled;
diff --git a/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserInteractor.kt b/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserInteractor.kt
index 0ec1a214660c..c2922c4d6f34 100644
--- a/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserInteractor.kt
@@ -26,6 +26,7 @@ import android.content.IntentFilter
import android.content.pm.UserInfo
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
+import android.graphics.drawable.Icon
import android.os.RemoteException
import android.os.UserHandle
import android.os.UserManager
@@ -762,8 +763,18 @@ constructor(
}
// TODO(b/246631653): cache the bitmaps to avoid the background work to fetch them.
- // TODO(b/246631653): downscale the bitmaps to R.dimen.max_avatar_size if requested.
- val userIcon = withContext(backgroundDispatcher) { manager.getUserIcon(userId) }
+ val userIcon = withContext(backgroundDispatcher) {
+ manager.getUserIcon(userId)
+ ?.let { bitmap ->
+ val iconSize =
+ applicationContext
+ .resources
+ .getDimensionPixelSize(R.dimen.bouncer_user_switcher_icon_size)
+ Icon.scaleDownIfNecessary(bitmap, iconSize, iconSize)
+ }
+ }
+
+
if (userIcon != null) {
return BitmapDrawable(userIcon)
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index 71246c994bfa..2962c14b813a 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -383,7 +383,6 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
}
private void setupFingerprintAuth(boolean isClass3) throws RemoteException {
- when(mAuthController.isFingerprintEnrolled(anyInt())).thenReturn(true);
when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
when(mFingerprintManager.hasEnrolledTemplates(anyInt())).thenReturn(true);
mFingerprintSensorProperties = List.of(
@@ -2693,42 +2692,33 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
}
@Test
public void testFingerprintSensorProperties() throws RemoteException {
- // GIVEN no fingerprint sensor properties
- when(mAuthController.isFingerprintEnrolled(anyInt())).thenReturn(true);
mFingerprintAuthenticatorsRegisteredCallback.onAllAuthenticatorsRegistered(
new ArrayList<>());
- // THEN fingerprint is not possible
assertThat(mKeyguardUpdateMonitor.isUnlockWithFingerprintPossible(
KeyguardUpdateMonitor.getCurrentUser())).isFalse();
- // WHEN there are fingerprint sensor properties
mFingerprintAuthenticatorsRegisteredCallback
.onAllAuthenticatorsRegistered(mFingerprintSensorProperties);
- // THEN unlock with fp is possible & fingerprint starts listening
+ verifyFingerprintAuthenticateCall();
assertThat(mKeyguardUpdateMonitor.isUnlockWithFingerprintPossible(
KeyguardUpdateMonitor.getCurrentUser())).isTrue();
- verifyFingerprintAuthenticateCall();
}
@Test
public void testFaceSensorProperties() throws RemoteException {
- // GIVEN no face sensor properties
- when(mAuthController.isFaceAuthEnrolled(anyInt())).thenReturn(true);
mFaceAuthenticatorsRegisteredCallback.onAllAuthenticatorsRegistered(new ArrayList<>());
- // THEN face is not possible
- assertThat(mKeyguardUpdateMonitor.isUnlockWithFacePossible(
+ assertThat(mKeyguardUpdateMonitor.isFaceAuthEnabledForUser(
KeyguardUpdateMonitor.getCurrentUser())).isFalse();
- // WHEN there are face sensor properties
mFaceAuthenticatorsRegisteredCallback.onAllAuthenticatorsRegistered(mFaceSensorProperties);
+ biometricsEnabledForCurrentUser();
- // THEN face is possible but face does NOT start listening immediately
- assertThat(mKeyguardUpdateMonitor.isUnlockWithFacePossible(
- KeyguardUpdateMonitor.getCurrentUser())).isTrue();
verifyFaceAuthenticateNeverCalled();
verifyFaceDetectNeverCalled();
+ assertThat(mKeyguardUpdateMonitor.isFaceAuthEnabledForUser(
+ KeyguardUpdateMonitor.getCurrentUser())).isTrue();
}
@Test
@@ -2801,6 +2791,9 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
}
private void mockCanBypassLockscreen(boolean canBypass) {
+ // force update the isFaceEnrolled cache:
+ mKeyguardUpdateMonitor.isFaceAuthEnabledForUser(getCurrentUser());
+
mKeyguardUpdateMonitor.setKeyguardBypassController(mKeyguardBypassController);
when(mKeyguardBypassController.canBypass()).thenReturn(canBypass);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/OWNERS b/packages/SystemUI/tests/src/com/android/systemui/accessibility/OWNERS
new file mode 100644
index 000000000000..a2001e66e55b
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/view/accessibility/OWNERS \ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/SystemActionsTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/SystemActionsTest.java
new file mode 100644
index 000000000000..025c88c36203
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/SystemActionsTest.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.accessibility;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.hardware.input.InputManager;
+import android.os.RemoteException;
+import android.telecom.TelecomManager;
+import android.telephony.TelephonyManager;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.view.KeyEvent;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.recents.Recents;
+import com.android.systemui.settings.FakeDisplayTracker;
+import com.android.systemui.settings.UserTracker;
+import com.android.systemui.shade.ShadeController;
+import com.android.systemui.statusbar.NotificationShadeWindowController;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
+
+import dagger.Lazy;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+@TestableLooper.RunWithLooper
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+public class SystemActionsTest extends SysuiTestCase {
+ @Mock
+ private UserTracker mUserTracker;
+ @Mock
+ private NotificationShadeWindowController mNotificationShadeController;
+ @Mock
+ private ShadeController mShadeController;
+ @Mock
+ private Lazy<Optional<CentralSurfaces>> mCentralSurfacesOptionalLazy;
+ @Mock
+ private Optional<Recents> mRecentsOptional;
+ @Mock
+ private TelecomManager mTelecomManager;
+ @Mock
+ private InputManager mInputManager;
+ private final FakeDisplayTracker mDisplayTracker = new FakeDisplayTracker(mContext);
+
+ private SystemActions mSystemActions;
+
+ @Before
+ public void setUp() throws RemoteException {
+ MockitoAnnotations.initMocks(this);
+ mContext.addMockSystemService(TelecomManager.class, mTelecomManager);
+ mContext.addMockSystemService(InputManager.class, mInputManager);
+ mSystemActions = new SystemActions(mContext, mUserTracker, mNotificationShadeController,
+ mShadeController, mCentralSurfacesOptionalLazy, mRecentsOptional, mDisplayTracker);
+ }
+
+ @Test
+ public void handleHeadsetHook_callStateIdle_injectsKeyEvents() {
+ when(mTelecomManager.getCallState()).thenReturn(TelephonyManager.CALL_STATE_IDLE);
+ // Use a custom doAnswer captor that copies the KeyEvent before storing it, because the
+ // method under test modifies the event object after injecting it which prevents
+ // reliably asserting on the event properties.
+ final List<KeyEvent> keyEvents = new ArrayList<>();
+ doAnswer(invocation -> {
+ keyEvents.add(new KeyEvent(invocation.getArgument(0)));
+ return null;
+ }).when(mInputManager).injectInputEvent(any(), anyInt());
+
+ mSystemActions.handleHeadsetHook();
+
+ assertThat(keyEvents.size()).isEqualTo(2);
+ assertThat(keyEvents.get(0).getKeyCode()).isEqualTo(KeyEvent.KEYCODE_HEADSETHOOK);
+ assertThat(keyEvents.get(0).getAction()).isEqualTo(KeyEvent.ACTION_DOWN);
+ assertThat(keyEvents.get(1).getKeyCode()).isEqualTo(KeyEvent.KEYCODE_HEADSETHOOK);
+ assertThat(keyEvents.get(1).getAction()).isEqualTo(KeyEvent.ACTION_UP);
+ }
+
+ @Test
+ public void handleHeadsetHook_callStateRinging_answersCall() {
+ when(mTelecomManager.getCallState()).thenReturn(TelephonyManager.CALL_STATE_RINGING);
+
+ mSystemActions.handleHeadsetHook();
+
+ verify(mTelecomManager).acceptRingingCall();
+ }
+
+ @Test
+ public void handleHeadsetHook_callStateOffhook_endsCall() {
+ when(mTelecomManager.getCallState()).thenReturn(TelephonyManager.CALL_STATE_OFFHOOK);
+
+ mSystemActions.handleHeadsetHook();
+
+ verify(mTelecomManager).endCall();
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt
index 578e1d4d02ce..cc004363a049 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt
@@ -159,22 +159,11 @@ class ActivityLaunchAnimatorTest : SysuiTestCase() {
@Test
fun doesNotStartIfAnimationIsCancelled() {
val runner = activityLaunchAnimator.createRunner(controller)
- runner.onAnimationCancelled(false /* isKeyguardOccluded */)
+ runner.onAnimationCancelled()
runner.onAnimationStart(0, emptyArray(), emptyArray(), emptyArray(), iCallback)
waitForIdleSync()
- verify(controller).onLaunchAnimationCancelled(false /* newKeyguardOccludedState */)
- verify(controller, never()).onLaunchAnimationStart(anyBoolean())
- }
-
- @Test
- fun passesOccludedStateToLaunchAnimationCancelled_ifTrue() {
- val runner = activityLaunchAnimator.createRunner(controller)
- runner.onAnimationCancelled(true /* isKeyguardOccluded */)
- runner.onAnimationStart(0, emptyArray(), emptyArray(), emptyArray(), iCallback)
-
- waitForIdleSync()
- verify(controller).onLaunchAnimationCancelled(true /* newKeyguardOccludedState */)
+ verify(controller).onLaunchAnimationCancelled()
verify(controller, never()).onLaunchAnimationStart(anyBoolean())
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsBindingControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsBindingControllerImplTest.kt
index ebbe096b0da3..26cbd7703075 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsBindingControllerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsBindingControllerImplTest.kt
@@ -41,11 +41,11 @@ import org.mockito.ArgumentCaptor
import org.mockito.Captor
import org.mockito.Mock
import org.mockito.Mockito
-import org.mockito.Mockito.`when`
import org.mockito.Mockito.mock
import org.mockito.Mockito.never
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when`
import org.mockito.MockitoAnnotations
@SmallTest
@@ -378,7 +378,13 @@ class TestableControlsBindingControllerImpl(
executor: DelayableExecutor,
lazyController: Lazy<ControlsController>,
userTracker: UserTracker
-) : ControlsBindingControllerImpl(context, executor, lazyController, userTracker) {
+) : ControlsBindingControllerImpl(
+ context,
+ executor,
+ lazyController,
+ mock(PackageUpdateMonitor.Factory::class.java),
+ userTracker
+) {
companion object {
val providers = mutableListOf<ControlsProviderLifecycleManager>()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManagerTest.kt
index da548f7ccef2..b5d34768dc9f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManagerTest.kt
@@ -30,6 +30,10 @@ import android.testing.AndroidTestingRunner
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.util.concurrency.FakeExecutor
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.argumentCaptor
+import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.mockito.mock
import com.android.systemui.util.time.FakeSystemClock
import org.junit.After
import org.junit.Assert.assertEquals
@@ -39,17 +43,17 @@ import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
-import org.mockito.ArgumentMatchers
-import org.mockito.ArgumentMatchers.any
import org.mockito.ArgumentMatchers.anyString
-import org.mockito.ArgumentMatchers.eq
import org.mockito.Captor
import org.mockito.Mock
-import org.mockito.Mockito.`when`
import org.mockito.Mockito.anyInt
-import org.mockito.Mockito.mock
+import org.mockito.Mockito.clearInvocations
+import org.mockito.Mockito.inOrder
import org.mockito.Mockito.never
+import org.mockito.Mockito.times
import org.mockito.Mockito.verify
+import org.mockito.Mockito.verifyNoMoreInteractions
+import org.mockito.Mockito.`when`
import org.mockito.MockitoAnnotations
@SmallTest
@@ -62,16 +66,21 @@ class ControlsProviderLifecycleManagerTest : SysuiTestCase() {
private lateinit var subscriberService: IControlsSubscriber.Stub
@Mock
private lateinit var service: IControlsProvider.Stub
-
+ @Mock
+ private lateinit var packageUpdateMonitor: PackageUpdateMonitor
@Captor
private lateinit var wrapperCaptor: ArgumentCaptor<ControlActionWrapper>
+ private lateinit var packageUpdateMonitorFactory: FakePackageUpdateMonitorFactory
+
private val componentName = ComponentName("test.pkg", "test.cls")
private lateinit var manager: ControlsProviderLifecycleManager
private lateinit var executor: FakeExecutor
+ private lateinit var fakeSystemClock: FakeSystemClock
companion object {
fun <T> capture(argumentCaptor: ArgumentCaptor<T>): T = argumentCaptor.capture()
+ private val USER = UserHandle.of(0)
}
@Before
@@ -79,16 +88,20 @@ class ControlsProviderLifecycleManagerTest : SysuiTestCase() {
MockitoAnnotations.initMocks(this)
context.addMockService(componentName, service)
- executor = FakeExecutor(FakeSystemClock())
+ fakeSystemClock = FakeSystemClock()
+ executor = FakeExecutor(fakeSystemClock)
`when`(service.asBinder()).thenCallRealMethod()
- `when`(service.queryLocalInterface(ArgumentMatchers.anyString())).thenReturn(service)
+ `when`(service.queryLocalInterface(anyString())).thenReturn(service)
+
+ packageUpdateMonitorFactory = FakePackageUpdateMonitorFactory(packageUpdateMonitor)
manager = ControlsProviderLifecycleManager(
context,
executor,
actionCallbackService,
- UserHandle.of(0),
- componentName
+ USER,
+ componentName,
+ packageUpdateMonitorFactory,
)
}
@@ -122,7 +135,7 @@ class ControlsProviderLifecycleManagerTest : SysuiTestCase() {
@Test
fun testNullBinding() {
- val mockContext = mock(Context::class.java)
+ val mockContext = mock<Context>()
lateinit var serviceConnection: ServiceConnection
`when`(mockContext.bindServiceAsUser(any(), any(), anyInt(), any())).thenAnswer {
val component = (it.arguments[0] as Intent).component
@@ -139,8 +152,9 @@ class ControlsProviderLifecycleManagerTest : SysuiTestCase() {
mockContext,
executor,
actionCallbackService,
- UserHandle.of(0),
- componentName
+ USER,
+ componentName,
+ packageUpdateMonitorFactory,
)
nullManager.bindService()
@@ -229,14 +243,15 @@ class ControlsProviderLifecycleManagerTest : SysuiTestCase() {
@Test
fun testFalseBindCallsUnbind() {
- val falseContext = mock(Context::class.java)
+ val falseContext = mock<Context>()
`when`(falseContext.bindServiceAsUser(any(), any(), anyInt(), any())).thenReturn(false)
val manager = ControlsProviderLifecycleManager(
falseContext,
executor,
actionCallbackService,
- UserHandle.of(0),
- componentName
+ USER,
+ componentName,
+ packageUpdateMonitorFactory,
)
manager.bindService()
executor.runAllReady()
@@ -247,4 +262,150 @@ class ControlsProviderLifecycleManagerTest : SysuiTestCase() {
verify(falseContext).bindServiceAsUser(any(), captor.capture(), anyInt(), any())
verify(falseContext).unbindService(captor.value)
}
+
+ @Test
+ fun testPackageUpdateMonitor_createdWithCorrectValues() {
+ assertEquals(USER, packageUpdateMonitorFactory.lastUser)
+ assertEquals(componentName.packageName, packageUpdateMonitorFactory.lastPackage)
+ }
+
+ @Test
+ fun testBound_packageMonitorStartsMonitoring() {
+ manager.bindService()
+ executor.runAllReady()
+
+ // Service will connect and monitoring should start
+ verify(packageUpdateMonitor).startMonitoring()
+ }
+
+ @Test
+ fun testOnPackageUpdateWhileBound_unbound_thenBindAgain() {
+ val mockContext = mock<Context> {
+ `when`(bindServiceAsUser(any(), any(), anyInt(), any())).thenReturn(true)
+ }
+
+ val manager = ControlsProviderLifecycleManager(
+ mockContext,
+ executor,
+ actionCallbackService,
+ USER,
+ componentName,
+ packageUpdateMonitorFactory,
+ )
+
+ manager.bindService()
+ executor.runAllReady()
+ clearInvocations(mockContext)
+
+ packageUpdateMonitorFactory.lastCallback?.run()
+ executor.runAllReady()
+
+ val inOrder = inOrder(mockContext)
+ inOrder.verify(mockContext).unbindService(any())
+ inOrder.verify(mockContext).bindServiceAsUser(any(), any(), anyInt(), any())
+ }
+
+ @Test
+ fun testOnPackageUpdateWhenNotBound_nothingHappens() {
+ val mockContext = mock<Context> {
+ `when`(bindServiceAsUser(any(), any(), anyInt(), any())).thenReturn(true)
+ }
+
+ ControlsProviderLifecycleManager(
+ mockContext,
+ executor,
+ actionCallbackService,
+ USER,
+ componentName,
+ packageUpdateMonitorFactory,
+ )
+
+ packageUpdateMonitorFactory.lastCallback?.run()
+ verifyNoMoreInteractions(mockContext)
+ }
+
+ @Test
+ fun testUnbindService_stopsTracking() {
+ manager.bindService()
+ manager.unbindService()
+ executor.runAllReady()
+
+ verify(packageUpdateMonitor).stopMonitoring()
+ }
+
+ @Test
+ fun testRebindForPanelWithSameFlags() {
+ val mockContext = mock<Context> {
+ `when`(bindServiceAsUser(any(), any(), anyInt(), any())).thenReturn(true)
+ }
+
+ val manager = ControlsProviderLifecycleManager(
+ mockContext,
+ executor,
+ actionCallbackService,
+ USER,
+ componentName,
+ packageUpdateMonitorFactory,
+ )
+
+ manager.bindServiceForPanel()
+ executor.runAllReady()
+
+ val flagsCaptor = argumentCaptor<Int>()
+ verify(mockContext).bindServiceAsUser(any(), any(), capture(flagsCaptor), any())
+ clearInvocations(mockContext)
+
+ packageUpdateMonitorFactory.lastCallback?.run()
+ executor.runAllReady()
+
+ verify(mockContext).bindServiceAsUser(any(), any(), eq(flagsCaptor.value), any())
+ }
+
+ @Test
+ fun testBindAfterSecurityExceptionWorks() {
+ val mockContext = mock<Context> {
+ `when`(bindServiceAsUser(any(), any(), anyInt(), any()))
+ .thenThrow(SecurityException("exception"))
+ }
+
+ val manager = ControlsProviderLifecycleManager(
+ mockContext,
+ executor,
+ actionCallbackService,
+ USER,
+ componentName,
+ packageUpdateMonitorFactory,
+ )
+
+ manager.bindServiceForPanel()
+ executor.runAllReady()
+
+ `when`(mockContext.bindServiceAsUser(any(), any(), anyInt(), any())).thenReturn(true)
+
+ manager.bindServiceForPanel()
+ executor.runAllReady()
+
+ verify(mockContext, times(2)).bindServiceAsUser(any(), any(), anyInt(), any())
+ }
+
+ private class FakePackageUpdateMonitorFactory(
+ private val monitor: PackageUpdateMonitor
+ ) : PackageUpdateMonitor.Factory {
+
+ var lastUser: UserHandle? = null
+ var lastPackage: String? = null
+ var lastCallback: Runnable? = null
+
+ override fun create(
+ user: UserHandle,
+ packageName: String,
+ callback: Runnable
+ ): PackageUpdateMonitor {
+ lastUser = user
+ lastPackage = packageName
+ lastCallback = callback
+ return monitor
+ }
+ }
}
+
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/PackageUpdateMonitorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/PackageUpdateMonitorTest.kt
new file mode 100644
index 000000000000..69547105d419
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/PackageUpdateMonitorTest.kt
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.controls.controller
+
+import android.content.Context
+import android.os.Handler
+import android.os.UserHandle
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.mockito.mock
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.clearInvocations
+import org.mockito.Mockito.never
+import org.mockito.Mockito.times
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.verifyNoMoreInteractions
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class PackageUpdateMonitorTest : SysuiTestCase() {
+
+ @Mock private lateinit var context: Context
+ @Mock private lateinit var bgHandler: Handler
+
+ private lateinit var underTest: PackageUpdateMonitor
+
+ @Before
+ fun setup() {
+ MockitoAnnotations.initMocks(this)
+ }
+
+ @Test
+ fun startMonitoring_registerOnlyOnce() {
+ underTest = PackageUpdateMonitor(USER, PACKAGE, {}, bgHandler, context)
+
+ underTest.startMonitoring()
+ // There are two receivers registered
+ verify(context, times(2))
+ .registerReceiverAsUser(any(), eq(USER), any(), eq(null), eq(bgHandler))
+
+ underTest.startMonitoring()
+ verifyNoMoreInteractions(context)
+ }
+
+ @Test
+ fun stopMonitoring_unregistersOnlyOnce() {
+ underTest = PackageUpdateMonitor(USER, PACKAGE, {}, bgHandler, context)
+
+ underTest.startMonitoring()
+ clearInvocations(context)
+
+ underTest.stopMonitoring()
+ verify(context).unregisterReceiver(any())
+
+ underTest.stopMonitoring()
+ verifyNoMoreInteractions(context)
+ }
+
+ @Test
+ fun onPackageUpdated_correctPackageAndUser_callbackRuns() {
+ val callback = mock<Runnable>()
+
+ underTest = PackageUpdateMonitor(USER, PACKAGE, callback, bgHandler, context)
+
+ underTest.onPackageUpdateFinished(PACKAGE, UserHandle.getUid(USER.identifier, 10000))
+ verify(callback).run()
+ }
+
+ @Test
+ fun onPackageUpdated_correctPackage_wrongUser_callbackDoesntRun() {
+ val callback = mock<Runnable>()
+
+ underTest = PackageUpdateMonitor(USER, PACKAGE, callback, bgHandler, context)
+
+ underTest.onPackageUpdateFinished(PACKAGE, UserHandle.getUid(USER.identifier + 1, 10000))
+ verify(callback, never()).run()
+ }
+
+ @Test
+ fun onPackageUpdated_wrongPackage_correctUser_callbackDoesntRun() {
+ val callback = mock<Runnable>()
+
+ underTest = PackageUpdateMonitor(USER, PACKAGE, callback, bgHandler, context)
+
+ underTest.onPackageUpdateFinished("bad", UserHandle.getUid(USER.identifier + 1, 10000))
+ verify(callback, never()).run()
+ }
+
+ companion object {
+ private val USER = UserHandle.of(0)
+ private val PACKAGE = "pkg"
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/PanelTaskViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/PanelTaskViewControllerTest.kt
index f7c8ccaf731a..7840525b14aa 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/PanelTaskViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/PanelTaskViewControllerTest.kt
@@ -19,6 +19,7 @@ package com.android.systemui.controls.ui
import android.app.ActivityOptions
import android.app.PendingIntent
+import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK
@@ -90,6 +91,11 @@ class PanelTaskViewControllerTest : SysuiTestCase() {
}
@Test
+ fun testTaskViewStartsWithAlpha0() {
+ verify(taskView).alpha = 0f
+ }
+
+ @Test
fun testLaunchTaskViewAttachedListener() {
underTest.launchTaskView()
verify(taskView).setListener(eq(uiExecutor), any())
@@ -120,6 +126,16 @@ class PanelTaskViewControllerTest : SysuiTestCase() {
}
@Test
+ fun testOnTaskCreated_taskViewAlpha1() {
+ underTest.launchTaskView()
+ verify(taskView).setListener(any(), capture(listenerCaptor))
+
+ listenerCaptor.value.onTaskCreated(1, ComponentName("Test", "TEST"))
+
+ verify(taskView).alpha = 1f
+ }
+
+ @Test
fun testHideRunnableCalledWhenBackOnRoot() {
underTest.launchTaskView()
verify(taskView).setListener(any(), capture(listenerCaptor))
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayAnimationsControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayAnimationsControllerTest.kt
index b7c62463899f..039682c88498 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayAnimationsControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayAnimationsControllerTest.kt
@@ -24,6 +24,7 @@ import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
import org.mockito.Mock
import org.mockito.Mockito.anyLong
+import org.mockito.Mockito.atLeastOnce
import org.mockito.Mockito.eq
import org.mockito.Mockito.never
import org.mockito.Mockito.times
@@ -49,6 +50,7 @@ class DreamOverlayAnimationsControllerTest : SysuiTestCase() {
@Mock private lateinit var stateController: DreamOverlayStateController
@Mock private lateinit var configController: ConfigurationController
@Mock private lateinit var transitionViewModel: DreamingToLockscreenTransitionViewModel
+ @Mock private lateinit var logger: DreamLogger
private lateinit var controller: DreamOverlayAnimationsController
@Before
@@ -67,6 +69,7 @@ class DreamOverlayAnimationsControllerTest : SysuiTestCase() {
DREAM_IN_COMPLICATIONS_ANIMATION_DURATION,
DREAM_IN_TRANSLATION_Y_DISTANCE,
DREAM_IN_TRANSLATION_Y_DURATION,
+ logger
)
val mockView: View = mock()
@@ -82,9 +85,9 @@ class DreamOverlayAnimationsControllerTest : SysuiTestCase() {
verify(stateController).setExitAnimationsRunning(true)
val captor = argumentCaptor<Animator.AnimatorListener>()
- verify(mockAnimator).addListener(captor.capture())
+ verify(mockAnimator, atLeastOnce()).addListener(captor.capture())
- captor.value.onAnimationEnd(mockAnimator)
+ captor.allValues.forEach { it.onAnimationEnd(mockAnimator) }
verify(stateController).setExitAnimationsRunning(false)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigParameterizedStateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigParameterizedStateTest.kt
index b46d996ddfcd..f8cb40885d21 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigParameterizedStateTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigParameterizedStateTest.kt
@@ -19,7 +19,6 @@ package com.android.systemui.keyguard.data.quickaffordance
import androidx.test.filters.SmallTest
import com.android.systemui.R
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.controls.ControlsServiceInfo
import com.android.systemui.controls.controller.ControlsController
@@ -46,7 +45,6 @@ import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
@SmallTest
-@RoboPilotTest
@RunWith(Parameterized::class)
class HomeControlsKeyguardQuickAffordanceConfigParameterizedStateTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt
index b50cf73b9ec7..1d0b58a8e0f4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt
@@ -67,6 +67,7 @@ import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.user.data.repository.FakeUserRepository
import com.android.systemui.util.mockito.KotlinArgumentCaptor
import com.android.systemui.util.mockito.captureMany
+import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.whenever
import com.android.systemui.util.time.FakeSystemClock
import com.android.systemui.util.time.SystemClock
@@ -193,8 +194,24 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
bypassControllerOverride: KeyguardBypassController? = bypassController
): DeviceEntryFaceAuthRepositoryImpl {
val systemClock = FakeSystemClock()
- val faceAuthBuffer = TableLogBuffer(10, "face auth", systemClock)
- val faceDetectBuffer = TableLogBuffer(10, "face detect", systemClock)
+ val faceAuthBuffer =
+ TableLogBuffer(
+ 10,
+ "face auth",
+ systemClock,
+ mock(),
+ testDispatcher,
+ testScope.backgroundScope
+ )
+ val faceDetectBuffer =
+ TableLogBuffer(
+ 10,
+ "face detect",
+ systemClock,
+ mock(),
+ testDispatcher,
+ testScope.backgroundScope
+ )
keyguardTransitionRepository = FakeKeyguardTransitionRepository()
val keyguardTransitionInteractor =
KeyguardTransitionInteractor(keyguardTransitionRepository)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepositoryTest.kt
index f4d28431a2e9..d0bfaa9bedc9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepositoryTest.kt
@@ -23,7 +23,6 @@ import android.util.Log.TerribleFailureHandler
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.FlakyTest
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.animation.Interpolators
import com.android.systemui.keyguard.shared.model.KeyguardState
@@ -48,7 +47,6 @@ import org.junit.Test
import org.junit.runner.RunWith
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
@FlakyTest(bugId = 270760395)
class KeyguardTransitionRepositoryTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
index fe65236c699f..344df0acc409 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
@@ -180,7 +180,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
}
@Test
- fun DREAMINGtoLOCKSCREEN() =
+ fun dreamingToLockscreen() =
testScope.runTest {
// GIVEN a device is dreaming
keyguardRepository.setDreamingWithOverlay(true)
@@ -215,7 +215,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
}
@Test
- fun LOCKSCREENtoPRIMARY_BOUNCERviaBouncerShowingCall() =
+ fun lockscreenToPrimaryBouncerViaBouncerShowingCall() =
testScope.runTest {
// GIVEN a device that has at least woken up
keyguardRepository.setWakefulnessModel(startingToWake())
@@ -242,7 +242,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
}
@Test
- fun OCCLUDEDtoDOZING() =
+ fun occludedToDozing() =
testScope.runTest {
// GIVEN a device with AOD not available
keyguardRepository.setAodAvailable(false)
@@ -269,7 +269,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
}
@Test
- fun OCCLUDEDtoAOD() =
+ fun occludedToAod() =
testScope.runTest {
// GIVEN a device with AOD available
keyguardRepository.setAodAvailable(true)
@@ -296,7 +296,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
}
@Test
- fun LOCKSCREENtoDREAMING() =
+ fun lockscreenToDreaming() =
testScope.runTest {
// GIVEN a device that is not dreaming or dozing
keyguardRepository.setDreamingWithOverlay(false)
@@ -327,7 +327,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
}
@Test
- fun LOCKSCREENtoDOZING() =
+ fun lockscreenToDozing() =
testScope.runTest {
// GIVEN a device with AOD not available
keyguardRepository.setAodAvailable(false)
@@ -354,7 +354,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
}
@Test
- fun LOCKSCREENtoAOD() =
+ fun lockscreenToAod() =
testScope.runTest {
// GIVEN a device with AOD available
keyguardRepository.setAodAvailable(true)
@@ -381,7 +381,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
}
@Test
- fun DOZINGtoLOCKSCREEN() =
+ fun dozingToLockscreen() =
testScope.runTest {
// GIVEN a prior transition has run to DOZING
runTransition(KeyguardState.LOCKSCREEN, KeyguardState.DOZING)
@@ -404,7 +404,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
}
@Test
- fun DOZINGtoLOCKSCREENcannotBeInterrupedByDREAMING() =
+ fun dozingToLockscreenCannotBeInterruptedByDreaming() =
testScope.runTest {
// GIVEN a prior transition has started to LOCKSCREEN
transitionRepository.sendTransitionStep(
@@ -430,7 +430,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
}
@Test
- fun DOZINGtoGONE() =
+ fun dozingToGone() =
testScope.runTest {
// GIVEN a prior transition has run to DOZING
runTransition(KeyguardState.LOCKSCREEN, KeyguardState.DOZING)
@@ -453,7 +453,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
}
@Test
- fun GONEtoDOZING() =
+ fun goneToDozing() =
testScope.runTest {
// GIVEN a device with AOD not available
keyguardRepository.setAodAvailable(false)
@@ -480,7 +480,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
}
@Test
- fun GONEtoAOD() =
+ fun goneToAod() =
testScope.runTest {
// GIVEN a device with AOD available
keyguardRepository.setAodAvailable(true)
@@ -507,7 +507,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
}
@Test
- fun GONEtoLOCKSREEN() =
+ fun goneToLockscreen() =
testScope.runTest {
// GIVEN a prior transition has run to GONE
runTransition(KeyguardState.LOCKSCREEN, KeyguardState.GONE)
@@ -530,7 +530,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
}
@Test
- fun GONEtoDREAMING() =
+ fun goneToDreaming() =
testScope.runTest {
// GIVEN a device that is not dreaming or dozing
keyguardRepository.setDreamingWithOverlay(false)
@@ -561,7 +561,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
}
@Test
- fun ALTERNATE_BOUNCERtoPRIMARY_BOUNCER() =
+ fun alternateBouncerToPrimaryBouncer() =
testScope.runTest {
// GIVEN a prior transition has run to ALTERNATE_BOUNCER
runTransition(KeyguardState.LOCKSCREEN, KeyguardState.ALTERNATE_BOUNCER)
@@ -584,7 +584,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
}
@Test
- fun ALTERNATE_BOUNCERtoAOD() =
+ fun alternateBoucnerToAod() =
testScope.runTest {
// GIVEN a prior transition has run to ALTERNATE_BOUNCER
bouncerRepository.setAlternateVisible(true)
@@ -613,7 +613,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
}
@Test
- fun ALTERNATE_BOUNCERtoDOZING() =
+ fun alternateBouncerToDozing() =
testScope.runTest {
// GIVEN a prior transition has run to ALTERNATE_BOUNCER
bouncerRepository.setAlternateVisible(true)
@@ -643,7 +643,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
}
@Test
- fun ALTERNATE_BOUNCERtoLOCKSCREEN() =
+ fun alternateBouncerToLockscreen() =
testScope.runTest {
// GIVEN a prior transition has run to ALTERNATE_BOUNCER
bouncerRepository.setAlternateVisible(true)
@@ -671,7 +671,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
}
@Test
- fun PRIMARY_BOUNCERtoAOD() =
+ fun primaryBouncerToAod() =
testScope.runTest {
// GIVEN a prior transition has run to PRIMARY_BOUNCER
bouncerRepository.setPrimaryShow(true)
@@ -699,7 +699,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
}
@Test
- fun PRIMARY_BOUNCERtoDOZING() =
+ fun primaryBouncerToDozing() =
testScope.runTest {
// GIVEN a prior transition has run to PRIMARY_BOUNCER
bouncerRepository.setPrimaryShow(true)
@@ -727,7 +727,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
}
@Test
- fun PRIMARY_BOUNCERtoLOCKSCREEN() =
+ fun primaryBouncerToLockscreen() =
testScope.runTest {
// GIVEN a prior transition has run to PRIMARY_BOUNCER
bouncerRepository.setPrimaryShow(true)
@@ -754,7 +754,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
}
@Test
- fun OCCLUDEDtoGONE() =
+ fun occludedToGone() =
testScope.runTest {
// GIVEN a device on lockscreen
keyguardRepository.setKeyguardShowing(true)
@@ -785,7 +785,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
}
@Test
- fun OCCLUDEDtoLOCKSCREEN() =
+ fun occludedToLockscreen() =
testScope.runTest {
// GIVEN a device on lockscreen
keyguardRepository.setKeyguardShowing(true)
@@ -813,6 +813,61 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
coroutineContext.cancelChildren()
}
+ @Test
+ fun occludedToAlternateBouncer() =
+ testScope.runTest {
+
+ // GIVEN a prior transition has run to OCCLUDED
+ runTransition(KeyguardState.LOCKSCREEN, KeyguardState.OCCLUDED)
+ keyguardRepository.setKeyguardOccluded(true)
+ runCurrent()
+
+ // WHEN alternate bouncer shows
+ bouncerRepository.setAlternateVisible(true)
+ runCurrent()
+
+ val info =
+ withArgCaptor<TransitionInfo> {
+ verify(mockTransitionRepository).startTransition(capture(), anyBoolean())
+ }
+ // THEN a transition to AlternateBouncer should occur
+ assertThat(info.ownerName).isEqualTo("FromOccludedTransitionInteractor")
+ assertThat(info.from).isEqualTo(KeyguardState.OCCLUDED)
+ assertThat(info.to).isEqualTo(KeyguardState.ALTERNATE_BOUNCER)
+ assertThat(info.animator).isNotNull()
+
+ coroutineContext.cancelChildren()
+ }
+
+ @Test
+ fun primaryBouncerToOccluded() =
+ testScope.runTest {
+ // GIVEN device not sleeping
+ keyguardRepository.setWakefulnessModel(startingToWake())
+
+ // GIVEN a prior transition has run to PRIMARY_BOUNCER
+ runTransition(KeyguardState.LOCKSCREEN, KeyguardState.PRIMARY_BOUNCER)
+ bouncerRepository.setPrimaryShow(true)
+ runCurrent()
+
+ // WHEN the keyguard is occluded and primary bouncer stops showing
+ keyguardRepository.setKeyguardOccluded(true)
+ bouncerRepository.setPrimaryShow(false)
+ runCurrent()
+
+ val info =
+ withArgCaptor<TransitionInfo> {
+ verify(mockTransitionRepository).startTransition(capture(), anyBoolean())
+ }
+ // THEN a transition to AlternateBouncer should occur
+ assertThat(info.ownerName).isEqualTo("FromPrimaryBouncerTransitionInteractor")
+ assertThat(info.from).isEqualTo(KeyguardState.PRIMARY_BOUNCER)
+ assertThat(info.to).isEqualTo(KeyguardState.OCCLUDED)
+ assertThat(info.animator).isNotNull()
+
+ coroutineContext.cancelChildren()
+ }
+
private fun startingToWake() =
WakefulnessModel(
WakefulnessState.STARTING_TO_WAKE,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/log/table/FakeLogProxy.kt b/packages/SystemUI/tests/src/com/android/systemui/log/table/FakeLogProxy.kt
new file mode 100644
index 000000000000..471c4615ef0a
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/log/table/FakeLogProxy.kt
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.log.table
+
+/**
+ * Fake [LogProxy] that collects all lines sent to it. Mimics the ADB logcat format without the
+ * timestamp. [FakeLogProxy.d] will write a log like so:
+ * ```
+ * logger.d("TAG", "message here")
+ * // writes this to the [logs] field
+ * "D TAG: message here"
+ * ```
+ *
+ * Logs sent to this class are collected as a list of strings for simple test assertions.
+ */
+class FakeLogProxy : LogProxy {
+ val logs: MutableList<String> = mutableListOf()
+
+ override fun v(tag: String, message: String) {
+ logs.add("V $tag: $message")
+ }
+
+ override fun d(tag: String, message: String) {
+ logs.add("D $tag: $message")
+ }
+
+ override fun i(tag: String, message: String) {
+ logs.add("I $tag: $message")
+ }
+
+ override fun w(tag: String, message: String) {
+ logs.add("W $tag: $message")
+ }
+
+ override fun e(tag: String, message: String) {
+ logs.add("E $tag: $message")
+ }
+
+ override fun wtf(tag: String, message: String) {
+ logs.add("WTF $tag: $message")
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/log/table/LogDiffsForTableTest.kt b/packages/SystemUI/tests/src/com/android/systemui/log/table/LogDiffsForTableTest.kt
index c49337a53970..1d182cfec49c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/log/table/LogDiffsForTableTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/log/table/LogDiffsForTableTest.kt
@@ -19,6 +19,7 @@ package com.android.systemui.log.table
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.log.table.TableChange.Companion.IS_INITIAL_PREFIX
+import com.android.systemui.util.mockito.mock
import com.android.systemui.util.time.FakeSystemClock
import com.google.common.truth.Truth.assertThat
import java.io.PrintWriter
@@ -39,7 +40,8 @@ import org.junit.Test
@OptIn(ExperimentalCoroutinesApi::class)
class LogDiffsForTableTest : SysuiTestCase() {
- private val testScope = TestScope(UnconfinedTestDispatcher())
+ private val testDispatcher = UnconfinedTestDispatcher()
+ private val testScope = TestScope(testDispatcher)
private lateinit var systemClock: FakeSystemClock
private lateinit var tableLogBuffer: TableLogBuffer
@@ -47,7 +49,15 @@ class LogDiffsForTableTest : SysuiTestCase() {
@Before
fun setUp() {
systemClock = FakeSystemClock()
- tableLogBuffer = TableLogBuffer(MAX_SIZE, BUFFER_NAME, systemClock)
+ tableLogBuffer =
+ TableLogBuffer(
+ MAX_SIZE,
+ BUFFER_NAME,
+ systemClock,
+ mock(),
+ testDispatcher,
+ testScope.backgroundScope,
+ )
}
// ---- Flow<Boolean> tests ----
diff --git a/packages/SystemUI/tests/src/com/android/systemui/log/table/TableLogBufferFactoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/log/table/TableLogBufferFactoryTest.kt
index af83a560d7d0..8ba76437c725 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/log/table/TableLogBufferFactoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/log/table/TableLogBufferFactoryTest.kt
@@ -22,13 +22,20 @@ import com.android.systemui.dump.DumpManager
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.time.FakeSystemClock
import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
import org.junit.Test
+@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
class TableLogBufferFactoryTest : SysuiTestCase() {
private val dumpManager: DumpManager = mock()
private val systemClock = FakeSystemClock()
- private val underTest = TableLogBufferFactory(dumpManager, systemClock)
+ private val testDispatcher = UnconfinedTestDispatcher()
+ private val testScope = TestScope(testDispatcher)
+ private val underTest =
+ TableLogBufferFactory(dumpManager, systemClock, mock(), testDispatcher, testScope)
@Test
fun create_alwaysCreatesNewInstance() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/log/table/TableLogBufferTest.kt b/packages/SystemUI/tests/src/com/android/systemui/log/table/TableLogBufferTest.kt
index aed830ae0d53..a2b2322899b7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/log/table/TableLogBufferTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/log/table/TableLogBufferTest.kt
@@ -19,31 +19,66 @@ package com.android.systemui.log.table
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.log.table.TableChange.Companion.IS_INITIAL_PREFIX
+import com.android.systemui.plugins.log.LogLevel
+import com.android.systemui.plugins.log.LogcatEchoTracker
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.mockito.mock
+import com.android.systemui.util.mockito.whenever
import com.android.systemui.util.time.FakeSystemClock
import com.google.common.truth.Truth.assertThat
import java.io.PrintWriter
import java.io.StringWriter
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
import org.junit.Before
import org.junit.Test
+@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
class TableLogBufferTest : SysuiTestCase() {
private lateinit var underTest: TableLogBuffer
private lateinit var systemClock: FakeSystemClock
private lateinit var outputWriter: StringWriter
+ private lateinit var logcatEchoTracker: LogcatEchoTracker
+ private lateinit var localLogcat: FakeLogProxy
+
+ private val testDispatcher = UnconfinedTestDispatcher()
+ private val testScope = TestScope(testDispatcher)
@Before
fun setup() {
+ localLogcat = FakeLogProxy()
+ logcatEchoTracker = mock()
systemClock = FakeSystemClock()
outputWriter = StringWriter()
- underTest = TableLogBuffer(MAX_SIZE, NAME, systemClock)
+ underTest =
+ TableLogBuffer(
+ MAX_SIZE,
+ NAME,
+ systemClock,
+ logcatEchoTracker,
+ testDispatcher,
+ testScope.backgroundScope,
+ localLogcat = localLogcat,
+ )
+ underTest.init()
}
@Test(expected = IllegalArgumentException::class)
fun maxSizeZero_throwsException() {
- TableLogBuffer(maxSize = 0, "name", systemClock)
+ TableLogBuffer(
+ maxSize = 0,
+ "name",
+ systemClock,
+ logcatEchoTracker,
+ testDispatcher,
+ testScope.backgroundScope,
+ localLogcat = localLogcat,
+ )
}
@Test
@@ -791,6 +826,112 @@ class TableLogBufferTest : SysuiTestCase() {
assertThat(dumpedString).contains(evictedColumnLog3)
}
+ @Test
+ fun logcat_bufferNotLoggable_tagNotLoggable_noEcho() {
+ whenever(logcatEchoTracker.isBufferLoggable(eq(NAME), any())).thenReturn(false)
+ whenever(logcatEchoTracker.isTagLoggable(eq("columnName"), any())).thenReturn(false)
+
+ underTest.logChange("prefix", "columnName", true)
+
+ assertThat(localLogcat.logs).isEmpty()
+ }
+
+ @Test
+ fun logcat_bufferIsLoggable_tagNotLoggable_echoes() {
+ whenever(logcatEchoTracker.isBufferLoggable(eq(NAME), any())).thenReturn(true)
+ whenever(logcatEchoTracker.isTagLoggable(eq("columnName"), any())).thenReturn(false)
+
+ underTest.logChange("prefix", "columnName", true)
+
+ assertThat(localLogcat.logs).hasSize(1)
+ }
+
+ @Test
+ fun logcat_bufferNotLoggable_tagIsLoggable_echoes() {
+ whenever(logcatEchoTracker.isBufferLoggable(eq(NAME), any())).thenReturn(false)
+ whenever(logcatEchoTracker.isTagLoggable(eq("columnName"), any())).thenReturn(true)
+
+ underTest.logChange("prefix", "columnName", true)
+
+ assertThat(localLogcat.logs).hasSize(1)
+ }
+
+ @Test
+ fun logcat_echoesDebugLogs_debugDisabled_noEcho() {
+ // Allow any log other than debug
+ whenever(logcatEchoTracker.isBufferLoggable(eq(NAME), any())).thenAnswer { invocation ->
+ (invocation.getArgument(1) as LogLevel) != LogLevel.DEBUG
+ }
+
+ underTest.logChange("prefix", "columnName", true)
+
+ assertThat(localLogcat.logs).isEmpty()
+ }
+
+ @Test
+ fun logcat_echoesDebugLogs_debugEnabled_echoes() {
+ // Only allow debug logs
+ whenever(logcatEchoTracker.isBufferLoggable(eq(NAME), eq(LogLevel.DEBUG))).thenReturn(true)
+
+ underTest.logChange("prefix", "columnName", true)
+
+ assertThat(localLogcat.logs).hasSize(1)
+ }
+
+ @Test
+ fun logcat_bufferNotLoggable_tagIsLoggable_usesColNameForTagCheck() {
+ systemClock.setCurrentTimeMillis(1000L)
+
+ val nonLoggingTag = "nonLoggingColName"
+ val loggingTag = "loggingColName"
+
+ whenever(logcatEchoTracker.isBufferLoggable(eq(NAME), any())).thenReturn(false)
+ whenever(logcatEchoTracker.isTagLoggable(eq(loggingTag), eq(LogLevel.DEBUG)))
+ .thenReturn(true)
+ whenever(logcatEchoTracker.isTagLoggable(eq(nonLoggingTag), eq(LogLevel.DEBUG)))
+ .thenReturn(false)
+
+ underTest.logChange("", nonLoggingTag, true)
+ underTest.logChange("", loggingTag, true)
+
+ assertThat(localLogcat.logs).hasSize(1)
+
+ val timestamp = TABLE_LOG_DATE_FORMAT.format(1000L)
+ val expectedMessage = "${timestamp}${SEPARATOR}${loggingTag}${SEPARATOR}true"
+ val expectedLine = "D $NAME: $expectedMessage"
+
+ assertThat(localLogcat.logs[0]).isEqualTo(expectedLine)
+ }
+
+ @Test
+ fun logcat_bufferLoggable_multipleMessagesAreEchoed() {
+ systemClock.setCurrentTimeMillis(1000L)
+ whenever(logcatEchoTracker.isBufferLoggable(eq(NAME), any())).thenReturn(true)
+
+ val col1 = "column1"
+ val col2 = "column2"
+
+ // Log a couple of columns that flip bits
+ underTest.logChange("", col1, true)
+ underTest.logChange("", col2, false)
+ underTest.logChange("", col1, false)
+ underTest.logChange("", col2, true)
+
+ assertThat(localLogcat.logs).hasSize(4)
+
+ val timestamp = TABLE_LOG_DATE_FORMAT.format(1000L)
+ val msg1 = "${timestamp}${SEPARATOR}${col1}${SEPARATOR}true"
+ val msg2 = "${timestamp}${SEPARATOR}${col2}${SEPARATOR}false"
+ val msg3 = "${timestamp}${SEPARATOR}${col1}${SEPARATOR}false"
+ val msg4 = "${timestamp}${SEPARATOR}${col2}${SEPARATOR}true"
+ val expected = listOf(msg1, msg2, msg3, msg4).map { "D $NAME: $it" }
+
+ // Logs use the same bg dispatcher for writing to logcat, they should be in order
+ for ((msg, logLine) in expected zip localLogcat.logs) {
+ assertThat(logLine).isEqualTo(msg)
+ }
+ }
+
private fun dumpChanges(): String {
underTest.dump(PrintWriter(outputWriter), arrayOf())
return outputWriter.toString()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDeviceManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDeviceManagerTest.kt
index a45e9d9fcacf..0c57e7b82586 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDeviceManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDeviceManagerTest.kt
@@ -468,7 +468,7 @@ public class MediaDeviceManagerTest : SysuiTestCase() {
}
@Test
- fun audioInfoChanged() {
+ fun audioInfoPlaybackTypeChanged() {
whenever(playbackInfo.getPlaybackType()).thenReturn(PlaybackInfo.PLAYBACK_TYPE_LOCAL)
whenever(controller.getPlaybackInfo()).thenReturn(playbackInfo)
// GIVEN a controller with local playback type
@@ -486,6 +486,25 @@ public class MediaDeviceManagerTest : SysuiTestCase() {
}
@Test
+ fun audioInfoVolumeControlIdChanged() {
+ whenever(playbackInfo.getPlaybackType()).thenReturn(PlaybackInfo.PLAYBACK_TYPE_LOCAL)
+ whenever(playbackInfo.getVolumeControlId()).thenReturn(null)
+ whenever(controller.getPlaybackInfo()).thenReturn(playbackInfo)
+ // GIVEN a controller with local playback type
+ manager.onMediaDataLoaded(KEY, null, mediaData)
+ fakeBgExecutor.runAllReady()
+ fakeFgExecutor.runAllReady()
+ reset(mr2)
+ // WHEN onAudioInfoChanged fires with a volume control id change
+ whenever(playbackInfo.getVolumeControlId()).thenReturn("placeholder id")
+ val captor = ArgumentCaptor.forClass(MediaController.Callback::class.java)
+ verify(controller).registerCallback(captor.capture())
+ captor.value.onAudioInfoChanged(playbackInfo)
+ // THEN the route is checked
+ verify(mr2).getRoutingSessionForMediaController(eq(controller))
+ }
+
+ @Test
fun audioInfoHasntChanged() {
whenever(playbackInfo.getPlaybackType()).thenReturn(PlaybackInfo.PLAYBACK_TYPE_REMOTE)
whenever(controller.getPlaybackInfo()).thenReturn(playbackInfo)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselControllerTest.kt
index 1a00ac2722fe..07f7c158fc4d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselControllerTest.kt
@@ -17,7 +17,9 @@
package com.android.systemui.media.controls.ui
import android.app.PendingIntent
+import android.content.res.ColorStateList
import android.content.res.Configuration
+import android.os.LocaleList
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.util.MathUtils.abs
@@ -26,6 +28,7 @@ import androidx.test.filters.SmallTest
import com.android.internal.logging.InstanceId
import com.android.keyguard.KeyguardUpdateMonitor
import com.android.keyguard.KeyguardUpdateMonitorCallback
+import com.android.systemui.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.classifier.FalsingCollector
import com.android.systemui.dagger.qualifiers.Main
@@ -50,9 +53,11 @@ import com.android.systemui.statusbar.notification.collection.provider.OnReorder
import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.util.concurrency.DelayableExecutor
+import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.capture
import com.android.systemui.util.mockito.eq
import com.android.systemui.util.time.FakeSystemClock
+import java.util.Locale
import javax.inject.Provider
import junit.framework.Assert.assertEquals
import junit.framework.Assert.assertFalse
@@ -68,6 +73,7 @@ import org.mockito.Captor
import org.mockito.Mock
import org.mockito.Mockito.floatThat
import org.mockito.Mockito.mock
+import org.mockito.Mockito.never
import org.mockito.Mockito.reset
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
@@ -77,6 +83,8 @@ import org.mockito.MockitoAnnotations
private val DATA = MediaTestUtils.emptyMediaData
private val SMARTSPACE_KEY = "smartspace"
+private const val PAUSED_LOCAL = "paused local"
+private const val PLAYING_LOCAL = "playing local"
@SmallTest
@TestableLooper.RunWithLooper(setAsMainLooper = true)
@@ -118,6 +126,7 @@ class MediaCarouselControllerTest : SysuiTestCase() {
@Before
fun setup() {
MockitoAnnotations.initMocks(this)
+ context.resources.configuration.locales = LocaleList(Locale.US, Locale.UK)
transitionRepository = FakeKeyguardTransitionRepository()
mediaCarouselController =
MediaCarouselController(
@@ -157,7 +166,7 @@ class MediaCarouselControllerTest : SysuiTestCase() {
// Test values: key, data, last active time
val playingLocal =
Triple(
- "playing local",
+ PLAYING_LOCAL,
DATA.copy(
active = true,
isPlaying = true,
@@ -181,7 +190,7 @@ class MediaCarouselControllerTest : SysuiTestCase() {
val pausedLocal =
Triple(
- "paused local",
+ PAUSED_LOCAL,
DATA.copy(
active = true,
isPlaying = false,
@@ -384,8 +393,8 @@ class MediaCarouselControllerTest : SysuiTestCase() {
testPlayerOrdering()
// playing paused player
listener.value.onMediaDataLoaded(
- "paused local",
- "paused local",
+ PAUSED_LOCAL,
+ PAUSED_LOCAL,
DATA.copy(
active = true,
isPlaying = true,
@@ -394,8 +403,8 @@ class MediaCarouselControllerTest : SysuiTestCase() {
)
)
listener.value.onMediaDataLoaded(
- "playing local",
- "playing local",
+ PLAYING_LOCAL,
+ PLAYING_LOCAL,
DATA.copy(
active = true,
isPlaying = false,
@@ -405,7 +414,7 @@ class MediaCarouselControllerTest : SysuiTestCase() {
)
assertEquals(
- MediaPlayerData.getMediaPlayerIndex("paused local"),
+ MediaPlayerData.getMediaPlayerIndex(PAUSED_LOCAL),
mediaCarouselController.mediaCarouselScrollHandler.visibleMediaIndex
)
// paused player order should stays the same in visibleMediaPLayer map.
@@ -486,7 +495,7 @@ class MediaCarouselControllerTest : SysuiTestCase() {
@Test
fun testMediaLoaded_ScrollToActivePlayer() {
listener.value.onMediaDataLoaded(
- "playing local",
+ PLAYING_LOCAL,
null,
DATA.copy(
active = true,
@@ -496,7 +505,7 @@ class MediaCarouselControllerTest : SysuiTestCase() {
)
)
listener.value.onMediaDataLoaded(
- "paused local",
+ PAUSED_LOCAL,
null,
DATA.copy(
active = true,
@@ -514,8 +523,8 @@ class MediaCarouselControllerTest : SysuiTestCase() {
mediaCarouselController.shouldScrollToKey = true
// switching between media players.
listener.value.onMediaDataLoaded(
- "playing local",
- "playing local",
+ PLAYING_LOCAL,
+ PLAYING_LOCAL,
DATA.copy(
active = true,
isPlaying = false,
@@ -524,8 +533,8 @@ class MediaCarouselControllerTest : SysuiTestCase() {
)
)
listener.value.onMediaDataLoaded(
- "paused local",
- "paused local",
+ PAUSED_LOCAL,
+ PAUSED_LOCAL,
DATA.copy(
active = true,
isPlaying = true,
@@ -535,7 +544,7 @@ class MediaCarouselControllerTest : SysuiTestCase() {
)
assertEquals(
- MediaPlayerData.getMediaPlayerIndex("paused local"),
+ MediaPlayerData.getMediaPlayerIndex(PAUSED_LOCAL),
mediaCarouselController.mediaCarouselScrollHandler.visibleMediaIndex
)
}
@@ -548,7 +557,7 @@ class MediaCarouselControllerTest : SysuiTestCase() {
false
)
listener.value.onMediaDataLoaded(
- "playing local",
+ PLAYING_LOCAL,
null,
DATA.copy(
active = true,
@@ -558,7 +567,7 @@ class MediaCarouselControllerTest : SysuiTestCase() {
)
)
- var playerIndex = MediaPlayerData.getMediaPlayerIndex("playing local")
+ var playerIndex = MediaPlayerData.getMediaPlayerIndex(PLAYING_LOCAL)
assertEquals(
playerIndex,
mediaCarouselController.mediaCarouselScrollHandler.visibleMediaIndex
@@ -569,7 +578,7 @@ class MediaCarouselControllerTest : SysuiTestCase() {
// And check that the card stays in its position.
mediaCarouselController.shouldScrollToKey = true
listener.value.onMediaDataLoaded(
- "playing local",
+ PLAYING_LOCAL,
null,
DATA.copy(
active = true,
@@ -579,7 +588,7 @@ class MediaCarouselControllerTest : SysuiTestCase() {
packageName = "PACKAGE_NAME"
)
)
- playerIndex = MediaPlayerData.getMediaPlayerIndex("playing local")
+ playerIndex = MediaPlayerData.getMediaPlayerIndex(PLAYING_LOCAL)
assertEquals(playerIndex, 0)
}
@@ -676,36 +685,52 @@ class MediaCarouselControllerTest : SysuiTestCase() {
@Test
fun testOnConfigChanged_playersAreAddedBack() {
- listener.value.onMediaDataLoaded(
- "playing local",
- null,
- DATA.copy(
- active = true,
- isPlaying = true,
- playbackLocation = MediaData.PLAYBACK_LOCAL,
- resumption = false
- )
- )
- listener.value.onMediaDataLoaded(
- "paused local",
- null,
- DATA.copy(
- active = true,
- isPlaying = false,
- playbackLocation = MediaData.PLAYBACK_LOCAL,
- resumption = false
- )
- )
+ testConfigurationChange { configListener.value.onConfigChanged(Configuration()) }
+ }
- val playersSize = MediaPlayerData.players().size
+ @Test
+ fun testOnUiModeChanged_playersAreAddedBack() {
+ testConfigurationChange(configListener.value::onUiModeChanged)
- configListener.value.onConfigChanged(Configuration())
+ verify(pageIndicator).tintList =
+ ColorStateList.valueOf(context.getColor(R.color.media_paging_indicator))
+ verify(pageIndicator, times(2)).setNumPages(any())
+ }
- assertEquals(playersSize, MediaPlayerData.players().size)
- assertEquals(
- MediaPlayerData.getMediaPlayerIndex("playing local"),
- mediaCarouselController.mediaCarouselScrollHandler.visibleMediaIndex
- )
+ @Test
+ fun testOnDensityOrFontScaleChanged_playersAreAddedBack() {
+ testConfigurationChange(configListener.value::onDensityOrFontScaleChanged)
+
+ verify(pageIndicator).tintList =
+ ColorStateList.valueOf(context.getColor(R.color.media_paging_indicator))
+ // when recreateMedia is set to true, page indicator is updated on removal and addition.
+ verify(pageIndicator, times(4)).setNumPages(any())
+ }
+
+ @Test
+ fun testOnThemeChanged_playersAreAddedBack() {
+ testConfigurationChange(configListener.value::onThemeChanged)
+
+ verify(pageIndicator).tintList =
+ ColorStateList.valueOf(context.getColor(R.color.media_paging_indicator))
+ verify(pageIndicator, times(2)).setNumPages(any())
+ }
+
+ @Test
+ fun testOnLocaleListChanged_playersAreAddedBack() {
+ context.resources.configuration.locales = LocaleList(Locale.US, Locale.UK, Locale.CANADA)
+ testConfigurationChange(configListener.value::onLocaleListChanged)
+
+ verify(pageIndicator, never()).tintList =
+ ColorStateList.valueOf(context.getColor(R.color.media_paging_indicator))
+
+ context.resources.configuration.locales = LocaleList(Locale.UK, Locale.US, Locale.CANADA)
+ testConfigurationChange(configListener.value::onLocaleListChanged)
+
+ verify(pageIndicator).tintList =
+ ColorStateList.valueOf(context.getColor(R.color.media_paging_indicator))
+ // When recreateMedia is set to true, page indicator is updated on removal and addition.
+ verify(pageIndicator, times(4)).setNumPages(any())
}
@Test
@@ -846,4 +871,43 @@ class MediaCarouselControllerTest : SysuiTestCase() {
// Then the carousel visibility is updated
assertTrue(stateUpdated)
}
+
+ /**
+ * Helper method when a configuration change occurs.
+ *
+ * @param function called when a certain configuration change occurs.
+ */
+ private fun testConfigurationChange(function: () -> Unit) {
+ mediaCarouselController.pageIndicator = pageIndicator
+ listener.value.onMediaDataLoaded(
+ PLAYING_LOCAL,
+ null,
+ DATA.copy(
+ active = true,
+ isPlaying = true,
+ playbackLocation = MediaData.PLAYBACK_LOCAL,
+ resumption = false
+ )
+ )
+ listener.value.onMediaDataLoaded(
+ PAUSED_LOCAL,
+ null,
+ DATA.copy(
+ active = true,
+ isPlaying = false,
+ playbackLocation = MediaData.PLAYBACK_LOCAL,
+ resumption = false
+ )
+ )
+
+ val playersSize = MediaPlayerData.players().size
+ reset(pageIndicator)
+ function()
+
+ assertEquals(playersSize, MediaPlayerData.players().size)
+ assertEquals(
+ MediaPlayerData.getMediaPlayerIndex(PLAYING_LOCAL),
+ mediaCarouselController.mediaCarouselScrollHandler.visibleMediaIndex
+ )
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java
index 0bdcaf464cfd..299303d38f29 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java
@@ -19,6 +19,7 @@ package com.android.systemui.media.dialog;
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.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
@@ -33,7 +34,12 @@ import static org.mockito.Mockito.when;
import android.app.KeyguardManager;
import android.app.Notification;
+import android.content.ComponentName;
import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.graphics.PorterDuffColorFilter;
+import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.media.AudioDeviceAttributes;
import android.media.AudioManager;
@@ -44,6 +50,7 @@ import android.media.NearbyDevice;
import android.media.RoutingSessionInfo;
import android.media.session.MediaController;
import android.media.session.MediaSessionManager;
+import android.media.session.PlaybackState;
import android.os.PowerExemptionManager;
import android.os.RemoteException;
import android.service.notification.StatusBarNotification;
@@ -74,6 +81,9 @@ import com.google.common.collect.ImmutableList;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
import java.util.ArrayList;
import java.util.List;
@@ -93,29 +103,54 @@ public class MediaOutputControllerTest extends SysuiTestCase {
private static final String TEST_SONG = "test_song";
private static final String TEST_SESSION_ID = "test_session_id";
private static final String TEST_SESSION_NAME = "test_session_name";
- private final DialogLaunchAnimator mDialogLaunchAnimator = mock(DialogLaunchAnimator.class);
- private final ActivityLaunchAnimator.Controller mActivityLaunchAnimatorController = mock(
- ActivityLaunchAnimator.Controller.class);
- private final NearbyMediaDevicesManager mNearbyMediaDevicesManager = mock(
- NearbyMediaDevicesManager.class);
+ @Mock
+ private DialogLaunchAnimator mDialogLaunchAnimator;
+ @Mock
+ private ActivityLaunchAnimator.Controller mActivityLaunchAnimatorController;
+ @Mock
+ private NearbyMediaDevicesManager mNearbyMediaDevicesManager;
// Mock
- private MediaController mMediaController = mock(MediaController.class);
- private MediaSessionManager mMediaSessionManager = mock(MediaSessionManager.class);
- private CachedBluetoothDeviceManager mCachedBluetoothDeviceManager =
- mock(CachedBluetoothDeviceManager.class);
- private LocalBluetoothManager mLocalBluetoothManager = mock(LocalBluetoothManager.class);
- private MediaOutputController.Callback mCb = mock(MediaOutputController.Callback.class);
- private MediaDevice mMediaDevice1 = mock(MediaDevice.class);
- private MediaDevice mMediaDevice2 = mock(MediaDevice.class);
- private NearbyDevice mNearbyDevice1 = mock(NearbyDevice.class);
- private NearbyDevice mNearbyDevice2 = mock(NearbyDevice.class);
- private MediaMetadata mMediaMetadata = mock(MediaMetadata.class);
- private RoutingSessionInfo mRemoteSessionInfo = mock(RoutingSessionInfo.class);
- private ActivityStarter mStarter = mock(ActivityStarter.class);
- private AudioManager mAudioManager = mock(AudioManager.class);
- private KeyguardManager mKeyguardManager = mock(KeyguardManager.class);
- private PowerExemptionManager mPowerExemptionManager = mock(PowerExemptionManager.class);
- private CommonNotifCollection mNotifCollection = mock(CommonNotifCollection.class);
+ @Mock
+ private MediaController mMediaController;
+ @Mock
+ private MediaSessionManager mMediaSessionManager;
+ @Mock
+ private CachedBluetoothDeviceManager mCachedBluetoothDeviceManager;
+ @Mock
+ private LocalBluetoothManager mLocalBluetoothManager;
+ @Mock
+ private MediaOutputController.Callback mCb;
+ @Mock
+ private MediaDevice mMediaDevice1;
+ @Mock
+ private MediaDevice mMediaDevice2;
+ @Mock
+ private NearbyDevice mNearbyDevice1;
+ @Mock
+ private NearbyDevice mNearbyDevice2;
+ @Mock
+ private MediaMetadata mMediaMetadata;
+ @Mock
+ private RoutingSessionInfo mRemoteSessionInfo;
+ @Mock
+ private ActivityStarter mStarter;
+ @Mock
+ private AudioManager mAudioManager;
+ @Mock
+ private KeyguardManager mKeyguardManager;
+ @Mock
+ private ActivityLaunchAnimator.Controller mController;
+ @Mock
+ private PowerExemptionManager mPowerExemptionManager;
+ @Mock
+ private CommonNotifCollection mNotifCollection;
+ @Mock
+ private PackageManager mPackageManager;
+ @Mock
+ private Drawable mDrawable;
+ @Mock
+ private PlaybackState mPlaybackState;
+
private FeatureFlags mFlags = mock(FeatureFlags.class);
private View mDialogLaunchView = mock(View.class);
private MediaOutputController.Callback mCallback = mock(MediaOutputController.Callback.class);
@@ -131,8 +166,11 @@ public class MediaOutputControllerTest extends SysuiTestCase {
@Before
public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mContext.setMockPackageManager(mPackageManager);
mSpyContext = spy(mContext);
when(mMediaController.getPackageName()).thenReturn(TEST_PACKAGE_NAME);
+ when(mMediaController.getPlaybackState()).thenReturn(mPlaybackState);
mMediaControllers.add(mMediaController);
when(mMediaSessionManager.getActiveSessions(any())).thenReturn(mMediaControllers);
doReturn(mMediaSessionManager).when(mSpyContext).getSystemService(
@@ -258,6 +296,34 @@ public class MediaOutputControllerTest extends SysuiTestCase {
}
@Test
+ public void tryToLaunchMediaApplication_intentNotNull_startActivity() {
+ when(mDialogLaunchAnimator.createActivityLaunchController(any(View.class))).thenReturn(
+ mController);
+ Intent intent = new Intent(TEST_PACKAGE_NAME);
+ doReturn(intent).when(mPackageManager).getLaunchIntentForPackage(TEST_PACKAGE_NAME);
+ mMediaOutputController.start(mCallback);
+
+ mMediaOutputController.tryToLaunchMediaApplication(mDialogLaunchView);
+
+ verify(mStarter).startActivity(any(Intent.class), anyBoolean(),
+ Mockito.eq(mController));
+ }
+
+ @Test
+ public void tryToLaunchInAppRoutingIntent_componentNameNotNull_startActivity() {
+ when(mDialogLaunchAnimator.createActivityLaunchController(any(View.class))).thenReturn(
+ mController);
+ mMediaOutputController.start(mCallback);
+ when(mLocalMediaManager.getLinkedItemComponentName()).thenReturn(
+ new ComponentName(TEST_PACKAGE_NAME, ""));
+
+ mMediaOutputController.tryToLaunchInAppRoutingIntent(TEST_DEVICE_1_ID, mDialogLaunchView);
+
+ verify(mStarter).startActivity(any(Intent.class), anyBoolean(),
+ Mockito.eq(mController));
+ }
+
+ @Test
public void onDevicesUpdated_unregistersNearbyDevicesCallback() throws RemoteException {
mMediaOutputController.start(mCb);
@@ -342,6 +408,30 @@ public class MediaOutputControllerTest extends SysuiTestCase {
}
@Test
+ public void advanced_onDeviceListUpdateWithConnectedDeviceRemote_verifyItemSize() {
+ when(mFlags.isEnabled(Flags.OUTPUT_SWITCHER_ADVANCED_LAYOUT)).thenReturn(true);
+ when(mMediaDevice1.getFeatures()).thenReturn(
+ ImmutableList.of(MediaRoute2Info.FEATURE_REMOTE_PLAYBACK));
+ when(mLocalMediaManager.getCurrentConnectedDevice()).thenReturn(mMediaDevice1);
+ mMediaOutputController.start(mCb);
+ reset(mCb);
+
+ mMediaOutputController.onDeviceListUpdate(mMediaDevices);
+ final List<MediaDevice> devices = new ArrayList<>();
+ for (MediaItem item : mMediaOutputController.getMediaItemList()) {
+ if (item.getMediaDevice().isPresent()) {
+ devices.add(item.getMediaDevice().get());
+ }
+ }
+
+ assertThat(devices.containsAll(mMediaDevices)).isTrue();
+ assertThat(devices.size()).isEqualTo(mMediaDevices.size());
+ assertThat(mMediaOutputController.getMediaItemList().size()).isEqualTo(
+ mMediaDevices.size() + 1);
+ verify(mCb).onDeviceListChanged();
+ }
+
+ @Test
public void advanced_categorizeMediaItems_withSuggestedDevice_verifyDeviceListSize() {
when(mFlags.isEnabled(Flags.OUTPUT_SWITCHER_ADVANCED_LAYOUT)).thenReturn(true);
when(mMediaDevice1.isSuggestedDevice()).thenReturn(true);
@@ -582,6 +672,17 @@ public class MediaOutputControllerTest extends SysuiTestCase {
}
@Test
+ public void isAnyDeviceTransferring_advancedLayoutSupport() {
+ when(mFlags.isEnabled(Flags.OUTPUT_SWITCHER_ADVANCED_LAYOUT)).thenReturn(true);
+ when(mMediaDevice1.getState()).thenReturn(
+ LocalMediaManager.MediaDeviceState.STATE_CONNECTING);
+ mMediaOutputController.start(mCb);
+ mMediaOutputController.onDeviceListUpdate(mMediaDevices);
+
+ assertThat(mMediaOutputController.isAnyDeviceTransferring()).isTrue();
+ }
+
+ @Test
public void isPlaying_stateIsNull() {
when(mMediaController.getPlaybackState()).thenReturn(null);
@@ -661,22 +762,6 @@ public class MediaOutputControllerTest extends SysuiTestCase {
}
@Test
- public void connectDevice_verifyConnect() {
- when(mLocalMediaManager.getCurrentConnectedDevice()).thenReturn(mMediaDevice2);
-
- mMediaOutputController.connectDevice(mMediaDevice1);
-
- // Wait for background thread execution
- try {
- Thread.sleep(100);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
-
- verify(mLocalMediaManager).connectDevice(mMediaDevice1);
- }
-
- @Test
public void getActiveRemoteMediaDevice_isSystemSession_returnSession() {
when(mRemoteSessionInfo.getId()).thenReturn(TEST_SESSION_ID);
when(mRemoteSessionInfo.getName()).thenReturn(TEST_SESSION_NAME);
@@ -883,6 +968,56 @@ public class MediaOutputControllerTest extends SysuiTestCase {
}
@Test
+ public void getDeviceIconCompat_deviceIconIsNotNull_returnsIcon() {
+ when(mLocalMediaManager.getCurrentConnectedDevice()).thenReturn(mMediaDevice2);
+ when(mMediaDevice1.getIcon()).thenReturn(mDrawable);
+
+ assertThat(mMediaOutputController.getDeviceIconCompat(mMediaDevice1)).isInstanceOf(
+ IconCompat.class);
+ }
+
+ @Test
+ public void getDeviceIconCompat_deviceIconIsNull_returnsIcon() {
+ when(mLocalMediaManager.getCurrentConnectedDevice()).thenReturn(mMediaDevice2);
+ when(mMediaDevice1.getIcon()).thenReturn(null);
+
+ assertThat(mMediaOutputController.getDeviceIconCompat(mMediaDevice1)).isInstanceOf(
+ IconCompat.class);
+ }
+
+ @Test
+ public void setColorFilter_setColorFilterToDrawable() {
+ mMediaOutputController.setColorFilter(mDrawable, true);
+
+ verify(mDrawable).setColorFilter(any(PorterDuffColorFilter.class));
+ }
+
+ @Test
+ public void resetGroupMediaDevices_clearGroupDevices() {
+ final MediaDevice selectedMediaDevice1 = mock(MediaDevice.class);
+ final MediaDevice selectedMediaDevice2 = mock(MediaDevice.class);
+ final MediaDevice selectableMediaDevice1 = mock(MediaDevice.class);
+ final MediaDevice selectableMediaDevice2 = mock(MediaDevice.class);
+ final List<MediaDevice> selectedMediaDevices = new ArrayList<>();
+ final List<MediaDevice> selectableMediaDevices = new ArrayList<>();
+ when(selectedMediaDevice1.getId()).thenReturn(TEST_DEVICE_1_ID);
+ when(selectedMediaDevice2.getId()).thenReturn(TEST_DEVICE_2_ID);
+ when(selectableMediaDevice1.getId()).thenReturn(TEST_DEVICE_3_ID);
+ when(selectableMediaDevice2.getId()).thenReturn(TEST_DEVICE_4_ID);
+ selectedMediaDevices.add(selectedMediaDevice1);
+ selectedMediaDevices.add(selectedMediaDevice2);
+ selectableMediaDevices.add(selectableMediaDevice1);
+ selectableMediaDevices.add(selectableMediaDevice2);
+ doReturn(selectedMediaDevices).when(mLocalMediaManager).getSelectedMediaDevice();
+ doReturn(selectableMediaDevices).when(mLocalMediaManager).getSelectableMediaDevice();
+ assertThat(mMediaOutputController.getGroupMediaDevices().isEmpty()).isFalse();
+
+ mMediaOutputController.resetGroupMediaDevices();
+
+ assertThat(mMediaOutputController.mGroupMediaDevices.isEmpty()).isTrue();
+ }
+
+ @Test
public void isVolumeControlEnabled_isCastWithVolumeFixed_returnsFalse() {
when(mMediaDevice1.getDeviceType()).thenReturn(
MediaDevice.MediaDeviceType.TYPE_CAST_DEVICE);
@@ -919,6 +1054,42 @@ public class MediaOutputControllerTest extends SysuiTestCase {
}
@Test
+ public void setTemporaryAllowListExceptionIfNeeded_packageNameIsNull_NoAction() {
+ MediaOutputController testMediaOutputController = new MediaOutputController(mSpyContext,
+ null,
+ mMediaSessionManager, mLocalBluetoothManager, mStarter,
+ mNotifCollection, mDialogLaunchAnimator,
+ Optional.of(mNearbyMediaDevicesManager), mAudioManager, mPowerExemptionManager,
+ mKeyguardManager, mFlags);
+
+ testMediaOutputController.setTemporaryAllowListExceptionIfNeeded(mMediaDevice2);
+
+ verify(mPowerExemptionManager, never()).addToTemporaryAllowList(anyString(), anyInt(),
+ anyString(),
+ anyLong());
+ }
+
+ @Test
+ public void onMetadataChanged_triggersOnMetadataChanged() {
+ mMediaOutputController.mCallback = this.mCallback;
+
+ mMediaOutputController.mCb.onMetadataChanged(mMediaMetadata);
+
+ verify(mMediaOutputController.mCallback).onMediaChanged();
+ }
+
+ @Test
+ public void onPlaybackStateChanged_updateWithNullState_onMediaStoppedOrPaused() {
+ when(mPlaybackState.getState()).thenReturn(PlaybackState.STATE_PLAYING);
+ mMediaOutputController.mCallback = this.mCallback;
+ mMediaOutputController.start(mCb);
+
+ mMediaOutputController.mCb.onPlaybackStateChanged(null);
+
+ verify(mMediaOutputController.mCallback).onMediaStoppedOrPaused();
+ }
+
+ @Test
public void launchBluetoothPairing_isKeyguardLocked_dismissDialog() {
when(mDialogLaunchAnimator.createActivityLaunchController(mDialogLaunchView)).thenReturn(
mActivityLaunchAnimatorController);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java
index 8ee1ea8a9916..39accfb5ffcc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java
@@ -49,6 +49,8 @@ import com.android.systemui.Dependency;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dump.DumpManager;
+import com.android.systemui.flags.FakeFeatureFlags;
+import com.android.systemui.flags.Flags;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.recents.OverviewProxyService;
import com.android.systemui.settings.UserTracker;
@@ -110,6 +112,7 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase {
private NotificationEntry mCurrentUserNotif;
private NotificationEntry mSecondaryUserNotif;
private NotificationEntry mWorkProfileNotif;
+ private final FakeFeatureFlags mFakeFeatureFlags = new FakeFeatureFlags();
@Before
public void setUp() {
@@ -291,7 +294,16 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase {
}
@Test
+ public void testUserSwitchedCallsOnUserSwitching() {
+ mFakeFeatureFlags.set(Flags.LOAD_NOTIFICATIONS_BEFORE_THE_USER_SWITCH_IS_COMPLETE, true);
+ mLockscreenUserManager.getUserTrackerCallbackForTest().onUserChanging(mSecondaryUser.id,
+ mContext);
+ verify(mPresenter, times(1)).onUserSwitched(mSecondaryUser.id);
+ }
+
+ @Test
public void testUserSwitchedCallsOnUserSwitched() {
+ mFakeFeatureFlags.set(Flags.LOAD_NOTIFICATIONS_BEFORE_THE_USER_SWITCH_IS_COMPLETE, false);
mLockscreenUserManager.getUserTrackerCallbackForTest().onUserChanged(mSecondaryUser.id,
mContext);
verify(mPresenter, times(1)).onUserSwitched(mSecondaryUser.id);
@@ -356,7 +368,8 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase {
mKeyguardStateController,
mSettings,
mock(DumpManager.class),
- mock(LockPatternUtils.class));
+ mock(LockPatternUtils.class),
+ mFakeFeatureFlags);
}
public BroadcastReceiver getBaseBroadcastReceiverForTest() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherTest.kt
index 3ec96908dac8..bde05b9f499e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherTest.kt
@@ -53,6 +53,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
import org.junit.After
import org.junit.Before
import org.junit.Test
@@ -92,13 +93,15 @@ class MobileRepositorySwitcherTest : SysuiTestCase() {
private val mobileMappings = FakeMobileMappingsProxy()
private val subscriptionManagerProxy = FakeSubscriptionManagerProxy()
+ private val testDispatcher = UnconfinedTestDispatcher()
private val scope = CoroutineScope(IMMEDIATE)
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
- logFactory = TableLogBufferFactory(dumpManager, FakeSystemClock())
+ logFactory =
+ TableLogBufferFactory(dumpManager, FakeSystemClock(), mock(), testDispatcher, scope)
// Never start in demo mode
whenever(demoModeController.isInDemoMode).thenReturn(false)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionParameterizedTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionParameterizedTest.kt
index 37fac3458c83..7573b28c8a7f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionParameterizedTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionParameterizedTest.kt
@@ -61,11 +61,18 @@ import org.junit.runners.Parameterized.Parameters
internal class DemoMobileConnectionParameterizedTest(private val testCase: TestCase) :
SysuiTestCase() {
- private val logFactory = TableLogBufferFactory(mock(), FakeSystemClock())
-
private val testDispatcher = UnconfinedTestDispatcher()
private val testScope = TestScope(testDispatcher)
+ private val logFactory =
+ TableLogBufferFactory(
+ mock(),
+ FakeSystemClock(),
+ mock(),
+ testDispatcher,
+ testScope.backgroundScope,
+ )
+
private val fakeNetworkEventFlow = MutableStateFlow<FakeNetworkEventModel?>(null)
private val fakeWifiEventFlow = MutableStateFlow<FakeWifiEventModel?>(null)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepositoryTest.kt
index 1251dfacddfc..efaf15235b46 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepositoryTest.kt
@@ -54,13 +54,20 @@ import org.junit.Test
@SmallTest
class DemoMobileConnectionsRepositoryTest : SysuiTestCase() {
private val dumpManager: DumpManager = mock()
- private val logFactory = TableLogBufferFactory(dumpManager, FakeSystemClock())
private val testDispatcher = UnconfinedTestDispatcher()
private val testScope = TestScope(testDispatcher)
private val fakeNetworkEventFlow = MutableStateFlow<FakeNetworkEventModel?>(null)
private val fakeWifiEventFlow = MutableStateFlow<FakeWifiEventModel?>(null)
+ private val logFactory =
+ TableLogBufferFactory(
+ dumpManager,
+ FakeSystemClock(),
+ mock(),
+ testDispatcher,
+ testScope.backgroundScope,
+ )
private lateinit var underTest: DemoMobileConnectionsRepository
private lateinit var mobileDataSource: DemoModeMobileConnectionDataSource
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryTest.kt
index 9f77744e1fec..b701fbd66937 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryTest.kt
@@ -66,7 +66,15 @@ class FullMobileConnectionRepositoryTest : SysuiTestCase() {
private val systemClock = FakeSystemClock()
private val testDispatcher = UnconfinedTestDispatcher()
private val testScope = TestScope(testDispatcher)
- private val tableLogBuffer = TableLogBuffer(maxSize = 100, name = "TestName", systemClock)
+ private val tableLogBuffer =
+ TableLogBuffer(
+ maxSize = 100,
+ name = "TestName",
+ systemClock,
+ mock(),
+ testDispatcher,
+ testScope.backgroundScope,
+ )
private val mobileFactory = mock<MobileConnectionRepositoryImpl.Factory>()
private val carrierMergedFactory = mock<CarrierMergedConnectionRepository.Factory>()
@@ -294,7 +302,14 @@ class FullMobileConnectionRepositoryTest : SysuiTestCase() {
@Test
fun factory_reusesLogBuffersForSameConnection() =
testScope.runTest {
- val realLoggerFactory = TableLogBufferFactory(mock(), FakeSystemClock())
+ val realLoggerFactory =
+ TableLogBufferFactory(
+ mock(),
+ FakeSystemClock(),
+ mock(),
+ testDispatcher,
+ testScope.backgroundScope,
+ )
val factory =
FullMobileConnectionRepository.Factory(
@@ -329,7 +344,14 @@ class FullMobileConnectionRepositoryTest : SysuiTestCase() {
@Test
fun factory_reusesLogBuffersForSameSubIDevenIfCarrierMerged() =
testScope.runTest {
- val realLoggerFactory = TableLogBufferFactory(mock(), FakeSystemClock())
+ val realLoggerFactory =
+ TableLogBufferFactory(
+ mock(),
+ FakeSystemClock(),
+ mock(),
+ testDispatcher,
+ testScope.backgroundScope,
+ )
val factory =
FullMobileConnectionRepository.Factory(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt
index c84c9c032225..6e1ab58db56d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt
@@ -61,6 +61,16 @@ class MobileIconsInteractorTest : SysuiTestCase() {
private val testDispatcher = UnconfinedTestDispatcher()
private val testScope = TestScope(testDispatcher)
+ private val tableLogBuffer =
+ TableLogBuffer(
+ 8,
+ "MobileIconsInteractorTest",
+ FakeSystemClock(),
+ mock(),
+ testDispatcher,
+ testScope.backgroundScope,
+ )
+
@Mock private lateinit var carrierConfigTracker: CarrierConfigTracker
@Before
@@ -687,16 +697,14 @@ class MobileIconsInteractorTest : SysuiTestCase() {
}
companion object {
- private val tableLogBuffer =
- TableLogBuffer(8, "MobileIconsInteractorTest", FakeSystemClock())
private const val SUB_1_ID = 1
private val SUB_1 = SubscriptionModel(subscriptionId = SUB_1_ID)
- private val CONNECTION_1 = FakeMobileConnectionRepository(SUB_1_ID, tableLogBuffer)
+ private val CONNECTION_1 = FakeMobileConnectionRepository(SUB_1_ID, mock())
private const val SUB_2_ID = 2
private val SUB_2 = SubscriptionModel(subscriptionId = SUB_2_ID)
- private val CONNECTION_2 = FakeMobileConnectionRepository(SUB_2_ID, tableLogBuffer)
+ private val CONNECTION_2 = FakeMobileConnectionRepository(SUB_2_ID, mock())
private const val SUB_3_ID = 3
private val SUB_3_OPP =
@@ -705,7 +713,7 @@ class MobileIconsInteractorTest : SysuiTestCase() {
isOpportunistic = true,
groupUuid = ParcelUuid(UUID.randomUUID()),
)
- private val CONNECTION_3 = FakeMobileConnectionRepository(SUB_3_ID, tableLogBuffer)
+ private val CONNECTION_3 = FakeMobileConnectionRepository(SUB_3_ID, mock())
private const val SUB_4_ID = 4
private val SUB_4_OPP =
@@ -714,6 +722,6 @@ class MobileIconsInteractorTest : SysuiTestCase() {
isOpportunistic = true,
groupUuid = ParcelUuid(UUID.randomUUID()),
)
- private val CONNECTION_4 = FakeMobileConnectionRepository(SUB_4_ID, tableLogBuffer)
+ private val CONNECTION_4 = FakeMobileConnectionRepository(SUB_4_ID, mock())
}
}
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index a3b4a0f51c75..a510d1663298 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -490,7 +490,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
mMainHandler, context,
new PolicyWarningUIController.NotificationController(context));
mSecurityPolicy = new AccessibilitySecurityPolicy(policyWarningUIController, mContext,
- this);
+ this, LocalServices.getService(PackageManagerInternal.class));
mA11yWindowManager = new AccessibilityWindowManager(mLock, mMainHandler,
mWindowManagerService, this, mSecurityPolicy, this, mTraceManager);
mA11yDisplayListener = new AccessibilityDisplayListener(mContext, mMainHandler);
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilitySecurityPolicy.java b/services/accessibility/java/com/android/server/accessibility/AccessibilitySecurityPolicy.java
index 88656239e59b..65c1873498a1 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilitySecurityPolicy.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilitySecurityPolicy.java
@@ -29,6 +29,7 @@ import android.appwidget.AppWidgetManagerInternal;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.pm.UserInfo;
@@ -99,6 +100,7 @@ public class AccessibilitySecurityPolicy {
private final Context mContext;
private final PackageManager mPackageManager;
+ private final PackageManagerInternal mPackageManagerInternal;
private final UserManager mUserManager;
private final AppOpsManager mAppOpsManager;
private final AccessibilityUserManager mAccessibilityUserManager;
@@ -116,10 +118,12 @@ public class AccessibilitySecurityPolicy {
*/
public AccessibilitySecurityPolicy(PolicyWarningUIController policyWarningUIController,
@NonNull Context context,
- @NonNull AccessibilityUserManager a11yUserManager) {
+ @NonNull AccessibilityUserManager a11yUserManager,
+ @NonNull PackageManagerInternal packageManagerInternal) {
mContext = context;
mAccessibilityUserManager = a11yUserManager;
mPackageManager = mContext.getPackageManager();
+ mPackageManagerInternal = packageManagerInternal;
mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
mPolicyWarningUIController = policyWarningUIController;
@@ -513,12 +517,7 @@ public class AccessibilitySecurityPolicy {
private boolean isValidPackageForUid(String packageName, int uid) {
final long token = Binder.clearCallingIdentity();
try {
- // Since we treat calls from a profile as if made by its parent, using
- // MATCH_ANY_USER to query the uid of the given package name.
- return uid == mPackageManager.getPackageUidAsUser(
- packageName, PackageManager.MATCH_ANY_USER, UserHandle.getUserId(uid));
- } catch (PackageManager.NameNotFoundException e) {
- return false;
+ return mPackageManagerInternal.isSameApp(packageName, uid, UserHandle.getUserId(uid));
} finally {
Binder.restoreCallingIdentity(token);
}
diff --git a/services/accessibility/java/com/android/server/accessibility/SystemActionPerformer.java b/services/accessibility/java/com/android/server/accessibility/SystemActionPerformer.java
index a13df475d25d..9747579fa231 100644
--- a/services/accessibility/java/com/android/server/accessibility/SystemActionPerformer.java
+++ b/services/accessibility/java/com/android/server/accessibility/SystemActionPerformer.java
@@ -36,6 +36,7 @@ import android.view.WindowManager;
import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
import com.android.internal.R;
+import com.android.internal.accessibility.util.AccessibilityUtils;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ScreenshotHelper;
@@ -302,8 +303,10 @@ public class SystemActionPerformer {
case AccessibilityService.GLOBAL_ACTION_TAKE_SCREENSHOT:
return takeScreenshot();
case AccessibilityService.GLOBAL_ACTION_KEYCODE_HEADSETHOOK:
- sendDownAndUpKeyEvents(KeyEvent.KEYCODE_HEADSETHOOK,
- InputDevice.SOURCE_KEYBOARD);
+ if (!AccessibilityUtils.interceptHeadsetHookForActiveCall(mContext)) {
+ sendDownAndUpKeyEvents(KeyEvent.KEYCODE_HEADSETHOOK,
+ InputDevice.SOURCE_KEYBOARD);
+ }
return true;
case AccessibilityService.GLOBAL_ACTION_DPAD_UP:
sendDownAndUpKeyEvents(KeyEvent.KEYCODE_DPAD_UP,
diff --git a/services/autofill/java/com/android/server/autofill/Helper.java b/services/autofill/java/com/android/server/autofill/Helper.java
index bc5d6457c945..ac770439a524 100644
--- a/services/autofill/java/com/android/server/autofill/Helper.java
+++ b/services/autofill/java/com/android/server/autofill/Helper.java
@@ -16,13 +16,18 @@
package com.android.server.autofill;
+import static com.android.server.autofill.Helper.sDebug;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.assist.AssistStructure;
import android.app.assist.AssistStructure.ViewNode;
import android.app.assist.AssistStructure.WindowNode;
import android.content.ComponentName;
+import android.content.Context;
+import android.hardware.display.DisplayManager;
import android.metrics.LogMaker;
+import android.os.UserManager;
import android.service.autofill.Dataset;
import android.service.autofill.InternalSanitizer;
import android.service.autofill.SaveInfo;
@@ -30,6 +35,7 @@ import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Slog;
+import android.view.Display;
import android.view.View;
import android.view.WindowManager;
import android.view.autofill.AutofillId;
@@ -37,6 +43,7 @@ import android.view.autofill.AutofillValue;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.util.ArrayUtils;
+import com.android.server.utils.Slogf;
import java.io.PrintWriter;
import java.util.ArrayDeque;
@@ -281,6 +288,38 @@ public final class Helper {
return true;
}
+ /**
+ * Gets a context with the proper display id.
+ *
+ * <p>For most cases it will return the provided context, but on devices that
+ * {@link UserManager#isVisibleBackgroundUsersEnabled() support visible background users}, it
+ * will return a context with the display pased as parameter.
+ */
+ static Context getDisplayContext(Context context, int displayId) {
+ if (!UserManager.isVisibleBackgroundUsersEnabled()) {
+ return context;
+ }
+ if (context.getDisplayId() == displayId) {
+ if (sDebug) {
+ Slogf.d(TAG, "getDisplayContext(): context %s already has displayId %d", context,
+ displayId);
+ }
+ return context;
+ }
+ if (sDebug) {
+ Slogf.d(TAG, "Creating context for display %d", displayId);
+ }
+ Display display = context.getSystemService(DisplayManager.class).getDisplay(displayId);
+ if (display == null) {
+ Slogf.wtf(TAG, "Could not get context with displayId %d, Autofill operations will "
+ + "probably fail)", displayId);
+ return context;
+ }
+
+ return context.createDisplayContext(display);
+ }
+
+
private interface ViewNodeFilter {
boolean matches(ViewNode node);
}
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 3ab5bca215dc..f83d7342b6e3 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -164,10 +164,12 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.util.ArrayUtils;
+import com.android.server.LocalServices;
import com.android.server.autofill.ui.AutoFillUI;
import com.android.server.autofill.ui.InlineFillUi;
import com.android.server.autofill.ui.PendingUi;
import com.android.server.inputmethod.InputMethodManagerInternal;
+import com.android.server.wm.ActivityTaskManagerInternal;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
@@ -214,7 +216,12 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
private final AutofillManagerServiceImpl mService;
private final Handler mHandler;
private final AutoFillUI mUi;
- @NonNull private final Context mContext;
+
+ /**
+ * Context associated with the session, it has the same {@link Context#getDisplayId() displayId}
+ * of the activity being autofilled.
+ */
+ private final Context mContext;
private final MetricsLogger mMetricsLogger = new MetricsLogger();
@@ -1352,7 +1359,9 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
mHasCallback = hasCallback;
mUiLatencyHistory = uiLatencyHistory;
mWtfHistory = wtfHistory;
- mContext = context;
+ int displayId = LocalServices.getService(ActivityTaskManagerInternal.class)
+ .getDisplayId(activityToken);
+ mContext = Helper.getDisplayContext(context, displayId);
mComponentName = componentName;
mCompatMode = compatMode;
mSessionState = STATE_ACTIVE;
@@ -3401,7 +3410,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
final long saveUiDisplayStartTimestamp = SystemClock.elapsedRealtime();
getUiForShowing().showSaveUi(serviceLabel, serviceIcon,
mService.getServicePackageName(), saveInfo, this,
- mComponentName, this, userId, mPendingSaveUi, isUpdate, mCompatMode,
+ mComponentName, this, mContext, mPendingSaveUi, isUpdate, mCompatMode,
response.getShowSaveDialogIcon());
mSaveEventLogger.maybeSetLatencySaveUiDisplayMillis(
SystemClock.elapsedRealtime()- saveUiDisplayStartTimestamp);
@@ -4272,7 +4281,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
getUiForShowing().showFillUi(filledId, response, filterText,
mService.getServicePackageName(), mComponentName,
- targetLabel, targetIcon, this, userId, id, mCompatMode);
+ targetLabel, targetIcon, this, mContext, id, mCompatMode);
synchronized (mLock) {
mPresentationStatsEventLogger.maybeSetCountShown(
@@ -5453,6 +5462,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
pw.print(prefix); pw.print("uid: "); pw.println(uid);
pw.print(prefix); pw.print("taskId: "); pw.println(taskId);
pw.print(prefix); pw.print("flags: "); pw.println(mFlags);
+ pw.print(prefix); pw.print("displayId: "); pw.println(mContext.getDisplayId());
pw.print(prefix); pw.print("state: "); pw.println(sessionStateAsString(mSessionState));
pw.print(prefix); pw.print("mComponentName: "); pw.println(mComponentName);
pw.print(prefix); pw.print("mActivityToken: "); pw.println(mActivityToken);
diff --git a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
index cfd66f1e7351..b3cbe45ea4a7 100644
--- a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
+++ b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
@@ -23,7 +23,6 @@ import static com.android.server.autofill.Helper.sVerbose;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.annotation.UserIdInt;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -53,6 +52,7 @@ import com.android.server.LocalServices;
import com.android.server.UiModeManagerInternal;
import com.android.server.UiThread;
import com.android.server.autofill.Helper;
+import com.android.server.utils.Slogf;
import java.io.PrintWriter;
@@ -198,6 +198,7 @@ public final class AutoFillUI {
* @param serviceIcon icon of autofill service
* @param callback identifier for the caller
* @param userId the user associated wit the session
+ * @param context context with the proper state (like display id) to show the UI
* @param sessionId id of the autofill session
* @param compatMode whether the app is being autofilled in compatibility mode.
*/
@@ -205,11 +206,11 @@ public final class AutoFillUI {
@Nullable String filterText, @Nullable String servicePackageName,
@NonNull ComponentName componentName, @NonNull CharSequence serviceLabel,
@NonNull Drawable serviceIcon, @NonNull AutoFillUiCallback callback,
- @UserIdInt int userId, int sessionId, boolean compatMode) {
+ @NonNull Context context, int sessionId, boolean compatMode) {
if (sDebug) {
final int size = filterText == null ? 0 : filterText.length();
- Slog.d(TAG, "showFillUi(): id=" + focusedId + ", filter=" + size + " chars, userId="
- + userId);
+ Slogf.d(TAG, "showFillUi(): id=%s, filter=%d chars, displayId=%d", focusedId, size,
+ context.getDisplayId());
}
final LogMaker log = Helper
.newLogMaker(MetricsEvent.AUTOFILL_FILL_UI, componentName, servicePackageName,
@@ -224,10 +225,8 @@ public final class AutoFillUI {
return;
}
hideAllUiThread(callback);
- mFillUi = new FillUi(mContext, userId, response, focusedId,
- filterText, mOverlayControl, serviceLabel, serviceIcon,
- mUiModeMgr.isNightMode(),
- new FillUi.Callback() {
+ mFillUi = new FillUi(context, response, focusedId, filterText, mOverlayControl,
+ serviceLabel, serviceIcon, mUiModeMgr.isNightMode(), new FillUi.Callback() {
@Override
public void onResponsePicked(FillResponse response) {
log.setType(MetricsEvent.TYPE_DETAIL);
@@ -325,12 +324,12 @@ public final class AutoFillUI {
public void showSaveUi(@NonNull CharSequence serviceLabel, @NonNull Drawable serviceIcon,
@Nullable String servicePackageName, @NonNull SaveInfo info,
@NonNull ValueFinder valueFinder, @NonNull ComponentName componentName,
- @NonNull AutoFillUiCallback callback, @UserIdInt int userId,
+ @NonNull AutoFillUiCallback callback, @NonNull Context context,
@NonNull PendingUi pendingSaveUi, boolean isUpdate, boolean compatMode,
boolean showServiceIcon) {
if (sVerbose) {
- Slog.v(TAG, "showSaveUi(update=" + isUpdate + ") for " + componentName.toShortString()
- + " and user " + userId + ": " + info);
+ Slogf.v(TAG, "showSaveUi(update=%b) for %s and display %d: %s", isUpdate,
+ componentName.toShortString(), context.getDisplayId(), info);
}
int numIds = 0;
numIds += info.getRequiredIds() == null ? 0 : info.getRequiredIds().length;
@@ -350,7 +349,7 @@ public final class AutoFillUI {
}
hideAllUiThread(callback);
mSaveUiCallback = callback;
- mSaveUi = new SaveUi(mContext, userId, pendingSaveUi, serviceLabel, serviceIcon,
+ mSaveUi = new SaveUi(context, pendingSaveUi, serviceLabel, serviceIcon,
servicePackageName, componentName, info, valueFinder, mOverlayControl,
new SaveUi.OnSaveListener() {
@Override
diff --git a/services/autofill/java/com/android/server/autofill/ui/DisplayHelper.java b/services/autofill/java/com/android/server/autofill/ui/DisplayHelper.java
deleted file mode 100644
index 53534809a1ae..000000000000
--- a/services/autofill/java/com/android/server/autofill/ui/DisplayHelper.java
+++ /dev/null
@@ -1,68 +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.server.autofill.ui;
-
-import static com.android.server.autofill.Helper.sDebug;
-
-import android.annotation.UserIdInt;
-import android.content.Context;
-import android.hardware.display.DisplayManager;
-import android.os.UserManager;
-import android.view.Display;
-
-import com.android.server.LocalServices;
-import com.android.server.pm.UserManagerInternal;
-import com.android.server.utils.Slogf;
-
-/**
- * Helper for display-related needs.
- */
-final class DisplayHelper {
-
- private static final String TAG = "AutofillDisplayHelper";
-
- private static final UserManagerInternal sUmi = LocalServices
- .getService(UserManagerInternal.class);
-
- /**
- * Gets a context with the proper display id set for the given user.
- *
- * <p>For most cases it will return the provided context, but on devices that
- * {@link UserManager#isVisibleBackgroundUsersEnabled() support visible background users}, it
- * will return a context with the display the user started visible on.
- */
- static Context getDisplayContext(Context context, @UserIdInt int userId) {
- if (!UserManager.isVisibleBackgroundUsersEnabled()) {
- return context;
- }
- int displayId = sUmi.getMainDisplayAssignedToUser(userId);
- if (sDebug) {
- Slogf.d(TAG, "Creating context for display %d for user %d", displayId, userId);
- }
- Display display = context.getSystemService(DisplayManager.class).getDisplay(displayId);
- if (display == null) {
- Slogf.wtf(TAG, "Could not get display with id %d (which is associated with user %d; "
- + "FillUi operations will probably fail", displayId, userId);
- return context;
- }
-
- return context.createDisplayContext(display);
- }
-
- private DisplayHelper() {
- throw new UnsupportedOperationException("Contains only static methods");
- }
-}
diff --git a/services/autofill/java/com/android/server/autofill/ui/FillUi.java b/services/autofill/java/com/android/server/autofill/ui/FillUi.java
index b651ae592866..129ce72e037d 100644
--- a/services/autofill/java/com/android/server/autofill/ui/FillUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/FillUi.java
@@ -22,7 +22,6 @@ import static com.android.server.autofill.Helper.sVerbose;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.annotation.UserIdInt;
import android.content.Context;
import android.content.IntentSender;
import android.content.pm.PackageManager;
@@ -61,6 +60,7 @@ import com.android.internal.R;
import com.android.server.UiThread;
import com.android.server.autofill.AutofillManagerService;
import com.android.server.autofill.Helper;
+import com.android.server.utils.Slogf;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -134,14 +134,15 @@ final class FillUi {
return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK);
}
- FillUi(@NonNull Context systemContext, @UserIdInt int userId, @NonNull FillResponse response,
+ FillUi(@NonNull Context context, @NonNull FillResponse response,
@NonNull AutofillId focusedViewId, @Nullable String filterText,
@NonNull OverlayControl overlayControl, @NonNull CharSequence serviceLabel,
@NonNull Drawable serviceIcon, boolean nightMode, @NonNull Callback callback) {
- if (sVerbose) Slog.v(TAG, "nightMode: " + nightMode);
+ if (sVerbose) {
+ Slogf.v(TAG, "nightMode: %b displayId: %d", nightMode, context.getDisplayId());
+ }
mThemeId = nightMode ? THEME_ID_DARK : THEME_ID_LIGHT;
mCallback = callback;
- Context context = DisplayHelper.getDisplayContext(systemContext, userId);
mFullScreen = isFullScreen(context);
mContext = new ContextThemeWrapper(context, mThemeId);
diff --git a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
index aec0bdfa3a76..12042594fefb 100644
--- a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
@@ -21,7 +21,6 @@ import static com.android.server.autofill.Helper.sVerbose;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.annotation.UserIdInt;
import android.app.Dialog;
import android.app.PendingIntent;
import android.content.ComponentName;
@@ -71,6 +70,7 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.util.ArrayUtils;
import com.android.server.UiThread;
import com.android.server.autofill.Helper;
+import com.android.server.utils.Slogf;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -173,14 +173,15 @@ final class SaveUi {
private boolean mDestroyed;
- SaveUi(@NonNull Context systemContext, @UserIdInt int userId, @NonNull PendingUi pendingUi,
+ SaveUi(@NonNull Context context, @NonNull PendingUi pendingUi,
@NonNull CharSequence serviceLabel, @NonNull Drawable serviceIcon,
@Nullable String servicePackageName, @NonNull ComponentName componentName,
@NonNull SaveInfo info, @NonNull ValueFinder valueFinder,
@NonNull OverlayControl overlayControl, @NonNull OnSaveListener listener,
boolean nightMode, boolean isUpdate, boolean compatMode, boolean showServiceIcon) {
- Context context = DisplayHelper.getDisplayContext(systemContext, userId);
- if (sVerbose) Slog.v(TAG, "nightMode: " + nightMode);
+ if (sVerbose) {
+ Slogf.v(TAG, "nightMode: %b displayId: %d", nightMode, context.getDisplayId());
+ }
mThemeId = nightMode ? THEME_ID_DARK : THEME_ID_LIGHT;
mPendingUi = pendingUi;
mListener = new OneActionThenDestroyListener(listener);
diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java
index 7c32627dd1b1..55e805ab4ad0 100644
--- a/services/core/java/com/android/server/UiModeManagerService.java
+++ b/services/core/java/com/android/server/UiModeManagerService.java
@@ -28,6 +28,7 @@ import static android.app.UiModeManager.MODE_NIGHT_YES;
import static android.app.UiModeManager.PROJECTION_TYPE_AUTOMOTIVE;
import static android.app.UiModeManager.PROJECTION_TYPE_NONE;
import static android.os.UserHandle.USER_SYSTEM;
+import static android.os.UserHandle.getCallingUserId;
import static android.provider.Settings.Secure.CONTRAST_LEVEL;
import static android.util.TimeUtils.isTimeBetween;
@@ -199,8 +200,8 @@ final class UiModeManagerService extends SystemService {
private PowerManagerInternal mLocalPowerManager;
@GuardedBy("mLock")
- private final RemoteCallbackList<IUiModeManagerCallback> mUiModeManagerCallbacks =
- new RemoteCallbackList<IUiModeManagerCallback>();
+ private final SparseArray<RemoteCallbackList<IUiModeManagerCallback>> mUiModeManagerCallbacks =
+ new SparseArray<>();
@GuardedBy("mLock")
@Nullable
@@ -371,8 +372,9 @@ final class UiModeManagerService extends SystemService {
synchronized (mLock) {
if (updateContrastLocked()) {
float contrast = getContrastLocked();
- mUiModeManagerCallbacks.broadcast(ignoreRemoteException(callback ->
- callback.notifyContrastChanged(contrast)));
+ mUiModeManagerCallbacks.get(mCurrentUser, new RemoteCallbackList<>())
+ .broadcast(ignoreRemoteException(
+ callback -> callback.notifyContrastChanged(contrast)));
}
}
}
@@ -664,8 +666,12 @@ final class UiModeManagerService extends SystemService {
private final IUiModeManager.Stub mService = new IUiModeManager.Stub() {
@Override
public void addCallback(IUiModeManagerCallback callback) {
+ int userId = getCallingUserId();
synchronized (mLock) {
- mUiModeManagerCallbacks.register(callback);
+ if (!mUiModeManagerCallbacks.contains(userId)) {
+ mUiModeManagerCallbacks.put(userId, new RemoteCallbackList<>());
+ }
+ mUiModeManagerCallbacks.get(userId).register(callback);
}
}
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index d140403f77c3..6360e2a0d089 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -167,7 +167,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub
.onMalformedInput(CodingErrorAction.REPLACE)
.onUnmappableCharacter(CodingErrorAction.REPLACE)
.replaceWith("?");
- private static final int MAX_LOW_POWER_STATS_SIZE = 16384;
+ private static final int MAX_LOW_POWER_STATS_SIZE = 32768;
private static final int POWER_STATS_QUERY_TIMEOUT_MILLIS = 2000;
private static final String EMPTY = "Empty";
diff --git a/services/core/java/com/android/server/am/ContentProviderHelper.java b/services/core/java/com/android/server/am/ContentProviderHelper.java
index d8cb094caa65..6015e5f02221 100644
--- a/services/core/java/com/android/server/am/ContentProviderHelper.java
+++ b/services/core/java/com/android/server/am/ContentProviderHelper.java
@@ -778,7 +778,7 @@ public class ContentProviderHelper {
* Drop a content provider from a ProcessRecord's bookkeeping
*/
void removeContentProvider(IBinder connection, boolean stable) {
- mService.enforceNotIsolatedOrSdkSandboxCaller("removeContentProvider");
+ mService.enforceNotIsolatedCaller("removeContentProvider");
final long ident = Binder.clearCallingIdentity();
try {
ContentProviderConnection conn;
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 33f05525066e..0d89ba88c1cf 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -167,6 +167,51 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
private static final int RINGBUFFER_MAX = 100;
+ private static final float[] BRIGHTNESS_RANGE_BOUNDARIES = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30, 40, 50, 60, 70, 80,
+ 90, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1200,
+ 1400, 1600, 1800, 2000, 2250, 2500, 2750, 3000};
+ private static final int[] BRIGHTNESS_RANGE_INDEX = {
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_UNKNOWN,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_0_1,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_1_2,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_2_3,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_3_4,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_4_5,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_5_6,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_6_7,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_7_8,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_8_9,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_9_10,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_10_20,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_20_30,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_30_40,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_40_50,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_50_60,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_60_70,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_70_80,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_80_90,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_90_100,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_100_200,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_200_300,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_300_400,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_400_500,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_500_600,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_600_700,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_700_800,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_800_900,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_900_1000,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_1000_1200,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_1200_1400,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_1400_1600,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_1600_1800,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_1800_2000,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_2000_2250,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_2250_2500,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_2500_2750,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_2750_3000,
+ };
+
private final String mTag;
private final Object mLock = new Object();
@@ -1937,8 +1982,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
? BrightnessEvent.FLAG_USER_SET : 0));
Slog.i(mTag, newEvent.toString(/* includeTime= */ false));
- if (userSetBrightnessChanged) {
- logManualBrightnessEvent(newEvent);
+ if (userSetBrightnessChanged
+ || newEvent.getReason().getReason() != BrightnessReason.REASON_TEMPORARY) {
+ logBrightnessEvent(newEvent, unthrottledBrightnessState);
}
if (mBrightnessEventRingBuffer != null) {
mBrightnessEventRingBuffer.append(newEvent);
@@ -3091,7 +3137,63 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
}
}
- private void logManualBrightnessEvent(BrightnessEvent event) {
+ // Return bucket index of range_[left]_[right] where
+ // left <= nits < right
+ private int nitsToRangeIndex(float nits) {
+ for (int i = 0; i < BRIGHTNESS_RANGE_BOUNDARIES.length; i++) {
+ if (nits < BRIGHTNESS_RANGE_BOUNDARIES[i]) {
+ return BRIGHTNESS_RANGE_INDEX[i];
+ }
+ }
+ return FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_3000_INF;
+ }
+
+ private int convertBrightnessReasonToStatsEnum(int brightnessReason) {
+ switch(brightnessReason) {
+ case BrightnessReason.REASON_UNKNOWN:
+ return FrameworkStatsLog
+ .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_UNKNOWN;
+ case BrightnessReason.REASON_MANUAL:
+ return FrameworkStatsLog
+ .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_MANUAL;
+ case BrightnessReason.REASON_DOZE:
+ return FrameworkStatsLog
+ .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_DOZE;
+ case BrightnessReason.REASON_DOZE_DEFAULT:
+ return FrameworkStatsLog
+ .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_DOZE_DEFAULT;
+ case BrightnessReason.REASON_AUTOMATIC:
+ return FrameworkStatsLog
+ .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_AUTOMATIC;
+ case BrightnessReason.REASON_SCREEN_OFF:
+ return FrameworkStatsLog
+ .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_SCREEN_OFF;
+ case BrightnessReason.REASON_OVERRIDE:
+ return FrameworkStatsLog
+ .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_OVERRIDE;
+ case BrightnessReason.REASON_TEMPORARY:
+ return FrameworkStatsLog
+ .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_TEMPORARY;
+ case BrightnessReason.REASON_BOOST:
+ return FrameworkStatsLog
+ .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_BOOST;
+ case BrightnessReason.REASON_SCREEN_OFF_BRIGHTNESS_SENSOR:
+ return FrameworkStatsLog
+ .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_SCREEN_OFF_BRIGHTNESS_SENSOR;
+ case BrightnessReason.REASON_FOLLOWER:
+ return FrameworkStatsLog
+ .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_FOLLOWER;
+ }
+ return FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_UNKNOWN;
+ }
+
+ private void logBrightnessEvent(BrightnessEvent event, float unmodifiedBrightness) {
+ int modifier = event.getReason().getModifier();
+ int flags = event.getFlags();
+ // It's easier to check if the brightness is at maximum level using the brightness
+ // value untouched by any modifiers
+ boolean brightnessIsMax = unmodifiedBrightness == event.getHbmMax();
+ float brightnessInNits = convertToAdjustedNits(event.getBrightness());
float appliedLowPowerMode = event.isLowPowerModeSet() ? event.getPowerFactor() : -1f;
int appliedRbcStrength = event.isRbcEnabled() ? event.getRbcStrength() : -1;
float appliedHbmMaxNits =
@@ -3105,7 +3207,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
if (mIsDisplayInternal) {
FrameworkStatsLog.write(FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED,
convertToAdjustedNits(event.getInitialBrightness()),
- convertToAdjustedNits(event.getBrightness()),
+ brightnessInNits,
event.getLux(),
event.getPhysicalDisplayId(),
event.wasShortTermModelActive(),
@@ -3114,7 +3216,21 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
appliedHbmMaxNits,
appliedThermalCapNits,
event.isAutomaticBrightnessEnabled(),
- FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__REASON__REASON_MANUAL);
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__REASON__REASON_MANUAL,
+ convertBrightnessReasonToStatsEnum(event.getReason().getReason()),
+ nitsToRangeIndex(brightnessInNits),
+ brightnessIsMax,
+ event.getHbmMode() == BrightnessInfo.HIGH_BRIGHTNESS_MODE_SUNLIGHT,
+ event.getHbmMode() == BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR,
+ (modifier & BrightnessReason.MODIFIER_LOW_POWER) > 0,
+ mBrightnessThrottler.getBrightnessMaxReason(),
+ (modifier & BrightnessReason.MODIFIER_DIMMED) > 0,
+ event.isRbcEnabled(),
+ (flags & BrightnessEvent.FLAG_INVALID_LUX) > 0,
+ (flags & BrightnessEvent.FLAG_DOZE_SCALE) > 0,
+ (flags & BrightnessEvent.FLAG_USER_SET) > 0,
+ (flags & BrightnessEvent.FLAG_IDLE_CURVE) > 0,
+ (flags & BrightnessEvent.FLAG_LOW_POWER_MODE) > 0);
}
}
diff --git a/services/core/java/com/android/server/display/DisplayPowerController2.java b/services/core/java/com/android/server/display/DisplayPowerController2.java
index f96b58e9ef2d..9e8c47f64926 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController2.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController2.java
@@ -157,6 +157,51 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
private static final int RINGBUFFER_MAX = 100;
+ private static final float[] BRIGHTNESS_RANGE_BOUNDARIES = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30, 40, 50, 60, 70, 80,
+ 90, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1200,
+ 1400, 1600, 1800, 2000, 2250, 2500, 2750, 3000};
+ private static final int[] BRIGHTNESS_RANGE_INDEX = {
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_UNKNOWN,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_0_1,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_1_2,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_2_3,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_3_4,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_4_5,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_5_6,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_6_7,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_7_8,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_8_9,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_9_10,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_10_20,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_20_30,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_30_40,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_40_50,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_50_60,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_60_70,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_70_80,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_80_90,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_90_100,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_100_200,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_200_300,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_300_400,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_400_500,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_500_600,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_600_700,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_700_800,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_800_900,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_900_1000,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_1000_1200,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_1200_1400,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_1400_1600,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_1600_1800,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_1800_2000,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_2000_2250,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_2250_2500,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_2500_2750,
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_2750_3000,
+ };
+
private final String mTag;
private final Object mLock = new Object();
@@ -1570,8 +1615,9 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
? BrightnessEvent.FLAG_USER_SET : 0));
Slog.i(mTag, newEvent.toString(/* includeTime= */ false));
- if (userSetBrightnessChanged) {
- logManualBrightnessEvent(newEvent);
+ if (userSetBrightnessChanged
+ || newEvent.getReason().getReason() != BrightnessReason.REASON_TEMPORARY) {
+ logBrightnessEvent(newEvent, unthrottledBrightnessState);
}
if (mBrightnessEventRingBuffer != null) {
mBrightnessEventRingBuffer.append(newEvent);
@@ -2448,7 +2494,64 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
}
}
- private void logManualBrightnessEvent(BrightnessEvent event) {
+ // Return bucket index of range_[left]_[right] where
+ // left <= nits < right
+ private int nitsToRangeIndex(float nits) {
+ for (int i = 0; i < BRIGHTNESS_RANGE_BOUNDARIES.length; i++) {
+ if (nits < BRIGHTNESS_RANGE_BOUNDARIES[i]) {
+ return BRIGHTNESS_RANGE_INDEX[i];
+ }
+ }
+ return FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__BUCKET_INDEX__RANGE_3000_INF;
+ }
+
+ private int convertBrightnessReasonToStatsEnum(int brightnessReason) {
+ switch(brightnessReason) {
+ case BrightnessReason.REASON_UNKNOWN:
+ return FrameworkStatsLog
+ .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_UNKNOWN;
+ case BrightnessReason.REASON_MANUAL:
+ return FrameworkStatsLog
+ .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_MANUAL;
+ case BrightnessReason.REASON_DOZE:
+ return FrameworkStatsLog
+ .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_DOZE;
+ case BrightnessReason.REASON_DOZE_DEFAULT:
+ return FrameworkStatsLog
+ .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_DOZE_DEFAULT;
+ case BrightnessReason.REASON_AUTOMATIC:
+ return FrameworkStatsLog
+ .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_AUTOMATIC;
+ case BrightnessReason.REASON_SCREEN_OFF:
+ return FrameworkStatsLog
+ .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_SCREEN_OFF;
+ case BrightnessReason.REASON_OVERRIDE:
+ return FrameworkStatsLog
+ .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_OVERRIDE;
+ case BrightnessReason.REASON_TEMPORARY:
+ return FrameworkStatsLog
+ .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_TEMPORARY;
+ case BrightnessReason.REASON_BOOST:
+ return FrameworkStatsLog
+ .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_BOOST;
+ case BrightnessReason.REASON_SCREEN_OFF_BRIGHTNESS_SENSOR:
+ return FrameworkStatsLog
+ .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_SCREEN_OFF_BRIGHTNESS_SENSOR;
+ case BrightnessReason.REASON_FOLLOWER:
+ return FrameworkStatsLog
+ .DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_FOLLOWER;
+ }
+ return FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__ENTIRE_REASON__REASON_UNKNOWN;
+ }
+
+ private void logBrightnessEvent(BrightnessEvent event, float unmodifiedBrightness) {
+ int modifier = event.getReason().getModifier();
+ int flags = event.getFlags();
+ // It's easier to check if the brightness is at maximum level using the brightness
+ // value untouched by any modifiers
+ boolean brightnessIsMax = unmodifiedBrightness == event.getHbmMax();
+ float brightnessInNits =
+ mDisplayBrightnessController.convertToAdjustedNits(event.getBrightness());
float appliedLowPowerMode = event.isLowPowerModeSet() ? event.getPowerFactor() : -1f;
int appliedRbcStrength = event.isRbcEnabled() ? event.getRbcStrength() : -1;
float appliedHbmMaxNits =
@@ -2462,7 +2565,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
FrameworkStatsLog.write(FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED,
mDisplayBrightnessController
.convertToAdjustedNits(event.getInitialBrightness()),
- mDisplayBrightnessController.convertToAdjustedNits(event.getBrightness()),
+ brightnessInNits,
event.getLux(),
event.getPhysicalDisplayId(),
event.wasShortTermModelActive(),
@@ -2471,7 +2574,21 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
appliedHbmMaxNits,
appliedThermalCapNits,
event.isAutomaticBrightnessEnabled(),
- FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__REASON__REASON_MANUAL);
+ FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED__REASON__REASON_MANUAL,
+ convertBrightnessReasonToStatsEnum(event.getReason().getReason()),
+ nitsToRangeIndex(brightnessInNits),
+ brightnessIsMax,
+ event.getHbmMode() == BrightnessInfo.HIGH_BRIGHTNESS_MODE_SUNLIGHT,
+ event.getHbmMode() == BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR,
+ (modifier & BrightnessReason.MODIFIER_LOW_POWER) > 0,
+ mBrightnessThrottler.getBrightnessMaxReason(),
+ (modifier & BrightnessReason.MODIFIER_DIMMED) > 0,
+ event.isRbcEnabled(),
+ (flags & BrightnessEvent.FLAG_INVALID_LUX) > 0,
+ (flags & BrightnessEvent.FLAG_DOZE_SCALE) > 0,
+ (flags & BrightnessEvent.FLAG_USER_SET) > 0,
+ (flags & BrightnessEvent.FLAG_IDLE_CURVE) > 0,
+ (flags & BrightnessEvent.FLAG_LOW_POWER_MODE) > 0);
}
}
diff --git a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
index 7a51126eff2d..377b8cf1230e 100644
--- a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
+++ b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
@@ -395,8 +395,8 @@ public final class MediaProjectionManagerService extends SystemService
synchronized (mLock) {
final boolean consentGranted =
consentResult == RECORD_CONTENT_DISPLAY || consentResult == RECORD_CONTENT_TASK;
- if (consentGranted && projection == null || !isCurrentProjection(
- projection.asBinder())) {
+ if (consentGranted && !isCurrentProjection(
+ projection == null ? null : projection.asBinder())) {
Slog.v(TAG, "Reusing token: Ignore consent result of " + consentResult + " for a "
+ "token that isn't current");
return;
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index d1d6f5f10bc6..33e6a8f15df2 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -124,6 +124,7 @@ import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_C
import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_CHANNEL_PREFERENCES;
import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_PREFERENCES;
import static com.android.internal.util.Preconditions.checkArgument;
+import static com.android.internal.util.Preconditions.checkNotNull;
import static com.android.server.am.PendingIntentRecord.FLAG_ACTIVITY_SENDER;
import static com.android.server.am.PendingIntentRecord.FLAG_BROADCAST_SENDER;
import static com.android.server.am.PendingIntentRecord.FLAG_SERVICE_SENDER;
@@ -277,7 +278,6 @@ import android.widget.Toast;
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.app.IAppOpsService;
import com.android.internal.compat.IPlatformCompat;
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
import com.android.internal.config.sysui.SystemUiSystemPropertiesFlags;
@@ -306,7 +306,6 @@ import com.android.server.EventLogTags;
import com.android.server.IoThread;
import com.android.server.LocalServices;
import com.android.server.SystemService;
-import com.android.server.UiThread;
import com.android.server.job.JobSchedulerInternal;
import com.android.server.lights.LightsManager;
import com.android.server.lights.LogicalLight;
@@ -560,10 +559,10 @@ public class NotificationManagerService extends SystemService {
private PermissionHelper mPermissionHelper;
private UsageStatsManagerInternal mUsageStatsManagerInternal;
private TelecomManager mTelecomManager;
+ private PostNotificationTrackerFactory mPostNotificationTrackerFactory;
final IBinder mForegroundToken = new Binder();
private WorkerHandler mHandler;
- private Handler mUiHandler;
private final HandlerThread mRankingThread = new HandlerThread("ranker",
Process.THREAD_PRIORITY_BACKGROUND);
@@ -572,7 +571,6 @@ public class NotificationManagerService extends SystemService {
private boolean mUseAttentionLight;
boolean mHasLight = true;
- boolean mLightEnabled;
boolean mSystemReady;
private boolean mDisableNotificationEffects;
@@ -629,7 +627,6 @@ public class NotificationManagerService extends SystemService {
ArrayList<String> mLights = new ArrayList<>();
private AppOpsManager mAppOps;
- private IAppOpsService mAppOpsService;
private UsageStatsManagerInternal mAppUsageStats;
private DevicePolicyManagerInternal mDpm;
private StatsManager mStatsManager;
@@ -926,7 +923,7 @@ public class NotificationManagerService extends SystemService {
if (oldFlags != flags) {
summary.getSbn().getNotification().flags = flags;
mHandler.post(new EnqueueNotificationRunnable(userId, summary, isAppForeground,
- SystemClock.elapsedRealtime()));
+ mPostNotificationTrackerFactory.newTracker()));
}
}
@@ -1459,7 +1456,8 @@ public class NotificationManagerService extends SystemService {
// Force isAppForeground true here, because for sysui's purposes we
// want to adjust the flag behaviour.
mHandler.post(new EnqueueNotificationRunnable(r.getUser().getIdentifier(),
- r, true /* isAppForeground*/, SystemClock.elapsedRealtime()));
+ r, true /* isAppForeground*/,
+ mPostNotificationTrackerFactory.newTracker()));
}
}
}
@@ -1489,7 +1487,8 @@ public class NotificationManagerService extends SystemService {
// want to be able to adjust the flag behaviour.
mHandler.post(
new EnqueueNotificationRunnable(r.getUser().getIdentifier(), r,
- true /* isAppForeground */, SystemClock.elapsedRealtime()));
+ /* foreground= */ true,
+ mPostNotificationTrackerFactory.newTracker()));
}
}
}
@@ -2173,11 +2172,6 @@ public class NotificationManagerService extends SystemService {
}
@VisibleForTesting
- void setPackageManager(IPackageManager packageManager) {
- mPackageManager = packageManager;
- }
-
- @VisibleForTesting
void setRankingHelper(RankingHelper rankingHelper) {
mRankingHelper = rankingHelper;
}
@@ -2231,15 +2225,15 @@ public class NotificationManagerService extends SystemService {
ActivityManager activityManager, GroupHelper groupHelper, IActivityManager am,
ActivityTaskManagerInternal atm, UsageStatsManagerInternal appUsageStats,
DevicePolicyManagerInternal dpm, IUriGrantsManager ugm,
- UriGrantsManagerInternal ugmInternal, AppOpsManager appOps, IAppOpsService iAppOps,
- UserManager userManager,
+ UriGrantsManagerInternal ugmInternal, AppOpsManager appOps, UserManager userManager,
NotificationHistoryManager historyManager, StatsManager statsManager,
TelephonyManager telephonyManager, ActivityManagerInternal ami,
MultiRateLimiter toastRateLimiter, PermissionHelper permissionHelper,
UsageStatsManagerInternal usageStatsManagerInternal,
TelecomManager telecomManager, NotificationChannelLogger channelLogger,
SystemUiSystemPropertiesFlags.FlagResolver flagResolver,
- PermissionManager permissionManager) {
+ PermissionManager permissionManager,
+ PostNotificationTrackerFactory postNotificationTrackerFactory) {
mHandler = handler;
Resources resources = getContext().getResources();
mMaxPackageEnqueueRate = Settings.Global.getFloat(getContext().getContentResolver(),
@@ -2261,7 +2255,6 @@ public class NotificationManagerService extends SystemService {
mUmInternal = LocalServices.getService(UserManagerInternal.class);
mUsageStatsManagerInternal = usageStatsManagerInternal;
mAppOps = appOps;
- mAppOpsService = iAppOps;
mAppUsageStats = appUsageStats;
mAlarmManager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE);
mCompanionManager = companionManager;
@@ -2271,11 +2264,11 @@ public class NotificationManagerService extends SystemService {
mDpm = dpm;
mUm = userManager;
mTelecomManager = telecomManager;
+ mPostNotificationTrackerFactory = postNotificationTrackerFactory;
mPlatformCompat = IPlatformCompat.Stub.asInterface(
ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));
mStrongAuthTracker = new StrongAuthTracker(getContext());
- mUiHandler = new Handler(UiThread.get().getLooper());
String[] extractorNames;
try {
extractorNames = resources.getStringArray(R.array.config_notificationSignalExtractors);
@@ -2560,7 +2553,6 @@ public class NotificationManagerService extends SystemService {
UriGrantsManager.getService(),
LocalServices.getService(UriGrantsManagerInternal.class),
getContext().getSystemService(AppOpsManager.class),
- IAppOpsService.Stub.asInterface(ServiceManager.getService(Context.APP_OPS_SERVICE)),
getContext().getSystemService(UserManager.class),
new NotificationHistoryManager(getContext(), handler),
mStatsManager = (StatsManager) getContext().getSystemService(
@@ -2573,7 +2565,8 @@ public class NotificationManagerService extends SystemService {
LocalServices.getService(UsageStatsManagerInternal.class),
getContext().getSystemService(TelecomManager.class),
new NotificationChannelLoggerImpl(), SystemUiSystemPropertiesFlags.getResolver(),
- getContext().getSystemService(PermissionManager.class));
+ getContext().getSystemService(PermissionManager.class),
+ new PostNotificationTrackerFactory() {});
publishBinderService(Context.NOTIFICATION_SERVICE, mService, /* allowIsolated= */ false,
DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL);
@@ -2689,7 +2682,7 @@ public class NotificationManagerService extends SystemService {
final boolean isAppForeground =
mActivityManager.getPackageImportance(pkg) == IMPORTANCE_FOREGROUND;
mHandler.post(new EnqueueNotificationRunnable(userId, r, isAppForeground,
- SystemClock.elapsedRealtime()));
+ mPostNotificationTrackerFactory.newTracker()));
}
}
@@ -6562,6 +6555,26 @@ public class NotificationManagerService extends SystemService {
void enqueueNotificationInternal(final String pkg, final String opPkg, final int callingUid,
final int callingPid, final String tag, final int id, final Notification notification,
int incomingUserId, boolean postSilently) {
+ PostNotificationTracker tracker = mPostNotificationTrackerFactory.newTracker();
+ boolean enqueued = false;
+ try {
+ enqueued = enqueueNotificationInternal(pkg, opPkg, callingUid, callingPid, tag, id,
+ notification, incomingUserId, postSilently, tracker);
+ } finally {
+ if (!enqueued) {
+ tracker.cancel();
+ }
+ }
+ }
+
+ /**
+ * @return True if we successfully processed the notification and handed off the task of
+ * enqueueing it to a background thread; false otherwise.
+ */
+ private boolean enqueueNotificationInternal(final String pkg, final String opPkg,
+ final int callingUid, final int callingPid, final String tag, final int id,
+ final Notification notification, int incomingUserId, boolean postSilently,
+ PostNotificationTracker tracker) {
if (DBG) {
Slog.v(TAG, "enqueueNotificationInternal: pkg=" + pkg + " id=" + id
+ " notification=" + notification);
@@ -6610,7 +6623,7 @@ public class NotificationManagerService extends SystemService {
throw new SecurityException("Invalid FGS notification", e);
}
Slog.e(TAG, "Cannot fix notification", e);
- return;
+ return false;
}
if (policy == ServiceNotificationPolicy.UPDATE_ONLY) {
@@ -6619,7 +6632,7 @@ public class NotificationManagerService extends SystemService {
// handling.
if (!isNotificationShownInternal(pkg, tag, id, userId)) {
reportForegroundServiceUpdate(false, notification, id, pkg, userId);
- return;
+ return false;
}
}
@@ -6660,7 +6673,7 @@ public class NotificationManagerService extends SystemService {
"Failed to post notification on channel \"" + channelId + "\"\n" +
"See log for more details");
}
- return;
+ return false;
}
final NotificationRecord r = new NotificationRecord(getContext(), n, channel);
@@ -6707,7 +6720,7 @@ public class NotificationManagerService extends SystemService {
if (!checkDisqualifyingFeatures(userId, notificationUid, id, tag, r,
r.getSbn().getOverrideGroupKey() != null)) {
- return;
+ return false;
}
if (info != null) {
@@ -6748,8 +6761,8 @@ public class NotificationManagerService extends SystemService {
} finally {
Binder.restoreCallingIdentity(token);
}
- mHandler.post(new EnqueueNotificationRunnable(userId, r, isAppForeground,
- SystemClock.elapsedRealtime()));
+ mHandler.post(new EnqueueNotificationRunnable(userId, r, isAppForeground, tracker));
+ return true;
}
private void onConversationRemovedInternal(String pkg, int uid, Set<String> shortcuts) {
@@ -7069,7 +7082,7 @@ public class NotificationManagerService extends SystemService {
mHandler.post(
new NotificationManagerService.EnqueueNotificationRunnable(
r.getUser().getIdentifier(), r, isAppForeground,
- SystemClock.elapsedRealtime()));
+ mPostNotificationTrackerFactory.newTracker()));
}
}
}
@@ -7213,12 +7226,12 @@ public class NotificationManagerService extends SystemService {
}
if (n.isStyle(Notification.CallStyle.class)) {
- boolean isForegroundService = (n.flags & FLAG_FOREGROUND_SERVICE) != 0;
boolean hasFullScreenIntent = n.fullScreenIntent != null;
- if (!isForegroundService && !hasFullScreenIntent) {
+ boolean requestedFullScreenIntent = (n.flags & FLAG_FSI_REQUESTED_BUT_DENIED) != 0;
+ if (!n.isFgsOrUij() && !hasFullScreenIntent && !requestedFullScreenIntent) {
throw new IllegalArgumentException(r.getKey() + " Not posted."
- + " CallStyle notifications must either be for a foreground Service or"
- + " use a fullScreenIntent.");
+ + " CallStyle notifications must be for a foreground service or"
+ + " user initated job or use a fullScreenIntent.");
}
}
@@ -7410,7 +7423,6 @@ public class NotificationManagerService extends SystemService {
} else {
Log.w(TAG, "Cannot snooze " + r.getKey() + ": too many snoozed notifications");
}
-
}
@GuardedBy("mNotificationLock")
@@ -7429,14 +7441,25 @@ public class NotificationManagerService extends SystemService {
cancelNotificationLocked(r, false, REASON_SNOOZED, wasPosted, null,
SystemClock.elapsedRealtime());
updateLightsLocked();
- if (mSnoozeCriterionId != null) {
- mAssistants.notifyAssistantSnoozedLocked(r, mSnoozeCriterionId);
- mSnoozeHelper.snooze(r, mSnoozeCriterionId);
- } else {
- mSnoozeHelper.snooze(r, mDuration);
+ if (isSnoozable(r)) {
+ if (mSnoozeCriterionId != null) {
+ mAssistants.notifyAssistantSnoozedLocked(r, mSnoozeCriterionId);
+ mSnoozeHelper.snooze(r, mSnoozeCriterionId);
+ } else {
+ mSnoozeHelper.snooze(r, mDuration);
+ }
+ r.recordSnoozed();
+ handleSavePolicyFile();
}
- r.recordSnoozed();
- handleSavePolicyFile();
+ }
+
+ /**
+ * Autogroup summaries are not snoozable
+ * They will be recreated as needed when the group children are unsnoozed
+ */
+ private boolean isSnoozable(NotificationRecord record) {
+ return !(record.getNotification().isGroupSummary() && GroupHelper.AUTOGROUP_KEY.equals(
+ record.getNotification().getGroup()));
}
}
@@ -7607,28 +7630,43 @@ public class NotificationManagerService extends SystemService {
private final NotificationRecord r;
private final int userId;
private final boolean isAppForeground;
- private final long enqueueElapsedTimeMs;
+ private final PostNotificationTracker mTracker;
EnqueueNotificationRunnable(int userId, NotificationRecord r, boolean foreground,
- @ElapsedRealtimeLong long enqueueElapsedTimeMs) {
+ PostNotificationTracker tracker) {
this.userId = userId;
this.r = r;
this.isAppForeground = foreground;
- this.enqueueElapsedTimeMs = enqueueElapsedTimeMs;
+ this.mTracker = checkNotNull(tracker);
}
@Override
public void run() {
+ boolean enqueued = false;
+ try {
+ enqueued = enqueueNotification();
+ } finally {
+ if (!enqueued) {
+ mTracker.cancel();
+ }
+ }
+ }
+
+ /**
+ * @return True if we successfully enqueued the notification and handed off the task of
+ * posting it to a background thread; false otherwise.
+ */
+ private boolean enqueueNotification() {
synchronized (mNotificationLock) {
- final Long snoozeAt =
+ final long snoozeAt =
mSnoozeHelper.getSnoozeTimeForUnpostedNotification(
r.getUser().getIdentifier(),
r.getSbn().getPackageName(), r.getSbn().getKey());
final long currentTime = System.currentTimeMillis();
- if (snoozeAt.longValue() > currentTime) {
+ if (snoozeAt > currentTime) {
(new SnoozeNotificationRunnable(r.getSbn().getKey(),
- snoozeAt.longValue() - currentTime, null)).snoozeLocked(r);
- return;
+ snoozeAt - currentTime, null)).snoozeLocked(r);
+ return false;
}
final String contextId =
@@ -7638,7 +7676,7 @@ public class NotificationManagerService extends SystemService {
if (contextId != null) {
(new SnoozeNotificationRunnable(r.getSbn().getKey(),
0, contextId)).snoozeLocked(r);
- return;
+ return false;
}
mEnqueuedNotifications.add(r);
@@ -7689,12 +7727,14 @@ public class NotificationManagerService extends SystemService {
mAssistants.onNotificationEnqueuedLocked(r);
mHandler.postDelayed(
new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(),
- r.getUid(), enqueueElapsedTimeMs),
+ r.getUid(), mTracker),
DELAY_FOR_ASSISTANT_TIME);
} else {
- mHandler.post(new PostNotificationRunnable(r.getKey(),
- r.getSbn().getPackageName(), r.getUid(), enqueueElapsedTimeMs));
+ mHandler.post(
+ new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(),
+ r.getUid(), mTracker));
}
+ return true;
}
}
}
@@ -7716,22 +7756,37 @@ public class NotificationManagerService extends SystemService {
protected class PostNotificationRunnable implements Runnable {
private final String key;
- private final long postElapsedTimeMs;
private final String pkg;
private final int uid;
+ private final PostNotificationTracker mTracker;
- PostNotificationRunnable(String key, String pkg, int uid,
- @ElapsedRealtimeLong long postElapsedTimeMs) {
+ PostNotificationRunnable(String key, String pkg, int uid, PostNotificationTracker tracker) {
this.key = key;
this.pkg = pkg;
this.uid = uid;
- this.postElapsedTimeMs = postElapsedTimeMs;
+ this.mTracker = checkNotNull(tracker);
}
@Override
public void run() {
+ boolean posted = false;
+ try {
+ posted = postNotification();
+ } finally {
+ if (!posted) {
+ mTracker.cancel();
+ }
+ }
+ }
+
+ /**
+ * @return True if we successfully processed the notification and handed off the task of
+ * notifying all listeners to a background thread; false otherwise.
+ */
+ private boolean postNotification() {
boolean appBanned = !areNotificationsEnabledForPackageInt(pkg, uid);
boolean isCallNotification = isCallNotification(pkg, uid);
+ boolean posted = false;
synchronized (mNotificationLock) {
try {
NotificationRecord r = null;
@@ -7745,7 +7800,7 @@ public class NotificationManagerService extends SystemService {
}
if (r == null) {
Slog.i(TAG, "Cannot find enqueued record for key: " + key);
- return;
+ return false;
}
final StatusBarNotification n = r.getSbn();
@@ -7759,7 +7814,7 @@ public class NotificationManagerService extends SystemService {
if (DBG) {
Slog.e(TAG, "Suppressing notification from package " + pkg);
}
- return;
+ return false;
}
final boolean isPackageSuspended =
@@ -7782,7 +7837,7 @@ public class NotificationManagerService extends SystemService {
mNotificationList.add(r);
mUsageStats.registerPostedByApp(r);
mUsageStatsManagerInternal.reportNotificationPosted(r.getSbn().getOpPkg(),
- r.getSbn().getUser(), postElapsedTimeMs);
+ r.getSbn().getUser(), mTracker.getStartTime());
final boolean isInterruptive = isVisuallyInterruptive(null, r);
r.setInterruptive(isInterruptive);
r.setTextChanged(isInterruptive);
@@ -7791,7 +7846,7 @@ public class NotificationManagerService extends SystemService {
mNotificationList.set(index, r);
mUsageStats.registerUpdatedByApp(r, old);
mUsageStatsManagerInternal.reportNotificationUpdated(r.getSbn().getOpPkg(),
- r.getSbn().getUser(), postElapsedTimeMs);
+ r.getSbn().getUser(), mTracker.getStartTime());
// Make sure we don't lose the foreground service state.
notification.flags |=
old.getNotification().flags & FLAG_FOREGROUND_SERVICE;
@@ -7818,8 +7873,14 @@ public class NotificationManagerService extends SystemService {
}
if (notification.getSmallIcon() != null) {
+ mTracker.setReport(
+ mNotificationRecordLogger.prepareToLogNotificationPosted(r, old,
+ position, buzzBeepBlinkLoggingCode,
+ getGroupInstanceId(r.getSbn().getGroupKey())));
+ notifyListenersPostedAndLogLocked(r, old, mTracker);
+ posted = true;
+
StatusBarNotification oldSbn = (old != null) ? old.getSbn() : null;
- mListeners.notifyPostedLocked(r, old);
if (oldSbn == null
|| !Objects.equals(oldSbn.getGroup(), n.getGroup())
|| oldSbn.getNotification().flags != n.getNotification().flags) {
@@ -7860,10 +7921,6 @@ public class NotificationManagerService extends SystemService {
maybeRecordInterruptionLocked(r);
maybeRegisterMessageSent(r);
maybeReportForegroundServiceUpdate(r, true);
-
- // Log event to statsd
- mNotificationRecordLogger.maybeLogNotificationPosted(r, old, position,
- buzzBeepBlinkLoggingCode, getGroupInstanceId(r.getSbn().getGroupKey()));
} finally {
int N = mEnqueuedNotifications.size();
for (int i = 0; i < N; i++) {
@@ -7875,6 +7932,7 @@ public class NotificationManagerService extends SystemService {
}
}
}
+ return posted;
}
}
@@ -10790,6 +10848,34 @@ public class NotificationManagerService extends SystemService {
}
}
+ /**
+ * Asynchronously notify all listeners about a posted (new or updated) notification. This
+ * should be called from {@link PostNotificationRunnable} to "complete" the post (since SysUI is
+ * one of the NLSes, and will display it to the user).
+ *
+ * <p>This method will call {@link PostNotificationTracker#finish} on the supplied tracker
+ * when every {@link NotificationListenerService} has received the news.
+ *
+ * <p>Also takes care of removing a notification that has been visible to a listener before,
+ * but isn't anymore.
+ */
+ @GuardedBy("mNotificationLock")
+ private void notifyListenersPostedAndLogLocked(NotificationRecord r, NotificationRecord old,
+ @NonNull PostNotificationTracker tracker) {
+ List<Runnable> listenerCalls = mListeners.prepareNotifyPostedLocked(r, old, true);
+ mHandler.post(() -> {
+ for (Runnable listenerCall : listenerCalls) {
+ listenerCall.run();
+ }
+
+ tracker.finish();
+ NotificationRecordLogger.NotificationReported report = tracker.getReport();
+ if (report != null) {
+ mNotificationRecordLogger.logNotificationPosted(report);
+ }
+ });
+ }
+
public class NotificationListeners extends ManagedServices {
static final String TAG_ENABLED_NOTIFICATION_LISTENERS = "enabled_listeners";
static final String TAG_REQUESTED_LISTENERS = "request_listeners";
@@ -11160,28 +11246,59 @@ public class NotificationManagerService extends SystemService {
}
/**
- * asynchronously notify all listeners about a new notification
+ * Asynchronously notify all listeners about a new or updated notification. Note that the
+ * notification is new or updated from the point of view of the NLS, but might not be
+ * "strictly new" <em>from the point of view of NMS itself</em> -- for example, this method
+ * is also invoked after exiting lockdown mode.
*
* <p>
* Also takes care of removing a notification that has been visible to a listener before,
* but isn't anymore.
*/
+ @VisibleForTesting
@GuardedBy("mNotificationLock")
- public void notifyPostedLocked(NotificationRecord r, NotificationRecord old) {
+ void notifyPostedLocked(NotificationRecord r, NotificationRecord old) {
notifyPostedLocked(r, old, true);
}
/**
+ * Asynchronously notify all listeners about a new or updated notification. Note that the
+ * notification is new or updated from the point of view of the NLS, but might not be
+ * "strictly new" <em>from the point of view of NMS itself</em> -- for example, this method
+ * is invoked after exiting lockdown mode.
+ *
* @param notifyAllListeners notifies all listeners if true, else only notifies listeners
- * targetting <= O_MR1
+ * targeting <= O_MR1
*/
+ @VisibleForTesting
@GuardedBy("mNotificationLock")
void notifyPostedLocked(NotificationRecord r, NotificationRecord old,
boolean notifyAllListeners) {
+ for (Runnable listenerCall : prepareNotifyPostedLocked(r, old, notifyAllListeners)) {
+ mHandler.post(listenerCall);
+ }
+ }
+
+ /**
+ * "Prepares" to notify all listeners about the posted notification.
+ *
+ * <p>This method <em>does not invoke</em> the listeners; the caller should post each
+ * returned {@link Runnable} on a suitable thread to do so.
+ *
+ * @param notifyAllListeners notifies all listeners if true, else only notifies listeners
+ * targeting <= O_MR1
+ * @return A list of {@link Runnable} operations to notify all listeners about the posted
+ * notification.
+ */
+ @VisibleForTesting
+ @GuardedBy("mNotificationLock")
+ List<Runnable> prepareNotifyPostedLocked(NotificationRecord r,
+ NotificationRecord old, boolean notifyAllListeners) {
if (isInLockDownMode(r.getUser().getIdentifier())) {
- return;
+ return new ArrayList<>();
}
+ ArrayList<Runnable> listenerCalls = new ArrayList<>();
try {
// Lazily initialized snapshots of the notification.
StatusBarNotification sbn = r.getSbn();
@@ -11215,7 +11332,7 @@ public class NotificationManagerService extends SystemService {
// This notification became invisible -> remove the old one.
if (oldSbnVisible && !sbnVisible) {
final StatusBarNotification oldSbnLightClone = oldSbn.cloneLight();
- mHandler.post(() -> notifyRemoved(
+ listenerCalls.add(() -> notifyRemoved(
info, oldSbnLightClone, update, null, REASON_USER_STOPPED));
continue;
}
@@ -11231,11 +11348,12 @@ public class NotificationManagerService extends SystemService {
false /* direct */, false /* retainOnUpdate */);
final StatusBarNotification sbnToPost = trimCache.ForListener(info);
- mHandler.post(() -> notifyPosted(info, sbnToPost, update));
+ listenerCalls.add(() -> notifyPosted(info, sbnToPost, update));
}
} catch (Exception e) {
Slog.e(TAG, "Could not notify listeners for " + r.getKey(), e);
}
+ return listenerCalls;
}
/**
@@ -11417,7 +11535,7 @@ public class NotificationManagerService extends SystemService {
int numChangedNotifications = changedNotifications.size();
for (int i = 0; i < numChangedNotifications; i++) {
NotificationRecord rec = changedNotifications.get(i);
- mListeners.notifyPostedLocked(rec, rec, false);
+ notifyPostedLocked(rec, rec, false);
}
}
@@ -12016,4 +12134,76 @@ public class NotificationManagerService extends SystemService {
&& !CompatChanges.isChangeEnabled(NOTIFICATION_TRAMPOLINE_BLOCK, uid);
}
}
+
+ interface PostNotificationTrackerFactory {
+ default PostNotificationTracker newTracker() {
+ return new PostNotificationTracker();
+ }
+ }
+
+ static class PostNotificationTracker {
+ @ElapsedRealtimeLong private final long mStartTime;
+ @Nullable private NotificationRecordLogger.NotificationReported mReport;
+ private boolean mOngoing;
+
+ @VisibleForTesting
+ PostNotificationTracker() {
+ // TODO(b/275044361): (Conditionally) receive a wakelock.
+ mStartTime = SystemClock.elapsedRealtime();
+ mOngoing = true;
+ if (DBG) {
+ Slog.d(TAG, "PostNotification: Started");
+ }
+ }
+
+ void setReport(@Nullable NotificationRecordLogger.NotificationReported report) {
+ mReport = report;
+ }
+
+ NotificationRecordLogger.NotificationReported getReport() {
+ return mReport;
+ }
+
+ @ElapsedRealtimeLong
+ long getStartTime() {
+ return mStartTime;
+ }
+
+ @VisibleForTesting
+ boolean isOngoing() {
+ return mOngoing;
+ }
+
+ void cancel() {
+ if (!isOngoing()) {
+ Log.wtfStack(TAG, "cancel() called on already-finished tracker");
+ return;
+ }
+ mOngoing = false;
+
+ // TODO(b/275044361): Release wakelock.
+
+ if (DBG) {
+ long elapsedTime = SystemClock.elapsedRealtime() - mStartTime;
+ Slog.d(TAG, TextUtils.formatSimple("PostNotification: Abandoned after %d ms",
+ elapsedTime));
+ }
+ }
+
+ void finish() {
+ if (!isOngoing()) {
+ Log.wtfStack(TAG, "finish() called on already-finished tracker");
+ return;
+ }
+ mOngoing = false;
+
+ // TODO(b/275044361): Release wakelock.
+
+ long elapsedTime = SystemClock.elapsedRealtime() - mStartTime;
+ if (DBG) {
+ Slog.d(TAG,
+ TextUtils.formatSimple("PostNotification: Finished in %d ms", elapsedTime));
+ }
+ }
+ }
}
diff --git a/services/core/java/com/android/server/notification/NotificationRecordLogger.java b/services/core/java/com/android/server/notification/NotificationRecordLogger.java
index 25d619dea296..71ebf7a39610 100644
--- a/services/core/java/com/android/server/notification/NotificationRecordLogger.java
+++ b/services/core/java/com/android/server/notification/NotificationRecordLogger.java
@@ -42,26 +42,45 @@ import java.util.Objects;
* in production. Use NotificationRecordLoggerFake for testing.
* @hide
*/
-public interface NotificationRecordLogger {
+interface NotificationRecordLogger {
// The high-level interface used by clients.
/**
- * May log a NotificationReported atom reflecting the posting or update of a notification.
- * @param r The new NotificationRecord. If null, no action is taken.
- * @param old The previous NotificationRecord. Null if there was no previous record.
+ * Prepare to log an atom reflecting the posting or update of a notification.
+ *
+ * The returned {@link NotificationReported} object, if any, should be supplied to
+ * {@link #logNotificationPosted}. Because only some updates are considered "interesting
+ * enough" to log, this method may return {@code null}. In that case, the follow-up call
+ * should not be performed.
+ *
+ * @param r The new {@link NotificationRecord}.
+ * @param old The previous {@link NotificationRecord}. Null if there was no previous record.
* @param position The position at which this notification is ranked.
* @param buzzBeepBlink Logging code reflecting whether this notification alerted the user.
- * @param groupId The instance Id of the group summary notification, or null.
+ * @param groupId The {@link InstanceId} of the group summary notification, or null.
*/
- void maybeLogNotificationPosted(@Nullable NotificationRecord r,
+ @Nullable
+ default NotificationReported prepareToLogNotificationPosted(@Nullable NotificationRecord r,
@Nullable NotificationRecord old,
int position, int buzzBeepBlink,
- InstanceId groupId);
+ InstanceId groupId) {
+ NotificationRecordPair p = new NotificationRecordPair(r, old);
+ if (!p.shouldLogReported(buzzBeepBlink)) {
+ return null;
+ }
+ return new NotificationReported(p, NotificationReportedEvent.fromRecordPair(p), position,
+ buzzBeepBlink, groupId);
+ }
+
+ /**
+ * Log a NotificationReported atom reflecting the posting or update of a notification.
+ */
+ void logNotificationPosted(NotificationReported nr);
/**
* Logs a NotificationReported atom reflecting an adjustment to a notification.
- * Unlike maybeLogNotificationPosted, this method is guaranteed to log a notification update,
+ * Unlike for posted notifications, this method is guaranteed to log a notification update,
* so the caller must take responsibility for checking that that logging update is necessary,
* and that the notification is meaningfully changed.
* @param r The NotificationRecord. If null, no action is taken.
@@ -125,7 +144,7 @@ public interface NotificationRecordLogger {
public static NotificationReportedEvent fromRecordPair(NotificationRecordPair p) {
return (p.old != null) ? NotificationReportedEvent.NOTIFICATION_UPDATED :
- NotificationReportedEvent.NOTIFICATION_POSTED;
+ NotificationReportedEvent.NOTIFICATION_POSTED;
}
}
@@ -450,6 +469,68 @@ public interface NotificationRecordLogger {
}
+ /** Data object corresponding to a NotificationReported atom.
+ *
+ * Fields must be kept in sync with frameworks/proto_logging/stats/atoms.proto.
+ */
+ class NotificationReported {
+ final int event_id;
+ final int uid;
+ final String package_name;
+ final int instance_id;
+ final int notification_id_hash;
+ final int channel_id_hash;
+ final int group_id_hash;
+ final int group_instance_id;
+ final boolean is_group_summary;
+ final String category;
+ final int style;
+ final int num_people;
+ final int position;
+ final int importance;
+ final int alerting;
+ final int importance_source;
+ final int importance_initial;
+ final int importance_initial_source;
+ final int importance_asst;
+ final int assistant_hash;
+ final float assistant_ranking_score;
+ final boolean is_ongoing;
+ final boolean is_foreground_service;
+ final long timeout_millis;
+ final boolean is_non_dismissible;
+
+ NotificationReported(NotificationRecordPair p,
+ NotificationReportedEvent eventType, int position, int buzzBeepBlink,
+ InstanceId groupId) {
+ this.event_id = eventType.getId();
+ this.uid = p.r.getUid();
+ this.package_name = p.r.getSbn().getPackageName();
+ this.instance_id = p.getInstanceId();
+ this.notification_id_hash = p.getNotificationIdHash();
+ this.channel_id_hash = p.getChannelIdHash();
+ this.group_id_hash = p.getGroupIdHash();
+ this.group_instance_id = (groupId == null) ? 0 : groupId.getId();
+ this.is_group_summary = p.r.getSbn().getNotification().isGroupSummary();
+ this.category = p.r.getSbn().getNotification().category;
+ this.style = p.getStyle();
+ this.num_people = p.getNumPeople();
+ this.position = position;
+ this.importance = NotificationRecordLogger.getLoggingImportance(p.r);
+ this.alerting = buzzBeepBlink;
+ this.importance_source = p.r.getImportanceExplanationCode();
+ this.importance_initial = p.r.getInitialImportance();
+ this.importance_initial_source = p.r.getInitialImportanceExplanationCode();
+ this.importance_asst = p.r.getAssistantImportance();
+ this.assistant_hash = p.getAssistantHash();
+ this.assistant_ranking_score = p.r.getRankingScore();
+ this.is_ongoing = p.r.getSbn().isOngoing();
+ this.is_foreground_service = NotificationRecordLogger.isForegroundService(p.r);
+ this.timeout_millis = p.r.getSbn().getNotification().getTimeoutAfter();
+ this.is_non_dismissible = NotificationRecordLogger.isNonDismissible(p.r);
+ }
+ }
+
/**
* @param r NotificationRecord
* @return Logging importance of record, taking important conversation channels into account.
diff --git a/services/core/java/com/android/server/notification/NotificationRecordLoggerImpl.java b/services/core/java/com/android/server/notification/NotificationRecordLoggerImpl.java
index 9a1f19d0c514..cd457b793390 100644
--- a/services/core/java/com/android/server/notification/NotificationRecordLoggerImpl.java
+++ b/services/core/java/com/android/server/notification/NotificationRecordLoggerImpl.java
@@ -27,20 +27,13 @@ import com.android.internal.util.FrameworkStatsLog;
* Standard implementation of NotificationRecordLogger interface.
* @hide
*/
-public class NotificationRecordLoggerImpl implements NotificationRecordLogger {
+class NotificationRecordLoggerImpl implements NotificationRecordLogger {
private UiEventLogger mUiEventLogger = new UiEventLoggerImpl();
@Override
- public void maybeLogNotificationPosted(NotificationRecord r, NotificationRecord old,
- int position, int buzzBeepBlink,
- InstanceId groupId) {
- NotificationRecordPair p = new NotificationRecordPair(r, old);
- if (!p.shouldLogReported(buzzBeepBlink)) {
- return;
- }
- writeNotificationReportedAtom(p, NotificationReportedEvent.fromRecordPair(p),
- position, buzzBeepBlink, groupId);
+ public void logNotificationPosted(NotificationReported nr) {
+ writeNotificationReportedAtom(nr);
}
@Override
@@ -48,48 +41,40 @@ public class NotificationRecordLoggerImpl implements NotificationRecordLogger {
int position, int buzzBeepBlink,
InstanceId groupId) {
NotificationRecordPair p = new NotificationRecordPair(r, null);
- writeNotificationReportedAtom(p, NotificationReportedEvent.NOTIFICATION_ADJUSTED,
- position, buzzBeepBlink, groupId);
+ writeNotificationReportedAtom(
+ new NotificationReported(p, NotificationReportedEvent.NOTIFICATION_ADJUSTED,
+ position, buzzBeepBlink, groupId));
}
- private void writeNotificationReportedAtom(NotificationRecordPair p,
- NotificationReportedEvent eventType, int position, int buzzBeepBlink,
- InstanceId groupId) {
- FrameworkStatsLog.write(FrameworkStatsLog.NOTIFICATION_REPORTED,
- /* int32 event_id = 1 */ eventType.getId(),
- /* int32 uid = 2 */ p.r.getUid(),
- /* string package_name = 3 */ p.r.getSbn().getPackageName(),
- /* int32 instance_id = 4 */ p.getInstanceId(),
- /* int32 notification_id_hash = 5 */ p.getNotificationIdHash(),
- /* int32 channel_id_hash = 6 */ p.getChannelIdHash(),
- /* string group_id_hash = 7 */ p.getGroupIdHash(),
- /* int32 group_instance_id = 8 */ (groupId == null) ? 0 : groupId.getId(),
- /* bool is_group_summary = 9 */ p.r.getSbn().getNotification().isGroupSummary(),
- /* string category = 10 */ p.r.getSbn().getNotification().category,
- /* int32 style = 11 */ p.getStyle(),
- /* int32 num_people = 12 */ p.getNumPeople(),
- /* int32 position = 13 */ position,
- /* android.stats.sysui.NotificationImportance importance = 14 */
- NotificationRecordLogger.getLoggingImportance(p.r),
- /* int32 alerting = 15 */ buzzBeepBlink,
- /* NotificationImportanceExplanation importance_source = 16 */
- p.r.getImportanceExplanationCode(),
- /* android.stats.sysui.NotificationImportance importance_initial = 17 */
- p.r.getInitialImportance(),
- /* NotificationImportanceExplanation importance_initial_source = 18 */
- p.r.getInitialImportanceExplanationCode(),
- /* android.stats.sysui.NotificationImportance importance_asst = 19 */
- p.r.getAssistantImportance(),
- /* int32 assistant_hash = 20 */ p.getAssistantHash(),
- /* float assistant_ranking_score = 21 */ p.r.getRankingScore(),
- /* bool is_ongoing = 22 */ p.r.getSbn().isOngoing(),
- /* bool is_foreground_service = 23 */
- NotificationRecordLogger.isForegroundService(p.r),
- /* optional int64 timeout_millis = 24 */
- p.r.getSbn().getNotification().getTimeoutAfter(),
- /* bool is_nondismissible = 25 */
- NotificationRecordLogger.isNonDismissible(p.r)
- );
+ private void writeNotificationReportedAtom(
+ NotificationReported notificationReported) {
+ FrameworkStatsLog.write(
+ FrameworkStatsLog.NOTIFICATION_REPORTED,
+ notificationReported.event_id,
+ notificationReported.uid,
+ notificationReported.package_name,
+ notificationReported.instance_id,
+ notificationReported.notification_id_hash,
+ notificationReported.channel_id_hash,
+ notificationReported.group_id_hash,
+ notificationReported.group_instance_id,
+ notificationReported.is_group_summary,
+ notificationReported.category,
+ notificationReported.style,
+ notificationReported.num_people,
+ notificationReported.position,
+ notificationReported.importance,
+ notificationReported.alerting,
+ notificationReported.importance_source,
+ notificationReported.importance_initial,
+ notificationReported.importance_initial_source,
+ notificationReported.importance_asst,
+ notificationReported.assistant_hash,
+ notificationReported.assistant_ranking_score,
+ notificationReported.is_ongoing,
+ notificationReported.is_foreground_service,
+ notificationReported.timeout_millis,
+ notificationReported.is_non_dismissible);
}
@Override
diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java
index 402fb30437b0..9b1a80bed17b 100644
--- a/services/core/java/com/android/server/pm/LauncherAppsService.java
+++ b/services/core/java/com/android/server/pm/LauncherAppsService.java
@@ -1120,12 +1120,12 @@ public class LauncherAppsService extends SystemService {
return shortcutOverridesInfo;
}
- List<String> packagesToOverride =
+ Map<String, String> packagesToOverride =
DevicePolicyCache.getInstance().getLauncherShortcutOverrides();
- for (String packageName : packagesToOverride) {
+ for (Map.Entry<String, String> packageNames : packagesToOverride.entrySet()) {
Intent intent = new Intent(Intent.ACTION_MAIN)
.addCategory(Intent.CATEGORY_LAUNCHER)
- .setPackage(packageName);
+ .setPackage(packageNames.getValue());
List<LauncherActivityInfoInternal> possibleShortcutOverrides =
queryIntentLauncherActivities(
@@ -1135,7 +1135,8 @@ public class LauncherAppsService extends SystemService {
);
if (!possibleShortcutOverrides.isEmpty()) {
- shortcutOverridesInfo.put(packageName, possibleShortcutOverrides.get(0));
+ shortcutOverridesInfo.put(packageNames.getKey(),
+ possibleShortcutOverrides.get(0));
}
}
return shortcutOverridesInfo;
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 51872b339c40..98d2d3d4b997 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -803,6 +803,20 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
protected WallpaperData mLastLockWallpaper;
private IWallpaperManagerCallback mKeyguardListener;
private boolean mWaitingForUnlock;
+
+ /**
+ * Flag set to true after reboot if the home wallpaper is waiting for the device to be unlocked.
+ * This happens for wallpapers that are not direct-boot aware; they can only be rendered after
+ * the user unlocks the device for the first time after a reboot. In the meantime, the default
+ * wallpaper is shown instead.
+ */
+ private boolean mHomeWallpaperWaitingForUnlock;
+
+ /**
+ * Flag set to true after reboot if the lock wallpaper is waiting for the device to be unlocked.
+ */
+ private boolean mLockWallpaperWaitingForUnlock;
+
private boolean mShuttingDown;
/**
@@ -1790,7 +1804,23 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
public void onUnlockUser(final int userId) {
synchronized (mLock) {
if (mCurrentUserId == userId) {
- if (mWaitingForUnlock) {
+ if (mIsLockscreenLiveWallpaperEnabled) {
+ if (mHomeWallpaperWaitingForUnlock) {
+ final WallpaperData systemWallpaper =
+ getWallpaperSafeLocked(userId, FLAG_SYSTEM);
+ switchWallpaper(systemWallpaper, null);
+ // TODO(b/278261563): call notifyCallbacksLocked inside switchWallpaper
+ notifyCallbacksLocked(systemWallpaper);
+ }
+ if (mLockWallpaperWaitingForUnlock) {
+ final WallpaperData lockWallpaper =
+ getWallpaperSafeLocked(userId, FLAG_LOCK);
+ switchWallpaper(lockWallpaper, null);
+ notifyCallbacksLocked(lockWallpaper);
+ }
+ }
+
+ if (mWaitingForUnlock && !mIsLockscreenLiveWallpaperEnabled) {
// the desired wallpaper is not direct-boot aware, load it now
final WallpaperData systemWallpaper =
getWallpaperSafeLocked(userId, FLAG_SYSTEM);
@@ -1845,13 +1875,23 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
}
mCurrentUserId = userId;
systemWallpaper = getWallpaperSafeLocked(userId, FLAG_SYSTEM);
- final WallpaperData tmpLockWallpaper = mLockWallpaperMap.get(userId);
- lockWallpaper = tmpLockWallpaper == null ? systemWallpaper : tmpLockWallpaper;
+
+ if (mIsLockscreenLiveWallpaperEnabled) {
+ lockWallpaper = systemWallpaper.mWhich == (FLAG_LOCK | FLAG_SYSTEM)
+ ? systemWallpaper : getWallpaperSafeLocked(userId, FLAG_LOCK);
+ } else {
+ final WallpaperData tmpLockWallpaper = mLockWallpaperMap.get(userId);
+ lockWallpaper = tmpLockWallpaper == null ? systemWallpaper : tmpLockWallpaper;
+ }
+
// Not started watching yet, in case wallpaper data was loaded for other reasons.
if (systemWallpaper.wallpaperObserver == null) {
systemWallpaper.wallpaperObserver = new WallpaperObserver(systemWallpaper);
systemWallpaper.wallpaperObserver.startWatching();
}
+ if (mIsLockscreenLiveWallpaperEnabled && lockWallpaper != systemWallpaper) {
+ switchWallpaper(lockWallpaper, null);
+ }
switchWallpaper(systemWallpaper, reply);
}
@@ -1870,6 +1910,11 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
void switchWallpaper(WallpaperData wallpaper, IRemoteCallback reply) {
synchronized (mLock) {
mWaitingForUnlock = false;
+ if (mIsLockscreenLiveWallpaperEnabled) {
+ if ((wallpaper.mWhich & FLAG_SYSTEM) != 0) mHomeWallpaperWaitingForUnlock = false;
+ if ((wallpaper.mWhich & FLAG_LOCK) != 0) mLockWallpaperWaitingForUnlock = false;
+ }
+
final ComponentName cname = wallpaper.wallpaperComponent != null ?
wallpaper.wallpaperComponent : wallpaper.nextWallpaperComponent;
if (!bindWallpaperComponentLocked(cname, true, false, wallpaper, reply)) {
@@ -1882,6 +1927,11 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
} catch (RemoteException ignored) {
}
+ if (mIsLockscreenLiveWallpaperEnabled) {
+ onSwitchWallpaperFailLocked(wallpaper, reply, si);
+ return;
+ }
+
if (si == null) {
Slog.w(TAG, "Failure starting previous wallpaper; clearing");
clearWallpaperLocked(false, FLAG_SYSTEM, wallpaper.userId, reply);
@@ -1899,6 +1949,43 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
}
}
+ /**
+ * Fallback method if a wallpaper fails to load on boot or after a user switch.
+ * Only called if mIsLockscreenLiveWallpaperEnabled is true.
+ */
+ private void onSwitchWallpaperFailLocked(
+ WallpaperData wallpaper, IRemoteCallback reply, ServiceInfo serviceInfo) {
+
+ if (serviceInfo == null) {
+ Slog.w(TAG, "Failure starting previous wallpaper; clearing");
+
+ if (wallpaper.mWhich == (FLAG_LOCK | FLAG_SYSTEM)) {
+ clearWallpaperLocked(false, FLAG_SYSTEM, wallpaper.userId, null);
+ clearWallpaperLocked(false, FLAG_LOCK, wallpaper.userId, reply);
+ } else {
+ clearWallpaperLocked(false, wallpaper.mWhich, wallpaper.userId, reply);
+ }
+ return;
+ }
+ Slog.w(TAG, "Wallpaper isn't direct boot aware; using fallback until unlocked");
+ // We might end up persisting the current wallpaper data
+ // while locked, so pretend like the component was actually
+ // bound into place
+ wallpaper.wallpaperComponent = wallpaper.nextWallpaperComponent;
+ final WallpaperData fallback = new WallpaperData(wallpaper.userId, wallpaper.mWhich);
+
+ // files from the previous static wallpaper may still be stored in memory.
+ // delete them in order to show the default wallpaper.
+ if (wallpaper.wallpaperFile.exists()) {
+ wallpaper.wallpaperFile.delete();
+ wallpaper.cropFile.delete();
+ }
+
+ bindWallpaperComponentLocked(mImageWallpaper, true, false, fallback, reply);
+ if ((wallpaper.mWhich & FLAG_SYSTEM) != 0) mHomeWallpaperWaitingForUnlock = true;
+ if ((wallpaper.mWhich & FLAG_LOCK) != 0) mLockWallpaperWaitingForUnlock = true;
+ }
+
@Override
public void clearWallpaper(String callingPackage, int which, int userId) {
if (DEBUG) Slog.v(TAG, "clearWallpaper");
diff --git a/services/core/java/com/android/server/wm/AbsAppSnapshotController.java b/services/core/java/com/android/server/wm/AbsAppSnapshotController.java
index 32f7b9682fb7..5c929a93bf12 100644
--- a/services/core/java/com/android/server/wm/AbsAppSnapshotController.java
+++ b/services/core/java/com/android/server/wm/AbsAppSnapshotController.java
@@ -239,7 +239,17 @@ abstract class AbsAppSnapshotController<TYPE extends WindowContainer,
}
return null;
}
- source.getBounds(mTmpRect);
+ mTmpRect.setEmpty();
+ if (source.mTransitionController.inFinishingTransition(source)) {
+ final Transition.ChangeInfo changeInfo = source.mTransitionController
+ .mFinishingTransition.mChanges.get(source);
+ if (changeInfo != null) {
+ mTmpRect.set(changeInfo.mAbsoluteBounds);
+ }
+ }
+ if (mTmpRect.isEmpty()) {
+ source.getBounds(mTmpRect);
+ }
mTmpRect.offsetTo(0, 0);
SurfaceControl[] excludeLayers;
final WindowState imeWindow = source.getDisplayContent().mInputMethodWindow;
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index f843b7c5e3ab..78c066bdc212 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -5296,6 +5296,10 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
if (isCollecting) {
mTransitionController.collect(this);
} else {
+ // Failsafe to make sure that we show any activities that were incorrectly hidden
+ // during a transition. If this vis-change is a result of finishing, ignore it.
+ // Finish should only ever commit visibility=false, so we can check full containment
+ // rather than just direct membership.
inFinishingTransition = mTransitionController.inFinishingTransition(this);
if (!inFinishingTransition && !mDisplayContent.isSleeping()) {
Slog.e(TAG, "setVisibility=" + visible
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
index 4949ebc46b80..3f4a775bc37a 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
@@ -755,4 +755,10 @@ public abstract class ActivityTaskManagerInternal {
/** Unregister a task stack listener so that it stops receiving callbacks. */;
public abstract void unregisterTaskStackListener(ITaskStackListener listener);
+
+ /**
+ * Gets the id of the display the activity was launched on.
+ * @param token The activity token.
+ */
+ public abstract int getDisplayId(IBinder token);
}
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index b37703204b7b..1f4606b09396 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -5816,6 +5816,18 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
}
@Override
+ public int getDisplayId(IBinder token) {
+ synchronized (mGlobalLock) {
+ ActivityRecord r = ActivityRecord.forTokenLocked(token);
+ if (r == null) {
+ throw new IllegalArgumentException(
+ "setFocusedActivity: No activity record matching token=" + token);
+ }
+ return r.getDisplayId();
+ }
+ }
+
+ @Override
public void registerScreenObserver(ScreenObserver observer) {
mScreenObservers.add(observer);
}
diff --git a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
index e447049a7362..1a3d6730fe20 100644
--- a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
+++ b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
@@ -452,6 +452,9 @@ public class BackgroundActivityStartController {
// If we are here, it means all exemptions not based on PI sender failed, so we'll block
// unless resultIfPiSenderAllowsBal is an allow and the PI sender allows BAL
+ String realCallingPackage = callingUid == realCallingUid ? callingPackage :
+ mService.mContext.getPackageManager().getNameForUid(realCallingUid);
+
String stateDumpLog = " [callingPackage: " + callingPackage
+ "; callingUid: " + callingUid
+ "; appSwitchState: " + appSwitchState
@@ -460,6 +463,7 @@ public class BackgroundActivityStartController {
ActivityManager.class, "PROCESS_STATE_", callingUidProcState)
+ "; isCallingUidPersistentSystemProcess: " + isCallingUidPersistentSystemProcess
+ "; balAllowedByPiSender: " + balAllowedByPiSender
+ + "; realCallingPackage: " + realCallingPackage
+ "; realCallingUid: " + realCallingUid
+ "; realCallingUidHasAnyVisibleWindow: " + realCallingUidHasAnyVisibleWindow
+ "; realCallingUidProcState: " + DebugUtils.valueToString(
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 8bfa4269af1c..ef38e8962599 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -2190,6 +2190,14 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
}
mWmService.mDisplayManagerInternal.performTraversal(transaction);
+ if (shellTransitions) {
+ // Before setDisplayProjection is applied by the start transaction of transition,
+ // set the transform hint to avoid using surface in old rotation.
+ getPendingTransaction().setFixedTransformHint(mSurfaceControl, rotation);
+ // The sync transaction should already contains setDisplayProjection, so unset the
+ // hint to restore the natural state when the transaction is applied.
+ transaction.unsetFixedTransformHint(mSurfaceControl);
+ }
scheduleAnimation();
mWmService.mRotationWatcherController.dispatchDisplayRotationChange(mDisplayId, rotation);
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 747819e93ff2..ce4362853b23 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -1882,6 +1882,12 @@ public class DisplayPolicy {
static final int DECOR_TYPES = Type.displayCutout() | Type.navigationBars();
+ /**
+ * The types that may affect display configuration. This excludes cutout because it is
+ * known from display info.
+ */
+ static final int CONFIG_TYPES = Type.statusBars() | Type.navigationBars();
+
private final DisplayContent mDisplayContent;
private final Info[] mInfoForRotation = new Info[4];
final Info mTmpInfo = new Info();
@@ -1921,7 +1927,7 @@ public class DisplayPolicy {
final DecorInsets.Info newInfo = mDecorInsets.mTmpInfo;
newInfo.update(mDisplayContent, rotation, dw, dh);
final DecorInsets.Info currentInfo = getDecorInsetsInfo(rotation, dw, dh);
- if (newInfo.mNonDecorFrame.equals(currentInfo.mNonDecorFrame)) {
+ if (newInfo.mConfigFrame.equals(currentInfo.mConfigFrame)) {
return false;
}
mDecorInsets.invalidate();
diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java
index a5e652cce41e..a3d233df7b61 100644
--- a/services/core/java/com/android/server/wm/DisplayRotation.java
+++ b/services/core/java/com/android/server/wm/DisplayRotation.java
@@ -123,6 +123,7 @@ public class DisplayRotation {
public final boolean isDefaultDisplay;
private final boolean mSupportAutoRotation;
+ private final boolean mAllowRotationResolver;
private final int mLidOpenRotation;
private final int mCarDockRotation;
private final int mDeskDockRotation;
@@ -272,6 +273,8 @@ public class DisplayRotation {
mSupportAutoRotation =
mContext.getResources().getBoolean(R.bool.config_supportAutoRotation);
+ mAllowRotationResolver =
+ mContext.getResources().getBoolean(R.bool.config_allowRotationResolver);
mLidOpenRotation = readRotation(R.integer.config_lidOpenRotation);
mCarDockRotation = readRotation(R.integer.config_carDockRotation);
mDeskDockRotation = readRotation(R.integer.config_deskDockRotation);
@@ -2041,7 +2044,8 @@ public class DisplayRotation {
@Override
public boolean isRotationResolverEnabled() {
- return mUserRotationMode == WindowManagerPolicy.USER_ROTATION_FREE
+ return mAllowRotationResolver
+ && mUserRotationMode == WindowManagerPolicy.USER_ROTATION_FREE
&& mCameraRotationMode == CAMERA_ROTATION_ENABLED
&& !mService.mPowerManager.isPowerSaveMode();
}
diff --git a/services/core/java/com/android/server/wm/RemoteAnimationController.java b/services/core/java/com/android/server/wm/RemoteAnimationController.java
index b879d1a8ec56..eb639b6f2033 100644
--- a/services/core/java/com/android/server/wm/RemoteAnimationController.java
+++ b/services/core/java/com/android/server/wm/RemoteAnimationController.java
@@ -362,15 +362,8 @@ class RemoteAnimationController implements DeathRecipient {
private void invokeAnimationCancelled(String reason) {
ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "cancelAnimation(): reason=%s", reason);
- final boolean isKeyguardOccluded = mDisplayContent.isKeyguardOccluded();
-
try {
- EventLogTags.writeWmSetKeyguardOccluded(
- isKeyguardOccluded ? 1 : 0,
- 0 /* animate */,
- 0 /* transit */,
- "onAnimationCancelled");
- mRemoteAnimationAdapter.getRunner().onAnimationCancelled(isKeyguardOccluded);
+ mRemoteAnimationAdapter.getRunner().onAnimationCancelled();
} catch (RemoteException e) {
Slog.e(TAG, "Failed to notify cancel", e);
}
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index 54dfdd93b26c..d531ad175f10 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -244,6 +244,16 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
private IContainerFreezer mContainerFreezer = null;
private final SurfaceControl.Transaction mTmpTransaction = new SurfaceControl.Transaction();
+ /**
+ * {@code true} if some other operation may have caused the originally-recorded state (in
+ * mChanges) to be dirty. This is usually due to finishTransition being called mid-collect;
+ * and, the reason that finish can alter the "start" state of other transitions is because
+ * setVisible(false) is deferred until then.
+ * Instead of adding this conditional, we could re-check always; but, this situation isn't
+ * common so it'd be wasted work.
+ */
+ boolean mPriorVisibilityMightBeDirty = false;
+
final TransitionController.Logger mLogger = new TransitionController.Logger();
/** Whether this transition was forced to play early (eg for a SLEEP signal). */
@@ -865,6 +875,13 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
if (c.getSnapshot() != null) {
t.reparent(c.getSnapshot(), null);
}
+ // The fixed transform hint was set in DisplayContent#applyRotation(). Make sure to
+ // clear the hint in case the start transaction is not applied.
+ if (c.hasFlags(FLAG_IS_DISPLAY) && c.getStartRotation() != c.getEndRotation()
+ && c.getContainer() != null) {
+ t.unsetFixedTransformHint(WindowContainer.fromBinder(c.getContainer().asBinder())
+ .asDisplayContent().mSurfaceControl);
+ }
}
for (int i = info.getRootCount() - 1; i >= 0; --i) {
final SurfaceControl leash = info.getRoot(i).getLeash();
@@ -959,28 +976,30 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
mController.mFinishingTransition = this;
if (mTransientHideTasks != null && !mTransientHideTasks.isEmpty()) {
- // Record all the now-hiding activities so that they are committed after
- // recalculating visibilities. We just use mParticipants because we can and it will
- // ensure proper reporting of `isInFinishTransition`.
+ // The transient hide tasks could be occluded now, e.g. returning to home. So trigger
+ // the update to make the activities in the tasks invisible-requested, then the next
+ // step can continue to commit the visibility.
+ mController.mAtm.mRootWindowContainer.ensureActivitiesVisible(null /* starting */,
+ 0 /* configChanges */, true /* preserveWindows */);
+ // Record all the now-hiding activities so that they are committed. Just use
+ // mParticipants because we can avoid a new list this way.
for (int i = 0; i < mTransientHideTasks.size(); ++i) {
+ // Only worry about tasks that were actually hidden. Otherwise, we could end-up
+ // committing visibility for activity-level changes that aren't part of this
+ // transition.
+ if (mTransientHideTasks.get(i).isVisibleRequested()) continue;
mTransientHideTasks.get(i).forAllActivities(r -> {
// Only check leaf-tasks that were collected
if (!mParticipants.contains(r.getTask())) return;
- // Only concern ourselves with anything that can become invisible
- if (!r.isVisible()) return;
mParticipants.add(r);
});
}
- // The transient hide tasks could be occluded now, e.g. returning to home. So trigger
- // the update to make the activities in the tasks invisible-requested, then the next
- // step can continue to commit the visibility.
- mController.mAtm.mRootWindowContainer.ensureActivitiesVisible(null /* starting */,
- 0 /* configChanges */, true /* preserveWindows */);
}
boolean hasParticipatedDisplay = false;
boolean hasVisibleTransientLaunch = false;
boolean enterAutoPip = false;
+ boolean committedSomeInvisible = false;
// Commit all going-invisible containers
for (int i = 0; i < mParticipants.size(); ++i) {
final WindowContainer<?> participant = mParticipants.valueAt(i);
@@ -1016,6 +1035,7 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
}
ar.commitVisibility(false /* visible */, false /* performLayout */,
true /* fromTransition */);
+ committedSomeInvisible = true;
} else {
enterAutoPip = true;
}
@@ -1074,6 +1094,9 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
}
}
}
+ if (committedSomeInvisible) {
+ mController.onCommittedInvisibles();
+ }
if (hasVisibleTransientLaunch) {
// Notify the change about the transient-below task if entering auto-pip.
@@ -1286,6 +1309,9 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
// leftover order changes.
collectOrderChanges(mController.mWaitingTransitions.isEmpty());
+ if (mPriorVisibilityMightBeDirty) {
+ updatePriorVisibility();
+ }
// Resolve the animating targets from the participants.
mTargets = calculateTargets(mParticipants, mChanges);
// Check whether the participants were animated from back navigation.
@@ -1799,6 +1825,20 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
}
}
+ private void updatePriorVisibility() {
+ for (int i = 0; i < mChanges.size(); ++i) {
+ final ChangeInfo chg = mChanges.valueAt(i);
+ // For task/activity, recalculate the current "real" visibility.
+ if (chg.mContainer.asActivityRecord() == null && chg.mContainer.asTask() == null) {
+ continue;
+ }
+ // This ONLY works in the visible -> invisible case (and is only needed for this case)
+ // because commitVisible(false) is deferred until finish.
+ if (!chg.mVisible) continue;
+ chg.mVisible = chg.mContainer.isVisible();
+ }
+ }
+
/**
* Under some conditions (eg. all visible targets within a parent container are transitioning
* the same way) the transition can be "promoted" to the parent container. This means an
diff --git a/services/core/java/com/android/server/wm/TransitionController.java b/services/core/java/com/android/server/wm/TransitionController.java
index 8af037be8d06..7950edaaa267 100644
--- a/services/core/java/com/android/server/wm/TransitionController.java
+++ b/services/core/java/com/android/server/wm/TransitionController.java
@@ -408,9 +408,9 @@ class TransitionController {
return false;
}
- /** Returns {@code true} if the `wc` is a participant of the finishing transition. */
+ /** Returns {@code true} if the finishing transition contains `wc`. */
boolean inFinishingTransition(WindowContainer<?> wc) {
- return mFinishingTransition != null && mFinishingTransition.mParticipants.contains(wc);
+ return mFinishingTransition != null && mFinishingTransition.isInTransition(wc);
}
/** @return {@code true} if a transition is running */
@@ -823,6 +823,17 @@ class TransitionController {
// Can reset track-count now that everything is idle.
mTrackCount = 0;
validateStates();
+ mAtm.mWindowManager.onAnimationFinished();
+ }
+ }
+
+ /** Called by {@link Transition#finishTransition} if it committed invisible to any activities */
+ void onCommittedInvisibles() {
+ if (mCollectingTransition != null) {
+ mCollectingTransition.mPriorVisibilityMightBeDirty = true;
+ }
+ for (int i = mWaitingTransitions.size() - 1; i >= 0; --i) {
+ mWaitingTransitions.get(i).mPriorVisibilityMightBeDirty = true;
}
}
@@ -963,6 +974,7 @@ class TransitionController {
if (sync) {
info.setFlags(info.getFlags() | TransitionInfo.FLAG_SYNC);
}
+ transition.mAnimationTrack = track;
info.setTrack(track);
mTrackCount = Math.max(mTrackCount, track + 1);
}
diff --git a/services/core/java/com/android/server/wm/TransitionTracer.java b/services/core/java/com/android/server/wm/TransitionTracer.java
index 6597d4c7f916..6aac81bc3b6c 100644
--- a/services/core/java/com/android/server/wm/TransitionTracer.java
+++ b/services/core/java/com/android/server/wm/TransitionTracer.java
@@ -21,6 +21,7 @@ import static android.os.Build.IS_USER;
import static com.android.server.wm.shell.TransitionTraceProto.MAGIC_NUMBER;
import static com.android.server.wm.shell.TransitionTraceProto.MAGIC_NUMBER_H;
import static com.android.server.wm.shell.TransitionTraceProto.MAGIC_NUMBER_L;
+import static com.android.server.wm.shell.TransitionTraceProto.REAL_TO_ELAPSED_TIME_OFFSET_NANOS;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -37,6 +38,7 @@ import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.concurrent.TimeUnit;
/**
* Helper class to collect and dump transition traces.
@@ -395,6 +397,10 @@ public class TransitionTracer {
try {
ProtoOutputStream proto = new ProtoOutputStream();
proto.write(MAGIC_NUMBER, MAGIC_NUMBER_VALUE);
+ long timeOffsetNs =
+ TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis())
+ - SystemClock.elapsedRealtimeNanos();
+ proto.write(REAL_TO_ELAPSED_TIME_OFFSET_NANOS, timeOffsetNs);
int pid = android.os.Process.myPid();
LogAndPrintln.i(pw, "Writing file to " + file.getAbsolutePath()
+ " from process " + pid);
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index f4a1765d4663..510e6756b8ef 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -3839,7 +3839,8 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
// This can still happen if WMCore starts a new transition when there is ongoing
// sync transaction from Shell. Please file a bug if it happens.
throw new IllegalStateException("Can't sync on 2 groups simultaneously"
- + " currentSyncId=" + mSyncGroup.mSyncId + " newSyncId=" + group.mSyncId);
+ + " currentSyncId=" + mSyncGroup.mSyncId + " newSyncId=" + group.mSyncId
+ + " wc=" + this);
}
mSyncGroup = group;
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 40b8274d4e51..6cb6d9d7bcea 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -1831,7 +1831,7 @@ public class WindowManagerService extends IWindowManager.Stub
boolean needToSendNewConfiguration =
win.isVisibleRequestedOrAdding() && displayContent.updateOrientation();
- if (win.providesNonDecorInsets()) {
+ if (win.providesDisplayDecorInsets()) {
needToSendNewConfiguration |= displayPolicy.updateDecorInsetsInfo();
}
if (needToSendNewConfiguration) {
@@ -2274,7 +2274,7 @@ public class WindowManagerService extends IWindowManager.Stub
& WindowManager.LayoutParams.SYSTEM_UI_VISIBILITY_CHANGED) != 0) {
win.mLayoutNeeded = true;
}
- if (layoutChanged && win.providesNonDecorInsets()) {
+ if (layoutChanged && win.providesDisplayDecorInsets()) {
configChanged = displayPolicy.updateDecorInsetsInfo();
}
if (win.mActivityRecord != null && ((flagChanges & FLAG_SHOW_WHEN_LOCKED) != 0
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 2920652674d3..6f07b7719be0 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -1834,13 +1834,13 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
return (mPolicyVisibility & POLICY_VISIBILITY_ALL) == POLICY_VISIBILITY_ALL;
}
- boolean providesNonDecorInsets() {
+ boolean providesDisplayDecorInsets() {
if (mInsetsSourceProviders == null) {
return false;
}
for (int i = mInsetsSourceProviders.size() - 1; i >= 0; i--) {
final InsetsSource source = mInsetsSourceProviders.valueAt(i).getSource();
- if (source.getType() == WindowInsets.Type.navigationBars()) {
+ if ((source.getType() & DisplayPolicy.DecorInsets.CONFIG_TYPES) != 0) {
return true;
}
}
@@ -2507,13 +2507,13 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
}
// Check if window provides non decor insets before clearing its provided insets.
- final boolean windowProvidesNonDecorInsets = providesNonDecorInsets();
+ final boolean windowProvidesDisplayDecorInsets = providesDisplayDecorInsets();
removeImmediately();
// Removing a visible window may affect the display orientation so just update it if
// needed. Also recompute configuration if it provides screen decor insets.
boolean needToSendNewConfiguration = wasVisible && displayContent.updateOrientation();
- if (windowProvidesNonDecorInsets) {
+ if (windowProvidesDisplayDecorInsets) {
needToSendNewConfiguration |=
displayContent.getDisplayPolicy().updateDecorInsetsInfo();
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyCacheImpl.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyCacheImpl.java
index 80100a927e82..c681b884d2ed 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyCacheImpl.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyCacheImpl.java
@@ -19,13 +19,13 @@ import android.annotation.UserIdInt;
import android.app.admin.DevicePolicyCache;
import android.app.admin.DevicePolicyManager;
import android.os.UserHandle;
+import android.util.ArrayMap;
import android.util.IndentingPrintWriter;
import android.util.SparseIntArray;
import com.android.internal.annotations.GuardedBy;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
/**
@@ -55,8 +55,7 @@ public class DevicePolicyCacheImpl extends DevicePolicyCache {
private final SparseIntArray mPermissionPolicy = new SparseIntArray();
@GuardedBy("mLock")
- private List<String> mLauncherShortcutOverrides =
- new ArrayList<>();
+ private ArrayMap<String, String> mLauncherShortcutOverrides = new ArrayMap<>();
/** Maps to {@code ActiveAdmin.mAdminCanGrantSensorsPermissions}. */
@@ -130,18 +129,20 @@ public class DevicePolicyCacheImpl extends DevicePolicyCache {
}
@Override
- public List<String> getLauncherShortcutOverrides() {
+ public Map<String, String> getLauncherShortcutOverrides() {
synchronized (mLock) {
- return new ArrayList<>(mLauncherShortcutOverrides);
+ return new ArrayMap<>(mLauncherShortcutOverrides);
}
}
/**
- * Sets a list of packages for which shortcuts should be replaced by their badged version.
+ * Sets a map of packages names to package names, for which all launcher shortcuts which
+ * match a key package name should be modified to launch the corresponding value package
+ * name in the managed profile. The overridden shortcut should be badged accordingly.
*/
- public void setLauncherShortcutOverrides(List<String> launcherShortcutOverrides) {
+ public void setLauncherShortcutOverrides(ArrayMap<String, String> launcherShortcutOverrides) {
synchronized (mLock) {
- mLauncherShortcutOverrides = new ArrayList<>(launcherShortcutOverrides);
+ mLauncherShortcutOverrides = new ArrayMap<>(launcherShortcutOverrides);
}
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java
index 415440b1f46d..cf49dcf8004e 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java
@@ -130,12 +130,11 @@ final class DevicePolicyEngine {
<V> void setLocalPolicy(
@NonNull PolicyDefinition<V> policyDefinition,
@NonNull EnforcingAdmin enforcingAdmin,
- @NonNull PolicyValue<V> value,
+ @Nullable PolicyValue<V> value,
int userId,
boolean skipEnforcePolicy) {
Objects.requireNonNull(policyDefinition);
Objects.requireNonNull(enforcingAdmin);
- Objects.requireNonNull(value);
synchronized (mLock) {
PolicyState<V> localPolicyState = getLocalPolicyStateLocked(policyDefinition, userId);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 40024f1f0be3..0a4cd7a9a8a4 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -7721,7 +7721,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
private void clearLauncherShortcutOverrides() {
- mPolicyCache.setLauncherShortcutOverrides(new ArrayList<>());
+ mPolicyCache.setLauncherShortcutOverrides(new ArrayMap<>());
}
private void updateTelephonyCrossProfileIntentFilters(int parentUserId, int profileUserId,
@@ -12214,17 +12214,22 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
synchronized (getLockObject()) {
- ActiveAdmin admin;
- if (isPermissionCheckFlagEnabled()) {
- admin = enforcePermissionAndGetEnforcingAdmin(
- who, MANAGE_DEVICE_POLICY_INPUT_METHODS,
- caller.getPackageName(), userId).getActiveAdmin();
+ if (isPolicyEngineForFinanceFlagEnabled()) {
+ EnforcingAdmin admin = getEnforcingAdminForCaller(who, callerPackageName);
+ mDevicePolicyEngine.setLocalPolicy(
+ PolicyDefinition.PERMITTED_INPUT_METHODS,
+ admin,
+ packageList == null
+ ? null
+ : new StringSetPolicyValue(new HashSet<>(packageList)),
+ userId);
} else {
- admin = getParentOfAdminIfRequired(
- getProfileOwnerOrDeviceOwnerLocked(caller.getUserId()), calledOnParentInstance);
+ ActiveAdmin admin = getParentOfAdminIfRequired(
+ getProfileOwnerOrDeviceOwnerLocked(caller.getUserId()),
+ calledOnParentInstance);
+ admin.permittedInputMethods = packageList;
+ saveSettingsLocked(caller.getUserId());
}
- admin.permittedInputMethods = packageList;
- saveSettingsLocked(caller.getUserId());
}
DevicePolicyEventLogger
@@ -12272,19 +12277,18 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
synchronized (getLockObject()) {
- ActiveAdmin admin;
- if (isPermissionCheckFlagEnabled()) {
+ if (isPolicyEngineForFinanceFlagEnabled()) {
int affectedUser = calledOnParentInstance ? getProfileParentId(
caller.getUserId()) : caller.getUserId();
- admin = enforcePermissionAndGetEnforcingAdmin(
- who, MANAGE_DEVICE_POLICY_INPUT_METHODS, caller.getPackageName(),
- affectedUser).getActiveAdmin();
+ Set<String> policy = mDevicePolicyEngine.getResolvedPolicy(
+ PolicyDefinition.PERMITTED_INPUT_METHODS, affectedUser);
+ return policy == null ? null : new ArrayList<>(policy);
} else {
- admin = getParentOfAdminIfRequired(
+ ActiveAdmin admin = getParentOfAdminIfRequired(
getProfileOwnerOrDeviceOwnerLocked(
caller.getUserId()), calledOnParentInstance);
+ return admin.permittedInputMethods;
}
- return admin.permittedInputMethods;
}
}
@@ -12302,37 +12306,45 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
private @Nullable List<String> getPermittedInputMethodsUnchecked(@UserIdInt int userId) {
- synchronized (getLockObject()) {
- List<String> result = null;
- // Only device or profile owners can have permitted lists set.
- List<ActiveAdmin> admins = getActiveAdminsForAffectedUserInclPermissionBasedAdminLocked(userId);
- for (ActiveAdmin admin: admins) {
- List<String> fromAdmin = admin.permittedInputMethods;
- if (fromAdmin != null) {
- if (result == null) {
- result = new ArrayList<String>(fromAdmin);
- } else {
- result.retainAll(fromAdmin);
+ List<String> result = null;
+ if (isPolicyEngineForFinanceFlagEnabled()) {
+ Set<String> policy = mDevicePolicyEngine.getResolvedPolicy(
+ PolicyDefinition.PERMITTED_INPUT_METHODS, userId);
+ result = policy == null ? null : new ArrayList<>(policy);
+ } else {
+ synchronized (getLockObject()) {
+ // Only device or profile owners can have permitted lists set.
+ List<ActiveAdmin> admins =
+ getActiveAdminsForAffectedUserInclPermissionBasedAdminLocked(
+ userId);
+ for (ActiveAdmin admin : admins) {
+ List<String> fromAdmin = admin.permittedInputMethods;
+ if (fromAdmin != null) {
+ if (result == null) {
+ result = new ArrayList<String>(fromAdmin);
+ } else {
+ result.retainAll(fromAdmin);
+ }
}
}
}
+ }
- // If we have a permitted list add all system input methods.
- if (result != null) {
- List<InputMethodInfo> imes = InputMethodManagerInternal
- .get().getInputMethodListAsUser(userId);
- if (imes != null) {
- for (InputMethodInfo ime : imes) {
- ServiceInfo serviceInfo = ime.getServiceInfo();
- ApplicationInfo applicationInfo = serviceInfo.applicationInfo;
- if ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
- result.add(serviceInfo.packageName);
- }
+ // If we have a permitted list add all system input methods.
+ if (result != null) {
+ List<InputMethodInfo> imes = InputMethodManagerInternal
+ .get().getInputMethodListAsUser(userId);
+ if (imes != null) {
+ for (InputMethodInfo ime : imes) {
+ ServiceInfo serviceInfo = ime.getServiceInfo();
+ ApplicationInfo applicationInfo = serviceInfo.applicationInfo;
+ if ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
+ result.add(serviceInfo.packageName);
}
}
}
- return result;
}
+ return result;
}
@Override
@@ -12347,17 +12359,38 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
String.format(NOT_SYSTEM_CALLER_MSG,
"query if an input method is disabled by admin"));
- synchronized (getLockObject()) {
- ActiveAdmin admin = getParentOfAdminIfRequired(
- getActiveAdminUncheckedLocked(who, userHandle), calledOnParentInstance);
- if (admin == null) {
- return false;
+ if (isPolicyEngineForFinanceFlagEnabled()) {
+ int affectedUser = calledOnParentInstance ? getProfileParentId(userHandle) : userHandle;
+ Map<EnforcingAdmin, PolicyValue<Set<String>>> policies =
+ mDevicePolicyEngine.getLocalPoliciesSetByAdmins(
+ PolicyDefinition.PERMITTED_INPUT_METHODS, affectedUser);
+ EnforcingAdmin admin = null;
+ for (EnforcingAdmin a : policies.keySet()) {
+ if (a.getPackageName().equals(who.getPackageName())) {
+ if (policies.get(a).getValue() == null) {
+ return true;
+ } else {
+ return checkPackagesInPermittedListOrSystem(
+ Collections.singletonList(packageName),
+ new ArrayList<>(policies.get(a).getValue()), affectedUser);
+ }
+ }
}
- if (admin.permittedInputMethods == null) {
- return true;
+ // Admin didn't set a policy
+ return false;
+ } else {
+ synchronized (getLockObject()) {
+ ActiveAdmin admin = getParentOfAdminIfRequired(
+ getActiveAdminUncheckedLocked(who, userHandle), calledOnParentInstance);
+ if (admin == null) {
+ return false;
+ }
+ if (admin.permittedInputMethods == null) {
+ return true;
+ }
+ return checkPackagesInPermittedListOrSystem(Collections.singletonList(packageName),
+ admin.permittedInputMethods, userHandle);
}
- return checkPackagesInPermittedListOrSystem(Collections.singletonList(packageName),
- admin.permittedInputMethods, userHandle);
}
}
@@ -20215,9 +20248,20 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
private boolean isLockTaskFeatureEnabled(int lockTaskFeature) throws RemoteException {
- //TODO(b/175285301): Explicitly get the user's identity to check.
- int lockTaskFeatures =
- getUserData(getCurrentForegroundUserId()).mLockTaskFeatures;
+ int lockTaskFeatures = 0;
+ if (isPolicyEngineForFinanceFlagEnabled()) {
+ LockTaskPolicy policy = mDevicePolicyEngine.getResolvedPolicy(
+ PolicyDefinition.LOCK_TASK, getCurrentForegroundUserId());
+ lockTaskFeatures = policy == null
+ // We default on the power button menu, in order to be consistent with pre-P
+ // behaviour.
+ ? DevicePolicyManager.LOCK_TASK_FEATURE_GLOBAL_ACTIONS
+ : policy.getFlags();
+ } else {
+ //TODO(b/175285301): Explicitly get the user's identity to check.
+ lockTaskFeatures =
+ getUserData(getCurrentForegroundUserId()).mLockTaskFeatures;
+ }
return (lockTaskFeatures & lockTaskFeature) == lockTaskFeature;
}
@@ -21602,7 +21646,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
copyAccount(targetUser, sourceUser, accountToMigrate, callerPackage);
if (!keepAccountMigrated) {
- removeAccount(accountToMigrate);
+ removeAccount(accountToMigrate, sourceUserId);
}
}
@@ -21646,9 +21690,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
.write();
}
- private void removeAccount(Account account) {
- final AccountManager accountManager =
- mContext.getSystemService(AccountManager.class);
+ private void removeAccount(Account account, @UserIdInt int sourceUserId) {
+ final AccountManager accountManager = mContext.createContextAsUser(
+ UserHandle.of(sourceUserId), /* flags= */ 0)
+ .getSystemService(AccountManager.class);
final AccountManagerFuture<Bundle> bundle = accountManager.removeAccount(account,
null, null /* callback */, null /* handler */);
try {
@@ -23709,15 +23754,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
private void updateDialerAndSmsManagedShortcutsOverrideCache(
String defaultDialerPackageName, String defaultSmsPackageName) {
-
- List<String> shortcutOverrides = new ArrayList<>();
+ ArrayMap<String, String> shortcutOverrides = new ArrayMap<>();
if (defaultDialerPackageName != null) {
- shortcutOverrides.add(defaultDialerPackageName);
+ shortcutOverrides.put(defaultDialerPackageName, defaultDialerPackageName);
}
if (defaultSmsPackageName != null) {
- shortcutOverrides.add(defaultSmsPackageName);
+ shortcutOverrides.put(defaultSmsPackageName, defaultSmsPackageName);
}
mPolicyCache.setLauncherShortcutOverrides(shortcutOverrides);
}
@@ -23782,6 +23826,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
public DevicePolicyState getDevicePolicyState() {
Preconditions.checkCallAuthorization(
hasCallingOrSelfPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS));
+
return mInjector.binderWithCleanCallingIdentity(mDevicePolicyEngine::getDevicePolicyState);
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java
index 638596b5cc20..43a2c9bbf5c5 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java
@@ -308,6 +308,13 @@ final class PolicyDefinition<V> {
DevicePolicyIdentifiers.ACCOUNT_MANAGEMENT_DISABLED_POLICY, accountType));
}
+ static PolicyDefinition<Set<String>> PERMITTED_INPUT_METHODS = new PolicyDefinition<>(
+ new NoArgsPolicyKey(DevicePolicyIdentifiers.PERMITTED_INPUT_METHODS_POLICY),
+ new MostRecent<>(),
+ POLICY_FLAG_LOCAL_ONLY_POLICY,
+ (Set<String> value, Context context, Integer userId, PolicyKey policyKey) -> true,
+ new StringSetPolicySerializer());
+
private static final Map<String, PolicyDefinition<?>> POLICY_DEFINITIONS = new HashMap<>();
private static Map<String, Integer> USER_RESTRICTION_FLAGS = new HashMap<>();
@@ -333,6 +340,8 @@ final class PolicyDefinition<V> {
GENERIC_APPLICATION_HIDDEN);
POLICY_DEFINITIONS.put(DevicePolicyIdentifiers.ACCOUNT_MANAGEMENT_DISABLED_POLICY,
GENERIC_ACCOUNT_MANAGEMENT_DISABLED);
+ POLICY_DEFINITIONS.put(DevicePolicyIdentifiers.PERMITTED_INPUT_METHODS_POLICY,
+ PERMITTED_INPUT_METHODS);
// User Restriction Policies
USER_RESTRICTION_FLAGS.put(UserManager.DISALLOW_MODIFY_ACCOUNTS, /* flags= */ 0);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyState.java b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyState.java
index 741f209a90c3..dd4c6afdcfb6 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyState.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyState.java
@@ -67,9 +67,8 @@ final class PolicyState<V> {
/**
* Returns {@code true} if the resolved policy has changed, {@code false} otherwise.
*/
- boolean addPolicy(@NonNull EnforcingAdmin admin, @NonNull PolicyValue<V> policy) {
+ boolean addPolicy(@NonNull EnforcingAdmin admin, @Nullable PolicyValue<V> policy) {
Objects.requireNonNull(admin);
- Objects.requireNonNull(policy);
//LinkedHashMap doesn't update the insertion order of existing keys, removing the existing
// key will cause it to update.
@@ -89,9 +88,9 @@ final class PolicyState<V> {
* Returns {@code true} if the resolved policy has changed, {@code false} otherwise.
*/
boolean addPolicy(
- @NonNull EnforcingAdmin admin, @NonNull PolicyValue<V> policy,
+ @NonNull EnforcingAdmin admin, @Nullable PolicyValue<V> policy,
LinkedHashMap<EnforcingAdmin, PolicyValue<V>> globalPoliciesSetByAdmins) {
- mPoliciesSetByAdmins.put(Objects.requireNonNull(admin), Objects.requireNonNull(policy));
+ mPoliciesSetByAdmins.put(Objects.requireNonNull(admin), policy);
return resolvePolicy(globalPoliciesSetByAdmins);
}
@@ -210,10 +209,12 @@ final class PolicyState<V> {
for (EnforcingAdmin admin : mPoliciesSetByAdmins.keySet()) {
serializer.startTag(/* namespace= */ null, TAG_ADMIN_POLICY_ENTRY);
- serializer.startTag(/* namespace= */ null, TAG_POLICY_VALUE_ENTRY);
- mPolicyDefinition.savePolicyValueToXml(
- serializer, mPoliciesSetByAdmins.get(admin).getValue());
- serializer.endTag(/* namespace= */ null, TAG_POLICY_VALUE_ENTRY);
+ if (mPoliciesSetByAdmins.get(admin) != null) {
+ serializer.startTag(/* namespace= */ null, TAG_POLICY_VALUE_ENTRY);
+ mPolicyDefinition.savePolicyValueToXml(
+ serializer, mPoliciesSetByAdmins.get(admin).getValue());
+ serializer.endTag(/* namespace= */ null, TAG_POLICY_VALUE_ENTRY);
+ }
serializer.startTag(/* namespace= */ null, TAG_ENFORCING_ADMIN_ENTRY);
admin.saveToXml(serializer);
@@ -250,7 +251,7 @@ final class PolicyState<V> {
break;
}
}
- if (admin != null && value != null) {
+ if (admin != null) {
policiesSetByAdmins.put(admin, value);
} else {
Log.e(TAG, "Error Parsing TAG_ADMIN_POLICY_ENTRY");
diff --git a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
index a5adf3f9bf80..f1d4de9369f0 100644
--- a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
@@ -54,6 +54,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
import static com.android.server.SystemTimeZone.TIME_ZONE_CONFIDENCE_HIGH;
import static com.android.server.alarm.Alarm.EXACT_ALLOW_REASON_ALLOW_LIST;
import static com.android.server.alarm.Alarm.EXACT_ALLOW_REASON_COMPAT;
+import static com.android.server.alarm.Alarm.EXACT_ALLOW_REASON_LISTENER;
import static com.android.server.alarm.Alarm.EXACT_ALLOW_REASON_NOT_APPLICABLE;
import static com.android.server.alarm.Alarm.EXACT_ALLOW_REASON_PERMISSION;
import static com.android.server.alarm.Alarm.EXACT_ALLOW_REASON_POLICY_PERMISSION;
@@ -2728,6 +2729,66 @@ public final class AlarmManagerServiceTest {
}
@Test
+ public void exactListenerBinderCallWithoutPermissionWithoutAllowlist() throws RemoteException {
+ mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
+ mockChangeEnabled(AlarmManager.ENABLE_USE_EXACT_ALARM, true);
+
+ mockScheduleExactAlarmState(false);
+ mockUseExactAlarmState(false);
+ when(mDeviceIdleInternal.isAppOnWhitelist(anyInt())).thenReturn(false);
+
+ final IAlarmListener listener = getNewListener(() -> {});
+ mBinder.set(TEST_CALLING_PACKAGE, ELAPSED_REALTIME_WAKEUP, 1234, WINDOW_EXACT, 0,
+ 0, null, listener, "test-tag", null, null);
+
+ verify(mService, never()).hasUseExactAlarmInternal(TEST_CALLING_PACKAGE, TEST_CALLING_UID);
+ verify(mService, never()).hasScheduleExactAlarmInternal(TEST_CALLING_PACKAGE,
+ TEST_CALLING_UID);
+ verify(mDeviceIdleInternal, never()).isAppOnWhitelist(anyInt());
+
+ final ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
+ verify(mService).setImpl(eq(ELAPSED_REALTIME_WAKEUP), eq(1234L), eq(WINDOW_EXACT), eq(0L),
+ isNull(), eq(listener), eq("test-tag"), eq(FLAG_STANDALONE), isNull(), isNull(),
+ eq(TEST_CALLING_UID), eq(TEST_CALLING_PACKAGE), bundleCaptor.capture(),
+ eq(EXACT_ALLOW_REASON_LISTENER));
+
+ final BroadcastOptions idleOptions = new BroadcastOptions(bundleCaptor.getValue());
+ final int type = idleOptions.getTemporaryAppAllowlistType();
+ assertEquals(TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED, type);
+ }
+
+ @Test
+ public void exactAllowWhileIdleListenerBinderCallWithoutPermissionWithoutAllowlist()
+ throws RemoteException {
+ mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
+ mockChangeEnabled(AlarmManager.ENABLE_USE_EXACT_ALARM, true);
+
+ mockScheduleExactAlarmState(false);
+ mockUseExactAlarmState(false);
+ when(mDeviceIdleInternal.isAppOnWhitelist(anyInt())).thenReturn(false);
+
+ final IAlarmListener listener = getNewListener(() -> {});
+ mBinder.set(TEST_CALLING_PACKAGE, ELAPSED_REALTIME_WAKEUP, 1234, WINDOW_EXACT, 0,
+ FLAG_ALLOW_WHILE_IDLE, null, listener, "test-tag", null, null);
+
+ verify(mService, never()).hasUseExactAlarmInternal(TEST_CALLING_PACKAGE, TEST_CALLING_UID);
+ verify(mService, never()).hasScheduleExactAlarmInternal(TEST_CALLING_PACKAGE,
+ TEST_CALLING_UID);
+ verify(mDeviceIdleInternal, never()).isAppOnWhitelist(anyInt());
+
+ final ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
+ verify(mService).setImpl(eq(ELAPSED_REALTIME_WAKEUP), eq(1234L), eq(WINDOW_EXACT), eq(0L),
+ isNull(), eq(listener), eq("test-tag"),
+ eq(FLAG_STANDALONE | FLAG_ALLOW_WHILE_IDLE_COMPAT), isNull(), isNull(),
+ eq(TEST_CALLING_UID), eq(TEST_CALLING_PACKAGE), bundleCaptor.capture(),
+ eq(EXACT_ALLOW_REASON_LISTENER));
+
+ final BroadcastOptions idleOptions = new BroadcastOptions(bundleCaptor.getValue());
+ final int type = idleOptions.getTemporaryAppAllowlistType();
+ assertEquals(TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED, type);
+ }
+
+ @Test
public void inexactAllowWhileIdleBinderCall() throws RemoteException {
// Both permission and power exemption status don't matter for these alarms.
// We only want to test that the flags and idleOptions are correct.
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilitySecurityPolicyTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilitySecurityPolicyTest.java
index eb6670ee964c..8f0d0144a40e 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilitySecurityPolicyTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilitySecurityPolicyTest.java
@@ -146,7 +146,7 @@ public class AccessibilitySecurityPolicyTest {
@Mock
private PolicyWarningUIController mPolicyWarningUIController;
@Mock
- private PackageManagerInternal mPackageManagerInternal;
+ private PackageManagerInternal mMockPackageManagerInternal;
@Before
public void setUp() {
@@ -158,7 +158,8 @@ public class AccessibilitySecurityPolicyTest {
R.dimen.accessibility_focus_highlight_stroke_width, 1);
mA11ySecurityPolicy = new AccessibilitySecurityPolicy(
- mPolicyWarningUIController, mContext, mMockA11yUserManager);
+ mPolicyWarningUIController, mContext, mMockA11yUserManager,
+ mMockPackageManagerInternal);
mA11ySecurityPolicy.setSendingNonA11yToolNotificationLocked(true);
mA11ySecurityPolicy.setAccessibilityWindowManager(mMockA11yWindowManager);
mA11ySecurityPolicy.setAppWidgetManager(mMockAppWidgetManager);
@@ -237,8 +238,8 @@ public class AccessibilitySecurityPolicyTest {
@Test
public void resolveValidReportedPackage_uidAndPkgNameMatched_returnPkgName()
throws PackageManager.NameNotFoundException {
- when(mMockPackageManager.getPackageUidAsUser(PACKAGE_NAME,
- PackageManager.MATCH_ANY_USER, TEST_USER_ID)).thenReturn(APP_UID);
+ when(mMockPackageManagerInternal.isSameApp(PACKAGE_NAME, APP_UID, TEST_USER_ID))
+ .thenReturn(true);
assertEquals(mA11ySecurityPolicy.resolveValidReportedPackageLocked(
PACKAGE_NAME, APP_UID, TEST_USER_ID, APP_PID),
@@ -257,8 +258,8 @@ public class AccessibilitySecurityPolicyTest {
when(mMockAppWidgetManager.getHostedWidgetPackages(widgetHostUid))
.thenReturn(widgetPackages);
- when(mMockPackageManager.getPackageUidAsUser(hostPackageName, TEST_USER_ID))
- .thenReturn(widgetHostUid);
+ when(mMockPackageManagerInternal.isSameApp(hostPackageName, widgetHostUid, TEST_USER_ID))
+ .thenReturn(true);
assertEquals(mA11ySecurityPolicy.resolveValidReportedPackageLocked(
widgetPackageName, widgetHostUid, TEST_USER_ID, widgetHostPid),
@@ -272,8 +273,8 @@ public class AccessibilitySecurityPolicyTest {
final String[] uidPackages = {PACKAGE_NAME, PACKAGE_NAME2};
when(mMockPackageManager.getPackagesForUid(APP_UID))
.thenReturn(uidPackages);
- when(mMockPackageManager.getPackageUidAsUser(invalidPackageName, TEST_USER_ID))
- .thenThrow(PackageManager.NameNotFoundException.class);
+ when(mMockPackageManagerInternal.isSameApp(invalidPackageName, APP_UID, TEST_USER_ID))
+ .thenReturn(false);
when(mMockAppWidgetManager.getHostedWidgetPackages(APP_UID))
.thenReturn(new ArraySet<>());
mContext.getTestablePermissions().setPermission(
@@ -292,8 +293,8 @@ public class AccessibilitySecurityPolicyTest {
final String[] uidPackages = {PACKAGE_NAME};
when(mMockPackageManager.getPackagesForUid(APP_UID))
.thenReturn(uidPackages);
- when(mMockPackageManager.getPackageUidAsUser(wantedPackageName, TEST_USER_ID))
- .thenReturn(wantedUid);
+ when(mMockPackageManagerInternal.isSameApp(wantedPackageName, wantedUid, TEST_USER_ID))
+ .thenReturn(true);
when(mMockAppWidgetManager.getHostedWidgetPackages(APP_UID))
.thenReturn(new ArraySet<>());
mContext.getTestablePermissions().setPermission(
@@ -312,8 +313,8 @@ public class AccessibilitySecurityPolicyTest {
final String[] uidPackages = {PACKAGE_NAME};
when(mMockPackageManager.getPackagesForUid(APP_UID))
.thenReturn(uidPackages);
- when(mMockPackageManager.getPackageUidAsUser(wantedPackageName, TEST_USER_ID))
- .thenReturn(wantedUid);
+ when(mMockPackageManagerInternal.isSameApp(wantedPackageName, wantedUid, TEST_USER_ID))
+ .thenReturn(true);
when(mMockAppWidgetManager.getHostedWidgetPackages(APP_UID))
.thenReturn(new ArraySet<>());
mContext.getTestablePermissions().setPermission(
diff --git a/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java
index 5751db0727e7..275533fb1c37 100644
--- a/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java
@@ -446,6 +446,25 @@ public class MediaProjectionManagerServiceTest {
}
@Test
+ public void testSetUserReviewGrantedConsentResult_projectionNull_consentNotGranted()
+ throws Exception {
+ MediaProjectionManagerService.MediaProjection projection = startProjectionPreconditions();
+ projection.start(mIMediaProjectionCallback);
+ assertThat(mService.isCurrentProjection(projection)).isTrue();
+ doReturn(true).when(mWindowManagerInternal).setContentRecordingSession(
+ any(ContentRecordingSession.class));
+ // Some other token.
+ final IMediaProjection otherProjection = null;
+ // Waiting for user to review consent.
+ mService.setContentRecordingSession(mWaitingDisplaySession);
+ mService.setUserReviewGrantedConsentResult(RECORD_CANCEL, otherProjection);
+
+ // Display result is ignored; only the first session is set.
+ verify(mWindowManagerInternal, times(1)).setContentRecordingSession(
+ eq(mWaitingDisplaySession));
+ }
+
+ @Test
public void testSetUserReviewGrantedConsentResult_noVirtualDisplay() throws Exception {
MediaProjectionManagerService.MediaProjection projection = startProjectionPreconditions();
projection.start(mIMediaProjectionCallback);
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index 5dbc6ab4a6d0..e31eed2be367 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -94,6 +94,7 @@ import static junit.framework.Assert.assertSame;
import static junit.framework.Assert.assertTrue;
import static junit.framework.Assert.fail;
+import static org.junit.Assert.assertThrows;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyLong;
@@ -212,7 +213,6 @@ import android.widget.RemoteViews;
import androidx.test.InstrumentationRegistry;
-import com.android.internal.app.IAppOpsService;
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
import com.android.internal.config.sysui.SystemUiSystemPropertiesFlags.Flag;
import com.android.internal.config.sysui.TestableFlagResolver;
@@ -232,6 +232,8 @@ import com.android.server.lights.LightsManager;
import com.android.server.lights.LogicalLight;
import com.android.server.notification.NotificationManagerService.NotificationAssistants;
import com.android.server.notification.NotificationManagerService.NotificationListeners;
+import com.android.server.notification.NotificationManagerService.PostNotificationTracker;
+import com.android.server.notification.NotificationManagerService.PostNotificationTrackerFactory;
import com.android.server.pm.PackageManagerService;
import com.android.server.pm.UserManagerInternal;
import com.android.server.policy.PermissionPolicyInternal;
@@ -345,6 +347,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
private PermissionManager mPermissionManager;
@Mock
private DevicePolicyManagerInternal mDevicePolicyManager;
+ private final TestPostNotificationTrackerFactory mPostNotificationTrackerFactory =
+ new TestPostNotificationTrackerFactory();
@Mock
IIntentSender pi1;
@@ -381,8 +385,6 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
@Mock
AppOpsManager mAppOpsManager;
@Mock
- IAppOpsService mAppOpsService;
- @Mock
private TestableNotificationManagerService.NotificationAssistantAccessGrantedCallback
mNotificationAssistantAccessGrantedCallback;
@Mock
@@ -420,6 +422,18 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
}
}
+ private class TestPostNotificationTrackerFactory implements PostNotificationTrackerFactory {
+
+ private final List<PostNotificationTracker> mCreatedTrackers = new ArrayList<>();
+
+ @Override
+ public PostNotificationTracker newTracker() {
+ PostNotificationTracker tracker = PostNotificationTrackerFactory.super.newTracker();
+ mCreatedTrackers.add(tracker);
+ return tracker;
+ }
+ }
+
@Before
public void setUp() throws Exception {
// Shell permisssions will override permissions of our app, so add all necessary permissions
@@ -557,10 +571,11 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
mockLightsManager, mListeners, mAssistants, mConditionProviders, mCompanionMgr,
mSnoozeHelper, mUsageStats, mPolicyFile, mActivityManager, mGroupHelper, mAm, mAtm,
mAppUsageStats, mDevicePolicyManager, mUgm, mUgmInternal,
- mAppOpsManager, mAppOpsService, mUm, mHistoryManager, mStatsManager,
+ mAppOpsManager, mUm, mHistoryManager, mStatsManager,
mock(TelephonyManager.class),
mAmi, mToastRateLimiter, mPermissionHelper, mock(UsageStatsManagerInternal.class),
- mTelecomManager, mLogger, mTestFlagResolver, mPermissionManager);
+ mTelecomManager, mLogger, mTestFlagResolver, mPermissionManager,
+ mPostNotificationTrackerFactory);
// Return first true for RoleObserver main-thread check
when(mMainLooper.isCurrentThread()).thenReturn(true).thenReturn(false);
mService.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY, mMainLooper);
@@ -643,11 +658,22 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
@After
public void assertNotificationRecordLoggerCallsValid() {
+ waitForIdle(); // Finish async work, including all logging calls done by Runnables.
for (NotificationRecordLoggerFake.CallRecord call : mNotificationRecordLogger.getCalls()) {
if (call.wasLogged) {
assertNotNull(call.event);
}
}
+ assertThat(mNotificationRecordLogger.getPendingLogs()).isEmpty();
+ }
+
+ @After
+ public void assertAllTrackersFinishedOrCancelled() {
+ // Verify that no trackers were left dangling.
+ for (PostNotificationTracker tracker : mPostNotificationTrackerFactory.mCreatedTrackers) {
+ assertThat(tracker.isOngoing()).isFalse();
+ }
+ mPostNotificationTrackerFactory.mCreatedTrackers.clear();
}
@After
@@ -1451,7 +1477,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
NotificationManagerService.PostNotificationRunnable runnable =
mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(),
- r.getUid(), SystemClock.elapsedRealtime());
+ r.getUid(), mPostNotificationTrackerFactory.newTracker());
runnable.run();
waitForIdle();
@@ -1472,7 +1498,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
NotificationManagerService.PostNotificationRunnable runnable =
mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(),
- r.getUid(), SystemClock.elapsedRealtime());
+ r.getUid(), mPostNotificationTrackerFactory.newTracker());
runnable.run();
waitForIdle();
@@ -1712,6 +1738,68 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
}
@Test
+ public void enqueueNotificationWithTag_usesAndFinishesTracker() throws Exception {
+ mBinderService.enqueueNotificationWithTag(PKG, PKG,
+ "testEnqueueNotificationWithTag_PopulatesGetActiveNotifications", 0,
+ generateNotificationRecord(null).getNotification(), 0);
+
+ assertThat(mPostNotificationTrackerFactory.mCreatedTrackers).hasSize(1);
+ assertThat(mPostNotificationTrackerFactory.mCreatedTrackers.get(0).isOngoing()).isTrue();
+
+ waitForIdle();
+
+ assertThat(mBinderService.getActiveNotifications(PKG)).hasLength(1);
+ assertThat(mPostNotificationTrackerFactory.mCreatedTrackers).hasSize(1);
+ assertThat(mPostNotificationTrackerFactory.mCreatedTrackers.get(0).isOngoing()).isFalse();
+ }
+
+ @Test
+ public void enqueueNotificationWithTag_throws_usesAndCancelsTracker() throws Exception {
+ // Simulate not enqueued due to rejected inputs.
+ assertThrows(Exception.class,
+ () -> mBinderService.enqueueNotificationWithTag(PKG, PKG,
+ "testEnqueueNotificationWithTag_PopulatesGetActiveNotifications", 0,
+ /* notification= */ null, 0));
+
+ waitForIdle();
+
+ assertThat(mBinderService.getActiveNotifications(PKG)).hasLength(0);
+ assertThat(mPostNotificationTrackerFactory.mCreatedTrackers).hasSize(1);
+ assertThat(mPostNotificationTrackerFactory.mCreatedTrackers.get(0).isOngoing()).isFalse();
+ }
+
+ @Test
+ public void enqueueNotificationWithTag_notEnqueued_usesAndCancelsTracker() throws Exception {
+ // Simulate not enqueued due to snoozing inputs.
+ when(mSnoozeHelper.getSnoozeContextForUnpostedNotification(anyInt(), any(), any()))
+ .thenReturn("zzzzzzz");
+
+ mBinderService.enqueueNotificationWithTag(PKG, PKG,
+ "testEnqueueNotificationWithTag_PopulatesGetActiveNotifications", 0,
+ generateNotificationRecord(null).getNotification(), 0);
+ waitForIdle();
+
+ assertThat(mBinderService.getActiveNotifications(PKG)).hasLength(0);
+ assertThat(mPostNotificationTrackerFactory.mCreatedTrackers).hasSize(1);
+ assertThat(mPostNotificationTrackerFactory.mCreatedTrackers.get(0).isOngoing()).isFalse();
+ }
+
+ @Test
+ public void enqueueNotificationWithTag_notPosted_usesAndCancelsTracker() throws Exception {
+ // Simulate not posted due to blocked app.
+ when(mPermissionHelper.hasPermission(anyInt())).thenReturn(false);
+
+ mBinderService.enqueueNotificationWithTag(PKG, PKG,
+ "testEnqueueNotificationWithTag_PopulatesGetActiveNotifications", 0,
+ generateNotificationRecord(null).getNotification(), 0);
+ waitForIdle();
+
+ assertThat(mBinderService.getActiveNotifications(PKG)).hasLength(0);
+ assertThat(mPostNotificationTrackerFactory.mCreatedTrackers).hasSize(1);
+ assertThat(mPostNotificationTrackerFactory.mCreatedTrackers.get(0).isOngoing()).isFalse();
+ }
+
+ @Test
public void testCancelNonexistentNotification() throws Exception {
mBinderService.cancelNotificationWithTag(PKG, PKG,
"testCancelNonexistentNotification", 0, 0);
@@ -1908,8 +1996,10 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
mService.mSummaryByGroupKey.put("pkg", summary);
mService.mAutobundledSummaries.put(0, new ArrayMap<>());
mService.mAutobundledSummaries.get(0).put("pkg", summary.getKey());
+
mService.updateAutobundledSummaryFlags(
0, "pkg", GroupHelper.BASE_FLAGS | FLAG_ONGOING_EVENT, false);
+ waitForIdle();
assertTrue(summary.getSbn().isOngoing());
}
@@ -1926,6 +2016,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
mService.mSummaryByGroupKey.put("pkg", summary);
mService.updateAutobundledSummaryFlags(0, "pkg", GroupHelper.BASE_FLAGS, false);
+ waitForIdle();
assertFalse(summary.getSbn().isOngoing());
}
@@ -3775,6 +3866,37 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
}
@Test
+ public void testSnoozeRunnable_snoozeAutoGroupChild_summaryNotSnoozed() throws Exception {
+ final NotificationRecord parent = generateNotificationRecord(
+ mTestNotificationChannel, 1, GroupHelper.AUTOGROUP_KEY, true);
+ final NotificationRecord child = generateNotificationRecord(
+ mTestNotificationChannel, 2, GroupHelper.AUTOGROUP_KEY, false);
+ mService.addNotification(parent);
+ mService.addNotification(child);
+ when(mSnoozeHelper.canSnooze(anyInt())).thenReturn(true);
+
+ // snooze child only
+ NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
+ mService.new SnoozeNotificationRunnable(
+ child.getKey(), 100, null);
+ snoozeNotificationRunnable.run();
+
+ // only child should be snoozed
+ verify(mSnoozeHelper, times(1)).snooze(any(NotificationRecord.class), anyLong());
+
+ // both group summary and child should be cancelled
+ assertNull(mService.getNotificationRecord(parent.getKey()));
+ assertNull(mService.getNotificationRecord(child.getKey()));
+
+ assertEquals(4, mNotificationRecordLogger.numCalls());
+ assertEquals(NotificationRecordLogger.NotificationEvent.NOTIFICATION_SNOOZED,
+ mNotificationRecordLogger.event(0));
+ assertEquals(
+ NotificationRecordLogger.NotificationCancelledEvent.NOTIFICATION_CANCEL_SNOOZED,
+ mNotificationRecordLogger.event(1));
+ }
+
+ @Test
public void testPostGroupChild_unsnoozeParent() throws Exception {
final NotificationRecord child = generateNotificationRecord(
mTestNotificationChannel, 2, "group", false);
@@ -4228,7 +4350,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
mService.addEnqueuedNotification(r);
NotificationManagerService.PostNotificationRunnable runnable =
mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(),
- r.getUid(), SystemClock.elapsedRealtime());
+ r.getUid(), mPostNotificationTrackerFactory.newTracker());
runnable.run();
waitForIdle();
@@ -4247,7 +4369,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
NotificationManagerService.PostNotificationRunnable runnable =
mService.new PostNotificationRunnable(update.getKey(),
update.getSbn().getPackageName(), update.getUid(),
- SystemClock.elapsedRealtime());
+ mPostNotificationTrackerFactory.newTracker());
runnable.run();
waitForIdle();
@@ -4267,7 +4389,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
NotificationManagerService.PostNotificationRunnable runnable =
mService.new PostNotificationRunnable(update.getKey(),
update.getSbn().getPackageName(), update.getUid(),
- SystemClock.elapsedRealtime());
+ mPostNotificationTrackerFactory.newTracker());
runnable.run();
waitForIdle();
@@ -4287,7 +4409,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
NotificationManagerService.PostNotificationRunnable runnable =
mService.new PostNotificationRunnable(update.getKey(),
update.getSbn().getPackageName(),
- update.getUid(), SystemClock.elapsedRealtime());
+ update.getUid(), mPostNotificationTrackerFactory.newTracker());
runnable.run();
waitForIdle();
@@ -4301,13 +4423,13 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
mService.addEnqueuedNotification(r);
NotificationManagerService.PostNotificationRunnable runnable =
mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(),
- r.getUid(), SystemClock.elapsedRealtime());
+ r.getUid(), mPostNotificationTrackerFactory.newTracker());
runnable.run();
r = generateNotificationRecord(mTestNotificationChannel, 1, null, false);
r.setCriticality(CriticalNotificationExtractor.CRITICAL);
runnable = mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(),
- r.getUid(), SystemClock.elapsedRealtime());
+ r.getUid(), mPostNotificationTrackerFactory.newTracker());
mService.addEnqueuedNotification(r);
runnable.run();
@@ -4956,7 +5078,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
mService.new PostNotificationRunnable(original.getKey(),
original.getSbn().getPackageName(),
original.getUid(),
- SystemClock.elapsedRealtime());
+ mPostNotificationTrackerFactory.newTracker());
runnable.run();
waitForIdle();
@@ -4980,7 +5102,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
mService.new PostNotificationRunnable(update.getKey(),
update.getSbn().getPackageName(),
update.getUid(),
- SystemClock.elapsedRealtime());
+ mPostNotificationTrackerFactory.newTracker());
runnable.run();
waitForIdle();
@@ -7286,8 +7408,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
NotificationManagerService.PostNotificationRunnable runnable =
mService.new PostNotificationRunnable(update.getKey(), r.getSbn().getPackageName(),
- r.getUid(),
- SystemClock.elapsedRealtime());
+ r.getUid(), mPostNotificationTrackerFactory.newTracker());
runnable.run();
waitForIdle();
@@ -7595,13 +7716,12 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
@Test
public void clearDefaultDnDPackageShouldEnableIt() throws RemoteException {
- ComponentName deviceConfig = new ComponentName("device", "config");
ArrayMap<Boolean, ArrayList<ComponentName>> changed = generateResetComponentValues();
when(mAssistants.resetComponents(anyString(), anyInt())).thenReturn(changed);
when(mListeners.resetComponents(anyString(), anyInt())).thenReturn(changed);
- mService.getBinderService().clearData("device", 0, false);
+ mService.getBinderService().clearData("pkgName", 0, false);
verify(mConditionProviders, times(1)).resetPackage(
- eq("device"), eq(0));
+ eq("pkgName"), eq(0));
}
@Test
@@ -8445,7 +8565,6 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
assertEquals(0, notifsBefore.length);
Uri uri = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, 1);
- int uid = 0; // sysui on primary user
mService.mNotificationDelegate.grantInlineReplyUriPermission(
nr.getKey(), uri, nr.getSbn().getUser(), nr.getSbn().getPackageName(),
@@ -8578,7 +8697,6 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
reset(mPackageManager);
Uri uri1 = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, 1);
- Uri uri2 = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, 2);
// create an inline record a uri in it
mService.mNotificationDelegate.grantInlineReplyUriPermission(
@@ -9982,7 +10100,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
mService.addEnqueuedNotification(r);
NotificationManagerService.PostNotificationRunnable runnable =
mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(),
- r.getUid(), SystemClock.elapsedRealtime());
+ r.getUid(), mPostNotificationTrackerFactory.newTracker());
runnable.run();
waitForIdle();
@@ -9999,7 +10117,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
mService.addEnqueuedNotification(r);
runnable = mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(),
- r.getUid(), SystemClock.elapsedRealtime());
+ r.getUid(), mPostNotificationTrackerFactory.newTracker());
runnable.run();
waitForIdle();
@@ -10016,7 +10134,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
mService.addEnqueuedNotification(r);
runnable = mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(),
- r.getUid(), SystemClock.elapsedRealtime());
+ r.getUid(), mPostNotificationTrackerFactory.newTracker());
runnable.run();
waitForIdle();
@@ -10108,10 +10226,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
// normal blocked notifications - blocked
mService.addEnqueuedNotification(r);
- NotificationManagerService.PostNotificationRunnable runnable =
- mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(),
- r.getUid(), SystemClock.elapsedRealtime());
- runnable.run();
+ mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(), r.getUid(),
+ mPostNotificationTrackerFactory.newTracker()).run();
waitForIdle();
verify(mUsageStats).registerBlocked(any());
@@ -10128,9 +10244,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
mService.addEnqueuedNotification(r);
- runnable = mService.new PostNotificationRunnable(
- r.getKey(), r.getSbn().getPackageName(), r.getUid(), SystemClock.elapsedRealtime());
- runnable.run();
+ mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(), r.getUid(),
+ mPostNotificationTrackerFactory.newTracker()).run();
waitForIdle();
verify(mUsageStats).registerBlocked(any());
@@ -10142,7 +10257,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
when(mTelecomManager.isInManagedCall()).thenReturn(true);
mService.addEnqueuedNotification(r);
- runnable.run();
+ mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(), r.getUid(),
+ mPostNotificationTrackerFactory.newTracker()).run();
waitForIdle();
verify(mUsageStats, never()).registerBlocked(any());
@@ -10155,7 +10271,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
.thenReturn(true);
mService.addEnqueuedNotification(r);
- runnable.run();
+ mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(), r.getUid(),
+ mPostNotificationTrackerFactory.newTracker()).run();
waitForIdle();
verify(mUsageStats, never()).registerBlocked(any());
@@ -10168,7 +10285,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
mService.setTelecomManager(null);
mService.addEnqueuedNotification(r);
- runnable.run();
+ mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(), r.getUid(),
+ mPostNotificationTrackerFactory.newTracker()).run();
waitForIdle();
verify(mUsageStats).registerBlocked(any());
@@ -10182,7 +10300,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
mService.setTelecomManager(null);
mService.addEnqueuedNotification(r);
- runnable.run();
+ mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(), r.getUid(),
+ mPostNotificationTrackerFactory.newTracker()).run();
waitForIdle();
verify(mUsageStats).registerBlocked(any());
@@ -10194,7 +10313,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
reset(mUsageStats);
mService.addEnqueuedNotification(r);
- runnable.run();
+ mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(), r.getUid(),
+ mPostNotificationTrackerFactory.newTracker()).run();
waitForIdle();
verify(mUsageStats).registerBlocked(any());
@@ -10592,6 +10712,90 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
}
@Test
+ public void checkCallStyleNotification_withoutAnyValidUseCase_throws() throws Exception {
+ Person person = new Person.Builder().setName("caller").build();
+ Notification n = new Notification.Builder(mContext, "test")
+ .setStyle(Notification.CallStyle.forOngoingCall(
+ person, mock(PendingIntent.class)))
+ .build();
+ StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
+ n, UserHandle.getUserHandleForUid(mUid), null, 0);
+ NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
+
+ try {
+ mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(),
+ r.getSbn().getId(), r.getSbn().getTag(), r, false);
+ assertFalse("CallStyle should not be allowed without a valid use case", true);
+ } catch (IllegalArgumentException error) {
+ assertThat(error.getMessage()).contains("CallStyle");
+ }
+ }
+
+ @Test
+ public void checkCallStyleNotification_allowedForFgs() throws Exception {
+ Person person = new Person.Builder().setName("caller").build();
+ Notification n = new Notification.Builder(mContext, "test")
+ .setFlag(FLAG_FOREGROUND_SERVICE, true)
+ .setStyle(Notification.CallStyle.forOngoingCall(
+ person, mock(PendingIntent.class)))
+ .build();
+ StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
+ n, UserHandle.getUserHandleForUid(mUid), null, 0);
+ NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
+
+ assertThat(mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(),
+ r.getSbn().getId(), r.getSbn().getTag(), r, false)).isTrue();
+ }
+
+ @Test
+ public void checkCallStyleNotification_allowedForUij() throws Exception {
+ Person person = new Person.Builder().setName("caller").build();
+ Notification n = new Notification.Builder(mContext, "test")
+ .setFlag(FLAG_USER_INITIATED_JOB, true)
+ .setStyle(Notification.CallStyle.forOngoingCall(
+ person, mock(PendingIntent.class)))
+ .build();
+ StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
+ n, UserHandle.getUserHandleForUid(mUid), null, 0);
+ NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
+
+ assertThat(mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(),
+ r.getSbn().getId(), r.getSbn().getTag(), r, false)).isTrue();
+ }
+
+ @Test
+ public void checkCallStyleNotification_allowedForFsiAllowed() throws Exception {
+ Person person = new Person.Builder().setName("caller").build();
+ Notification n = new Notification.Builder(mContext, "test")
+ .setFullScreenIntent(mock(PendingIntent.class), true)
+ .setStyle(Notification.CallStyle.forOngoingCall(
+ person, mock(PendingIntent.class)))
+ .build();
+ StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
+ n, UserHandle.getUserHandleForUid(mUid), null, 0);
+ NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
+
+ assertThat(mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(),
+ r.getSbn().getId(), r.getSbn().getTag(), r, false)).isTrue();
+ }
+
+ @Test
+ public void checkCallStyleNotification_allowedForFsiDenied() throws Exception {
+ Person person = new Person.Builder().setName("caller").build();
+ Notification n = new Notification.Builder(mContext, "test")
+ .setFlag(Notification.FLAG_FSI_REQUESTED_BUT_DENIED, true)
+ .setStyle(Notification.CallStyle.forOngoingCall(
+ person, mock(PendingIntent.class)))
+ .build();
+ StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
+ n, UserHandle.getUserHandleForUid(mUid), null, 0);
+ NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
+
+ assertThat(mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(),
+ r.getSbn().getId(), r.getSbn().getTag(), r, false)).isTrue();
+ }
+
+ @Test
public void fixSystemNotification_withOnGoingFlag_shouldBeDismissible()
throws Exception {
final ApplicationInfo ai = new ApplicationInfo();
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordLoggerFake.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordLoggerFake.java
index 8a11798bbf19..1bb35021d76c 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordLoggerFake.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordLoggerFake.java
@@ -16,11 +16,15 @@
package com.android.server.notification;
+import androidx.annotation.Nullable;
+
import com.android.internal.logging.InstanceId;
import com.android.internal.logging.UiEventLogger;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
/**
* Fake implementation of NotificationRecordLogger, for testing.
@@ -60,7 +64,8 @@ class NotificationRecordLoggerFake implements NotificationRecordLogger {
this.event = event;
}
}
- private List<CallRecord> mCalls = new ArrayList<>();
+ private final List<CallRecord> mCalls = new ArrayList<>();
+ private final Map<NotificationReported, CallRecord> mPendingLogs = new HashMap<>();
public int numCalls() {
return mCalls.size();
@@ -70,6 +75,10 @@ class NotificationRecordLoggerFake implements NotificationRecordLogger {
return mCalls;
}
+ List<NotificationReported> getPendingLogs() {
+ return new ArrayList<>(mPendingLogs.keySet());
+ }
+
CallRecord get(int index) {
return mCalls.get(index);
}
@@ -77,10 +86,31 @@ class NotificationRecordLoggerFake implements NotificationRecordLogger {
return mCalls.get(index).event;
}
+ @Nullable
+ @Override
+ public NotificationReported prepareToLogNotificationPosted(@Nullable NotificationRecord r,
+ @Nullable NotificationRecord old, int position, int buzzBeepBlink, InstanceId groupId) {
+ NotificationReported nr = NotificationRecordLogger.super.prepareToLogNotificationPosted(r,
+ old, position, buzzBeepBlink, groupId);
+ CallRecord callRecord = new CallRecord(r, old, position, buzzBeepBlink, groupId);
+ callRecord.wasLogged = false;
+ mCalls.add(callRecord);
+ if (nr != null) {
+ mPendingLogs.put(nr, callRecord);
+ }
+ return nr;
+ }
+
@Override
- public void maybeLogNotificationPosted(NotificationRecord r, NotificationRecord old,
- int position, int buzzBeepBlink, InstanceId groupId) {
- mCalls.add(new CallRecord(r, old, position, buzzBeepBlink, groupId));
+ public void logNotificationPosted(NotificationReported nr) {
+ CallRecord callRecord = mPendingLogs.get(nr);
+ if (callRecord == null) {
+ throw new IllegalStateException(
+ "Didn't find corresponding CallRecord in mPreparedCalls. Did you call "
+ + "logNotificationPosted() twice!?");
+ }
+ mPendingLogs.remove(nr);
+ callRecord.wasLogged = true;
}
@Override
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java b/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java
index 34bb664c9598..d4a2e9aa4f5b 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java
@@ -28,7 +28,6 @@ import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -56,7 +55,6 @@ import android.telecom.TelecomManager;
import android.telephony.TelephonyManager;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
-import android.testing.TestableContext;
import android.testing.TestableLooper.RunWithLooper;
import android.util.ArraySet;
import android.util.AtomicFile;
@@ -64,7 +62,6 @@ import android.util.Pair;
import androidx.test.InstrumentationRegistry;
-import com.android.internal.app.IAppOpsService;
import com.android.internal.config.sysui.TestableFlagResolver;
import com.android.internal.logging.InstanceIdSequence;
import com.android.internal.logging.InstanceIdSequenceFake;
@@ -162,14 +159,14 @@ public class RoleObserverTest extends UiServiceTestCase {
mock(UsageStatsManagerInternal.class),
mock(DevicePolicyManagerInternal.class), mock(IUriGrantsManager.class),
mock(UriGrantsManagerInternal.class),
- mock(AppOpsManager.class), mock(IAppOpsService.class),
- mUm, mock(NotificationHistoryManager.class),
+ mock(AppOpsManager.class), mUm, mock(NotificationHistoryManager.class),
mock(StatsManager.class), mock(TelephonyManager.class),
mock(ActivityManagerInternal.class),
mock(MultiRateLimiter.class), mock(PermissionHelper.class),
- mock(UsageStatsManagerInternal.class), mock (TelecomManager.class),
+ mock(UsageStatsManagerInternal.class), mock(TelecomManager.class),
mock(NotificationChannelLogger.class), new TestableFlagResolver(),
- mock(PermissionManager.class));
+ mock(PermissionManager.class),
+ new NotificationManagerService.PostNotificationTrackerFactory() {});
} catch (SecurityException e) {
if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
throw e;
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
index b2a54010e75e..cb41769c3619 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
@@ -55,14 +55,13 @@ import static junit.framework.TestCase.fail;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNull;
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.ArgumentMatchers.eq;
import static org.mockito.Mockito.atLeastOnce;
-import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.notNull;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
@@ -149,7 +148,7 @@ public class ZenModeHelperTest extends UiServiceTestCase {
@Mock PackageManager mPackageManager;
private Resources mResources;
private TestableLooper mTestableLooper;
- private ZenModeHelper mZenModeHelperSpy;
+ private ZenModeHelper mZenModeHelper;
private ContentResolver mContentResolver;
@Mock AppOpsManager mAppOps;
private WrappedSysUiStatsEvent.WrappedBuilderFactory mStatsEventBuilderFactory;
@@ -176,8 +175,8 @@ public class ZenModeHelperTest extends UiServiceTestCase {
mConditionProviders = new ConditionProviders(mContext, new UserProfiles(),
AppGlobals.getPackageManager());
mConditionProviders.addSystemProvider(new CountdownConditionProvider());
- mZenModeHelperSpy = spy(new ZenModeHelper(mContext, mTestableLooper.getLooper(),
- mConditionProviders, mStatsEventBuilderFactory));
+ mZenModeHelper = new ZenModeHelper(mContext, mTestableLooper.getLooper(),
+ mConditionProviders, mStatsEventBuilderFactory);
ResolveInfo ri = new ResolveInfo();
ri.activityInfo = new ActivityInfo();
@@ -187,7 +186,7 @@ public class ZenModeHelperTest extends UiServiceTestCase {
.thenReturn(CUSTOM_PKG_UID);
when(mPackageManager.getPackagesForUid(anyInt())).thenReturn(
new String[] {pkg});
- mZenModeHelperSpy.mPm = mPackageManager;
+ mZenModeHelper.mPm = mPackageManager;
}
private XmlResourceParser getDefaultConfigParser() throws IOException, XmlPullParserException {
@@ -221,10 +220,10 @@ public class ZenModeHelperTest extends UiServiceTestCase {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
serializer.startDocument(null, true);
- mZenModeHelperSpy.writeXml(serializer, false, version, UserHandle.USER_ALL);
+ mZenModeHelper.writeXml(serializer, false, version, UserHandle.USER_ALL);
serializer.endDocument();
serializer.flush();
- mZenModeHelperSpy.setConfig(new ZenModeConfig(), null, "writing xml");
+ mZenModeHelper.setConfig(new ZenModeConfig(), null, "writing xml");
return baos;
}
@@ -234,12 +233,12 @@ public class ZenModeHelperTest extends UiServiceTestCase {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
serializer.startDocument(null, true);
- mZenModeHelperSpy.writeXml(serializer, true, version, userId);
+ mZenModeHelper.writeXml(serializer, true, version, userId);
serializer.endDocument();
serializer.flush();
ZenModeConfig newConfig = new ZenModeConfig();
newConfig.user = userId;
- mZenModeHelperSpy.setConfig(newConfig, null, "writing xml");
+ mZenModeHelper.setConfig(newConfig, null, "writing xml");
return baos;
}
@@ -277,209 +276,209 @@ public class ZenModeHelperTest extends UiServiceTestCase {
return customRule;
}
+ // Verify that the appropriate appOpps operations are called for the restrictions requested.
+ // Note that this method assumes that priority only DND exempt packages is set to something
+ // in order to be able to distinguish it from the null case, so callers should make sure
+ // setPriorityOnlyDndExemptPackages has been called bofre this verify statement.
+ private void verifyApplyRestrictions(boolean zenPriorityOnly, boolean mute, int usage) {
+ int expectedMode = mute ? AppOpsManager.MODE_IGNORED : AppOpsManager.MODE_ALLOWED;
+ verify(mAppOps, atLeastOnce()).setRestriction(eq(AppOpsManager.OP_VIBRATE), eq(usage),
+ eq(expectedMode), zenPriorityOnly ? notNull() : eq(null));
+ verify(mAppOps, atLeastOnce()).setRestriction(eq(AppOpsManager.OP_PLAY_AUDIO), eq(usage),
+ eq(expectedMode), zenPriorityOnly ? notNull() : eq(null));
+ }
+
@Test
public void testZenOff_NoMuteApplied() {
- mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_OFF;
- mZenModeHelperSpy.mConsolidatedPolicy = new Policy(Policy.PRIORITY_CATEGORY_ALARMS |
- PRIORITY_CATEGORY_MEDIA, 0, 0, 0, 0, 0);
- mZenModeHelperSpy.applyRestrictions();
+ mZenModeHelper.mZenMode = Settings.Global.ZEN_MODE_OFF;
+ mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[] {PKG_O});
+ mZenModeHelper.mConsolidatedPolicy = new Policy(Policy.PRIORITY_CATEGORY_ALARMS
+ | PRIORITY_CATEGORY_MEDIA, 0, 0, 0, 0, 0);
+ mZenModeHelper.applyRestrictions();
- doNothing().when(mZenModeHelperSpy).applyRestrictions(eq(false), anyBoolean(), anyInt());
- verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, false,
- AudioAttributes.USAGE_ALARM);
- verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, false,
- AudioAttributes.USAGE_MEDIA);
+ // Check that we call through to applyRestrictions with usages USAGE_ALARM and USAGE_MEDIA
+ verifyApplyRestrictions(false, false, AudioAttributes.USAGE_ALARM);
+ verifyApplyRestrictions(false, false, AudioAttributes.USAGE_MEDIA);
}
@Test
public void testZenOn_NotificationApplied() {
- mZenModeHelperSpy.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+ mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+ mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[] {PKG_O});
// The most permissive policy
- mZenModeHelperSpy.mConsolidatedPolicy = new Policy(Policy.PRIORITY_CATEGORY_ALARMS |
- PRIORITY_CATEGORY_MEDIA | PRIORITY_CATEGORY_MESSAGES
+ mZenModeHelper.mConsolidatedPolicy = new Policy(Policy.PRIORITY_CATEGORY_ALARMS
+ | PRIORITY_CATEGORY_MEDIA | PRIORITY_CATEGORY_MESSAGES
| PRIORITY_CATEGORY_CONVERSATIONS | PRIORITY_CATEGORY_CALLS
| PRIORITY_CATEGORY_ALARMS | PRIORITY_CATEGORY_EVENTS | PRIORITY_CATEGORY_REMINDERS
| PRIORITY_CATEGORY_REPEAT_CALLERS | PRIORITY_CATEGORY_SYSTEM, PRIORITY_SENDERS_ANY,
PRIORITY_SENDERS_ANY, 0, CONVERSATION_SENDERS_ANYONE);
- mZenModeHelperSpy.applyRestrictions();
-
- doNothing().when(mZenModeHelperSpy).applyRestrictions(anyBoolean(), anyBoolean(), anyInt());
- verify(mZenModeHelperSpy).applyRestrictions(true, true,
- AudioAttributes.USAGE_NOTIFICATION);
- verify(mZenModeHelperSpy).applyRestrictions(true, true,
- AudioAttributes.USAGE_NOTIFICATION_EVENT);
- verify(mZenModeHelperSpy).applyRestrictions(true, true,
+ mZenModeHelper.applyRestrictions();
+
+ verifyApplyRestrictions(true, true, AudioAttributes.USAGE_NOTIFICATION);
+ verifyApplyRestrictions(true, true, AudioAttributes.USAGE_NOTIFICATION_EVENT);
+ verifyApplyRestrictions(true, true,
AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_DELAYED);
- verify(mZenModeHelperSpy).applyRestrictions(true, true,
+ verifyApplyRestrictions(true, true,
AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_INSTANT);
}
@Test
public void testZenOn_StarredCallers_CallTypesBlocked() {
- mZenModeHelperSpy.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+ mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+ mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[] {PKG_O});
// The most permissive policy
- mZenModeHelperSpy.mConsolidatedPolicy = new Policy(Policy.PRIORITY_CATEGORY_ALARMS |
- PRIORITY_CATEGORY_MEDIA | PRIORITY_CATEGORY_MESSAGES
+ mZenModeHelper.mConsolidatedPolicy = new Policy(Policy.PRIORITY_CATEGORY_ALARMS
+ | PRIORITY_CATEGORY_MEDIA | PRIORITY_CATEGORY_MESSAGES
| PRIORITY_CATEGORY_CONVERSATIONS | PRIORITY_CATEGORY_CALLS
| PRIORITY_CATEGORY_ALARMS | PRIORITY_CATEGORY_EVENTS | PRIORITY_CATEGORY_REMINDERS
| PRIORITY_CATEGORY_SYSTEM,
PRIORITY_SENDERS_STARRED,
PRIORITY_SENDERS_ANY, 0, CONVERSATION_SENDERS_ANYONE);
- mZenModeHelperSpy.applyRestrictions();
+ mZenModeHelper.applyRestrictions();
- doNothing().when(mZenModeHelperSpy).applyRestrictions(anyBoolean(), anyBoolean(), anyInt());
- verify(mZenModeHelperSpy).applyRestrictions(true, true,
+ verifyApplyRestrictions(true, true,
AudioAttributes.USAGE_NOTIFICATION_RINGTONE);
- verify(mZenModeHelperSpy).applyRestrictions(true, true,
+ verifyApplyRestrictions(true, true,
AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_REQUEST);
}
@Test
public void testZenOn_AllCallers_CallTypesAllowed() {
- mZenModeHelperSpy.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+ mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+ mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[] {PKG_O});
// The most permissive policy
- mZenModeHelperSpy.mConsolidatedPolicy = new Policy(Policy.PRIORITY_CATEGORY_ALARMS |
- PRIORITY_CATEGORY_MEDIA | PRIORITY_CATEGORY_MESSAGES
+ mZenModeHelper.mConsolidatedPolicy = new Policy(Policy.PRIORITY_CATEGORY_ALARMS
+ | PRIORITY_CATEGORY_MEDIA | PRIORITY_CATEGORY_MESSAGES
| PRIORITY_CATEGORY_CONVERSATIONS | PRIORITY_CATEGORY_CALLS
| PRIORITY_CATEGORY_ALARMS | PRIORITY_CATEGORY_EVENTS | PRIORITY_CATEGORY_REMINDERS
| PRIORITY_CATEGORY_REPEAT_CALLERS | PRIORITY_CATEGORY_SYSTEM,
PRIORITY_SENDERS_ANY,
PRIORITY_SENDERS_ANY, 0, CONVERSATION_SENDERS_ANYONE);
- mZenModeHelperSpy.applyRestrictions();
+ mZenModeHelper.applyRestrictions();
- doNothing().when(mZenModeHelperSpy).applyRestrictions(anyBoolean(), anyBoolean(), anyInt());
- verify(mZenModeHelperSpy).applyRestrictions(true, false,
- AudioAttributes.USAGE_NOTIFICATION_RINGTONE);
- verify(mZenModeHelperSpy).applyRestrictions(true, false,
+ verifyApplyRestrictions(true, false, AudioAttributes.USAGE_NOTIFICATION_RINGTONE);
+ verifyApplyRestrictions(true, false,
AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_REQUEST);
}
@Test
public void testZenOn_AllowAlarmsMedia_NoAlarmMediaMuteApplied() {
- mZenModeHelperSpy.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
- mZenModeHelperSpy.mConsolidatedPolicy = new Policy(Policy.PRIORITY_CATEGORY_ALARMS |
- PRIORITY_CATEGORY_MEDIA, 0, 0, 0, 0, 0);
+ mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+ mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[] {PKG_O});
+ mZenModeHelper.mConsolidatedPolicy = new Policy(Policy.PRIORITY_CATEGORY_ALARMS
+ | PRIORITY_CATEGORY_MEDIA, 0, 0, 0, 0, 0);
- mZenModeHelperSpy.applyRestrictions();
- verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true, false,
- AudioAttributes.USAGE_ALARM);
- verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true, false,
- AudioAttributes.USAGE_MEDIA);
+ mZenModeHelper.applyRestrictions();
+ verifyApplyRestrictions(true, false, AudioAttributes.USAGE_ALARM);
+ verifyApplyRestrictions(true, false, AudioAttributes.USAGE_MEDIA);
}
@Test
public void testZenOn_DisallowAlarmsMedia_AlarmMediaMuteApplied() {
- mZenModeHelperSpy.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
- mZenModeHelperSpy.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
- mZenModeHelperSpy.applyRestrictions();
- verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true, true,
- AudioAttributes.USAGE_ALARM);
+ mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+ mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[] {PKG_O});
+ mZenModeHelper.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
+ mZenModeHelper.applyRestrictions();
+ verifyApplyRestrictions(true, true, AudioAttributes.USAGE_ALARM);
// Media is a catch-all that includes games
- verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true, true,
- AudioAttributes.USAGE_MEDIA);
- verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true, true,
- AudioAttributes.USAGE_GAME);
+ verifyApplyRestrictions(true, true, AudioAttributes.USAGE_MEDIA);
+ verifyApplyRestrictions(true, true, AudioAttributes.USAGE_GAME);
}
@Test
public void testTotalSilence() {
- mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_NO_INTERRUPTIONS;
- mZenModeHelperSpy.mConsolidatedPolicy = new Policy(Policy.PRIORITY_CATEGORY_ALARMS |
- PRIORITY_CATEGORY_MEDIA, 0, 0, 0, 0, 0);
- mZenModeHelperSpy.applyRestrictions();
+ mZenModeHelper.mZenMode = Settings.Global.ZEN_MODE_NO_INTERRUPTIONS;
+ mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[] {PKG_O});
+ mZenModeHelper.mConsolidatedPolicy = new Policy(Policy.PRIORITY_CATEGORY_ALARMS
+ | PRIORITY_CATEGORY_MEDIA, 0, 0, 0, 0, 0);
+ mZenModeHelper.applyRestrictions();
// Total silence will silence alarms, media and system noises (but not vibrations)
- verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, true,
- AudioAttributes.USAGE_ALARM);
- verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, true,
- AudioAttributes.USAGE_MEDIA);
- verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, true,
- AudioAttributes.USAGE_GAME);
- verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, true,
- AudioAttributes.USAGE_ASSISTANCE_SONIFICATION, AppOpsManager.OP_PLAY_AUDIO);
- verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, false,
- AudioAttributes.USAGE_ASSISTANCE_SONIFICATION, AppOpsManager.OP_VIBRATE);
- verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, true,
- AudioAttributes.USAGE_UNKNOWN);
+ verifyApplyRestrictions(false, true, AudioAttributes.USAGE_ALARM);
+ verifyApplyRestrictions(false, true, AudioAttributes.USAGE_MEDIA);
+ verifyApplyRestrictions(false, true, AudioAttributes.USAGE_GAME);
+ verify(mAppOps, atLeastOnce()).setRestriction(AppOpsManager.OP_PLAY_AUDIO,
+ AudioAttributes.USAGE_ASSISTANCE_SONIFICATION, AppOpsManager.MODE_IGNORED, null);
+ verify(mAppOps, atLeastOnce()).setRestriction(AppOpsManager.OP_VIBRATE,
+ AudioAttributes.USAGE_ASSISTANCE_SONIFICATION, AppOpsManager.MODE_ALLOWED, null);
+ verifyApplyRestrictions(false, true, AudioAttributes.USAGE_UNKNOWN);
}
@Test
public void testAlarmsOnly_alarmMediaMuteNotApplied() {
- mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_ALARMS;
- mZenModeHelperSpy.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
- mZenModeHelperSpy.applyRestrictions();
+ mZenModeHelper.mZenMode = Settings.Global.ZEN_MODE_ALARMS;
+ mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[] {PKG_O});
+ mZenModeHelper.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
+ mZenModeHelper.applyRestrictions();
// Alarms only mode will not silence alarms
- verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, false,
- AudioAttributes.USAGE_ALARM);
+ verifyApplyRestrictions(false, false, AudioAttributes.USAGE_ALARM);
// Alarms only mode will not silence media
- verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, false,
- AudioAttributes.USAGE_MEDIA);
- verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, false,
- AudioAttributes.USAGE_GAME);
- verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, false,
- AudioAttributes.USAGE_UNKNOWN);
+ verifyApplyRestrictions(false, false, AudioAttributes.USAGE_MEDIA);
+ verifyApplyRestrictions(false, false, AudioAttributes.USAGE_GAME);
+ verifyApplyRestrictions(false, false, AudioAttributes.USAGE_UNKNOWN);
// Alarms only will silence system noises (but not vibrations)
- verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, true,
- AudioAttributes.USAGE_ASSISTANCE_SONIFICATION, AppOpsManager.OP_PLAY_AUDIO);
+ verify(mAppOps, atLeastOnce()).setRestriction(AppOpsManager.OP_PLAY_AUDIO,
+ AudioAttributes.USAGE_ASSISTANCE_SONIFICATION, AppOpsManager.MODE_IGNORED, null);
}
@Test
public void testAlarmsOnly_callsMuteApplied() {
- mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_ALARMS;
- mZenModeHelperSpy.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
- mZenModeHelperSpy.applyRestrictions();
+ mZenModeHelper.mZenMode = Settings.Global.ZEN_MODE_ALARMS;
+ mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[] {PKG_O});
+ mZenModeHelper.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
+ mZenModeHelper.applyRestrictions();
// Alarms only mode will silence calls despite priority-mode config
- verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, true,
- AudioAttributes.USAGE_NOTIFICATION_RINGTONE);
- verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, true,
+ verifyApplyRestrictions(false, true, AudioAttributes.USAGE_NOTIFICATION_RINGTONE);
+ verifyApplyRestrictions(false, true,
AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_REQUEST);
}
@Test
public void testAlarmsOnly_allZenConfigToggledCannotBypass_alarmMuteNotApplied() {
// Only audio attributes with SUPPRESIBLE_NEVER can bypass
- mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_ALARMS;
- mZenModeHelperSpy.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
- mZenModeHelperSpy.applyRestrictions();
+ mZenModeHelper.mZenMode = Settings.Global.ZEN_MODE_ALARMS;
+ mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[] {PKG_O});
+ mZenModeHelper.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
+ mZenModeHelper.applyRestrictions();
- verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, false,
- AudioAttributes.USAGE_ALARM);
+ verifyApplyRestrictions(false, false, AudioAttributes.USAGE_ALARM);
}
@Test
public void testZenAllCannotBypass() {
// Only audio attributes with SUPPRESIBLE_NEVER can bypass
// with special case USAGE_ASSISTANCE_SONIFICATION
- mZenModeHelperSpy.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
- mZenModeHelperSpy.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
- mZenModeHelperSpy.applyRestrictions();
+ mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+ mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[] {PKG_O});
+ mZenModeHelper.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
+ mZenModeHelper.applyRestrictions();
for (int usage : AudioAttributes.SDK_USAGES) {
if (usage == AudioAttributes.USAGE_ASSISTANCE_SONIFICATION) {
// only mute audio, not vibrations
- verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true, true, usage,
- AppOpsManager.OP_PLAY_AUDIO);
- verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true, false, usage,
- AppOpsManager.OP_VIBRATE);
+ verify(mAppOps, atLeastOnce()).setRestriction(eq(AppOpsManager.OP_PLAY_AUDIO),
+ eq(usage), eq(AppOpsManager.MODE_IGNORED), notNull());
+ verify(mAppOps, atLeastOnce()).setRestriction(eq(AppOpsManager.OP_VIBRATE),
+ eq(usage), eq(AppOpsManager.MODE_ALLOWED), notNull());
} else {
boolean shouldMute = AudioAttributes.SUPPRESSIBLE_USAGES.get(usage)
!= AudioAttributes.SUPPRESSIBLE_NEVER;
- verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true, shouldMute, usage);
+ verifyApplyRestrictions(true, shouldMute, usage);
}
}
}
@Test
public void testApplyRestrictions_whitelist_priorityOnlyMode() {
- mZenModeHelperSpy.setPriorityOnlyDndExemptPackages(new String[] {PKG_O});
- mZenModeHelperSpy.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
- mZenModeHelperSpy.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
- mZenModeHelperSpy.applyRestrictions();
+ mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[] {PKG_O});
+ mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+ mZenModeHelper.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
+ mZenModeHelper.applyRestrictions();
for (int usage : AudioAttributes.SDK_USAGES) {
verify(mAppOps).setRestriction(
@@ -491,10 +490,10 @@ public class ZenModeHelperTest extends UiServiceTestCase {
@Test
public void testApplyRestrictions_whitelist_alarmsOnlyMode() {
- mZenModeHelperSpy.setPriorityOnlyDndExemptPackages(new String[] {PKG_O});
- mZenModeHelperSpy.mZenMode = Global.ZEN_MODE_ALARMS;
- mZenModeHelperSpy.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
- mZenModeHelperSpy.applyRestrictions();
+ mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[] {PKG_O});
+ mZenModeHelper.mZenMode = Global.ZEN_MODE_ALARMS;
+ mZenModeHelper.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
+ mZenModeHelper.applyRestrictions();
for (int usage : AudioAttributes.SDK_USAGES) {
verify(mAppOps).setRestriction(
@@ -506,10 +505,10 @@ public class ZenModeHelperTest extends UiServiceTestCase {
@Test
public void testApplyRestrictions_whitelist_totalSilenceMode() {
- mZenModeHelperSpy.setPriorityOnlyDndExemptPackages(new String[] {PKG_O});
- mZenModeHelperSpy.mZenMode = Global.ZEN_MODE_NO_INTERRUPTIONS;
- mZenModeHelperSpy.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
- mZenModeHelperSpy.applyRestrictions();
+ mZenModeHelper.setPriorityOnlyDndExemptPackages(new String[] {PKG_O});
+ mZenModeHelper.mZenMode = Global.ZEN_MODE_NO_INTERRUPTIONS;
+ mZenModeHelper.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
+ mZenModeHelper.applyRestrictions();
for (int usage : AudioAttributes.SDK_USAGES) {
verify(mAppOps).setRestriction(
@@ -533,11 +532,10 @@ public class ZenModeHelperTest extends UiServiceTestCase {
// and we're setting zen mode on
Settings.Secure.putInt(mContentResolver, Settings.Secure.SHOW_ZEN_UPGRADE_NOTIFICATION, 1);
Settings.Secure.putInt(mContentResolver, Settings.Secure.ZEN_SETTINGS_UPDATED, 0);
- mZenModeHelperSpy.mIsBootComplete = true;
- mZenModeHelperSpy.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
- mZenModeHelperSpy.setZenModeSetting(ZEN_MODE_IMPORTANT_INTERRUPTIONS);
+ mZenModeHelper.mIsBootComplete = true;
+ mZenModeHelper.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0, 0);
+ mZenModeHelper.setZenModeSetting(ZEN_MODE_IMPORTANT_INTERRUPTIONS);
- verify(mZenModeHelperSpy, times(1)).createZenUpgradeNotification();
verify(mNotificationManager, times(1)).notify(eq(ZenModeHelper.TAG),
eq(SystemMessage.NOTE_ZEN_UPGRADE), any());
assertEquals(0, Settings.Secure.getInt(mContentResolver,
@@ -549,10 +547,9 @@ public class ZenModeHelperTest extends UiServiceTestCase {
// doesn't show upgrade notification if stored settings says don't show
Settings.Secure.putInt(mContentResolver, Settings.Secure.SHOW_ZEN_UPGRADE_NOTIFICATION, 0);
Settings.Secure.putInt(mContentResolver, Settings.Secure.ZEN_SETTINGS_UPDATED, 0);
- mZenModeHelperSpy.mIsBootComplete = true;
- mZenModeHelperSpy.setZenModeSetting(ZEN_MODE_IMPORTANT_INTERRUPTIONS);
+ mZenModeHelper.mIsBootComplete = true;
+ mZenModeHelper.setZenModeSetting(ZEN_MODE_IMPORTANT_INTERRUPTIONS);
- verify(mZenModeHelperSpy, never()).createZenUpgradeNotification();
verify(mNotificationManager, never()).notify(eq(ZenModeHelper.TAG),
eq(SystemMessage.NOTE_ZEN_UPGRADE), any());
}
@@ -562,10 +559,9 @@ public class ZenModeHelperTest extends UiServiceTestCase {
// doesn't show upgrade notification since zen was already updated
Settings.Secure.putInt(mContentResolver, Settings.Secure.SHOW_ZEN_UPGRADE_NOTIFICATION, 0);
Settings.Secure.putInt(mContentResolver, Settings.Secure.ZEN_SETTINGS_UPDATED, 1);
- mZenModeHelperSpy.mIsBootComplete = true;
- mZenModeHelperSpy.setZenModeSetting(ZEN_MODE_IMPORTANT_INTERRUPTIONS);
+ mZenModeHelper.mIsBootComplete = true;
+ mZenModeHelper.setZenModeSetting(ZEN_MODE_IMPORTANT_INTERRUPTIONS);
- verify(mZenModeHelperSpy, never()).createZenUpgradeNotification();
verify(mNotificationManager, never()).notify(eq(ZenModeHelper.TAG),
eq(SystemMessage.NOTE_ZEN_UPGRADE), any());
}
@@ -573,41 +569,41 @@ public class ZenModeHelperTest extends UiServiceTestCase {
@Test
public void testZenSetInternalRinger_AllPriorityNotificationSoundsMuted() {
AudioManagerInternal mAudioManager = mock(AudioManagerInternal.class);
- mZenModeHelperSpy.mAudioManager = mAudioManager;
+ mZenModeHelper.mAudioManager = mAudioManager;
Global.putString(mContext.getContentResolver(), Global.ZEN_MODE_RINGER_LEVEL,
Integer.toString(AudioManager.RINGER_MODE_NORMAL));
// 1. Current ringer is normal
when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
// Set zen to priority-only with all notification sounds muted (so ringer will be muted)
- mZenModeHelperSpy.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
- mZenModeHelperSpy.mConfig.allowReminders = false;
- mZenModeHelperSpy.mConfig.allowCalls = false;
- mZenModeHelperSpy.mConfig.allowMessages = false;
- mZenModeHelperSpy.mConfig.allowEvents = false;
- mZenModeHelperSpy.mConfig.allowRepeatCallers = false;
- mZenModeHelperSpy.mConfig.allowConversations = false;
+ mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+ mZenModeHelper.mConfig.allowReminders = false;
+ mZenModeHelper.mConfig.allowCalls = false;
+ mZenModeHelper.mConfig.allowMessages = false;
+ mZenModeHelper.mConfig.allowEvents = false;
+ mZenModeHelper.mConfig.allowRepeatCallers = false;
+ mZenModeHelper.mConfig.allowConversations = false;
// 2. apply priority only zen - verify ringer is unchanged
- mZenModeHelperSpy.applyZenToRingerMode();
+ mZenModeHelper.applyZenToRingerMode();
verify(mAudioManager, never()).setRingerModeInternal(AudioManager.RINGER_MODE_SILENT,
- mZenModeHelperSpy.TAG);
+ mZenModeHelper.TAG);
// 3. apply zen off - verify zen is set to previous ringer (normal)
when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT);
- mZenModeHelperSpy.mZenMode = Global.ZEN_MODE_OFF;
- mZenModeHelperSpy.applyZenToRingerMode();
+ mZenModeHelper.mZenMode = Global.ZEN_MODE_OFF;
+ mZenModeHelper.applyZenToRingerMode();
verify(mAudioManager, atLeastOnce()).setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
- mZenModeHelperSpy.TAG);
+ mZenModeHelper.TAG);
}
@Test
public void testRingerAffectedStreamsTotalSilence() {
// in total silence:
// ringtone, notification, system, alarm, streams, music are affected by ringer mode
- mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_NO_INTERRUPTIONS;
+ mZenModeHelper.mZenMode = Settings.Global.ZEN_MODE_NO_INTERRUPTIONS;
ZenModeHelper.RingerModeDelegate ringerModeDelegate =
- mZenModeHelperSpy.new RingerModeDelegate();
+ mZenModeHelper.new RingerModeDelegate();
int ringerModeAffectedStreams = ringerModeDelegate.getRingerModeAffectedStreams(0);
assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_RING)) != 0);
assertTrue((ringerModeAffectedStreams & (1 << AudioSystem.STREAM_NOTIFICATION))
@@ -622,11 +618,11 @@ public class ZenModeHelperTest extends UiServiceTestCase {
public void testRingerAffectedStreamsPriorityOnly() {
// in priority only mode:
// ringtone, notification and system streams are affected by ringer mode
- mZenModeHelperSpy.mConfig.allowAlarms = true;
- mZenModeHelperSpy.mConfig.allowReminders = true;
- mZenModeHelperSpy.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+ mZenModeHelper.mConfig.allowAlarms = true;
+ mZenModeHelper.mConfig.allowReminders = true;
+ mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
ZenModeHelper.RingerModeDelegate ringerModeDelegateRingerMuted =
- mZenModeHelperSpy.new RingerModeDelegate();
+ mZenModeHelper.new RingerModeDelegate();
int ringerModeAffectedStreams =
ringerModeDelegateRingerMuted.getRingerModeAffectedStreams(0);
@@ -640,15 +636,15 @@ public class ZenModeHelperTest extends UiServiceTestCase {
// even when ringer is muted (since all ringer sounds cannot bypass DND),
// system stream is still affected by ringer mode
- mZenModeHelperSpy.mConfig.allowSystem = false;
- mZenModeHelperSpy.mConfig.allowReminders = false;
- mZenModeHelperSpy.mConfig.allowCalls = false;
- mZenModeHelperSpy.mConfig.allowMessages = false;
- mZenModeHelperSpy.mConfig.allowEvents = false;
- mZenModeHelperSpy.mConfig.allowRepeatCallers = false;
- mZenModeHelperSpy.mConfig.allowConversations = false;
+ mZenModeHelper.mConfig.allowSystem = false;
+ mZenModeHelper.mConfig.allowReminders = false;
+ mZenModeHelper.mConfig.allowCalls = false;
+ mZenModeHelper.mConfig.allowMessages = false;
+ mZenModeHelper.mConfig.allowEvents = false;
+ mZenModeHelper.mConfig.allowRepeatCallers = false;
+ mZenModeHelper.mConfig.allowConversations = false;
ZenModeHelper.RingerModeDelegate ringerModeDelegateRingerNotMuted =
- mZenModeHelperSpy.new RingerModeDelegate();
+ mZenModeHelper.new RingerModeDelegate();
int ringerMutedRingerModeAffectedStreams =
ringerModeDelegateRingerNotMuted.getRingerModeAffectedStreams(0);
@@ -665,74 +661,74 @@ public class ZenModeHelperTest extends UiServiceTestCase {
@Test
public void testZenSetInternalRinger_NotAllPriorityNotificationSoundsMuted_StartNormal() {
AudioManagerInternal mAudioManager = mock(AudioManagerInternal.class);
- mZenModeHelperSpy.mAudioManager = mAudioManager;
+ mZenModeHelper.mAudioManager = mAudioManager;
Global.putString(mContext.getContentResolver(), Global.ZEN_MODE_RINGER_LEVEL,
Integer.toString(AudioManager.RINGER_MODE_NORMAL));
// 1. Current ringer is normal
when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
- mZenModeHelperSpy.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
- mZenModeHelperSpy.mConfig.allowReminders = true;
+ mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+ mZenModeHelper.mConfig.allowReminders = true;
// 2. apply priority only zen - verify ringer is normal
- mZenModeHelperSpy.applyZenToRingerMode();
+ mZenModeHelper.applyZenToRingerMode();
verify(mAudioManager, atLeastOnce()).setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
- mZenModeHelperSpy.TAG);
+ mZenModeHelper.TAG);
// 3. apply zen off - verify ringer remains normal
when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
- mZenModeHelperSpy.mZenMode = Global.ZEN_MODE_OFF;
- mZenModeHelperSpy.applyZenToRingerMode();
+ mZenModeHelper.mZenMode = Global.ZEN_MODE_OFF;
+ mZenModeHelper.applyZenToRingerMode();
verify(mAudioManager, atLeastOnce()).setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
- mZenModeHelperSpy.TAG);
+ mZenModeHelper.TAG);
}
@Test
public void testZenSetInternalRinger_NotAllPriorityNotificationSoundsMuted_StartSilent() {
AudioManagerInternal mAudioManager = mock(AudioManagerInternal.class);
- mZenModeHelperSpy.mAudioManager = mAudioManager;
+ mZenModeHelper.mAudioManager = mAudioManager;
Global.putString(mContext.getContentResolver(), Global.ZEN_MODE_RINGER_LEVEL,
Integer.toString(AudioManager.RINGER_MODE_SILENT));
// 1. Current ringer is silent
when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT);
- mZenModeHelperSpy.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
- mZenModeHelperSpy.mConfig.allowReminders = true;
+ mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+ mZenModeHelper.mConfig.allowReminders = true;
// 2. apply priority only zen - verify ringer is silent
- mZenModeHelperSpy.applyZenToRingerMode();
+ mZenModeHelper.applyZenToRingerMode();
verify(mAudioManager, atLeastOnce()).setRingerModeInternal(AudioManager.RINGER_MODE_SILENT,
- mZenModeHelperSpy.TAG);
+ mZenModeHelper.TAG);
// 3. apply zen-off - verify ringer is still silent
when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT);
- mZenModeHelperSpy.mZenMode = Global.ZEN_MODE_OFF;
- mZenModeHelperSpy.applyZenToRingerMode();
+ mZenModeHelper.mZenMode = Global.ZEN_MODE_OFF;
+ mZenModeHelper.applyZenToRingerMode();
verify(mAudioManager, atLeastOnce()).setRingerModeInternal(AudioManager.RINGER_MODE_SILENT,
- mZenModeHelperSpy.TAG);
+ mZenModeHelper.TAG);
}
@Test
public void testZenSetInternalRinger_NotAllPriorityNotificationSoundsMuted_RingerChanges() {
AudioManagerInternal mAudioManager = mock(AudioManagerInternal.class);
- mZenModeHelperSpy.mAudioManager = mAudioManager;
+ mZenModeHelper.mAudioManager = mAudioManager;
Global.putString(mContext.getContentResolver(), Global.ZEN_MODE_RINGER_LEVEL,
Integer.toString(AudioManager.RINGER_MODE_NORMAL));
// 1. Current ringer is normal
when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
// Set zen to priority-only with all notification sounds muted (so ringer will be muted)
- mZenModeHelperSpy.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
- mZenModeHelperSpy.mConfig.allowReminders = true;
+ mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+ mZenModeHelper.mConfig.allowReminders = true;
// 2. apply priority only zen - verify zen will still be normal
- mZenModeHelperSpy.applyZenToRingerMode();
+ mZenModeHelper.applyZenToRingerMode();
verify(mAudioManager, atLeastOnce()).setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
- mZenModeHelperSpy.TAG);
+ mZenModeHelper.TAG);
// 3. change ringer from normal to silent, verify previous ringer set to new ringer (silent)
ZenModeHelper.RingerModeDelegate ringerModeDelegate =
- mZenModeHelperSpy.new RingerModeDelegate();
+ mZenModeHelper.new RingerModeDelegate();
ringerModeDelegate.onSetRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
AudioManager.RINGER_MODE_SILENT, "test", AudioManager.RINGER_MODE_NORMAL,
VolumePolicy.DEFAULT);
@@ -741,41 +737,40 @@ public class ZenModeHelperTest extends UiServiceTestCase {
// 4. apply zen off - verify ringer still silenced
when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT);
- mZenModeHelperSpy.mZenMode = Global.ZEN_MODE_OFF;
- mZenModeHelperSpy.applyZenToRingerMode();
+ mZenModeHelper.mZenMode = Global.ZEN_MODE_OFF;
+ mZenModeHelper.applyZenToRingerMode();
verify(mAudioManager, atLeastOnce()).setRingerModeInternal(AudioManager.RINGER_MODE_SILENT,
- mZenModeHelperSpy.TAG);
+ mZenModeHelper.TAG);
}
@Test
public void testSilentRingerSavedInZenOff_startsZenOff() {
AudioManagerInternal mAudioManager = mock(AudioManagerInternal.class);
- mZenModeHelperSpy.mConfig = new ZenModeConfig();
- mZenModeHelperSpy.mAudioManager = mAudioManager;
+ mZenModeHelper.mConfig = new ZenModeConfig();
+ mZenModeHelper.mAudioManager = mAudioManager;
// apply zen off multiple times - verify ringer is not set to normal
when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT);
- mZenModeHelperSpy.mZenMode = Global.ZEN_MODE_OFF;
- mZenModeHelperSpy.mConfig = null; // will evaluate config to zen mode off
+ mZenModeHelper.mZenMode = Global.ZEN_MODE_OFF;
+ mZenModeHelper.mConfig = null; // will evaluate config to zen mode off
for (int i = 0; i < 3; i++) {
// if zen doesn't change, zen should not reapply itself to the ringer
- mZenModeHelperSpy.evaluateZenMode("test", true);
+ mZenModeHelper.evaluateZenMode("test", true);
}
- verify(mZenModeHelperSpy, never()).applyZenToRingerMode();
verify(mAudioManager, never()).setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
- mZenModeHelperSpy.TAG);
+ mZenModeHelper.TAG);
}
@Test
public void testSilentRingerSavedOnZenOff_startsZenOn() {
AudioManagerInternal mAudioManager = mock(AudioManagerInternal.class);
- mZenModeHelperSpy.mAudioManager = mAudioManager;
- mZenModeHelperSpy.mZenMode = Global.ZEN_MODE_OFF;
- mZenModeHelperSpy.mConfig = new ZenModeConfig();
+ mZenModeHelper.mAudioManager = mAudioManager;
+ mZenModeHelper.mZenMode = Global.ZEN_MODE_OFF;
+ mZenModeHelper.mConfig = new ZenModeConfig();
// previously set silent ringer
ZenModeHelper.RingerModeDelegate ringerModeDelegate =
- mZenModeHelperSpy.new RingerModeDelegate();
+ mZenModeHelper.new RingerModeDelegate();
ringerModeDelegate.onSetRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
AudioManager.RINGER_MODE_SILENT, "test", AudioManager.RINGER_MODE_NORMAL,
VolumePolicy.DEFAULT);
@@ -784,26 +779,25 @@ public class ZenModeHelperTest extends UiServiceTestCase {
// apply zen off multiple times - verify ringer is not set to normal
when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT);
- mZenModeHelperSpy.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+ mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
for (int i = 0; i < 3; i++) {
// if zen doesn't change, zen should not reapply itself to the ringer
- mZenModeHelperSpy.evaluateZenMode("test", true);
+ mZenModeHelper.evaluateZenMode("test", true);
}
- verify(mZenModeHelperSpy, times(1)).applyZenToRingerMode();
verify(mAudioManager, never()).setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
- mZenModeHelperSpy.TAG);
+ mZenModeHelper.TAG);
}
@Test
public void testVibrateRingerSavedOnZenOff_startsZenOn() {
AudioManagerInternal mAudioManager = mock(AudioManagerInternal.class);
- mZenModeHelperSpy.mAudioManager = mAudioManager;
- mZenModeHelperSpy.mZenMode = Global.ZEN_MODE_OFF;
- mZenModeHelperSpy.mConfig = new ZenModeConfig();
+ mZenModeHelper.mAudioManager = mAudioManager;
+ mZenModeHelper.mZenMode = Global.ZEN_MODE_OFF;
+ mZenModeHelper.mConfig = new ZenModeConfig();
// previously set silent ringer
ZenModeHelper.RingerModeDelegate ringerModeDelegate =
- mZenModeHelperSpy.new RingerModeDelegate();
+ mZenModeHelper.new RingerModeDelegate();
ringerModeDelegate.onSetRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
AudioManager.RINGER_MODE_VIBRATE, "test", AudioManager.RINGER_MODE_NORMAL,
VolumePolicy.DEFAULT);
@@ -812,89 +806,88 @@ public class ZenModeHelperTest extends UiServiceTestCase {
// apply zen off multiple times - verify ringer is not set to normal
when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_VIBRATE);
- mZenModeHelperSpy.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+ mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
for (int i = 0; i < 3; i++) {
// if zen doesn't change, zen should not reapply itself to the ringer
- mZenModeHelperSpy.evaluateZenMode("test", true);
+ mZenModeHelper.evaluateZenMode("test", true);
}
- verify(mZenModeHelperSpy, times(1)).applyZenToRingerMode();
verify(mAudioManager, never()).setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
- mZenModeHelperSpy.TAG);
+ mZenModeHelper.TAG);
}
@Test
public void testParcelConfig() {
- mZenModeHelperSpy.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
- mZenModeHelperSpy.mConfig.allowAlarms = false;
- mZenModeHelperSpy.mConfig.allowMedia = false;
- mZenModeHelperSpy.mConfig.allowSystem = false;
- mZenModeHelperSpy.mConfig.allowReminders = true;
- mZenModeHelperSpy.mConfig.allowCalls = true;
- mZenModeHelperSpy.mConfig.allowMessages = true;
- mZenModeHelperSpy.mConfig.allowEvents = true;
- mZenModeHelperSpy.mConfig.allowRepeatCallers = true;
- mZenModeHelperSpy.mConfig.allowConversations = true;
- mZenModeHelperSpy.mConfig.allowConversationsFrom = ZenPolicy.CONVERSATION_SENDERS_ANYONE;
- mZenModeHelperSpy.mConfig.suppressedVisualEffects = SUPPRESSED_EFFECT_BADGE;
- mZenModeHelperSpy.mConfig.manualRule = new ZenModeConfig.ZenRule();
- mZenModeHelperSpy.mConfig.manualRule.component = new ComponentName("a", "a");
- mZenModeHelperSpy.mConfig.manualRule.enabled = true;
- mZenModeHelperSpy.mConfig.manualRule.snoozing = true;
-
- ZenModeConfig actual = mZenModeHelperSpy.mConfig.copy();
-
- assertEquals(mZenModeHelperSpy.mConfig, actual);
+ mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+ mZenModeHelper.mConfig.allowAlarms = false;
+ mZenModeHelper.mConfig.allowMedia = false;
+ mZenModeHelper.mConfig.allowSystem = false;
+ mZenModeHelper.mConfig.allowReminders = true;
+ mZenModeHelper.mConfig.allowCalls = true;
+ mZenModeHelper.mConfig.allowMessages = true;
+ mZenModeHelper.mConfig.allowEvents = true;
+ mZenModeHelper.mConfig.allowRepeatCallers = true;
+ mZenModeHelper.mConfig.allowConversations = true;
+ mZenModeHelper.mConfig.allowConversationsFrom = ZenPolicy.CONVERSATION_SENDERS_ANYONE;
+ mZenModeHelper.mConfig.suppressedVisualEffects = SUPPRESSED_EFFECT_BADGE;
+ mZenModeHelper.mConfig.manualRule = new ZenModeConfig.ZenRule();
+ mZenModeHelper.mConfig.manualRule.component = new ComponentName("a", "a");
+ mZenModeHelper.mConfig.manualRule.enabled = true;
+ mZenModeHelper.mConfig.manualRule.snoozing = true;
+
+ ZenModeConfig actual = mZenModeHelper.mConfig.copy();
+
+ assertEquals(mZenModeHelper.mConfig, actual);
}
@Test
public void testWriteXml() throws Exception {
- mZenModeHelperSpy.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
- mZenModeHelperSpy.mConfig.allowAlarms = false;
- mZenModeHelperSpy.mConfig.allowMedia = false;
- mZenModeHelperSpy.mConfig.allowSystem = false;
- mZenModeHelperSpy.mConfig.allowReminders = true;
- mZenModeHelperSpy.mConfig.allowCalls = true;
- mZenModeHelperSpy.mConfig.allowMessages = true;
- mZenModeHelperSpy.mConfig.allowEvents = true;
- mZenModeHelperSpy.mConfig.allowRepeatCallers = true;
- mZenModeHelperSpy.mConfig.allowConversations = true;
- mZenModeHelperSpy.mConfig.allowConversationsFrom = ZenPolicy.CONVERSATION_SENDERS_ANYONE;
- mZenModeHelperSpy.mConfig.suppressedVisualEffects = SUPPRESSED_EFFECT_BADGE;
- mZenModeHelperSpy.mConfig.manualRule = new ZenModeConfig.ZenRule();
- mZenModeHelperSpy.mConfig.manualRule.zenMode =
+ mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+ mZenModeHelper.mConfig.allowAlarms = false;
+ mZenModeHelper.mConfig.allowMedia = false;
+ mZenModeHelper.mConfig.allowSystem = false;
+ mZenModeHelper.mConfig.allowReminders = true;
+ mZenModeHelper.mConfig.allowCalls = true;
+ mZenModeHelper.mConfig.allowMessages = true;
+ mZenModeHelper.mConfig.allowEvents = true;
+ mZenModeHelper.mConfig.allowRepeatCallers = true;
+ mZenModeHelper.mConfig.allowConversations = true;
+ mZenModeHelper.mConfig.allowConversationsFrom = ZenPolicy.CONVERSATION_SENDERS_ANYONE;
+ mZenModeHelper.mConfig.suppressedVisualEffects = SUPPRESSED_EFFECT_BADGE;
+ mZenModeHelper.mConfig.manualRule = new ZenModeConfig.ZenRule();
+ mZenModeHelper.mConfig.manualRule.zenMode =
ZEN_MODE_IMPORTANT_INTERRUPTIONS;
- mZenModeHelperSpy.mConfig.manualRule.component = new ComponentName("a", "a");
- mZenModeHelperSpy.mConfig.manualRule.pkg = "a";
- mZenModeHelperSpy.mConfig.manualRule.enabled = true;
+ mZenModeHelper.mConfig.manualRule.component = new ComponentName("a", "a");
+ mZenModeHelper.mConfig.manualRule.pkg = "a";
+ mZenModeHelper.mConfig.manualRule.enabled = true;
- ZenModeConfig expected = mZenModeHelperSpy.mConfig.copy();
+ ZenModeConfig expected = mZenModeHelper.mConfig.copy();
ByteArrayOutputStream baos = writeXmlAndPurge(null);
TypedXmlPullParser parser = getParserForByteStream(baos);
- mZenModeHelperSpy.readXml(parser, false, UserHandle.USER_ALL);
+ mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL);
assertEquals("Config mismatch: current vs expected: "
- + new ZenModeDiff.ConfigDiff(mZenModeHelperSpy.mConfig, expected), expected,
- mZenModeHelperSpy.mConfig);
+ + new ZenModeDiff.ConfigDiff(mZenModeHelper.mConfig, expected), expected,
+ mZenModeHelper.mConfig);
}
@Test
public void testProto() {
- mZenModeHelperSpy.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+ mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
// existence of manual rule means it should be in output
- mZenModeHelperSpy.mConfig.manualRule = new ZenModeConfig.ZenRule();
- mZenModeHelperSpy.mConfig.manualRule.pkg = "android"; // system
+ mZenModeHelper.mConfig.manualRule = new ZenModeConfig.ZenRule();
+ mZenModeHelper.mConfig.manualRule.pkg = "android"; // system
- int n = mZenModeHelperSpy.mConfig.automaticRules.size();
+ int n = mZenModeHelper.mConfig.automaticRules.size();
List<String> ids = new ArrayList<>(n);
- for (ZenModeConfig.ZenRule rule : mZenModeHelperSpy.mConfig.automaticRules.values()) {
+ for (ZenModeConfig.ZenRule rule : mZenModeHelper.mConfig.automaticRules.values()) {
ids.add(rule.id);
}
ids.add(ZenModeConfig.MANUAL_RULE_ID);
ids.add(""); // for ROOT_CONFIG, logged with empty string as id
List<StatsEvent> events = new LinkedList<>();
- mZenModeHelperSpy.pullRules(events);
+ mZenModeHelper.pullRules(events);
assertEquals(n + 2, events.size()); // automatic rules + manual rule + root config
for (WrappedSysUiStatsEvent.WrappedBuilder builder : mStatsEventBuilderFactory.builders) {
if (builder.getAtomId() == DND_MODE_RULE) {
@@ -918,10 +911,10 @@ public class ZenModeHelperTest extends UiServiceTestCase {
public void testProtoWithAutoRule() throws Exception {
setupZenConfig();
// one enabled automatic rule
- mZenModeHelperSpy.mConfig.automaticRules = getCustomAutomaticRules(ZEN_MODE_FOR_TESTING);
+ mZenModeHelper.mConfig.automaticRules = getCustomAutomaticRules(ZEN_MODE_FOR_TESTING);
List<StatsEvent> events = new LinkedList<>();
- mZenModeHelperSpy.pullRules(events);
+ mZenModeHelper.pullRules(events);
boolean foundCustomEvent = false;
for (WrappedSysUiStatsEvent.WrappedBuilder builder : mStatsEventBuilderFactory.builders) {
@@ -942,23 +935,23 @@ public class ZenModeHelperTest extends UiServiceTestCase {
public void ruleUidsCached() throws Exception {
setupZenConfig();
// one enabled automatic rule
- mZenModeHelperSpy.mConfig.automaticRules = getCustomAutomaticRules();
+ mZenModeHelper.mConfig.automaticRules = getCustomAutomaticRules();
List<StatsEvent> events = new LinkedList<>();
// first time retrieving uid:
- mZenModeHelperSpy.pullRules(events);
+ mZenModeHelper.pullRules(events);
verify(mPackageManager, atLeastOnce()).getPackageUidAsUser(anyString(), anyInt());
// second time retrieving uid:
reset(mPackageManager);
- mZenModeHelperSpy.pullRules(events);
+ mZenModeHelper.pullRules(events);
verify(mPackageManager, never()).getPackageUidAsUser(anyString(), anyInt());
// new rule from same package + user added
reset(mPackageManager);
ZenModeConfig.ZenRule rule = createCustomAutomaticRule(ZEN_MODE_IMPORTANT_INTERRUPTIONS,
CUSTOM_RULE_ID + "2");
- mZenModeHelperSpy.mConfig.automaticRules.put(rule.id, rule);
- mZenModeHelperSpy.pullRules(events);
+ mZenModeHelper.mConfig.automaticRules.put(rule.id, rule);
+ mZenModeHelper.pullRules(events);
verify(mPackageManager, never()).getPackageUidAsUser(anyString(), anyInt());
}
@@ -969,23 +962,23 @@ public class ZenModeHelperTest extends UiServiceTestCase {
setupZenConfig();
// one enabled automatic rule
- mZenModeHelperSpy.mConfig.automaticRules = getCustomAutomaticRules();
+ mZenModeHelper.mConfig.automaticRules = getCustomAutomaticRules();
List<StatsEvent> events = new LinkedList<>();
- mZenModeHelperSpy.pullRules(events);
- mZenModeHelperSpy.removeAutomaticZenRule(CUSTOM_RULE_ID, "test");
+ mZenModeHelper.pullRules(events);
+ mZenModeHelper.removeAutomaticZenRule(CUSTOM_RULE_ID, "test");
assertTrue(-1
- == mZenModeHelperSpy.mRulesUidCache.getOrDefault(CUSTOM_PKG_NAME + "|" + 0, -1));
+ == mZenModeHelper.mRulesUidCache.getOrDefault(CUSTOM_PKG_NAME + "|" + 0, -1));
}
@Test
public void testProtoRedactsIds() throws Exception {
setupZenConfig();
// one enabled automatic rule
- mZenModeHelperSpy.mConfig.automaticRules = getCustomAutomaticRules();
+ mZenModeHelper.mConfig.automaticRules = getCustomAutomaticRules();
List<StatsEvent> events = new LinkedList<>();
- mZenModeHelperSpy.pullRules(events);
+ mZenModeHelper.pullRules(events);
boolean foundCustomEvent = false;
for (WrappedSysUiStatsEvent.WrappedBuilder builder : mStatsEventBuilderFactory.builders) {
@@ -999,12 +992,12 @@ public class ZenModeHelperTest extends UiServiceTestCase {
@Test
public void testProtoWithManualRule() throws Exception {
setupZenConfig();
- mZenModeHelperSpy.mConfig.automaticRules = getCustomAutomaticRules();
- mZenModeHelperSpy.mConfig.manualRule = new ZenModeConfig.ZenRule();
- mZenModeHelperSpy.mConfig.manualRule.enabled = true;
+ mZenModeHelper.mConfig.automaticRules = getCustomAutomaticRules();
+ mZenModeHelper.mConfig.manualRule = new ZenModeConfig.ZenRule();
+ mZenModeHelper.mConfig.manualRule.enabled = true;
List<StatsEvent> events = new LinkedList<>();
- mZenModeHelperSpy.pullRules(events);
+ mZenModeHelper.pullRules(events);
boolean foundManualRule = false;
for (WrappedSysUiStatsEvent.WrappedBuilder builder : mStatsEventBuilderFactory.builders) {
@@ -1020,50 +1013,50 @@ public class ZenModeHelperTest extends UiServiceTestCase {
public void testWriteXml_onlyBackupsTargetUser() throws Exception {
// Setup configs for user 10 and 11.
setupZenConfig();
- ZenModeConfig config10 = mZenModeHelperSpy.mConfig.copy();
+ ZenModeConfig config10 = mZenModeHelper.mConfig.copy();
config10.user = 10;
config10.allowAlarms = true;
config10.allowMedia = true;
- mZenModeHelperSpy.setConfig(config10, null, "writeXml");
- ZenModeConfig config11 = mZenModeHelperSpy.mConfig.copy();
+ mZenModeHelper.setConfig(config10, null, "writeXml");
+ ZenModeConfig config11 = mZenModeHelper.mConfig.copy();
config11.user = 11;
config11.allowAlarms = false;
config11.allowMedia = false;
- mZenModeHelperSpy.setConfig(config11, null, "writeXml");
+ mZenModeHelper.setConfig(config11, null, "writeXml");
// Backup user 10 and reset values.
ByteArrayOutputStream baos = writeXmlAndPurgeForUser(null, 10);
ZenModeConfig newConfig11 = new ZenModeConfig();
newConfig11.user = 11;
- mZenModeHelperSpy.mConfigs.put(11, newConfig11);
+ mZenModeHelper.mConfigs.put(11, newConfig11);
// Parse backup data.
TypedXmlPullParser parser = getParserForByteStream(baos);
- mZenModeHelperSpy.readXml(parser, true, 10);
- mZenModeHelperSpy.readXml(parser, true, 11);
+ mZenModeHelper.readXml(parser, true, 10);
+ mZenModeHelper.readXml(parser, true, 11);
- ZenModeConfig actual = mZenModeHelperSpy.mConfigs.get(10);
+ ZenModeConfig actual = mZenModeHelper.mConfigs.get(10);
assertEquals(
"Config mismatch: current vs expected: "
+ new ZenModeDiff.ConfigDiff(actual, config10), config10, actual);
- assertNotEquals("Expected config mismatch", config11, mZenModeHelperSpy.mConfigs.get(11));
+ assertNotEquals("Expected config mismatch", config11, mZenModeHelper.mConfigs.get(11));
}
@Test
public void testReadXmlRestore_forSystemUser() throws Exception {
setupZenConfig();
// one enabled automatic rule
- mZenModeHelperSpy.mConfig.automaticRules = getCustomAutomaticRules();
- ZenModeConfig original = mZenModeHelperSpy.mConfig.copy();
+ mZenModeHelper.mConfig.automaticRules = getCustomAutomaticRules();
+ ZenModeConfig original = mZenModeHelper.mConfig.copy();
ByteArrayOutputStream baos = writeXmlAndPurgeForUser(null, UserHandle.USER_SYSTEM);
TypedXmlPullParser parser = getParserForByteStream(baos);
- mZenModeHelperSpy.readXml(parser, true, UserHandle.USER_SYSTEM);
+ mZenModeHelper.readXml(parser, true, UserHandle.USER_SYSTEM);
assertEquals("Config mismatch: current vs original: "
- + new ZenModeDiff.ConfigDiff(mZenModeHelperSpy.mConfig, original),
- original, mZenModeHelperSpy.mConfig);
- assertEquals(original.hashCode(), mZenModeHelperSpy.mConfig.hashCode());
+ + new ZenModeDiff.ConfigDiff(mZenModeHelper.mConfig, original),
+ original, mZenModeHelper.mConfig);
+ assertEquals(original.hashCode(), mZenModeHelper.mConfig.hashCode());
}
/** Restore should ignore the data's user id and restore for the target user. */
@@ -1071,24 +1064,24 @@ public class ZenModeHelperTest extends UiServiceTestCase {
public void testReadXmlRestore_forNonSystemUser() throws Exception {
// Setup config.
setupZenConfig();
- mZenModeHelperSpy.mConfig.automaticRules = getCustomAutomaticRules();
- ZenModeConfig expected = mZenModeHelperSpy.mConfig.copy();
+ mZenModeHelper.mConfig.automaticRules = getCustomAutomaticRules();
+ ZenModeConfig expected = mZenModeHelper.mConfig.copy();
// Backup data for user 0.
ByteArrayOutputStream baos = writeXmlAndPurgeForUser(null, UserHandle.USER_SYSTEM);
// Restore data for user 10.
TypedXmlPullParser parser = getParserForByteStream(baos);
- mZenModeHelperSpy.readXml(parser, true, 10);
+ mZenModeHelper.readXml(parser, true, 10);
- ZenModeConfig actual = mZenModeHelperSpy.mConfigs.get(10);
+ ZenModeConfig actual = mZenModeHelper.mConfigs.get(10);
expected.user = 10;
assertEquals("Config mismatch: current vs original: "
+ new ZenModeDiff.ConfigDiff(actual, expected),
expected, actual);
assertEquals(expected.hashCode(), actual.hashCode());
expected.user = 0;
- assertNotEquals(expected, mZenModeHelperSpy.mConfig);
+ assertNotEquals(expected, mZenModeHelper.mConfig);
}
@Test
@@ -1119,19 +1112,19 @@ public class ZenModeHelperTest extends UiServiceTestCase {
.allowReminders(false)
.build();
automaticRules.put("customRule", customRule);
- mZenModeHelperSpy.mConfig.automaticRules = automaticRules;
+ mZenModeHelper.mConfig.automaticRules = automaticRules;
- ZenModeConfig expected = mZenModeHelperSpy.mConfig.copy();
+ ZenModeConfig expected = mZenModeHelper.mConfig.copy();
ByteArrayOutputStream baos = writeXmlAndPurge(null);
TypedXmlPullParser parser = Xml.newFastPullParser();
parser.setInput(new BufferedInputStream(
new ByteArrayInputStream(baos.toByteArray())), null);
parser.nextTag();
- mZenModeHelperSpy.readXml(parser, false, UserHandle.USER_ALL);
+ mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL);
ZenModeConfig.ZenRule original = expected.automaticRules.get(ruleId);
- ZenModeConfig.ZenRule current = mZenModeHelperSpy.mConfig.automaticRules.get(ruleId);
+ ZenModeConfig.ZenRule current = mZenModeHelper.mConfig.automaticRules.get(ruleId);
assertEquals("Automatic rules mismatch", original, current);
}
@@ -1160,16 +1153,16 @@ public class ZenModeHelperTest extends UiServiceTestCase {
.allowReminders(true)
.build();
automaticRules.put(ruleId, customRule);
- mZenModeHelperSpy.mConfig.automaticRules = automaticRules;
+ mZenModeHelper.mConfig.automaticRules = automaticRules;
- ZenModeConfig expected = mZenModeHelperSpy.mConfig.copy();
+ ZenModeConfig expected = mZenModeHelper.mConfig.copy();
ByteArrayOutputStream baos = writeXmlAndPurgeForUser(null, UserHandle.USER_SYSTEM);
TypedXmlPullParser parser = getParserForByteStream(baos);
- mZenModeHelperSpy.readXml(parser, true, UserHandle.USER_SYSTEM);
+ mZenModeHelper.readXml(parser, true, UserHandle.USER_SYSTEM);
ZenModeConfig.ZenRule original = expected.automaticRules.get(ruleId);
- ZenModeConfig.ZenRule current = mZenModeHelperSpy.mConfig.automaticRules.get(ruleId);
+ ZenModeConfig.ZenRule current = mZenModeHelper.mConfig.automaticRules.get(ruleId);
assertEquals("Automatic rules mismatch", original, current);
}
@@ -1188,7 +1181,7 @@ public class ZenModeHelperTest extends UiServiceTestCase {
customRule.conditionId = ZenModeConfig.toScheduleConditionId(weeknights);
customRule.component = new ComponentName("android", "ScheduleConditionProvider");
enabledAutoRule.put("customRule", customRule);
- mZenModeHelperSpy.mConfig.automaticRules = enabledAutoRule;
+ mZenModeHelper.mConfig.automaticRules = enabledAutoRule;
// set previous version
ByteArrayOutputStream baos = writeXmlAndPurge(5);
@@ -1196,9 +1189,9 @@ public class ZenModeHelperTest extends UiServiceTestCase {
parser.setInput(new BufferedInputStream(
new ByteArrayInputStream(baos.toByteArray())), null);
parser.nextTag();
- mZenModeHelperSpy.readXml(parser, false, UserHandle.USER_ALL);
+ mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL);
- assertTrue(mZenModeHelperSpy.mConfig.automaticRules.containsKey("customRule"));
+ assertTrue(mZenModeHelper.mConfig.automaticRules.containsKey("customRule"));
setupZenConfigMaintained();
}
@@ -1216,9 +1209,9 @@ public class ZenModeHelperTest extends UiServiceTestCase {
parser.setInput(new BufferedInputStream(
new ByteArrayInputStream(xml.getBytes())), null);
parser.nextTag();
- mZenModeHelperSpy.readXml(parser, false, UserHandle.USER_ALL);
+ mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL);
- assertEquals(0, mZenModeHelperSpy.mConfig.suppressedVisualEffects);
+ assertEquals(0, mZenModeHelper.mConfig.suppressedVisualEffects);
xml = "<zen version=\"6\" user=\"0\">\n"
+ "<allow calls=\"false\" repeatCallers=\"false\" messages=\"true\" "
@@ -1232,9 +1225,9 @@ public class ZenModeHelperTest extends UiServiceTestCase {
parser.setInput(new BufferedInputStream(
new ByteArrayInputStream(xml.getBytes())), null);
parser.nextTag();
- mZenModeHelperSpy.readXml(parser, false, UserHandle.USER_ALL);
+ mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL);
- assertEquals(0, mZenModeHelperSpy.mConfig.suppressedVisualEffects);
+ assertEquals(0, mZenModeHelper.mConfig.suppressedVisualEffects);
}
@Test
@@ -1251,9 +1244,9 @@ public class ZenModeHelperTest extends UiServiceTestCase {
parser.setInput(new BufferedInputStream(
new ByteArrayInputStream(xml.getBytes())), null);
parser.nextTag();
- mZenModeHelperSpy.readXml(parser, false, UserHandle.USER_ALL);
+ mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL);
- assertEquals(0, mZenModeHelperSpy.mConfig.suppressedVisualEffects);
+ assertEquals(0, mZenModeHelper.mConfig.suppressedVisualEffects);
}
@Test
@@ -1270,13 +1263,13 @@ public class ZenModeHelperTest extends UiServiceTestCase {
parser.setInput(new BufferedInputStream(
new ByteArrayInputStream(xml.getBytes())), null);
parser.nextTag();
- mZenModeHelperSpy.readXml(parser, false, UserHandle.USER_ALL);
+ mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL);
assertEquals(SUPPRESSED_EFFECT_FULL_SCREEN_INTENT
| SUPPRESSED_EFFECT_LIGHTS
| SUPPRESSED_EFFECT_AMBIENT
| SUPPRESSED_EFFECT_PEEK,
- mZenModeHelperSpy.mConfig.suppressedVisualEffects);
+ mZenModeHelper.mConfig.suppressedVisualEffects);
xml = "<zen version=\"6\" user=\"0\">\n"
+ "<allow calls=\"false\" repeatCallers=\"false\" messages=\"true\" "
@@ -1290,9 +1283,9 @@ public class ZenModeHelperTest extends UiServiceTestCase {
parser.setInput(new BufferedInputStream(
new ByteArrayInputStream(xml.getBytes())), null);
parser.nextTag();
- mZenModeHelperSpy.readXml(parser, false, UserHandle.USER_ALL);
+ mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL);
- assertEquals(SUPPRESSED_EFFECT_PEEK, mZenModeHelperSpy.mConfig.suppressedVisualEffects);
+ assertEquals(SUPPRESSED_EFFECT_PEEK, mZenModeHelper.mConfig.suppressedVisualEffects);
xml = "<zen version=\"6\" user=\"0\">\n"
+ "<allow calls=\"false\" repeatCallers=\"false\" messages=\"true\" "
@@ -1306,12 +1299,12 @@ public class ZenModeHelperTest extends UiServiceTestCase {
parser.setInput(new BufferedInputStream(
new ByteArrayInputStream(xml.getBytes())), null);
parser.nextTag();
- mZenModeHelperSpy.readXml(parser, false, UserHandle.USER_ALL);
+ mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL);
assertEquals(SUPPRESSED_EFFECT_FULL_SCREEN_INTENT
| SUPPRESSED_EFFECT_LIGHTS
| SUPPRESSED_EFFECT_AMBIENT,
- mZenModeHelperSpy.mConfig.suppressedVisualEffects);
+ mZenModeHelper.mConfig.suppressedVisualEffects);
}
@Test
@@ -1320,7 +1313,7 @@ public class ZenModeHelperTest extends UiServiceTestCase {
// no enabled automatic zen rules and no default rules
// so rules should be overriden by default rules
- mZenModeHelperSpy.mConfig.automaticRules = new ArrayMap<>();
+ mZenModeHelper.mConfig.automaticRules = new ArrayMap<>();
// set previous version
ByteArrayOutputStream baos = writeXmlAndPurge(5);
@@ -1328,10 +1321,10 @@ public class ZenModeHelperTest extends UiServiceTestCase {
parser.setInput(new BufferedInputStream(
new ByteArrayInputStream(baos.toByteArray())), null);
parser.nextTag();
- mZenModeHelperSpy.readXml(parser, false, UserHandle.USER_ALL);
+ mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL);
// check default rules
- ArrayMap<String, ZenModeConfig.ZenRule> rules = mZenModeHelperSpy.mConfig.automaticRules;
+ ArrayMap<String, ZenModeConfig.ZenRule> rules = mZenModeHelper.mConfig.automaticRules;
assertTrue(rules.size() != 0);
for (String defaultId : ZenModeConfig.DEFAULT_RULE_IDS) {
assertTrue(rules.containsKey(defaultId));
@@ -1356,7 +1349,7 @@ public class ZenModeHelperTest extends UiServiceTestCase {
customRule.conditionId = ZenModeConfig.toScheduleConditionId(weeknights);
customRule.component = new ComponentName("android", "ScheduleConditionProvider");
disabledAutoRule.put("customRule", customRule);
- mZenModeHelperSpy.mConfig.automaticRules = disabledAutoRule;
+ mZenModeHelper.mConfig.automaticRules = disabledAutoRule;
// set previous version
ByteArrayOutputStream baos = writeXmlAndPurge(5);
@@ -1364,10 +1357,10 @@ public class ZenModeHelperTest extends UiServiceTestCase {
parser.setInput(new BufferedInputStream(
new ByteArrayInputStream(baos.toByteArray())), null);
parser.nextTag();
- mZenModeHelperSpy.readXml(parser, false, UserHandle.USER_ALL);
+ mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL);
// check default rules
- ArrayMap<String, ZenModeConfig.ZenRule> rules = mZenModeHelperSpy.mConfig.automaticRules;
+ ArrayMap<String, ZenModeConfig.ZenRule> rules = mZenModeHelper.mConfig.automaticRules;
assertTrue(rules.size() != 0);
for (String defaultId : ZenModeConfig.DEFAULT_RULE_IDS) {
assertTrue(rules.containsKey(defaultId));
@@ -1408,7 +1401,7 @@ public class ZenModeHelperTest extends UiServiceTestCase {
defaultScheduleRule.id = ZenModeConfig.EVERY_NIGHT_DEFAULT_RULE_ID;
automaticRules.put(ZenModeConfig.EVERY_NIGHT_DEFAULT_RULE_ID, defaultScheduleRule);
- mZenModeHelperSpy.mConfig.automaticRules = automaticRules;
+ mZenModeHelper.mConfig.automaticRules = automaticRules;
// set previous version
ByteArrayOutputStream baos = writeXmlAndPurge(5);
@@ -1416,10 +1409,10 @@ public class ZenModeHelperTest extends UiServiceTestCase {
parser.setInput(new BufferedInputStream(
new ByteArrayInputStream(baos.toByteArray())), null);
parser.nextTag();
- mZenModeHelperSpy.readXml(parser, false, UserHandle.USER_ALL);
+ mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL);
// check default rules
- ArrayMap<String, ZenModeConfig.ZenRule> rules = mZenModeHelperSpy.mConfig.automaticRules;
+ ArrayMap<String, ZenModeConfig.ZenRule> rules = mZenModeHelper.mConfig.automaticRules;
assertTrue(rules.size() != 0);
for (String defaultId : ZenModeConfig.DEFAULT_RULE_IDS) {
assertTrue(rules.containsKey(defaultId));
@@ -1477,7 +1470,7 @@ public class ZenModeHelperTest extends UiServiceTestCase {
.build();
automaticRules.put(ZenModeConfig.EVENTS_DEFAULT_RULE_ID, defaultEventRule);
- mZenModeHelperSpy.mConfig.automaticRules = automaticRules;
+ mZenModeHelper.mConfig.automaticRules = automaticRules;
// set previous version
ByteArrayOutputStream baos = writeXmlAndPurge(5);
@@ -1485,10 +1478,10 @@ public class ZenModeHelperTest extends UiServiceTestCase {
parser.setInput(new BufferedInputStream(
new ByteArrayInputStream(baos.toByteArray())), null);
parser.nextTag();
- mZenModeHelperSpy.readXml(parser, false, UserHandle.USER_ALL);
+ mZenModeHelper.readXml(parser, false, UserHandle.USER_ALL);
// check default rules
- ArrayMap<String, ZenModeConfig.ZenRule> rules = mZenModeHelperSpy.mConfig.automaticRules;
+ ArrayMap<String, ZenModeConfig.ZenRule> rules = mZenModeHelper.mConfig.automaticRules;
assertTrue(rules.size() != 0);
for (String defaultId : ZenModeConfig.DEFAULT_RULE_IDS) {
assertTrue(rules.containsKey(defaultId));
@@ -1498,32 +1491,32 @@ public class ZenModeHelperTest extends UiServiceTestCase {
setupZenConfigMaintained();
List<StatsEvent> events = new LinkedList<>();
- mZenModeHelperSpy.pullRules(events);
+ mZenModeHelper.pullRules(events);
assertEquals(4, events.size());
}
@Test
public void testCountdownConditionSubscription() throws Exception {
ZenModeConfig config = new ZenModeConfig();
- mZenModeHelperSpy.mConfig = config;
- mZenModeHelperSpy.mConditions.evaluateConfig(mZenModeHelperSpy.mConfig, null, true);
- assertEquals(0, mZenModeHelperSpy.mConditions.mSubscriptions.size());
+ mZenModeHelper.mConfig = config;
+ mZenModeHelper.mConditions.evaluateConfig(mZenModeHelper.mConfig, null, true);
+ assertEquals(0, mZenModeHelper.mConditions.mSubscriptions.size());
- mZenModeHelperSpy.mConfig.manualRule = new ZenModeConfig.ZenRule();
+ mZenModeHelper.mConfig.manualRule = new ZenModeConfig.ZenRule();
Uri conditionId = ZenModeConfig.toCountdownConditionId(9000000, false);
- mZenModeHelperSpy.mConfig.manualRule.conditionId = conditionId;
- mZenModeHelperSpy.mConfig.manualRule.component = new ComponentName("android",
+ mZenModeHelper.mConfig.manualRule.conditionId = conditionId;
+ mZenModeHelper.mConfig.manualRule.component = new ComponentName("android",
CountdownConditionProvider.class.getName());
- mZenModeHelperSpy.mConfig.manualRule.condition = new Condition(conditionId, "", "", "", 0,
+ mZenModeHelper.mConfig.manualRule.condition = new Condition(conditionId, "", "", "", 0,
STATE_TRUE, Condition.FLAG_RELEVANT_NOW);
- mZenModeHelperSpy.mConfig.manualRule.enabled = true;
- ZenModeConfig originalConfig = mZenModeHelperSpy.mConfig.copy();
+ mZenModeHelper.mConfig.manualRule.enabled = true;
+ ZenModeConfig originalConfig = mZenModeHelper.mConfig.copy();
- mZenModeHelperSpy.mConditions.evaluateConfig(mZenModeHelperSpy.mConfig, null, true);
+ mZenModeHelper.mConditions.evaluateConfig(mZenModeHelper.mConfig, null, true);
assertEquals(true, ZenModeConfig.isValidCountdownConditionId(conditionId));
- assertEquals(originalConfig, mZenModeHelperSpy.mConfig);
- assertEquals(1, mZenModeHelperSpy.mConditions.mSubscriptions.size());
+ assertEquals(originalConfig, mZenModeHelper.mConfig);
+ assertEquals(1, mZenModeHelper.mConditions.mSubscriptions.size());
}
@Test
@@ -1531,9 +1524,9 @@ public class ZenModeHelperTest extends UiServiceTestCase {
List<StatsEvent> events = new LinkedList<>();
ZenModeConfig config = new ZenModeConfig();
config.automaticRules = new ArrayMap<>();
- mZenModeHelperSpy.mConfig = config;
- mZenModeHelperSpy.updateDefaultZenRules(); // shouldn't throw null pointer
- mZenModeHelperSpy.pullRules(events); // shouldn't throw null pointer
+ mZenModeHelper.mConfig = config;
+ mZenModeHelper.updateDefaultZenRules(); // shouldn't throw null pointer
+ mZenModeHelper.pullRules(events); // shouldn't throw null pointer
}
@Test
@@ -1555,11 +1548,11 @@ public class ZenModeHelperTest extends UiServiceTestCase {
ArrayMap<String, ZenModeConfig.ZenRule> autoRules = new ArrayMap<>();
autoRules.put(SCHEDULE_DEFAULT_RULE_ID, updatedDefaultRule);
- mZenModeHelperSpy.mConfig.automaticRules = autoRules;
+ mZenModeHelper.mConfig.automaticRules = autoRules;
- mZenModeHelperSpy.updateDefaultZenRules();
+ mZenModeHelper.updateDefaultZenRules();
assertEquals(updatedDefaultRule,
- mZenModeHelperSpy.mConfig.automaticRules.get(SCHEDULE_DEFAULT_RULE_ID));
+ mZenModeHelper.mConfig.automaticRules.get(SCHEDULE_DEFAULT_RULE_ID));
}
@Test
@@ -1581,11 +1574,11 @@ public class ZenModeHelperTest extends UiServiceTestCase {
ArrayMap<String, ZenModeConfig.ZenRule> autoRules = new ArrayMap<>();
autoRules.put(SCHEDULE_DEFAULT_RULE_ID, updatedDefaultRule);
- mZenModeHelperSpy.mConfig.automaticRules = autoRules;
+ mZenModeHelper.mConfig.automaticRules = autoRules;
- mZenModeHelperSpy.updateDefaultZenRules();
+ mZenModeHelper.updateDefaultZenRules();
assertEquals(updatedDefaultRule,
- mZenModeHelperSpy.mConfig.automaticRules.get(SCHEDULE_DEFAULT_RULE_ID));
+ mZenModeHelper.mConfig.automaticRules.get(SCHEDULE_DEFAULT_RULE_ID));
}
@Test
@@ -1608,11 +1601,11 @@ public class ZenModeHelperTest extends UiServiceTestCase {
ArrayMap<String, ZenModeConfig.ZenRule> autoRules = new ArrayMap<>();
autoRules.put(SCHEDULE_DEFAULT_RULE_ID, customDefaultRule);
- mZenModeHelperSpy.mConfig.automaticRules = autoRules;
+ mZenModeHelper.mConfig.automaticRules = autoRules;
- mZenModeHelperSpy.updateDefaultZenRules();
+ mZenModeHelper.updateDefaultZenRules();
ZenModeConfig.ZenRule ruleAfterUpdating =
- mZenModeHelperSpy.mConfig.automaticRules.get(SCHEDULE_DEFAULT_RULE_ID);
+ mZenModeHelper.mConfig.automaticRules.get(SCHEDULE_DEFAULT_RULE_ID);
assertEquals(customDefaultRule.enabled, ruleAfterUpdating.enabled);
assertEquals(customDefaultRule.modified, ruleAfterUpdating.modified);
assertEquals(customDefaultRule.id, ruleAfterUpdating.id);
@@ -1633,7 +1626,7 @@ public class ZenModeHelperTest extends UiServiceTestCase {
NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
// We need the package name to be something that's not "android" so there aren't any
// existing rules under that package.
- String id = mZenModeHelperSpy.addAutomaticZenRule("pkgname", zenRule, "test");
+ String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, "test");
assertNotNull(id);
}
try {
@@ -1643,7 +1636,7 @@ public class ZenModeHelperTest extends UiServiceTestCase {
ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
new ZenPolicy.Builder().build(),
NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
- String id = mZenModeHelperSpy.addAutomaticZenRule("pkgname", zenRule, "test");
+ String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, "test");
fail("allowed too many rules to be created");
} catch (IllegalArgumentException e) {
// yay
@@ -1663,7 +1656,7 @@ public class ZenModeHelperTest extends UiServiceTestCase {
ZenModeConfig.toScheduleConditionId(si),
new ZenPolicy.Builder().build(),
NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
- String id = mZenModeHelperSpy.addAutomaticZenRule("pkgname", zenRule, "test");
+ String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, "test");
assertNotNull(id);
}
try {
@@ -1673,7 +1666,7 @@ public class ZenModeHelperTest extends UiServiceTestCase {
ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
new ZenPolicy.Builder().build(),
NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
- String id = mZenModeHelperSpy.addAutomaticZenRule("pkgname", zenRule, "test");
+ String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, "test");
fail("allowed too many rules to be created");
} catch (IllegalArgumentException e) {
// yay
@@ -1693,7 +1686,7 @@ public class ZenModeHelperTest extends UiServiceTestCase {
ZenModeConfig.toScheduleConditionId(si),
new ZenPolicy.Builder().build(),
NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
- String id = mZenModeHelperSpy.addAutomaticZenRule("pkgname", zenRule, "test");
+ String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, "test");
assertNotNull(id);
}
try {
@@ -1703,7 +1696,7 @@ public class ZenModeHelperTest extends UiServiceTestCase {
ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
new ZenPolicy.Builder().build(),
NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
- String id = mZenModeHelperSpy.addAutomaticZenRule("pkgname", zenRule, "test");
+ String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, "test");
fail("allowed too many rules to be created");
} catch (IllegalArgumentException e) {
// yay
@@ -1718,10 +1711,10 @@ public class ZenModeHelperTest extends UiServiceTestCase {
ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
new ZenPolicy.Builder().build(),
NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
- String id = mZenModeHelperSpy.addAutomaticZenRule("android", zenRule, "test");
+ String id = mZenModeHelper.addAutomaticZenRule("android", zenRule, "test");
assertTrue(id != null);
- ZenModeConfig.ZenRule ruleInConfig = mZenModeHelperSpy.mConfig.automaticRules.get(id);
+ ZenModeConfig.ZenRule ruleInConfig = mZenModeHelper.mConfig.automaticRules.get(id);
assertTrue(ruleInConfig != null);
assertEquals(zenRule.isEnabled(), ruleInConfig.enabled);
assertEquals(zenRule.isModified(), ruleInConfig.modified);
@@ -1738,10 +1731,10 @@ public class ZenModeHelperTest extends UiServiceTestCase {
new ComponentName("android", "ScheduleConditionProvider"),
ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
- String id = mZenModeHelperSpy.addAutomaticZenRule("android", zenRule, "test");
+ String id = mZenModeHelper.addAutomaticZenRule("android", zenRule, "test");
assertTrue(id != null);
- ZenModeConfig.ZenRule ruleInConfig = mZenModeHelperSpy.mConfig.automaticRules.get(id);
+ ZenModeConfig.ZenRule ruleInConfig = mZenModeHelper.mConfig.automaticRules.get(id);
assertTrue(ruleInConfig != null);
assertEquals(zenRule.isEnabled(), ruleInConfig.enabled);
assertEquals(zenRule.isModified(), ruleInConfig.modified);
@@ -1761,11 +1754,11 @@ public class ZenModeHelperTest extends UiServiceTestCase {
new ZenPolicy.Builder().build(),
NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
- String id = mZenModeHelperSpy.addAutomaticZenRule(null, zenRule, "test");
- mZenModeHelperSpy.setAutomaticZenRuleState(zenRule.getConditionId(),
+ String id = mZenModeHelper.addAutomaticZenRule(null, zenRule, "test");
+ mZenModeHelper.setAutomaticZenRuleState(zenRule.getConditionId(),
new Condition(zenRule.getConditionId(), "", STATE_TRUE));
- ZenModeConfig.ZenRule ruleInConfig = mZenModeHelperSpy.mConfig.automaticRules.get(id);
+ ZenModeConfig.ZenRule ruleInConfig = mZenModeHelper.mConfig.automaticRules.get(id);
assertEquals(STATE_TRUE, ruleInConfig.condition.state);
}
@@ -1778,7 +1771,7 @@ public class ZenModeHelperTest extends UiServiceTestCase {
new ZenPolicy.Builder().build(),
NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
- String id = mZenModeHelperSpy.addAutomaticZenRule(null, zenRule, "test");
+ String id = mZenModeHelper.addAutomaticZenRule(null, zenRule, "test");
AutomaticZenRule zenRule2 = new AutomaticZenRule("NEW",
null,
@@ -1787,9 +1780,9 @@ public class ZenModeHelperTest extends UiServiceTestCase {
new ZenPolicy.Builder().build(),
NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
- mZenModeHelperSpy.updateAutomaticZenRule(id, zenRule2, "");
+ mZenModeHelper.updateAutomaticZenRule(id, zenRule2, "");
- ZenModeConfig.ZenRule ruleInConfig = mZenModeHelperSpy.mConfig.automaticRules.get(id);
+ ZenModeConfig.ZenRule ruleInConfig = mZenModeHelper.mConfig.automaticRules.get(id);
assertEquals("NEW", ruleInConfig.name);
}
@@ -1802,15 +1795,15 @@ public class ZenModeHelperTest extends UiServiceTestCase {
new ZenPolicy.Builder().build(),
NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
- String id = mZenModeHelperSpy.addAutomaticZenRule(null, zenRule, "test");
+ String id = mZenModeHelper.addAutomaticZenRule(null, zenRule, "test");
assertTrue(id != null);
- ZenModeConfig.ZenRule ruleInConfig = mZenModeHelperSpy.mConfig.automaticRules.get(id);
+ ZenModeConfig.ZenRule ruleInConfig = mZenModeHelper.mConfig.automaticRules.get(id);
assertTrue(ruleInConfig != null);
assertEquals(zenRule.getName(), ruleInConfig.name);
- mZenModeHelperSpy.removeAutomaticZenRule(id, "test");
- assertNull(mZenModeHelperSpy.mConfig.automaticRules.get(id));
+ mZenModeHelper.removeAutomaticZenRule(id, "test");
+ assertNull(mZenModeHelper.mConfig.automaticRules.get(id));
}
@Test
@@ -1821,15 +1814,15 @@ public class ZenModeHelperTest extends UiServiceTestCase {
ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
new ZenPolicy.Builder().build(),
NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
- String id = mZenModeHelperSpy.addAutomaticZenRule(null, zenRule, "test");
+ String id = mZenModeHelper.addAutomaticZenRule(null, zenRule, "test");
assertTrue(id != null);
- ZenModeConfig.ZenRule ruleInConfig = mZenModeHelperSpy.mConfig.automaticRules.get(id);
+ ZenModeConfig.ZenRule ruleInConfig = mZenModeHelper.mConfig.automaticRules.get(id);
assertTrue(ruleInConfig != null);
assertEquals(zenRule.getName(), ruleInConfig.name);
- mZenModeHelperSpy.removeAutomaticZenRules(mContext.getPackageName(), "test");
- assertNull(mZenModeHelperSpy.mConfig.automaticRules.get(id));
+ mZenModeHelper.removeAutomaticZenRules(mContext.getPackageName(), "test");
+ assertNull(mZenModeHelper.mConfig.automaticRules.get(id));
}
@Test
@@ -1839,17 +1832,17 @@ public class ZenModeHelperTest extends UiServiceTestCase {
new ComponentName("android", "ScheduleConditionProvider"),
sharedUri,
NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
- String id = mZenModeHelperSpy.addAutomaticZenRule("android", zenRule, "test");
+ String id = mZenModeHelper.addAutomaticZenRule("android", zenRule, "test");
AutomaticZenRule zenRule2 = new AutomaticZenRule("name2",
new ComponentName("android", "ScheduleConditionProvider"),
sharedUri,
NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
- String id2 = mZenModeHelperSpy.addAutomaticZenRule("android", zenRule2, "test");
+ String id2 = mZenModeHelper.addAutomaticZenRule("android", zenRule2, "test");
Condition condition = new Condition(sharedUri, "", STATE_TRUE);
- mZenModeHelperSpy.setAutomaticZenRuleState(sharedUri, condition);
+ mZenModeHelper.setAutomaticZenRuleState(sharedUri, condition);
- for (ZenModeConfig.ZenRule rule : mZenModeHelperSpy.mConfig.automaticRules.values()) {
+ for (ZenModeConfig.ZenRule rule : mZenModeHelper.mConfig.automaticRules.values()) {
if (rule.id.equals(id)) {
assertNotNull(rule.condition);
assertTrue(rule.condition.state == STATE_TRUE);
@@ -1861,9 +1854,9 @@ public class ZenModeHelperTest extends UiServiceTestCase {
}
condition = new Condition(sharedUri, "", Condition.STATE_FALSE);
- mZenModeHelperSpy.setAutomaticZenRuleState(sharedUri, condition);
+ mZenModeHelper.setAutomaticZenRuleState(sharedUri, condition);
- for (ZenModeConfig.ZenRule rule : mZenModeHelperSpy.mConfig.automaticRules.values()) {
+ for (ZenModeConfig.ZenRule rule : mZenModeHelper.mConfig.automaticRules.values()) {
if (rule.id.equals(id)) {
assertNotNull(rule.condition);
assertTrue(rule.condition.state == Condition.STATE_FALSE);
@@ -1875,31 +1868,48 @@ public class ZenModeHelperTest extends UiServiceTestCase {
}
}
+ @Test
+ public void testSetManualZenMode() {
+ setupZenConfig();
+
+ // note that caller=null because that's how it comes in from NMS.setZenMode
+ mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, null, "");
+ mTestableLooper.processAllMessages();
+
+ // confirm that setting zen mode via setManualZenMode changed the zen mode correctly
+ assertEquals(ZEN_MODE_IMPORTANT_INTERRUPTIONS, mZenModeHelper.mZenMode);
+
+ // and also that it works to turn it back off again
+ mZenModeHelper.setManualZenMode(Global.ZEN_MODE_OFF, null, null, "");
+ mTestableLooper.processAllMessages();
+ assertEquals(Global.ZEN_MODE_OFF, mZenModeHelper.mZenMode);
+ }
+
private void setupZenConfig() {
- mZenModeHelperSpy.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
- mZenModeHelperSpy.mConfig.allowAlarms = false;
- mZenModeHelperSpy.mConfig.allowMedia = false;
- mZenModeHelperSpy.mConfig.allowSystem = false;
- mZenModeHelperSpy.mConfig.allowReminders = true;
- mZenModeHelperSpy.mConfig.allowCalls = true;
- mZenModeHelperSpy.mConfig.allowMessages = true;
- mZenModeHelperSpy.mConfig.allowEvents = true;
- mZenModeHelperSpy.mConfig.allowRepeatCallers= true;
- mZenModeHelperSpy.mConfig.suppressedVisualEffects = SUPPRESSED_EFFECT_BADGE;
- mZenModeHelperSpy.mConfig.manualRule = null;
+ mZenModeHelper.mZenMode = Global.ZEN_MODE_OFF;
+ mZenModeHelper.mConfig.allowAlarms = false;
+ mZenModeHelper.mConfig.allowMedia = false;
+ mZenModeHelper.mConfig.allowSystem = false;
+ mZenModeHelper.mConfig.allowReminders = true;
+ mZenModeHelper.mConfig.allowCalls = true;
+ mZenModeHelper.mConfig.allowMessages = true;
+ mZenModeHelper.mConfig.allowEvents = true;
+ mZenModeHelper.mConfig.allowRepeatCallers = true;
+ mZenModeHelper.mConfig.suppressedVisualEffects = SUPPRESSED_EFFECT_BADGE;
+ mZenModeHelper.mConfig.manualRule = null;
}
private void setupZenConfigMaintained() {
// config is still the same as when it was setup (setupZenConfig)
- assertFalse(mZenModeHelperSpy.mConfig.allowAlarms);
- assertFalse(mZenModeHelperSpy.mConfig.allowMedia);
- assertFalse(mZenModeHelperSpy.mConfig.allowSystem);
- assertTrue(mZenModeHelperSpy.mConfig.allowReminders);
- assertTrue(mZenModeHelperSpy.mConfig.allowCalls);
- assertTrue(mZenModeHelperSpy.mConfig.allowMessages);
- assertTrue(mZenModeHelperSpy.mConfig.allowEvents);
- assertTrue(mZenModeHelperSpy.mConfig.allowRepeatCallers);
- assertEquals(SUPPRESSED_EFFECT_BADGE, mZenModeHelperSpy.mConfig.suppressedVisualEffects);
+ assertFalse(mZenModeHelper.mConfig.allowAlarms);
+ assertFalse(mZenModeHelper.mConfig.allowMedia);
+ assertFalse(mZenModeHelper.mConfig.allowSystem);
+ assertTrue(mZenModeHelper.mConfig.allowReminders);
+ assertTrue(mZenModeHelper.mConfig.allowCalls);
+ assertTrue(mZenModeHelper.mConfig.allowMessages);
+ assertTrue(mZenModeHelper.mConfig.allowEvents);
+ assertTrue(mZenModeHelper.mConfig.allowRepeatCallers);
+ assertEquals(SUPPRESSED_EFFECT_BADGE, mZenModeHelper.mConfig.suppressedVisualEffects);
}
/**
diff --git a/services/tests/wmtests/AndroidManifest.xml b/services/tests/wmtests/AndroidManifest.xml
index fe7cd4a5edd9..37e5da5f5eaf 100644
--- a/services/tests/wmtests/AndroidManifest.xml
+++ b/services/tests/wmtests/AndroidManifest.xml
@@ -79,6 +79,7 @@
android:turnScreenOn="true"
android:showWhenLocked="true" />
<activity android:name="com.android.server.wm.ActivityOptionsTest$MainActivity"
+ android:configChanges="screenLayout|screenSize|smallestScreenSize|orientation"
android:turnScreenOn="true"
android:showWhenLocked="true" />
<activity android:name="com.android.server.wm.ScreenshotTests$ScreenshotActivity"
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index 0033e3e368c6..cb984f814f1a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -851,7 +851,7 @@ public class ActivityRecordTests extends WindowTestsBase {
}
@Override
- public void onAnimationCancelled(boolean isKeyguardOccluded) {
+ public void onAnimationCancelled() {
}
}, 0, 0));
activity.updateOptionsLocked(opts);
@@ -3124,7 +3124,7 @@ public class ActivityRecordTests extends WindowTestsBase {
.setSystemDecorations(true).build();
// Add a decor insets provider window.
final WindowState navbar = createNavBarWithProvidedInsets(squareDisplay);
- assertTrue(navbar.providesNonDecorInsets()
+ assertTrue(navbar.providesDisplayDecorInsets()
&& squareDisplay.getDisplayPolicy().updateDecorInsetsInfo());
squareDisplay.sendNewConfiguration();
final Task task = new TaskBuilder(mSupervisor).setDisplay(squareDisplay).build();
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java
index 6d1312458ce2..169968c75fc5 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java
@@ -87,7 +87,7 @@ public class AppChangeTransitionTests extends WindowTestsBase {
}
@Override
- public void onAnimationCancelled(boolean isKeyguardOccluded) {
+ public void onAnimationCancelled() {
}
@Override
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
index 0ae579bab413..a11079be85ab 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
@@ -735,7 +735,7 @@ public class AppTransitionControllerTest extends WindowTestsBase {
}
@Override
- public void onAnimationCancelled(boolean isKeyguardOccluded) throws RemoteException {
+ public void onAnimationCancelled() throws RemoteException {
mFinishedCallback = null;
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java
index 59cc4f5b0948..ba8c94dd9218 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java
@@ -549,7 +549,7 @@ public class AppTransitionTests extends WindowTestsBase {
}
@Override
- public void onAnimationCancelled(boolean isKeyguardOccluded) {
+ public void onAnimationCancelled() {
mCancelled = true;
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/AssistDataRequesterTest.java b/services/tests/wmtests/src/com/android/server/wm/AssistDataRequesterTest.java
index 06b4ad975a87..7b4392b5e15d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AssistDataRequesterTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AssistDataRequesterTest.java
@@ -50,7 +50,6 @@ import android.platform.test.annotations.Presubmit;
import android.util.Log;
import android.view.IWindowManager;
-import androidx.test.filters.FlakyTest;
import androidx.test.filters.MediumTest;
import com.android.server.am.AssistDataRequester;
@@ -155,7 +154,6 @@ public class AssistDataRequesterTest {
}
@Test
- @FlakyTest(bugId = 130388718)
public void testRequestData() throws Exception {
setupMocks(CURRENT_ACTIVITY_ASSIST_ALLOWED, CALLER_ASSIST_STRUCTURE_ALLOWED,
CALLER_ASSIST_SCREENSHOT_ALLOWED);
@@ -263,7 +261,6 @@ public class AssistDataRequesterTest {
}
@Test
- @FlakyTest(bugId = 130388718)
public void testNoFetchScreenshots_expectNoScreenshotCallbacks() throws Exception {
setupMocks(CURRENT_ACTIVITY_ASSIST_ALLOWED, CALLER_ASSIST_STRUCTURE_ALLOWED,
CALLER_ASSIST_SCREENSHOT_ALLOWED);
@@ -275,7 +272,6 @@ public class AssistDataRequesterTest {
}
@Test
- @FlakyTest(bugId = 130388718)
public void testDisallowAssistScreenshot_expectNullScreenshotCallback() throws Exception {
setupMocks(CURRENT_ACTIVITY_ASSIST_ALLOWED, CALLER_ASSIST_STRUCTURE_ALLOWED,
!CALLER_ASSIST_SCREENSHOT_ALLOWED);
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
index c8fdee06f3e4..353a8ecaf13d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
@@ -45,6 +45,8 @@ import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
@@ -298,20 +300,27 @@ public class DisplayPolicyTests extends WindowTestsBase {
@Test
public void testUpdateDisplayConfigurationByDecor() {
+ doReturn(NO_CUTOUT).when(mDisplayContent).calculateDisplayCutoutForRotation(anyInt());
final WindowState navbar = createNavBarWithProvidedInsets(mDisplayContent);
final DisplayPolicy displayPolicy = mDisplayContent.getDisplayPolicy();
final DisplayInfo di = mDisplayContent.getDisplayInfo();
final int prevScreenHeightDp = mDisplayContent.getConfiguration().screenHeightDp;
- assertTrue(navbar.providesNonDecorInsets() && displayPolicy.updateDecorInsetsInfo());
+ assertTrue(navbar.providesDisplayDecorInsets() && displayPolicy.updateDecorInsetsInfo());
assertEquals(NAV_BAR_HEIGHT, displayPolicy.getDecorInsetsInfo(di.rotation,
di.logicalWidth, di.logicalHeight).mConfigInsets.bottom);
mDisplayContent.sendNewConfiguration();
assertNotEquals(prevScreenHeightDp, mDisplayContent.getConfiguration().screenHeightDp);
- assertFalse(navbar.providesNonDecorInsets() && displayPolicy.updateDecorInsetsInfo());
+ assertFalse(navbar.providesDisplayDecorInsets() && displayPolicy.updateDecorInsetsInfo());
navbar.removeIfPossible();
assertEquals(0, displayPolicy.getDecorInsetsInfo(di.rotation, di.logicalWidth,
di.logicalHeight).mNonDecorInsets.bottom);
+
+ final WindowState statusBar = createStatusBarWithProvidedInsets(mDisplayContent);
+ assertTrue(statusBar.providesDisplayDecorInsets()
+ && displayPolicy.updateDecorInsetsInfo());
+ assertEquals(STATUS_BAR_HEIGHT, displayPolicy.getDecorInsetsInfo(di.rotation,
+ di.logicalWidth, di.logicalHeight).mConfigInsets.top);
}
@SetupWindows(addWindows = { W_NAVIGATION_BAR, W_INPUT_METHOD })
diff --git a/services/tests/wmtests/src/com/android/server/wm/PersisterQueueTests.java b/services/tests/wmtests/src/com/android/server/wm/PersisterQueueTests.java
index 027f90333561..8cf2776b85e9 100644
--- a/services/tests/wmtests/src/com/android/server/wm/PersisterQueueTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/PersisterQueueTests.java
@@ -27,7 +27,6 @@ import static org.junit.Assert.assertTrue;
import android.os.SystemClock;
import android.platform.test.annotations.Presubmit;
-import androidx.test.filters.FlakyTest;
import androidx.test.filters.MediumTest;
import org.junit.After;
@@ -110,7 +109,6 @@ public class PersisterQueueTests {
}
@Test
- @FlakyTest(bugId = 131005232)
public void testProcessOneItem_Flush() throws Exception {
mFactory.setExpectedProcessedItemNumber(1);
mListener.setExpectedOnPreProcessItemCallbackTimes(1);
@@ -162,7 +160,6 @@ public class PersisterQueueTests {
}
@Test
- @FlakyTest(bugId = 128526085)
public void testProcessTwoItems_OneAfterAnother() throws Exception {
// First item
mFactory.setExpectedProcessedItemNumber(1);
diff --git a/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java
index 0db983c6396c..c4d03bebc751 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java
@@ -37,7 +37,6 @@ import android.view.Surface;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
-import androidx.test.filters.FlakyTest;
import androidx.test.filters.SmallTest;
import com.android.server.wm.RefreshRatePolicy.FrameRateVote;
@@ -53,7 +52,6 @@ import org.junit.runner.RunWith;
@SmallTest
@Presubmit
@RunWith(WindowTestRunner.class)
-@FlakyTest
public class RefreshRatePolicyTest extends WindowTestsBase {
private static final int HI_MODE_ID = 1;
private static final float HI_REFRESH_RATE = 90;
diff --git a/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java
index eb26415c2b21..11d9629cf25e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java
@@ -211,7 +211,7 @@ public class RemoteAnimationControllerTest extends WindowTestsBase {
mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN);
adapter.onAnimationCancelled(mMockLeash);
- verify(mMockRunner).onAnimationCancelled(anyBoolean());
+ verify(mMockRunner).onAnimationCancelled();
}
@Test
@@ -227,7 +227,7 @@ public class RemoteAnimationControllerTest extends WindowTestsBase {
mClock.fastForward(10500);
mHandler.timeAdvance();
- verify(mMockRunner).onAnimationCancelled(anyBoolean());
+ verify(mMockRunner).onAnimationCancelled();
verify(mFinishedCallback).onAnimationFinished(eq(ANIMATION_TYPE_APP_TRANSITION),
eq(adapter));
}
@@ -248,12 +248,12 @@ public class RemoteAnimationControllerTest extends WindowTestsBase {
mClock.fastForward(10500);
mHandler.timeAdvance();
- verify(mMockRunner, never()).onAnimationCancelled(anyBoolean());
+ verify(mMockRunner, never()).onAnimationCancelled();
mClock.fastForward(52500);
mHandler.timeAdvance();
- verify(mMockRunner).onAnimationCancelled(anyBoolean());
+ verify(mMockRunner).onAnimationCancelled();
verify(mFinishedCallback).onAnimationFinished(eq(ANIMATION_TYPE_APP_TRANSITION),
eq(adapter));
} finally {
@@ -265,7 +265,7 @@ public class RemoteAnimationControllerTest extends WindowTestsBase {
public void testZeroAnimations() throws Exception {
mController.goodToGo(TRANSIT_OLD_NONE);
verify(mMockRunner, never()).onAnimationStart(anyInt(), any(), any(), any(), any());
- verify(mMockRunner).onAnimationCancelled(anyBoolean());
+ verify(mMockRunner).onAnimationCancelled();
}
@Test
@@ -275,7 +275,7 @@ public class RemoteAnimationControllerTest extends WindowTestsBase {
new Point(50, 100), null, new Rect(50, 100, 150, 150), null, false);
mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN);
verify(mMockRunner, never()).onAnimationStart(anyInt(), any(), any(), any(), any());
- verify(mMockRunner).onAnimationCancelled(anyBoolean());
+ verify(mMockRunner).onAnimationCancelled();
}
@Test
@@ -317,7 +317,7 @@ public class RemoteAnimationControllerTest extends WindowTestsBase {
win.mActivityRecord.removeImmediately();
mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN);
verify(mMockRunner, never()).onAnimationStart(anyInt(), any(), any(), any(), any());
- verify(mMockRunner).onAnimationCancelled(anyBoolean());
+ verify(mMockRunner).onAnimationCancelled();
verify(mFinishedCallback).onAnimationFinished(eq(ANIMATION_TYPE_APP_TRANSITION),
eq(adapter));
}
@@ -575,7 +575,7 @@ public class RemoteAnimationControllerTest extends WindowTestsBase {
// Cancel the wallpaper window animator and ensure the runner is not canceled
wallpaperWindowToken.cancelAnimation();
- verify(mMockRunner, never()).onAnimationCancelled(anyBoolean());
+ verify(mMockRunner, never()).onAnimationCancelled();
} finally {
mDisplayContent.mOpeningApps.clear();
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimationRunnerTest.java b/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimationRunnerTest.java
index ff753f21d01b..339162a02301 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimationRunnerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimationRunnerTest.java
@@ -98,7 +98,6 @@ public class SurfaceAnimationRunnerTest {
mFinishCallbackLatch.countDown();
}
- @FlakyTest(bugId = 144611135)
@Test
public void testAnimation() throws Exception {
mSurfaceAnimationRunner
diff --git a/services/tests/wmtests/src/com/android/server/wm/SurfaceControlTests.java b/services/tests/wmtests/src/com/android/server/wm/SurfaceControlTests.java
index a27a5fd8a286..342ab83de6f0 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SurfaceControlTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SurfaceControlTests.java
@@ -16,19 +16,34 @@
package com.android.server.wm;
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
+import android.app.Activity;
+import android.app.Instrumentation;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.res.Configuration;
import android.os.Parcel;
import android.platform.test.annotations.Presubmit;
+import android.util.Log;
import android.view.SurfaceControl;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import androidx.annotation.NonNull;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.util.concurrent.atomic.AtomicInteger;
+
/**
* Class for testing {@link SurfaceControl}.
*
@@ -106,6 +121,50 @@ public class SurfaceControlTests {
}
}
+ @Test
+ public void testSurfaceChangedOnRotation() {
+ final Instrumentation instrumentation = getInstrumentation();
+ final Context context = instrumentation.getContext();
+ final Activity activity = instrumentation.startActivitySync(new Intent().setComponent(
+ new ComponentName(context, ActivityOptionsTest.MainActivity.class))
+ .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
+ final SurfaceView sv = new SurfaceView(activity);
+ final AtomicInteger surfaceChangedCount = new AtomicInteger();
+ instrumentation.runOnMainSync(() -> activity.setContentView(sv));
+ sv.getHolder().addCallback(new SurfaceHolder.Callback() {
+ @Override
+ public void surfaceCreated(@NonNull SurfaceHolder holder) {
+ }
+ @Override
+ public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width,
+ int height) {
+ surfaceChangedCount.getAndIncrement();
+ Log.i("surfaceChanged", "width=" + width + " height=" + height
+ + " getTransformHint="
+ + sv.getViewRootImpl().getSurfaceControl().getTransformHint());
+ }
+ @Override
+ public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
+ }
+ });
+ final int rotation = activity.getResources().getConfiguration()
+ .windowConfiguration.getRotation();
+ activity.setRequestedOrientation(activity.getResources().getConfiguration().orientation
+ == Configuration.ORIENTATION_PORTRAIT
+ ? ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
+ : ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
+ instrumentation.getUiAutomation().syncInputTransactions();
+ instrumentation.waitForIdleSync();
+ final int newRotation = activity.getResources().getConfiguration()
+ .windowConfiguration.getRotation();
+ final int count = surfaceChangedCount.get();
+ activity.finishAndRemoveTask();
+ // The first count is triggered from creation, so the target number is 2.
+ if (rotation != newRotation && count > 2) {
+ fail("More than once surfaceChanged for rotation change: " + count);
+ }
+ }
+
private SurfaceControl buildTestSurface() {
return new SurfaceControl.Builder()
.setContainerLayer()
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java
index 790b15443198..453e4684e859 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java
@@ -52,7 +52,6 @@ import android.view.Display;
import android.view.ViewGroup;
import android.widget.LinearLayout;
-import androidx.test.filters.FlakyTest;
import androidx.test.filters.MediumTest;
import org.junit.After;
@@ -319,7 +318,6 @@ public class TaskStackChangedListenerTest {
};
@Presubmit
- @FlakyTest(bugId = 150409355)
@Test
public void testNotifyTaskRequestedOrientationChanged() throws Exception {
final ArrayBlockingQueue<int[]> taskIdAndOrientationQueue = new ArrayBlockingQueue<>(10);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
index a1ddd5748002..ad606cb90841 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
@@ -1112,7 +1112,7 @@ public class WindowContainerTests extends WindowTestsBase {
}
@Override
- public void onAnimationCancelled(boolean isKeyguardOccluded) {
+ public void onAnimationCancelled() {
}
}, 0, 0, false);
adapter.setCallingPidUid(123, 456);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContainerThumbnailTest.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerThumbnailTest.java
index 0b1b877c27de..2ae117214dd3 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerThumbnailTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerThumbnailTest.java
@@ -26,7 +26,6 @@ import static org.mockito.ArgumentMatchers.any;
import android.hardware.HardwareBuffer;
import android.platform.test.annotations.Presubmit;
-import androidx.test.filters.FlakyTest;
import androidx.test.filters.SmallTest;
import org.junit.Test;
@@ -55,7 +54,6 @@ public class WindowContainerThumbnailTest extends WindowTestsBase {
}
@Test
- @FlakyTest(bugId = 131005232)
public void testDestroy_nullsSurface() {
final WindowContainerThumbnail t = buildThumbnail();
assertNotNull(t.getSurfaceControl());
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
index 07244a4f2478..a63807d23a14 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -471,6 +471,17 @@ class WindowTestsBase extends SystemServiceTestsBase {
return navbar;
}
+ WindowState createStatusBarWithProvidedInsets(DisplayContent dc) {
+ final WindowState statusBar = createWindow(null, TYPE_STATUS_BAR, dc, "statusBar");
+ final Binder owner = new Binder();
+ statusBar.mAttrs.providedInsets = new InsetsFrameProvider[] {
+ new InsetsFrameProvider(owner, 0, WindowInsets.Type.statusBars())
+ .setInsetsSize(Insets.of(0, STATUS_BAR_HEIGHT, 0, 0))
+ };
+ dc.getDisplayPolicy().addWindowLw(statusBar, statusBar.mAttrs);
+ return statusBar;
+ }
+
WindowState createAppWindow(Task task, int type, String name) {
final ActivityRecord activity = createNonAttachedActivityRecord(task.getDisplayContent());
task.addChild(activity, 0);
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 9dd2a61671ec..26590c4704c3 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -744,10 +744,6 @@ public class TelecomManager {
* state of calls in the self-managed {@link ConnectionService}. An example use-case is
* exposing these calls to an automotive device via its companion app.
* <p>
- * This meta-data can only be set for an {@link InCallService} which also sets
- * {@link #METADATA_IN_CALL_SERVICE_UI}. Only the default phone/dialer app, or a car-mode
- * {@link InCallService} can see self-managed calls.
- * <p>
* See also {@link Connection#PROPERTY_SELF_MANAGED}.
*/
public static final String METADATA_INCLUDE_SELF_MANAGED_CALLS =
diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java
index 1ce85ba93d95..28ea5a681730 100644
--- a/telephony/java/android/telephony/data/ApnSetting.java
+++ b/telephony/java/android/telephony/data/ApnSetting.java
@@ -1186,6 +1186,7 @@ public class ApnSetting implements Parcelable {
ApnSetting other = (ApnSetting) o;
return mEntryName.equals(other.mEntryName)
+ && Objects.equals(mId, other.mId)
&& Objects.equals(mOperatorNumeric, other.mOperatorNumeric)
&& Objects.equals(mApnName, other.mApnName)
&& Objects.equals(mProxyAddress, other.mProxyAddress)
@@ -1337,6 +1338,14 @@ public class ApnSetting implements Parcelable {
public ContentValues toContentValues() {
ContentValues apnValue = new ContentValues();
apnValue.put(Telephony.Carriers.NUMERIC, nullToEmpty(mOperatorNumeric));
+ // If the APN is editable, the user may be able to set an invalid numeric. The numeric must
+ // always be 5 or 6 characters (depending on the length of the MNC), so skip if it is
+ // potentially invalid.
+ if (!TextUtils.isEmpty(mOperatorNumeric)
+ && (mOperatorNumeric.length() == 5 || mOperatorNumeric.length() == 6)) {
+ apnValue.put(Telephony.Carriers.MCC, mOperatorNumeric.substring(0, 3));
+ apnValue.put(Telephony.Carriers.MNC, mOperatorNumeric.substring(3));
+ }
apnValue.put(Telephony.Carriers.NAME, nullToEmpty(mEntryName));
apnValue.put(Telephony.Carriers.APN, nullToEmpty(mApnName));
apnValue.put(Telephony.Carriers.PROXY, nullToEmpty(mProxyAddress));
@@ -1356,6 +1365,7 @@ public class ApnSetting implements Parcelable {
getProtocolStringFromInt(mRoamingProtocol));
apnValue.put(Telephony.Carriers.CARRIER_ENABLED, mCarrierEnabled);
apnValue.put(Telephony.Carriers.MVNO_TYPE, getMvnoTypeStringFromInt(mMvnoType));
+ apnValue.put(Telephony.Carriers.MVNO_MATCH_DATA, nullToEmpty(mMvnoMatchData));
apnValue.put(Telephony.Carriers.NETWORK_TYPE_BITMASK, mNetworkTypeBitmask);
apnValue.put(Telephony.Carriers.LINGERING_NETWORK_TYPE_BITMASK,
mLingeringNetworkTypeBitmask);
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/BaseTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/BaseTest.kt
index 4e3ae0c0752a..efd9b004f8fd 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/BaseTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/BaseTest.kt
@@ -18,7 +18,7 @@ package com.android.server.wm.flicker
import android.app.Instrumentation
import android.platform.test.annotations.Presubmit
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerBuilderProvider
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.FlickerTest
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt
index f389e13a6884..1f120d47a1ac 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt
@@ -19,9 +19,9 @@
package com.android.server.wm.flicker
import android.tools.common.PlatformConsts
-import android.tools.common.datatypes.component.ComponentNameMatcher
-import android.tools.common.datatypes.component.IComponentNameMatcher
import android.tools.common.flicker.subject.region.RegionSubject
+import android.tools.common.traces.component.ComponentNameMatcher
+import android.tools.common.traces.component.IComponentNameMatcher
import android.tools.common.traces.wm.WindowManagerTrace
import android.tools.device.flicker.legacy.FlickerTest
import android.tools.device.helpers.WindowUtils
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/OpenActivityEmbeddingSecondaryToSplitTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/OpenActivityEmbeddingSecondaryToSplitTest.kt
index c3cbb84fd37f..863828881d36 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/OpenActivityEmbeddingSecondaryToSplitTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/OpenActivityEmbeddingSecondaryToSplitTest.kt
@@ -17,7 +17,7 @@
package com.android.server.wm.flicker.activityembedding
import android.platform.test.annotations.Presubmit
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.FlickerTest
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt
index 5dc2dd7d93a8..10b71ff1efd7 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt
@@ -40,20 +40,27 @@ import org.junit.runners.Parameterized
* Launch an app [testApp] and wait animation to complete
* Press back button
* ```
+ *
* To run only the presubmit assertions add: `--
+ *
* ```
* --module-arg FlickerTests:exclude-annotation:androidx.test.filters.FlakyTest
* --module-arg FlickerTests:include-annotation:android.platform.test.annotations.Presubmit`
* ```
+ *
* To run only the postsubmit assertions add: `--
+ *
* ```
* --module-arg FlickerTests:exclude-annotation:androidx.test.filters.FlakyTest
* --module-arg FlickerTests:include-annotation:android.platform.test.annotations.Postsubmit`
* ```
+ *
* To run only the flaky assertions add: `--
+ *
* ```
* --module-arg FlickerTests:include-annotation:androidx.test.filters.FlakyTest`
* ```
+ *
* Notes:
* ```
* 1. Some default assertions (e.g., nav bar, status bar and screen covered)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt
index b042a14b30da..e5bd350019c8 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt
@@ -40,20 +40,27 @@ import org.junit.runners.Parameterized
* Launch an app [testApp] and wait animation to complete
* Press home button
* ```
+ *
* To run only the presubmit assertions add: `--
+ *
* ```
* --module-arg FlickerTests:exclude-annotation:androidx.test.filters.FlakyTest
* --module-arg FlickerTests:include-annotation:android.platform.test.annotations.Presubmit`
* ```
+ *
* To run only the postsubmit assertions add: `--
+ *
* ```
* --module-arg FlickerTests:exclude-annotation:androidx.test.filters.FlakyTest
* --module-arg FlickerTests:include-annotation:android.platform.test.annotations.Postsubmit`
* ```
+ *
* To run only the flaky assertions add: `--
+ *
* ```
* --module-arg FlickerTests:include-annotation:androidx.test.filters.FlakyTest`
* ```
+ *
* Notes:
* ```
* 1. Some default assertions (e.g., nav bar, status bar and screen covered)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppTransition.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppTransition.kt
index c4628aaa90af..4570fa23dc43 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppTransition.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppTransition.kt
@@ -17,7 +17,7 @@
package com.android.server.wm.flicker.close
import android.platform.test.annotations.Presubmit
-import android.tools.common.datatypes.component.ComponentNameMatcher.Companion.LAUNCHER
+import android.tools.common.traces.component.ComponentNameMatcher.Companion.LAUNCHER
import android.tools.device.apphelpers.StandardAppHelper
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.FlickerTest
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ActivityEmbeddingAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ActivityEmbeddingAppHelper.kt
index e531bc06fb3d..6053f1dc9319 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ActivityEmbeddingAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ActivityEmbeddingAppHelper.kt
@@ -17,7 +17,7 @@
package com.android.server.wm.flicker.helpers
import android.app.Instrumentation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.common.traces.wm.WindowManagerState.Companion.STATE_RESUMED
import android.tools.device.apphelpers.StandardAppHelper
import android.tools.device.helpers.FIND_TIMEOUT
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/AppPairsHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/AppPairsHelper.kt
index afb9fbf47350..94ac1a6e1e02 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/AppPairsHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/AppPairsHelper.kt
@@ -17,7 +17,7 @@
package com.android.server.wm.flicker.helpers
import android.app.Instrumentation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.apphelpers.StandardAppHelper
class AppPairsHelper(
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FixedOrientationAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FixedOrientationAppHelper.kt
index 47dd4e9fb32d..c6fa1bb89220 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FixedOrientationAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FixedOrientationAppHelper.kt
@@ -17,7 +17,7 @@
package com.android.server.wm.flicker.helpers
import android.app.Instrumentation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.apphelpers.StandardAppHelper
import android.tools.device.traces.parsers.toFlickerComponent
import com.android.server.wm.flicker.testapp.ActivityOptions
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/GameAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/GameAppHelper.kt
index d4f48fe8d50f..747cf3742bf7 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/GameAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/GameAppHelper.kt
@@ -17,7 +17,7 @@
package com.android.server.wm.flicker.helpers
import android.app.Instrumentation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.apphelpers.StandardAppHelper
import android.tools.device.traces.parsers.WindowManagerStateHelper
import android.tools.device.traces.parsers.toFlickerComponent
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppHelper.kt
index 73effbde4515..d1722521bba8 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppHelper.kt
@@ -17,7 +17,7 @@
package com.android.server.wm.flicker.helpers
import android.app.Instrumentation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.apphelpers.StandardAppHelper
import android.tools.device.helpers.FIND_TIMEOUT
import android.tools.device.traces.parsers.WindowManagerStateHelper
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeEditorPopupDialogAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeEditorPopupDialogAppHelper.kt
index a6e57d5641d6..7a8d780c3d9f 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeEditorPopupDialogAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeEditorPopupDialogAppHelper.kt
@@ -17,7 +17,7 @@
package com.android.server.wm.flicker.helpers
import android.app.Instrumentation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.helpers.FIND_TIMEOUT
import android.tools.device.traces.parsers.WindowManagerStateHelper
import android.tools.device.traces.parsers.toFlickerComponent
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeShownOnAppStartHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeShownOnAppStartHelper.kt
index d61a500e3293..83a41abbd4bd 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeShownOnAppStartHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeShownOnAppStartHelper.kt
@@ -18,10 +18,10 @@ package com.android.server.wm.flicker.helpers
import android.app.Instrumentation
import android.tools.common.Rotation
-import android.tools.common.datatypes.component.ComponentNameMatcher
-import android.tools.common.datatypes.component.IComponentMatcher
import android.tools.common.traces.Condition
import android.tools.common.traces.DeviceStateDump
+import android.tools.common.traces.component.ComponentNameMatcher
+import android.tools.common.traces.component.IComponentMatcher
import android.tools.device.helpers.FIND_TIMEOUT
import android.tools.device.helpers.IME_PACKAGE
import android.tools.device.traces.parsers.WindowManagerStateHelper
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeStateInitializeHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeStateInitializeHelper.kt
index fb5e1d2da26b..b2aeb14aaf78 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeStateInitializeHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeStateInitializeHelper.kt
@@ -17,7 +17,7 @@
package com.android.server.wm.flicker.helpers
import android.app.Instrumentation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.apphelpers.StandardAppHelper
import android.tools.device.traces.parsers.toFlickerComponent
import com.android.server.wm.flicker.testapp.ActivityOptions
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/LetterboxAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/LetterboxAppHelper.kt
index 1ccac13c280f..a670d68cabd9 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/LetterboxAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/LetterboxAppHelper.kt
@@ -17,15 +17,15 @@
package com.android.server.wm.flicker.helpers
import android.app.Instrumentation
-import androidx.test.uiautomator.By
-import androidx.test.uiautomator.Until
-import com.android.server.wm.flicker.testapp.ActivityOptions
-import android.tools.common.datatypes.component.ComponentNameMatcher
-import android.tools.device.traces.parsers.toFlickerComponent
-import android.tools.device.traces.parsers.WindowManagerStateHelper
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.apphelpers.StandardAppHelper
import android.tools.device.helpers.FIND_TIMEOUT
import android.tools.device.helpers.SYSTEMUI_PACKAGE
+import android.tools.device.traces.parsers.WindowManagerStateHelper
+import android.tools.device.traces.parsers.toFlickerComponent
+import androidx.test.uiautomator.By
+import androidx.test.uiautomator.Until
+import com.android.server.wm.flicker.testapp.ActivityOptions
class LetterboxAppHelper
@JvmOverloads
@@ -37,13 +37,21 @@ constructor(
) : StandardAppHelper(instr, launcherName, component) {
fun clickRestart(wmHelper: WindowManagerStateHelper) {
- val restartButton = uiDevice.wait(Until.findObject(By.res(
- SYSTEMUI_PACKAGE, "size_compat_restart_button")), FIND_TIMEOUT)
+ val restartButton =
+ uiDevice.wait(
+ Until.findObject(By.res(SYSTEMUI_PACKAGE, "size_compat_restart_button")),
+ FIND_TIMEOUT
+ )
restartButton?.run { restartButton.click() } ?: error("Restart button not found")
// size compat mode restart confirmation dialog button
- val restartDialogButton = uiDevice.wait(Until.findObject(By.res(
- SYSTEMUI_PACKAGE, "letterbox_restart_dialog_restart_button")), FIND_TIMEOUT)
+ val restartDialogButton =
+ uiDevice.wait(
+ Until.findObject(
+ By.res(SYSTEMUI_PACKAGE, "letterbox_restart_dialog_restart_button")
+ ),
+ FIND_TIMEOUT
+ )
restartDialogButton?.run { restartDialogButton.click() }
?: error("Restart dialog button not found")
wmHelper.StateSyncBuilder().withAppTransitionIdle().waitForAndVerify()
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/MailAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/MailAppHelper.kt
index ab916858858a..c98f1c4b4d29 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/MailAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/MailAppHelper.kt
@@ -17,7 +17,7 @@
package com.android.server.wm.flicker.helpers
import android.app.Instrumentation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.apphelpers.StandardAppHelper
import android.tools.device.helpers.FIND_TIMEOUT
import android.tools.device.traces.parsers.toFlickerComponent
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/MultiWindowUtils.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/MultiWindowUtils.kt
index e93e9c8e9bfb..65175ef33afb 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/MultiWindowUtils.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/MultiWindowUtils.kt
@@ -19,7 +19,7 @@ package com.android.server.wm.flicker.helpers
import android.app.Instrumentation
import android.content.Context
import android.provider.Settings
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.apphelpers.StandardAppHelper
import android.util.Log
import com.android.compatibility.common.util.SystemUtil
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NewTasksAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NewTasksAppHelper.kt
index c547ad06fe6c..5b3d3083fe1c 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NewTasksAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NewTasksAppHelper.kt
@@ -17,7 +17,7 @@
package com.android.server.wm.flicker.helpers
import android.app.Instrumentation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.apphelpers.StandardAppHelper
import android.tools.device.helpers.FIND_TIMEOUT
import android.tools.device.traces.parsers.WindowManagerStateHelper
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NonResizeableAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NonResizeableAppHelper.kt
index 20ee3b9d236d..ee65004e9e78 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NonResizeableAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NonResizeableAppHelper.kt
@@ -17,7 +17,7 @@
package com.android.server.wm.flicker.helpers
import android.app.Instrumentation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.apphelpers.StandardAppHelper
import android.tools.device.traces.parsers.toFlickerComponent
import com.android.server.wm.flicker.testapp.ActivityOptions
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NotificationAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NotificationAppHelper.kt
index 78f8bcf70b60..7665690a3122 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NotificationAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/NotificationAppHelper.kt
@@ -17,7 +17,7 @@
package com.android.server.wm.flicker.helpers
import android.app.Instrumentation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.apphelpers.StandardAppHelper
import android.tools.device.helpers.FIND_TIMEOUT
import android.tools.device.traces.parsers.WindowManagerStateHelper
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt
index c5a21a80d8d0..24e231c73a0f 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt
@@ -21,8 +21,8 @@ import android.media.session.MediaController
import android.media.session.MediaSessionManager
import android.tools.common.datatypes.Rect
import android.tools.common.datatypes.Region
-import android.tools.common.datatypes.component.IComponentMatcher
import android.tools.common.traces.ConditionsFactory
+import android.tools.common.traces.component.IComponentMatcher
import android.tools.device.apphelpers.StandardAppHelper
import android.tools.device.helpers.FIND_TIMEOUT
import android.tools.device.helpers.SYSTEMUI_PACKAGE
@@ -250,7 +250,8 @@ open class PipAppHelper(instrumentation: Instrumentation) :
waitConditions = arrayOf(ConditionsFactory.hasPipWindow())
)
- wmHelper.StateSyncBuilder()
+ wmHelper
+ .StateSyncBuilder()
.withWindowSurfaceAppeared(this)
.withPipShown()
.waitForAndVerify()
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/SeamlessRotationAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/SeamlessRotationAppHelper.kt
index 06e668ea07a1..cac3530399de 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/SeamlessRotationAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/SeamlessRotationAppHelper.kt
@@ -17,7 +17,7 @@
package com.android.server.wm.flicker.helpers
import android.app.Instrumentation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.apphelpers.StandardAppHelper
import android.tools.device.traces.parsers.toFlickerComponent
import com.android.server.wm.flicker.testapp.ActivityOptions
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ShowWhenLockedAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ShowWhenLockedAppHelper.kt
index 94c90dabd2c8..8366a7a1fe41 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ShowWhenLockedAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ShowWhenLockedAppHelper.kt
@@ -17,7 +17,7 @@
package com.android.server.wm.flicker.helpers
import android.app.Instrumentation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.apphelpers.StandardAppHelper
import android.tools.device.traces.parsers.toFlickerComponent
import com.android.server.wm.flicker.testapp.ActivityOptions
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/SimpleAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/SimpleAppHelper.kt
index 64af811d1c4f..89c6c35af47d 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/SimpleAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/SimpleAppHelper.kt
@@ -17,7 +17,7 @@
package com.android.server.wm.flicker.helpers
import android.app.Instrumentation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.apphelpers.StandardAppHelper
import android.tools.device.traces.parsers.toFlickerComponent
import com.android.server.wm.flicker.testapp.ActivityOptions
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/TwoActivitiesAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/TwoActivitiesAppHelper.kt
index 316766a5c3f3..895725c1efef 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/TwoActivitiesAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/TwoActivitiesAppHelper.kt
@@ -17,7 +17,7 @@
package com.android.server.wm.flicker.helpers
import android.app.Instrumentation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.apphelpers.StandardAppHelper
import android.tools.device.helpers.FIND_TIMEOUT
import android.tools.device.traces.parsers.WindowManagerStateHelper
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeOnDismissPopupDialogTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeOnDismissPopupDialogTest.kt
index 34fa921f5777..7e0632d216ea 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeOnDismissPopupDialogTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeOnDismissPopupDialogTest.kt
@@ -18,8 +18,8 @@ package com.android.server.wm.flicker.ime
import android.platform.test.annotations.Presubmit
import android.tools.common.Rotation
-import android.tools.common.datatypes.component.ComponentNameMatcher
import android.tools.common.flicker.subject.region.RegionSubject
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.FlickerTest
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeOnGoHomeTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeOnGoHomeTest.kt
index 823328af57aa..7f496d828996 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeOnGoHomeTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeOnGoHomeTest.kt
@@ -19,7 +19,7 @@ package com.android.server.wm.flicker.ime
import android.platform.test.annotations.IwTest
import android.platform.test.annotations.Presubmit
import android.tools.common.Rotation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.FlickerTest
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeShownOnAppStartOnGoHomeTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeShownOnAppStartOnGoHomeTest.kt
index df9d33bf2c8f..cbe03dcd932a 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeShownOnAppStartOnGoHomeTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeShownOnAppStartOnGoHomeTest.kt
@@ -18,7 +18,7 @@ package com.android.server.wm.flicker.ime
import android.platform.test.annotations.Presubmit
import android.tools.common.Rotation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.FlickerTest
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeShownOnAppStartToAppOnPressBackTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeShownOnAppStartToAppOnPressBackTest.kt
index 7954dd13e906..82c390b77d59 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeShownOnAppStartToAppOnPressBackTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeShownOnAppStartToAppOnPressBackTest.kt
@@ -18,7 +18,7 @@ package com.android.server.wm.flicker.ime
import android.platform.test.annotations.Presubmit
import android.tools.common.Rotation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.FlickerTest
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeToAppOnPressBackTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeToAppOnPressBackTest.kt
index 10ce5eab4f29..c693ca759bdd 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeToAppOnPressBackTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeToAppOnPressBackTest.kt
@@ -18,7 +18,7 @@ package com.android.server.wm.flicker.ime
import android.platform.test.annotations.IwTest
import android.platform.test.annotations.Presubmit
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.FlickerTest
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CommonAssertions.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CommonAssertions.kt
index 579c10f62f52..8e3371986056 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CommonAssertions.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CommonAssertions.kt
@@ -18,7 +18,7 @@
package com.android.server.wm.flicker.ime
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.legacy.FlickerTest
fun FlickerTest.imeLayerBecomesVisible() {
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowToFixedPortraitAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowToFixedPortraitAppTest.kt
index 3f87aef16cdb..19bbf0cb92b0 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowToFixedPortraitAppTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowToFixedPortraitAppTest.kt
@@ -18,8 +18,8 @@ package com.android.server.wm.flicker.ime
import android.platform.test.annotations.Presubmit
import android.tools.common.NavBar
import android.tools.common.Rotation
-import android.tools.common.datatypes.component.ComponentNameMatcher
import android.tools.common.flicker.subject.region.RegionSubject
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.FlickerTest
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromOverviewTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromOverviewTest.kt
index 6179fc2aef21..f64ad53bf2f7 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromOverviewTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromOverviewTest.kt
@@ -18,7 +18,7 @@ package com.android.server.wm.flicker.ime
import android.platform.test.annotations.Presubmit
import android.tools.common.Rotation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.FlickerTest
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromQuickSwitchTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromQuickSwitchTest.kt
index 690ed53df5f2..11bc7b9f29c0 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromQuickSwitchTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromQuickSwitchTest.kt
@@ -19,7 +19,7 @@ package com.android.server.wm.flicker.ime
import android.platform.test.annotations.Presubmit
import android.tools.common.NavBar
import android.tools.common.Rotation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.FlickerTest
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppTest.kt
index 866e858f3865..46967db55086 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppTest.kt
@@ -18,7 +18,7 @@ package com.android.server.wm.flicker.ime
import android.platform.test.annotations.Presubmit
import android.tools.common.Rotation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.FlickerTest
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeWhileDismissingThemedPopupDialogTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeWhileDismissingThemedPopupDialogTest.kt
index 6f225891f39c..277b91558416 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeWhileDismissingThemedPopupDialogTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeWhileDismissingThemedPopupDialogTest.kt
@@ -18,7 +18,7 @@ package com.android.server.wm.flicker.ime
import android.platform.test.annotations.Presubmit
import android.tools.common.Rotation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.FlickerTest
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeWhileEnteringOverviewTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeWhileEnteringOverviewTest.kt
index 231d0d74c2a1..9275d6a2f17f 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeWhileEnteringOverviewTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeWhileEnteringOverviewTest.kt
@@ -17,8 +17,8 @@
package com.android.server.wm.flicker.ime
import android.platform.test.annotations.Presubmit
-import android.tools.common.datatypes.component.ComponentNameMatcher
import android.tools.common.traces.ConditionsFactory
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.FlickerTest
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivitiesTransitionTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivitiesTransitionTest.kt
index 3c577ac2db35..e6594c969373 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivitiesTransitionTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivitiesTransitionTest.kt
@@ -17,7 +17,7 @@
package com.android.server.wm.flicker.launch
import android.platform.test.annotations.Presubmit
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.FlickerTest
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppAfterCameraTestCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppAfterCameraTestCfArm.kt
index 3289bc601160..ac05c7687311 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppAfterCameraTestCfArm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppAfterCameraTestCfArm.kt
@@ -41,4 +41,4 @@ class OpenAppAfterCameraTestCfArm(flicker: FlickerTest) : OpenAppAfterCameraTest
return FlickerTestFactory.nonRotationTests()
}
}
-} \ No newline at end of file
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdFromIcon.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdFromIcon.kt
index 360a2336962c..a658293c4294 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdFromIcon.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdFromIcon.kt
@@ -16,7 +16,6 @@
package com.android.server.wm.flicker.launch
-import android.tools.common.NavBar
import android.tools.common.Rotation
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
@@ -87,10 +86,7 @@ open class OpenAppColdFromIcon(flicker: FlickerTest) : OpenAppFromLauncherTransi
@Parameterized.Parameters(name = "{0}")
@JvmStatic
fun getParams(): Collection<FlickerTest> {
- // TAPL fails on landscape mode b/240916028
- return FlickerTestFactory.nonRotationTests(
- supportedNavigationModes = listOf(NavBar.MODE_3BUTTON)
- )
+ return FlickerTestFactory.nonRotationTests()
}
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdFromIconCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdFromIconCfArm.kt
index ccbe74f04a70..d33a2724ca44 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdFromIconCfArm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdFromIconCfArm.kt
@@ -17,7 +17,6 @@
package com.android.server.wm.flicker.launch
import android.platform.test.annotations.FlakyTest
-import android.tools.common.NavBar
import android.tools.device.flicker.annotation.FlickerServiceCompatible
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerTest
@@ -50,10 +49,7 @@ class OpenAppColdFromIconCfArm(flicker: FlickerTest) : OpenAppColdFromIcon(flick
@Parameterized.Parameters(name = "{0}")
@JvmStatic
fun getParams(): Collection<FlickerTest> {
- // TAPL fails on landscape mode b/240916028
- return FlickerTestFactory.nonRotationTests(
- supportedNavigationModes = listOf(NavBar.MODE_3BUTTON)
- )
+ return FlickerTestFactory.nonRotationTests()
}
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt
index d0dc42f29b9e..26f88d23cda0 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt
@@ -23,9 +23,9 @@ import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.FlickerTest
import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.rules.RemoveAllTasksButHomeRule.Companion.removeAllTasksButHome
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.helpers.setRotation
-import android.tools.device.flicker.rules.RemoveAllTasksButHomeRule.Companion.removeAllTasksButHome
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -42,6 +42,7 @@ import org.junit.runners.Parameterized
* Make sure no apps are running on the device
* Launch an app [testApp] and wait animation to complete
* ```
+ *
* Notes:
* ```
* 1. Some default assertions (e.g., nav bar, status bar and screen covered)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTestCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTestCfArm.kt
index f75d9eede25b..d9a99dadbd3d 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTestCfArm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTestCfArm.kt
@@ -49,4 +49,4 @@ class OpenAppColdTestCfArm(flicker: FlickerTest) : OpenAppColdTest(flicker) {
return FlickerTestFactory.nonRotationTests()
}
}
-} \ No newline at end of file
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLauncherTransition.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLauncherTransition.kt
index 1a1d4036579f..3d5a8e309b10 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLauncherTransition.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLauncherTransition.kt
@@ -17,7 +17,7 @@
package com.android.server.wm.flicker.launch
import android.platform.test.annotations.Presubmit
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.legacy.FlickerTest
import com.android.server.wm.flicker.replacesLayer
import org.junit.Test
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationCold.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationCold.kt
index b1a267ac27b4..b21777b30b21 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationCold.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationCold.kt
@@ -78,9 +78,7 @@ open class OpenAppFromLockNotificationCold(flicker: FlickerTest) :
override fun taskBarLayerIsVisibleAtStartAndEnd() {}
/** {@inheritDoc} */
- @Test
- @Ignore("Display is off at the start")
- override fun taskBarWindowIsAlwaysVisible() {}
+ @Test @Ignore("Display is off at the start") override fun taskBarWindowIsAlwaysVisible() {}
/** {@inheritDoc} */
@Test
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWarm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWarm.kt
index e41432555ded..ec92ca65f80a 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWarm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWarm.kt
@@ -20,7 +20,7 @@ import android.platform.test.annotations.FlakyTest
import android.platform.test.annotations.Presubmit
import android.platform.test.rule.SettingOverrideRule
import android.provider.Settings
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.FlickerTest
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWithLockOverlayApp.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWithLockOverlayApp.kt
index 0b09e248b221..009d61797fe0 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWithLockOverlayApp.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWithLockOverlayApp.kt
@@ -19,7 +19,7 @@ package com.android.server.wm.flicker.launch
import android.platform.test.annotations.FlakyTest
import android.platform.test.annotations.Postsubmit
import android.platform.test.annotations.Presubmit
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.FlickerTest
@@ -113,9 +113,7 @@ class OpenAppFromLockNotificationWithLockOverlayApp(flicker: FlickerTest) :
@Test
override fun navBarWindowIsAlwaysVisible() = super.navBarWindowIsAlwaysVisible()
- @Presubmit
- @Test
- override fun entireScreenCovered() = super.entireScreenCovered()
+ @Presubmit @Test override fun entireScreenCovered() = super.entireScreenCovered()
@FlakyTest(bugId = 278227468)
@Test
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockTransition.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockTransition.kt
index 730f78ff3bc2..eae9ca10c711 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockTransition.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockTransition.kt
@@ -18,7 +18,7 @@ package com.android.server.wm.flicker.launch
import android.platform.test.annotations.FlakyTest
import android.platform.test.annotations.Presubmit
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.FlickerTest
import com.android.server.wm.flicker.navBarLayerPositionAtEnd
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationCold.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationCold.kt
index 9c16b7938e73..7bcb91070ecf 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationCold.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationCold.kt
@@ -18,7 +18,7 @@ package com.android.server.wm.flicker.launch
import android.platform.test.annotations.Postsubmit
import android.platform.test.annotations.Presubmit
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.FlickerTest
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationColdCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationColdCfArm.kt
index 4aa78d4482fb..8b4a613305c0 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationColdCfArm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationColdCfArm.kt
@@ -44,4 +44,4 @@ class OpenAppFromNotificationColdCfArm(flicker: FlickerTest) :
return FlickerTestFactory.nonRotationTests()
}
}
-} \ No newline at end of file
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationWarm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationWarm.kt
index 23cb1d49619f..425e674dec3a 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationWarm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationWarm.kt
@@ -18,7 +18,7 @@ package com.android.server.wm.flicker.launch
import android.platform.test.annotations.Postsubmit
import android.platform.test.annotations.Presubmit
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.FlickerTest
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt
index 00d7544f7217..8e1b059b2bc7 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt
@@ -44,6 +44,7 @@ import org.junit.runners.Parameterized
* Relaunch an app [testApp] by selecting it in the overview screen, and wait animation to
* complete (only this action is traced)
* ```
+ *
* Notes:
* ```
* 1. Some default assertions (e.g., nav bar, status bar and screen covered)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt
index 17f5638a1a50..1383ae39f760 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt
@@ -20,7 +20,7 @@ import android.platform.test.annotations.FlakyTest
import android.platform.test.annotations.Presubmit
import android.tools.common.NavBar
import android.tools.common.Rotation
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.annotation.FlickerServiceCompatible
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerTest
@@ -47,6 +47,7 @@ import org.junit.runners.Parameterized
* Lock the device.
* Launch an app on top of the lock screen [testApp] and wait animation to complete
* ```
+ *
* Notes:
* ```
* 1. Some default assertions (e.g., nav bar, status bar and screen covered)
@@ -161,9 +162,7 @@ open class OpenAppNonResizeableTest(flicker: FlickerTest) : OpenAppFromLockTrans
super.appWindowBecomesFirstAndOnlyTopWindow()
/** {@inheritDoc} */
- @Presubmit
- @Test
- override fun appWindowBecomesVisible() = super.appWindowBecomesVisible()
+ @Presubmit @Test override fun appWindowBecomesVisible() = super.appWindowBecomesVisible()
/** Checks the [ComponentNameMatcher.NAV_BAR] is visible at the end of the transition */
@Presubmit
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTransition.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTransition.kt
index e0db96f3b5c6..87a14c69e3ac 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTransition.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTransition.kt
@@ -17,7 +17,7 @@
package com.android.server.wm.flicker.launch
import android.platform.test.annotations.Presubmit
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.apphelpers.StandardAppHelper
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.FlickerTest
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt
index cdd2d45769bb..3385830ee77f 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt
@@ -42,6 +42,7 @@ import org.junit.runners.Parameterized
* Press home
* Relaunch an app [testApp] and wait animation to complete (only this action is traced)
* ```
+ *
* Notes:
* ```
* 1. Some default assertions (e.g., nav bar, status bar and screen covered)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTestCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTestCfArm.kt
index 9679059e5069..d8b38b30cf13 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTestCfArm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTestCfArm.kt
@@ -43,4 +43,4 @@ class OpenAppWarmTestCfArm(flicker: FlickerTest) : OpenAppWarmTest(flicker) {
return FlickerTestFactory.nonRotationTests()
}
}
-} \ No newline at end of file
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OverrideTaskTransitionTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OverrideTaskTransitionTest.kt
index b848e63c9c87..b48611edd738 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OverrideTaskTransitionTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OverrideTaskTransitionTest.kt
@@ -20,20 +20,20 @@ import android.app.Instrumentation
import android.os.Bundle
import android.os.Handler
import android.platform.test.annotations.Presubmit
-import android.tools.common.datatypes.component.ComponentNameMatcher
import android.tools.common.traces.ConditionsFactory
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerBuilderProvider
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.FlickerTest
import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.rules.RemoveAllTasksButHomeRule
+import android.tools.device.helpers.wakeUpAndGoToHomeScreen
import androidx.test.filters.RequiresDevice
import androidx.test.platform.app.InstrumentationRegistry
import com.android.server.wm.flicker.R
-import com.android.server.wm.flicker.helpers.setRotation
-import android.tools.device.flicker.rules.RemoveAllTasksButHomeRule
-import android.tools.device.helpers.wakeUpAndGoToHomeScreen
import com.android.server.wm.flicker.helpers.SimpleAppHelper
+import com.android.server.wm.flicker.helpers.setRotation
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/TaskTransitionTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/TaskTransitionTest.kt
index be735477dc40..d0fd73207c42 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/TaskTransitionTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/TaskTransitionTest.kt
@@ -21,11 +21,11 @@ import android.app.WallpaperManager
import android.content.res.Resources
import android.platform.test.annotations.FlakyTest
import android.platform.test.annotations.Presubmit
-import android.tools.common.datatypes.component.ComponentNameMatcher
-import android.tools.common.datatypes.component.ComponentNameMatcher.Companion.SPLASH_SCREEN
-import android.tools.common.datatypes.component.ComponentNameMatcher.Companion.WALLPAPER_BBQ_WRAPPER
-import android.tools.common.datatypes.component.ComponentSplashScreenMatcher
-import android.tools.common.datatypes.component.IComponentMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher.Companion.SPLASH_SCREEN
+import android.tools.common.traces.component.ComponentNameMatcher.Companion.WALLPAPER_BBQ_WRAPPER
+import android.tools.common.traces.component.ComponentSplashScreenMatcher
+import android.tools.common.traces.component.IComponentMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.FlickerTest
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest.kt
index eadeef5bf3e6..a8b80ad1d16c 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest.kt
@@ -20,7 +20,7 @@ import android.platform.test.annotations.FlakyTest
import android.platform.test.annotations.Presubmit
import android.tools.common.NavBar
import android.tools.common.datatypes.Rect
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.FlickerTest
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt
index 136049533350..96cd8ffa3eff 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt
@@ -20,7 +20,7 @@ import android.platform.test.annotations.FlakyTest
import android.platform.test.annotations.Presubmit
import android.tools.common.NavBar
import android.tools.common.datatypes.Rect
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.FlickerTest
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt
index d49f035fa84a..7e935f03aeb1 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt
@@ -21,7 +21,7 @@ import android.platform.test.annotations.Presubmit
import android.tools.common.NavBar
import android.tools.common.Rotation
import android.tools.common.datatypes.Rect
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.FlickerTest
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
index fe789a7a7384..855ea3e38b3e 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
@@ -18,7 +18,7 @@ package com.android.server.wm.flicker.rotation
import android.platform.test.annotations.IwTest
import android.platform.test.annotations.Presubmit
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.FlickerTest
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/RotationTransition.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/RotationTransition.kt
index 3c0bbd6c4c1c..fe9da335a675 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/RotationTransition.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/RotationTransition.kt
@@ -17,7 +17,7 @@
package com.android.server.wm.flicker.rotation
import android.platform.test.annotations.Presubmit
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.apphelpers.StandardAppHelper
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.FlickerTest
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
index 4d010f35d4eb..0cbbb83b48ee 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
@@ -19,7 +19,7 @@ package com.android.server.wm.flicker.rotation
import android.platform.test.annotations.IwTest
import android.platform.test.annotations.Presubmit
import android.tools.common.ScenarioBuilder
-import android.tools.common.datatypes.component.ComponentNameMatcher
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.FlickerTest